From f98f578742fc238169a993d4c446f34ab30304d9 Mon Sep 17 00:00:00 2001 From: Krish Dholakia Date: Wed, 4 Feb 2026 23:12:33 -0800 Subject: [PATCH] Revert "fix(mypy): fix type: ignore placement for OTEL LogRecord import (#20351)" This reverts commit 424e1bb931c305bfdb0f4e8c5bb634f094159c59. --- .circleci/config.yml | 225 +-- .circleci/requirements.txt | 3 +- .github/workflows/test-linting.yml | 2 +- .github/workflows/test-litellm.yml | 2 +- .github/workflows/test-model-map.yaml | 15 - .gitignore | 8 + AGENTS.md | 8 +- README.md | 15 +- .../litellm-helm/templates/deployment.yaml | 4 - .../templates/migrations-job.yaml | 4 - deploy/charts/litellm-helm/values.yaml | 1 - docs/my-website/docs/a2a.md | 2 +- docs/my-website/docs/observability/datadog.md | 52 +- .../docs/providers/anthropic_tool_search.md | 448 ++--- docs/my-website/docs/providers/gemini.md | 51 - docs/my-website/docs/providers/sarvam.md | 89 - .../docs/providers/vercel_ai_gateway.md | 36 +- docs/my-website/docs/proxy/cli_sso.md | 31 - docs/my-website/docs/proxy/config_settings.md | 2 - docs/my-website/docs/proxy/deploy.md | 1 - .../docs/proxy/guardrails/onyx_security.md | 3 - .../docs/proxy/guardrails/quick_start.md | 6 +- .../docs/proxy/keys_teams_router_settings.md | 150 -- .../docs/proxy/litellm_managed_files.md | 2 +- docs/my-website/docs/proxy/prometheus.md | 15 +- .../docs/proxy/ui/page_visibility.md | 121 -- docs/my-website/docs/rag_ingest.md | 78 +- docs/my-website/docs/routing.md | 6 - docs/my-website/docs/traffic_mirroring.md | 83 - .../img/ui_granular_router_settings.png | Bin 359348 -> 0 bytes .../my-website/release_notes/v1.81.0/index.md | 4 +- .../release_notes/v1.81.3-stable/index.md | 423 ----- docs/my-website/sidebars.js | 18 +- .../proxy/auth/route_checks.py | 2 +- .../proxy/hooks/managed_files.py | 73 - ...tellm_proxy_extras-0.4.27-py3-none-any.whl | Bin 50073 -> 0 bytes .../dist/litellm_proxy_extras-0.4.27.tar.gz | Bin 23269 -> 0 bytes .../litellm_proxy_extras/_logging.py | 40 +- .../migration.sql | 10 +- .../litellm_proxy_extras/schema.prisma | 5 - .../litellm_proxy_extras/utils.py | 109 +- litellm-proxy-extras/pyproject.toml | 4 +- litellm/__init__.py | 2 - litellm/_logging.py | 60 - litellm/a2a_protocol/card_resolver.py | 97 - litellm/a2a_protocol/main.py | 9 +- litellm/constants.py | 13 - litellm/cost_calculator.py | 56 +- litellm/experimental_mcp_client/client.py | 164 +- litellm/integrations/callback_configs.json | 29 +- litellm/integrations/custom_guardrail.py | 16 +- litellm/integrations/datadog/datadog.py | 17 +- .../datadog/datadog_cost_management.py | 204 -- .../integrations/datadog/datadog_handler.py | 8 - .../integrations/datadog/datadog_llm_obs.py | 64 +- litellm/integrations/langfuse/langfuse.py | 14 +- .../langfuse/langfuse_prompt_management.py | 92 +- litellm/integrations/opentelemetry.py | 12 +- litellm/integrations/prometheus.py | 232 +-- .../litellm_core_utils/get_litellm_params.py | 9 +- litellm/litellm_core_utils/litellm_logging.py | 59 +- .../litellm_core_utils/llm_cost_calc/utils.py | 40 +- .../convert_dict_to_response.py | 18 - litellm/litellm_core_utils/logging_worker.py | 22 - .../prompt_templates/factory.py | 20 +- .../prompt_templates/image_handling.py | 14 +- litellm/llms/anthropic/chat/transformation.py | 19 +- .../adapters/transformation.py | 179 +- .../llms/azure/chat/gpt_5_transformation.py | 8 +- litellm/llms/azure/cost_calculation.py | 39 +- .../base_llm/vector_store/transformation.py | 26 +- litellm/llms/bedrock/base_aws_llm.py | 2 +- .../bedrock/chat/converse_transformation.py | 73 +- litellm/llms/bedrock/chat/invoke_handler.py | 5 - .../anthropic_claude3_transformation.py | 37 +- litellm/llms/bedrock/common_utils.py | 23 +- .../anthropic_claude3_transformation.py | 67 +- litellm/llms/custom_httpx/llm_http_handler.py | 36 +- litellm/llms/gemini/chat/transformation.py | 2 +- litellm/llms/gigachat/chat/transformation.py | 56 +- litellm/llms/groq/chat/transformation.py | 8 - .../llms/hosted_vllm/chat/transformation.py | 23 +- litellm/llms/minimax/chat/transformation.py | 29 +- litellm/llms/oci/chat/transformation.py | 3 +- .../llms/openai/chat/gpt_5_transformation.py | 4 +- .../image_generation/cost_calculator.py | 20 +- .../llms/openrouter/chat/transformation.py | 4 - litellm/llms/s3_vectors/__init__.py | 1 - .../llms/s3_vectors/vector_stores/__init__.py | 1 - .../vector_stores/transformation.py | 254 --- .../vercel_ai_gateway/embedding/__init__.py | 0 .../embedding/transformation.py | 176 -- litellm/llms/vertex_ai/common_utils.py | 2 +- .../vertex_and_google_ai_studio_gemini.py | 10 - litellm/llms/xai/responses/transformation.py | 123 +- litellm/llms/zai/chat/transformation.py | 16 +- litellm/main.py | 93 +- ...odel_prices_and_context_window_backup.json | 231 +-- .../mcp_server/discoverable_endpoints.py | 172 +- .../mcp_server/mcp_server_manager.py | 39 +- .../proxy/_experimental/mcp_server/server.py | 42 +- litellm/proxy/_experimental/out/404.html | 1 - .../static/chunks/1098-a1702da59647cf14.js | 1 - .../static/chunks/1098-c3e95c9684ff5e95.js | 1 + .../static/chunks/1108-8b678b0704cb239b.js | 1 - .../static/chunks/1108-c2d0c742b6e72436.js | 1 + .../static/chunks/1112-0b9bd4ebde18e77b.js | 1 - .../static/chunks/1128-64fa4a41ccaf67ea.js | 1 + .../static/chunks/1132-d0fa0c9565944e8f.js | 1 - .../static/chunks/1176-9175d7684b344026.js | 1 - .../static/chunks/137-c6f74fedf576a11b.js | 1 + .../static/chunks/1414-2770d1155b664522.js | 1 + .../static/chunks/1442-024f7e51804e0d7e.js | 1 + .../static/chunks/1658-2c9554a5b3840812.js | 1 - .../static/chunks/1716-1c0ba935a144e6ff.js | 1 - .../static/chunks/1717-bb1b888f6ccc52d6.js | 1 - .../static/chunks/1789-a56ee544e60cd01d.js | 1 - .../static/chunks/1901-4d02d1f2a71cdbf7.js | 1 + .../static/chunks/1994-6637a121c9ee1602.js | 1 + .../_next/static/chunks/2-253aec8d55c7bb6f.js | 1 - ...6e23aa271e.js => 2068-2c78bfc32dc0de5f.js} | 4 +- .../static/chunks/2136-2c0d6e8c18d2c5c4.js | 1 + .../static/chunks/2172-c97c9e958a9c36e3.js | 1 - .../static/chunks/2202-a83ad035a17401aa.js | 1 + .../static/chunks/2227-5ae3f36b0a81c5b4.js | 1 + .../static/chunks/2318-b8f043257a4eca15.js | 1 - .../static/chunks/2344-905d7ecc9d0c6724.js | 1 - .../static/chunks/2353-c94748c0aac514ff.js | 1 - .../static/chunks/2378-252212b7a5e313ce.js | 1 + ...56841bda3f.js => 2409-e94c05c6f11bb939.js} | 0 .../static/chunks/2500-811f2612ec5f6830.js | 1 + .../static/chunks/2652-55de14f9e14b1064.js | 1 - .../static/chunks/2699-38ff37315d78ae04.js | 1 + .../static/chunks/2731-b2ffcaeb9eabaa23.js | 1 - .../static/chunks/2820-592c2b4ff874a913.js | 1 + ...39800f0159.js => 2901-0cdd0656eb7463d6.js} | 0 .../static/chunks/292-7bd148a17bc0a05b.js | 1 - .../static/chunks/292-aaba6c4e7c8d416d.js | 1 + .../static/chunks/2926-a9cb83e61fc8ad20.js | 1 + .../static/chunks/2926-ac542d9fa707b8a4.js | 1 - .../static/chunks/3178-47bc3b9e8cf9bf6c.js | 1 - ...64e87271d0.js => 3242-6e6ec7e18f5d698d.js} | 0 ...b3d3d247b2.js => 3367-58830187e9e5b9fa.js} | 2 +- ...aa1bd1d68cc.js => 337-bb33d149e9f461b3.js} | 0 .../static/chunks/3507-14fb4e6cd377d7da.js | 1 + ...836f09d94a0.js => 353-e55516ea4730f9d4.js} | 0 .../static/chunks/3554-f22a2e21673afd42.js | 1 - .../static/chunks/3567-9a29feedd7b63950.js | 5 + .../static/chunks/3634-5083d080185955ff.js | 1 - ...c8a6221d7f.js => 3709-34dbb332d3a3ac26.js} | 0 .../static/chunks/3862-064a3fb795c75b62.js | 1 + .../static/chunks/3898-fc3dbf5a964ea4ca.js | 1 - .../static/chunks/3918-942eadaf4103218b.js | 1 - ...2983f3aa2b.js => 4077-50cf2a28a79fdcd4.js} | 0 .../static/chunks/4105-9c3c0ee7c494102f.js | 1 + .../static/chunks/4306-f891b96cf0ee333b.js | 1 + .../static/chunks/4388-2f4ca3419d20af67.js | 1 + .../static/chunks/4470-3ef8ade20eaf2875.js | 1 + .../static/chunks/4509-5bbcd014724651a9.js | 1 - .../static/chunks/4559-52ca85b2d8893149.js | 1 + .../static/chunks/4750-3aeac3fa94708e1c.js | 1 - .../static/chunks/4817-59d642defb0e86f2.js | 1 + .../static/chunks/4851-0dc9f6cfeabb43d0.js | 1 - .../static/chunks/4891-a6a8811399a4a3df.js | 1 - .../static/chunks/4951-59d280e876cbbf1f.js | 1 - .../static/chunks/5105-2998cbe1c9fc8ee4.js | 1 + .../static/chunks/5105-ea8985e1ca9e840a.js | 1 - .../static/chunks/5144-bbc18c43eade9aef.js | 1 + .../static/chunks/5144-ddfa7a8f89c5d465.js | 1 - .../static/chunks/5202-60292daf4bc5c8fb.js | 1 + .../static/chunks/5238-3fa69435be59fb79.js | 1 - .../static/chunks/5276-8bb0b1938bb0f21f.js | 1 - ...7ef011d5c9.js => 5319-5b2d4bf2dc450f99.js} | 0 .../static/chunks/5333-1540faf81c7d7006.js | 1 + .../static/chunks/5518-0926d5b7250ad191.js | 1 - .../static/chunks/5695-dbbcbf2da21d2bab.js | 1 + .../static/chunks/5706-1e314cef9ea5c5d6.js | 1 + .../static/chunks/5706-b92e3cca4b167e71.js | 1 - .../static/chunks/5733-6e7eac59c8bc246c.js | 1 - .../static/chunks/5733-aa80f52062105ad2.js | 1 + .../static/chunks/5752-f504fb38ff5e13e8.js | 1 + .../static/chunks/5767-b9e6413b33909bd8.js | 1 - ...13b1b23ec5.js => 5869-426268ba6ad0ce0c.js} | 2 +- ...bcb1abfaaf.js => 5945-8b3b7713d7f416a2.js} | 0 .../static/chunks/5975-60599e8984464729.js | 1 - .../static/chunks/5975-758334d6641b9c63.js | 1 + .../static/chunks/5992-243bba762148af9b.js | 1 - .../static/chunks/5992-287cec06808c74ae.js | 1 + .../static/chunks/605-102c0e6d8bb7517c.js | 1 + .../static/chunks/6213-20bb5f06094f361d.js | 1 - .../static/chunks/6266-e38c5801183e9c17.js | 1 - .../static/chunks/6276-841bc8541051bc36.js | 1 - .../static/chunks/6285-68f82c874b184eba.js | 1 + ...275286c0df.js => 6399-ccf9cdbdcd5f7abb.js} | 2 +- .../static/chunks/6537-f70f2c4278e93458.js | 1 + .../static/chunks/6554-265013ca56622e1f.js | 1 - ...439e75d3a3.js => 6600-0ec5e2dc66d8b41a.js} | 2 +- .../static/chunks/6609-3e081758ffbe3786.js | 1 + .../static/chunks/6609-707213b617f85369.js | 1 - .../static/chunks/665-05a55da381817c0d.js | 1 - .../static/chunks/665-d94073042ee5b874.js | 1 + .../static/chunks/6653-e61fdc06093fc0a8.js | 1 + .../static/chunks/6868-c5f994b9d687f7b6.js | 1 - .../static/chunks/6891-4d6d997a2bca3514.js | 1 - ...fd596f74e8.js => 7138-5b134dc8ad670770.js} | 2 +- .../static/chunks/7451-a657252554fd3e24.js | 1 - .../static/chunks/7471-f852accc26f14f8c.js | 1 - .../static/chunks/7526-da6b2857a3ca248d.js | 1 + .../static/chunks/7526-e76a2c2b549bf2d2.js | 1 - .../static/chunks/7572-64b63fb5f5a45de2.js | 1 - .../static/chunks/766-baf0336e8ba5c686.js | 1 + .../static/chunks/7688-ca173ea41812cf94.js | 1 + .../static/chunks/7851-c10cbe6fcac2f9d6.js | 1 + ...8da2773bb2.js => 7906-59ba450db59c8efa.js} | 2 +- .../static/chunks/7914-25af99af34bee64b.js | 1 - .../static/chunks/7926-108623e14caeb770.js | 1 + .../static/chunks/7967-1ac5097c3d83016f.js | 1 - .../static/chunks/7971-76912e9c9a840367.js | 1 - .../static/chunks/8014-d6138fce46bba1e2.js | 1 + .../static/chunks/8049-cb52b16664f13e28.js | 1 + .../static/chunks/8049-e2c66b7a50d69b89.js | 1 - .../static/chunks/8135-881fe2cea0032570.js | 1 + ...f553d5fa4b.js => 8143-9e4312f059e9ed27.js} | 2 +- ...4bbf6b36a05.js => 816-37c57b39f4e7ece1.js} | 2 +- .../static/chunks/8184-2b143f8083048e52.js | 1 - .../static/chunks/8205-66bf13815010afdb.js | 5 - .../static/chunks/8358-0821a1ee08903103.js | 1 - .../static/chunks/8437-d1298f5313ff07fa.js | 1 - .../static/chunks/8473-7749355a9a4b1818.js | 1 + .../static/chunks/8529-6b66d5dba2148164.js | 1 + .../static/chunks/8565-5c05f6bbb9d0662f.js | 1 + .../static/chunks/8582-3a775364dbf07fa8.js | 1 + ...023f636492.js => 9028-2bfc9f09930a0d61.js} | 2 +- .../static/chunks/9028-d6bbee9a46c36af2.js | 1 - .../static/chunks/9039-2037889778daf211.js | 1 - .../static/chunks/9039-e44ff08ca4f37a12.js | 1 + .../static/chunks/9120-dc2d8129a3d2175b.js | 1 - .../static/chunks/9140-09af618948244b82.js | 1 + .../static/chunks/9145-9507437d5b599cea.js | 1 + .../static/chunks/9264-e3d8a8136b3fe80a.js | 1 - .../static/chunks/9264-fd8ab51d702e9535.js | 1 + .../static/chunks/9409-6eefc92a7f8433ff.js | 1 + .../static/chunks/9409-b5ab5f84c55f5e0f.js | 1 - .../static/chunks/9584-4d5bef7e60cfea45.js | 1 - .../static/chunks/9584-9d4fd7b3d6a7c9e7.js | 1 + .../static/chunks/9682-099cae97c99cd9b0.js | 1 - .../static/chunks/9818-6f03d7efd4fb8533.js | 1 + .../static/chunks/9841-721a173be76941d1.js | 1 + .../static/chunks/9967-329bb618cc1c8902.js | 1 - ...9e352b9570.js => page-a6a3e9e67b671303.js} | 2 +- .../api-playground/page-67c4f150eba92e64.js | 1 + .../api-playground/page-da46af8c74d0ccba.js | 1 - .../budgets/page-9862f852f653749a.js | 1 - .../budgets/page-e471b9b73cfc894b.js | 1 + .../caching/page-d31cc105402ab7e0.js | 1 + .../caching/page-f9ab4bd9b8938219.js | 1 - .../page-dadb6b98d2bf3122.js | 1 - .../old-usage/page-1599bddd1bf7a448.js | 1 - .../old-usage/page-5e097dbb8ce40bb4.js | 1 + .../prompts/page-8236f1efda3366f0.js | 1 + .../prompts/page-c1b2f89fce632eb9.js | 1 - .../tag-management/page-38b1e2925ef4d78c.js | 1 - .../tag-management/page-5627fd94813402eb.js | 1 + .../guardrails/page-060e61cb783d32ef.js | 1 + .../guardrails/page-6fcfd67591571b0f.js | 1 - .../(dashboard)/layout-ee00b63098f63896.js | 1 - .../(dashboard)/layout-f7f722423efd1c5b.js | 1 + ...2bfde568ab.js => page-5a10d46ca991b83e.js} | 2 +- .../model-hub/page-0802bc3228446009.js | 1 - .../model-hub/page-1479dcb217587498.js | 1 + .../page-b69988590beaa5c8.js | 1 + .../page-e9561bb2dd6ebb7b.js | 1 - .../organizations/page-56a03e123f452d60.js | 1 + .../organizations/page-bb7939b01e416574.js | 1 - .../playground/page-80b8f3245f6936d1.js | 1 - .../playground/page-fc3dff494dc4db08.js | 1 + .../policies/page-33090e865d27d3fa.js | 1 - .../admin-settings/page-746658933a633902.js | 1 + .../admin-settings/page-d54333a842352184.js | 1 - .../page-e3df74ef5ac0dcd5.js | 1 + .../page-e83525d261d7c7f9.js | 1 - .../router-settings/page-46ff6edf1109f13d.js | 1 - .../router-settings/page-ffa3245ebcbbc02a.js | 1 + .../ui-theme/page-b0efda16443e630f.js | 1 - .../ui-theme/page-d833946961b065a5.js | 1 + .../teams/page-49b94da614a653ba.js | 1 - .../teams/page-8d1a71afa9e9ff16.js | 1 + .../test-key/page-63cd64b722408984.js | 1 + .../test-key/page-afaa514ad2d69fe0.js | 1 - .../mcp-servers/page-59e552ea419ac5b6.js | 1 - .../mcp-servers/page-7dd2ea6f1433d41f.js | 1 + .../vector-stores/page-0f618cc2d6cae794.js | 1 + .../vector-stores/page-414136a92d1a02e9.js | 1 - ...f48fc11bd9.js => page-d7532f354d44803b.js} | 2 +- .../users/page-0ba6bd2b4262da93.js | 1 - .../users/page-6d3643cef6c068ee.js | 1 + ...040440802a.js => page-73444bcb0cfe86b7.js} | 2 +- ...9372d51712.js => page-61bfa80619b62f6b.js} | 2 +- ...7c1a6e991f.js => page-92347d2021ca8580.js} | 2 +- .../model_hub_table/page-2ad344049541235f.js | 1 + .../model_hub_table/page-516d7511795e23d9.js | 1 - ...336329736d.js => page-17ecf5bf068f8157.js} | 2 +- .../chunks/app/page-587b0acf34f8c747.js | 1 + .../chunks/app/page-682f895ca508b763.js | 1 - ...0ac20e4399.js => main-e4e168e4dfadea03.js} | 2 +- .../out/_next/static/css/83c095d0528a2e35.css | 3 + .../out/_next/static/css/9a035dba96de4cd5.css | 3 - .../_buildManifest.js | 0 .../_ssgManifest.js | 0 .../_experimental/out/api-reference.html | 1 - .../proxy/_experimental/out/api-reference.txt | 6 +- .../out/api-reference/index.html | 1 + .../out/assets/logos/s3_vector.png | Bin 191076 -> 0 bytes .../out/experimental/api-playground.txt | 6 +- .../index.html} | 2 +- .../out/experimental/budgets.html | 1 - .../out/experimental/budgets.txt | 6 +- .../out/experimental/budgets/index.html | 1 + .../out/experimental/caching.html | 1 - .../out/experimental/caching.txt | 6 +- .../out/experimental/caching/index.html | 1 + .../out/experimental/claude-code-plugins.html | 1 - .../out/experimental/claude-code-plugins.txt | 13 - .../out/experimental/old-usage.html | 1 - .../out/experimental/old-usage.txt | 6 +- .../index.html} | 2 +- .../out/experimental/prompts.txt | 6 +- .../out/experimental/prompts/index.html | 1 + .../out/experimental/tag-management.txt | 6 +- .../experimental/tag-management/index.html | 1 + .../proxy/_experimental/out/guardrails.html | 1 - .../proxy/_experimental/out/guardrails.txt | 6 +- litellm/proxy/_experimental/out/index.html | 2 +- litellm/proxy/_experimental/out/index.txt | 4 +- litellm/proxy/_experimental/out/login.txt | 4 +- .../out/{login.html => login/index.html} | 2 +- litellm/proxy/_experimental/out/logs.txt | 6 +- .../out/{logs.html => logs/index.html} | 2 +- .../_experimental/out/mcp/oauth/callback.txt | 2 +- .../{callback.html => callback/index.html} | 2 +- .../proxy/_experimental/out/model-hub.html | 1 - litellm/proxy/_experimental/out/model-hub.txt | 6 +- .../_experimental/out/model-hub/index.html | 1 + .../proxy/_experimental/out/model_hub.html | 1 - litellm/proxy/_experimental/out/model_hub.txt | 4 +- .../_experimental/out/model_hub_table.html | 1 - .../_experimental/out/model_hub_table.txt | 4 +- .../out/model_hub_table/index.html | 1 + .../out/models-and-endpoints.html | 1 - .../out/models-and-endpoints.txt | 6 +- .../index.html} | 2 +- .../proxy/_experimental/out/onboarding.html | 1 - .../proxy/_experimental/out/onboarding.txt | 4 +- .../_experimental/out/organizations.html | 1 - .../proxy/_experimental/out/organizations.txt | 6 +- .../out/organizations/index.html | 1 + .../proxy/_experimental/out/playground.html | 1 - .../proxy/_experimental/out/playground.txt | 6 +- .../_experimental/out/playground/index.html | 1 + litellm/proxy/_experimental/out/policies.html | 1 - litellm/proxy/_experimental/out/policies.txt | 13 - .../out/settings/admin-settings.html | 1 - .../out/settings/admin-settings.txt | 6 +- .../out/settings/admin-settings/index.html | 1 + .../out/settings/logging-and-alerts.txt | 6 +- .../index.html} | 2 +- .../out/settings/router-settings.txt | 6 +- .../index.html} | 2 +- .../_experimental/out/settings/ui-theme.txt | 6 +- .../{ui-theme.html => ui-theme/index.html} | 2 +- litellm/proxy/_experimental/out/teams.html | 1 - litellm/proxy/_experimental/out/teams.txt | 6 +- .../proxy/_experimental/out/teams/index.html | 1 + litellm/proxy/_experimental/out/test-key.html | 1 - litellm/proxy/_experimental/out/test-key.txt | 6 +- .../_experimental/out/test-key/index.html | 1 + .../_experimental/out/tools/mcp-servers.txt | 6 +- .../out/tools/mcp-servers/index.html | 1 + .../out/tools/vector-stores.html | 1 - .../_experimental/out/tools/vector-stores.txt | 6 +- .../out/tools/vector-stores/index.html | 1 + litellm/proxy/_experimental/out/usage.html | 1 - litellm/proxy/_experimental/out/usage.txt | 6 +- .../prompts.html => usage/index.html} | 2 +- litellm/proxy/_experimental/out/users.txt | 6 +- .../out/{users.html => users/index.html} | 2 +- .../proxy/_experimental/out/virtual-keys.html | 1 - .../proxy/_experimental/out/virtual-keys.txt | 6 +- .../_experimental/out/virtual-keys/index.html | 1 + litellm/proxy/_types.py | 34 +- .../proxy/agent_endpoints/a2a_endpoints.py | 9 - litellm/proxy/auth/auth_checks.py | 16 +- litellm/proxy/auth/auth_utils.py | 20 +- litellm/proxy/auth/route_checks.py | 10 +- litellm/proxy/batches_endpoints/endpoints.py | 22 +- litellm/proxy/client/cli/commands/auth.py | 245 ++- litellm/proxy/common_request_processing.py | 12 +- litellm/proxy/common_utils/callback_utils.py | 45 +- litellm/proxy/google_endpoints/endpoints.py | 2 +- .../litellm_content_filter/content_filter.py | 176 +- .../litellm_content_filter/patterns.json | 12 +- .../guardrails/guardrail_hooks/onyx/onyx.py | 7 +- .../guardrails/guardrail_hooks/presidio.py | 145 +- litellm/proxy/litellm_pre_call_utils.py | 65 +- .../internal_user_endpoints.py | 4 +- .../key_management_endpoints.py | 373 ---- .../mcp_management_endpoints.py | 18 +- .../management_endpoints/team_endpoints.py | 140 +- litellm/proxy/management_endpoints/ui_sso.py | 38 +- .../llm_passthrough_endpoints.py | 124 +- litellm/proxy/proxy_cli.py | 5 +- litellm/proxy/proxy_server.py | 814 +------- litellm/proxy/rag_endpoints/endpoints.py | 210 --- .../proxy/response_api_endpoints/endpoints.py | 2 - .../proxy/response_polling/polling_handler.py | 12 +- litellm/proxy/route_llm_request.py | 11 +- litellm/proxy/schema.prisma | 6 - litellm/proxy/search_endpoints/endpoints.py | 82 +- .../spend_management_endpoints.py | 9 - .../spend_tracking/spend_tracking_utils.py | 17 +- .../proxy_setting_endpoints.py | 6 - litellm/proxy/utils.py | 51 +- .../proxy/vector_store_endpoints/endpoints.py | 53 +- .../management_endpoints.py | 271 +-- litellm/rag/ingestion/base_ingestion.py | 17 +- .../rag/ingestion/file_parsers/__init__.py | 9 - .../rag/ingestion/file_parsers/pdf_parser.py | 70 - litellm/rag/ingestion/s3_vectors_ingestion.py | 573 ------ litellm/rag/main.py | 2 - .../transformation.py | 4 - litellm/responses/main.py | 10 - litellm/router.py | 205 +- litellm/router_utils/get_retry_from_policy.py | 10 +- litellm/router_utils/search_api_router.py | 3 +- litellm/secret_managers/main.py | 20 +- litellm/types/guardrails.py | 25 +- .../integrations/datadog_cost_management.py | 27 - litellm/types/integrations/prometheus.py | 100 - litellm/types/llms/bedrock.py | 85 - litellm/types/llms/oci.py | 9 +- litellm/types/llms/openai.py | 6 +- litellm/types/llms/xai.py | 23 - .../proxy/guardrails/guardrail_hooks/onyx.py | 5 - .../key_management_endpoints.py | 42 - litellm/types/rag.py | 46 +- litellm/types/router.py | 4 - litellm/types/utils.py | 28 +- litellm/types/vector_stores.py | 4 - litellm/utils.py | 21 +- model_prices_and_context_window.json | 231 +-- poetry.lock | 72 +- proxy_config.yaml | 101 + pyproject.toml | 11 +- requirements.txt | 5 +- schema.prisma | 5 - tests/code_coverage_tests/liccheck.ini | 1 - tests/code_coverage_tests/license_cache.json | 2 +- .../router_code_coverage.py | 4 +- .../test_prometheus_logging_callbacks.py | 14 +- .../integrations/test_prometheus.py | 118 -- .../proxy/auth/test_route_checks.py | 65 - .../proxy/hooks/test_managed_files.py | 259 --- tests/guardrails_tests/test_lakera_v2.py | 74 +- .../test_litellm_proxy_extras_utils.py | 5 - .../oci/chat/test_oci_chat_transformation.py | 37 +- .../mcp_server/test_discoverable_endpoints.py | 1108 ----------- .../test_bedrock_completion.py | 285 --- tests/llm_translation/test_gigachat.py | 108 +- tests/llm_translation/test_groq.py | 126 +- tests/llm_translation/test_xai.py | 4 - tests/local_testing/test_add_update_models.py | 2 - .../test_amazing_vertex_completion.py | 21 +- tests/local_testing/test_auth_utils.py | 19 - .../test_completion_with_retries.py | 1 - tests/local_testing/test_literalai.py | 72 + tests/local_testing/test_timeout.py | 91 + .../mcp_tests/test_aresponses_api_with_mcp.py | 6 +- tests/mcp_tests/test_mcp_client_unit.py | 4 +- tests/mcp_tests/test_mcp_server.py | 21 +- .../test_anthropic_messages_tool_search.py | 20 +- .../test_key_management.py | 56 +- tests/proxy_unit_tests/test_auth_checks.py | 4 +- tests/proxy_unit_tests/test_get_image.py | 89 - tests/proxy_unit_tests/test_proxy_server.py | 18 +- .../test_response_polling_handler.py | 136 -- .../proxy_unit_tests/test_server_root_path.py | 64 - .../test_router_helper_utils.py | 29 - .../a2a_protocol/test_card_resolver.py | 69 - .../containers/test_container_api.py | 39 +- .../containers/test_container_integration.py | 24 +- .../send_emails/test_resend_email.py | 88 +- .../send_emails/test_sendgrid_email.py | 51 +- .../test_mcp_client.py | 72 +- .../google_genai/test_google_genai_adapter.py | 4 +- .../google_genai/test_google_genai_handler.py | 23 +- .../integrations/arize/test_arize_utils.py | 21 +- .../datadog/test_datadog_cost_management.py | 169 -- .../datadog/test_datadog_llm_obs_agent.py | 62 - .../test_custom_guardrail_recursion.py | 73 - .../test_prometheus_client_ip_user_agent.py | 203 -- .../integrations/test_prometheus_labels.py | 164 +- .../test_prometheus_missing_metrics.py | 77 - ...llm_core_utils_prompt_templates_factory.py | 83 +- .../litellm_core_utils/test_image_handling.py | 79 - .../test_litellm_logging.py | 2 - .../test_anthropic_chat_transformation.py | 55 +- ...al_pass_through_adapters_transformation.py | 306 --- .../chat/test_azure_gpt5_transformation.py | 11 - ...ations_anthropic_claude3_transformation.py | 290 --- .../bedrock/test_anthropic_beta_support.py | 100 - .../test_hosted_vllm_chat_transformation.py | 47 - .../llms/openai/test_gpt5_transformation.py | 17 - .../test_litellm/llms/s3_vectors/__init__.py | 1 - .../llms/s3_vectors/vector_stores/__init__.py | 1 - .../test_s3_vectors_transformation.py | 115 -- .../llms/test_cache_control_and_reasoning.py | 281 --- .../vercel_ai_gateway/embedding/__init__.py | 0 .../test_vercel_ai_gateway_embedding.py | 218 --- .../vertex_ai/test_vertex_ai_common_utils.py | 30 - .../test_xai_responses_transformation.py | 213 +-- .../mcp_server/test_mcp_server_manager.py | 2 +- .../proxy/auth/test_auth_checks.py | 117 +- .../proxy/auth/test_auth_utils.py | 23 - .../test_litellm/proxy/auth/test_cli_auth.py | 203 -- .../proxy/auth/test_route_checks.py | 4 - .../test_interactions_agent_param.py | 75 - .../content_filter/test_content_filter.py | 84 +- .../guardrails/guardrail_hooks/test_onyx.py | 302 +-- .../guardrail_hooks/test_presidio.py | 141 +- ...st_post_call_streaming_hook_integration.py | 273 --- ...test_post_call_success_hook_integration.py | 260 --- .../test_internal_user_endpoints.py | 54 - .../test_key_management_endpoints.py | 467 ----- .../test_team_endpoints.py | 214 --- .../proxy/management_endpoints/test_ui_sso.py | 80 - .../test_vertex_passthrough_load_balancing.py | 72 - .../test_spend_management_endpoints.py | 83 - .../test_spend_tracking_utils.py | 46 - .../proxy/test_litellm_pre_call_utils.py | 47 - tests/test_litellm/proxy/test_proxy_cli.py | 7 +- tests/test_litellm/proxy/test_proxy_server.py | 1645 ++--------------- .../proxy/test_route_llm_request.py | 82 +- .../test_vector_store_access_control.py | 87 - .../responses/test_responses_utils.py | 43 - .../test_secret_managers_main.py | 69 +- tests/test_litellm/test_cost_calculator.py | 345 +--- .../test_litellm/test_eager_tiktoken_load.py | 29 - .../test_gpt_image_cost_calculator.py | 68 - tests/test_litellm/test_main.py | 32 +- .../test_responses_api_bridge_non_stream.py | 380 +--- .../test_router_per_deployment_num_retries.py | 57 +- .../test_router_silent_experiment.py | 157 -- tests/test_litellm/test_video_generation.py | 86 +- .../test_vector_store_registry.py | 16 +- tests/test_otel_thread_leak.py | 90 - tests/test_presidio_latency.py | 73 - tests/test_team.py | 1 - .../rag/test_rag_s3_vectors.py | 107 -- .../test_s3_vectors_vector_store.py | 42 - ui/litellm-dashboard/package.json | 1 - .../public/assets/logos/s3_vector.png | Bin 191076 -> 0 bytes .../components/SidebarProvider.tsx | 44 +- .../hooks/models/useModels.test.ts | 14 +- .../app/(dashboard)/hooks/models/useModels.ts | 9 +- .../useStoreRequestInSpendLogs.ts | 63 - .../(dashboard)/hooks/useAuthorized.test.ts | 61 +- .../app/(dashboard)/hooks/useAuthorized.ts | 16 +- .../hooks/useDisableShowPrompts.ts | 35 - .../src/app/(dashboard)/layout.tsx | 4 +- .../ModelsAndEndpointsView.tsx | 1 + .../components/AllModelsTab.test.tsx | 22 +- .../components/AllModelsTab.tsx | 162 +- .../src/app/(dashboard)/policies/page.tsx | 20 + .../components/modals/CreateTeamModal.tsx | 48 +- ui/litellm-dashboard/src/app/globals.css | 28 + ui/litellm-dashboard/src/app/page.tsx | 431 +++-- .../src/components/BulkEditUsers.test.tsx | 343 ---- .../EntityUsageExport/ExportTypeSelector.tsx | 10 +- .../src/components/EntityUsageExport/types.ts | 2 +- .../EntityUsageExport/utils.test.ts | 560 ------ .../src/components/EntityUsageExport/utils.ts | 91 - .../ModelSelect/ModelSelect.test.tsx | 4 +- .../components/ModelSelect/ModelSelect.tsx | 12 +- .../src/components/OldTeams.tsx | 37 - .../UISettings/PageVisibilitySettings.tsx | 146 -- .../AdminSettings/UISettings/UISettings.tsx | 25 +- .../Fallbacks/Fallbacks.test.tsx | 6 +- .../VirtualKeysPage/VirtualKeysTable.test.tsx | 89 +- .../VirtualKeysPage/VirtualKeysTable.tsx | 75 +- .../{BulkEditUsers.tsx => bulk_edit_user.tsx} | 10 +- .../KeyLifecycleSettings.test.tsx | 383 ---- .../KeyLifecycleSettings.tsx | 12 +- .../RouterSettingsAccordion.tsx | 373 ---- .../TableHeaderSortDropdown.test.tsx | 148 -- .../TableHeaderSortDropdown.tsx | 85 - .../guardrails/guardrail_info.test.tsx | 119 -- .../components/guardrails/guardrail_info.tsx | 18 +- .../src/components/leftnav.tsx | 115 +- .../model_dashboard/all_models_table.tsx | 204 -- .../src/components/model_info_view.test.tsx | 302 +-- .../src/components/model_info_view.tsx | 119 +- .../src/components/molecules/filter.test.tsx | 127 -- .../src/components/molecules/filter.tsx | 1 - .../components/molecules/models/columns.tsx | 525 +++--- .../src/components/navbar.test.tsx | 15 - .../src/components/navbar.tsx | 41 +- .../src/components/networking.tsx | 165 +- .../organisms/create_key_button.tsx | 91 +- .../organization/organization_view.tsx | 36 +- .../src/components/page_metadata.ts | 44 - .../src/components/page_utils.test.ts | 241 --- .../src/components/page_utils.ts | 75 - .../playground/chat_ui/CodeSnippets.test.tsx | 3 +- .../playground/compareUI/CompareUI.tsx | 1 - .../llm_calls/chat_completion.test.tsx | 4 +- .../llm_calls/responses_api.test.tsx | 29 +- .../policies/add_attachment_form.tsx | 48 +- .../components/policies/add_policy_form.tsx | 40 +- .../src/components/policies/index.tsx | 73 +- .../src/components/policies/policy_info.tsx | 8 +- .../src/components/public_model_hub.tsx | 4 - .../ReliabilityRetriesSection.tsx | 8 +- .../router_settings/RouterSettingsForm.tsx | 84 - .../src/components/router_settings/index.tsx | 88 +- .../components/survey/NudgePrompt.test.tsx | 101 - .../src/components/survey/NudgePrompt.tsx | 73 +- .../src/components/team/team_info.tsx | 130 -- .../components/templates/key_edit_view.tsx | 23 - .../components/templates/key_info_view.tsx | 89 +- .../components/templates/model_dashboard.tsx | 25 +- .../CreateVectorStore.test.tsx | 276 --- .../CreateVectorStore.tsx | 434 ----- .../DocumentsTable.test.tsx | 102 - .../DocumentsTable.tsx | 98 - .../S3VectorsConfig.test.tsx | 203 -- .../S3VectorsConfig.tsx | 192 -- .../TestVectorStoreTab.test.tsx | 90 - .../TestVectorStoreTab.tsx | 75 - .../VectorStoreTable.test.tsx | 12 +- .../VectorStoreTable.tsx | 26 - .../vector_store_management/index.tsx | 58 +- .../vector_store_management/types.tsx | 45 +- .../src/components/vector_store_providers.tsx | 37 - .../SpendLogsSettingsModal.test.tsx | 348 ---- .../SpendLogsSettingsModal.tsx | 100 - .../src/components/view_logs/index.tsx | 22 +- .../components/view_logs/log_filter_logic.tsx | 6 +- .../src/components/view_users.tsx | 6 +- ui/litellm-dashboard/vitest.config.ts | 1 - 649 files changed, 3648 insertions(+), 27300 deletions(-) delete mode 100644 .github/workflows/test-model-map.yaml delete mode 100644 docs/my-website/docs/providers/sarvam.md delete mode 100644 docs/my-website/docs/proxy/keys_teams_router_settings.md delete mode 100644 docs/my-website/docs/proxy/ui/page_visibility.md delete mode 100644 docs/my-website/docs/traffic_mirroring.md delete mode 100644 docs/my-website/img/ui_granular_router_settings.png delete mode 100644 docs/my-website/release_notes/v1.81.3-stable/index.md delete mode 100644 litellm-proxy-extras/dist/litellm_proxy_extras-0.4.27-py3-none-any.whl delete mode 100644 litellm-proxy-extras/dist/litellm_proxy_extras-0.4.27.tar.gz delete mode 100644 litellm/a2a_protocol/card_resolver.py delete mode 100644 litellm/integrations/datadog/datadog_cost_management.py delete mode 100644 litellm/llms/s3_vectors/__init__.py delete mode 100644 litellm/llms/s3_vectors/vector_stores/__init__.py delete mode 100644 litellm/llms/s3_vectors/vector_stores/transformation.py delete mode 100644 litellm/llms/vercel_ai_gateway/embedding/__init__.py delete mode 100644 litellm/llms/vercel_ai_gateway/embedding/transformation.py delete mode 100644 litellm/proxy/_experimental/out/404.html delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1098-a1702da59647cf14.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1098-c3e95c9684ff5e95.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1108-8b678b0704cb239b.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1108-c2d0c742b6e72436.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1112-0b9bd4ebde18e77b.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1128-64fa4a41ccaf67ea.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1132-d0fa0c9565944e8f.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1176-9175d7684b344026.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/137-c6f74fedf576a11b.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1414-2770d1155b664522.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1442-024f7e51804e0d7e.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1658-2c9554a5b3840812.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1716-1c0ba935a144e6ff.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1717-bb1b888f6ccc52d6.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1789-a56ee544e60cd01d.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1901-4d02d1f2a71cdbf7.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1994-6637a121c9ee1602.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2-253aec8d55c7bb6f.js rename litellm/proxy/_experimental/out/_next/static/chunks/{6894-8c74216e23aa271e.js => 2068-2c78bfc32dc0de5f.js} (89%) create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2136-2c0d6e8c18d2c5c4.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2172-c97c9e958a9c36e3.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2202-a83ad035a17401aa.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2227-5ae3f36b0a81c5b4.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2318-b8f043257a4eca15.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2344-905d7ecc9d0c6724.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2353-c94748c0aac514ff.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2378-252212b7a5e313ce.js rename litellm/proxy/_experimental/out/_next/static/chunks/{2409-43d87f56841bda3f.js => 2409-e94c05c6f11bb939.js} (100%) create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2500-811f2612ec5f6830.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2652-55de14f9e14b1064.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2699-38ff37315d78ae04.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2731-b2ffcaeb9eabaa23.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2820-592c2b4ff874a913.js rename litellm/proxy/_experimental/out/_next/static/chunks/{2901-b2d9f739800f0159.js => 2901-0cdd0656eb7463d6.js} (100%) delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/292-7bd148a17bc0a05b.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/292-aaba6c4e7c8d416d.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2926-a9cb83e61fc8ad20.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2926-ac542d9fa707b8a4.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3178-47bc3b9e8cf9bf6c.js rename litellm/proxy/_experimental/out/_next/static/chunks/{3242-663d3264e87271d0.js => 3242-6e6ec7e18f5d698d.js} (100%) rename litellm/proxy/_experimental/out/_next/static/chunks/{3367-33bb84b3d3d247b2.js => 3367-58830187e9e5b9fa.js} (98%) rename litellm/proxy/_experimental/out/_next/static/chunks/{337-929caaa1bd1d68cc.js => 337-bb33d149e9f461b3.js} (100%) create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3507-14fb4e6cd377d7da.js rename litellm/proxy/_experimental/out/_next/static/chunks/{353-347e4836f09d94a0.js => 353-e55516ea4730f9d4.js} (100%) delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3554-f22a2e21673afd42.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3567-9a29feedd7b63950.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3634-5083d080185955ff.js rename litellm/proxy/_experimental/out/_next/static/chunks/{3709-7f9257c8a6221d7f.js => 3709-34dbb332d3a3ac26.js} (100%) create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3862-064a3fb795c75b62.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3898-fc3dbf5a964ea4ca.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3918-942eadaf4103218b.js rename litellm/proxy/_experimental/out/_next/static/chunks/{4077-c4828a2983f3aa2b.js => 4077-50cf2a28a79fdcd4.js} (100%) create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/4105-9c3c0ee7c494102f.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/4306-f891b96cf0ee333b.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/4388-2f4ca3419d20af67.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/4470-3ef8ade20eaf2875.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/4509-5bbcd014724651a9.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/4559-52ca85b2d8893149.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/4750-3aeac3fa94708e1c.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/4817-59d642defb0e86f2.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/4851-0dc9f6cfeabb43d0.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/4891-a6a8811399a4a3df.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/4951-59d280e876cbbf1f.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5105-2998cbe1c9fc8ee4.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5105-ea8985e1ca9e840a.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5144-bbc18c43eade9aef.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5144-ddfa7a8f89c5d465.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5202-60292daf4bc5c8fb.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5238-3fa69435be59fb79.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5276-8bb0b1938bb0f21f.js rename litellm/proxy/_experimental/out/_next/static/chunks/{5319-7f07d87ef011d5c9.js => 5319-5b2d4bf2dc450f99.js} (100%) create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5333-1540faf81c7d7006.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5518-0926d5b7250ad191.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5695-dbbcbf2da21d2bab.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5706-1e314cef9ea5c5d6.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5706-b92e3cca4b167e71.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5733-6e7eac59c8bc246c.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5733-aa80f52062105ad2.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5752-f504fb38ff5e13e8.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5767-b9e6413b33909bd8.js rename litellm/proxy/_experimental/out/_next/static/chunks/{5869-aa0b3213b1b23ec5.js => 5869-426268ba6ad0ce0c.js} (99%) rename litellm/proxy/_experimental/out/_next/static/chunks/{5945-93803bbcb1abfaaf.js => 5945-8b3b7713d7f416a2.js} (100%) delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5975-60599e8984464729.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5975-758334d6641b9c63.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5992-243bba762148af9b.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/5992-287cec06808c74ae.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/605-102c0e6d8bb7517c.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/6213-20bb5f06094f361d.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/6266-e38c5801183e9c17.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/6276-841bc8541051bc36.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/6285-68f82c874b184eba.js rename litellm/proxy/_experimental/out/_next/static/chunks/{6399-9e22a1275286c0df.js => 6399-ccf9cdbdcd5f7abb.js} (65%) create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/6537-f70f2c4278e93458.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/6554-265013ca56622e1f.js rename litellm/proxy/_experimental/out/_next/static/chunks/{6600-077d81439e75d3a3.js => 6600-0ec5e2dc66d8b41a.js} (99%) create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/6609-3e081758ffbe3786.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/6609-707213b617f85369.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/665-05a55da381817c0d.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/665-d94073042ee5b874.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/6653-e61fdc06093fc0a8.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/6868-c5f994b9d687f7b6.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/6891-4d6d997a2bca3514.js rename litellm/proxy/_experimental/out/_next/static/chunks/{3705-dde102fd596f74e8.js => 7138-5b134dc8ad670770.js} (79%) delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/7451-a657252554fd3e24.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/7471-f852accc26f14f8c.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/7526-da6b2857a3ca248d.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/7526-e76a2c2b549bf2d2.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/7572-64b63fb5f5a45de2.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/766-baf0336e8ba5c686.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/7688-ca173ea41812cf94.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/7851-c10cbe6fcac2f9d6.js rename litellm/proxy/_experimental/out/_next/static/chunks/{7906-1b1cdd8da2773bb2.js => 7906-59ba450db59c8efa.js} (99%) delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/7914-25af99af34bee64b.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/7926-108623e14caeb770.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/7967-1ac5097c3d83016f.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/7971-76912e9c9a840367.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/8014-d6138fce46bba1e2.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/8049-cb52b16664f13e28.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/8049-e2c66b7a50d69b89.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/8135-881fe2cea0032570.js rename litellm/proxy/_experimental/out/_next/static/chunks/{8143-774574f553d5fa4b.js => 8143-9e4312f059e9ed27.js} (99%) rename litellm/proxy/_experimental/out/_next/static/chunks/{816-924f34bbf6b36a05.js => 816-37c57b39f4e7ece1.js} (99%) delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/8184-2b143f8083048e52.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/8205-66bf13815010afdb.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/8358-0821a1ee08903103.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/8437-d1298f5313ff07fa.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/8473-7749355a9a4b1818.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/8529-6b66d5dba2148164.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/8565-5c05f6bbb9d0662f.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/8582-3a775364dbf07fa8.js rename litellm/proxy/_experimental/out/_next/static/chunks/{1954-82e3a4023f636492.js => 9028-2bfc9f09930a0d61.js} (99%) delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/9028-d6bbee9a46c36af2.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/9039-2037889778daf211.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/9039-e44ff08ca4f37a12.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/9120-dc2d8129a3d2175b.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/9140-09af618948244b82.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/9145-9507437d5b599cea.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/9264-e3d8a8136b3fe80a.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/9264-fd8ab51d702e9535.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/9409-6eefc92a7f8433ff.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/9409-b5ab5f84c55f5e0f.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/9584-4d5bef7e60cfea45.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/9584-9d4fd7b3d6a7c9e7.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/9682-099cae97c99cd9b0.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/9818-6f03d7efd4fb8533.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/9841-721a173be76941d1.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/9967-329bb618cc1c8902.js rename litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/api-reference/{page-cc0fe29e352b9570.js => page-a6a3e9e67b671303.js} (99%) create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/experimental/api-playground/page-67c4f150eba92e64.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/experimental/api-playground/page-da46af8c74d0ccba.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/experimental/budgets/page-9862f852f653749a.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/experimental/budgets/page-e471b9b73cfc894b.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/experimental/caching/page-d31cc105402ab7e0.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/experimental/caching/page-f9ab4bd9b8938219.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/experimental/claude-code-plugins/page-dadb6b98d2bf3122.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/experimental/old-usage/page-1599bddd1bf7a448.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/experimental/old-usage/page-5e097dbb8ce40bb4.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/experimental/prompts/page-8236f1efda3366f0.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/experimental/prompts/page-c1b2f89fce632eb9.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/experimental/tag-management/page-38b1e2925ef4d78c.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/experimental/tag-management/page-5627fd94813402eb.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/guardrails/page-060e61cb783d32ef.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/guardrails/page-6fcfd67591571b0f.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/layout-ee00b63098f63896.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js rename litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/logs/{page-c832262bfde568ab.js => page-5a10d46ca991b83e.js} (97%) delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/model-hub/page-0802bc3228446009.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/model-hub/page-1479dcb217587498.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/models-and-endpoints/page-b69988590beaa5c8.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/models-and-endpoints/page-e9561bb2dd6ebb7b.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/organizations/page-56a03e123f452d60.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/organizations/page-bb7939b01e416574.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/playground/page-80b8f3245f6936d1.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/playground/page-fc3dff494dc4db08.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/policies/page-33090e865d27d3fa.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/settings/admin-settings/page-746658933a633902.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/settings/admin-settings/page-d54333a842352184.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/settings/logging-and-alerts/page-e3df74ef5ac0dcd5.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/settings/logging-and-alerts/page-e83525d261d7c7f9.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/settings/router-settings/page-46ff6edf1109f13d.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/settings/router-settings/page-ffa3245ebcbbc02a.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/settings/ui-theme/page-b0efda16443e630f.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/settings/ui-theme/page-d833946961b065a5.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/teams/page-49b94da614a653ba.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/teams/page-8d1a71afa9e9ff16.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/test-key/page-63cd64b722408984.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/test-key/page-afaa514ad2d69fe0.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/tools/mcp-servers/page-59e552ea419ac5b6.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/tools/mcp-servers/page-7dd2ea6f1433d41f.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/tools/vector-stores/page-0f618cc2d6cae794.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/tools/vector-stores/page-414136a92d1a02e9.js rename litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/usage/{page-1b951af48fc11bd9.js => page-d7532f354d44803b.js} (96%) delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/users/page-0ba6bd2b4262da93.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/users/page-6d3643cef6c068ee.js rename litellm/proxy/_experimental/out/_next/static/chunks/app/(dashboard)/virtual-keys/{page-a6a4dc040440802a.js => page-73444bcb0cfe86b7.js} (66%) rename litellm/proxy/_experimental/out/_next/static/chunks/app/login/{page-a5e4539372d51712.js => page-61bfa80619b62f6b.js} (99%) rename litellm/proxy/_experimental/out/_next/static/chunks/app/model_hub/{page-39babd7c1a6e991f.js => page-92347d2021ca8580.js} (83%) create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/model_hub_table/page-2ad344049541235f.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/model_hub_table/page-516d7511795e23d9.js rename litellm/proxy/_experimental/out/_next/static/chunks/app/onboarding/{page-a989f5336329736d.js => page-17ecf5bf068f8157.js} (97%) create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/page-587b0acf34f8c747.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/page-682f895ca508b763.js rename litellm/proxy/_experimental/out/_next/static/chunks/{main-3f67160ac20e4399.js => main-e4e168e4dfadea03.js} (67%) create mode 100644 litellm/proxy/_experimental/out/_next/static/css/83c095d0528a2e35.css delete mode 100644 litellm/proxy/_experimental/out/_next/static/css/9a035dba96de4cd5.css rename litellm/proxy/_experimental/out/_next/static/{8YepvLrDdt6e_FwiLneCs => zHD7JXLXiWgn1NPp82VmF}/_buildManifest.js (100%) rename litellm/proxy/_experimental/out/_next/static/{8YepvLrDdt6e_FwiLneCs => zHD7JXLXiWgn1NPp82VmF}/_ssgManifest.js (100%) delete mode 100644 litellm/proxy/_experimental/out/api-reference.html create mode 100644 litellm/proxy/_experimental/out/api-reference/index.html delete mode 100644 litellm/proxy/_experimental/out/assets/logos/s3_vector.png rename litellm/proxy/_experimental/out/experimental/{api-playground.html => api-playground/index.html} (87%) delete mode 100644 litellm/proxy/_experimental/out/experimental/budgets.html create mode 100644 litellm/proxy/_experimental/out/experimental/budgets/index.html delete mode 100644 litellm/proxy/_experimental/out/experimental/caching.html create mode 100644 litellm/proxy/_experimental/out/experimental/caching/index.html delete mode 100644 litellm/proxy/_experimental/out/experimental/claude-code-plugins.html delete mode 100644 litellm/proxy/_experimental/out/experimental/claude-code-plugins.txt delete mode 100644 litellm/proxy/_experimental/out/experimental/old-usage.html rename litellm/proxy/_experimental/out/experimental/{tag-management.html => old-usage/index.html} (59%) create mode 100644 litellm/proxy/_experimental/out/experimental/prompts/index.html create mode 100644 litellm/proxy/_experimental/out/experimental/tag-management/index.html delete mode 100644 litellm/proxy/_experimental/out/guardrails.html rename litellm/proxy/_experimental/out/{login.html => login/index.html} (77%) rename litellm/proxy/_experimental/out/{logs.html => logs/index.html} (74%) rename litellm/proxy/_experimental/out/mcp/oauth/{callback.html => callback/index.html} (95%) delete mode 100644 litellm/proxy/_experimental/out/model-hub.html create mode 100644 litellm/proxy/_experimental/out/model-hub/index.html delete mode 100644 litellm/proxy/_experimental/out/model_hub.html delete mode 100644 litellm/proxy/_experimental/out/model_hub_table.html create mode 100644 litellm/proxy/_experimental/out/model_hub_table/index.html delete mode 100644 litellm/proxy/_experimental/out/models-and-endpoints.html rename litellm/proxy/_experimental/out/{tools/mcp-servers.html => models-and-endpoints/index.html} (58%) delete mode 100644 litellm/proxy/_experimental/out/onboarding.html delete mode 100644 litellm/proxy/_experimental/out/organizations.html create mode 100644 litellm/proxy/_experimental/out/organizations/index.html delete mode 100644 litellm/proxy/_experimental/out/playground.html create mode 100644 litellm/proxy/_experimental/out/playground/index.html delete mode 100644 litellm/proxy/_experimental/out/policies.html delete mode 100644 litellm/proxy/_experimental/out/policies.txt delete mode 100644 litellm/proxy/_experimental/out/settings/admin-settings.html create mode 100644 litellm/proxy/_experimental/out/settings/admin-settings/index.html rename litellm/proxy/_experimental/out/settings/{logging-and-alerts.html => logging-and-alerts/index.html} (79%) rename litellm/proxy/_experimental/out/settings/{router-settings.html => router-settings/index.html} (82%) rename litellm/proxy/_experimental/out/settings/{ui-theme.html => ui-theme/index.html} (85%) delete mode 100644 litellm/proxy/_experimental/out/teams.html create mode 100644 litellm/proxy/_experimental/out/teams/index.html delete mode 100644 litellm/proxy/_experimental/out/test-key.html create mode 100644 litellm/proxy/_experimental/out/test-key/index.html create mode 100644 litellm/proxy/_experimental/out/tools/mcp-servers/index.html delete mode 100644 litellm/proxy/_experimental/out/tools/vector-stores.html create mode 100644 litellm/proxy/_experimental/out/tools/vector-stores/index.html delete mode 100644 litellm/proxy/_experimental/out/usage.html rename litellm/proxy/_experimental/out/{experimental/prompts.html => usage/index.html} (57%) rename litellm/proxy/_experimental/out/{users.html => users/index.html} (74%) delete mode 100644 litellm/proxy/_experimental/out/virtual-keys.html create mode 100644 litellm/proxy/_experimental/out/virtual-keys/index.html delete mode 100644 litellm/rag/ingestion/file_parsers/__init__.py delete mode 100644 litellm/rag/ingestion/file_parsers/pdf_parser.py delete mode 100644 litellm/rag/ingestion/s3_vectors_ingestion.py delete mode 100644 litellm/types/integrations/datadog_cost_management.py delete mode 100644 litellm/types/llms/xai.py delete mode 100644 litellm/types/proxy/management_endpoints/key_management_endpoints.py create mode 100644 proxy_config.yaml delete mode 100644 tests/litellm/proxy/_experimental/mcp_server/test_discoverable_endpoints.py create mode 100644 tests/local_testing/test_literalai.py delete mode 100644 tests/proxy_unit_tests/test_get_image.py delete mode 100644 tests/proxy_unit_tests/test_server_root_path.py delete mode 100644 tests/test_litellm/a2a_protocol/test_card_resolver.py delete mode 100644 tests/test_litellm/integrations/datadog/test_datadog_cost_management.py delete mode 100644 tests/test_litellm/integrations/datadog/test_datadog_llm_obs_agent.py delete mode 100644 tests/test_litellm/integrations/test_custom_guardrail_recursion.py delete mode 100644 tests/test_litellm/integrations/test_prometheus_client_ip_user_agent.py delete mode 100644 tests/test_litellm/integrations/test_prometheus_missing_metrics.py delete mode 100644 tests/test_litellm/llms/s3_vectors/__init__.py delete mode 100644 tests/test_litellm/llms/s3_vectors/vector_stores/__init__.py delete mode 100644 tests/test_litellm/llms/s3_vectors/vector_stores/test_s3_vectors_transformation.py delete mode 100644 tests/test_litellm/llms/test_cache_control_and_reasoning.py delete mode 100644 tests/test_litellm/llms/vercel_ai_gateway/embedding/__init__.py delete mode 100644 tests/test_litellm/llms/vercel_ai_gateway/embedding/test_vercel_ai_gateway_embedding.py delete mode 100644 tests/test_litellm/proxy/auth/test_cli_auth.py delete mode 100644 tests/test_litellm/proxy/google_endpoints/test_interactions_agent_param.py delete mode 100644 tests/test_litellm/proxy/hooks/test_post_call_streaming_hook_integration.py delete mode 100644 tests/test_litellm/proxy/hooks/test_post_call_success_hook_integration.py delete mode 100644 tests/test_litellm/proxy/vector_store_endpoints/test_vector_store_access_control.py delete mode 100644 tests/test_litellm/test_router_silent_experiment.py delete mode 100644 tests/test_otel_thread_leak.py delete mode 100644 tests/test_presidio_latency.py delete mode 100644 tests/vector_store_tests/rag/test_rag_s3_vectors.py delete mode 100644 tests/vector_store_tests/test_s3_vectors_vector_store.py delete mode 100644 ui/litellm-dashboard/public/assets/logos/s3_vector.png delete mode 100644 ui/litellm-dashboard/src/app/(dashboard)/hooks/storeRequestInSpendLogs/useStoreRequestInSpendLogs.ts delete mode 100644 ui/litellm-dashboard/src/app/(dashboard)/hooks/useDisableShowPrompts.ts delete mode 100644 ui/litellm-dashboard/src/components/BulkEditUsers.test.tsx delete mode 100644 ui/litellm-dashboard/src/components/Settings/AdminSettings/UISettings/PageVisibilitySettings.tsx rename ui/litellm-dashboard/src/components/{BulkEditUsers.tsx => bulk_edit_user.tsx} (98%) delete mode 100644 ui/litellm-dashboard/src/components/common_components/KeyLifecycleSettings.test.tsx delete mode 100644 ui/litellm-dashboard/src/components/common_components/RouterSettingsAccordion.tsx delete mode 100644 ui/litellm-dashboard/src/components/common_components/TableHeaderSortDropdown/TableHeaderSortDropdown.test.tsx delete mode 100644 ui/litellm-dashboard/src/components/common_components/TableHeaderSortDropdown/TableHeaderSortDropdown.tsx delete mode 100644 ui/litellm-dashboard/src/components/model_dashboard/all_models_table.tsx delete mode 100644 ui/litellm-dashboard/src/components/molecules/filter.test.tsx delete mode 100644 ui/litellm-dashboard/src/components/page_metadata.ts delete mode 100644 ui/litellm-dashboard/src/components/page_utils.test.ts delete mode 100644 ui/litellm-dashboard/src/components/page_utils.ts delete mode 100644 ui/litellm-dashboard/src/components/router_settings/RouterSettingsForm.tsx delete mode 100644 ui/litellm-dashboard/src/components/survey/NudgePrompt.test.tsx delete mode 100644 ui/litellm-dashboard/src/components/vector_store_management/CreateVectorStore.test.tsx delete mode 100644 ui/litellm-dashboard/src/components/vector_store_management/CreateVectorStore.tsx delete mode 100644 ui/litellm-dashboard/src/components/vector_store_management/DocumentsTable.test.tsx delete mode 100644 ui/litellm-dashboard/src/components/vector_store_management/DocumentsTable.tsx delete mode 100644 ui/litellm-dashboard/src/components/vector_store_management/S3VectorsConfig.test.tsx delete mode 100644 ui/litellm-dashboard/src/components/vector_store_management/S3VectorsConfig.tsx delete mode 100644 ui/litellm-dashboard/src/components/vector_store_management/TestVectorStoreTab.test.tsx delete mode 100644 ui/litellm-dashboard/src/components/vector_store_management/TestVectorStoreTab.tsx delete mode 100644 ui/litellm-dashboard/src/components/view_logs/SpendLogsSettingsModal/SpendLogsSettingsModal.test.tsx delete mode 100644 ui/litellm-dashboard/src/components/view_logs/SpendLogsSettingsModal/SpendLogsSettingsModal.tsx diff --git a/.circleci/config.yml b/.circleci/config.yml index 84b15572a66..0b369477c28 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -112,7 +112,7 @@ jobs: python -m mypy . cd .. no_output_timeout: 10m - local_testing_part1: + local_testing: docker: - image: cimg/python:3.12 auth: @@ -205,143 +205,13 @@ jobs: # Run pytest and generate JUnit XML report - run: - name: Run tests (Part 1 - A-M) - command: | - mkdir test-results - - # Discover test files (A-M) - TEST_FILES=$(circleci tests glob "tests/local_testing/**/test_[a-mA-M]*.py") - - echo "$TEST_FILES" | circleci tests run \ - --split-by=timings \ - --verbose \ - --command="xargs python -m pytest \ - -vv \ - --cov=litellm \ - --cov-report=xml \ - --junitxml=test-results/junit.xml \ - --durations=20 \ - -k \"not test_python_38.py and not test_basic_python_version.py and not router and not assistants and not langfuse and not caching and not cache\" \ - -n 4 \ - --timeout=300 \ - --timeout_method=thread" - no_output_timeout: 120m - - run: - name: Rename the coverage files - command: | - mv coverage.xml local_testing_part1_coverage.xml - mv .coverage local_testing_part1_coverage - - # Store test results - - store_test_results: - path: test-results - - persist_to_workspace: - root: . - paths: - - local_testing_part1_coverage.xml - - local_testing_part1_coverage - local_testing_part2: - docker: - - image: cimg/python:3.12 - auth: - username: ${DOCKERHUB_USERNAME} - password: ${DOCKERHUB_PASSWORD} - working_directory: ~/project - parallelism: 4 - steps: - - checkout - - setup_google_dns - - run: - name: Show git commit hash - command: | - echo "Git commit hash: $CIRCLE_SHA1" - - - restore_cache: - keys: - - v1-dependencies-{{ checksum ".circleci/requirements.txt" }} - - run: - name: Install Dependencies - command: | - python -m pip install --upgrade pip - python -m pip install -r .circleci/requirements.txt - pip install "pytest==7.3.1" - pip install "pytest-retry==1.6.3" - pip install "pytest-asyncio==0.21.1" - pip install "pytest-cov==5.0.0" - pip install "mypy==1.18.2" - pip install "google-generativeai==0.3.2" - pip install "google-cloud-aiplatform==1.43.0" - pip install pyarrow - pip install "boto3==1.36.0" - pip install "aioboto3==13.4.0" - pip install langchain - pip install lunary==0.2.5 - pip install "azure-identity==1.16.1" - pip install "langfuse==2.59.7" - pip install "logfire==0.29.0" - pip install numpydoc - pip install traceloop-sdk==0.21.1 - pip install opentelemetry-api==1.25.0 - pip install opentelemetry-sdk==1.25.0 - pip install opentelemetry-exporter-otlp==1.25.0 - pip install openai==1.100.1 - pip install prisma==0.11.0 - pip install "detect_secrets==1.5.0" - pip install "httpx==0.24.1" - pip install "respx==0.22.0" - pip install fastapi - pip install "gunicorn==21.2.0" - pip install "anyio==4.2.0" - pip install "aiodynamo==23.10.1" - pip install "asyncio==3.4.3" - pip install "apscheduler==3.10.4" - pip install "PyGithub==1.59.1" - pip install argon2-cffi - pip install "pytest-mock==3.12.0" - pip install python-multipart - pip install google-cloud-aiplatform - pip install prometheus-client==0.20.0 - pip install "pydantic==2.10.2" - pip install "diskcache==5.6.1" - pip install "Pillow==10.3.0" - pip install "jsonschema==4.22.0" - pip install "pytest-xdist==3.6.1" - pip install "pytest-timeout==2.2.0" - pip install "websockets==13.1.0" - pip install semantic_router --no-deps - pip install aurelio_sdk --no-deps - pip uninstall posthog -y - - setup_litellm_enterprise_pip - - save_cache: - paths: - - ./venv - key: v1-dependencies-{{ checksum ".circleci/requirements.txt" }} - - run: - name: Run prisma ./docker/entrypoint.sh - command: | - set +e - chmod +x docker/entrypoint.sh - ./docker/entrypoint.sh - set -e - - run: - name: Black Formatting - command: | - cd litellm - python -m pip install black - python -m black . - cd .. - - # Run pytest and generate JUnit XML report - - run: - name: Run tests (Part 2 - N-Z) + name: Run tests command: | mkdir test-results - - # Discover test files (N-Z) - TEST_FILES=$(circleci tests glob "tests/local_testing/**/test_[n-zN-Z]*.py") - + # Discover test files + TEST_FILES=$(circleci tests glob "tests/local_testing/**/test_*.py") echo "$TEST_FILES" | circleci tests run \ - --split-by=timings \ + --split-by=filesize \ --verbose \ --command="xargs python -m pytest \ -vv \ @@ -357,8 +227,8 @@ jobs: - run: name: Rename the coverage files command: | - mv coverage.xml local_testing_part2_coverage.xml - mv .coverage local_testing_part2_coverage + mv coverage.xml local_testing_coverage.xml + mv .coverage local_testing_coverage # Store test results - store_test_results: @@ -366,8 +236,8 @@ jobs: - persist_to_workspace: root: . paths: - - local_testing_part2_coverage.xml - - local_testing_part2_coverage + - local_testing_coverage.xml + - local_testing_coverage langfuse_logging_unit_tests: docker: - image: cimg/python:3.11 @@ -639,6 +509,7 @@ jobs: username: ${DOCKERHUB_USERNAME} password: ${DOCKERHUB_PASSWORD} working_directory: ~/project + parallelism: 4 steps: - checkout - setup_google_dns @@ -660,9 +531,21 @@ jobs: - run: name: Run tests command: | - pwd - ls - python -m pytest tests/local_testing --cov=litellm --cov-report=xml -vv -k "router" -v --junitxml=test-results/junit.xml --durations=5 + mkdir test-results + # Find test files only in local_testing + TEST_FILES=$(circleci tests glob "tests/local_testing/**/test_*.py") + echo "$TEST_FILES" | circleci tests run \ + --split-by=filesize \ + --verbose \ + --command="xargs python -m pytest -o junit_family=legacy \ + -k 'router' \ + --cov=litellm \ + --cov-report=xml \ + -n 4 \ + --dist=loadscope \ + --junitxml=test-results/junit.xml \ + --durations=5 \ + -vv" no_output_timeout: 120m - run: name: Rename the coverage files @@ -715,8 +598,8 @@ jobs: - run: name: Rename the coverage files command: | - mv coverage.xml litellm_router_unit_coverage.xml - mv .coverage litellm_router_unit_coverage + mv coverage.xml litellm_router_coverage.xml + mv .coverage litellm_router_coverage # Store test results - store_test_results: path: test-results @@ -724,8 +607,8 @@ jobs: - persist_to_workspace: root: . paths: - - litellm_router_unit_coverage.xml - - litellm_router_unit_coverage + - litellm_router_coverage.xml + - litellm_router_coverage litellm_security_tests: machine: image: ubuntu-2204:2023.10.1 @@ -1933,7 +1816,6 @@ jobs: pip install "mlflow==2.17.2" pip install "anthropic==0.52.0" pip install "blockbuster==1.5.24" - pip install "pytest-xdist==3.6.1" # Run pytest and generate JUnit XML report - setup_litellm_enterprise_pip - run: @@ -1941,7 +1823,7 @@ jobs: command: | pwd ls - python -m pytest -vv tests/logging_callback_tests --cov=litellm -n 4 --cov-report=xml -s -v --junitxml=test-results/junit.xml --durations=5 + python -m pytest -vv tests/logging_callback_tests --cov=litellm --cov-report=xml -s -v --junitxml=test-results/junit.xml --durations=5 no_output_timeout: 120m - run: name: Rename the coverage files @@ -3428,7 +3310,7 @@ jobs: python -m venv venv . venv/bin/activate pip install coverage - coverage combine llm_translation_coverage llm_responses_api_coverage ocr_coverage search_coverage mcp_coverage logging_coverage audio_coverage litellm_router_coverage litellm_router_unit_coverage local_testing_part1_coverage local_testing_part2_coverage litellm_assistants_api_coverage auth_ui_unit_tests_coverage langfuse_coverage caching_coverage litellm_proxy_unit_tests_part1_coverage litellm_proxy_unit_tests_part2_coverage image_gen_coverage pass_through_unit_tests_coverage batches_coverage litellm_security_tests_coverage guardrails_coverage litellm_mapped_tests_coverage + coverage combine llm_translation_coverage llm_responses_api_coverage ocr_coverage search_coverage mcp_coverage logging_coverage audio_coverage litellm_router_coverage local_testing_coverage litellm_assistants_api_coverage auth_ui_unit_tests_coverage langfuse_coverage caching_coverage litellm_proxy_unit_tests_part1_coverage litellm_proxy_unit_tests_part2_coverage image_gen_coverage pass_through_unit_tests_coverage batches_coverage litellm_security_tests_coverage guardrails_coverage litellm_mapped_tests_coverage coverage xml - codecov/upload: file: ./coverage.xml @@ -3478,22 +3360,8 @@ jobs: ls dist/ twine upload --verbose dist/* else - echo "Version ${VERSION} of package is already published on PyPI." - - # Check if corresponding Docker nightly image exists - NIGHTLY_TAG="v${VERSION}-nightly" - echo "Checking for Docker nightly image: litellm/litellm:${NIGHTLY_TAG}" - - # Check Docker Hub for the nightly image - if curl -s "https://hub.docker.com/v2/repositories/litellm/litellm/tags/${NIGHTLY_TAG}" | grep -q "name"; then - echo "Docker nightly image ${NIGHTLY_TAG} exists. This release was already completed successfully." - echo "Skipping PyPI publish and continuing to ensure Docker images are up to date." - circleci step halt - else - echo "ERROR: PyPI package ${VERSION} exists but Docker nightly image ${NIGHTLY_TAG} does not exist!" - echo "This indicates an incomplete release. Please investigate." - exit 1 - fi + echo "Version ${VERSION} of package is already published on PyPI. Skipping PyPI publish." + circleci step halt fi - run: name: Trigger Github Action for new Docker Container + Trigger Load Testing @@ -3502,21 +3370,11 @@ jobs: python3 -m pip install toml VERSION=$(python3 -c "import toml; print(toml.load('pyproject.toml')['tool']['poetry']['version'])") echo "LiteLLM Version ${VERSION}" - - # Determine which branch to use for Docker build - if [[ "$CIRCLE_BRANCH" =~ ^litellm_release_day_.* ]]; then - BUILD_BRANCH="$CIRCLE_BRANCH" - echo "Using release branch: $BUILD_BRANCH" - else - BUILD_BRANCH="main" - echo "Using default branch: $BUILD_BRANCH" - fi - curl -X POST \ -H "Accept: application/vnd.github.v3+json" \ -H "Authorization: Bearer $GITHUB_TOKEN" \ "https://api.github.com/repos/BerriAI/litellm/actions/workflows/ghcr_deploy.yml/dispatches" \ - -d "{\"ref\":\"${BUILD_BRANCH}\", \"inputs\":{\"tag\":\"v${VERSION}-nightly\", \"commit_hash\":\"$CIRCLE_SHA1\"}}" + -d "{\"ref\":\"main\", \"inputs\":{\"tag\":\"v${VERSION}-nightly\", \"commit_hash\":\"$CIRCLE_SHA1\"}}" echo "triggering load testing server for version ${VERSION} and commit ${CIRCLE_SHA1}" curl -X POST "https://proxyloadtester-production.up.railway.app/start/load/test?version=${VERSION}&commit_hash=${CIRCLE_SHA1}&release_type=nightly" @@ -3907,13 +3765,7 @@ workflows: only: - main - /litellm_.*/ - - local_testing_part1: - filters: - branches: - only: - - main - - /litellm_.*/ - - local_testing_part2: + - local_testing: filters: branches: only: @@ -4218,8 +4070,7 @@ workflows: - litellm_proxy_unit_testing_part2 - litellm_security_tests - langfuse_logging_unit_tests - - local_testing_part1 - - local_testing_part2 + - local_testing - litellm_assistants_api_testing - auth_ui_unit_tests - db_migration_disable_update_check: @@ -4259,12 +4110,10 @@ workflows: branches: only: - main - - /litellm_release_day_.*/ - publish_to_pypi: requires: - mypy_linting - - local_testing_part1 - - local_testing_part2 + - local_testing - build_and_test - e2e_openai_endpoints - test_bad_database_url diff --git a/.circleci/requirements.txt b/.circleci/requirements.txt index a5ec74424fe..8c44dc18305 100644 --- a/.circleci/requirements.txt +++ b/.circleci/requirements.txt @@ -16,5 +16,4 @@ uvloop==0.21.0 mcp==1.25.0 # for MCP server semantic_router==0.1.10 # for auto-routing with litellm fastuuid==0.12.0 -responses==0.25.7 # for proxy client tests -pytest-retry==1.6.3 # for automatic test retries \ No newline at end of file +responses==0.25.7 # for proxy client tests \ No newline at end of file diff --git a/.github/workflows/test-linting.yml b/.github/workflows/test-linting.yml index 7c5c269f899..35ebffeada3 100644 --- a/.github/workflows/test-linting.yml +++ b/.github/workflows/test-linting.yml @@ -73,4 +73,4 @@ jobs: - name: Check import safety run: | - poetry run python -c "from litellm import *" || (echo '🚨 import failed, this means you introduced unprotected imports! 🚨'; exit 1) + poetry run python -c "from litellm import *" || (echo '🚨 import failed, this means you introduced unprotected imports! 🚨'; exit 1) \ No newline at end of file diff --git a/.github/workflows/test-litellm.yml b/.github/workflows/test-litellm.yml index d9cf2e74a11..ba32dc1bf54 100644 --- a/.github/workflows/test-litellm.yml +++ b/.github/workflows/test-litellm.yml @@ -34,7 +34,7 @@ jobs: poetry run pip install "google-genai==1.22.0" poetry run pip install "google-cloud-aiplatform>=1.38" poetry run pip install "fastapi-offline==1.7.3" - poetry run pip install "python-multipart==0.0.22" + poetry run pip install "python-multipart==0.0.18" poetry run pip install "openapi-core" - name: Setup litellm-enterprise as local package run: | diff --git a/.github/workflows/test-model-map.yaml b/.github/workflows/test-model-map.yaml deleted file mode 100644 index ae5ac402e23..00000000000 --- a/.github/workflows/test-model-map.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: Validate model_prices_and_context_window.json - -on: - pull_request: - branches: [ main ] - -jobs: - validate-model-prices-json: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Validate model_prices_and_context_window.json - run: | - jq empty model_prices_and_context_window.json diff --git a/.gitignore b/.gitignore index 32f1b6f8e1f..0248d68c1e1 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,10 @@ litellm/proxy/_super_secret_config.yaml litellm/proxy/myenv/bin/activate litellm/proxy/myenv/bin/Activate.ps1 myenv/* +litellm/proxy/_experimental/out/_next/ +litellm/proxy/_experimental/out/404/index.html +litellm/proxy/_experimental/out/model_hub/index.html +litellm/proxy/_experimental/out/onboarding/index.html litellm/tests/log.txt litellm/tests/langfuse.log litellm/tests/langfuse.log @@ -72,6 +76,9 @@ tests/local_testing/log.txt litellm/proxy/_new_new_secret_config.yaml litellm/proxy/custom_guardrail.py .mypy_cache/* +litellm/proxy/_experimental/out/404.html +litellm/proxy/_experimental/out/404.html +litellm/proxy/_experimental/out/model_hub.html .mypy_cache/* litellm/proxy/application.log tests/llm_translation/vertex_test_account.json @@ -93,6 +100,7 @@ litellm_config.yaml litellm/proxy/to_delete_loadtest_work/* update_model_cost_map.py tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server_manager.py +litellm/proxy/_experimental/out/guardrails/index.html scripts/test_vertex_ai_search.py LAZY_LOADING_IMPROVEMENTS.md **/test-results diff --git a/AGENTS.md b/AGENTS.md index 5a48049ef45..61afbd035fe 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -51,14 +51,12 @@ LiteLLM is a unified interface for 100+ LLMs that: ### MAKING CODE CHANGES FOR THE UI (IGNORE FOR BACKEND) -1. **Tremor is DEPRECATED, do not use Tremor components in new features/changes** - - The only exception is the Tremor Table component and its required Tremor Table sub components. - -2. **Use Common Components as much as possible**: +1. **Use Common Components as much as possible**: - These are usually defined in the `common_components` directory - Use these components as much as possible and avoid building new components unless needed + - Tremor components are deprecated; prefer using Ant Design (AntD) as much as possible -3. **Testing**: +2. **Testing**: - The codebase uses **Vitest** and **React Testing Library** - **Query Priority Order**: Use query methods in this order: `getByRole`, `getByLabelText`, `getByPlaceholderText`, `getByText`, `getByTestId` - **Always use `screen`** instead of destructuring from `render()` (e.g., use `screen.getByText()` not `getByText`) diff --git a/README.md b/README.md index 77adddf8978..dee5c7167ff 100644 --- a/README.md +++ b/README.md @@ -259,17 +259,12 @@ LiteLLM Performance: **8ms P95 latency** at 1k RPS (See benchmarks [here](https: Support for more providers. Missing a provider or LLM Platform, raise a [feature request](https://github.com/BerriAI/litellm/issues/new?assignees=&labels=enhancement&projects=&template=feature_request.yml&title=%5BFeature%5D%3A+). ## OSS Adopters +Stripe wordmark - Blurple - Small + +download__1_-removebg-preview + + - - - - - - - - - -
StripeGoogle ADKGreptileOpenHands

Netflix

OpenAI Agents SDK
## Supported Providers ([Website Supported Models](https://models.litellm.ai/) | [Docs](https://docs.litellm.ai/docs/providers)) diff --git a/deploy/charts/litellm-helm/templates/deployment.yaml b/deploy/charts/litellm-helm/templates/deployment.yaml index 4ac5582d060..c3e0055e380 100644 --- a/deploy/charts/litellm-helm/templates/deployment.yaml +++ b/deploy/charts/litellm-helm/templates/deployment.yaml @@ -38,10 +38,6 @@ spec: serviceAccountName: {{ include "litellm.serviceAccountName" . }} securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} - {{- with .Values.extraInitContainers }} - initContainers: - {{- toYaml . | nindent 8 }} - {{- end }} containers: - name: {{ include "litellm.name" . }} securityContext: diff --git a/deploy/charts/litellm-helm/templates/migrations-job.yaml b/deploy/charts/litellm-helm/templates/migrations-job.yaml index 3459fa12d1c..f8893a47afe 100644 --- a/deploy/charts/litellm-helm/templates/migrations-job.yaml +++ b/deploy/charts/litellm-helm/templates/migrations-job.yaml @@ -35,10 +35,6 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} serviceAccountName: {{ include "litellm.serviceAccountName" . }} - {{- with .Values.migrationJob.extraInitContainers }} - initContainers: - {{- toYaml . | nindent 8 }} - {{- end }} containers: - name: prisma-migrations image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default (printf "main-%s" .Chart.AppVersion) }}" diff --git a/deploy/charts/litellm-helm/values.yaml b/deploy/charts/litellm-helm/values.yaml index cea25974bb0..b75ce640370 100644 --- a/deploy/charts/litellm-helm/values.yaml +++ b/deploy/charts/litellm-helm/values.yaml @@ -281,7 +281,6 @@ migrationJob: # cpu: 100m # memory: 100Mi extraContainers: [] - extraInitContainers: [] # Hook configuration hooks: diff --git a/docs/my-website/docs/a2a.md b/docs/my-website/docs/a2a.md index a7e8b52d99a..7b863f185d0 100644 --- a/docs/my-website/docs/a2a.md +++ b/docs/my-website/docs/a2a.md @@ -68,7 +68,7 @@ Follow [this guide, to add your pydantic ai agent to LiteLLM Agent Gateway](./pr ## Invoking your Agents -Use the [A2A Python SDK](https://pypi.org/project/a2a-sdk) to invoke agents through LiteLLM. +Use the [A2A Python SDK](https://pypi.org/project/a2a/) to invoke agents through LiteLLM. This example shows how to: 1. **List available agents** - Query `/v1/agents` to see which agents your key can access diff --git a/docs/my-website/docs/observability/datadog.md b/docs/my-website/docs/observability/datadog.md index 6f785be1013..7cf91ced34c 100644 --- a/docs/my-website/docs/observability/datadog.md +++ b/docs/my-website/docs/observability/datadog.md @@ -7,7 +7,6 @@ import TabItem from '@theme/TabItem'; LiteLLM Supports logging to the following Datdog Integrations: - `datadog` [Datadog Logs](https://docs.datadoghq.com/logs/) - `datadog_llm_observability` [Datadog LLM Observability](https://www.datadoghq.com/product/llm-observability/) -- `datadog_cost_management` [Datadog Cloud Cost Management](#datadog-cloud-cost-management) - `ddtrace-run` [Datadog Tracing](#datadog-tracing) ## Datadog Logs @@ -74,7 +73,7 @@ Send logs through a local DataDog agent (useful for containerized environments): ```shell LITELLM_DD_AGENT_HOST="localhost" # hostname or IP of DataDog agent LITELLM_DD_AGENT_PORT="10518" # [OPTIONAL] port of DataDog agent (default: 10518) -DD_API_KEY="5f2d0f310***********" # [OPTIONAL] your datadog API Key (Agent handles auth for Logs. REQUIRED for LLM Observability) +DD_API_KEY="5f2d0f310***********" # [OPTIONAL] your datadog API Key (agent handles auth) DD_SOURCE="litellm_dev" # [OPTIONAL] your datadog source ``` @@ -85,9 +84,6 @@ When `LITELLM_DD_AGENT_HOST` is set, logs are sent to the agent instead of direc **Note:** We use `LITELLM_DD_AGENT_HOST` instead of `DD_AGENT_HOST` to avoid conflicts with `ddtrace` which automatically sets `DD_AGENT_HOST` for APM tracing. -> [!IMPORTANT] -> **Datadog LLM Observability**: `DD_API_KEY` is **REQUIRED** even when using the Datadog Agent (`LITELLM_DD_AGENT_HOST`). The agent acts as a proxy but the API key header is mandatory for the LLM Observability endpoint. - **Step 3**: Start the proxy, make a test request Start proxy @@ -165,50 +161,6 @@ On the Datadog LLM Observability page, you should see that both input messages a - - - -## Datadog Cloud Cost Management - -| Feature | Details | -|---------|---------| -| **What is logged** | Aggregated LLM Costs (FOCUS format) | -| **Events** | Periodic Uploads of Aggregated Cost Data | -| **Product Link** | [Datadog Cloud Cost Management](https://docs.datadoghq.com/cost_management/) | - -We will use the `--config` to set `litellm.callbacks = ["datadog_cost_management"]`. This will periodically upload aggregated LLM cost data to Datadog. - -**Step 1**: Create a `config.yaml` file and set `litellm_settings`: `success_callback` - -```yaml -model_list: - - model_name: gpt-3.5-turbo - litellm_params: - model: gpt-3.5-turbo -litellm_settings: - callbacks: ["datadog_cost_management"] -``` - -**Step 2**: Set Required env variables - -```shell -DD_API_KEY="your-api-key" -DD_APP_KEY="your-app-key" # REQUIRED for Cost Management -DD_SITE="us5.datadoghq.com" -``` - -**Step 3**: Start the proxy - -```shell -litellm --config config.yaml -``` - -**How it works** -* LiteLLM aggregates costs in-memory by Provider, Model, Date, and Tags. -* Requires `DD_APP_KEY` for the Custom Costs API. -* Costs are uploaded periodically (flushed). - - ### Datadog Tracing Use `ddtrace-run` to enable [Datadog Tracing](https://ddtrace.readthedocs.io/en/stable/installation_quickstart.html) on litellm proxy @@ -251,5 +203,5 @@ LiteLLM supports customizing the following Datadog environment variables | `POD_NAME` | Pod name tag (useful for Kubernetes deployments) | "unknown" | ❌ No | \* **Required when using Direct API** (default): `DD_API_KEY` and `DD_SITE` are required -\* **Optional when using DataDog Agent**: Set `LITELLM_DD_AGENT_HOST` to use agent mode; `DD_API_KEY` and `DD_SITE` are not required for **Datadog Logs**. (**Note: `DD_API_KEY` IS REQUIRED for Datadog LLM Observability**) +\* **Optional when using DataDog Agent**: Set `LITELLM_DD_AGENT_HOST` to use agent mode; `DD_API_KEY` and `DD_SITE` are not required diff --git a/docs/my-website/docs/providers/anthropic_tool_search.md b/docs/my-website/docs/providers/anthropic_tool_search.md index 203a2947ebc..28ce5688eeb 100644 --- a/docs/my-website/docs/providers/anthropic_tool_search.md +++ b/docs/my-website/docs/providers/anthropic_tool_search.md @@ -1,46 +1,43 @@ -# Tool Search +# Anthropic Tool Search Tool search enables Claude to dynamically discover and load tools on-demand from large tool catalogs (10,000+ tools). Instead of loading all tool definitions into the context window upfront, Claude searches your tool catalog and loads only the tools it needs. -## Supported Providers - -| Provider | Chat Completions API | Messages API | -|----------|---------------------|--------------| -| **Anthropic API** | ✅ | ✅ | -| **Azure Anthropic** (Microsoft Foundry) | ✅ | ✅ | -| **Google Cloud Vertex AI** | ✅ | ✅ | -| **Amazon Bedrock** | ✅ (Invoke API only, Opus 4.5 only) | ✅ (Invoke API only, Opus 4.5 only) | - - ## Benefits - **Context efficiency**: Avoid consuming massive portions of your context window with tool definitions - **Better tool selection**: Claude's tool selection accuracy degrades with more than 30-50 tools. Tool search maintains accuracy even with thousands of tools - **On-demand loading**: Tools are only loaded when Claude needs them +## Supported Models + +Tool search is available on: +- Claude Opus 4.5 +- Claude Sonnet 4.5 + +## Supported Platforms + +- Anthropic API (direct) +- Azure Anthropic (Microsoft Foundry) +- Google Cloud Vertex AI +- Amazon Bedrock (invoke API only, not converse API) + ## Tool Search Variants LiteLLM supports both tool search variants: ### 1. Regex Tool Search (`tool_search_tool_regex_20251119`) -Claude constructs regex patterns to search for tools. Best for exact pattern matching (faster). +Claude constructs regex patterns to search for tools. ### 2. BM25 Tool Search (`tool_search_tool_bm25_20251119`) -Claude uses natural language queries to search for tools using the BM25 algorithm. Best for natural language semantic search. - -**Note**: BM25 variant is not supported on Bedrock. - ---- - -## Chat Completions API +Claude uses natural language queries to search for tools using the BM25 algorithm. -### SDK Usage +## Quick Start -#### Basic Example with Regex Tool Search +### Basic Example with Regex Tool Search -```python showLineNumbers title="Basic Tool Search Example" +```python import litellm response = litellm.completion( @@ -73,6 +70,26 @@ response = litellm.completion( } }, "defer_loading": True # Mark for deferred loading + }, + # Another deferred tool + { + "type": "function", + "function": { + "name": "search_files", + "description": "Search through files in the workspace", + "parameters": { + "type": "object", + "properties": { + "query": {"type": "string"}, + "file_types": { + "type": "array", + "items": {"type": "string"} + } + }, + "required": ["query"] + } + }, + "defer_loading": True } ] ) @@ -80,9 +97,9 @@ response = litellm.completion( print(response.choices[0].message.content) ``` -#### BM25 Tool Search Example +### BM25 Tool Search Example -```python showLineNumbers title="BM25 Tool Search" +```python import litellm response = litellm.completion( @@ -117,9 +134,9 @@ response = litellm.completion( ) ``` -#### Azure Anthropic Example +## Using with Azure Anthropic -```python showLineNumbers title="Azure Anthropic Tool Search" +```python import litellm response = litellm.completion( @@ -153,9 +170,9 @@ response = litellm.completion( ) ``` -#### Vertex AI Example +## Using with Vertex AI -```python showLineNumbers title="Vertex AI Tool Search" +```python import litellm response = litellm.completion( @@ -175,9 +192,11 @@ response = litellm.completion( ) ``` -#### Streaming Support +## Streaming Support -```python showLineNumbers title="Streaming with Tool Search" +Tool search works with streaming: + +```python import litellm response = litellm.completion( @@ -214,13 +233,13 @@ for chunk in response: print(chunk.choices[0].delta.content, end="") ``` -### AI Gateway Usage +## LiteLLM Proxy -Tool search works automatically through the LiteLLM proxy. +Tool search works automatically through the LiteLLM proxy: -#### Proxy Configuration +### Proxy Config -```yaml showLineNumbers title="config.yaml" +```yaml model_list: - model_name: claude-sonnet litellm_params: @@ -228,19 +247,18 @@ model_list: api_key: os.environ/ANTHROPIC_API_KEY ``` -#### Client Request +### Client Request -```python showLineNumbers title="Client Request via Proxy" -from anthropic import Anthropic +```python +import openai -client = Anthropic( +client = openai.OpenAI( api_key="your-litellm-proxy-key", base_url="http://0.0.0.0:4000" ) -response = client.messages.create( +response = client.chat.completions.create( model="claude-sonnet", - max_tokens=1024, messages=[ {"role": "user", "content": "What's the weather?"} ], @@ -250,14 +268,17 @@ response = client.messages.create( "name": "tool_search_tool_regex" }, { - "name": "get_weather", - "description": "Get weather information", - "input_schema": { - "type": "object", - "properties": { - "location": {"type": "string"} - }, - "required": ["location"] + "type": "function", + "function": { + "name": "get_weather", + "description": "Get weather information", + "parameters": { + "type": "object", + "properties": { + "location": {"type": "string"} + }, + "required": ["location"] + } }, "defer_loading": True } @@ -265,278 +286,127 @@ response = client.messages.create( ) ``` ---- +## Important Notes -## Messages API +### Beta Header -The Messages API provides native Anthropic-style tool search support via the `litellm.anthropic.messages` interface. +LiteLLM automatically detects tool search tools and adds the appropriate beta header based on your provider: -### SDK Usage +- **Anthropic API & Microsoft Foundry**: `advanced-tool-use-2025-11-20` +- **Google Cloud Vertex AI**: `tool-search-tool-2025-10-19` +- **Amazon Bedrock** (Invoke API, Opus 4.5 only): `tool-search-tool-2025-10-19` -#### Basic Example +You don't need to manually specify beta headers—LiteLLM handles this automatically. -```python showLineNumbers title="Messages API - Basic Tool Search" -import litellm +### Deferred Loading -response = await litellm.anthropic.messages.acreate( - model="anthropic/claude-sonnet-4-20250514", - messages=[ - { - "role": "user", - "content": "What's the weather in San Francisco?" - } - ], - tools=[ - { - "type": "tool_search_tool_regex_20251119", - "name": "tool_search_tool_regex" - }, - { - "name": "get_weather", - "description": "Get the current weather for a location", - "input_schema": { - "type": "object", - "properties": { - "location": { - "type": "string", - "description": "The city and state, e.g. San Francisco, CA" - } - }, - "required": ["location"] - }, - "defer_loading": True - } - ], - max_tokens=1024, - extra_headers={"anthropic-beta": "advanced-tool-use-2025-11-20"} -) +- Tools with `defer_loading: true` are only loaded when Claude discovers them via search +- At least one tool must be non-deferred (the tool search tool itself) +- Keep your 3-5 most frequently used tools as non-deferred for optimal performance -print(response) -``` +### Tool Descriptions -#### Azure Anthropic Messages Example +Write clear, descriptive tool names and descriptions that match how users describe tasks. The search algorithm uses: +- Tool names +- Tool descriptions +- Argument names +- Argument descriptions -```python showLineNumbers title="Azure Anthropic Messages API" -import litellm +### Usage Tracking -response = await litellm.anthropic.messages.acreate( - model="azure_anthropic/claude-sonnet-4-20250514", - messages=[ - { - "role": "user", - "content": "What's the stock price of Apple?" - } - ], - tools=[ - { - "type": "tool_search_tool_regex_20251119", - "name": "tool_search_tool_regex" - }, - { - "name": "get_stock_price", - "description": "Get the current stock price for a ticker symbol", - "input_schema": { - "type": "object", - "properties": { - "ticker": { - "type": "string", - "description": "The stock ticker symbol, e.g. AAPL" - } - }, - "required": ["ticker"] - }, - "defer_loading": True - } - ], - max_tokens=1024, - extra_headers={"anthropic-beta": "advanced-tool-use-2025-11-20"} -) -``` - -#### Vertex AI Messages Example +Tool search requests are tracked in the usage object: -```python showLineNumbers title="Vertex AI Messages API" -import litellm - -response = await litellm.anthropic.messages.acreate( - model="vertex_ai/claude-sonnet-4@20250514", - messages=[ - { - "role": "user", - "content": "Search the web for information about AI" - } - ], - tools=[ - { - "type": "tool_search_tool_bm25_20251119", - "name": "tool_search_tool_bm25" - }, - { - "name": "search_web", - "description": "Search the web for information", - "input_schema": { - "type": "object", - "properties": { - "query": { - "type": "string", - "description": "The search query" - } - }, - "required": ["query"] - }, - "defer_loading": True - } - ], - max_tokens=1024, - extra_headers={"anthropic-beta": "tool-search-tool-2025-10-19"} +```python +response = litellm.completion( + model="anthropic/claude-sonnet-4-5-20250929", + messages=[{"role": "user", "content": "Search for tools"}], + tools=[...] ) -``` -#### Bedrock Messages Example - -```python showLineNumbers title="Bedrock Messages API (Invoke)" -import litellm +# Check tool search usage +if response.usage.server_tool_use: + print(f"Tool search requests: {response.usage.server_tool_use.tool_search_requests}") +``` -response = await litellm.anthropic.messages.acreate( - model="bedrock/invoke/anthropic.claude-opus-4-20250514-v1:0", - messages=[ - { - "role": "user", - "content": "What's the weather?" - } - ], - tools=[ - { - "type": "tool_search_tool_regex_20251119", - "name": "tool_search_tool_regex" - }, - { - "name": "get_weather", - "description": "Get weather information", - "input_schema": { - "type": "object", - "properties": { - "location": {"type": "string"} - }, - "required": ["location"] - }, - "defer_loading": True - } - ], - max_tokens=1024, - extra_headers={"anthropic-beta": "tool-search-tool-2025-10-19"} -) +## Error Handling + +### All Tools Deferred + +```python +# ❌ This will fail - at least one tool must be non-deferred +tools = [ + { + "type": "function", + "function": {...}, + "defer_loading": True + } +] + +# ✅ Correct - tool search tool is non-deferred +tools = [ + { + "type": "tool_search_tool_regex_20251119", + "name": "tool_search_tool_regex" + }, + { + "type": "function", + "function": {...}, + "defer_loading": True + } +] ``` -#### Streaming Support +### Missing Tool Definition -```python showLineNumbers title="Messages API - Streaming" -import litellm -import json +If Claude references a tool that isn't in your deferred tools list, you'll get an error. Make sure all tools that might be discovered are included in the tools parameter with `defer_loading: true`. -response = await litellm.anthropic.messages.acreate( - model="anthropic/claude-sonnet-4-20250514", - messages=[ - { - "role": "user", - "content": "What's the weather in Tokyo?" - } - ], - tools=[ - { - "type": "tool_search_tool_regex_20251119", - "name": "tool_search_tool_regex" - }, - { - "name": "get_weather", - "description": "Get weather information", - "input_schema": { - "type": "object", - "properties": { - "location": {"type": "string"} - }, - "required": ["location"] - }, - "defer_loading": True - } - ], - max_tokens=1024, - stream=True, - extra_headers={"anthropic-beta": "advanced-tool-use-2025-11-20"} -) +## Best Practices -async for chunk in response: - if isinstance(chunk, bytes): - chunk_str = chunk.decode("utf-8") - for line in chunk_str.split("\n"): - if line.startswith("data: "): - try: - json_data = json.loads(line[6:]) - print(json_data) - except json.JSONDecodeError: - pass -``` +1. **Keep frequently used tools non-deferred**: Your 3-5 most common tools should not have `defer_loading: true` -### AI Gateway Usage +2. **Use semantic descriptions**: Tool descriptions should use natural language that matches user queries -Configure the proxy to use Messages API endpoints. +3. **Choose the right variant**: + - Use **regex** for exact pattern matching (faster) + - Use **BM25** for natural language semantic search -#### Proxy Configuration +4. **Monitor usage**: Track `tool_search_requests` in the usage object to understand search patterns -```yaml showLineNumbers title="config.yaml" -model_list: - - model_name: claude-sonnet-messages - litellm_params: - model: anthropic/claude-sonnet-4-20250514 - api_key: os.environ/ANTHROPIC_API_KEY -``` +5. **Optimize tool catalog**: Remove unused tools and consolidate similar functionality -#### Client Request +## When to Use Tool Search -```python showLineNumbers title="Client Request via Proxy (Messages API)" -from anthropic import Anthropic +**Good use cases:** +- 10+ tools available in your system +- Tool definitions consuming >10K tokens +- Experiencing tool selection accuracy issues +- Building systems with multiple tool categories +- Tool library growing over time -client = Anthropic( - api_key="your-litellm-proxy-key", - base_url="http://0.0.0.0:4000" -) +**When traditional tool calling is better:** +- Less than 10 tools total +- All tools are frequently used +- Very small tool definitions (\<100 tokens total) -response = client.messages.create( - model="claude-sonnet-messages", - max_tokens=1024, - messages=[ - { - "role": "user", - "content": "What's the weather?" - } - ], - tools=[ - { - "type": "tool_search_tool_regex_20251119", - "name": "tool_search_tool_regex" - }, - { - "name": "get_weather", - "description": "Get weather information", - "input_schema": { - "type": "object", - "properties": { - "location": {"type": "string"} - }, - "required": ["location"] - }, - "defer_loading": True - } - ], - extra_headers={"anthropic-beta": "advanced-tool-use-2025-11-20"} -) +## Limitations -print(response) -``` +- Not compatible with tool use examples +- Requires Claude Opus 4.5 or Sonnet 4.5 +- On Bedrock, only available via invoke API (not converse API) +- On Bedrock, only supported for Claude Opus 4.5 (not Sonnet 4.5) +- BM25 variant (`tool_search_tool_bm25_20251119`) is not supported on Bedrock +- Maximum 10,000 tools in catalog +- Returns 3-5 most relevant tools per search ---- +### Bedrock-Specific Notes + +When using Bedrock's Invoke API: +- The regex variant (`tool_search_tool_regex_20251119`) is automatically normalized to `tool_search_tool_regex` +- The BM25 variant (`tool_search_tool_bm25_20251119`) is automatically filtered out as it's not supported +- Tool search is only available for Claude Opus 4.5 models ## Additional Resources - [Anthropic Tool Search Documentation](https://docs.anthropic.com/en/docs/build-with-claude/tool-use/tool-search) - [LiteLLM Tool Calling Guide](https://docs.litellm.ai/docs/completion/function_call) + diff --git a/docs/my-website/docs/providers/gemini.md b/docs/my-website/docs/providers/gemini.md index b9ad7820dd4..23a02f7365c 100644 --- a/docs/my-website/docs/providers/gemini.md +++ b/docs/my-website/docs/providers/gemini.md @@ -1840,57 +1840,6 @@ content = response.get('choices', [{}])[0].get('message', {}).get('content') print(content) ``` -## gemini-robotics-er-1.5-preview Usage - -```python -from litellm import api_base -from openai import OpenAI -import os -import base64 - -client = OpenAI(base_url="http://0.0.0.0:4000", api_key="sk-12345") -base64_image = base64.b64encode(open("closeup-object-on-table-many-260nw-1216144471.webp", "rb").read()).decode() - -import json -import re -tools = [{"codeExecution": {}}] -response = client.chat.completions.create( - model="gemini/gemini-robotics-er-1.5-preview", - messages=[ - { - "role": "user", - "content": [ - { - "type": "text", - "text": "Point to no more than 10 items in the image. The label returned should be an identifying name for the object detected. The answer should follow the json format: [{\"point\": [y, x], \"label\": }, ...]. The points are in [y, x] format normalized to 0-1000." - }, - { - "type": "image_url", - "image_url": {"url": f"data:image/jpeg;base64,{base64_image}"} - } - ] - } - ], - tools=tools -) - -# Extract JSON from markdown code block if present -content = response.choices[0].message.content -# Look for triple-backtick JSON block -match = re.search(r'```json\s*(.*?)\s*```', content, re.DOTALL) -if match: - json_str = match.group(1) -else: - json_str = content - -try: - data = json.loads(json_str) - print(json.dumps(data, indent=2)) -except Exception as e: - print("Error parsing response as JSON:", e) - print("Response content:", content) -``` - ## Usage - PDF / Videos / etc. Files ### Inline Data (e.g. audio stream) diff --git a/docs/my-website/docs/providers/sarvam.md b/docs/my-website/docs/providers/sarvam.md deleted file mode 100644 index d77e9c0c75f..00000000000 --- a/docs/my-website/docs/providers/sarvam.md +++ /dev/null @@ -1,89 +0,0 @@ -# Sarvam.ai - -LiteLLM supports all the text models from [Sarvam ai](https://docs.sarvam.ai/api-reference-docs/chat/chat-completions) - -## Usage - -```python -import os -from litellm import completion - -# Set your Sarvam API key -os.environ["SARVAM_API_KEY"] = "" - -messages = [{"role": "user", "content": "Hello"}] - -response = completion( - model="sarvam/sarvam-m", - messages=messages, -) -print(response) -``` - -## Usage with LiteLLM Proxy Server - -Here's how to call a Sarvam.ai model with the LiteLLM Proxy Server - -1. **Modify the `config.yaml`:** - - ```yaml - model_list: - - model_name: my-model - litellm_params: - model: sarvam/ # add sarvam/ prefix to route as Sarvam provider - api_key: api-key # api key to send your model - ``` - -2. **Start the proxy:** - - ```bash - $ litellm --config /path/to/config.yaml - ``` - -3. **Send a request to LiteLLM Proxy Server:** - - - - - - ```python - import openai - - client = openai.OpenAI( - api_key="sk-1234", # pass litellm proxy key, if you're using virtual keys - base_url="http://0.0.0.0:4000" # litellm-proxy-base url - ) - - response = client.chat.completions.create( - model="my-model", - messages=[ - { - "role": "user", - "content": "what llm are you" - } - ], - ) - - print(response) - ``` - - - - - ```shell - curl --location 'http://0.0.0.0:4000/chat/completions' \ - --header 'Authorization: Bearer sk-1234' \ - --header 'Content-Type: application/json' \ - --data '{ - "model": "my-model", - "messages": [ - { - "role": "user", - "content": "what llm are you" - } - ] - }' - ``` - - - diff --git a/docs/my-website/docs/providers/vercel_ai_gateway.md b/docs/my-website/docs/providers/vercel_ai_gateway.md index 3ff007171ed..91f0a18ea1c 100644 --- a/docs/my-website/docs/providers/vercel_ai_gateway.md +++ b/docs/my-website/docs/providers/vercel_ai_gateway.md @@ -11,7 +11,7 @@ import TabItem from '@theme/TabItem'; | Provider Route on LiteLLM | `vercel_ai_gateway/` | | Link to Provider Doc | [Vercel AI Gateway Documentation ↗](https://vercel.com/docs/ai-gateway) | | Base URL | `https://ai-gateway.vercel.sh/v1` | -| Supported Operations | `/chat/completions`, `/embeddings`, `/models` | +| Supported Operations | `/chat/completions`, `/models` |

@@ -73,7 +73,7 @@ messages = [{"content": "Hello, how are you?", "role": "user"}] # Vercel AI Gateway call with streaming response = completion( - model="vercel_ai_gateway/openai/gpt-4o", + model="vercel_ai_gateway/openai/gpt-4o", messages=messages, stream=True ) @@ -82,33 +82,6 @@ for chunk in response: print(chunk) ``` -### Embeddings - -```python showLineNumbers title="Vercel AI Gateway Embeddings" -import os -from litellm import embedding - -os.environ["VERCEL_AI_GATEWAY_API_KEY"] = "your-api-key" - -# Vercel AI Gateway embedding call -response = embedding( - model="vercel_ai_gateway/openai/text-embedding-3-small", - input="Hello world" -) - -print(response.data[0]["embedding"][:5]) # Print first 5 dimensions -``` - -You can also specify the `dimensions` parameter: - -```python showLineNumbers title="Vercel AI Gateway Embeddings with Dimensions" -response = embedding( - model="vercel_ai_gateway/openai/text-embedding-3-small", - input=["Hello world", "Goodbye world"], - dimensions=768 -) -``` - ## Usage - LiteLLM Proxy Add the following to your LiteLLM Proxy configuration file: @@ -124,11 +97,6 @@ model_list: litellm_params: model: vercel_ai_gateway/anthropic/claude-4-sonnet api_key: os.environ/VERCEL_AI_GATEWAY_API_KEY - - - model_name: text-embedding-3-small-gateway - litellm_params: - model: vercel_ai_gateway/openai/text-embedding-3-small - api_key: os.environ/VERCEL_AI_GATEWAY_API_KEY ``` Start your LiteLLM Proxy server: diff --git a/docs/my-website/docs/proxy/cli_sso.md b/docs/my-website/docs/proxy/cli_sso.md index ad0f033f802..cde6bf266d4 100644 --- a/docs/my-website/docs/proxy/cli_sso.md +++ b/docs/my-website/docs/proxy/cli_sso.md @@ -28,37 +28,6 @@ EXPERIMENTAL_UI_LOGIN="True" litellm --config config.yaml ::: -### Configuration - -#### JWT Token Expiration - -By default, CLI authentication tokens expire after **24 hours**. You can customize this expiration time by setting the `LITELLM_CLI_JWT_EXPIRATION_HOURS` environment variable when starting your LiteLLM Proxy: - -```bash -# Set CLI JWT tokens to expire after 48 hours -export LITELLM_CLI_JWT_EXPIRATION_HOURS=48 -export EXPERIMENTAL_UI_LOGIN="True" -litellm --config config.yaml -``` - -Or in a single command: - -```bash -LITELLM_CLI_JWT_EXPIRATION_HOURS=48 EXPERIMENTAL_UI_LOGIN="True" litellm --config config.yaml -``` - -**Examples:** -- `LITELLM_CLI_JWT_EXPIRATION_HOURS=12` - Tokens expire after 12 hours -- `LITELLM_CLI_JWT_EXPIRATION_HOURS=168` - Tokens expire after 7 days (168 hours) -- `LITELLM_CLI_JWT_EXPIRATION_HOURS=720` - Tokens expire after 30 days (720 hours) - -:::tip -You can check your current token's age and expiration status using: -```bash -litellm-proxy whoami -``` -::: - ### Steps 1. **Install the CLI** diff --git a/docs/my-website/docs/proxy/config_settings.md b/docs/my-website/docs/proxy/config_settings.md index 37e58d55407..6d3fa206113 100644 --- a/docs/my-website/docs/proxy/config_settings.md +++ b/docs/my-website/docs/proxy/config_settings.md @@ -462,7 +462,6 @@ router_settings: | CHATGPT_USER_AGENT_SUFFIX | Suffix to append to the ChatGPT user agent string | CIRCLE_OIDC_TOKEN | OpenID Connect token for CircleCI | CIRCLE_OIDC_TOKEN_V2 | Version 2 of the OpenID Connect token for CircleCI -| CLI_JWT_EXPIRATION_HOURS | Expiration time in hours for CLI-generated JWT tokens. Default is 24 hours. Can also be set via LITELLM_CLI_JWT_EXPIRATION_HOURS | CLOUDZERO_API_KEY | CloudZero API key for authentication | CLOUDZERO_CONNECTION_ID | CloudZero connection ID for data submission | CLOUDZERO_EXPORT_INTERVAL_MINUTES | Interval in minutes for CloudZero data export operations @@ -724,7 +723,6 @@ router_settings: | LITERAL_API_URL | API URL for Literal service | LITERAL_BATCH_SIZE | Batch size for Literal operations | LITELLM_ANTHROPIC_DISABLE_URL_SUFFIX | Disable automatic URL suffix appending for Anthropic API base URLs. When set to `true`, prevents LiteLLM from automatically adding `/v1/messages` or `/v1/complete` to custom Anthropic API endpoints -| LITELLM_CLI_JWT_EXPIRATION_HOURS | Expiration time in hours for CLI-generated JWT tokens. Default is 24 hours | LITELLM_DD_AGENT_HOST | Hostname or IP of DataDog agent for LiteLLM-specific logging. When set, logs are sent to agent instead of direct API | LITELLM_DD_AGENT_PORT | Port of DataDog agent for LiteLLM-specific log intake. Default is 10518 | LITELLM_DONT_SHOW_FEEDBACK_BOX | Flag to hide feedback box in LiteLLM UI diff --git a/docs/my-website/docs/proxy/deploy.md b/docs/my-website/docs/proxy/deploy.md index 0761e0e9fa8..7393e73ba87 100644 --- a/docs/my-website/docs/proxy/deploy.md +++ b/docs/my-website/docs/proxy/deploy.md @@ -200,7 +200,6 @@ Example `requirements.txt` ```shell litellm[proxy]==1.57.3 # Specify the litellm version you want to use -litellm-enterprise prometheus_client langfuse prisma diff --git a/docs/my-website/docs/proxy/guardrails/onyx_security.md b/docs/my-website/docs/proxy/guardrails/onyx_security.md index d240902eb52..85b0ba9f830 100644 --- a/docs/my-website/docs/proxy/guardrails/onyx_security.md +++ b/docs/my-website/docs/proxy/guardrails/onyx_security.md @@ -128,7 +128,6 @@ guardrails: mode: ["pre_call", "post_call", "during_call"] # Run at multiple stages api_key: os.environ/ONYX_API_KEY api_base: os.environ/ONYX_API_BASE - timeout: 10.0 # Optional, defaults to 10 seconds ``` ### Required Parameters @@ -138,7 +137,6 @@ guardrails: ### Optional Parameters - **`api_base`**: Onyx API base URL (defaults to `https://ai-guard.onyx.security`) -- **`timeout`**: Request timeout in seconds (defaults to `10.0`) ## Environment Variables @@ -147,5 +145,4 @@ You can set these environment variables instead of hardcoding values in your con ```shell export ONYX_API_KEY="your-api-key-here" export ONYX_API_BASE="https://ai-guard.onyx.security" # Optional -export ONYX_TIMEOUT=10 # Optional, timeout in seconds ``` diff --git a/docs/my-website/docs/proxy/guardrails/quick_start.md b/docs/my-website/docs/proxy/guardrails/quick_start.md index ddb215fcb66..cb6379d49f4 100644 --- a/docs/my-website/docs/proxy/guardrails/quick_start.md +++ b/docs/my-website/docs/proxy/guardrails/quick_start.md @@ -405,10 +405,14 @@ curl --location 'http://0.0.0.0:4000/chat/completions' \ ## **Proxy Admin Controls** -### Monitoring Guardrails +### ✨ Monitoring Guardrails Monitor which guardrails were executed and whether they passed or failed. e.g. guardrail going rogue and failing requests we don't intend to fail +:::info + +✨ This is an Enterprise only feature [Get a free trial](https://www.litellm.ai/enterprise#trial) + ::: #### Setup diff --git a/docs/my-website/docs/proxy/keys_teams_router_settings.md b/docs/my-website/docs/proxy/keys_teams_router_settings.md deleted file mode 100644 index ec59e8f271b..00000000000 --- a/docs/my-website/docs/proxy/keys_teams_router_settings.md +++ /dev/null @@ -1,150 +0,0 @@ -import Image from '@theme/IdealImage'; - -# UI - Router Settings for Keys and Teams - -Configure router settings at the key and team level to achieve granular control over routing behavior, fallbacks, retries, and other router configurations. This enables you to customize routing behavior for specific keys or teams without affecting global settings. - -## Overview - -Router Settings for Keys and Teams allows you to configure router behavior at different levels of granularity. Previously, router settings could only be configured globally, applying the same routing strategy, fallbacks, timeouts, and retry policies to all requests across your entire proxy instance. - -With key-level and team-level router settings, you can now: - -- **Customize routing strategies** per key or team (e.g., use `least-busy` for high-priority keys, `latency-based-routing` for others) -- **Configure different fallback chains** for different keys or teams -- **Set key-specific or team-specific timeouts** and retry policies -- **Apply different reliability settings** (cooldowns, allowed failures) per key or team -- **Override global settings** when needed for specific use cases - - - -## Summary - -Router settings follow a **hierarchical resolution order**: **Keys > Teams > Global**. When a request is made: - -1. **Key-level settings** are checked first. If router settings are configured for the API key being used, those settings are applied. -2. **Team-level settings** are checked next. If the key belongs to a team and that team has router settings configured, those settings are used (unless key-level settings exist). -3. **Global settings** are used as the final fallback. If neither key nor team settings are found, the global router settings from your proxy configuration are applied. - -This hierarchical approach ensures that the most specific settings take precedence, allowing you to fine-tune routing behavior for individual keys or teams while maintaining sensible defaults at the global level. - -## How Router Settings Resolution Works - -Router settings are resolved in the following priority order: - -### Resolution Order: Key > Team > Global - -1. **Key-level router settings** (highest priority) - - Applied when router settings are configured directly on an API key - - Takes precedence over all other settings - - Useful for individual key customization - -2. **Team-level router settings** (medium priority) - - Applied when the API key belongs to a team with router settings configured - - Only used if no key-level settings exist - - Useful for applying consistent settings across multiple keys in a team - -3. **Global router settings** (lowest priority) - - Applied from your proxy configuration file or database - - Used as the default when no key or team settings are found - - Previously, this was the only option available - -## How to Configure Router Settings - -### Configuring Router Settings for Keys - -Follow these steps to configure router settings for an API key: - -1. Navigate to [http://localhost:4000/ui/?login=success](http://localhost:4000/ui/?login=success) - -![](https://colony-recorder.s3.amazonaws.com/files/2026-01-24/61889da3-32de-4ebf-9cf3-7dc1db2fc993/ascreenshot_2492cf6d916a4ab98197cc8336e3a371_text_export.jpeg) - -2. Click "+ Create New Key" (or edit an existing key) - -![](https://colony-recorder.s3.amazonaws.com/files/2026-01-24/61889da3-32de-4ebf-9cf3-7dc1db2fc993/ascreenshot_5a25380cf5044b4f93c146139d84403a_text_export.jpeg) - -3. Click "Optional Settings" - -![](https://colony-recorder.s3.amazonaws.com/files/2026-01-24/e5eb5858-1cc1-4273-90bd-19ad139feebd/ascreenshot_33888989cfb9445bb83660f702ba32e0_text_export.jpeg) - -4. Click "Router Settings" - -![](https://colony-recorder.s3.amazonaws.com/files/2026-01-24/d9eeca83-1f76-4fcf-bf61-d89edf3454d3/ascreenshot_825c7993f4b24949aee9b31d4a788d8a_text_export.jpeg) - -5. Configure your desired router settings. For example, click "Fallbacks" to configure fallback models: - -![](https://colony-recorder.s3.amazonaws.com/files/2026-01-24/30ff647f-0254-4410-8311-660eef7ec0c4/ascreenshot_16966c8a0160473eb03e0f2c3b5c3afa_text_export.jpeg) - -6. Click "Select a model to begin configuring fallbacks" and configure your fallback chain: - -![](https://colony-recorder.s3.amazonaws.com/files/2026-01-24/918f1b5b-c656-4864-98bd-d8c58924b6d9/ascreenshot_79ca6cd93be04033929f080e0c8d040a_text_export.jpeg) - -### Configuring Router Settings for Teams - -Follow these steps to configure router settings for a team: - -1. Navigate to [http://localhost:4000/ui/?login=success](http://localhost:4000/ui/?login=success) - -![](https://colony-recorder.s3.amazonaws.com/files/2026-01-24/60a33a8c-2e48-4788-a1a2-e5bcffa98cca/ascreenshot_9e255ba48f914c72ae57db7d3c1c7cd5_text_export.jpeg) - -2. Click "Teams" - -![](https://colony-recorder.s3.amazonaws.com/files/2026-01-24/60a33a8c-2e48-4788-a1a2-e5bcffa98cca/ascreenshot_070934fa9c17453987f21f58117e673b_text_export.jpeg) - -3. Click "+ Create New Team" (or edit an existing team) - -![](https://colony-recorder.s3.amazonaws.com/files/2026-01-24/6f964ce2-f458-4719-a070-1af444ad92f5/ascreenshot_10f427f3106a4032a65d1046668880bd_text_export.jpeg) - -4. Click "Router Settings" - -![](https://colony-recorder.s3.amazonaws.com/files/2026-01-24/a923c4ae-29f2-42b5-93ae-12f62d442691/ascreenshot_144520f2dd2f419dad79dffb1579ec04_text_export.jpeg) - -5. Configure your desired router settings. For example, click "Fallbacks" to configure fallback models: - -![](https://colony-recorder.s3.amazonaws.com/files/2026-01-24/b062ecfa-bf5b-4c99-93a1-84b8b56fdb4c/ascreenshot_ea9acbc4e75448709b64a22addfb4157_text_export.jpeg) - -6. Click "Select a model to begin configuring fallbacks" and configure your fallback chain: - -![](https://colony-recorder.s3.amazonaws.com/files/2026-01-24/67ca2655-4e82-4f93-be9a-7244ad22640f/ascreenshot_4fdbed826cd546d784e8738626be835d_text_export.jpeg) - -## Use Cases - -### Different Routing Strategies per Key - -Configure different routing strategies for different use cases: - -- **High-priority production keys**: Use `latency-based-routing` for optimal performance -- **Development keys**: Use `simple-shuffle` for simplicity -- **Cost-sensitive keys**: Use `cost-based-routing` to minimize expenses - -### Team-Level Consistency - -Apply consistent router settings across all keys in a team: - -- Set team-wide fallback chains for reliability -- Configure team-specific timeout policies -- Apply uniform retry policies across team members - -### Override Global Settings - -Override global settings for specific scenarios: - -- Production keys may need stricter timeout policies than development -- Certain teams may require different fallback models -- Individual keys may need custom retry policies for specific use cases - -### Gradual Rollout - -Test new router settings on specific keys or teams before applying globally: - -- Configure new routing strategies on a test key first -- Validate fallback chains on a small team before global rollout -- A/B test different timeout values across different keys - -## Related Features - -- [Router Settings Reference](./config_settings.md#router_settings---reference) - Complete reference of all router settings -- [Load Balancing](./load_balancing.md) - Learn about routing strategies and load balancing -- [Reliability](./reliability.md) - Configure fallbacks, retries, and error handling -- [Keys](./keys.md) - Manage API keys and their settings -- [Teams](./teams.md) - Organize keys into teams diff --git a/docs/my-website/docs/proxy/litellm_managed_files.md b/docs/my-website/docs/proxy/litellm_managed_files.md index 6272180bd40..7aba173f35b 100644 --- a/docs/my-website/docs/proxy/litellm_managed_files.md +++ b/docs/my-website/docs/proxy/litellm_managed_files.md @@ -11,7 +11,7 @@ import Image from '@theme/IdealImage'; This is a free LiteLLM Enterprise feature. -Available via the `litellm` docker image. If you are using the pip package, you must install [`litellm-enterprise`](https://pypi.org/project/litellm-enterprise/). +Available via the `litellm[proxy]` package or any `litellm` docker image. ::: diff --git a/docs/my-website/docs/proxy/prometheus.md b/docs/my-website/docs/proxy/prometheus.md index 93a0675f097..cd2b3b68f37 100644 --- a/docs/my-website/docs/proxy/prometheus.md +++ b/docs/my-website/docs/proxy/prometheus.md @@ -121,8 +121,8 @@ Use this to track overall LiteLLM Proxy usage. | Metric Name | Description | |----------------------|--------------------------------------| -| `litellm_proxy_failed_requests_metric` | Total number of failed responses from proxy - the client did not get a success response from litellm proxy. Labels: `"end_user", "hashed_api_key", "api_key_alias", "requested_model", "team", "team_alias", "user", "user_email", "exception_status", "exception_class", "route", "model_id"` | -| `litellm_proxy_total_requests_metric` | Total number of requests made to the proxy server - track number of client side requests. Labels: `"end_user", "hashed_api_key", "api_key_alias", "requested_model", "team", "team_alias", "user", "status_code", "user_email", "route", "model_id"` | +| `litellm_proxy_failed_requests_metric` | Total number of failed responses from proxy - the client did not get a success response from litellm proxy. Labels: `"end_user", "hashed_api_key", "api_key_alias", "requested_model", "team", "team_alias", "user", "exception_status", "exception_class", "route"` | +| `litellm_proxy_total_requests_metric` | Total number of requests made to the proxy server - track number of client side requests. Labels: `"end_user", "hashed_api_key", "api_key_alias", "requested_model", "team", "team_alias", "user", "status_code", "user_email", "route"` | ### Callback Logging Metrics @@ -130,12 +130,7 @@ Monitor failures while shipping logs to downstream callbacks like `s3_v3` cold s | Metric Name | Description | |----------------------|--------------------------------------| -| `litellm_callback_logging_failures_metric` | Total number of failed attempts to emit logs to a configured callback. Labels: `"callback_name"`. Use this to alert on callback delivery issues such as repeated failures when writing to `s3_v3`, `langfuse`, or `langfuse_otel` and other otel providers | - -**Supported Callbacks:** -- `S3Logger` - S3 v2 cold storage failures -- `langfuse` - Langfuse logging failures -- `otel` - OpenTelemetry logging failures +| `litellm_callback_logging_failures_metric` | Total number of failed attempts to emit logs to a configured callback. Labels: `"callback_name"`. Use this to alert on callback delivery issues such as repeated failures when writing to `s3_v3`. | ## LLM Provider Metrics @@ -196,10 +191,10 @@ Use this for LLM API Error monitoring and tracking remaining rate limits and tok | Metric Name | Description | |----------------------|--------------------------------------| -| `litellm_request_total_latency_metric` | Total latency (seconds) for a request to LiteLLM Proxy Server - tracked for labels "end_user", "hashed_api_key", "api_key_alias", "requested_model", "team", "team_alias", "user", "model", "model_id" | +| `litellm_request_total_latency_metric` | Total latency (seconds) for a request to LiteLLM Proxy Server - tracked for labels "end_user", "hashed_api_key", "api_key_alias", "requested_model", "team", "team_alias", "user", "model" | | `litellm_overhead_latency_metric` | Latency overhead (seconds) added by LiteLLM processing - tracked for labels "model_group", "api_provider", "api_base", "litellm_model_name", "hashed_api_key", "api_key_alias" | | `litellm_llm_api_latency_metric` | Latency (seconds) for just the LLM API call - tracked for labels "model", "hashed_api_key", "api_key_alias", "team", "team_alias", "requested_model", "end_user", "user" | -| `litellm_llm_api_time_to_first_token_metric` | Time to first token for LLM API call - tracked for labels `model`, `hashed_api_key`, `api_key_alias`, `team`, `team_alias`, `requested_model`, `end_user`, `user`, `model_id` [Note: only emitted for streaming requests] | +| `litellm_llm_api_time_to_first_token_metric` | Time to first token for LLM API call - tracked for labels `model`, `hashed_api_key`, `api_key_alias`, `team`, `team_alias` [Note: only emitted for streaming requests] | ## Tracking `end_user` on Prometheus diff --git a/docs/my-website/docs/proxy/ui/page_visibility.md b/docs/my-website/docs/proxy/ui/page_visibility.md deleted file mode 100644 index 06b06f33219..00000000000 --- a/docs/my-website/docs/proxy/ui/page_visibility.md +++ /dev/null @@ -1,121 +0,0 @@ -import Image from '@theme/IdealImage'; - -# Control Page Visibility for Internal Users - -Configure which navigation tabs and pages are visible to internal users (non-admin developers) in the LiteLLM UI. - -Use this feature to simplify the UI and control which pages your internal users/developers can see when signing in. - -## Overview - -By default, all pages accessible to internal users are visible in the navigation sidebar. The page visibility control allows admins to restrict which pages internal users can see, creating a more focused and streamlined experience. - - -## Configure Page Visibility - -### 1. Navigate to Settings - -Click the **Settings** icon in the sidebar. - -![Navigate to Settings](https://colony-recorder.s3.amazonaws.com/files/2026-01-28/cbb6f272-ab18-4996-b57d-7ed4aad721ea/ascreenshot_ab80f3175b1a41b0bdabdd2cd3980573_text_export.jpeg) - -### 2. Go to Admin Settings - -Click **Admin Settings** from the settings menu. - -![Go to Admin Settings](https://colony-recorder.s3.amazonaws.com/files/2026-01-28/e2b327bf-1cfd-4519-a9ce-8a6ecb2de53a/ascreenshot_23bb1577b3f84d22be78e0faa58dee3d_text_export.jpeg) - -### 3. Select UI Settings - -Click **UI Settings** to access the page visibility controls. - -![Select UI Settings](https://colony-recorder.s3.amazonaws.com/files/2026-01-28/fff0366a-4944-457a-8f6a-e22018dde108/ascreenshot_0e268e8651654e75bb9fb40d2ed366a9_text_export.jpeg) - -### 4. Open Page Visibility Configuration - -Click **Configure Page Visibility** to expand the configuration panel. - -![Open Configuration](https://colony-recorder.s3.amazonaws.com/files/2026-01-28/3a4761d6-145a-4afd-8abf-d92744b9ac9f/ascreenshot_23c16eb79c32481887b879d961f1f00a_text_export.jpeg) - -### 5. Select Pages to Make Visible - -Check the boxes for the pages you want internal users to see. Pages are organized by category for easy navigation. - -![Select Pages](https://colony-recorder.s3.amazonaws.com/files/2026-01-28/b9c96b54-6c20-484f-8b0b-3a86decb5717/ascreenshot_3347ade01ebe4ea390bc7b57e53db43f_text_export.jpeg) - -**Available pages include:** -- Virtual Keys -- Playground -- Models + Endpoints -- Agents -- MCP Servers -- Search Tools -- Vector Stores -- Logs -- Teams -- Organizations -- Usage -- Budgets -- And more... - -### 6. Save Your Configuration - -Click **Save Page Visibility Settings** to apply the changes. - -![Save Settings](https://colony-recorder.s3.amazonaws.com/files/2026-01-28/8a215378-44f5-4bb8-b984-06fa2aa03903/ascreenshot_44e7aeebe25a477ba92f73a3ed3df644_text_export.jpeg) - -### 7. Verify Changes - -Internal users will now only see the selected pages in their navigation sidebar. - -![Verify Changes](https://colony-recorder.s3.amazonaws.com/files/2026-01-28/493a7718-b276-40b9-970f-5814054932d9/ascreenshot_ad23b8691f824095ba60256f91ad24f8_text_export.jpeg) - -## Reset to Default - -To restore all pages to internal users: - -1. Open the Page Visibility configuration -2. Click **Reset to Default (All Pages)** -3. Click **Save Page Visibility Settings** - -This will clear the restriction and show all accessible pages to internal users. - -## API Configuration - -You can also configure page visibility programmatically using the API: - -### Get Current Settings - -```bash -curl -X GET 'http://localhost:4000/ui_settings/get' \ - -H 'Authorization: Bearer ' -``` - -### Update Page Visibility - -```bash -curl -X PATCH 'http://localhost:4000/ui_settings/update' \ - -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - -d '{ - "enabled_ui_pages_internal_users": [ - "api-keys", - "agents", - "mcp-servers", - "logs", - "teams" - ] - }' -``` - -### Clear Page Visibility Restrictions - -```bash -curl -X PATCH 'http://localhost:4000/ui_settings/update' \ - -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - -d '{ - "enabled_ui_pages_internal_users": null - }' -``` - diff --git a/docs/my-website/docs/rag_ingest.md b/docs/my-website/docs/rag_ingest.md index 7adc2d70b5b..1133b85f206 100644 --- a/docs/my-website/docs/rag_ingest.md +++ b/docs/my-website/docs/rag_ingest.md @@ -5,7 +5,7 @@ All-in-one document ingestion pipeline: **Upload → Chunk → Embed → Vector | Feature | Supported | |---------|-----------| | Logging | Yes | -| Supported Providers | `openai`, `bedrock`, `vertex_ai`, `gemini`, `s3_vectors` | +| Supported Providers | `openai`, `bedrock`, `vertex_ai`, `gemini` | :::tip After ingesting documents, use [/rag/query](./rag_query.md) to search and generate responses with your ingested content. @@ -75,31 +75,6 @@ curl -X POST "http://localhost:4000/v1/rag/ingest" \ }" ``` -### AWS S3 Vectors - -```bash showLineNumbers title="Ingest to S3 Vectors" -curl -X POST "http://localhost:4000/v1/rag/ingest" \ - -H "Authorization: Bearer sk-1234" \ - -H "Content-Type: application/json" \ - -d "{ - \"file\": { - \"filename\": \"document.txt\", - \"content\": \"$(base64 -i document.txt)\", - \"content_type\": \"text/plain\" - }, - \"ingest_options\": { - \"embedding\": { - \"model\": \"text-embedding-3-small\" - }, - \"vector_store\": { - \"custom_llm_provider\": \"s3_vectors\", - \"vector_bucket_name\": \"my-embeddings\", - \"aws_region_name\": \"us-west-2\" - } - } - }" -``` - ## Response ```json @@ -290,57 +265,6 @@ When `vector_store_id` is omitted, LiteLLM automatically creates: 4. Install: `pip install 'google-cloud-aiplatform>=1.60.0'` ::: -### vector_store (AWS S3 Vectors) - -| Parameter | Type | Default | Description | -|-----------|------|---------|-------------| -| `custom_llm_provider` | string | - | `"s3_vectors"` | -| `vector_bucket_name` | string | **required** | S3 vector bucket name | -| `index_name` | string | auto-create | Vector index name | -| `dimension` | integer | auto-detect | Vector dimension (auto-detected from embedding model) | -| `distance_metric` | string | `cosine` | Distance metric: `cosine` or `euclidean` | -| `non_filterable_metadata_keys` | array | `["source_text"]` | Metadata keys excluded from filtering | -| `aws_region_name` | string | `us-west-2` | AWS region | -| `aws_access_key_id` | string | env | AWS access key | -| `aws_secret_access_key` | string | env | AWS secret key | - -:::info S3 Vectors Auto-Creation -When `index_name` is omitted, LiteLLM automatically creates: -- S3 vector bucket (if it doesn't exist) -- Vector index with auto-detected dimensions from your embedding model - -**Dimension Auto-Detection**: The vector dimension is automatically detected by making a test embedding request to your specified model. No need to manually specify dimensions! - -**Supported Embedding Models**: Works with any LiteLLM-supported embedding model (OpenAI, Cohere, Bedrock, Azure, etc.) -::: - -**Example with auto-detection:** -```json -{ - "embedding": { - "model": "text-embedding-3-small" // Dimension auto-detected as 1536 - }, - "vector_store": { - "custom_llm_provider": "s3_vectors", - "vector_bucket_name": "my-embeddings" - } -} -``` - -**Example with custom embedding provider:** -```json -{ - "embedding": { - "model": "cohere/embed-english-v3.0" // Dimension auto-detected as 1024 - }, - "vector_store": { - "custom_llm_provider": "s3_vectors", - "vector_bucket_name": "my-embeddings", - "distance_metric": "cosine" - } -} -``` - ## Input Examples ### File (Base64) diff --git a/docs/my-website/docs/routing.md b/docs/my-website/docs/routing.md index 2b3a28edf75..47967775e1e 100644 --- a/docs/my-website/docs/routing.md +++ b/docs/my-website/docs/routing.md @@ -830,12 +830,6 @@ asyncio.run(router_acompletion()) -## Traffic Mirroring / Silent Experiments - -Traffic mirroring allows you to "mimic" production traffic to a secondary (silent) model for evaluation purposes. The silent model's response is gathered in the background and does not affect the latency or result of the primary request. - -[**See detailed guide on A/B Testing - Traffic Mirroring here**](./traffic_mirroring.md) - ## Basic Reliability ### Deployment Ordering (Priority) diff --git a/docs/my-website/docs/traffic_mirroring.md b/docs/my-website/docs/traffic_mirroring.md deleted file mode 100644 index 3bdcb0f1614..00000000000 --- a/docs/my-website/docs/traffic_mirroring.md +++ /dev/null @@ -1,83 +0,0 @@ -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - -# A/B Testing - Traffic Mirroring - -Traffic mirroring allows you to "mimic" production traffic to a secondary (silent) model for evaluation purposes. The silent model's response is gathered in the background and does not affect the latency or result of the primary request. - -This is useful for: -- Testing a new model's performance on production prompts before switching. -- Comparing costs and latency between different providers. -- Debugging issues by mirroring traffic to a more verbose model. - -## Quick Start - -To enable traffic mirroring, add `silent_model` to the `litellm_params` of a deployment. - - - - -```python -from litellm import Router - -model_list = [ - { - "model_name": "gpt-3.5-turbo", - "litellm_params": { - "model": "azure/chatgpt-v-2", - "api_key": "...", - "silent_model": "gpt-4" # 👈 Mirror traffic to gpt-4 - }, - }, - { - "model_name": "gpt-4", - "litellm_params": { - "model": "openai/gpt-4", - "api_key": "..." - }, - } -] - -router = Router(model_list=model_list) - -# The request to "gpt-3.5-turbo" will trigger a background call to "gpt-4" -response = await router.acompletion( - model="gpt-3.5-turbo", - messages=[{"role": "user", "content": "How does traffic mirroring work?"}] -) -``` - - - - -Add `silent_model` to your `config.yaml`: - -```yaml -model_list: - - model_name: primary-model - litellm_params: - model: azure/gpt-35-turbo - api_key: os.environ/AZURE_API_KEY - silent_model: evaluation-model # 👈 Mirror traffic here - - model_name: evaluation-model - litellm_params: - model: openai/gpt-4o - api_key: os.environ/OPENAI_API_KEY -``` - - - - -## How it works -1. **Request Received**: A request is made to a model group (e.g. `primary-model`). -2. **Deployment Picked**: LiteLLM picks a deployment from the group. -3. **Primary Call**: LiteLLM makes the call to the primary deployment. -4. **Mirroring**: If `silent_model` is present, LiteLLM triggers a background call to that model. - - For **Sync** calls: Uses a shared thread pool. - - For **Async** calls: Uses `asyncio.create_task`. -5. **Isolation**: The background call uses a `deepcopy` of the original request parameters and sets `metadata["is_silent_experiment"] = True`. It also strips out logging IDs to prevent collisions in usage tracking. - -## Key Features -- **Latency Isolation**: The primary request returns as soon as it's ready. The background (silent) call does not block. -- **Unified Logging**: Background calls are processed via the Router, meaning they are automatically logged to your configured observability tools (Langfuse, S3, etc.). -- **Evaluation**: Use the `is_silent_experiment: True` flag in your logs to filter and compare results between the primary and mirrored calls. diff --git a/docs/my-website/img/ui_granular_router_settings.png b/docs/my-website/img/ui_granular_router_settings.png deleted file mode 100644 index 6242679956c763435d313620e372efd6051672ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 359348 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

IUTGW+bd_A ze9dsy$`o;Qb8p}79~=<=gPG$}vJV!hN>FoU)9H~opTfn?4*|&|Ee$nNhK(#tMu_(P zd}*9s&Gm6TOz}L0P7nst>#?!_V8P=8;!fDD0;)0LA~E>fi~fDl`}Q>vI2WCKs(X6M znpawhm1ssK7SJ&I!V$c(S1){`nP6D`96;RB=J~nW*6zRlGW*xS(?%`a9P8;&#Fi(R zW^`PA8*CA|>^0*x+4=xtGloywTKRYvUJWN$oxFeh_LSI2nQ6^UgG#U1C|}TTaryF- z$B#R8pS35B*3JiL0K}Js9_H7SHr*)*ogUfBYw(*HysFhNX8kItir(p7ySJarZWYg1 zSp={l(Gb?@YN=Ue2fVSMan8!R4!q=MWLXn^e+ZWR?i8jtJsl{UA#J)D`h>B1pZxZI z-<8HW*8MM1nmo@4Rw#U?7KtUe6od+=%QwZd7WDWY4jovx&pbBrRp}Fne5zp3)!Apw zQgZK}c6;xa<1+z2_H%cA^k`SHZqXi>b>&^^ojB#|2u5c>Ctb#c=3sCNbXKl*X1YKS z(gcAuS5JhW3w`4AYjJm_8WcQKXX50VIM7*QGCv4u^x9Ke;Y?>EORSuhUJbBu{*Ya4 zh|%5H6%GcH7mOabNm}C{*VpU6`3O=##YW2#bo%K@tTZ3Y1e+c2?C99v>U+3%siZ(u zf|;!TWMuTsU+nS%D6>TW;dkGIJ;$6yam96k}qs<;T4Yv8Iu z0R$P_!mUWk`sl$_zJq?|ak2#=d92>4Tur2FE5&-cIZBZPkcY@-G>y?~A&$j%ppu^S zd&@Bo!DhgzS=LT?oy-IJ$Nl||`Gr))9*+cDN3pFAbS%0toI$UFO?o){?8UU&{@rzp z?Smfz=6<<1^dUxqJpRvE^Cw`;{Nf9a^Pc8@dAwbvaWXBww9*-2;0NA%+Mk`oE{F|t zR0+MLWsN@h)5~_}?ut{f()hS;+_MOd&c%_I=-`9Td;4MmT^*caF%je1e!15e?{BCF zFIWSJC#IG@CqfFOrEGzqc+bh!%V~-0~G^9kYOY{F%qXWFo)z z7%)~~12KSAh1sm-&AF!CG=aD=(!-mlZZ5V(w9MRX2DTj`?yHkSJJoF>->JCgFl_n( zun^gjSFNLIW&g3Gxu?71WJb#@;kMWdw>~Qt*(s(*l;cE!gOOq>j{EYqWo(k!aVOo( zvY|NDY}KxptC6a?j{CZ&oSu$J3RqLb>$Ue^v)_5J-`#>KY_wYoYy9AOc?XP*jjzbP z`K8%snK_8qeycEuIlJ&3V$ajHdPr-m`5mxz=|NL^QBGLbtC?CouQ^?FsuzCXO1y{m zVj(Z=b7FKqDi}Zc@}M~L zB}a-)T5?v}U}ZzO(;o!oD0!?tcab<|Y&Mu)Hf4j=j$bVP;)fE+f}=Mf=TgZ8fbbHo_i?$>NaUg z`~hANJ?w)yxHr=H-mK}0(OgAQIN=XbeAZbd)4s;r`0FL8&CLHitqkd&EGv?ES{ZP1f{%C#v|C-AN@V@8RRA#GFK0I7Ta%ZBpz#iFFVDb){ksq*(xKJxN7RTyX4<=IDsCv zdPmOP4=(-3p`WEC97ze#rFQs~W?3&M|JGIBB-PqCNzi4LOTNykNO^q6e=%xDO-sP{ zAD^C>VyKsLuG~ab_%j>cbpuZ`9#U@UW~cY0Ygoqu@@5>#Gei!-&rTK zp&<_?-KegfiE(r+uKNXk;J^XbKJg&m37&?5#K#dc5ZPI(up3o`y|KqjVO_*U9oWsr z3hYY{ckSWA1+NlGUL%iiADZzF=#8>u399#=@#LW?oSOqGp0hqo?N#0lAOBgs~lf3lS_T0T}KW8VbcJ|psVg4b}Xxmz$e4O;97?u}yJb7t3 z`0{0BmgBzXFhh8^a2R)W7E{t6kd>PYe@<*@XfQ|to1>3)JC$Sz(i;pCz;@VHh|QVr zaWaO|04v+f{^NlqNePX9HWmt_(FS?=X0JT1)4;-5e1kRd? zQaf^b^;j@-kKLD=7U9K^HrrUQoU=wfTf8NNGT~&U^-6Pj=$W6$9PC!{H>FwU0v{Qa z+s4bXRs%XK@8a;o5#J0OJDZlfJKG8eiy6!e?MKW;CpXDDOZgunU{`S_HyIvnRYor(gJAC-Q8l<-BE{s^$@2 z)y%{=tDZ{?Irp@2KYOwBb)>Z?tE=kX@?hV6+mare4aeq1$4&y_;zi|nH5O_Z&W32d zAYh`e<0VA~55P^{)@$K4M<6bLd3OBxal$3G_`_L8Cr9_Mh&|Qv1FnF^MJJQRWu-Yg zYP&nMIOS%;gUx`K_DjftS4Z%W+PuncznP5N256yTi{U?U(V`nFbwFej>slcR7rWzT z55Nun;s4Xb5pD}$4a711h|0crAY>8a1|NTRnZ8A#Q{FG#E33xKKIpG!xX#RsP!lmt zP(2UOuHJR#(c$Hz?m9*V9ck+DGT=;6pY%36`2G>kTUhNPo#^PkhN1%gPmI8Y6Ph0d z^6%;U+aCtY$8=>U6auIuSU?@d9dU5>J^04=t2ao8O0YJq@a02TFyt!u{%N9Dlr^u0H1U; zAiFZE={+7p9)Q8`k?VK3sN1Z5pR`>}>U#Ndu;OBoUl|bNeR=)*zks)FqOTx9pjIFb ze)d!AQXQr4L`wdfnzt_IA3bsk_U|d@oFQo0SsSI1Zw|jrYM-T}TRjcup>I}>x^8*B zK@NXaeXFPc{%?aHJ`9H2SM~2AL0IpIL-#w~l0AZ>ATbB?YE9>ctT5zQbmhdNV@bq{ zCh;>5(2FCz>$RsY=n%C5m+e#IOFbSg9bs?}yur@+8cEF&&n-ru*`sqqA)*?D`=@rV$ z6bF-&C(_ZOQHv+78wl%-9^e?8I+~PF&2jAR{BSnr`0)xSe@n$mfnuy#Xo}Act!qKg zCT(vG<+@T_DG(PZU20kr0&6rt>1CUjvQ(YB#p1Xc?*_lchmNH!TD4-yJOxbdT?-8?R~#l`kqflzmZF1*(BAlH@Af@H%4 z7W`KIc^oLE6=*E+FWc5Adi<5XZcRUc6Q|*t=kE<-Ge|%u!!+D1oaXN&+dlvK z-(OczH+LqyOyp~4;x=FXEQWIu^qfj`GRn%z43c2K5=YO#9vSrSs;y8cms0g zl6S1Iw|S8OgS}iF5pYp!A3S8WO4(%d=ID}9f{)#1L(z08N5+g>#IIyemEHDeLBhOE zW3`>Kv%5y_2SzPEbyp?b0uPgNrlzLil;VbambN;0$#^h#7{|5v<@xHbMoHiN9*7sK zE2p>9(1&!}Byr@){44|@uLt4?;&tHtTvdeaYWq(1sgr41i7l@V=28I9@Q29p>w)%% zm9m90Xf8?4A7E6ocp6A`psal?=mk9Z37pkJfc%nAsdZ9iYFRv-C{(-BWi-vVAv#AY!T|XYIl`ag}11fD-K@nYo@4C4U zgI^~%W@pvh;%p`2j1(WdI61>g8K-l8{*Cy3A-F**U8=}^y--ZO>bk{|NJ6v#3%Uuf z%P^7+BeK+!-lsl)-@F|o{?2tZYFm9#j4B;P$k~Xl%SFjowoz8x!s7xzW8m`(n}Lju z$oiW0Q1e4v+qnNpE*$jFkAcS3DNlcY|B@7))yXXemp&$;cmE7kWQM5cItJH`x+-sw z0oo7VK-|2Pcsv6}F0a_>4thl>hYPQ{(rrwoMC_2`XQ6;aIBDaN7qx3$g;fyP9b^=+ zef^V`D^akyEtDM0ngfJA4Gn_ozW9?0ZlZ!Erg9Q3u~UcbZ03a0b*OTEM53;|)~29B zGpDA?JR1DYc_*_88X!=5Pmfb^DP%&FtDDKycj|gQcumPVpp2Gf(*+iOGrjrG-)|SK z4$e!St7Czd8TqCaz3;)`MT-fyu1AHpHa-OQ^xZC)qj2OauLch16?|LZ72fi=HA^`2 zak8$mJ5%M5Emw0(trM;&2%er0=|7w(&4Iyo)YQNOcZDwEY8Mpjr%u{0kR@LrO0JBu zpm@o;sh~#ndQ<*Cr%N2$FflQ+QSdp-*wgMlv9R&YcLQBGA%(7q zk&Tj=-q?9`BiH+4XY;@B=k4p1$)kX0fBE^KQY;?k{)&?%$Yk^B^G`>O?=%qa)f{tY z*;ctXjrD2_4VIRTmw4X135crp%?zAjU*kzF&vdW_1H~6&?N}2;RiBHck`~v$RFASH z*$nZ*0Td6$6Dw(AMMMIvT5i^;|*HsYX)@$)y z0l_vVp6r~3A7KhQ>|j0NYj;QavC;U*Q0eMW4QtU+m-<(4HqKOzU*OJ63BMvLW7k$~ z!n^B_Pd}q8dYTuy5g7tOdNt=__sf?V8ag_JUpzDO=WOllbn^1@*aLccda(MBlMfXY z>97Ck;K^*{A5U#kG5hg99sO?q#eX=?{q>3ebfWx`zyF6*;=eE7^&d{j47u|khqeDd z94P<5<+J~AroGuu{~hdqXIACEX7K;8_oeYrw(s9#CxjG{HK8I~B4T7ITO=*WG9<~q z?~I*9$i7pN>_lW8OZJ_RUD-`#8H{Cy=e+LczVCG3zu)KizkFW&=Z*1E*L5z(c`V=K zdmJb1e-9Y!f5iayzhVGfhX2(D|38SqyRV)2_k+uyzI=f|j@G%k#~(5ug=Tov`fwc2;s`*a{I1s=Y!r~zG7b) zPU^em)}j%*srS%J=IM(UFZ68-HlC+nwR^p1xaK(*90*!BF8eQag|6RFZeiqRLc~1w zyc6|be;L@F<>NAUx^>Cr1=p|F?8$7g*3C-cWNErynu4_#!JTYUZB*X8J6 zG)3(19};=pEc!KI!@l`N3y(`dSM*kMP;PD|D}!sCj!!QC4;CCexD7O_nk;m7IO5yB z1&<333d+SZHRc*?Pv)l{wo_J}WQP~ci%Tq;$^B1uGE6Y;;ej!3ZO!(>=cDf9%(sop z6{RxX;{~~@aqMtJho)BAa0opw;eX$xqkk#6_awMT;mFiyI_6Am!C0%r0)~2QRN$bc z6#s|y^>uE%#O3dT0MJziuYcVFA>?3a-z7g;R0Rb zS4TJSH~DXF^S;$<6SvZ06aOo$_c74&zGH=4w-e~Zb2m5bseDLx6sy}-{dzFtMcFCh1-rGXw2|f5Z9BgMc{HN3pv2XvJJmazbJ>&!fef@vk zHHO^d2&X}Dm0tpIT_#tiI+-qi9+$Fh+kUy1uhkIUynaPe@?mq~aW<*b5Qphhbw`s* z2S&-QuCzeES`3a!1Q}nKDV-Z7VwPWMQ%vyx&jYBJLuEisO-+F~^5Uiy!Q$>-Ul-6L zX$-u1i@?#{#B-=2Pp>CJ<5D)4V)(tzIyElr(tj6yBc*0>3spI|IA-~jB zZZ-a>H%+>~cjJSK0I0=D8}*)jA>LBugnr@-+A0lqrUm_5DQLYuSUA7V_e&PE*>-iN z0DQB88RJIL?mh}4BE1(>xV<{f?t%UJqQAd?iNsCfa?pLU5)r=-CY^B~0X-m>VgWp$ zlM|8Gwdi#JX0d%GrstaJHh?XJ5;oY|(L1MpJ--;Y(z`9j)WF4`&n~{H8!3m25a^3xEyIK^jy$TWv8v0hw>R zajS~vtq}w}_i2Ro@9QEQU&9X0%0&9FA@rGSU}knDro#-KBva29=x>~H!pL`0m0L3* zm_n)!5B6sll5N5j*}cjHziBOYQp|xgNq(HWh#RW(A7ja3m9Wor$43>7zz;y&3^GZx z>4z9^Hr4K(#=lO*pBA8#4s}G>e-6)?BFDL9&cT7jpemndLon6lzR}p<{t*f-v5Q-3 zh1EDi`pzfbJ$S%B<;n~J+78dI;!;uc6_d`oQX6etpy`awCrzQce=OEFO_6XOtd)K~AnBbFtY~}0UmZ`Sr9&w&zv((ot zT)k^roDJgb1AEUG;o&WBBH+x>t^^bSM=Ug zbYL6Vc_j9aNktt!6Ppn@%Qa2p9s8u+7+2&|&kOK?x_jC3-WP=HL|h>f1Xisr$IR*K zcd$ME=zP>~PKCDhAG=e5L|1&HIhdglaATPb4K4Y73z;ogas z4F_2D{Y#V*{S5a6O9ZDkoz!@o+6`+U(XBsBO~mdy7jw2=s9nV^wNm-f|^fbdwUUeP~<*43t&HCI?#z{0b4m2*hZ7Ozb2yf=+&$R z*x(XSIenUyl{(H~s*db9%d^Ea4}sxA{WG;4|2W>(k#zahKdboCJU80E0NqvZ`Oj52 zepJgYc{>sF$uQQPZi?SGLAFWB82(I-z3^3~WdvIHYM0gH9g_BQN}fL*(nE`oTX`jJ zn1v;ie@xKP-)g-4e)U;xJ&NC@tLWfCaM!Qp_BqhwA6hmHF5Em(+H3z6FA$C7%h-e75C<-Ok!q!`;U) zRbl|=E#1IQdwXwM#rNQ(j>sGttWT9;zd-HR1Fo-j^qvqD^#e)35jxb0z*&Ho zT^D3#WqslCvod=O=(mg%T^tb=Li1H=4;Ovm0&-?b2Cx` z59F`>dO;r|C@AQg3N@Kyh{1D2fleupH87akD5O`uZiT>uA_G>?g{ELTd&0X8sOPKh zn@e3=9`mtUx%kTDk=pSh7t-Plcbn-tY4Aw*X3&8$cf`h^6a2zoONIFD!buJpM2c$m zU?O&!+_3*tl{7NeC=c*u?nl2BxBOz;Uq7TL!WOHFuW*wrHQ_+l`x4o$%`})xI4)^8 zCI_=4KR!pMdXECrsH!En=Z`8&Yq54Cn?r;o@7RK zv<-S;C$%n7QW)sxq&%wy;$*JuR{eb%CF2YTuJQX;x1%wWlUr z(5Lx*hjQEGNmK{<5HOC$=;4A+HrEbJZ)cRMI`ee3iw$V)#T%zPWs03}xD6;@<3J)f z5U9^ZuS9tCI!9=B-4_5qC5I5Ti?JWAut7NKJVC(0yBGw1y9adf3^OwTkJsH;N3x@I z9?-yd47ENL*}vYNjgVo3y7PVq{T4=NA!9yv8@~Iv22AdLibW-4zN=Qj^8|R`R3?kt z6dLr-p$jJTE3EbT<5{mcL-~eKp!{$Tcz#XL2QzQ_VsYQin1Da78!`xx)t--el_$yn z!E1lp+}>F{*~=~dT0ksz^5-PP5;25tY(1z8*Xf}hekC6aIcZ=A>%Toa;swIuF9YU5 z(JbJS^4mAskrv0Ps@F^b9vnoB?qrL4_)Ie3gI;utg&RAYg#9@%nnH!T;~pSwluK(j z7>D_A9vlgoww?RcKhhI_IhQ`FoxQBRi=i%FB8e>~LS`d{`Xze6S=9(E67h-U%r}UO zZb|pr9yJMdg%kr&wZKW4QJF`Vw6c3kL3@0&sctt(6!aSpja?0e!Klt2Rbz(m1d4A0X%I6PSzW%?HOnso4AQ0Hz)0PewxutIsg|@bK4~!h{fn+K!-yj`+<% z=bsZy5i$p^R8c9S2Y{K_3~qB^R&)Or!kgR11ol{N9-Ro9uUix*%n*&NV>4S#HcCg zOP!ZTjF_Y(GcZZyK7noIJ3y=mVTO@iTQtx=`s>5!P$~HBRQ>CZDYPGfgZ)&6)f@7w zsou{6e%EMeb`=WDih;|xWjE<<88p>;xo18^F#q53B--Ra&hM*}vjBDbRtmp42#sLI zlGtLh%BeqwH_i1dcpU>5q7(8%?0z}*Fh|Ox!MUL@aq&|86q z>X~|H0CeX+0mHmpb%NBoA?n6eGliu$2~qgGqB?Z!TO2m-5!^3AW$C?0io-qO7C*duxu6t z~Ok?cL;)8 zMPEOJLb<%PTNnIK*LQ4L6zZbU21PdL$+7QS1y*9D_u&H24gd{E={_!3ex+a^HpBn> z@(OGvJ_f|qFF@Ig8Ud;#Pn!NK>N8^Z8giR&aWK|B{5X0iv$0JKL1i;oTgKP`F>xz0tleu{sO&ff`H4;^l_ul50R+9lpyHZmdt^ zbv~WQ!Ruu&b>+{t$>#iP=A|Q?mAZobD9NiYs{wbqCk|^$s>fuRRe_0nG&xwX(ssW# ztvd@z{r+UnG!Nt1%=9_ujsyID9`@s&n{IvTwF~l&x24a!f`49~K*b^43M+7WDP5 zM{{1O(G8db0clPtK?`*SFQ5qB#YnYQ*89-W1*!#2@sGlKO@IuQnD(ZfH!?pXy{E>? z*|r$WGkm6W-nDJ<8RTbF<2PAeqQ7Ou$p$x1-Q02)Ttzn%_iWfh7O@|#QYg4LFP5ZQ zht$cnZExNjbgwubJv=_E7VKd!oh+L$!NVS)WF=_R8T0waIEvBZAfM>P7G}g=u}I8j ziUqMZ5dS(8c}%=}YTFgq?dNb)y<2#sLY?)G5ir}Y9S9xct*J{s168PXsgiBE^{VXP$_Q+7jYalw z<8*D`_a(iGI?|jGn##{bg8Q5rl>9~3-ZE!LytdGbl7vgOAF`r*-GEACPQXsXs&3?g zI~xA}_?#FcP<mj%A_0H~I#>8V+L6D?3iJaU9?e9{XcluXUknSdvlu zoq;EqL;qG)QHUV*l4&Wz!qw&oAPvh9*Z1{`EfNLvrEd3-N1G)rNx&u!AGoI?r} zrMbq_GkKUb;^dqh$j$1WOq=pd^j@+l0`X5RdUaJYAeR2QnqT02KTUN1WhIU|QE#T> zomPGmBuRG^7a^8^8bWIbtv5bj@44BuPglz2Bd4v!v$|UIBjAYA01Sp`7=tPgFGp-R z%p}GPv(Vizpbb{hDft*ezcNgkYT#3~qd6{wmNp$6{H=rPZ<;=(Lt5VE|83TKmMo-}vf$(nxcu;uJ#jiN9jU>xK# zTG-8%*RHHJs}-*RKI{En@A7VfxasCPlOuNr7+xR;l}!+ynk5Zvd&7YH-g0(eQQ>v< z^87b6{v5nX3z=QW7kYEVV=1;a1Is#Fr&s4cHqzggG7=FM%?Rh(o_)M2c`Gv1saQ>+GaxD`Y_3=Q4264Nynu~AuP*Ac_qN$ZfFry1svs2 z6rU8>9tD;puB*YH>`f*pX?`wxs`yEFk|EN5V;+#n;6nYuVFvRGgDEkiy&K3Y%Z?9a zUaZ#$FquJ-157n9oNm*C#jc#HpTTrhK{w?g_3l%9Cf`YozH6U~`W#BF=pZTch9tT4AWxFZr6GQVpexkp9kM5o9G5$QvecW68DC0GZzB{Fixh$?FW-VcTkU>~ z>#_iG!`~mD1}>lG*Ylrt2BPnP5cotfi+$r3$E~_f^v+rn4cVZ5ZQPxAvI(|HSbPRC z$wt+aCF%r}9{ZCp4&FDHts>8AyGaM0Ut-9r(2Be46Fbh!bZy@b6&_<2yd+@J$W${x0dw3&6rT_RAs=Dzv#`((BFo{qZcDOA!p&;0R&3w%TAQAsGh_)TLC!3y7rL&xZWl1h+Ax-n>vH`4VqvfrO5XW1;Lf*oV)zFliI z)l0{Zc04i;p9UVV_j7Z3Q3Ux{EQUV?QJ*19iZiZGZ=zvBbp-B?mKZA{NYzPof1r%%t5CIW%92Vl|pW$jf zQ`WlWmLXsbiHpmi>`qnz0tHXvz`fsG8NW+QS_OiN{i-Ld3FDSb(NF|#4EldwmKoWo zjot)pV(t~4xlEf}-Fe9d0cUY%sp-g7;>w9M@W`L zyD0l~Wpd|kwAx*Dfo|pO%H(Ku2e0V<+W8vXHRtco07drpOlHL6FZ_)3&zKx5>n1-~ zXz^F*p%&c5($83f-ugSh&%euxJaAAjnDT_bOXsq0Z{4sDq}cGpYy$({N~rx%Ek8Nw z%W+U^QL%HM)2({JBD6bMoUAW3?pljJist2bVr2@-N`igM;{?-_t{*+~_TZ#Kx5L$B zppR?`3^u6*3%$`!VaZJqRX+e)K-~VoADm)Y1#(`A@7g^HHQiG7TuVntDyP~hvYF_f zN(ROHMoUenUUMN`d~W=Ym0M3ru7=>;YW6;s`tw#IM?s*pCDrdpg%06OgM4)g6m6tvj ztmjE8B#+x|xjSuFeVhvKoRn18l?bMZ2J{Sn{5#YFkr-T;+PtK{d?D$Ez) z9fTwyiXP#h$+YQDgl?ti~yuLz}%W~LBr_|Lt z!4)C(J~N_Lsz6UfC357#$f#Ni1M!wXOhqd=>!z>ioH*?I(iIbR;o-?&kljKm%AHKe z$^=iVsFFHQuc(OLKq&?^`2*`tRuFUY`Dwc)LYhNM_B5JtNuZPN;iZyP3EjGbZdVI| z&hMaumAYtdF+pq90$Q5-cJ4+!0Xf7>szPbvadE#SXw*kE{l)PYT#7el8(yNWEl?e5SuwZ8o5qfD9LzuH+FNb4#`!FE2ROCVHv&G9&#HCQ&Btry>ucA}~B7>AQL{ zy~>sPiF8Rkb5@eiUVeJ}EuJc9V%YqwUOf6))Ovi)@lK|lE;P1Jp5_!y=I8zfy^Xym z0p^u*+DsXvWoFS`)=I@;YM<$`i<$thdwr+~>7-LGzfsrm(cxx-h`{(K zNulZZ?jPe5!>kHw(!Wis_6HIB&h>oI*8j;N$Pqn3ihCSyb3yG-YJV`l|KacrJN~KX znm>CO-@2*ywkargTsA+%q7LziJiSo9t75`l^}`_-`>xW2I+`SHm${Y}dxa$6{hdRCOP_Mz z$u7IfO$AH%x$H5j&y zBu2pZo{Dm|T3=8LMm*_kHG;D_)Q&sG6dJJek8JC8WSB1-iVIcf#f$G6d>XthQ~Q0K za~G)*y-I1~Xd5||tkk*7ax|jaOoQ|SeDf8}{Z4A}30f4c6D3uO`)(?etOIf8T|p3- zH~%Sw-YyG?n`LhWZ2C9mP{o|7y0|=OL5Tk*c<`;ur2RCbDZs%Evxu|-Ky`eHMB=Le z@0647PVVrhPx~ph3DHuRa&2{xaU$i8D`TM#xt!AX8GlvxE+@wl18{=PA2)i!<1lXa zpbXwAGGlYkGV*N57REcs`V*PB9I8TEoJ57{8ou|@QDAFZuYG(+Gww2+ z^j7DOuCU9oap+3PfX|m!u-r+Q_#;0`3I>L?XB^xqQxN(^9)hPkP}Y(S=seWhWDO5T<0}Qg3vn zSK=Mi04ZmbHW_)<6`0CuyS54dDxcppIiLI4+5RRXi5%4xhaR0Lk2g@Cs$*)?4Of~1 zj@6wP7YyAdybtkr9^#Wqbf;yyl4&(wV3la{Y$7l;_XN#VTvUM+U0{(T5JK zUwWfgR9__W#Wn=+aB2I~7Wh7dw;%urx?=a>Y(Q+pq|^`V=#l-BR<_WnJum&JS0SEh zv>b*x-=}J;`*-dGK&kFz*7vawd`b5d4Xd_3D6`7*v+7Gt1Jy zc_F6<#p~8zq`9pMArSFM>G584br@p)7oh|se-2N8O;J(TFv#6$wC`*;<$I7{oKmq_ zWgSYSACg67Bn>QszRXuqB5iIWRwz_NMpx)8+kTOQF#Q)&;&WbOMg7bPotlBg8kJ7%$+^Hr z(BRLdJZK9W_D4!MGed|X2CTQ64ptJvtV&1{^+8O{dUsm-> z(E}XF``zsA^C0(_uCrka`Z+ZF&HJAuRjX+6E&TjQUR#1dSpLGKfcSBhDFjm`nwN=t zX}CSh4FPiGh!;GY#$TukKY@S7q_h%vS`~hHNsQD@0{>CK4Tz;XPno<+hq%ki+7Q5x zYWVxxfnUft9&U9Or4Xs{NC2(PDrW}=Rp!RV%2NaV`u}qz0d{J)tK)N%HRigwkuHjmnuTH+}Ekgnj3wp^dLJ-d7WnVGQ~?BRuOOr>i86muXN^7;TOH&;Thq`jvg< zsiMi6gG;P=IZ(rI0)GC0SoF)cuX$9zg2pVNntSUKa=7P#ZKoA)%0rPWeVzHm6HdZV zf*>YxyMlO!aWVKxW2J;<~(k* zIy}I?2&lCm7kk4|%LXkV2FD0v zkW$-s%Sct)l=q&AdJ%p zCf{$Dr;+~L=KOR@v3xxv1v5LUT9EFil!fSx3%eoCnZCHky-9v#*!4JaLxL`&$R?Un za6G@3Y4LJ`z(-PLIXGmKiEW8nLO?a>#2%+PsagVSqdN%EUTZ-F3zen#J{1`f-qU(n z6~=)4cP49oes!eP7#NMoHkg;`Q4qB3hZMQRGPHwn&GC%c-oQo!u%Csl!nK- zd3m;<*HF8=op?k~zv3|pk|vC`3m^mzi&7{yJP=VT23&^>nbG5~M?hd+yX0)y@)M%E zWNq1pISaVeZXhofgzQt0-l=m2_@hS5K!j{2SX_k*Ah)_SN{a>w-LZ;ZkgxmubNw(e zB_%~in}vYiMj2+hj%lPbsyOTce^`rP1e>|inL4k35B3=eiC-d;Y(+j`ty*D^?pq}l}F#UOh zauDLB{Wu%~g|eUk*}{Lv+n)zAKppSXvKX%b{Kr;#d880P zEMc92l~ulZ!D?*ju#-<=y1lykLnOtr-*Q*1XRvBxo-juzEv?$E zIvaWX!I3S7_8>}my}MVS2^Xu5+r2y8!FkJ&0)2(Fq4i+ zog`PBk0kE@loXCFTAx5OV_B&MA{qZFp=&j=TIvZQ$ll%?7zbrZ?7Ut&tkBf6FZQxJ zZJDG*0M*&ary3mqMj}id2g0d=6J?iA+QeB+)#!i}F9)(8a}&lObPe~N?1NxJXG-xM z6w>7tX38wN@A~+?wTNP!g5`t82P!5eSvjp_h7x=G`>mEm780anWNP~N?{iB_OaJU8udfn@ z#*-wn$oqpu8yE2S4K?ZQB0O*;lf1Wp9pxxJ6=RWmyuY1Vqy+~Nha~;O;wtLm~qJHG_%GT8x z(Q^?3g`aP%FdG65%PDsYu*#?_2ZZHXNvU7-d+Wr|7+w_p=l~d43vtId(~!Lmiyp9H z0APQ*9VT1fwd~=YDUj-&9X&R7lxy_o!q(#yz{{*aGvsf)3gUt+(U?p!p<#kkj^zl2_O2U;FgyXXFYX z0&_FJNOCtcte;>R9UZk!jgRM*kdS!W)6o%?1B!y;HO|jjuS#u$W452-@9)2`V4Frm zY-mL4xLz`ad${Jjvu3310u=sBrE_PO7qa3Fq5ul|oSnR0#m2pMb+URSAn9oaNGu*_ zWpwo9I7wG;*@x8}udsnAc1jmlzJEW7TJqpQ5oO;^okrQLVQ>VPz-d{Z1PN(HjF;3u z)Fl`?M%UQ*4ZvQSKNl1fYyeyTQKlM15R-epWNbp54+fn8CRz1?)Nt8BqW2Im*1JA~ z*2i&mb@00uJ40Z_iN(P2L9sV1QU8d8BY_P4Ay{GrNJDDg}yA2o0PPuAHu3WJI4~ayrW9 zU0&W1#`IsWfWaa?6A8O~rU|r}3yYo54`hpRdR?`iyY{l?gEM(x*-yBVz&-|rQ!}eH zohGQa8SAY9KID7j*5k@IYD`sZh{Xvnw>m+*#@|0a_e4cR&H_9Cw$5|+J(RC}+tc3u z^4e<6VC^&`YUjp!6A_Kn%rHPNMa73kMtH#zr{#n`e?AAg2so`W9uGEwcS5tbnd1L* z_WTQJ>6Tl8c z1TyuLR}upP024B0lR;0=a`a_Br06t ztnW0WE0Kd(Zj2qW!-EG_Z+RZ<#J}IcF=TQ~h=>{a0bKfxAfkf|6EKmq#Mz~#cX66P zTPm?KU(9IW2>|rkmT{Cf3ZgRxyd+e53Vc@IF3u}3)oGfyn&)HEeH&n~E(V#yr~j7M z>$x3mZIS)`ckUMHS3k(j%Tr@L9?UHxgYYYJT-MBa_fBZ5uP>5{iYh^pm$&shuO$mb z*Oxyu18{>+5u*X^{~MXUYrG2O$YOQ8fxGh0Dzrdj5ezos3Ydm-{fg||xMTGJ(3Am{ z;RMP|W)oZ}_#Y$`WSSla$Z}+u>=XMZ@kpTXFWNuy6591rvT6MWF{#!9ca{|5b42jjNV)p{Sv+<_bc0@$rC3KZC|=t}h_7|5-1f>up2z!VD>udx{x4p^Lj7Wo30?VeCK z{%?+!8=>i(Q}v#*ZEogo(*Ny0(NYA;@$7U|mI&rtxa*?>9p6%pQNg`0tgNj3Q^$OO zrvW&~4Ci|Fs89oNS;k58k4aO2tZR6{I<2)cDnoF+Dmm|~7IWJhmu796` z>yjKW%F;)G#;z;lFPeHy$%>)+g2#w`=JG|Y!yH)zt%UvD zvz;uk1hB5K^pTeb;dh$0g}rcWpfKQ{pJhK7e^(OZLR8IEzIoHc?~MFoEdWr81a9lL z@67VI-Fwui0S`;{9Rgt*Xh(s04CZh^7(=9TZX{~QcBvJ=or>;~km zd5{sLl`+$30w;mIZQYlYdzZ-%l!iQ!T?0g9GdaR2HO3b6Gq#PlK$YO9*A6hHv#eNr zT7_C%ICaly+0$nur@*z8O!UvcV{v!o%QxLb9r<){X`MY-SbkNNg8@O=YQv;57L;WXK8qHdg2(a0OT zZyE-yV3Mtr-z^x&2T0jR@k{b7eaSEm2tU=%#-+)5{zL+w<5ZDvv+SlYIMs<50&UDF zAToct&CShCX!u0*%a|ZCc;?^g6sE+=MA-Eja85#}MPYe$bp}G!js%s6s7fI(I0loV zuHX-YPOk)T+Mt`Od0@V4d@!X;%;E1iLu3bceZr}`ySty{_Z8hW3R?o+2dtF$-7ez& zo=EUC0SZZWJxdaWkRj-<@7iTLmyN=5Wgg`y{<#r@I%qvwzz2%FNlFzN z!$*dOLJ*+Eod9{<^rE8_b)7rtrwoxLE-<+_H|lUW(U~(zQPWdL(R*fz%L)5d-d^;T zCFbJuLL}t7rIDWBl~|OvpKGg0ZCaVQjzA%BaF3Ps%O2BiRfV!<|Bdg>Z??4*kc;3Y-nLNOx@c1>vpz{@9y zsc*P$kDA_v?>x69G2E6u*qN;(+ypu*2>DtC&2&&$ttjA3k(53!S)9v6Wew7 z5_^#>ymzEoU3Z{r`~V6L%qaYV8lPT$-9veo)tGoD0$k@K>z6^G-Ofx2G}#?l5{9?T zD1Q_VZc~~CtiS*h=O;`PRL~>{blk6T{Phh(M4+AE#2i4c@WofaeyY?o!f?;;Y7nHx zIkcGxX^E*(V>Z;t{rgUzdwG5y_$qx9Y?K{E`15$cukOsGr*#DqcV47esYk{PO zX0&nBX&yf%+(7vT@gN4+>iw$o_Ze%lRd<^8PAGhA2Tb5(v9DSxi~~dt_a%cVyDBsy z9uH>lqQ+IL0ugliupKlgi+RZbp-UG=FaWq|wvi1Se|yX;VucqkeS@~avXnd3Up<0N z`eMTVruzmO>%C{-TY01?>#qe8!h&cUvGh%xy5U%3^liBE$8OQ5wh7Z;jew?NBvvgV zK{cs~?p%C__7GbV?(bvdNW@VQsVv(1auDv*GJaZzbmPE9T$JtcdIazes4S;Gg4+No z9?}}AU@pK^7k>Z*h*oCTt`5h79gx5UPY;4i7Do0>fK(ktasM2Tp*3)=>-qzGsyM#b z0K2#`+KU{q4nSQ{?r>;-+7n zmHe4K{w2Mq;q3LQzDi@-Rmv@Q^_$wC7rK+1Z|}iJR%gE5dsQ^JirtEk+IW^3?U=f_ zjNE7K3j16F4Dxzt4`SDg{jb&e^;4(&e zIkUnw58pBY%OTrR#|?jW+;yMFn9Doz`xr;6b>$Jfx+yY(4hni4<;l;?pg5)(;Xo<+ zl4b3%`ea3|SNXkNT?RfSA9DP?Nobdt%rrZzwEMk*JCbB&k5+J0^#gT+Okab34e0N0 ze)8Y~g)GWcJQaRzfc6E50ge^k_HTqv-0douD>(6fGrP6dCEu<2jXKWM6M*$vo%sj` z^>vIYE{JT0Debk@M1%&N%#Uf5cMn+yEJtoJ5?rA0t>Q6p*3;=lm&5F@8UXpYDPM;} zrspoUM@S^5qcDBb4w7FS~8{ieED@y@7rCw9gG8xndj(`)45F z+>?EzzB5bvjW(XMXMoaD>92ps0R{WGxUi8^C%yC~ZLs6OMmEy`DjK~^*0^id;^k-4 z*Sg4-9lQ5OX?VCMgq}Kl@IIQm`E!gs{xJTXpX;sc@xbp;(h!A((&k$%3sXF5$Ot<3 z18{63S&%`}R%2z#1Jqx6lz?^O{>Dhnq?DaO;78}Th<&}svFKhZ8_^2d9}r)+1rQ2@ z65y446ck;Z3r@3<$l@*U%)!&LV4#ZAjDQEC=104!C-lx%kUA`hui?C;OCq0aH?kKq zFkh>t;rk@#E%54aQO7YJ!PEGRZ7*3olJET9wd(Z|s{cAlL&pX)E2{#qj>n)(cxpVS z_Fj@xiC!cD4Jd+q&*6qUUa!JC_EYEl^LwSh!CD^&s_{aOz`G1e;=Ho5djlj^v`U45 zjKmWO=UU1*NsS%QrDgNl>@V|<$lE{sVjQ7NE9%(2nsF0FR9q&Vy|@IR;1LGV^~jHEj43<q}#3afu6 zX@xdBzD%iG;9w;A`K6=@djnPfcIt9$Es+}*h`$zM_&b-0fbL{fgMT?1D>-gU1T!Y3Eu zQf2|jbbUaX7QYWQaxbGH_`JLHSYBuA!^+kT+JCjHg~1j8Hb(mn93|rNFQclAAuErB zYqR#xR-*eyb|G=CO3+?DyPcipt|C;C)%oE~s1kZ*g;?oIl@R=yZ9prV2S0a_R^#$Q zIfP|8mC15AEqTbHxA+>B|`{0*Y<%?6+@-i0CPy%``1yq3D$HjHb zCe)D)at!Zw^h(sRjW|*;-bZZ*5j>TFItAt@vLD{Sj2!iABO96&!sN1fr5d zDVrVd%s~x$mk4cwgAiuq3{iRIfTY-oZ6D6!}v4`zyHu{P-q0;@|muH z=|iN$lJu-pq>p)`Zq+%W;d#lT6)J>SXUastucZowhGsA|qy(z)-0N$h6#J{X#uL1c>T zV3}zdQ>sfWVr_2U0Zeh~=}c*Oh2%oEIU?Ivt(0j`glTU|saHM{&@nH{_G41N*PrpC zVc2w2yFWICt6A7O?LE(jc>IE}SA#hvrl2 zweL*vJlu{sCLxUE>t2ex)d^%Q^B=&X%21?2W0BA2x2qIe3<139o|=BIjjn>q+PDle zZ*XJTU2gK5tt6?zPuEoYHeINZWW*7SkNa{|o-8G%8^M>&A$jHXnoj<1JDvlm#EORa z>TS0%EcctDN;=*Q4ey9Wap~jW=J=x--aluv2E13Li~2ED79#@6Bw#{f+_aZaEA5OV7D zP_lM~-HzmODT02dOZ}#Vyb5&Jr3)a*c5l zk^Q>$O&4C5X)hPU)uyuPS?p0x`JdBMQY1FyTozTjz(ncK``f_ zxgtjdAo^PzsKw5_x_3;VNn2J=mDx7xJ4wY<;K=o=ezfS4-R)LkRz;ivZQ*Q8kUs76 zNOu)g)htL|WODN6(E4RrO;CuEMD9Vvhc6zK)Rf2UJ)zK0?J${YjEs~uAglF3L`j`D zwTNYxYD5Ja_A!Oz(mh}pWg?63N@urARRHtjP_(G)|K#q4GOx3HX}n9*tP)=7+c$D( z3AMGfcxC&ihyLv~z?PrE_%j1QLNqb3H|HiJgQSsmRlSCV{;g~Rno>2!g=OPwp>qJ^ znp{-PqJ0Sfu#$HIflx?;i~H_FPyGdIZm;9|qO2T9r823_=@!eNi;@jm?y9lHH}%jj z71`)e(ttvsOr17RBD-jb>>7gYC{81Y=}u;?=0T{otWKS0C7^%kMzu5TryACe9uKhd zOHRcW%La$N$hK0B@OXcYYw4bZQFbXSZZ;rkxsrQkbFXZYWXt1{Gz!_ZjL#U!oaW3A zd0IVWc-5)`!%1ulyjtZS`+siTksm&ZZ6`TMmL4sF0@3DxG03&LIKV+t>n6|YX!k~7 z4ydt2H|nY{-`y#D9EJ4&?p(Qy{_MRa>?CX;$$xHWWWSM8kX$o9jms(&S;1R-eA5kr zOemh0CdAC}b&=>+SX0kEOnqk18r+Vd7HuF}FdHXOJ|b)h!kPfi%n*oj zJ`ikv+P}vR@&IM~x8J=IBQ7RbR&G`JaoMqOQJi{ZaPip1^K-!O6rX+aezAB=M$#)Y z91lQ}Znr}r9mxgsjyK5KN&u~$bJv6|WARE`iRoEp_qhCZrST*KMfX8WzJofoa$1Mm zu!B2r)*O&bTG=-vTp~GBLKZgnuI089+nMS1PpdAYnA7GMtz4MhiwLr09rg@r%@X!k zaXqUEv!dg^q3)@knB-~EL!LJ>pE0*Jpe7do_zWC@ysB18Qq9I1CGq@AkFm~1x9MD2cL3{){~@*bqw+J-6Psnk}L0SPkWHw z@K+YqIDdcYntM}m4E@4)+%*HqE&|O9u$!&A)SN2Yt5;gmO(%I5rQ%~^!YYf>ba`nh z2IKR0@jDW=1DNkA7I>}IH=E3C-mLpfK3SXiz#vl@K!=Iq->asq%~=j=x?n?|v5js& zR=WYBtaloU|Cm1bwH^R0oLNhL1uj!=tpSGJ@rF5$8H>%Ukz8GA0Ei-EAbuVC6m;k^ zX6WkKey!?74WeElS@M7%h62Y#mWquvlgyMYi4@=9!D62kQ>i9_Ap zkaB6lLR^-W#(wO*g!IfYCp@S%PwqQ!qonozmN;?Wu6XPc%lInn@_(3(4VcaRl3yt} zB{x9fqwpx$G>%Ggl!{E%%!8sg9E{Z~XCKrqH+CwrxqX@p&gm1nq#uy`)g{2d2;OIL z?o<<MlS3H{a^-<0?^8UD8E-@#kwk)Y;b}}&SEnTykm)79=@~{ungBd#i z9y-S)$O*+{zT&95s@-&AGidG$s2^1k;AwebRMe)o9pz3=_L$3O0v z`~rKewdb01j4{VTQ~cle`&{>?gYVvbTbmWlVRUq#1HkzmIwhO~>8A8)d(ZV=A86`h z|K7Y91cd5dAH&;q-hp^9pTnp|%MSFh8gXdyimS+8@J-gzOnf!+pP;{e2>`8M+N*Ts zcTc`JrD6NEAhH~6A~YByJA*yM?6mPfWM2r`OK#YbPfr~^`taVAJkLOt(Zz$$-p(^V z01RnOb|G|-mI6Qr+#8xPOXz~zZc$tl22i>XL3%l)pXHm3zF=NH=-#{3XwaBM5! zQP9lD;@|U5Ir=y4<^K%lxAfR^*WL~NA#Hoc0${j~hKEZmT#?w3ge=q!-L7W4pCxO9 zIn;CQo?_T-Z?+GG8=CfitlU-%djj~DoK)oW9Q;GtAS)cSz`&T%fEA}OhrStt9?FJ@ zNAkRAT}g-Qw0D?s?f&OTu)*H}8_^+Kjr_>zyYh=!MSwxTU}kHX!p?;vcTrn(*tp3&>p#8n&Z=ZR`Y_0;hm*q7g+LKeYG{Q$ywE}VC#gifBt62xso|)yY=)Xv9U!JHnje7)C9CMnd z&#A`eEM33ZGKlEIZ0{Z2b(Ruk*RqH4Z0q63VHzu@*%T9|rU>Nc%pbqIu>EsYKdapv z5Fy(|Fnz<7x1;wnP%|apj-boU@!EO-iK|yipT7y>FvlMU!_D$MHvkKiOpEEX=!J3P zbE?9yowZ=?O&&3}FS0^>FH_rvHG=vl;=ZR8t+O`i>EE0H#sS^Re0z59G; zhMHoH=7#n^T}s;H!gNc3+33Z6+qajH=20vG$ha9O94}a<)2iP`zFkOX0c}H^#WGt@ zni}MWXm%k@LEKJ5e(05wlD=T>TNfFX8)}2wYM%ck*Yw-laIB4jh8BkMh@MYd4Cb4g zf%Gluwm;=Z*zwc>tp3)i!GW-&-v>)0er6AUg3N@m+xpGBLxHE%_2sqHJ^KN%qf{z& z9ROGL%lcI=!2J#j<@rMu`FbK&Z*!7Uq=@cS^D8AsYwER#ntwp-(}j7Mjd%dN`A=?~ zExEfy@EKqQDG7)l25~qkJRUzdHsuV2#NyEo?7`7A?Dby$7mKJl z-=m35M>t3!h7#jVKtGmuC$?!*={r?*WtJE!l0O9#fGVX-;;!tz$Z`R#@+|#F-St!V z^s`(MNi26V`ADzQsHi|x^!BG(=w(|}p7szooJONjuKOFLf|m4O9`}E~Xk)9ZW-8#7 z-F}C!AIKFAFKaK{7_1G8y2>&8GAwG`IoQ2T#{j#v<}>j5_BwL~2Ergga(=I)N3Opf zdQ>dfi%OKWbsNXoaD5-Vws$(Z`CceUwrzmD%Bn!@Nl^i84>bl&a*oZ5G} z>jy7gDB2zLEBZc6*Mi9QW3OcGPm*vCV+=Me#<1pN4q}NrP;ad&iN?eV@BUSkAeFlZ z^;2S;Z|4@{KQQL^fre}k#7@R$W(rgGQ96CA22dTxZDJ;u^!bjFZwwCQ8JDlhx3M?* z^4{x9I8>Fa<$0t}gYv#d$>{6dKR9M3BG*pDD-CSrXWv4iSao4cGAPME55hfV(RpQT zJE^J~YZqz=c=18?=L9%U^q)PHA@w+5jdcR*JN_>G#$hF1w`;us;3;9L#N!=rkW*majVt7~-fsQ}%&Zy?sOIV=6q z@5R?Shk2gw7B!iG*VBZJh~J}g1y!Dn1XHEaS8FF!#TsaCj_ElhAdoYiarl`1=H5*TOg1Shisyez-m6USzvhuuOuA{G zPAj<{4$0Nq%_Z)gXn7a6dQsw45PsQPwmf=!w!)kWX8p7QJFysntlQa5|^9=S!_c=1T?1@f{L`Z3v`Gk2|u z>Th|xd+W_DxV#qW#`X$qmoYc#pB-5XK2E6eOgkH-kOE^8R+yPU@7$3xC^O`)4*JYx z^Oh6D{RHi1TVrB{Fp8c1yi|Tb`ZCw?s+va!|mX;K%o0_11ukF6@@jO$KmzS3k z(F&YD(oemzFX0%lhPzcc!f8u56^WNu(_i}mJSRnROApt)y86{VB>gtA?!%sOO&phh z7BvKOFT>xR{61zi6}^?uF$<0jE0p_)^}$;87+$>L+taqAkHY~59+?lmA4k`~9e&sx z)74eldr(WTO^WGq`K-N@598i7T(^wpG`OqOdEC=zmZjf^;JKIHwc?Xbd%Pz`d9ReQ znLAarg4)#rK6hE`sFW>iMJeN_RO??etdL!6Ab_5k2-ne2A!~Eq$*?wae1lU`(Udjm z^H~?xUhz3JIPzhngMkPRCmb$Ty)jIG=p7dD_mwdi!~SiMJ1YkLD^HMGN@r{rz5AN` zkTJL_#rb{kkl#Xsi{(O-Hqh`YzTsBLL7aOx<^`f8$cjOL8pgCvC>S_#wK6R_TWxPV z?(QZOa?CbH4icx6Kk7O8h53);fDi>-%3r^Y?pX`xfO$0_h102*i!SVOA#EZ-kG%K1i{Utd;{n z7!ExuJTi@2SmWYePuC2121vob z*l~}yfv=DOl#*zW%rz}K>_G+9-LvxsjEdl4MD@ul)sFpSKUv$n1vGMPO$A0#nFac_ z;tw3*>ZnFBJ@-lnvH0jcYD>lM{J7oIy&cOC4spHwp5VVoNjp5?Vt-c>wK7;+cKF-H zr6j5*Vsi*!_Tr9Jz%bB<46>t0yFUq){!BzOCPb@JhO{F2V(xt}W!jwN<3Uc{DSCMzY@?$u9&}ez^)ia4@Wm`6y>1a7EL;nD9+B1VZFAq0m@G!vL z)Yan|oZRhl>x^aQ$C`=vR_`9UyREU5%EJUzol|ZDoB~iKRz%~m*yRJn}bic(6y9aQBEWqB3820)YNzg zE1C6PN$X|uGnp3f%&cF@tbz`^766?@qkmgjD&=aub|K zfFOb=AeUn<9d;tAWJwC|ay4DHj?3+wYvIAhfu^4lsBsHGA-prMqa6oWjo@gjk!Hs# zzFA(Uf{ZRk1fpkDoQ-bHo3CHiYBsJwj!pMW0W7u~>C=4Z=w30pF*0tPH+be89+wpU zCs}nQEsHoDtPS_m5DH8o8b(hpk!L#Nol0{3WE)Gs!f?;W@)U?>gwbi!yLUU2VM@2$ zN;0M$!zV(Ch2_D_fBcTU1*23A2*%j|c$GaBbTwX9E9Q8t*KGA-aS+=Buf)Tey5sAI z?Sa!I!7t-N>O#Nd<+Tq_J%#_t%bWa=Q8iLzQG;`Ia{NQ`S9xSoiEgO$&)eh{9c^VW z42H6)oA^nP`^7%6)6%}ncS%a-3U!S~A~$=0t5>=H)$r#~)EZBi@hoiBYb$*dQ74=jyHKADf4WbZ4LRXHHS`ZGp3mb-Bw z`~edP*)VeMxOb4;6cQMf`eWr?y*aU6?l-4C2iJA(>v z&oEXq?Q(PHGBGoAA%Rtp34O4+bH8m&J(+7T4^;&LMhqPaoZ-aVs*ZZ_({#R1+vNw!Yem^?Aa+CY5^Qn?6Vid`eBD|@|CEc6CEdj&lT7mKvOTr z-;?%SF~VVC)L{R8UXq`HoB#-5zkWU59>+F`1ENnwkoxmz^k^=~*m+{zuBf~*S+E?~ zoAhztfQFPFL)Co;j4r=K$HN7${_KfKXS?SaTEP279(3iO%PXTr%9(4WhuvvVM=C?` z>OQp){RrCE1wzvXB#sq*!yCPFG5tzl-AeaH*uu0LG4|)u0;L|JN^}8AKhKPZWn`mcENoUZ9?4w`Z9ugR<1bF84aHp*V=UUlC!;t^zT3Mu?xhAA3AsL9HiiE zTtRiuJa_g#mRtGt$o3j`Y)o~^K{b*)qt*AIs(}d8Vzr`?^a8gQ>DBoBDYpJ_1yeoJ z#}sl-c8LRetPrBgQPwE#*QhofA8k(Y83?P>f3T}$a`|Oo=FCCG_e4*>o|yZB)1p8^ zyxwOwhiXR(x&WMRHW+ZEbrx6kfv!S5aI zRDewpC>?-|Y+rKm)Cq6#KRU!E|n zw((5JB-oj9b8&TC+x=9aATKW_p@JQLRHU^&(7wExFgqK^k5;78sVe$*nGjTQk8~#* zebT_#*&;?=E@*evL^Y5A-5nXnh$qR~UZM8i8>ZLc@onlc^D8S!JEOJpq~(N7VCHE@ zPHJVLdFp@|j4YDuzHo+%G=S{vnjBv(a#1#;$hmO%L#LZJ z9m*AzR9Z7p#sX=n;$hJCxg*Q*pPTom$kC4+o>@;gOmp|nNK2cxV>B`$aqs-Y+}z4= z=8hN7^U2v71)+2ubsL60e=wN5r|3p4-E<^x6e#$v_wcXb;GEU9)UsUtI5jv);aN-jh-a^VkYI&yeQ z`e24WQ0bY<ojh0ot;h7HauzgQz2iNMoeqqd|LNM$cCC@xl2 z2f96%5LB5ES5*zT*NWO|oJ<&zayPWKvAM;DIquSLZoFu7W{V-xRfH5u?V7`=E+tN+ zp8*y}BkAyjKW#&-0fpvCO+(g!u(H;YR_R&>E!%Y=!P|^odlGz(H+Xgg%R}&9`~2EV zw|95DeK&2#t=HL6IsGd5p`G?dVu8}nl_-@-U_x3;KM7M2sfT>q;W)>p{<94+T3T~Z zTiDcRYiDa_?P30cA{mr;L4Hn-snJ8C73ZDvz8g8lCnx&^aCaWBAPv4)xX`D|4`1VK z+y9AcXSIDjPmZOshTCOI><%JexnHlj@%9)2b`2Yw8(r6=r76P;<-Utso$kvy-ybwN9a&+2nUoCg`o%{(hNu$13jJn*y$>>n!xIm)tR8 z4aP-E5f|mkVG#{q;dg$Y*k7o)|AL?W?O`e*F<-${O|DVnnu;y>J!^6-N}$PV7`ih#E9I2o>oRX_b!*YWZ%C>}$Y!nCxs z%sF9AMP8nd-I`Wbs@64ml+6I!*=264q@PH9nv7CVId$N`OZlr;T}UqeSEnFl@(LF` z@Mm7XKD3s#C%x{fM&ATd9a|z%-^;6{pas()`tgKsb#HIy3HyMFAV*)ikkX%TA3{1m z6jUOQMzqME%E?&+Y@FZefj}th1LaQ?SK0X#H2(LNfq$Pm06kBJ)R!8`q5lJ9{MQ@& zx4UP>c!v2CHd8HZEdm4g>8!zd1V2%xux})PVN7gA~Dk z1pEI57J$9$|9x@&+xM^~zwZHh7+Lpy6$KK;K4xUd@bmM(*pB+YFVV|({+5o44|Kxs z^kQ{wTUtWO`z)O-#iSG*N%t1XXTj7BT~ms=sfa4Qbf?~XCqmGx+_CfgB^ends*DPv z(#w4!>vhZK)xja0)TH+6O&SBpgB@L5I))oDeP>{SKSgG!H@#Eo7Q(Cx+uB)SHkX5= z414bfPJJ#2)o34aUl_c-t^-?@n?Pdm4a!r@cgNQ8A-!D>x1H6S#IH$iw}wXK=2qf| zvzWO@o;)(7nkgr7Yime)E(yW4e128<2Lv4ZLlJ^9H#3`oGCTORB@S&LlD8G~wk87E z&-U+d)Q30Qj=;v0xqX)IG0?tFky96K?En85>Az3IzmNMf!7KYL=}GlYlmpXr%N^>I ztN%Y9lYjd%pv+Wz4ID(_?{5ZlEe{=IWY|B^=T{Or`RPH%$I&jTBQ?#|?v+QHb@0&=q;`qwCLWRX3FKzw6#w zuA>Cd7`w|UyBB+VEes)4x1!@e+Dev}g%?&tE>mZvIPY7)28Q{kzDiq{U7Tw2x5C}Z zF)@Yt?tB>r)tq5KlWdy8T8HV$^q^=U&8(#sCRAc-oKcC^n3C8FrNm3Jl8V)9p9dbP zLf0!8)XCk|_QA0ca4!>6VkM)3wDlxCe|~*o9d~lu;{{G9utT! z9SC`!0GE}y6gxhvZ>afLDXwahD=^KOHC;VHA6+vY92xNhHZiBWGwZX5gO{}%=b^R_ zA1-2040TZayLY~(*b%J0gF|EiSVnFdUt*aiSj{Xl|uEj`cDJlIfJ^dvjx;q}$WKETl_c**R<1r@nwmoT zC6(6kk`R|}=KVkGd3}q?TIuJ{6*%{0RF}9j=vI}FYjNDKilf_A30S|a`F70OS4M3e z2VX1qIL&5#LlY?yHiQ809yu%uUoIPu^RttblKN6uHaNVEQ7R1^J89~k#n_Gz@vZKw zY-%#GUjhKIuO@pv6zzTtsm?@>VA7o=jndV~n*dU+Y)T zKJW7J7ig386?MN;+Kmj>qiWWg`w>K~15Jr`=_?(*Gn)RmK*<@h(H&ExEf_!$v$7jm ztHcR|sCE6S1#Z=CZJVQ41*+PJ6Qf}_h&kO!t)S_bG`wf8@uFXOKyTqIpauM2Kf2}) zTC)j27qFIpj>zz7>Q2N+XaCaHs%lBZ|2^=0QoQB*&X(3Bs3Ig;N^mo z<`+{}p>?C6mY2hY2~q~9!@K%_rW||@^rV=F?3Y&*J1@se_+xznbigD1k2F>jbRp_c z^VPnDH-t%cuYuKY4!)&tZxV|T;`Vo3xB5~Ph!dV_k00HTJcEAPuElw-;PhA85W8{R z+;(`5!+vBm)OUjO%6b%A1pXs?VXuoAeMuZETw z0W$~bb#T3$z?1K*sV3+1qE?`|UBf{$a}WYqc`3TgeD^MLqORhLF8%SjYaxcmZ$}u~ z22QOfV;3v8S&WlVP)n4e;}1g88^M}H_Y4||Bx!14iF_izVWaL@Jf=p-(;)Uq3E)7d zy4kPD+IfAgDvg18duQ2rdMZ>NrvEt;+T!-hb7Sl6(DGVQ5z5}vp*q)wEKun4!cPOj z+ETs`n~D>BmK!r$F*!HK>t}lV_HD1DZ|u0YGcT7-O`Y%)+|}sB42)fx5>`*wVU)yL z{&Hv&J5W~<fsoviey0GQD=wGJ7j}MxM!6h~n{E*msjZAIKr`HzybB$e zE=?oe7OidcPJuOzyu$+G0;U^b85^%W6Mx)*4|koa6#v60At|A5pFu58k9CPo7D`ol zWr&#{`8tb~oRj@o4;1KlQ42n=v~bYg{9{u6zQ?ATTtl;*K|39(FIA^=EZ!<*^|OXf zt9S*&jD5cg#Me9Evc5(K-t-{kK<=5w3yHb45iQxQ0s3l!aQOaMmv1zQ^GR$vvEb0^cvj2OIVhE^2i=c^Icn+t}=E)weLf69`&U%qkX%n44eIG3@>T@!_fTwY8AxyG8+3 z*4h=@`v9O-o+{|wB;(1RDW#%fAt0Ex+X~dR__Z#m7JS(n2UqS{HyDD1oagS8^|G(!kP7 zmC^CjT?u!9wBf^=e6hoTFSW2BG$bUqva)wrO;$xoMgP2vj0J+&B~Oh3L2RLG%c1Zl zVu^ZgamDbkD2Ae=u`ek}4)hk4`20Gpk~Est@$Ki&WFofqS{P%W-^52@2V#SwHI1ef z;cCwU4p#nQLmaEB?L?GCaYbx3{eMa5<8XY!!eOCMXazCBz z8$OkgaNjc7n^c6Udb@dh!6$(BM3KNwDn%BdT--ESM%VJIq=;8JZ=aXvZ-hVwCk7w8 zc?R+?2V z%QSqMw469Lh{ub{lu|;LCxW*(1Dl8}1IB3`YwP-34%i}^O+{s34N5lp+oOzcuS)*kbw+VKvC4GA8ip)f?o0E zr9NK*7EX>m#i^xmG9T;?j|*f;uv+zDJd=Fn?R1uW%eaKIRtRN$Wc??TmQq(-5!AD@ z(Z|}kP|fNjM;J`bH1HB@Hn@MpRA+J!E$96JL0KDfta^9u3C+f3vN9juHmsi{8<(rk z`Pa-9Qf|qgsf1=Ic1fO#(EB`FMhA7J}VSFGmy1+%&85kk{;sCPXy$LeF+rXYZ9q`z5tu9?9`M(Vw;GTQy-}i?0fl zikk)V6;E*9ziS4n9XxAg74YHv3zA+fWXKba?iLaT*xY$`eG+L=F`Iqb^$%NTX|r1g z%G2#j$OC_TwhU-ZW)7}q%k6YIH~hDm~cx2f3G7-iVD1S+0S{5F5a>TG;St# zRz)YMxVR4wxhTEwVs})7u75nUGnOWQits5*z9`D|Yu=!P;()vG={H$Pu>++sBLW=$ zgUqP5{f~SR%5w+HXJ;I{9bL9w3v=f#`F)1)ubtsoshq&^Ou{_*cszG0)stZNMsb~! zUj*FjV<`{M-#kI9bMapJh~;jJ2{bhws<~F;?)t6W+;~*q!Bit(wpr?W=>`}GeM4->e|w^fn-NVQ~@#qM*r|Q5qgq?y`~($Q9Pa^rkKIb3A;Bh*ILuIU%ryFz<+ z9SPK*^u~AZwv^Sh)GUx%lT$e&X%C6)LKzt0op8~l)2ZDK4`0r4_ycU$2z5t{WX5vvSCq=35E-2^3dLK=tHInqU3OU^X;p zT#}OmlMCM+qd7+z8hSw%d|y_|-Q3(9$Y(J9zWz(m(r^_FC!1JXAvZ^a;9;_}vu1G5mfXzo`;TWgu51+I$skbT1@H6?~ zP0bC!J5gOj6d0%Z6|rRkRhzBbP4t=3yO(4t8B>PUc#>VWt*s_T*%sd9UvOO(REk8M z>mv(!j}2Z}ZgO;VOor-Ft+96QMR@I)hr7g$g!tU{9}7bb?N2n8IDSC&tgNivsT=|I zn5Ie9$?+0kAU)hPc@dcoCLowencpH4<-h%I#BRyY%I1vsbb($>EUl)hDp2>LMkT6L zAUZ?N+|F(e6CxDoKjxX8m!~pSbwN#B+G=sEX##;%RD8&AqSeY^z&~xga~@>LpQ%T0 z_{g=Y&%6v#o3I%e9Z(eG2b5K9?<1$F zmNCI4B?JP}C%)s3G030Z!|z_=tev^Z$JNNyQd$Zk26byNWogUn-IV;94H;{-+#cN3=)M+ozK+!=9&$H{_lUak zU(f6}|3Cg_mlmd=abErg+k>y!u*FySdi~h?5FWbP#0)S1M{cb!-W-V5}^sWK>b;scE z9phxZ{jvWGbPXK}@E>m|`&v+FA{q|yQX!}8X*RQG5{es@z1qwt%X8%jtA>n7>daw-dkLcHjp&2WcEq1^c zeheg3zI3ju51GNjmMl(sAw4_U_mdXi(*y<0?47&_>4wBhf6b;0%>UvaWyJzfXU^g54nD2 zbY`=0ylLnhTTvg+RV&!qXLj9GX-zMqpfo`L0P)><#qMW@9=)6?JSi8(DqqG1dW_Fw zw0G8u264_ulp1NQ2rrlTszZ5=?%K?$*cgWxb4RL0puXCGy{N>5F7mrNVsm=*tCp7b zHjvRx1mr&QLN|O5m429t>_ut6yo4pDq6N;%- zn#x+wMftQluQbetF%JPq#P%UCkRX?{fhwE6NVzCR$Gv7M5>`qJ$7yVQgRFORdsfjV zNqxL#7O4;WRuaO4Ru@vriNN$C#}ox6DccoJRYnes3aiDrJWExG z!T9;BZH`Jkkmmc>?#iYMHf2z3{(Ai%SKp35`AuR2_1N+^5y9aXw z@7Z^=UWm!Qqhqi>*^_TOK7mb5$jP@JSF*?m2~jyY<8_C2!1Lw)gJD^P%4Lv`Nogo* z7C6lv><#j6ZWrO_Px$`*x+(XZqyC*cJ1Z;ZAKO6|*P)p+vvY0Hw=GW&IG8?15EjyNVJR%it@2xJyNUZoc71 z7->#DROa7#K9JG;V!tUjcZ}}RdM+2aJmhe}uUOthP&+37-4}BjV*2wypNsE^-?lyDTEoQi` z=0ux5fV#< z@9ZqaZ6T^B9EFI@?we0c45NzeT>Gpm@G+`TX|THs=Mu3-oSSwyMBLTW?_h-ermX`e!X_LDfEjPZ`XQho`?&e zdQ?ept;9#8jZEFuOD@U;u99;`8wSXB@U-BCWtu7u7;Fp_H{EN zNjCXm%)+hqCuBZYE9ZgG`R~To%)vtUZNJIhFMDUiU)RP1$aqC+rp9M zdUb%k=HS3m-Zes0r>y`S7 z-XEHCMVU;q5Bj@wxLX9qOmuv^b}J-wv8kfGygh?<%97GmS+oQoHlehPv|llvLfr!g zV-gZN+kgCp0)J`xsm1&+PAmU<{EqJXFa9Bay=w{o*Y)1TrB7e;b&nn6Z~#xeqPe?x z_>-rm9-FT%x;8X}sq*?tWgCJD>^5_ia_UpGXyB!_*$2mDuLN2O_6_5al z52h(PxvsieZVCc4NY4;LwVsg522XZ&b~a5-6Y7@5Y0!umsE1}B@URJo% z0Jg$20X_%B1tdyw;AW?__ii%+#8^0&@|I5L@WPLdiUHagI9G&%7(m7DR6SzK0FK7z zO_6q$H;gh=ok`2fUJLJR+kv`qHk7eDFkD-!>N|-Ktiy?DL+_`irXqtUti7$I_DFL$ zYqdkicj4MggVxso9yn7_z88&xn;Duy z8nc99?dC<3ZYu!0-Kw87JNh;r?&Vc0$+Ml%2WdlecXyp6+NmIIHAyej%1)XQubkaQ&`xs;yri%g02*eW zTmZy0_};;RM+;dvH}(E_EZ{4el$6*3NEVd#1dlcVTHQGL z^V=tDmFfz;s~)g}aDWE{)Y?xZ0dix{>X$xkY@{3Ly#kQ9GO}^4k$kBk!{exZeH7!Z zht20YyN^}`815x(<2Dmk!T4iemY7>dQV=A4Acf} zS^Q(;;~khte4@PkNz@$hbdqhjl0%+8^<5HI`?GRc@a@P=dFzTXZfoL$s2{AxDdor2 zI<$RGZ>vstMn)U-t#Q0QSsi(fT(d!?rj6sYkj`tLZ>u!eMHD-PP5rt}Bc}oxq%|6i zu0kVh`S?!V6?>e;hYws~9hr(Y6cjsC&pQd*{n`NV_5WDJM_6k*aCEtyyLD(@y&<4J zutwULNNooP!|f`4bHN^N2DTP36S&)Dc`*ocv-WB9-Sa6a1PA|VvMn-aG2O!ygsi-c zAf9<&`TPwSas2io8A!-Arj%7PDG4X))|y`3z%)5NsRwaya8EoHgs_4HqdFX=^Ggz& zo14i5=P*IrD*pl;tFW+0Os>ys8jUJ2XwNz&<%UP@_M%v#1to`a4tS!vUYM91A^D-{5??On_lP9>P5P66C!R;6Y z?_`&f?CBpL^5lYOFLRcIC=)8XW@s$va;05S>^TNhO^al>;KLodnFpj_2!;cs*X($3 z8+w4ft>k!7R^NMDovGrlUkbY|1SaS?F)?=?Ov?-0lVoDc1_#}jz0sw4D8>*GHHDcR zqd^u(%RVAxJ%^kED*Y+FFLvrgAXo8j6ODBQP(PeeU&bI=GoL;tjS(08vLL!zK#}y< zf@ixAv~vEwkagL`$ItUV&7L}9r2C9#`RD3k@mo19bMQNN;KKXAeBW=hb!YeIGj^PS z@yiG4_qZU-19x9>y4t_u!JLTee0?`+Y)Hj^DvEQ*AoZ*^5#h3o7mNDD{+A zXz>y>Ok$1TpnP%cjc_!E6YylpVQFLNqq!|OzA3+ z*w`{0Tw8nc?X3w<|J|F}{Yo(-+LzA)@HKpSX(`@OQg)A3TCCf4>wZPUJ;fp7G7>yV za-IxxD*#QyDm(_4Xf|ptV}paY<4%0m$6) zo;@j~DC+9rBcg+Yk3l)WYFZz<>0PHCdAzM}tq!cxy}zip@OC6`mx0;Gq|Wsxo1HFh zUYV=VB&1>ub+tpcnc*U$aFUU-dDlW>hgenl@6o9aS`s%DPUB6yq zwMC|JE|0Fq;tu=ym0wU8V!fFgyr3eia{v0MA9Kdh`EEeK=9g-rN&Tpx@sT4s(H*6h zu+Y|_KvFHbvy^Bk<(||jilVF1oH^WhYpBmgCRLjlf!ZHH4UFeKN_bnm?{Yds=2p9{ zgB>6*UQYI}tTdFhY49MS(aW!B*v*@+xV@5*f5TnN(#8x(B-9R* z*6v9dWyWgdf!+v-0C2M;fcjyx08s4^RwS^^+NH8Zsp!FYAC@2s#Ie{_sGRju*;!?- zFlu*9hh`w&mDJO-`ik=5WD&~WgYk>_Nhtw;C`3#l7xJ`f377(8W4-dd;k z5uR4ZaNWiS_%xLeNU+5#Yo^uSA2zu{p*dK8DD=0ZYpxZZ`;DJrW3zu(Qgti0vX#Ar zKjEBl$&r1Q<)RYm)?M98{RJK17iWz!wWbeGPBcAgG#DvRaGnL=lJovE^Adv?0<;%U zAyb}Q=GFTU@33THwZJK2(eij4f4QjhP$h6+K|Su)`L`gytD+v7D2R>Xt8ljBABxhV z3f(Lhvj+jce!c}1j;<~hFD(`GTLtr{Ill>PzG72Ssno^4j{FCyUNE>SE^($^&@DG+ zl8-}ki20^%zvjpA7_npD29&EzcvcVRnM79(n8-(50c{tg+}l zIz(ttG-zcv41FL`>Ui4stNu$83fxEO$PrVX90N)IV%obi_6 zjOz6r7w}F{xn_9tf}g{4y%1>A>ULj^w)NZ>(pw?_nTq->fNATwJ-!Jf^h#ipM=StK zo&IT)q>0xYcDP?Ya@U z(J8%ncGP|JnKnZ8k0t$f=RDL}xK&i1!zZ4Sz>?(~4RUK9|5F zUY4GakV-bV9g#DLA9CL-OM{tt-ZeO~5ItdqoqWpMxL==xZ0{>hF#!q58|y4BKa3`;6|=c_ zct;b!z3o*3!_LL5&RV-W4#eKlZ*^_y6w(rsg4ndPvU)^B;ckRQ#xaGm1&Wa@>RX?2B7#wv70L`(9}_U0&JTKAF3bq|I{XSwiA zPD`x)O(1z>FpkUs?To(F0C*e_)8|`+l5&MLsRt{%dAa#JdN6!S zgoN@k9;z}+LWqsrfD}(SCr#YPFgItjic6s_pQ~tcr?rlIBFo&|yl$^y62INb?+zUp za_HkbEV?$GOZoik^JCMbhuA7w%_fao50nLw2A?qy`*`AA7N0w7YNMV6lsI+Z9I((; z2REQ;E56kJdV+OYspxYGW@4H8GGG$r@+hj(5FD2FG)%B@GlW4mU;@xU@fv)H^*k@8 z4p3!aJef*3yBPF!%KD-^4PIF^lYL}G0c^{>P2S3Sx8iKuXiW|}^{z29M+EXq3%l2{ z3$7lei~;G5d)ijR%2FUfe``n0`I1~Y!!d)RTDj?vlT)2ihiGge&!}h9*HM5VUPtO8>aIc~3vv)jkBRHJI?y9yOxLP%M{i9&vRPLjFMn?@? z{~yZUJFJQH-5=JqEh4(YDk{xF5kU|TkQx;Qk*4$>1p(wN#1eKxxTA=e%E=g!#~VSU}loc^W67yf6DC`R%D7EVx-F7{@9?* zZ=4m)b?VDXoax!*bQND~7(e@$f|3GWE>jP|vrC_P(-q`}#XF`sB)YBa}y`z9@eRNY%;s7z- z0#UsZVQSieJ=0a}OmM?pSRFX4BvI^oLHjI7GWkMD?Ip$G#6*(pH4I}|@Ys|2l(c~_ zxk6?&X6+1gV_JjOH#A*uZEXc~)QnRnQIyWXMeWge^UCKRC)#;I z{^kUK+{tN2x4I8EN_8Cnip=y)%vfXlg6)%e`J`Y;|D*Ptk=}uknO64fDS5OYS8)A=^Y1ZSFRJF7=-JoK9@t5J`;2hpiGOpV_JNT{+aKsarw%vJU+pS`TsO{# zMR0ua+C%5$)By%&cOrCu&k5xziR^hgR7`a9A_`!3WPG(1ZF?jE8e@sScq23&R_hXU zVB|K2=Yp(s(>_*Fj3gHTYdC01@Ygc%4hJ%1tYHL4#Y5hX&)%r0QPW0y%EP+FOuaGs znex4JdOQldZ5AW9oItEjgWT*w`nc_5b93?OQMu{$IaO&Zea=%E<|z9rGng69Ga=^ZGj+y>TYZuEz zqf}{W7u=ykR|W`9@YC2o9Noh|1U!FkctP@1-NcYMATzaAza{?W2rWlKQZg~k-F%k0 z3aIqiYLrm5qvd<_lt$wdKPULZ^5SzRQrC7x0h_pDI>n~+BshYqnJ zvOYCfo)yoNrVO-(A2z6HQMB(L1uXpfhwwHlfR_+aF%p~wWXNs+rFD7)$l8IGiFQU} z#`Sssx}1^r)s>Z`{EnWU*tj?wgPQ6p9Y0J`QlVS$=8#!uZ#kg5X6MdE<>H0_(0>HN zNvFTf+97Hl@%Q%!(6pO>CbDx&0-1?5Hy}6h#7s?2&Y~CIL3GV+ae2%M2R`^)e(yy{ zQgX5;Al}OlKh7>>^rtDq7-E#2-+Z2n75vckm|5A@hxm+Hg1qggUi-LhPhee}BO!h@ zCQ&RYE#S)v7|_QF;THz7yW9d@+{rhQcQRB=M0(1$1_=EM_B;+#KY%=aeU};{9&bsd zANc{k0ig)cz!E*#@jyzqv~C?ZZleBnjVKFfM9!DZ>bp~x84RdEK5oNs*%K121>3L9 z^In`~lvYbQz)LJ06RrpZ+pNsYTrO-JLzV#$I8a1&Uy&U#wlgrOP=a!7i)6~rncDWeAGgaX39GuJ@o^Y@QhjwT!`Y?*=rZ-U zQpdq!)*2~G0GJ&~FWDBZ;|#2g&mxOqK{t(wlt}?18M5lZZ-FcWRI2tX-)e*1933Hx zx{v!Hd5oB-nu5`lv`rg^zWqYCs&sL51u#_TfSi!v<-B$*-5K0oTn!E69rVv1jNUP2 zSerQpom{G9Y?x0>2+}`IwlA1@M?G~2s^NzVLR)~|8p2B&;qQ-6;>=?Zi~JScH{deo z|C9CIb^<)b|FidFEyBN_ZR0ueiM5?5vAnz@4RP;#*Fe=pzotT6zVGMnrMCdGEJ~re61*tkdMD%`ECPK7ZVka`65)^u^JxH5 zg$C$42f!m)OH5644AD$D3XZs^f8~I48KiMPe2R_$PRr-Mzwb(Q5U#zN1l_EWgoEv8 zO7teDL(dgkH{R86eQ(z_mn=8sz9RF380_8%BtTR=BzJCcG1dG~MMKkLnWrIO8_EyR z1rBJobb<*^&XUYl!t06sTo9c-^*G0v*Kf!n96uvYJg-^}Q(!X-PR%FRgT+aHP3)bR zcM@NJ)NUYhK#P7j7ySJB^8{*6tt9(d!>&!B#uGgF!Kl3DLNc%JgJGYgpl?cKI(cf6 zJOVhQk!%qP-nzXlXt2JaAk7~N20QgklPdS@+V9;-0r{`RSP)GSS8KHp&K?&%&wU>s zF6{OeRXLgeC+AOPsIc|Lpr4+~e{cSgr~MDu1ZY}?N0bH>k!|+m#!hLu0n~xbnBh=esxv6MnWtc1PsD5 zdivfz7s2awFlxX@b zS4j11n^WiFh{~ml7l1C~i1HK88qzjO2G97qfa>)Rrb4X8tyO}%hsU>KwU4{9ACkG< z1G9yMHlVSP3~#BXaG<#D{A1Q-KfVd{2AdjEQ&U@jUa4o1h}e#pN1=^~SBGBNsDxj-Sc4N2&ye~`sw>SIa{xQ4ogN^qvY1y}J6a5!r(5b~-)!AUhi2`P z^RC?fnR1-icc4+A@@2t2w^+Bx+M{zmtkwIdx%!zuIRv0paC38;1zYCRW!AEIxvEsQ zc*}A-PdL=$v~Hze0?0We1~A#P(S;`oV|_tHim`D*nj+`<3xm0*)Ms3q0wWqGhzxIU zFB@vKX|&YR7>kFBv>unpnEfQIC^7Dy|ulsWP49ty+N;R@sIc=4F{ur zOW`boA2@P5sj#>h;PKn85F?`rw#LThGe08W01k8!ow6+Tp=oE_{m(NKv#)ld8#9lk z=3$0x=PZ*I-+GMOJbwC8Ho6pT88r_8!MCe^KakV(x2}*Uqpi! zEX`|pHlS8^^L8_q8$v>@Bk3hwF!4g2TWdBg7i5I%Pc|}~Vb%?x>s9=P(j$b;t<7fz zcjIcKWw+S$P(@dx`*=_&6p#V1zPzZc@dfbPFqxwTN6KjLR^Cl&_(x|GrcjY;n8jem zo6L=S)WXVcw0$M{AJFFCEQBwA+S#>pr-MqfACVfTPIBGayMy4}bwlN6^*^SKHStqn zc19a7lEBQMSVPH_$uCKDMWv;;`D>{LB%B_r6XQj6XDlPMG{kRw%*s*=2&6x|W?W)9 z9lE$L8O<;-tNJuDbYVz;o{f~+QJ*$aOA#RLExP5kgP2Pqn;T_ZIp}~N#abnJbGvz? zQ#MZrrR$W+)tVOmz+tSpnd>Cy2Sa^5<Kz>4j`z$cV7q!^fxOLi<&0QTCyPo(K;b(MEXu^dupM~|STYvZ)9a(Nn-6~%ntUMFrUPlewTJyy#N}uy=cH7+C z#2?7l;Th>lu4WbhWMsD(GKm%Fo3>R(^ee||Y0Y;<@4u%*z~CVKE@6t%$P+UBZS;9b z1+o9zM+@BK42*$cgd6bgS9CoD!lGl(&mLOThWo#o z<$nKGBtY%Yj5YVUq%<7XU1d+mK;B|@P!F&WVy<#?H4u&r54$1!7T0*@P7-r`n49@Z za)S5;F>pW&N5;Tk*#Lr@GosLSZ}uJT#|?QAqd^MO)>i-+^`W!H1V;_^=mV89A{FnE zOI~AX(AJmQb4m(PPu6fp44iM^?nM{k5Q8OT*0u_%VJ%q>K3+fRzOr0JkC|8uSkzGz zPE2f3BQbyAYBkJeI8DSJEl=np1Wn+F_|oK3(BC%JK+)7!EYg^J{T(xctpYEfT#fV2 zw{c`To)^&S22DQ|?Wm!rt%2zrgwK?PqFGrI)JJkv@a-jHdJ5O72#4>K_W4}_X1FFbte0z#NkYY1s-AL8dgt{gqN5W zIIlXpFxr&!%@W3O7V4o7{2xEizYk`;u<-SP0)$-eLcl`h2SGt^4=7+{oIa_g3ysRJ zC`P;buj%`yeGLg>3uBCXZFvbw%J%`DRiTvn+?|^FPtDEJyj6WHz`N_jy`wrRz_Oqt zCYX5)FurkePDAwo89EzPNC}8>MQKxG(=Z|*MS1Ox;Yd*hv*RH%e4GG61l zb>$;_8;=_>v?2-xjMG12KRyjapy~sPr^e9@ zNK9kaUFaH{R- z=uCDxY&<$CaoqJW@(kHKA*m%gJnD+BfXo7|s4Txml9?Xc)DrwbwFDhH%GIf@{#0eB zcY|EMx06ZA1av69SSZk^=w=1UR~Iu!K^jWcy~P=M`ha8Ch@*7MYNkSP!_K zHIR8F+XvMPm2oLG0xLYe`+WBJo+u2=9X>dG#@$`9T14>&LuBN7A43sWAsIhrJ>dt0 z+(@e5PFZ8|WHC_5YN?9@3Zi)Dd+ks%lgJdDX*_w%r-W09dB_-{{0D01%82TY&jc={ zdNyugcLTX@NmsKca7C`+O6!EAQ<(!ONyU?jxGL*cYim1}eNL?-)LC022;_~D>bPx) z3aDQSAGqIW`vI5TWddlSkrs>N*Gm`dk8tsJ9qcpptg12+&a%G~M3Ar6i|BK>qNXPO zXPVwh)i@uK?4#|o;871xJTp&{J3`x#x+pIn*j;s_pZE{m>BY127cN}bqO8Jy``Oy~ z3I9fkXkQPze~9nhI6yl26in_&8K(t2e}}P>Ga|fr*MRqnxvj2lx`|qg`HjPUWi9Nj z{9Ic|@lD>RVIto&ULCd_ma0|`-`ghAu1RbvJ1F1! z%5x&S>58rg_S@l?23VfE(wW}xDR_lNJw!8Geg7XR0A-WU5CD|#@X|&+zwIdV9A`h? z-Q%tslUC3hc5LN&ZJ2lFID5UIBnTFn)Yki^x-)Ku=h(TPoQ<{OZmu2a^Rvk5)Wh!_ zQ=;S_Ipo~z5PDpE#~`Z=N^s0z7a3~ZK9q?A4L`b#+?WV>Wzn!$`&X&Or?M}%-M^=8 z@=sih>iY7erLk95yqB$gfQXVl%gm)G$hR^zn|*|j4{e0Y@0V28j^aZSp6=bG(;9=L zcYI?_m*Pek!5dG+*66&py}_B8bm`RN?x4?A@{gRQ8)je0RMQ(9<-c5$6d|8 zKl}e<>x&sc(=r7{RBD!UX_2fbKYbxAXWk?wrnVueZ+ljBG6v#d; zeoS&jc6s$flt}XxD9>;(_B~(nqvs^c_|Cr;2@0$|^14UEb$f>`>z3(mhXiUsKhv{% z9N}B?Y4PbZL4rsi{pDX1C^X^Y$E6e`pF$=LZ#kpF{dg_#(+-ikBY#N`^b=cU*}h|o zrqBv!{B-ONsyY8$sEA9?FoPDchizz`k+}svCy^b?5Dmw+Tentmr{gJ zvx|Q#eXsmm@Nd~q6?JP3fkH%OrDfxSDnQf%{6IZ1q{t)I`3AXt^`OC1U=EG9$T90f zo|~I9cTD0r8ZWTUEr5whsq)l`ck=h{tI4wwv@=UZo?T1l3j!%tU;o^zaiMYAV!Cvs zvVTlY^>)M;R7=P$2}0e&9JWi^k=`HIY|(E%`uDvFwLI_R z@UuV9RNd?x$)SQ5_+%m8gE2n794HVE-x;8OGJA^mcq`GvR8VFoKQcV|^1z@ixobEn z??gMaFz>2(p?fdj&0pc!TwLzA0i@M)i)J`f@O7vU^r4zse7;5znL?qWCM*H1a&aJi zuLym`X$7!DhFBUJUL77b%CQFM6bS#NJ3pmMz&&d7|BPQAcw+s$_RrXt2bCHYX0w95 zTKC4MO%9CQ`ATVKCTc!8juGZUoo;_&#MSQgKX|VDaZ2c%IFhD1G zdPYe8fEH#7hg)>>ZZgmV)CLd!mKhp}InUSdGa&!EzIEt7pVa@{I*9#gs2+GhyZ9$6 z`#^db0dWp%&wNw8DmLFHwK8dLRxf;Hu7W&|-ntljLLtO9e z0r4*m0Qlz?+`h)st;2ER!~=l93oIq`hK9jVGH!HeZUo3hMr@y@1prPp0Qv6+G?O&9 zu<(ln<-n5w{W;r=|M_13b0kIb7armh{*KOm440hE%GXaPM6ZX#U2J>|_ow~w)zu$& zYc#eM)&%VB>>lWr)Y7x%D==f14t_^OM4VuA7{yJzqqytpM$s#PIilu=loOWZ3OLx7 zR`KD4|8uz?8{MIg1UWZ|SJMAE`r>9%VxrI&?J7tlwnLfmEM&pr{;^p}CTq_md9r?b zGiIAQ@zjzEGQBE>8*NewPqym{RoWC9ey;w=|MW-DKPURJ^<*zJG_)-!@YiT=L(o{i2b{VNAv^WC4Co#qd^lAhIdeL@wO4hPr2A9N^CR$1Im zkqHhhT237t@u?cKGFmIQax2H$X(qYomsdUFx%lu??Qa)<|0B=_>^*h)%H=D2FluAq zto`NRI<%k7g|hT?XN9G$TLQ^$Q^73^&VSw6kKG%u9{i#<{MVnnIDZCc%>K_$N_oGw zZe-Nac>@vkAwBr016EDV46+e4-bng5Syi(CopfP%{H*-^UTEIW4>fRt+R2z-3e(@u z&UrnwtGH8#@-_rY_fqrP!nvVuD@c%V^G%j^R-J6l2a8aAzkWXT+(#i|HVjVwDS;?8m3?%-2KC@%=a@Ygxw z0KWIvkL8ADmRWXr)*aecTEaNhI_3aS>~u!ov$MN*-73kWy~x_4%{|4j<)_h%^VP(pDX)(;X-%nCe2$^_EwDSe7SUX(sjKQFC)mk;t9i#|2lz(3g<7~ zk+lcVzM(^@Q3;}8bb@gPPCBQ-$N#SDn6)ETw(2pZW47wo8R5VIT=@U#{<0e`e<~<= zHKk+>7BEWn=}kyW%PMen#3wjAW&QiqZ(@J>rk})}t!XtB?|^5I`}hl<5&U9~Lf=)X zMXCSmGymRp`QK;y`CX^n5&Yk%)L$a5X=Upx{1YS(e7UvZXL+!upinZme820pza;15 zg8b@V3eCXzwT%=r__u=Z{p)6azVZQ?cZYwX-2C#=kDZjq|37zj`QR@?rGK5k{!h05 zM-#~Z{Lzgpn_oYc7mhIxvyFhFfv7`;8H9$FrB?Lt;0jD#0+^lS9S^V#m|7p&hx#B& zfvBXD(<8B@>ug}79DtHJtbO5vZo$Wo)9bt%h9N9Vo?uIXF%gb|ow6n2`b< zOls(31v>z>Jo1BAuvJFMY~HnO=F5YSh3+HNU}xfG6E~MUU)Q3FLJbV`#_k;n5tf6Y zkx^c2aStga))1Q*%}0K;?9-MoaaO)CG*rb~tY{zZhvaZF?vqA{3}qdYaS8wr#- z3i|t>G}J+hwX$XI@R;GtAJky%WpQKGk|%kUizfWW6Ot>d3hrHY!wv(a5qHCDR}FAb zSnN)4mCQN%GnWS|JMNQp-i2aawFbt9xn`9Xy%^k4{ zlegnLPy2Rj2nd*@YI}5tLJEzH?B0lKP*kG0-(8y9ZECtiWrRh^5cImbSz+^96GNZc zLWxny3V+q)_65Ti_U%mEobrY#7xqh*?}uM7vU08Z?U5;*^%wTFclOj&TH1vl$jy*8 z_L=(dbLdb4a>bv%GAvRI2(~H4W(=!C7wuqC0AsX z4Lm#S`xKzB3$KSAoMC2Rph8}lUQXD`e4K&t&;%*1O3m-pn-33gD%-wOzf$l?`M>6Y z+KhEc>Hj<+e{T$4PU|XY`grm58$q+!NXwCW*|ou>17h)=DLrd5<|Z|YW1hVU2FnrV z_;DL7AR6hZG`u!n0**U0Mno1BrQkYW0_eDrgGr3?Z4x8Zn|reF0uRy1zg84kUtd4R zRw~HWLkp)J7J?1%kKJ>e82$3)#mdTYxzk6}*k4V)$v5mtIc!?Z7sj4kQhQI_XgHD7 z*oEyfOozKU?z%SQ)_|=}5N*&k8$7XxJ*qP->qeG2UlauI;baQs>1Al+$^Rbp z-=Q*FtgpW&eZPKpHL|e9Uo1Tq(q$GU@~Bik@!g8P;Jx?~-bi&rfL;8d0L~kzkR{^y z263P#=-1m06H}kzHR4X!b`^k;;^cR03ANY% ztz^W;CeWGB+RcW6QXF=}6hD+^TCC)0tJWBT*2wM614MEkynv)xF?c6LRAXBu&cAiD z{Z4S&@b%YO>?1Ftie2Hcqs-BblLppxLHYG80!rJAG&}5}eLB~NhmV(6dR}%-EF`T^ zc4^1VI`f8|BW}!PovNnRydn|^TaE(3H{!(PmlZC>zDx5`OoYNgpXgiPzL$!EiL1u$ z%oRRrMJ54eQc_q9ZJ$s$T%oq$pf!H?GXGF`OX9|@iAxJ1Futx+CyxZ<$mG*}YHN6O zYonWR+e5Qx!T2V;FTh2H>~?q>xH-G_JMSCih!Z2nZ}g^hc}<_Y+M9v-3wO4uszWhf zIYK8D_8#R!D+p}60&zp|bzbny!G#SjXQ^ozx!1yy6b5%1^GEA~E6mX@VWJvXznvoy zxNO9m2MwanbmJv2N!bj#mcrr|&Bt6yNwM^p&cn7&YHAryc}NtAGK)iKL?gU_2})E7 zAC&S|t2O%V92yFte%LI9p+_dTBgg}2652cM@678v^ecSh=V1B;urUE?(0HGO;vS(**{ z^vO`sVEvpX3_`jaQ+ij9D@i2eFn9UK(&xVwWx|qg67e*xmAU+j2aPZD%doA6%yK!k zZVEXGcecp}GNf}xiSE`zc?&$i|BGwi@|<_d1vrX_a>Qq!PRyL8*3Uf{h-|HM(M|jy zD7HN@TrezV>EDOa{gQh-94aEQd`h-;dD2EBtgPYhei!wzlc8#rj|ivaC6mgTO?%MFPh z)?K2_egBx1gP*{;$2q*izV{kF8^v~6$-W_8TJ%9%{Ab?kM!=c6N$6u|0Gm~t$d{F+ zTeF;}tqJv-tu}W~NOU4yloFe*ek+>(yw^zppWP2i<#PHONdYWA4<-pV$F)S=<;1Qs zS|>;jOm*h)T9?&~E^17mVzyStr{J@-aly(B&&bMCoKJc<0RED&X6QOS(7^W92S?G# zcGn=^jR7Nyr=LW#V(5APlMCLUkJFY8@lP^Td>=Pbdg*^h)@nDxb8K8G&l{@-ui@4^ zJx{Y6*`b;(dL7@2VA#zOB!v)7eG&%! z57tqWpO>FinEe>2sz9W7dbBY*$7G9Or7dME#~nxa*|*CL1f^wf{FZ(5W`ZG35v8MW zAur+`v6RR3%9|8-)9;3MO55HK-bH@-yR#N_%uIqj$;Q zaWp|gqoTn7ah9lwkx~9mVi%tH3|)@3zhY{Ad&LQuVdvjxOBg3tn?Ki0hBN^>8c~t> zD~k4gkqQL!f(bu}(I1jSBXgiDGKvL9kG|FRHx(e`rpAZYO7P?3MK;rlS>@%HPj@Wq z#+R`@;U6qBhKCFbt{LUOcmqU*{Pz6MqFwl#1?`fLjn59-e$GHF9cl$w`KS$a!Kb_T zzoz7&OVoQDq@(Sm&l^Ow&yoUWHh@MGBEGIV9FPDG?uh(Y=@G9le$1@`ugR&Ir`jJ- zI!v|p@9U*uHE-~5r>CD}3;}x7?Q?KO9c=BIi9N&2G}79kx>{U%zUk#9$PWI90sjDX zyhQ8B*55sBze8{TCjQeG{Yd(;Vv-K1sVBGjmjzcMPv!~L$?h1eb(;*L{BC3A4e>N9S)k+qZgUc=L(c1f9W(QN~ zf}&PBI*D{9CV(W6XPL5I(V#pX7kQcNLtb{v5C zbp=ox1Ir{|ksbNV%0FKdJqSd+( zN&K(1Fgu^#|E6TPktNI|O8y*LgbTaH7XMsGla>v{Vz*gmR9{X%)1Q2Ap`sdp9y0&( zWz+st^a6{J?(fI!e}3=&mB&AZ?4DRG+$xoYK5xQ*UNiqQlXJsQTWH49KsQ(BT81VH zXIDXsIuovLRaafomUuWiL7kVTnLBtb@no;R z;gnJ!!b^dMh3nSA!Ix=UJ*e;66r=`U?q}^yDWAFVEH8SA{M&`y@fxzpn z1mA0+Z?{~d_2EDj@W$D+l`?dZk7v^uiL*&joEtdH}8Zb-(=>U$AFy5ZprI1>9lXd+S05d`2MW3-!lYFnlISHIZW~>mypXPgBk~tgb!=Mh1t2q7wsg(&@a9nUryvcz+4b zsK$AF*i~NY?p(m&Q&fzU0?0RdO%hgQFgvM*5ztKlp(#7_i#5~J(^AOu{Kr>nB~@?O zuR1#w`PyM581!T*PrXM;^vtfa{7MDawr2ed!C4?*GtLTHa3@O}gP}tlNO1p04pLj_ zc#K|>Wq5|z;KGG1SD&G@!hOX!T1#fy6qLQO2AHyD7oLXET`Dhmzhmsbe0j;rfsupf zVmeX+rc8`X3b3VCw6eMu1GQ<(WPa{&8pLv~2kGhF5a(RR=s?u;Pzel4Id?i)*1GJR z^mHR(J9gds(`;KWkmr*vkGHqY+GcdNwZSZIQfwt<90FXJTLy&m1quWEkcD0V8T59! zi@=JO;+@NgNvc*;JIaMV>2k4Eno{?XTAcwcX$FmoJG1U^m|R<|Xr6w=7DXAwS{8 z_$#YaN6t;*1Z=e%L$_{wL~oImV*64a!jo}&pE30PbAI2_YTDbb5zGzyjBML_9V1>c z6h6W)Viw{cd25n(vokr^_X91nvwhBjMGkeyYUXG1g#VKuIgTd}-88+|2!zTc$j(`Wsvs_{6+|1h=XEm3}Dn*qqW?HDGH*hbq*S> zyAZ*gEm{#M>I5;R**dLKbi!Vc|N0I96{pKTW^S3muP-4Z-xnXro!z202Bz|AF3g@I zE0nYh?Ck0A1yWY1;iODelN}slK-dM9^6Tak@^<`yuiY?JYe;0fDV0)gv5s2^KXR-_3X4ioJ4Y@183P#6&D~ICLwZM^s z9~&+PTr`6Xl6tHe44RInYq$kocurE8;aKJ3nD!${iWvLi-nsDUl&bO^n$-p{U$L)V zskw1E+ui@_`p~>!%A1}P*)(NhoTsPkg{e=aQsJL7emhxjbvMSC6Z9L2R0`@a3%XYfyeMPq-B}mbtk8r^MIXiUOb;eiBffa{X><%{27wypY3fu4`&*LrM}udK1l zeOeo>)>L7niVXDtEeK#sa`(E9N}>FTy%`ogxMx9DHS%@GY&ry`JKV3LJuWTTdQA$z z{6-lJP{59_p_OY4UhFZycN&(kKd-c)wK@dZOG5-=6SCp5l1^UjtW&HNFlw`rx@xFX z@BTh&&|$dBV>Yvr;hZr^x)Qkz?%9lZxKMPFM9Gi z!_YQsi@)ZcMN*@Zz2-Fp#YyiM!y^kMu#{r%eeM#as?KfmJKCh)@gdnWzJ=yT9*&PW%jh=q2D}#w2IC! z;=Hr{rqk>5DREbe)hJpz|5RafKpfNh>iH0t%qs6UF5-;68dfi3b-lgaQejbO+`KaH z4#s31ohDyoga}%_M5RHsd62oeQ?9zOtzzHF(TV)_0~2l8(f1qY4yDNzdAGx9H6Ws# zN!n}m`<&Nw?rF3u)P(KyfE$aW-Y%9G1lQFAUVPeSa?M!Nn?};Y4-u#1@Cz2m;68@- zN}t>9WMY-=%FKv8W7q~u#FZFFEAwsx<`qG|b=K+8NgX;d$JJGIN>rt8QMOFc;m4sklOrT`ExR8r` zxFCsb$~hlx4AWrj? zHcgRoWpbn@pb$Xj%haEIgZQ$vIbXOkUiE~Ku(wB=Vs$W9;Y=0-WTi0OGyGOnwWJqZ z`wYvM+m{~&^jVy;Wkn= zEi~@NQNYBevyi09V3LC$*UW!Umt3wdm5RX+`ZhxqV8JvDiw3Uuve2rSz*~RBvCEym zog9^`hiLq6y(r?f3vb+J`OY6BW7>NhsrahNjPMquTz=QQn91-dSS2nYJ4!E8aV-j2 zlJB#zT75muFgWEepRKkkr>-1`lXAX1hRjlqaD5$-42985YozJ~?#^H+#F3P8!R_6( zsr^c&g?HRMWXAkN$#pHp7|`QH_j%r_xH?UqSksAmGAW}VMkU}n^heo8*Dox<4#snG zQU1I)&@^*7D$FmK^)is`v$6i8?iWgFqG^S^%_LluO9ZiSa4Po^;1?P89Xmi>t@WBJ zQ5rJAY+5)KsNV8;fT5}yBptp6)sEef`d(ZYwXD$HE2=Ld$B!mwDs?B_kT%Kww|YDq~@$mwN`0Yr-sg9hb| zfjQI5EaSI@h&2dW!UqYU;OFhUL58tJ7WjYHOt|@nuwU$J<*<7h4kx z@f0e5inhW)6GiD|ccY^)z<{vz?Iyh?d)t|1S+U~~oS4y#>avg4*R9SfBTdU|joQCO z*V(!WrKSiL(*#&cQ?+E&_JzJS5$MU&B2m717`DZs>wErP1_-<>c7R}v#P%h=jZQxo zcpb_+>^<}3R@6g_Qntj;ATmDFJ&Rd^SWeJBiFyX&3HhGOcc;nW+dF^BI-)J3~-Q>^1WF#;;p^rjHa z(x{9jk2Q_GzqapRa?XS^!77Dr>X~c}d?j7B_N#1rsG>gfz6An;+?qYgvUVBrE_7vg z*#0oj2tKA`_SGHqI1!^u!@9$JTSqqi-^6ig>C5oE>ewS8nR`kk2NMXZlx*eJ7WL#t z!ft2VqqRLfjD(wAL&CEMCM65>DprtjZ@+NU2kh1uoSMt(6l#hiif>!ana+I<5Q*TK z^X~wnk{HRs*;o?c5g&mtmPMc_TVZJ&_Z1vH zdCIRRSkkp$6|)|%%UTj~Us)t#r03@q7pBgu8YDWjMiXIAgV*3Rt{+Jdk9?67(bMxT z$k|^F@NKib(T__5gJ@DI-Dl*gskS%#?fut1)-CNmNu{LI`IOw4+M^|mRyzIEii5-* z{DmTpkUHb>kVc6xF8G!=%@k0qSBH?r`g~lNH~p&}5VmbLo{eW&-x^6#eDQ&#zY)7H zK{qMz*q;g(|6^18;Qs~s`|BR3Cxhj6Mn|=M6|?0Yd@a-42FJ8Enc=c~|7-qJ*V>=UfM* zebH<4%uNCTtx6#?S3z}%Y<)))*zQZKf}EW31p3jV+kN^u_~Efx)vfKit!rn)>upuH z@_}dyte3ZV&ubRWJ@5e9Qbp$jiA{>v)+b?x0`)ZxDEAMNqd@D^PlL5Rn1F-8OY@mMY;r)jGD7Y^djs5Ix1gQHY@f zgQN~!Vq6TUoB1lBl!qoT;#x2XuR02U^rKFiKwNPi4uv>t*M0hQS5{uW-j*@BA4*$(3#r&D`piP zJeVM9-2gx*K7tKNio=HB#VBx{S8DwkwO7qF=YE8|a{A5rO8(y^tGNp0Bvb6)HQaf4C4gG<~K0$8A~$lOt6~ zyHk7n1|`bryvDCyy~@GkrpUw2`a1UzZb~~TUREMI{34A3sd+%^Y2iBhN9CJl0Kya? zN}i5X*Pi$zv7SSC~0|H(k?HB04PYfhiDUNCe32$}$N-a8_p@!Dqg|zf$$>{hS87LB(K> z>rMqEeA)e~P%>n0R}^y7C0SoGZ1X!IEud~u*SEW1XFhw~j}*qQD-pxkqZ;WLc}T+5z;ydym5LwJ&~TGSM2td5locBvekjzI z;US$*m_i7kK1V)l)}p@!Gd}$dZX^=}O&(jjVfh^T3L8Q22>|r0bf(*MtHkY`M&m9` zVkE(AZBZYmpUUT88(GB;s%udj?Hwkp6?a2DUpacw)?L>R- zQxz89?ve-d=#r;M=I?tQi}2a_5-aVY$CI!kpsDk*6+j(3t$=*w`xb!#gu@W>q|&fq zr*bS?`%56rAChP8p>o7)igS^DjU;p++0bY@U9N~cweUs-1{b%_O}S!q0(yg2$~1J$+BUqWDaVy??*bTvftuC~rJ6iD0IZ{# zJJg^Z_;SP{j0(gez17Os#dkg@C*Vx@QP0=gdJ4K7mh@iwF>U|Zz2OxEvv~^Ae(y4E zDp71}_sjQ39+Ey86SbGPdh42K(e?f=5BhjaN-VuWfqrUm%PX*xk$kCmB3}&(wJPl~=anuB6Np0lk;|>EiGSDlxxYD)Mf*YN14DBI9lY)7z zEuj8$d!y;4+5+r-4UB*Vw!%;@ z2t-zxz9=b#=}pGykx zsTQEA&4|?U2uHbU&b}a$rip4G>C^d%mVU0>q1&SpF5O;ylL+-jgl3Ubdtqg!*jl;- zW%!W*o}G&)bStXG)E!eZ1-!Yep6fb$maod>OBTzXkNWl!(E{P~(LWsXl@{bdR8f

B}mD)=sn=E>J(Wb`z2~i@5J4icl|CNOzD#V=;tRk`;l+Z?s~c1;NH6N zTw6;FY>J1U-^+V#Whc>TE9oM?%aBx2OTuLU@WsV}+M*-p31fcx3oqJ2_rCK&8YHM{ zKFb?(pyj$|^MN>bB+x?z>gr+|eWm*PLre|CGTSyw$h9~}oU%2h2O>pH<>ExIO#5v` zMO>M_^3nNt)c}A*1xQI#3&uk#qh@N7yWzpYw{@7&GMWtTishow zHUP_*606}6M!8b+%_W}qqb{GuKFqwFZ#_!uOH3hom@hJQ2 zxoT5*vYZ?8@qQYdRUj6w+1qO&txK2kFtCL&psW(5$@H6#t#1`D zH+kTNil~rUO`Fi?w|og@!QoLRArR8{Z-3PTmB3B>_uN4Ed=!{i6&p!3M#(9jVft$- zDZ{1SiH;DduBYhXRz&X0-i;Pp%bw3K7UAypDIPB)s$6pJdMp1>T}+p*ljjeRYsst|x-b+YOi-tbGj3SSJxr)q}5a(Y*VKGfnHtKdPG# zY?fr#?leA}a%7uGYw_QKg=73EX(i&`da1|T`!goAS49L>>qgGB*fIi?OTDvI+Ugfc ze6|a{7MG;jpVWqum-#$4zAG?R7Xm>i+TNvGC!BZ#kp!9-%wsvlZiYIW`G*?u|7b&* zx!gd}y>U_)f*}2Ft5ipgR`tRJTGhcuO>;u(Z+Wc8MDe`xvm9UYkbZaYbMei#mBDaPC(MIySZK{DB<_^QlvzvW1fyFg`fFid@J(O&x&E^gq$IELco< zE6{)oCJgrm;pcH>EoXaFrsAYPYPwTgJV@kaT| zyZc)k>)hKFB4NI7l-W!B?#-LM<&(7I4S&=3WIlBuNwb8?Sp3~#yKcV~zUNGBWCiV% z=_x;7081qF3n)vLZd5D5Zh%hGhFp>AnRR*8PJ`pxM(Nji+E*FJd)u{OH>77u?w8oA~B_|6Oyz({#j!6sMy%jvpy}=iE50cAb_K8 zQ7%)*+>E=H_bN0kpB?g4Zh-kqTJ-flFY@E*I>N)>qp(6P57v|m)LE);uoe8M*20fS z3xYP+4#88F9>fWbIwv@n@ho)P>mwsOsO6pd9Yh9f4Qmb3pY81uP}0vYDrDDGw3&D_ zC6OIW<2mB$#eE5qBoHVJWwl`u6)wLy)di`>umWY-`d-7 z#Cs{m{V8_MoJ*grT?R5nYXf3+kUI{d!Qj2-9We&MEg?GLew!e8V?w)4EAAroGEdZF zpur>0v!DvwbUa)MN~1m?g@aj#UNw^f$MC7wziE7)919e*1Et7e>C2sy+;Wv1ePJI-1yGfy_*&$f<*`jE*t)Tg#Bk! zlj-`#4eyz8bWqU|MnP#KRX{*MK>Ao{0wN*=q)JtK?<6xKD$=BPqSA{Ap@#qw>7hgr z2t7auEkJ+(A^o}8`~9%@|6S{Oz7b$8)?(fFb)Drneuv|o1JRD_YMbYY5Sn!HE$iVziPKBk(@vAF6a7%69;!Q?blka?)Ebo9!Htejc1Z|9WN`F zv1qIrhRyFHr^vEgSGT891+t${ix?0EeK_$OF53}C-+s;ims)y!Ql&BHnYd(a{3Y>6 zL6jpy@PewgbV0LH@l`dya~plCJ6W{(g@o&V3nPj7%`E;ga+EYnL!hhDup`Cr^Npya zKp}R)W?!%6YRGe?TYkdnkxAi-IcU`zR|E!QYJC*bjZjTD4he8KZ_NhXpzV8TxUIm( zUZ*fY>czXrfc9m=+y*j|n4x-^6=RrGQXrq`P>I>Th%ws#e52$6;^;Sf-!tRa(U zJYg<~Go2~&3vo*&*%7z4zirk_Vp6h#*)i?NC#%sw?hwg(S>6^~SC(Y?t4}xFB?1dH zR8Ro`#X2{CCuf8j>+}f0x}{duA?eI4$WTa0M)57wOOYM=uk|JCnQ|Y(L@@0MrL1F7 zk@7+Q7ldMgFFo7V(yU6PG<4jdh&tVP*UZn2t)8Xk@DR#>H5V2FhOJXed;I(x}$r9{M#`@VPQ(q7Chv?QJeErB%0YA`u>~QVe6;KvhKU+05*%4i2 z7`|7MSgCrnoBlqRLY;{oJ@iQB_h!;k;yah)TyD{#1)A;nVkMk+&>@NOo%+7N$0q%e z+*x98IqT}HRQ@{1EUX46@imh|+BQx`j^w9$cqppj`2K(J!msy2yv+XJG}eC`z5j1) z?cY3m5L(1dt1`?tvVj3nElPGsaX(?Mcytl;sZX>MXZO3A_|p@87b~+GXGa5o$T|3R z`5iR%k)aZD0-2tbN#`qiTp zD@|az(*dpG1YXw(gF9HW?+Bd8$X4(Qg2!(@l*dsm#wW%r;L&@O9S>l|5JCh3d*?l3 z8Lgo{sB6Qgph3IeFCA{9a#y#rs#r~OEe||Ax{AaHpY7V4$saWripasUA-K@SpxMdAwqR6s^|_e^pxd4S z-Bc!CpFhnx;2gJVt|k}S0xX77X?*!?c#uW0^dJlC78@F2?U?Yzud>-V8(x8g#q>PE z!C>~=PXO79s#|4sYpn=wJ+#G#bUMr=#4=O%;`#Gc4Va2bPwxs)eE4^H;pj!*MxUTv zAaBM8l>u&ZnUw^l6YOI%JKFcYK2yjQ>O%c}Xi!pKV$hmG6(BdyaEo3ii`*sx`?|87 z3yg4k`$Er`7f3*!YOo~mvd1LU147zl<-3q{L?9BEE$L-sTYYu#L6{$W^G?iUMyZ46 zH^e?YvND(`WUE&B&(Ynmk0l}rAn|G?yy2Q%bo-~KicoOoijsJq$ zxlOFO@J2XdQ8>3-J@&Z#jbfq+3vBw@es;w571s4Pmfl-_`hdXya z23WwIOfHF8t9n(9>J=`P(9v6e8cQ1VjuR)m>|2w{y3z+K^HZtnVM}QYc0QgR1@e9I z;<4OPG?D}p@*J)rmTgftD%UqRRMwRIAD{H;YkiKLfxlRdhJ%-qLJ9?wuMYqgvDwsu#bREhb?}X;VgYxe0DGuxDg1i(L;O?e@_~&5DUFpGm%dCfYuU^p!U|MLB-&W_)Pf zBBsSr(zZGSfsWxO#>Uo@$vZngyxu$6H3Sh{pFYh%?a!#l&PT;mxCmW-omBM%H@Hvi z%#l$n(>>B_J9g!C-ls>u>QEqj19oNehnN=OHl5|=2csRLx>lSsywp>DP;|Ia3bm8j zWZA6v(w2~!X;hO%hV$glw3I*O#N52r5cX0*btmD0l*p8EL70pn$aSGEqygAE)A#)# zlkG4GL5uF*LoYj;hb|{mBlu1QB)6Gy=JW($j<9O+lK+wL(AJS>jT}Sqp|+X|?6a!w z_6^7H7Q}9z-86BoNO&%={ljN>xpZ)cADukd&Xx?==(*L=T9eX9IpWarp=ITiRSbXm2S>S#C;M zr?RFO9En(bLK2j|QcRzFr3$jJCphP%j=w7s+qvZyFV(^RLT+_oPPJH4sWW+`W}$B9 z01LHy&JmhN`XK@}RaO3Q+qu^MVKqDux`w1J=Lv`D>V%GEl%`Av+$x(THGL7Vygs&& z$ET9JPY>we^EO>NQZG9%^U@!Bz7Oorz2S&#on!U*i%NAxjo0DiRmU^gt zn+=wBzpJzLsAi`Re|&_`ts5UiiA1j_`}z6?0@?>^HAoYvFXACg#Q`!I!k8DSI>+~_ z<7o}rSm4e^k4%$DJaz*tj>xvIA=n_vtNhx{Q%zzq*k0_nBeCn)pS{sJzs3J^x{GFA z5`5RK3iKK3Fe}NYn z?E?)Oc@+DzjI88>e&1l^MRQijB#;dAG|X&w>p^dM=3q7ocY|#HKG8g@hIdP_nX$wO zL0#C1OT5IMQ@muPoig3=W4d$=lhAp`3QlH8>F#}yHlB@H>15_fZBA_P%;V2=?QORPZ z4Q5kFxRjKlTYInynQ+cx7ufn#aewETAcO8(yY= z_BBYYRpcf?XX(l7;eci^dQO~VI@=4{T(h0__IC_jr!g^^k1Vn@QjrG7EH5SRS;z75 zrw6pHx>94i8Xcft2hchG#B{n%ru}TcmW9pL?qVK+=>YL60+3l7%_$mcadUvDG%J1x zKMI2kX3oxLBd6{!chv2+O9)$E)iKEM_*?gQ)FCWU+Yw<6Ef-=)-h=h@Caxa$4EuIu zL`enIyzm-ygxtIqMB1*avt^`kfzM06?{V6Xko`tFStY%pAC}0eIZlU$e`htHMWT=BIJjf!&Ucqo{xQNJ6rBd?h`JfQ^K!vhm(+|%Hk;&C zJuUr1N{sR!*XI9U7cNavwH@e4w>yq$GI@R>jb0Z;E45QK*fdhLv<%Om*wPOjou2Sg zU3(W?=C33;ojA!W`SdDu@nPEAsU(%U=jFdo+qwlk7hmRT3^vmFlmWGSnD)o?>t8y~ z@xfat*~7B;(@i!-^LJdk(zNkq{>AIzb%=4_Q>2ZJ5NP^CTE3g8ub7pdTThNDoqbvg zQg3DNlN5!oUmHQ8vB|3@b!GQlDIeO`T?Ptax+X%U5EJL#injtYtvVKJX`Cj z*jDwYtU2_(L&q?LyNT#UBUfddC1{m5tRHF6)gcz*tacCM-gwVwJJD9~qc|;d{*)}M z`tjI}mkQj6G*h;@Lc}|7r6z$=We4Y~_%!a9>VK^*lVx+boY>Y zCjZfyw{PaOAG(dXIH)a31b%38nvM02%qqEeZ}pPVS>>XFVyO3%G{*`q$yYpS%zh|- zqzEfz*jA4m@cGMc!VMC%|K)@0<)gf}X+~k~irRiNq|2tJhrg<^9=`h7R;{pbUOsp7 z0o<1UNl3Fq_?(0cPiW1pH6Ui_+~Kkk1#US&jJ8+2NFt$;4#nBs!3SLl=$Db;XgR_los!s&D1BW zWb2$%%N@{M!cVdoI8xjY?0v@^y#Ff%u<&rd9#1f>5RET=p9Gi+wX0-JbVeV8){;|o zwx#s;XoN3`jYmaB%lxzMTdb?tIX;C|Z^zt}C`_5+-`S>1^V)Z{vIUKjDvLwmav4zr z4%gcE^wK`e9E<0+HI}>yOxY@UVq>!-(RWqz3@(yVJX9H%CTloHgl0pq?0`e_PXjCj88-}pb;D^L$kOM$sy}ms*%XPT44>k$zO9(d)&?&d zXh9Ul_~8=N?{=WqfUdr>4d0oywv37=DMxI+s8B_|W0qbT%qoJ*O3sEeRf76vb}h3b z?l3XY04%_@3PKgdBh~M&{&O!zDtD-L&*nkfKi&wnWK5LaIq|HFQ`iXylYkxO`0RSP zx`NIjuagm^KIYM?DhF)Pt~gJQV$X%8I2a_qF)|Uec!5&7INNcPkW+{&5ovy-SW^Hp z&N+CYwefbKR-te=t;-~?CTPn}n&1^;x%Aovuu0KoBZ0PgM-Oqz6f9)Cd|lJsV=Nsa z|5zr?6?3GAR7iL)o*?w&;-R1`DO=j8GyZEAcWNpW<56;POe=_aOuU zQ9!iGnT6B@V?B6#pxB26))m@j2Paa??!%zPdxUp2xc55nJaHr+SZOm<;p*fQ*7?TI zUkh&FJZ6gyv>}NtnI5n9JHR|Y_8%Y_f|Ws

ylV?_U5_f%(nTUcR1VIH3k}U^dGi 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 z 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 z

    Z7pp^)v&V*qPpnu&@&hIN4fQM- z*{Z~wo;IY?&6YFX>M?(56 zJZQ>Qk^|7 zz4|8=c5rJeGtHJ>OyPH38O7Lrh*uTbbXz6$cL?a#NzXbes$MyZ>;?t1D+07syu8i` zg~E%~lZiPt-S|K&qXt}R!T!Qi#(sVs6}%cj2sW~Nyxpz^0?G8+{N1>6La7j>ExRJ1 zvrXU8hYO?9Fu;yfc{zmtc$DdfW2hCNB94uA**Fx1Qvfh14P2StNNDQz3JL*5bGrpF z19ozNm*`-&T?|dlB9cA?0u-p*1ofSnxdjCt9yrJ@d;zeDQy*_JRg8}>bK%8{sI!}) z!PmTY|3mUnM5j&?jph(!XiHVYL}2{TnyZ|YE-|VxG>?W(2KvNjk z)4Np7aw_+2QvnhHb{1vwOU(y*=rg8{_>JmG$8X;$;I~kPp*`PWNjdC`^XK6j!KC)> z+qdU_SNhi|t;-@Lta2fh3lVrSwcoivpu4?2`cCj3)jP5wibU~blXzJ{+^7Je!a6$)sa!}BH z+cxaG*IFIpws+Mwo==N z=pRe=9(ZJwy!kClPBh#wDF<{84KdVT@{Zoru-I+(^f-Ac6>UTwCy*af0T?|IYZ{P zeanK;XwQ{#%-rC19?da|2D=inKZnI`U^OHhOarKV@oFz7RV81?Cng#|s_mk?yCT@V zb4Bj~h=ByCnU$3l3&`dmjryDYJUQ22(8~RTi|r4H^tJfgORUFrxhtfV&Y?9uf2xR; zrSu&Q5UWS$+i#5-NOIee2#dpBZoKx%@`a_VFpOPH!>FF5>8_xMVdp9>G$;R>D z@enR(l0TIByf(;}$eu|Zunak?*)~Xv$^4J?(Ed8|c3JdB&+3@>c7?LJivQ_(coG)@ z91?Z>Ww-C#Dd-#+80fNWZSJKo-kta#tp~*p5_Eq!UKeg5SmhXQtAv7qfx&a&t1#9q zIe}>J(NRN0dmH?ZmZ&iJpK2;?T`ZSatB&hV`v3OvqxD8Pxh7n+2K1B{0ps(CbWA@j z=4|f&>~jUn|5&SO>jLbxzl(uAX)(Bjw{pA#BrN|FIsB(P`~9E)KdAOxw4T;SAsFQb z1_zh-_Akij;XF96`eVpYb)_5C$gJIed|B_?I^YI{e`Fkt$0(Nt`>-^xrl#ft)K4yM zOPcxa=vJ!gx?O9pTLH7v+nCEAUu+@vkNYbr9&}i=GxHbwtBO|C@#DvL%o}X`G^m?X*|%NNY4ZaV1xmR(U%(b^99DdJ&C&VQ)HbHsszTbn2q&H2k4C%G1%jG|$GcWiBB~a>_{W^%EL&0D{+xPfhz3Mn2^SXFd z4iwD(e%m_@Z#qH%aUMyEimGFg(y|aCe<3j^p_mNEWn?|X!w(>Tl%yQS5yG~8zr^}c z%AZ0Vi(7IM3~zzmT{Mo(isxq?P3==FTUe?yyY6wOs1*!p`s^myTDd#>7T4w!455kB zlz>Jn`5gO_eFT_XumGMwx!<;m&LW_h&rXhweOs|~!`77q7%b`NLHc z;ZpL;SD%~v)!zQK+*jL{=PIB3DNknSuiGeubNY{eq&&>Hm0xA}JfruZ{q4=)yP_L= zx~Da%+_uag8m~02Ob>iTUv&|mUPdU*>Iuw3t)|aHhr>$qg{Fztb62mv^1o?Ghz2V% zuOK8Ou8iLc2pL~aoyDD&UeL3LF9(tw$KP%YKR$m}B_x!zsTv_Bj9DBt;Mx^!)x}R( zSca9q{>$UT@4o%hV)&(t#X}4KFLCYqVz9LM?(4&Urp?bh`6pBG`=9SUy^t7O`~Zm! zI~Shp5AUvg^ncgwE^g)C(>gQ1t@;2IkD-AL@v0Zw^IddhaB7!39;vG#J)1}mNmw9^ z1F7D2A8M5dxuv@oHLCQg#l={f_@xSiHFZ z()ja>FXor=+7h>g*z;SKo(|sxdgs$a`9J}043nDouwV)U(pX(pf(%GQS{u%#7RJ1VA|T!(gKO*=RO$tyT`QwFcB@SAwg~7o{HBls+0{cpbk|XJ6%TK z!}2If0Q(&l2qCQ3*j5SlCG?!F2^~XoxOo12TE;f}Z`Dn{J_FPh3`wFgxrqf^*QxGbCgbgb+5Spx+ zrhB!tlG4)BLXpOULAJBAGorzg!XcDT1!AK0y!PCA=CM{JzWjp}Xh-o1N%wM=JS zZoB*X$oFoAAF7{sjwVm=V9(b^zHo2PN0hSfLGVjL^)>+U`0wlYx+F|oL1+5bGXji` zUO2Fk8JyX835fNxajTbi)f6s|8k_ceWM%vN)Cd{lO^=I|ONX_b-#(_A^hZ*tEO zcE@0B9_U$umwL)Vt z<6j8I_*L@SCavMew*khU#vLrc3*BwRcrh0jDqMjuHK0JWOyFc|?y-B7onb|EOhWh& zyps^Y!rBydjyj2rrb?Qyx&Ak25}}v0Bm*(PA%j*S+mq^m$-_bOO@E|La>Y!w@_HyE zV1Muw)ObFkIKZ(@w-*P|=Nyri+fY6*JsQ)+qUkVH1P|f&ib3X6)bnW}qqGljUcv%_ zKZ)sH?dn(7ogyO9=MefH<#m{mTHtoILxg+KAEAE-{+TECV!W^bXW51jMnImIdGwxa zI9Ae2mYaw08u{P+C|1XpQ~&`ug(vPN&-uB?kUHHf#*298&!4Yne|rD)7;`^<)?l_r ztztYpU;E0Z!+Gw-z?I&@=dr{1Ff2o#6Ea;EhRBorGL~i6_%}j z(3L#C9Gd$S=3IbXAInXkYo68N@;Uyshe9vkT7?}x#;lYRT`^fDDH%<>FnKuGaVjqo zo1LvA8jnl|xm<_2&jjj;Fn+X^<1W4?QRmPhyIgL8&Rl_ukSOMnm5Ss#!$vFO;M65v zA=Ty?8yKv`*h>fK^rPx&ruQ$6QPhbXSlW8t^hmo|n|NGDR6E%(CoayI9__T6!dTc} zLP(-#1<&M!7i@6+7Q7O%XhrV|^vuzcCWOnRqr}J6q!z124I>l!H zznU*k2kHkACJ)F7TDBt8=miA@x+G{8 zbs~L+F_{O1GqpNOEYJwgaa>Q4A<7EqxlTlC^DoQ_ibB{$^??vy!C_y|L--6VbM0+f zp$XOqIxcrZ!x?iDCUutByF#<1i?Gf(B;P)r1*B0-WG7huIFNp(dsQsJHIL^W))vy( z(fycwd3gqAiQ#|FF z4m3oh47tGJr!S$WIK`11f-N049Y_yPyHdO1na?C`J z2tm?wRJ9ks9JxKk?nBcP{^W*=p= zUTXv8R`K`9nAgXg9NWUI;&0z9U8Q+?d=4#Dli2k_c`4x$3|*B_tB?QTNXm6;uPK2C%!ii{o5&x zDo6_GW}J9+u_bL^w)`*p-tWy+4=Xq}J+-0ked@F3x`{^YE`$=%MdrwnfUOo^zaF?; zeMw`b+xhc5MnQ$yGl1OOy7eH}3kaivkB4AYoQ_(4kGY5Od7|G+eV>`N{AS%#Gv$gI zr+`ElpJsTeEqhm_LXA$?r_>Q(J5?_7IXD+rJ=?hD=$akTmFKtGyMFNtuOFN30#%Z@ z`n5%OjI|o4^2aw9oU)y9`ODMmNgJ-a2K?e+@QSkJf=W+`o->_r#F#2eao*V1HK-Dn zS5G@JXCj%EN?KA!F{bX_&&S1Cq?bpq+ZW?)eQ%NuSH%uC<%H4*OKfLR#j8`M zC$KxKiiae!4{^#1H1BwkYPQ*DA35#0{%dQJUrkByRJ&^!Dz`ZpcVCt=ExbZ=@QcQ% z8q9k{{+FDRPw@1*jgrkCis!J&$Gi_Z2{&J}NQ#p3QExnGutG_?Vcx>e+i3W{wAE<- zmDLMGEQGUoae#>&(5?wwDh4Sr>FBvav_eeTQ2ZsNiN?ej@Za|K_7qWbWXL1gkeS|; zo-#krK$z_OMN%&UW85I$?v?vV*KHvu_lj-L%)HgpHf@s=&(u=T0=q&ti;Xfed!`j+ z&w|;h7MVxxr;xY$tIX7>RXjlWwNgUB>qW97q5QEjj**U-tAlO@NQ0S0$lXoT02^!2ZsjsaL*pqeaq~#ITv@>eb{o{_xi^ zY%xvDM^pHq2ace?UYgKheu!>U>#oLrWDxa4KzhqAHh!)Ium8o>hi>v{-n(}O?c1cJ zq~rzO=Va%8jZ{N)+C?Z~)s?|MYO=Clg`cUCuOAe_VCy*-8HVDt=Y3smR~w6baN(Vi+{;DXmKEAs zS`LYktLLVrapTguGK}$2Ph3z*m$G<5S$b}D-$!mmRbJJ$s$x+cUU1T6)v8r7n74DA zQfj#+AAyCTooGRG47%)L*(^9#e#OmQ&VGaVPOBGgw44cjU zpwPllfti7OYKf%V!_h>XkUhw5(&QT0h@asmBkMV_!*w$YS%5}|XU#j=qn$-DJOyI8 zsi;U0D;LEut#Kk}X%ZFNV(c%}%Bt&|)518e?Eo zf7TT0TeY{m-|^=9*5yp|ttWO;dQYijW^PpSd9}p)De3_WXs-9Lm*>?jkzXV5$r6UX zk8i?>xPx5vM#W`I9ae6gVZc<3U3kXnl;xNC@9$`vw|d>zm>fO_Z2YHD{-4j7SS_tJ zl8?~(Dk*dGM_ZFG?$0;!svN7Ic4 z!C6zd5#}W4^U40EVBm9cb*Qjj>+iH-#9*aFT-v^4U2?rNOkVBNyrVu8tf-;MGT3^0 zH(lDvfP2tb%}Zrq@YsE?@7Gd#owqciLu8+tYdlxt69PH+yc&+!S*WB1{Bkb14dE%C zAi2G@!^jbicmq?|p{Fqg#eU{DN|m0gS8TRkp9NL@d;LJQtm84qR!K+Agk+B4R3+Hy zI>L+N%e@>1_m&Qmx;S2(I?4bhf4X9t82o8^3_G@Lfk(%fB zp=ARuM+F&9jyfVcT=KTl!aP**hXa3#w9L%YS9}WHucj7L+U;Rdt2_=E-g+L)Z*6(J z$L=4{fWLpSeR}hS#EF7~?jL{kAPc9wll%voY(cl6kj6$tRiJtU+T053(cdP<#_o*V zE*e52%t5bPZZc#=|1B0c>fR{@PUlcVLJN$M4+|9Xd4n@*3F+eSA~>JvU!qMUrfhuP z!d&YdrK@~SrN*nrsL&oG)U1&|1P5fCa$jD~Iq{jm2AsNTZowMzYK;R2%v<#zE1raf zRbXw1@lUp>MP?D~e6=nYcvL20wmBPcmGy?E^8uSpe$g-jyiFH@7GGC}d^E1w75G>& zOoKk@-Q41;SN(~%)H#T!7ek0(GXoDa8c&|QdudPZtt+MM{mMmN{WU2OUT@K3t73FHKN= zCH5Fax_jdKZ8ggHbP)N`n?h|nMC%d9hdEvSdEvqD5Q1`L(xhpL(WH^Ac*8TGRQDEg zxAUDq%j?QG$24^V)4&jWU*k#bm~oqNY?Q^Ea45l3iTD7X{-$~xcu$)dm*j&-FQFCK zhzS_PZhsZSx%a!td2JWN*nM+`GZA29Bq$PSPH!8kGH1lQs1$8emU0R)OSAdbQUa_J+2a^%#RwS+`dtHNtd3Yt6=@*kOe1CJ~N#vBgcL zLDVnK-tU{aO*-iEm?WhO!$&i2d+B~O=qXa~N$@Dm%z((TL+U8mh~dBqwEE$z$s|s& zyq4f|rDtjI&31$pNnW$5FOhL2GxiC>@a20DJWn%OJ5~E#jaEIx<(UBpw@LfmGg+IB z*3C_erpe@tZ96kJ`kG0e3;g`sGRol>8)#knYZR|Sto?|>2*K@NllEx31hqwZM{hT9 zR=L{iEStND@WMbqUX}sDK~jZaP&tNUQTf(LeoBleGS>2?wg#U~ZgvcEC!+9zpAgPk z=74j+{xv@rfn$~uG4A;8AYu9@5oq{au2>f;ZynebdFkd!7ca-H*2+O(_nL}{%~rF4 z_kucsL(#0liqz9zK(D`9SBxHN3QGTPZps7^nV2cBfbPTESo&ieMPMKxCOPBTe3>ZvR% zAI9A{%^M+#Sj2k19i4B-eW(Wetx7jhcdgM>0)J5!i-d~Z}dw6u-qq%bH9=a_dF;S774Y(R47*Zg? zpf7D&)M*H4!XOu@WYe2n~I-x62l?%YW0{-@2@I(`^EPu8AVu~3)b{U zH(e45+<7djiwt>h+}tY~I~5W_DG}&|E?}HAsSN>^yB8V#GfqkFNYExjJEAT6C=PB+ zX(Vg@z{qI6@VsCR1wXdgYEG+>lBs=YYL_Q2k8$Ynp-xN>iytf<-` z(X@@VIr2fUbCjm6sh&E#41?$1WMk1~HbIi-54#7Iun_e!SRbtmWu}gk?spx7zBp;n zfUL}^JBwhfKrp0B`WRHz9y(s%FNgJ?DA9;ge;jNtKTQDufx-u{P9aD;mjs~TdQ2im zZEi$SS*}m?>-2tB*HW+Crq)CAg4|~T8`gD8Kp%8A(#05=uJ>7*B_7poYvP`2yz23H z``mXP^I>(aIuHse%WnDVd4BApN5^y@E809%dLAnzUOxNG(|TNwwxt%50RsKLYMELNVR!yFuB_= zoGKzav?7u87Z0rcBk*;1Kv#$fLJ$b^g-7AHYp(Kg{YV6RB}W|uG{TLCp$!l{XQJod zffq6H6}>*&tcO7rxXuc61b4)z+ww@8Um@drCJLNVdJyk45L_}>nWJm*B`|q3CHGs$ zTYyv*W^WrFHa~0T72)HlIJGf+&M*izlNjb|&_0!42OkxO+z_jlUU?jPmu}h56tnnfVA^{r-MIFuaCf|$< z9@sXh)o1_a-TG}~M6!4e#A?m8=t{N#fT@+X<#eYLlrq14?||rtpEyFZ$oDP37f>TIuuOB zWU6vB=2`Oz*AJstktswbk&qpzjs?gwDk{nai$V+<8>Bj4+jsbMKqB~!Mqzodk*!SM z&_Fjg)_n?KTdClTKMfWEr+FGkcZ%qpt9BFu9;QU7*uGP@P)%s?PGZGseSW>P`k9A# z056Ej7cs;FyfkBPRqT)#7O?@_A~j805mHlRs^;lj?zE_fuE5?92JuBvMt@*C5OkX8 zK%{&T;6Yt2$T`0Wh{)558jb|ho09?5vbZ-v5E?45i`NH{97_`c#ZQPyWTq$YW__fywEE2O zd~>fPQrrd#FlT{T^sC?|xd>N~Kd%^^p@RWpBAzFU%=Hr)jjPl9w4=#r#9g3VIxu!} z_Rz&V@Uc#}QAKyzDD<;&t*fu_^WL6fBjP@#8774CfrIml{LDHgKZA*j;2}p$@b)(Z zT~l~KSV#seoRhywi51R!g|FA0uY0)tA`~KIfTMvhbXg&p8zvhq4m5#c;Vr^S+{`Kp z29O)GXU+bVu82Xb-c}9+GZ04F-7rbpD%}{+!a;8<D#7Y9uW^J&X^$)IcZcxEneG z=IH1)1a)h82|3pkk3!qb?lI#fOkQC1Hl)M}NvkAI=@= zKk%x!ssLmx4~2mfF>uLn>@CN9dSVbK04U&-$GM`BCQ)|wvvenN<({H0)5+6FTI2(Q zv}x%ijLiO%m8c0j<*v$eX zZfWX3LVW}TN7aC9*gY787YxX^#8vS^CWo6-8fh&*hTp&cNQm&INlzD> z-J9!l7=7d-qb23Mp|8THL6x?a=TtL)_|(-@INQWUf*B4kV5}0Nk=ZS;GZ#_X zT=g~QqARnVelhv}Z}-R=pX5bKJFdz95;%bZ7*_F()dYK7-Hv+Mvhp6#&QVZbmG^n& zFAuu6I%jolOy$e<3T>GYx{kO!ywqGmOv81(bW=%}dnn_HP~JB4UFJ)FHCm_nxcVbw z96jO>+9PR#x1mh%gNgF_2^-boj1GOOk5xLWc@hMp?(Q8-HhL%Q*`gmfT`&t(o-gw-^;~;CA6|ut=-`prkkc;o7>V&eWhLCv%RL zS0h*DXL910?0gwVBAP08#7zhye-wPz_|D>A#q#yxKM3FmpG`EDn|%vM9ya<5{>qAr zi<^vV3Qn^hgA<{IOXYw#UG(tC&A?4QlUoZTC7 z!P%ZKs5@OSq}BpS#QMPr6oUGF$?EbEaY78Xt24MOOvuM6u^_)1jW0wpM4e<|=b(2{ zm$!aN1DIGDdGBD>b0}afD`#p%=9_eLcrG(%Ls0rzl-cX4bw&T}zN*2*Wf=U6}4Mm8+ zzSyb$axp;ByJ+GT9brqpC=NdxH&H&IonZz*QDeXqg28W|M(Bfc9Lip0sCo9-YaX4% zIKq&`8_c{~Sp^#X-QD$ArElCq(4-4%P5*uXh^B}53{^)%xSsF6_K`Ur# zEe`>)CM|o2(nASn%cF(bk*ImvjtgL8QM|cdVDoeo^0H#KkM^MREC@8r1`9y zt_N;PfWe7gN$03d4$$@CC0;pOnqy`!hqw^40zW96rtqh6;^`K|aHQn+1f}RWX&$vN zqjIhnKh8&DsFARl9*u5|`Gdwd?eX+ z^y$&B`vhY-=trhN?K5=t!@XX8Mr*3;~zc*gdybbg9nd-vF#G>M&pZE5Zga-Lk zpsTT(cZj!&CQ3Xlx;EvOva+O-U5&M8&;4-0LO6EUC$0(G)r6!NV%X+4B>Iadcy_{` zd7J(1wxOZK-4ZL*_gnp!i4DkKET#SdL7 zn-^?KpYRH#kzcw{9;Z|wz%nu(ypL%y+GKWaS!l>g6%mrTG^wQrD>>UE@XupFp&qkweNy zS-$AERUudEu_cg^4b!{3H>(_dR^_buniG#IJ)8_GL_DH2=Ib3=6K}T-dQb@67xcs|%=O2!kXxQ)6Ww^39nfrK(~3%5Wo0c#=mPH?N^u2_F-t((u$mC6_9ZwSktInVAytnPlcL*X%cI zU&A{s*>otW*iYBmQq&df2$iy7zmgPx$BYR8a82LvPZQ${E`!9a-rnAq0oR8v;MLNXvko#Hgx{Eld}Tfxrfu+ zAT}-(WLx8WeP0H1VAQw*8?*+peD!lAU*-oV`kTo~UzLMU-(d(|NNSj0v&mDjwjc3&kjFOh z?0Ct1*|~Y+#@&&#@t1OUMQ(4rC`jd4^{R$K1Xn6KVwL9kqhnWR9L zCk!>E)u`7)3@*Q|6&u>yW*CCwXliN-rM z5C|#Hqjx8_Zdlrr1v0a?S9i-Blv3M|53BF)eY$z;+OygkXLg7zZ}@!M3)2M#q5aV3 z^y!cg&LC{pAFcw#>odP!USo#48=&gb<$FI*x>u* zdxxK>53OdDZR|3qP0_Qu@EE5k!X8m%;aG7R`jwhxx&q9 z>z16-uvTmwoGo3Y%lWyL5@DZWo748UrcL2Bf5R!aRvbuZxIUuK zD{!9c_E3{N<*ppz^J||!SH-GGXIQ9imB&G9&U~88BiX^z`aG^v;>474v`X39s(^Ql z{KiXUet>kJtl#!9ZUAyMbX=gS>_*tAIj zZ^cFx#Z@|PU40&rvtOMOG>Uiq;tGemCG|Nf1hVUUWHFSdS^)`(a@6(GTgw*Q-;eCy&f&;RuQYFm+&_zQsR|F2Tqg*w!0@hhPK3j@_n`}gnH?RG0% z+%JhMUU#9``7I`Ssddtd<&3C>`oJd#!;e4nKSy%p+$7I$qr~g#EkjcljOoFDSMz-O z4+Yjxf~1-tq%-2<;!Y+RrDxRE)R>lC?wFSX2?=|}p`oD<&>Ub=8%#!&`aybR>F_-5 z`ICb=mW1rG?y+5$7VhEGo3Ik>>>Z_NjXo0GRcGJKrWGvwZsCUwiIb>QEOD_lA2 z=9VRJDTZcM5|W4h|MRV_6`BV zlNT;>Ev&Yy%l?OJs{8gm1VT#-q`L5k%+G{>mHoY^7jg}!qoAA!YROHYq!2+7Q6eJ) zgGZDqM3g?-ai5zChD^L)oy@#S;>a8o~kVPU(yr6QIHsX_qIa>YUqg~YWL zKZd;9Cw}7cmOIw9wtyvjb6oN9fdQ}?E!!z2Og}%-f^*8LS3BY zGv%a>MoIwB7udYxQB+%VRQB(0(f@rpt~^9m7NdbAHe3(Iv_3rO=F zzDD0-t+LIvFUj{m>;S88?5}iwvD;?;kN*nfQ-#vS!1SO3NRG@-x4=z8op$vz>&)g8 zIhG2AoulA|KZ-Zhuuaqw>LyJ}V?Ll;PvT7E|LTQ9U|;a-ACZ_{ot$qz#@m08cp8BwAXqrZAl>if6XPNx?)S>m-F%*YDsu3KU~ z8YO)fZJ!(;zkA0cCCh9nxy@1U`6CjEA7CO*FAgo zY{yfdQ-5_w|8%dVlYqx;-*A(q+^BoTk=LW5p<&aOXYhS%7}-@ScR~M4Sp5R0Lv*>& z_Dcn}i;RyiL{cEz&E?;>?g`mhl9d!Dpin$5L@T4-XZ|<4^ZUMCIq39@Ve&a2?-x`U zEmDu#q4l%1<=ws60Lv~s+_j43`EEsX500uR6H&{GY@sY=1*tFPwC`Dit&a5HCrRCor z-`}tI*)mD9_k3`$=As6G1LT*Dj>ZC2uXwpp@+~y2uZ$;Gq!W)dCxrO z$G6tI*1LZsJ7w>E-`9QJS1%bEhSp>M@vQCS$;nR^2IhQ!GE?|xbN#dsT&2glRm7rz z=;f9~AUE~j?!3>xe7=-RN@sUt*FL)!`+wLdpV9J*E6pGOeJVzeo}aV4K$IkqB>iu9 z-sfMwx}oKsQp;k~sm{Frber*KTTo8Xfc%l_^8b0;0}uablm?!Duk~&$5cpaP@axkh zZvSXwerBayx6h{ngf|JI3%H;S0Y>Ka5Ao-VX~*1n`=clz4xV|QDND2PW0%V%^Z%z9 z;CV)y%XH`FDkJ@zNG6aS{J+?BPb*sN2euf`9){IxM0Umer;8UThXAb2;Eiy=9XHj# zu+g*pK;U3Puky)%G!>iih=_=fVc!638X16XI;3e$@w?mMyRM+TJYwkzpx!M30z*=2 zx8uL$`v1u`#pUXKSrg5(UP=P66-3RJHSMx7fI^@yv|nBed}UcY^&vNS((NB%&%(fN zH=j?35~K$(wEg+jSfXXcEX0W zSgv6e2Q%oNW0=ng#>nF=%=7WZVZVNR&j)9IHmy6nmN1_?L!(<3GpA|SQ!6U*(|t3!io|J&Z_KeC!2L#EJOl$2F1A8I z#BzU&fXl|fbv7<+&9CnC`fk6CdtH$K!PW)*snNmF(LXB#saJqgWe4ZSt03749;oshI|G}(Im*5SY{XHfb zZcbUt-I@Z3Fq<89u%aOAiVFKCpiRu*WR*lw{{V++aH{%M!E{6G`fa3wT-|kEbV$M2 z`t+{o)%Z1?OSi7ZK_u;EaKl>!@;J+Ybd3tSxuM1a~3y_3>{Ka)+O#q|BZE z>#s^3K>YeHv%MG7ZC#aI+s--N(qf_;87qas-IW?5XaB$@qe>$rZ%A-1c(#^@Q|o7T z=(crZS9h=XEK5Nm)hC1g7KC5p-k*=V{f7Xct7AWEs$zh~_aVp6^Ze{?jDe6^>OhN$ z{UnwQx9Vna3<|NOhS~94@5%=YcU&7&#-7$DQW%9$*sEky8Flvf4#=)K`GZ*o6a_@z zAIYft7%Q>+v_@^9N)&U}-+11a>GwWJUNS{wRh_GP;-cX;(N%~O{rKl1p@_r=u}iSX z10S@^cXt0nJl*bHJ>!9B2nV2xQoITwOkFPdW_CX+t@~+&BCA@pZyTgNhYMR*Ykp4OvwX;4@GfE3R6~QLyoLFe{^fRLA_}F5& zsxL^xc;#mrj6wB~LJ}GgA^U;P%Se4T>;ZRa)TYc1X`OAqE}1(*gMZWSb|yA04GDjX zrESdY1R`Qjag|&zW}x~e$)vRSfLkm>8#LxaIf!?5lbXzr{ zYt)MZHCKfc)d_k>j$jor8VVyPG>W2TcSc4#nB#+XbeAl) z!E+`GQ6jq3u-@6RqKvTh=7LwQW^he9bs>k6nQ1_oN74~_%w<8z`N_$rNz%{^?-~wO zkvDhGzHNMZ%5p9_d3a|_elYqL%O0p6n6+L{k3)K;l{F+Juz0tK0r>+lvg>qsYqaS& zCYNI&s8~73ggZ`FWWc=hiW)XSN1QpdwO2uUAz@gy1_T`%CPfPMx3}1s;`W&fCo{{T zVb-ESfweGHMIXP|gse`xK*2C++LvOJJy%kbWiE;8J%$zzi>|w(1PvRuV)VNFQj5cvd?hKfK#@RCpy4Dt(oY4ux?>Z- zx();zw=tO)8w3Rv82M1jr3$a90GEwAf47`u%XX6MR{1U?dH3x~!?$0kM_izAF!UGL zr9Cgjj7Kx#e95} zJ)!4tZ{E7W8=Cu1BCCeDZ)xiZX+A8_eP^+wj(6wbRUEi`8szTs(ywzG;D^gwWtZWU zrOVfES<<3vt4<^#5RMRnr1Uvw%Mm_Z62cpqBtPQheQ^8M6EdY0K7fJT8SJ4 zLMi&yG@dT`pCouMc-Hhxo|lz)gZhGs*fNfzQ}A5l{qTg5;`D~ZLQ8GZLnRIaTpi5bxK+s9QyT2B@Cr*Rnz*9q z;g(-k#@?sjP48T!fuE&Zo12Yi>p0CoIGa^@oqi?tjxUOE#qL161NL@W<*UK_4_JP& zB1=gN?Tp~XezvkpFDjTRd~$kQGt}jbfx$*q(8_hEusRkH_UmX_Thx%9rcgB)VX&mQ zs0uY$H>kUi0W1#Ds#@a%?}PpLsTk{rb?`jgbmL%{bGmZ={vO@$<{!sqD6fkrb#!T0 z4=`>%>@(4To@ZW=fA!;cLvAusq@_*3oUY|UnM)ZC$aZk(V z#3^x6%49R)6%@+(*`5Q0d7T^TOyr)^@IitBQ#QQCA$0b-A~5FWMnk^Kw<7nWI={Je z@+87IV@*+&ueq6a98uoWE|e*!Fs?Z>aw0^&36&%@hZ?-=+f_gRb_3Yaa4|A@F*{*?9_V;N&U6osp3OjovYyntsWx*?`UMk!?2wSL>? z14{#?O2Kw#{`Il*u{t&S_F4Lf?iC&IxPXI{)rOz~3ECPm*#^ zYFASq)-yI{xw?6mr}i57Q|cX!yWp#Il{FZASE| z)ll2V0UDagu|k@aQBmPIT(N6@n#a88=u9`ez)E<^ktJ2+o={4B}ph2XG0NLeU7dq2X3cSGH_yd`>}^gAOd;JP`k%Sa@dX$9WFT5c`KjzCPwycZo4RT-&O73EiQ6N z{tIg=#CeQ%O`8rXj`q=14e5+CEZ%HdJ$%7$$?p=>+>z2VcH+9UklLv7c`nypErQKx z@d+;1VH#Pvv>`2Qdyu_w_~z#NAPZ@MerXZw1;mSu`M&#=bIH*W$Y?8OtSR0cB9lEf z{R+bJ>pO6s4k;Nwe(+H3o!VjX?6R8wa!56`a*V%pYBV|&;ueHCX(dV(a#(rX63+Mt z;T82)PRGD$1W;G1Nt1CmqdilT+NLBbx}Y91Gth6(5|d0)94vQW9YkA-A3S(*VET`M zfr_4q6v5(tw;acfmEOVYElG9A@TE+Dhy>oXhkBKK6i@ZNIbMaTSb^31t$JGllxZNB zB_>;cF8Pq~B7JyWUlGd=h9hY-J@U>WfSZh(H+WQmHiLp|ll`d~lJjL{I>DP`W2@Nd zwNN2-p%Ij8Zht&G*k>)Kw`a2*MsC~O30jsNtX8vRO>FQlH;dVv%g53mw>%Sp0IAhF zK>B*ayG6J3w6F#P{q=!3xSBB#0i}w>7*^~on!{m5t2OEH^F{eJgqE7#{06U92+uC$ ztoMJdy>dJL!c`a_ObExJ9ty>F6o6AR=0!OrHa>GSQ6PGAd!u;$HLuCHr4fTcgGj6W zf*~_=W9vITVV->(INp3gk6Gy1CKQkokQ}+6u1qu|FdF14oWQxm^NF^4{gISnz7Vm! zp4hSa_iSiYh}d_U4m4$1HBB>(xZA}TAP?+Nt~-941>_JW`Y$ia25fm&@kCqJ@2KUy z9KH)|_ay0se2ar|QbN?B9lr|uD;)C^^3H*GUc#smf_R5}cr=bDccDa3V%|}*r}$oG zg7y{vSjb6ag4UClzXcA*$8e!(GhD|6?lc1;5o3iH_K4gREH@>E zUC|NsG*)OXsjJ8myTYU(bW~iiL@gjlt%+i&zuxKYuZr#b7o{{l##~kux0AVNU#*jM zm|M|#&Ma=pU#+J%@NG|?ubbWEopcXKDk6LhbI0POw0b?uqe>B;v5o5Oz7;Eptd3h6 zX#pA~~Guv}KzqH*P@qdCDr5vtVYL z=ohlJs8xF6y`zW!Bm-3MnZtuq@hwd|b7p%Z^;WSj8PSf5%E=khO@5&CbZ#yT2ze7@ zX>#anxe^~7K5`IG6%n7m=xXWA+|2UT5K0%NqF_PKVc_DzBq`^lEF;maM)U2)eN1O- zxwZB(=5UzSjqi?6lMmpm@e-F%m2QH%X;tf-j=qQeEhmp({+OGE@lpe8Nuvn~*!4Hf+z)OPr*V&Yt+CXfdek~s198J1K!^Cc ztGwH4sj1d4I6J+ux&38fvOtM|HPO(+znJHHw=Xq2sH?%|-6zgzmRMD8_V)Jx#pq*& zS!+L0Bui?HgW6TE3=W&oamNKge@Y);nB>^-P4=Fi@&z>>wO+l%x|fBuDvAOJV=G)&+ zwSM=bvXgI*jWXsOeS*0hS|vc3y%!dKh@-hRN(xcTWFmb$_S_1s&WflZsOyl(-Ec=a*9j_<9q&o8dEl&e{>DK; zMQ{kILc~X`H}myt-D;})0}8>hH$!K%5*^=m@?^3sV{fE{ZC8>dEeuyu!LjU}H9xJ6 zn~fk~H^|tXZN=n)z@UN($21V+Es03jzuo{F!dpCu-@i!2b5>!>38 z_v{%vNJx3b%A0d-=tdnwuEWDS(TYR6p!eikLlu4r-#^dI%?{k&l~KPwN=xRy{PLZF z={4~101g%~o*UjlNz|>*J9sd>)X!BKaYaXBQY_57$b2)(=q-qruW?ayo{1ty!q6Of&I^V8S(ut zKzRtAp1SV7>!(At(c9B{n6md<0VH*E44k66ueTOlOzfghPJ;8zt!E!PWmp=J9V>i# z$mvQWhvX1Nd!(f^Lb25>0F+0mBtOpe>Ys#_`hW&gcNnUwgNG_AEYuWC4}L%(CDRG! z2-u1UGtPd*dB;1`{Q5z+d~E11(754Y!)GZS<1b7LA4Wxa8VCr@PgAdGDhT*5b+$co z$^aYS6;x7QQMqOB1ffey6=Z?1=9sP+rP%lOodW~o6M~s9&M?xEMp!Rfrt8HJFSI{9 z=;zqTrDabLu6U#=2#v=wX0)nm##>ZxWEgk(ETJ{3cI7h9Y2%M>o)2pgxOS`jgn5m( zZT>=*#uY4hjxTH8q`3!)g)q!z_@0b4z%SY;3fwj6vHU~4L{l!|)_rFMoJWJJnK}?l zdrR{;zE5)9w^)~Z+&2cxbI7zQsTd0OOS6=g{Pt1{imkswq1~Wz0IRUHeBc^2 zq_$i6fCKu;`WxD*ML?^YEQg4-POEdf4lT21!xH$RdXjk{zTY2yq>KC8rg;jK5gQPBGf0ylRI@s zk`Ou$-JAF-T=RfmAly6koJn!NUv44W@o5z%w)U!53Dj?N=gNDaRVVviJC=o3j4gy94XfP@Gd(~x$KuA^knl9TM`3=A zaJLwaIG=&1k&9Ob^a`ETl=^tuV;xjul*4c~ds;VR^sa^Yp(fu+4wIjdSNSYy#ir=4V)6BL|{lMdqek z%d)Y7F2<~j?tV4G8WRU(>z@(Gfem0-eZUSc%=0YIA;+LH@tOcy{T1fs#X&Rqgo%ab z$a2i1g*JC@d?h^$v3&apvx|U%ZKe!+&i-22J!EomaU!u;5g?L^go*vQXvaEGGG#oF zvleu0cUg!$UsDWds`ocVmIc+FsancqrtN+vnJ4*E0Q7TxtV&(vqcdg{lbUv{O))uO zD&Kn4(%_uJO)-9fPM0?iX|&GNB{8wWEaLUW_bz4S6XMGOQW1%uisXmR>I;3J3Vw1PK=2A@W22?2rJx8WrLfth7Q}V&Gd_SsYt75iwQL{JQ z>UOpU(+X`>tOdU>wadyke#N5{EbfqHjvz=L|hM8eDrbK@yddQW= zs*u(<%b3E$3cl2}t;lX6ZvA$g3Sj87G}nBu{B@3CTcIs}WYJ6~;);Z8 zC2B-s($cIZLgqYiA-mnuSxs(GMgw(A($?iA&h{l``(TzXN?iZ}mO&@jNWZ0TPevUn zKH&jrtH(v>PjtpsV61=0H$wN;bvJ2Qi`7+@9UMNVkr5iUcvspv#!>)PW3IkiY5lneEbY@ZSpIQ=3+>r4S=bi9N#9$|Up3V3f z;^3z8KygA5$pbmPb|>2og7h>HhZqHwsN(`HYLfQe+yz_7-LLU>VcsqLqQvlzd*`t( zr+xI$Czh@4!>`JW%yeTRoIuh(9W9@WuD|z&IsPJ~SwCPi;F^>5T6c@c8<*pieZ!)H zg??$-0XBQwsT~S4EIT(0@PowU&em+Z8~HYM!E|(3Yz(SROOarwSa!@(>RY~xX=Pld zsOtVg)aH~W)_W}a5ju5D($c~sGG&k=d(SU8PdJru;&RoZ`$K7~@&#+~^26L|sb2f@ zrD7t~X*O9KGt&6$>7j+O)%;B4;E)845J;E9;*BN_5@n_e_4 z51FvEQC(?If3x-+bBb7Jmp0;BrJPo6kdchsJl+oVr~4h`vwhr(>ioX7)5m?_NHiwO zr=rPh7q~@LF1v4EANTxxm*C-Fl5WpiFHD2I#Ced0`dTRjADc8y+4sP2UtFyHMK8m#;z&efu&{G;1TmGQDfoT$a?{CSmJPlMIq9L=qWhT4mjhw=WLW=2trC zsk=Ad_4Hf{HJ5gW@H6}0Tt(NR*gR?vIzk`0^P?@1=jyXy5DD8qLZF2dU8L??mSLG; z26OVUkBEQ#G(NmnKR)@9ydDk)Gv+<~V+ExtL*qQmOUc-HsKHcr#{M z%mSTav%WL@8U^5KziTqdpbW^t_Bix_l7bOYr);ImJplZx_Ni*!Ty0wU5O4AO-fTkH zkBC?kUF`~qET9_Fl!h16{z?d*gKP+W{)n_j%zEB8N(kV6D6Bevf8#Kf)}&PzsHt|- z#<+UU&Ca%JdfLq}O8Iw?Y>2uStJ>zMkAvsR_}RU~9!@pFt(DeGxq+h^Xv-G#otwqJ zs`@)}al7*C9}rVBGaQDV`8USLe<=9gEHH_#HZA0%ZFv?xq9he&jlCTa)MdZeR#_S9 z4iTK=E>ZLvec=a}lwbp;C#9`lnid{8B z;avASzjvSH+=697j-R<@_f&9k!rOu+JBy%_;?(QAqYg}9D1MNKc30r@Q6%|&>E}-$ z&&X*F3ls1IrV;8H(S7xWI{4RI{;Se);QB7?Etf(m^p)F^JihQfcD6PAmfdbxQ^|+JF#Mg3U}-Mv zr%H=FaqDdv!m7ay9>d4>duqF$S-YK&Yz1)6P%K6eZFub3OwU=v{Ap#h8twy*rx|?n zF&=&Q(eI*-W%>?t2MrZk+=|OhblFe%R+JWJTD5Y;a{SUaQtwW*W;x#eLy`E@zIp(S zACuJOw)La5yW}3(D>(KqrA&$7U4tP|yGG!zd3^D9TX^`(c{cLp-7Gljg|<8h1UDo0 z2_WBdDyj(u4;>|$9xK(=7Tc*Sz?2#<=8w&{F8S|A8uBa7FI_Lb11+z)aD+0rn!X#j z!DaT-SBP*=vZ>~PZ%eN$y6E|E->-FN7t3DVJSbU6cxl#=Cs~MfKic^1J4=&{g@GwE zf~DDmOU37&y^X(tmWO6oaOs`@0Ev=Q!(WX0Zu-h%JYVXr)7Io{DHo?XP>u2hM(RJR>En~XMdx3ED^Ux2# zPt^Z!z@NAweXBIOVSoSJov!&|!(%Q*d0rJ32jyb0kOXt<}Tsqi8-+lA$ zz{v8$J{Jcsv8d!Utiyv`(taUP=ZIkG!dN~^r*3Xio7W-fUSzcGE_!d0qV}i;ETZ%ZuBJdlWGD&l3-?1?Az3G6`CFY8Z1O<*FBw9 zIt6>yn|!|H8D{tS)dx(zM3leAT6FTOmHz8nbF+=V&OW?(CcZF{n3LQs0wDwh%%2b` zSf6^`rd#gKkE(px5j;kZQp6|rxdhM?F-c}2UQW3IZw%Gew)YzA z6y|%a8qI#kRefrj@lwq%G4JJ_5?yejTFFC8G}zKqy}e!nr3(5J1r5JO!IuH`-~P;4 z4ZaI%EgsM^M}sE{kXXPkk-g2wmAq{2GnDdu(W(-g7Oaixseckc)+UG2*+g*z^-+?#(@KrV{=TXE0?jtxf|iUAVF zL&u8a<4gYA(Nl`4LoVp+DBPv&{{6!*RV=O57}}a0vfJ0f`i)j&!k$3Z6Ly|wz6Y^R zHOz{A@zY-+vAg5AXYJtNkn1xON!!;A0)Yla)f#@>vuBU3r)MAUbD!V-`?Y^}TU4Q$ z)YUJjg{N{+Nl8f%C-qx%nqYErQqlkvQh$tQl|tstY6qpq{OzFr+l~GFzS=X@);&`9 zZpk)SfWe0Ft(}`KqUOC-8<%F&5&!IVU$~|kYfRRD=FChhN-Upb|E&7-AAoFkbi45S z>%e5Z;xerx)Jti?GGa9EiO_$D|IbIk$oal>iZ?Sr1?gGS5-Ketv-ii-7S&j|7*7I5EKYUj${ zc5eUO@BVj}TNapXuNrg!+dm6P?EPQe;{@vm8j!rczOP?4xf&G~Rv~8w`p?m6?Hc#( zR;X@$y5>0%`ZPYd<39&wx)IHIiWb=>+s>N>DPeiK$N$G@8L0k2JzzYTo}OL@vdd*W zt|Uf_YEUr$3`bFgRsdQ4VttaE=jZ2B=_v7ge1NP``s&qsYGQ9L7!?Ts>^h(zq{sa; zZ1dZ=`6chGww8IpWh%q|Ie6laF}DcQ!doy&pPk>z;1&Y}Inaw; z@fK)jxn&Tawjp%XCpfXprs4OKIil)2vkA^>4W-Axgepx0*^fnsPs{Qx96ZP~d-CIE z;WAVDtmnuyc6RFC;9BULJlU~uSHMVC25{aoVRx#{a$Y3D6y)U0F!1SNmNq7IA?dkN z@6h|UsWnD;_^bVJm$mi0Qd_rE zhyXVd|8o7pW*@Y|XU!H}liJp+&bb-L7-l(R{JLg5SBK{0MUFkvjHV^Y$KvSo><6uz zaheSM!%$M~MJZWS4sCtiX3TI69tD~EuYSwNQrPbywM~(<;4dXJf zZR{MZXvj{1dTMX737r|2j-^e*(v*Wqcfq|$hM7O z^_uoE0}&Aco=Y8)K#NQ60HT+b0I$5jWGsF&W8)cj47Y8VZJClz20S4_uz6w!CSdd! zy5B5q^a?o04=9RwFMWB(z^n&Zjl_wD?K07WiT(YH2Dvw3;DX_%#0x)4NlWLW&SuzM%&>ZtZ}vm>$&>dNuB4MxJD!2M zdu7j%`?Lhip0vF1TYGL=7-7I@2}tSgmVM|LfH82$fAY3>kL{gPf}p9@YGTU5Wv|EG z?L;MNNl{U~BUVWx4q*cc3Y{O)H@D~>x4ZpEe5I3#(Xum)*TIYDZdC;(WjZm@bA2|- zZtP%PCCF<-AoLjmNAz&o)7GR#4U*bSGcXqXsHMApro%-sn%i$dO#vcdY6vq^(*ek% z29p4Sm+NS~yPg0Xho{;ke`{WL_j*_luuESgHfmI2Tr%?8FZ@CwudKKv z`OORbxFuV*x{q@IQsmEFE~Ff+23wVbNF{}m(|C{4Tq?|z@`_;6b^ac_nhdgLdRun( zNs83Hi&dq^9P3)Mz=VL(Hw^}9dC~v6&64Ruf!oC;3e9izN9cR^?TubQ zRJsw5x=eN^@i)xRXghhxyaL0{Bk%2%kIOJ&4&`-q|v1UorrKcMD)(KGQxNr0PU z6mLk~9k_c(Gl`#DMEss#Xw>(mt4*@`3GCzTm=~rJPk|ah+koRPNLjKiDK?+*i=WhS z*_dz5JCrk)V}<8}mx$GZ+*TV0ZcB$VJhF;b>+ODPS}5ik=`fblK3`E*)?aFS$@Hmg zEcU={ue?!+B>@2P@77>>g>keGK6OJPw<#7EZT?nXmdiibQAS8T3Gtwe`bi01v8?Al z`f=NSdjE3&LZ1UNO{uesJ+0of7#WZztXdgfoR&Wbcmkui%u@a9fB*+W0ib@gl-hQS zu`_Ial;)`vlqm?5a+ne}PS~ZR>G=c~F;1qtrktuEQ0HK9%XgJxZ={9BD-&z7 zxwQB11FNU=1P80V+Z1@!S1+5JTkDgRMkrkYXY99okoczD@dnQA(JGFoKtL_$a&z;g z$@-Ax1GriW1a?{qRg^=Un1GqjwSioq-VJ;A?Hdeq^F77GBj1!8yd0j~+@zJ%EM|l} z0Pq)?%{srXJb(Z!l9c$`M@RSG$R~(<`vwO~glg->bWJwCZf;c=3rriU^s7APEYDi%l{}dewGxVF2X48)HVe^VmgZ7M1K<5BhP_r{YD&OBU~oSU0l%J~(w(z&^W-3i47V5NBixa}^Q zr8yrip6$rb_`%2*Pzton;p=m~`Cd|L7j8*#0X^DC{@tL)V4Nzz6hamV&O-RR{tA-! z_+k)lq{`FQb1E@0SrwS{HlSb1O>>}`R42blVOA>WaFn+Hc(GktE6^b1dO>oM-$B-U zqxypHOH;c|S39GF)EVm)lY^N|vOLj;d~mYT%EOTC;_m)SIcaN26KL|4sS6nW%nFB# zRyugYICMn9D45u@Z!lU8T*-sgmlSfV1j6Drjp+c zJSQBom2!?K{c}Kb$&#(hy8&)Jjg>z8$!U+WWCkOAoo{Kp27C6YoVCPGKn-?#{=Vl* zU%Y&*a%x<56{%J+$RVia+2dv-HHKSRw{AgouX+IK`08Mcc6r7U|FUzgeQ+g8xT880 zCtMY=&_TWyqRwgRa)!0LhcpWl>KojPJ^doaNG>ZM1fJQnFc7hq1-$R}c2ZJ=A26S4BIJ=vaX9ndhwN7Mn42 zhMv@*Mvxr4*QHR+XK0J`gwAjyzK@#38|w$0xew6~pGd{-$vsJnPgY7y)ZWOw&07%% zovjN@npRdCgQ|csOa}q(=R9$DD7rVT+i}%}kLu*;7}8~l?In9@osMxuTfV@Rhw_}J zT$mt0%ZPk-4u0rIyrRndd*{dELSLyO`>ug+6k8q~w%iQ8`{2O?+qMYtF)_u6ZoVr}_-!Ju|JiTNUZ8=>RP zB2*qb=9aVMrLg2bC(`@&s266_w2IRz|HcPU%#YHQ1W4yhTY^;6#WU>dsfmfh&*R!P z0O2Re4m<2f1!t%Xt0o5zKv&P7%z!G(CMTN#Ubs$LS%3ct5BVoc3($90N~W+>B1iYa zhzU^As=DHdP#r-yTg8=n<5A7;nYeY|GRy_}qeT6(1}PawnsqFb)6 zl?7+0Yddjdy)ce_J<6YXb;++S9^DS*_mWf&V}NJykT+o^-%op~#r6Um)7d(M1U3r7 z6k=a1bj?gU(yiy`V8V!49x)%cq>4+;P>*FT&6e}dwqD{0a-eUC(~H6z49itln7UUO zDuD8^tStT<*16o=G%NxmB0rCqqVjvCrW$3C|H3Bo&wA-Q12jF4FxkNN(M$t&VaL$> z%he`6KHQV9uZYMJIfHPTq&DpRY}xbuMpEnXAjW8Y=&qpQDnPN3A>tt};Xr9yKfyHx>Nvrt*FOy7!1 zu=SV0<3RO0Vv{i)l9txiJg8+ne8k=VG_!|WaAzu$GdP)-LwIh^hBW@dpHthjE+&A{s+sS4Ap5w~=_d)*Hqk zJv<^-0kop1Uw66j>>aU=st@Teu9`Tiu~pA(ZVg9d=kvmYilrrPa$L zJ>s$#{4b1AIm}FUZ!0B}Gi4SXc>DGrXARdgn56hk#B8M%^pNOwV@OXe>6u&&gwstj zDhYxJXae-+8b>vwt&Dd@yLalmLeha3tVGUCFNn5}L|?AhY>IzV?K}M^!=MnY|9WlWo7Gp2Qd^v*7%ZaaVWEC3d-8FsB#uozS+_Y^uNji z`sF!W6Xf}b`f=(s{lLj-vq7cJNx|Bsa@Y3F(gKsk94Y=wom4$3{mN0{I=e8;mUoiu z$&OGG+TKbj^HOBo8G9WlQ!N$`O@9+D5eq$b5ck0RcOZRT20;z#64ri==^ixJu5ZW~ zb!3dL>2Pa`s0W{zOWrrQ#irKE24STUVhJ^&^q!?}N^V8Q2}x&UooQ2iSVasqD|1^* zQv){~E^B-jMaJ5tFfQuQ8`g^Flzf2lj*}mFf;5KgPCwdJk~3AlVB3qR(<Q@B!!-tY%pLz7>U%&9*y^~N-R1}RB){JihAmqE1 z24{+bx?Ir2fCmJ>_9a_D@^8BmE5Z$^C(als>GhuiQg)pBad6;VqI^c`#4+{=P;7Qm zmqzE%8lzWh&tgr2Bnt3WG|O0mZ54HK6`x zoER!Iw7W)B)9bcMVnf(@G- z$*DAt3BLIaZqDIn3HgSR@SWbU+(1$MT`zzVLF@dWf9fDxm#7CdSIek+WZmjOK;7es z(_owMiz=DJ>VwwuR+=@p;-^?|-mC=C`FzgTKQFdYj1+`UAlqp5MI}W?7u_Q} z)Z7^$$xdAng{zFU>kAm^KaPy=UsQ>Vh-ixFcVhyY`-&Z1-jr@!4)&z$k8?Ot>%BR=3&e^UP(kO+76 zl*(fwBI1>Bc6f5k7KGK=AUV}Q!?E!zWd$8}%=`DjOq)kNbAwqG)z8|xGFjH7&E2?pMH0cof!vG8`Lq0=)nO-CRn%KI#;+lS#XKLCih1v+cEwYE@+Bc9f`8 zWy*xo;ce-RuBn>}04aRCHks8xzbw!$bT*ELf1;d2L?*yb9bX7=>z#Q@yF(Nf6%FYQ zOMVg>HtkB1A##Xt#!#w*S8UuAx?SPXaxHmeg(VsU7ihO0JEy?kGZVmBk#qLA+^bI4 zT3z%}L*SPTy#SC^ZzQEfSHmE7kj~7DGA*memDyeE3Xz)3S|fEyda>0_{cw zj9!!`Crx_dVsHZGar2c}KK$d@&6##lP8QXO=v0HD&k#CxO2w^Tnk7)`!$Jq0j2T(nRe1y-wirY!_r zrYhUIwhd)Z0Y<`P<{bXcL1YGlk-Mjcc(L%g$6 z%)W8Pqh5nK5i?2Gq@~zdD3kINoRF&|tG}pji5S~e{4)jqc=m5B;-4M*n5YcccFjrv zr(e^EteYzkv3DO3^3QBwvOVcGRry|p!w0%eRT24lc}+&F7GBT-!Fvs%4cpZP?%#I< z!nAuIw&qUDv$K0)zXXMzM}YW~fdbR@zqh3+LJycdsUvw`In1fayL+%TP{~q ziFM@%pX_j4Ck^(I$-FfGd|J|6!S!O3rrhXu*xa;P%v$fkQ%iNO zlugfqh{%X0;Oq}ajzzhNr8^M|5FyP`zh&brksa^So z7qzJRdm9a$sTL%GaH7mK4-zykJbB-zo{NDkV4>nu>LLDOLH+vVQM&)qo01wZijN-1 zx&L6YDvX-YsxZx5o#2*@%qIBPQA$*w_z3@yyz9G11pDt)5q-?I!ZVr1WB+z0_KjA{ z7-@vnHKvq|6kyeaY?DzSuf^n`*!rdVkft7C{6L_1P010la#$wBd_QDc7n(+IpxbC; zyvUbd+^VR56@u$Ir?x)LRSVz8^f4J|D6T__e4xK$>Wfa&m_ z)PwJcX#+GA5Yp+Gg(YW9>ia;Ayq5E57>g9jQH=?-zi+AI zQfI9?Fb&nEPul=VhBtD~U`+1%#HJndEv}ySt4h+9;X4`_TU@MsEcwl{pnsm%TMD2( zl#kAIL0CGpqO~=k^{OZNY9$z^kajgA`8g@#7|GM4!O>g6zwvplgSrKFBj7i`tois!|m z%r`rh<$TsBsX@@uGHF3(z$r=@V8BDz6Dhr7OYe`Xi@Ij7`sh7YCH#gRcH>)U4f9$w zSBOQN31R?4E0d4y>QdgmlF7K)&tK>7&Ra!HLI~SmBgXpqC<3MEHHShyihP?CMFXox z*(XJVp@%tM<)r2-arw0S?-_Swj#p&Q&2<1ObeV!CYL?FFa*7Ugaj}0ku5{y-1zSy+ zQUfb_WDj8+SJGIRIrD@KE=>HSe3qR2EKWmTnm@dgYi07YWRI~bRUv>76k=H zn@0rSC^|hd@+R&G_YtW8JX(tXX_R}0pful`DDB(JSXIgQM|!bDX+wFXbH@$|_e47* zE#5tcNrUVh98L=<0dg{#g=j7CE<1ZQ>@A@#AOc_8YUx4|KjfvM*VX0xP4roQ)s9xy zAzq02{XZ%ShF^kAdFF*Se(hvAxVgQ$%e-r6hk0c0l?ZH^foki;U-;qAy18+_Bg-N7 z&dm7tLTe{L0Yra2%f+**VFT?81g#%CSg}F=3S~dv49n(?keB*N9LFF3DT>6j<#w3 z1?IZevZ7{oS%1JDKhDf7u=r|L-d?Y!!N}N7j)_+jj zqs7iMn*alUq6m8z75T$(}8zI=5X!+m7Jlzac2v0SS%P$W6r-AXavORd4>bXV0gP*7H; z`FcS*6~KhtlysxYP^m`&rD@RqO%L0gv;1tsB6UCkl_nrP1qFh10Ut6M@eruuDfhD1pOs}?4Ks^j(v9QZgt-b zs+AC(6N_iohEtIEG9}2}Yc-Ggg{15L{s$9GVq1H9KqM9-6IOUnHgcm1_$h;-(Qq|@ z@++pvr5If;8}hAh1%@v;ad}m-okL{Q9h3p%9~x}SWBJfpy*eKu7>2s6Vd%dWs*{EE z-?it!(djcN8Q>NUZNxg@TdfCUSz34Z$eNL&cI~-ak{4x|MB-*-T#KiWqRCCnvPsYV z`P$j#g&a{(CRG$e-iQ`)QT z)(KbISat56^?IFQ?&M${T_Pls<<*Yvir!Q}=z!|WS(5Tl_9;~QEVL+FG2=zvE1FY% z(&9NZqpy^c6<}>4*D42S$Xz61WBLcc__@9&0&pEp)kMHj4(RPmmg)BQ(3}sU3yz^G zhex8B1UqVD%{|$ut;ed`+WA;w2`H?K0T^$kc-VODS6X!GTq3XKtX9!RHnh4nb??^B^j)jQS|B+NiwOg=!Ngt&&N); zj%5!Izsu{!R+#%I7Nl^TU?>XybWo%|=2jub>dcup;dbU&!t&JV()UbKrpCBI{u$Dn z=tDjvEKN0ijd#=cx?#=$_LpT^uJDf`m=HwC)hd ztK_RpE1%;@OLT4;8-&T+W2&Dps5!bcidIf?k&)32S1K#f!Fhk2^UCoePUfb1b>>vT zosrhm2tz*vZEIy${)W9j!6v&yR~^RF=}!!oO(;W;M$NtdDV{XeqwM?E!9m*mcx=bdh>M=>f65~_j%PVj!M zpY*qU;F59Niq~@2=qGcefs|ZqD*MDJ1##ybMuO_dTYY;zJjY%-H9dnK;9C?B))ZCk zgJMr)5r>YzGk=*plSAIl9>-3$(AdlM4cp9LPW8H4!qN z3Qr& zQC~t^D^6WONaYxMH)XnggB7Ng>; z=5^SM;N~>ZnzvW8K{wt01cjNHpQj-;WK5!C`IT0H5^+XVMsx7S(un7%G3DUuhFA6? zmvp1IeyuW}a7UZh1hL|m?e}O;jw;5(-EKcd3beJgg^r@U+$C{+N9^HEcJ}g6BhjOA zT8Al`6P&}G)Xozn%`xAIii)+CRxVqRto5&>uRL7>d7eT}*Ld!FmX;y>xS}e&>B=Le zF2VL+tA09(;*QH+k27xc9m6X=3c}^q$0qEfx;mQ5iHe6d+4U@5U{12rU-~T0O=o6Y z&YbpkzLbhQg3UU0Dfi;5f$RdccW3E`;$zHLPwBeHw|i=ZP=`)Fe`{T0e`q;TdbBnm zVxJLvtK0ZNob{`ZZJlK&&ntyr7D+wt@5$rdaW{xoRQ{M+YuOyYia)g*jL+KHGR+|G zH0;wbnCu?#e^6_E)1|;pKncL+btg= z!=JQ|5$;*PRF#d;D|+)w)yH#S4*EE&W98^Tm_aQRa-uHigz_N~ z1KxDE*N?OMYi~(oL5G<>4Of0TEIN@8)2wng6k=Px6n*8Pbf@4sY@sr&Sz9q)98dYc zuPP(9YGI+NLj%k6PRIq2C|6v-YU#So}tl7yFEoD$Bdx$stmd{q`;aTBaSAyp`M^#oCae*9|Fe4e34+c(?33 zP^eDQUP!;Zudg~(CG3|*>z9h6aXszw$L5{}Q&|V+*exfodB4!Nddfk)hkVzshI4!- zDA7C}HbeT*BVnA^rx~1UYI~?WTTE?l-&G}b(Y@UPjb*kGF8#VR8$-l*iT%j1s+KdT zeRVMWAaG^pSO$PyUf(OP?O-H}DCBIXoE~qU# z{-0=%6=W+{$zAI0g8@50tMH@zCn}^TpQgdJTqUn=wf&uI@yC}IiBMsm$!c9Bg;4(# zUS#{j>C=FLV=f(~9Sa=EA-;3KVS}{q)RT@kAi|?Kqd@H$+E!ZHd-3@VIO>|2;~3nN zVOwQ>7&?`>asH=D^^l5y1X-(N!@kJ%hyl=Bun(fF5)*SqE(t^bD14oV-r<3yewYIF z`H^(cgU|y}67BHPSRflj+f1Orq;Gg>;L@6H7e$(24{`+lI&ffAF^oLD)2QgM=p47e zK#dE&IcG@#M>|bVJG9p#H|vKC&tDot6wJZ9PvdZ}D4>kfdXkAo=h>Dw&GpwjA30{+ zcU5IYB?^Ssm)lbGxmR??d~lD)#vD}+^JY4tYBsIm4#QnxxX!ZHu#t!Go1r>-<1Htj zQ6|Rh(vf?u-iE$kes#JzZPs3ar66Vjfz{Odgk0B3Op2x8>t-SZfuFP-ZCK}qdeV`6 z_i-ajBbnnBdh^*R_f(D!{KY+J7~`b14QTuucB}blN(ok+FBuz6OA#{2tyuWhnrwVB=6#rz-fohT`#o^o zdi&r(hjod=FY_dKFjNOAPwrG%;8+8`^56F{f8Gqh7DloNC_q{PK9#HJ}hz^FT&>zIOGfG3%!q;OzP8`GvkJjJ)ut+(D zt=Q<6Z28)VpbBSK%XWz?QDDT|k(ccDFaCb&OYUY}rMB=UW?2aw0D@8Gp*7W^6-L>Pb z7ZB`>K^^XIo9}1ZjD2JUwG8;kqb&eb{2f83^5{0W=CJ9Fe#VZ8$4)#J74M9m=ceXwMs93nptG=5swbOsIp1+V zfDttR0I2R5AZVg^=-HvRQ$L4Yzojl1_$Wal$L5(ADr!Cj<0t|~H%57hPa6EJau>{m z2d%qxMKtH<0wW6xo;rRj7aOi5BqU5tndDypj1;07;cPCN8ilBQ+bUt);SUdkn0S)) z&F!yIMWq_w{dR`8YQ=Tf2VD2+Bk%SlU}s`Xor(CSpny7JxN=$jC}d%hG~!5Zl4Ll- z3xgyCAFfxJuVK*(00aATJ32>f>4=!>3wd(Bm}29jZ>@)hvfmUxFB>&e`iYrqB4a^9 z-m_nROm^H2FiPg6kckkB%!vRvyu$Z7Zcxbi^55u`NOZX$x2Ii))I#vdQu z&`q1Yy2OMvGb=QbjkD2fX|Sho?+i9((WhN22|KHJD~Q)jkXc?7eVCIqE`G+O8eZmq zrYaKz-1}+05xz&J@0`;MY!VAuBp4JBr>nAxbmwcJTef^lop9aPx4^nGAm&O;+)nI^ z)G-6X%j-)yi?haKh2evc)pe*jcEPg5t=aUL@xFfR_b)*zE^LE#5Pg3U(*MmRM?YoB zd~xOYR-wEnA8d2>YWZaC79(xMS$5j5jfW{Er=?CVh8t)TU+F22iW@LMWu`p?I={@k zvC&Ip{aWSN_;S(&L%q{(e?SoJBQ-9qGF$^e|D1fFJ3h`JV+J44k9mZ3pPOA&BxZ2? z_sv!df-bPPbEV(B#R|nR9D!I`g5x0}< z&#%31Hi@g(1b93cy6IXJmYn*7*N^2DW$8G}Z$35dG(@8sjsE#{hry@VG>E(f75cN? z6};iM)6Pe$wTh%LxUn|>ShL%AJmB;`zUv5}bN8{paunG1qP4vNAQ^di9JJWZ{IlU< zj!xK%d)eh~;=6ZL+PK3#baPGwok$|j&Eb@!BqUU(V`AFhT^Ls;%4=(Ah{UE^y}ItL zGy!K509Mu$1hy_!1h59;w&lTpqIc&59RpNqJ(Uxal5Z?(*ma$GRNk`6a+fIH3(HvcB73hc9JQ{Nl%$dC&E^5==g8k ztm*}k|_I6f49({;L1|ahFg6kISrH$ep30>FuC0j*hwwN4!91{YKuNf zOKsn5hK<4rRf~)n7e9@BX?H_i+|5H0)HAVk8rr|_dD&$duk)mpaNQ`d9AuDH2nA+j zRO4|Ht=3la{ele}08dkC;VMZaq&jrm%>Yd0I0(ruA6cx(P^`a+Oy7#`hmPM11Xx;=>&P!pDUuCEb&E9jl!v-|yKx6skE-l+rdASyWbD zpUW8Ptg(&eg?Qs_^>?)e8{m;)#cr$8gUfTFk>)3Y4@USV;(hVex(TUKX=KjqV5a}a zw^f>SM$E_GyKyBWi4MaxAl$NDtviz9kfyj4wtoIHgpq-)G)_$wzFy5P`?;fQQ-ZVP z9W38}g2lz2@1O7r99eJA#Gr)z^8eZrw-y16_>*mDxk~v^AU9PClOLrPVl+7lNXcElQsV z)Y0EqdEyc22ERX9R4AEZ#JF&2>5%A1SAta=lz?%int4bIUIy5o#ad{iPM0=@bJ5zN z_s3hneG=K}(Iqdh^>pWd75cv}`8e;M2bs3skb`{pQ-a1!yOeW5W=UR{N^?c4No$D_ zbJjUqcJrf2{KhVzb;!yG0q)gdDua6$12{AgOkDKyKxN_&tfI+?{@ke>^+!6*w3p92 zYX5Fp3t;{~H5orM&t2Xh9N!)ZbgY*AecJ-0NZcKbRM*DYi9ez zn8-xEu!e}f=}y==*%0C0KuPyThO^Q*#f^@QQCoeqGa8njwAx3uf90S5L1B+ z#SitPf8q}CmR<*g(|0zmJ7M3NsU4C#ngM3%kcgx_lih@WcrM4TdezhKa8<4=NDXDN~i z2j`fF4NH;lly8VLucEmaE`r@{j07=hAtVZXJ%0K!0M1yDe>(#C{Sp4<^|E{9hja&r z`TePS+16Xf`invd-9?PSZ%?|1iN?2=$T!Elm_{Y`e>1<{iRRW5xp$mV>}6EVJyK+v zn6soTHP=PyA)_LMkb#9uKh9mOr2tbLbCA1gg}ItT#>T~|4lCch2XGt;bMShwaxkTQt`;0g}^grQAii(QYgK8gR0h}7ZZ9rdjtu3{A08Ngf zF8lD7=0z-AYI2AiR98 z_deW0ZHFaxwz6CKS;s08pIA!SK4xZmf!FaC^ zLc4(xd;{6q0ul@ck+z1v81V!IjPo@rdVE`fU^96~BH0BUgP}pLn!u?prgf&4w1Se@ z5kH2w%ut$4yF=%yjzE4dv+rIBXl zvRih8tEgdhS6{zQM@km z?D1lK`ci^Nq^fST;X2_JId)|^1Y{sHGBR2pxO61=pt(uA5;k0jyaLtZSrnM3^T9Pc z5c4JPbXR|v=prmk@<6_N^{8iHER?oZ1NprlfIvO$&9LjpBwTk-kNpWz6EGYsl2u9s zjMcjom2ipx725Fl0@3ib4Nc}NCnzPSw|PXS|J#)KitaUqD0Pl!^%-rae_+!f(` z(~83p#rIr{4O6`H@_v+!By!rds2AqiChE}~zpT9l5fW*hMfV`T)-+1mmY4BD#&f6X z1qHWX!b!0Q9UVc*aqQ_Nf*t}clP*X`TmxX+S z#zW`0y?w46%Imwbds7q;uzSAEjJcJ9y*K*b^&Ywl3LyzTTo!Mu)Of4)Tyjd{4UQ{- zF}_(V?!-w$)|tWz=KHDI=IdCzXFF5kQ@0Qf!fXG#W|O~fD1GrIZ$kJrZP_R+vI-2& z-XG0%k3N``AHCejhb!*y=68Fw@r{fK&8L1sdKn0`M)Xv>)f+(wDiYmVrrUqCaF>DQ5k$D1M0Sxg8^f*V{*&KAct|4!bPEoLs?>UC2bVgO1pw6CR4b8v zdzv#DGI^=(&WXc`^V;nSyOWdFLgK@@K{o8w}#Hbc2--a>iS4T`Xdzv4QbNKuzx5+2wz} z3LvkqJlN~%qjuuN&%it2I8||Cs|F5MRLol$kb7`7&yZS^IB%=cE3F?_{AjFv4hxhI zKyw$lb-=}@*>G#rWr|jk*Vk8SE3_j?iFn53%o{wlxp{OBKp*S^Rt{$L>D=zpH7~oY zOF!T5Z`Nrvd^tI(oXIyUBKA2P&gUx8L2o z5#{aYq0zw{C$p9h|=0(6&$!6$Q83TztC+Qr`JT8j7c#hU zdzY*bhRsG?DZ_c!#&1;U!4#*NNcMs2k*BqyH6%H_2X98P)COwaG{+sYl6H_=%UiSS z%z2cwID8pBoZ4UaG{D0DK(E{JYmiumM&3k+RIrZ)X?SJ>vGy2J3g?d(kQKnAeuZftcM=9_PxjpmfNxwYaRZgq1ghz&@*jss@sXfo8E=jqQ$ zaK~_ES+5CO!JBLIs_N<)SSWWv+mvE|H1_S(>(?)Td2Bl9atNe_IB4q8I@xop%*cgv z=)|D<6x}T`ZYe>3r4%!gy%;R-(hjupQ0QV^@6?V|VGrqiP4sFlEClCy*CKL3uwAQs zFrdZmVdR13KJ5tD_yKu^>gb>XlAkwy0=RoWpJ}GgqGuY(R?!Tj61cJlRma2_&=Gj$ zWvk4n+C5|tc?9-Qs9K{Dbc+NN=@v~-kKb@PCuLz_5tDF9rWw7-*wwlfxefxQ=II~^&QE44dgbtuI#Y8}phhXw8CvawPxsSgRi#8hGZzi* z5Zn~r(+zeT4#PURv1%30JZ_je>pOuey+>`}j6B`zO23REc+rcBW?yDbq}-GrLxf4A zqo`)aNEw$;%p5IgT?n<$gd-K6cXsTUhm4y@VX-4ygJDV!A7m@Gmj~+ssVRnsad4JD z{F3uT=G`JJ@Nr_W;Duim6-%$X25Bbg6@6=6>sfnb*%FjtX0UP2+5X@BUa(wSLVI_S zW>{y8uDt0Rjb?`#TnI`Comre+b>3&-j`;|RghiCaqFUeuX=1c{2cs3ee(X;SNqGCK znBCgK1vxoXo%H$DlD9E4p}D?Q5BM$=sE2Df+S~sK`_-FtMo!UJJ#1kuYaLQQvbyRI z->SC0Q8MB~wqBBhC0GYOwFd`Typ;DmlBfOX$Df4`;WEW`$1y{~bh~jH9ku{S5I(S; zaRaqr;eZILP&qqp(j3*8x>YlNz$Lr1cjb(bkZV{Kvbs*7-)}G@wz+$?5F++ug6R^i z5}Yuolpa6S#=6m9x8bfS;njcDNkLStlkFv)n$g6*=i*0zxO`K9Ou3RubG`92#GvZl z)Tt0}8ym-?>p^vDA0nOq`5d`&UK-;3I?Wqu>J?x9XtJqZI~g0CM0y{7jLBKmsebk9 zVGnFV_N6>xdm$pk#cnL%2~ofLVHBW(zt%AspAKwcse|q zb9zU&R|RjBMk;c-X39RGG?#p>Ca8}ttvnn0gm8BATyQ=~y%lsEls)pNE~96o6y~@~6Q^LrqQ#W<%GKZO zcXVo^*2hSUwEWx7YE4_Zg=3zvj~|cW%8c$S5kV@oK^%^04+96UtHs+gA-C+JfT7zZp=?v9!ye0%ep9(FqT zlC(v46w;g8i>kY4JoH^t*j3-vvWq@-l^gD1iB^Bk?gO6rKLX%JpT&6FQ5O(^T?F|L zR}N;+r@0Qd6deJK(NEU^)SRZ?6+H2n@T^a@QcSA%8IxW{u`4txt|?x3`Y`QZIqZ2C zuxe;HTHBvbrdwAnfwYIQeJKO2;BD&PQ#J5FBQN){UO6UJ+KHQSDA)T%w2jQ~KdJ-y2`<`QAQ??lvT zN$my3Q=i!QsCIf!6v=L{D9zhHskF4zID3{YDJ_1aPF7rcw>B}*rBZo)X^%UdvP<>{ zP>KM}g@+rn)0XJ!RM#;%&`Ti-kcE{-jus+#*fV^3wzgS}9t?BX{>A7-ST;mOIi@2& zvdKDl=55tM!@v#e0m#C+Y_hIY0O%_1t^#0vyEe3cYahkkU~Xx`emrjg&Dr$^WNVAz z-Z-JjiG;8SA}S;|h%IN5a+pn^~$*7pZ20gSj$Uet2?K>}js zVkRFg8Y-hW8KIxqqa22a!)dFj5%k<1@)}VQzPs<-+2LWoEC)fZoexzDGX{QoinYw@TWF9GOS z(kfNDpPV&3?4}bsbGC{zb;GcyW7&?md~Q`u%B8gP(3Q?zm4X_Wm-p>M>MB7IZhh17 zxVDPY4YF(p?e*)|&e;^amKe=Un{aWhUVCBQeR?bOU{bwrp7|WUOnDk5DY4x9LoYvw zoVp?1*G~7TaKl|LWny2SK|M&0VXc?;5^`3P*~>?#Pv1=z;nd~|p*?ceaR+P=4mLI* zlT%$eDo-F!ku*_*(cveHJuFmhocF%Or+l^ zKh?7n(433YN$J@UF3tuXJbkfz)BOF_(nK9KQEW#?GfwmV`YiH*yL&{xa*84C%0B9- z4F2Gv6+AyIwu3J|EZstgL}=bs-GQ)%b!xciXg7ImmEfMsu$ zZpie`QX=FV8dy%$;8WpFP0eK!RxZmjdU>GqOm{euFP^fCY*er1$| zvJYj3Fyt9`x_e)n54r$v>gPDZ0x-6 zK^%=MO+Q~&Ri$<~ zM~z5l$z!X&w-RCIi=~IxXl7Fi|KX~kbuCZv6twNP^I-!|sz*n}?Cvuz%%ZLH7U^%o zG8XJztdJ=?7Ppx7q5bjBp0$}zP!pJI#mr1u7Tr(j_Ei;`k()V~`=jdpC~J}LlVWgr z;l)<(X)sO_Pvw&#vrhqhazXP(9$%BOe)?a=hXu|t%TF(E(Z!{uk4)RvG7YW+az{?? zb-?9$Z`Ur#f@`Hk@Fz5Ew8$Z!C*dKox#olBwK!?2e*&}cp|ql;jO6)>f(O{7O$O6N z*)o+>FzH(YN0toxHt*dd6kBSh>++p*axmMz+;Opdr~_HZ1KnFco}N@&2i?H!+UhDQ zDltzw%%8%MR7;S9Nqd%qVAvW+BvhlV%Izui(+>>1)Lbo13q)H}UF1x+Xv;x6PrevgO&pzhaW)Vuguzg)S8IOYpkK``XCuk&vR*(;Pggt%d&Qv*bLgLf% zeBFSXwI4CCWqXA?3tGl*1BRHC4O8yyv{O>hv(uLh9Ub2;hF?Z!Sf*OJ75rgZRd?3z zVL^uCxkhI|eIo*B2>?&ba#hp#1ri{|x9%aoIC3jZRJ$=4o4+*(Lg9fo_ZBIh&0=aP zD((Ztw++pZH2umoXXmQS!4Dt8#aiO~4GJJ5TFhB5wxY*U*N^uc@a;-25jaTo5wGUq z^9fGI9p*XT^JzpRi7x{pHg2ax{^Qdvyc`+k1OhaO8i|16Nynbf%z>Y`=jJ9*rpC*{+D)~>I6L;~b0csdFTnoCE?H#qnc*)60ns9q{?Gq#DruUGsMTV-y7vdg) z9y>WX7awF)N8j<|C&t@a<>bt!O5fq}cHeC>?Y|ws57~)AY$woeP9J(p5#iwx+Z3VF zD%cJJGS)YAqc`+sXhUN1Qe&PkZu#}O%92IuqGETtiU(9(^_`Uy8t(d8v22Ufzmn@K z{qNqr3;nbZw|@BUyYGJNsjZ^Xs$Iwx>&)Kl`dV6{v7jlGm`B~TZSebJ_Zm~|%Tb+D zrXCC&*U@?3_T-6+D|7kvdev}gMm=q?J>fhI2D{y;rLT{~QLF!kYV2Rg@(ax8gG-;1 zd-BAU`Qf54=#VkW)w6?lBpe^XlpMNb z-&ar0GW?kQMQOI=-22u#>~+ub>#6Dh^0K^RgWo@G>H^`y+Ow764yvEeD@^i$>-_DkxGC2PWxES)&pRrv7BcwyK_MtC+mw8XEdE zE+Ra?xbZ46g&GIA2D;v@oE3)HAfG8YR5yHnTmk}j``*L|MsL+95UK*K z#u~j|#&vXbbg!)36lShH8YB{}oa!imBJ|L8`^Xc=k6#8dkd^P1oILF^Y%cS4V%B3|y^Lpgf!y?uYPQ-AGK zlu>eqvfbqmPG(BChM_#51V`;7qyI7e8zZtj;oalJtwPh)1eH!m6CnP6_^)2v`l+@O z`{H0I{GS&%pYqn=@v0iN)kZObqA3hS1?!0%N@7MEB3l-k(s2KP=f6KDINMiB$q5P= zz+GHiYW!(o@q+J22EV-hpD*dJixqs9l$iJkFv!i7RMyu6ov&>a6&1BD0+~kB<7i}G zWqnCKiVM4Oqv50&I1il0+SmwvtW0xk4yGLY=|6e^JKux4IbutFWNU40?Gc)Qo+}}D z@V1HBdt~80P)9NjKQ!dX6Ek`jL)a*uc~-53pO&(BrxynA0W|CXZkhj=B{>n^+_0f9 zv}ccKviE=XWqHX1QZU3c{zG^K6I`e0mp$kt6X(TVJ%QPHUir=MDr+6uheKQg17G>w zNd33_i7$q#0O}elAw>+BGPQtN%r7pE(N9`@rD5k%^70z`U>5pX1aSAbQtti(^OV(t zG@xzYJTUu@Hrkg<6%e>!!rKT9nH{#jmHe*+^1q4dt+*`T>y_w&l1<*1qqIcs!>uRb ztTtvDhy#vtJrByi7`wnjKa!G?P+{O+DhIdCkSc_+*2c39;}ESYzqJm0!t6M26&`N? zD*Wkxwnkr0EgPFiv8jb#cbnmbXu{b7^DfXW}^X>CGod_3GvA1qIuBv)br~2P) z=}-G-``fqXKT_uB=V!7XiYZxN1cpe^MC*T0v)kI~i}nE;;Xv>H=>#!|ugb6aV0SqH zQt!Kf)carR>h1r0b&!`vW}nx$1% zN>UOSIUbS$l-2PA91h2oHr-xSUtizC{f{)=;)*7CtRI|E8>?Qfz#PR{RoXg=D&7A| zfQdpvLK(ewb((Ml0;;?Iu@+dKHm@!PIN&vW)2Jt@V#~~-ly&x0fCd+n|vo91`}p77->5NMPDJH)qyr_ zWQ?Gg=pTBhZ9DYkoOAcTTAnZO_B`i)wuLQa{6?m1M?^U%irkm$gLH0>uf91@DDPP7 zc~wGO{N^-)K+yV3wY3#=)R!fNPzjT5a&mIBvl))w`SmwCA8HwT_Kt%X)#}#R z(Ep9~U-)9-d*VSMqB;s+CocnbfPsMl#ic_Q5h(@KQ+*19!Kg)4=I{M{6DPH&o63>F ziWOuKeq9&t2!bkJE4!IrA4Z?kA~dw}wbNs{!Tfpj= ztrKq}w1x@uz&<=|`WcfByhleEjOvKNL2ooTz5Y$BLeNQQkC5ih>NnF>?K^cs|8|it zei48Vw}AajFDQ5|FLOZRD94B;-?9sgsD|*~@FPjaYArW`zn(&9i_rUmSxIck1URw&p zSQDNj+Z}MDPq3wDJH%H#{Y37Gt9N97%!Ss|t(2Gx38Ko!O06nYb{$hmmXwk4B`K8+ zN6!78{rxw$=AT1U0639NLj)043vFq+iQ^be*`MorN)H&U3NK~2tgLiVoE(!=1TX=omq@N`SBm&L9UY9`c zr~DiYtEl7=muryWG=ouB)6yE*x*!T7Z83olA7(RcQ);i@xbZZJy}5ZFKs)9yb68au z7}es;Zv-;CZqUavn`OFKOKpv{EG3ib9$s8WSdf&#{eTYs#chq?@$5M@M1MB<+iCmB zmX?#>6n8vU|8zCCB*ww$atRrbxoNoP(H_6w3<-9j2MUe;;TS;?5}g%#M?}DH#W}JZ zhLr_cm9*(LbJ#RpL+r@iBhspN?K>9wQ~DFC5Y?{V2;Ayi@-o!Z*Pp;LBDHwAl>SO` zO`pqanINg>_+O*1B35IT?PDouq$GW_X^-HI5+=Fk7458Py*XZ+K z|4My+wSC`ySblw6r=dB{s>0qT9Rek^p-@9?m1@2j0s%i?n<)bQxKkiA;>nXIK1i32 zD+?5JK~n59yH_Ya)RKlPJ9OM#e+e{%Qf)2AuclSCqPb91xnLfax8 z<=p2qu}k0&FJW>GxKFdlmvkF)l~eEyy&ng#z{F?qsVYGlgYPbXSP>=@Ji`pe+AurV z#b0bi&&88d^Y@m3-=VKfRfEk>0()c`4N-r@DAEl?(ElaiRMBq#s-&bO zZf~%mU=RAp<&c*?e`$K1G@Uu@WyOA_$=Y4b}sn=1tj9SNirzXh5^H(2&M)G*!FX8&<|r>M;tE;;X(}a=F_UEucln3>f`q9h4mst&=^w!6Uh0C`iv<|5HiA z{zW$DGyU)Or2s|nf66!be>p$Cy&F}#9ite-t1UbBYQUjTsP1wDX}rT+kMiox?XhZC z(?)V$L{*AiEawAtecRHy6 zmb?rqg2$#%74kxzrDP+Ps`%b$%#Hw3l6D=fDQFRF@H|rlt`Z8pR&IMW`3f+NAQ#MD zKMq8-O--zebusa|n##9J7Ew8BhK7W7wE;39YHa_@7T#LkwlOVb_$n6@%l}f`y?eLx zz)ndwOA+z02DpoGNAGCr{xjjFaleUH5v~K)5Fbb2zNQJA>lDQ8WloD$C0Am&;cRx` zNQtkDqE&@=LbsCj%RdBqYCopdSp4WUQszNwy0}k0gA{H3>gFXofl>n2r0~eaROh_= z0WspIlVVyfPzb2zqgv912)^6vyi@uwgVTijTW4t7@?^SJB3I9|z{GjnpQ`Xr$4AUD z^!ikb_gHn&L?|igPh;TEn$4(B$&Fec<9iCTcK=nis@I>xG1wZ0HO^!i5^H(cqRFE#^)lim>zgqO3v|Tcxe;_xe6U?M3@|)8; z_D5aV`dvs$>k$)4HrQEQ9l=~ijh~&|QIQt=VG>}zS6~HuJO0kx8 zUdmTCIS_P(U$)47OO0kW?`_uIXOfO{j3@_)Mecjz;(GXzww(FAh-HuIj~0Au5jxwI z7Qr|WP;Th{jv)oS4MetY-M$B;T7{7BotUcQJ& zE&VQResfOe7d)q6RU1Lq1`{;Rx{%LAgr$W9xUzOaFOWoE? zJxvYYXbN8c_4e&2DTYmcD}@3hLfRAW+Tf`HQK=iRCjxcyjlU^F(&z&wvOe^MMD@O# zKkkiD8Vt~RY%Q<|o=>o_$v0);QHHEe3-is*CO{okl20J4EPqEG6W;l<@Q*8-?@J6d z=jnwh3Ey6lkX`uJI%EQFB8*viBRETlpepb39DZ@N*P`LWZ-OE%&iRFz=NtqSecddA zs?NBnbZ~x(iWC*rBj*Hk**PSp>SE$f2@*F)>c=|@Rjox4Ip;;b*Q2!wXY0&e$guZ6 z#~v*>a*NT}A63EO#3|$*sW}|4>UJrS-lu2rjnZ5#=n}5m>FDW&t1#ftjoV->H&cD5 zkLafwH_e@ncp>Oyz?w<*iQJ-f)bHd?6XhBOu8F8-m%X$Vxey%LHg#}L-{v3c(?B6r zL@D(>2adibeC>yz2dqX>aHsvd;XTqZXZOBuCNL`M@=@#KUVjm|-;x_GQ09Dz2fk?Y zmVG5(axVg^CH$BgWRryXD#<=*_$q}6@(u3{VSEMDs18B_zLab*a8Srz{gswzs4!cN zIa?swZ3r@#ZB-XcGgN%0-#!5ze8yvIbYvJ^c%k$t~a~;&R)aOHqb{8fgo2- zu}3!qClE0fVTEucwQp9E=q6A%rC~nFepGhSI-a6 zD#$)2g>OsC?drh?Nev4Pq+~@uol!8YIBb2)9Xz<>A(KH??9mu8M{7{L%G$V?$YRiZ zqk1Ih*-H_HMqP#;P05CvAFJJZv(|yx=gaSQCnBiUD8*mBQI!lHJ08QqQ(QP4nBz#1 zz{o^=cG#1*=R@aWFI68GhSUA$pc9$9RdI!( z!%)sJ6g*NGb20?V9^GZM@tUuE}ZmEm?)d&jS4C-#YbIQ6WB!m#=ZZ}#HOsU0b87(P~1GeL{ zY&O}D*{GEqwpi`jofX;|E7aTnV4<1FS$-Nb?CjkDRF|Oioe3f)u7(_^(Pz;Dek7qmUm4HA^E7>*gxjj*p@7#lcaQtWK*oA2A z@xZnAU%2J$sWe5aI*bWoKcGRb^R~f@DM8W5DDyQ<5T{cXLHiY6XEUL~*vJ;bd-v|* z<2dW}NV7>;tTl6Nxy1dBuKr8NUA!9p*SVVC&sWTAF*6N!A=1i(ZIwYEwV74{xRaqNj^`^scy-JJQjA1v2 z+5DGcx(9u(*9-{+)qn1>yB6)7LhhAlc0HoGXV)dA4}4vZFk-y7#OwSx-m``!18Y}H zGlihuFV|R_>lT%PeJ^k~zV?;i=YITR~#z{63v1!5cu&MPNHY6%; zW+`?3#Bo`hJi58@3K*e2!L#k|k!w$6m3JN6T-RG}coMf54cP*+=}qTe=WH@u4Lfxo zv-DI4rtEc|b+eWN`VDXdq`P56sLs#WCJMg39zGciRKpwpG1m-DnuL4Kz*f&LyE<== zWXfrg2Yd~S?{FJ0E;R5328Y9WUXtfYvPKy52ZHNd9wvW3jk!LfTcLBUk9Tb!+0>0b z+Ng4#w@_MHhmj3>f2r4Em3ZjG%G1OH;Pd~>&%XdaY-g%I-1DdRYG?4PLo`Y~(J?Q2 zb6y^_A(6B4U;0hG;j0BLG=J;i5Yxi>NBADmG{`tTA`r${d+KDlD|crfyXSdK1COq7 zi?7|Ltw(^*QV>O`>X5->VG($ISD|r2)&_r_b$MI#Y@KwE>e+GNi?L=DjK;XpgfOz^ z;!n{GD@1LM-boqHFB}_@V-Dz&b1Vt;JmwNJz&RU+uPcwkuzF$XyJRC@#__{W$ME?g`Q`a}4!?jDeL#{bUuJ+|&3R`!mQhZ~_(D(lcXY)$=_Rb@796iYYuZceo@Y~*kR zp&O^9pdebH95*q4@AHeX(PJN@NJc4ia*^?%^*V6DVhjq2UEGD+yJT)gpL*57reZL0 zAP2JEMH6SbZ0*Hx7cqq7lq#N^A`gn-FoGu#To$>T2*%pHN@)*Go2D1Sc2^Kt6`Ku_(uZT4h#1+Q~O0B#hDN%iVqG91hY1f~wsgd?%prsxx-nFN3@UG!n!Kxr; zMbHch)M9X>{ELpw%pEtRl7jlGw9^g9+WeS;#p7almD0~Z&a@h2737l*r_}RV7ueQo z@J1EBfd&~e;Qb!Qo3Hiq{l;vaIxlWiMcYPRcSAI1(+&B(S~S+sbjX7=a928@N6jpU zWYOg#GG{5PntDPK~(&%>2 zhsW1hltq_(*NDm_kYh9YWzJ0(lc|Gy%T;chkf$F?-gjJVnyOo$cZ7UyDxXt>7^%aF zL;Wk(_`4cG9hYIZ)<(pax2TyO4FsKl_ptvzyofj*;Z!G4pu6qm6oTFJf*B)RAK?#lPoKK>@2Q_wt-SN%kF5wb$&dxQCur*auetDxnIu6 zO+V7Dd}Fit!lr>;T(DB3eH-N4ruhto|5EIOTKz7-R~xL;;&h3|cuU-($R=?z<{jQ^ zHb&r>1mnkItao3Wz3ow(C#pBqqbQ)@Sku)LRNEC23Uxpm}0V-a#3{zItxTtf5j zn3-2LhHI7_t^%Uq_gL6hba51$P`xf7x2?IG3!^u6KggJEuF023zOp}O{r87`UZ-vT zVe9|h<^SCO|Ib+bO90R&d_MfSJbp16r;46v$@g%LL%>-9xZ_?-}x;l_GGv>b~>*Iu=h z0eH+yxR9Ai)9WBGEh6}iF*)9fqZ$Rc4@E_;sHkwGgDqkBQg(7D2YM{J;;Ey9OL+V3 zT1jyNL$89)Fn75LjCS1m#?(U<8Qlx7$ww0>lUV3itbEHZU<4^$sLXZVWn)}m^DiOE zk^b-#5$O~6=Ws@uFB>R0)(uYFE~7;DH#jz?sVA^yx%Z`e3U0jb>vwv z11lqB<}}+8H7j%-A|u1g!}Z*OCsu51pI&MzBOG&&W*S6lms!@NgGco_+Qa03Sz?h)>#> zlA5XnSf32y0kUhZ!qC4b*ik{(_uFF!=3&j@$KVsc%)MKKOCyPU0+cO&xF)o?*B+1Q z7cj)@UQFEq+lQeVGX{2f9t%uoy8&VhgvKy;#vL%S?-#v{%S|cdd-TW4z;x-n2C;D7 zjF>)IJOPFY-D57hr9b`|7US)U_TcIdZx9{B6Oe|v!mc&Ag;(}?)q{9vZHc-~hLOhB z*{p)5jkm{ML2|@weJV|~Wujb`84W+)clt8kFcsi?RXb#wUPiR2!}V}D^gXQ65hIz_ z906E{s~V;Q!sUJRA;CS&nY;}=^|*>hOp8!mk{82O?4iA9e9dvW(!$8G`_m}n{M#TH zL;;wwwG*L@SKe07*%)5ocI*q5aiRG!a~4gE6%GwjN0N@{Xhrn{@!QxhHcHU78%YGs z$t?0L!MH%+b4g*%b=P;Zip%afoufSKX$u`&@Ch7XMIk2)IW97mWn!Fg%1nZIj+emy z%AA|)f>F_Tix}Pj#ROU@>X3#BWCGDbw_PW1HjS^WSkBdKZZ1<)0L zd!yB$L>iMV16n&UR?Vd(Li)*W{=o*Z_vKHU^AB|UN}7{$G+2tdXgLO)>G3vC`5j<8 z;LmcWs)P=Hy4RRZk|K6uA9sL6h-#h@MI!E#NLv6$Cv`!_ai{FWRh|LD&}{^TtpNOS z0eE;$Q#em`25p)<>(7}kVN*-*?*Okfa&*N+O|hFnXu%j_73i9g$Gqjtl+_mS2PBfN zCuR*7iNokJy1!6tv{!{YrDky_L)YrBSmW4fiw?Ls2dTskrq~zc@$M&;tDNS|BFH~L zN4Qx)Mu+J22MK@}@m9@cQCIVL>D`+(<@)p8fuz>i7L}_Kb#gq?>S^G5g(eP0-VITl zDVQ~f3KhHN!oyTino06tuh*=f z77a|@11>ry0#0~aWz&H%BNC&6Xl}ZjVUz2nb_!?hosN7{o$l@t=PSaF+_15YL3V}T zl?h&}ti%_Rta75}n~xJ^k2t~1#a+}h-CYcMe&T*qgL-DAEm5MlEhgfyt-GW266^(v zpP(pyKP6+7mC*9O+6^CXquCQY@5RGM2?j_cz9Fm^;xEo4auplWX*S~bLaPf|icgiw z|3l59?8P*p_t8b_-4jN2QyR%za98}z%~z%W5>El&w-lWm`K=W2Fo#IAVAq86J(l-H z|3{(8oej?ug}Ig=6qj3RH$R+z;8?glVVVPO0J~jB`^f#lQ~G0)^IvP-f1gNVNzl#J zyI#A39?6l5rS8>S_kBUzogY0-R6Wg&W(pKPv}#|rHa*;%SVxeC3YZ(+SJe!u&V=o# zD0E*IQ0BfRD0-9R(if;7)6KumQNOm#iehlx{kZMVD*q0dJQ_Z~Q*|(bbP!X8jMF)7 zGu8RzX8qK($s1OdCoSjOCeS#gGSOuz?P0R;i@%iEd~N`!K3ZX)WYfOl{+VlA6SUoy z*A8OdN&&VVcJ4YM-L8r?|0O3roWXtZB=HkMa`wb$!56>eV;iX5?b*6yH~x`lQJ90W zi_%NZ6JnM>mFFCVskh0dWl67lbR=g>OE3W)VL9={TOkL`e=zB@-y2}Z*f;y+ufXv% z%-W>zpY0O%_R8&ZP=Tj@-7y^OV}I%0EmOGkW3f-=8jjSW-LCGdfV}5$I!pB$WmU8!A%Y>~v|TsPMYO0prJg-0>5{uH-EESK)hpvks|jI@-I|7MFxw8*j_^pCOk0 z=uf}&Q4JaneXxq;ZE^YX2+4zUv?`BZJWXtTC!-K{s@VVtZq_ej}M zeKU5p3`z4CllHB0DEO)33BvH4{r&R3iA=Y#)4}CFl{Q_?5#tef3zW5Eu6aA9cdOQz#q`P8Hx^H|K}6kPeX~xme2VS zGxaUY(w~Tbc9}dDR|U3@KgWcN5eD~355jRHRieG|V{u6uCJ2Ld>)qKs&)E8rf~tKi?c2P4_~aXo`YyTbNiYw+u;F(bF)RI zw!kLKr%&cM*2aLl!QAcxI@3)KFhsC5cHy0>Z8A5Sh@mV^7Q*n>l=~YTPc;z06*Bq= zOSY$&8p)!D;`8$M%fXl)4&ZEsJzk0V@M5J}S4{9Vq$$q4g9w5kZ@HhD4H)Vs>})iL z&Dhinh7pcFOjiOKXyjLF$_Ep;OQb?desc4~gL5TmeU<(hZP?oOIkuZg0mt|OKnxXm z!6(Vl4=WpKuFqyD%4NSmV`QL}W*vX$#nm<4`fHur3mc@uC46Foxo$=Rj08k$1X>C9 zpT#Mr0K(;aP{JvNLpXW!R(ipH?B#O}qcMf=-x3YiE!l2xfILeVz;x*dJ=JEUbJPTq z9=9zE>!e1Hf1R*IWzi(zva3RX+^o#`mw?HEC)Yu0t=`ueZQj6IsB|MAZ=CZmY|-L zpq+vRmisVv@%O@rt8D#K61^o1-QyZ)h51X)wh=IuO*TReFBJi?wSfOk6m~p~gY~Tm zKzf)#OpN&1nfmH5Fw+NG!5?70gXD+dre3*H!gUv&9RlP}x^m!j=>jy4=(ru~;@*JE zAx?>S-NW8Kh$W6^2~8z;b=!v%@O(0cp?sd$NYX%jhX8CKA6`3>z=! zX%l)G4yV(0-0Ku-#sTTJ%YEe9L9+lsk!GE=c6MdGpu(}wH-NFHcnxOiV7xBZ#dSD6 z3$s4n&JTANt?PKDwH%gUy|p=3Tx-mH-{oT^B)H^ReF?aQB^4`99p;Xc{nGgSvB6#r zT`x^6gxHes2Ua#5U*qECV-3CqzUkicDk`Jx{gH!tH7brOZ^KbJ}Z75_-T-96(ZB9mw@6QLL>@D zJjH8W+&jPzRs%MBSS`b#wa4q1#yk>^?KRdHr#3~478i#B4;c(mSo={Jny0{zaZld^ z-h^S54H-;N+1MI{^>ba(jnyhDPDkxo*dP=*5HsttMMHK3xNR+=-8dg)Yyh`0ZCe_f zO5-<1@+VZemwK8{Hnfchnit`8I=HeoL49WYz<6esJ_X=KHx!LSTaAbiIZQ8v0zU4|3-iDK`dBi`%aXn@}=mmO3Ldk67$`~$lOuhh{> zq}aEa6id`h1$z+XR37#1{0rV1HoY60EX;K4{c$2}X^_{wTfR0baS~Y;kSn+Iv+UMf z%R8ftW*UM}#~jr0G&jyAX67E&eN*(Gar<0gd1P2PqzY--(UZ+pH%27iwK?-v-sUH? zKKCK5lMuz^$Z+)M1nf5U2UC#yHV^=3AYCw*##FP-->&WYj@s8E^+zgzg0t8kJMFd^ zbA0p=kO#geo+2*KM_V|QU;oZ5h?cUoH*p;PW+Al>eF1fBD`x{M{nmo)=1ze-at*EV zU-|mlCt0@N?sVSUWvLdjT4`H76At%ShR33oBgghw&w|}Sb-TA|lS}UB%=|n1c6+R~ zcsbF24fQs1Y{uMOcKIegE%S-x313Aqr@>v&o{vv|8;e1YJv8Tw>AKli94Ya9ZQ>z9 zygP3N7KK8N&2Q30djg=SIrD5=!mr)A9}@t{P5GP0EKP__es`}acwg>HrmClM^BwK~ z{n_-HZ{o6ioT9of`xqdHRQBCFwiN(|W53!6Z}-#E_9nc+t4&a5<0srp z2cfcGabOcUu>Q|)W+cw5&bP04$g_Xd<1QFsk!N@;A#0{7+l@)-wmeQ)51}@HCXZDq z>wM`&#;v&{U8gC9m-&BwV1AT`JnFRP?uvB>=GUgLMJ<-fHjp|~tZ!Mh?E3zsI$I9s z)e7yEPT1qQ2kep`{?^Ibty;ga^M}Lapn693$9Lc=CZgiWpNH3f{n~P&D$9TUmQTSp zcKOD=8{?rWGFi6QB8qY7<}d3-0~e<=^XZMwdkXZi^H=Tw)%Ao3+ub_-!)N!x%WT}= zMHi6X=SYFX3fqqwIsCK!+zio5{R-@q!{&~U{rO!7J||<)R=MgP6po&au;uQfq?@0~ zvg*mq|9Ee7MfznkHsz6cm7;O#+%~6men4@Ci@&07lK*j>Y^^IbTdp?7B;3X@~D~r zxgLs@e#%Rr=}k$mY3ZEA88}9sxjqNGPyCjbDCIEec5M2PAUU{ey*|o^`YdtRYl90@ zJ6Y#b}3A0l|RK{4NL?8wctgVl!~X(;H_N*5Qc*in{26n$j6Vj~=3 zr%uhPBo#*oXSO&W28=K|Jd!bxzDabD!t0QanD^1^+XmXd7d9&8;uHKG!|~>wxg$O5 ztmNm4ClP|72&GF{&Pz{p!Rg8R(X5x>_HlmNsGCc(Uljs6xs(1FGc$i1=82)bVu71|YLQt+t~a$eKiL#yTW)vET<(q@~SqE(&b6~*tC+$|a4*EXW=X9p-B8l5C zu(|;hJc{7k7C-||qC?`uru@o;M5TM-Ab;naE&3sr_~V9V6(C^tqnsp=VFGaq*Sozi z>`g7`43`YM`SRSKTJIt+0^u+TJWQomto?EKHKr0Oa672TarfQs7eFmjFW;ny9H41+_gkg z;3WMOj`ydxYx{|3U^pL6kQ~t$a0{YB-)G5vSgoe|Ub7(YK4!tI=KNPD(65Vv#8&-dShVC`J!g! z+$8Ec;(-v}Tv4CyWJxU4Z70tL3LTT05ZHWLuNC1^uQFR&it!t* z7GY+=0SN%GO}4a9ABb@>?;^%uZjoXTF2wTY7Q!%P^~1LIidBlB%M=c=~uQwf|&^7S~C<#FQ(tvhUncnnf~4*bq`O& z%jW*pZ~WpywHST#RqnrZPvY08t)UpvdCc~` z*Oq+_IhM=or%s0beF}!dh!RHj7y0jv#3&{^-j9Wj-EaEHqi}1&WY?v5onN24P@4v4@1NF4|FyF>ssHt4^@)RQd<(bc{3jW*~RX!zp4gco?d-MRldaG_A-ad=(dn&=C;p%1$I zvR53axH0|M4UgTbdjm{r@g&XHIkrw3wLae_Jc~n&8(9Nz2&UhlHExuUTBe`uHFFsh zHz6(fxs{*8XYXuuRB>ykBR?ZYz-NQz!DvZ!|1xf*NnW$+=}gf4l`}NkRo2}N%TA34 z*B*&eIDIhFZO#4G&q^PkCB4B7Pi-VIggK7(7{L(!%$F`nyK+D7z1Up$YxkMxa#zvE zq4IRH&%rod*n=1tP*)kplftV*rgkT7U4^*)V|d}hV#~5q<)<4VC2{xOq#jppLsZgw zW{1$i1aSV`S=rPP9~EAT{OI|6D+fQ{ zvUqAjqL~S)f5nSOU>yU5#pnQ6C?{HWa@vqdD&iRojv2O4I@8sKw{K0;l

    a=LJIQ#s$}gicvS6hnUT|3w>N&Yt>2X3Gu7u-@y4d7HO#nNV z60?O()G-zC1>lBMTU-zmLfdvDET^JE%Pdn9UgJ8t3B_8y2w5N=U60rcOU7qgh!f=Zp?q@;n zRvvKW7H7BTT2N7K-64+)aV>)RO?+RXW&Fh_oX*58U%=YtziX`}A1f%`1kH%Rv9Ub~ z?(ZC=iU`l*g{mnOl zne%-Cg|$cH?Dp|a1H~(3QUheoVZ$WwbMAoLjArZ>=zI^%gph&8w>ajAW(ed)x|aA2 zawg9ZbuL~&Zwr4=h4*~Y{h)=AM+s5OfqtfcEQW=*Tqj|#^pv>9TVW17;}kpr@|^jb zn|XHO*%PlXUOG8%Mx9`*Fp^Q*!s(q57< zQNkr98m&RYDEP#<9>>K&ak3G2xjKy0(P@FqBzODG^#1DG&;#)WFd z$nv#BqAo_*w5f~OWd#RDPm)y8CS0Il2{&~95fcc4cQ?Xz@(M4&&+-}42z-(1KW$tuA2j3Io*&N#=83-#JX3TzbA| zl045$?q=M96l07G^4dT~_-s2;&3A<5efCKVKbsPLj1z9wn3mbXPxqX5J4rXm2s(e-UCv8#49?FB@C({k-ob=a$yM zTBa&hYTP`*5NsK+w!n$?LB}xa;sqfVUU_=Nz!%J9U3NSQP+RVDE?w0)$21E9Or9Rh zEe+XKK~Hk;TRrnkjrzR9GQaBQ)8>jN{`isWZv&;W^jFDQktP9i{(mJKPpD&qhvGcl zt2wtiblrVJ0_4I=ixLl3-bSz0r~3}oE$e4~Y^!YYEnmzNA5F0{(3z?(@~+&0iMmA{ zQ2V=X=2U*3{B_yc_3ZQ+G8_CuS?sB|bp+r5t1lrIg9~&Pd%iJRuQ;>UXjem@{~hLv znyKohW|MrO#>`KXz$t(T)Xh??Kzs z>>95J0WX@YG60r7fW_vKK#n3^r$#QeBjZGnPX%<;n5y5bN_V2PT=;56E3QcYk(pDBm{!(u^`s+8XTo1 z3qP1R?*I=1L%{4Rgu#HAk)kU(`Sety+_+$4tcnA!&up8tzi-X~y~Irp3@F9;1saqu z>&2-r0b>jZHO#8hA@613!-z4+DGs~{g~eHz2FT>rn>IKYh6pNCKMA+S)R3>M@)y(fFKpa*=D)BKZrqEfaP?HXJhsAZwj%G#vpY zK)l261TKmMGZ;v|SOJHrG#0EBS%Vy6lA7bjXwBV_1oI1SkzhoD#&Gb3oNrVc4T4MH zKnz^$Vk~w|0DXMtzF;a8_|qeBkr~+nwYaX!*^w&1X1sq{2%apr+CmAWdT4M)nGsyk zuEah=+USqd0|=>E(X?=SYZt5?G+hd z`eW5{kPaMXunl7kS3*GCx23@<4|o9Qv=S1PftzqdUJ*eGMo-^VfCVgKF@%JqCWJ#? zPhCbE67q}I0V2X4Px%8_>XWuTX6tX@5`oobiw!iSCGEgS&Ixv@$1)Pld_k@$K7)Xg zsIfBju((a^BfBCR5;r5(_{<;os`fW7j>@pqZoh`nve=8QJmSWH`ko-y(^;y!qOb7x z9$TwLZ7PQcvDKnOnJQ@72O$&4sQMqQ!T}_eR8a{lYRc5@L(zgDWEk3FiV0Okkw>F2 z2l5)>v$s34I|sKLDm0J>`T^vuj1#62p|zDrR5y|^&+~B;r?J1sTQcO93}7?6kwmM@oH}T8RTyKJ%<$e~13bH>#9I9eo5im!jrVYKLBnzbP|#x08i+z! z(#+VjUE*&Gkjf?_l>F%AAE)Z4-oBk3ZRIzgu~IN8JfcT$2R9DLN&1ZOllc1qIYl;1 zZ@2Lw(_Rlz-WNm5mDP=1~W$4~3qK<-t@1gmMT>usgBTnI|{TuQT z1zMs11P&776`{dkXk(3e*P4K(YLuu#n;Z*7%?yX$Ttg2-<1VE+PMZEFH#~WVT>Egg zROEpmOjIQusfn42h)1OvjCNpK{IT(NJq}6^^_^b%iiE{Ak{jDR{N+Mi{ zr7SLTjG2nJx5Ct>QCIQGzSMDSaqU#>oU0Onr@Qh`=51Yx9@&Jx720d6Gn5JzFYAUN zUzZymK7X;x1_y~ydk5n8b3VJ(@ndlXRGj#|-5JcR*r1aMB-%o6(nc{>nCW_L9NuIs z`G3ub|J{thH~W73pIU_f{s#KrlCTdC-h#-%soF4}feu!<8(mV{3I&$Uh`?Gn(H{~N zk9^DJszYRrz%T}aSkwjv4qEG8DKjxbNaC0niXy}V=mj>b`}$2*R&gRI3J8t6ftiD6 zqVEI4kE{GrVfd*rqd`sOoC8~;B}hqA<-nG4778BzXA?9qwF7*h_g3tHg0N+h1{e?t zC!l|(Oabug;Nnk1_F!jB6awP1ur!h0j2Ux4$g|rX>{cI(wAY9|00KO)O$k7g{<2JpK&+Xx&;b`?@9p;TOc6mi^;0a?Ar zfbq%=6_>m4O)|e(M%MvZQeDe5(7}jY;xYUViX5oOF|zkicnacRg})yubd$pTEFrtN zJx2C;7;HG_UK@_a!O-O0stMpfMOw1!##=y=_t>z?K1Ue@xdk_YAgd5q8R<(-FamtC zC<%-s?kEGlF-FA0>D!Tu{>>u1SIGi+6n5Gy{JFBk0|c+Y{HVi_LfK1F8xmwHRkA)} zImovJdV?B{)vS(=4&XoR+KBg@epH?K85wDBhB=4d@NkS&Pza+hM7EY`A_8)5j6f;7 z`sWAp?BM2prF38g2To`C3Ee){lNne7P0p$V^$7M@9bXVpOV@&!9rm|byJ|aa`Ak&Q zNUuQ&I0hI)d5$rFAdRIa8#jxBRb=G?1qMBBkcD~?N-8O`fYa^zSrVc7P%W-I+ukgF z6W`lUP$=0jjq+s`K+Zz>36TLX2V-%H;w%p2?k;H>t09j;oQ7J>b&j-|aKl@jS@OVx zm|sW>g!NtFmX$#{*xi1{4*|d$E>%RX{tm{!7>OKDb467Y=~Fz0u+sAwO&2m@(2E%c zQwPttLOF!ev^u!Lg!&Vo0WEFLoNXJ@EB6YWoP-hHN{SB>ns- zdj#x4@nsS^%;nfo*PwjN0|jqNW^bkwg7-2`m@S$FXZWDC*q<26v9mW*h@mKf-e(LZ z-t6L@C3ovjU)yzG(LZHbNjRL$f3C}#^4e=5YWt7f!9bhsI{hrv<$V%MJfV7|?u(mF zLRdH8y;uxb69gC@1P6z zR*b*_I2N!-1$2~wpn)~|#Zm?VU3R2+pBdU=&a+qiQ%7!dg~fQ2CH=!KSVO!^?-fWr z4WyCKKPb~_8wqGy7NrDkt>BH+Dw`hwA@*BJUmB?;e=t7riQDF`U&Q^9<#US>9ikpn zi8paF25eq?1Osd#YBst~QGyCX47hlG7_9#9_V(ww6PVyo%)wJ5X@%~6tQD7lZwGU5 z*iZRIr=@#BTw-K?X@cU=fYblg`zpoE*tu$6=opRXl7P=IO?J4);Y@HUJ<}C3LqEUL z`GW{er|J{U2WpaQLbAM8Kbz|`F>#VI*q9IGrtyr&53?W=G|+Q~AQ z@;!7N#gvDcf#7fX>bNaKf76**pPx~_RDT*mN6UsI?k~{vn9FgxPL}>SK_@R(s)$#e z$`eYT`{JI^YpmZ^?^AI_SRZ1sV=|see~s9!8ojxGZzuhHB=NY~?#_*4X3|}`XPKVj zIX_|%W+c>#W#)}YzHk4E zzb1!I@Ll`SFW)!lr`UCEgZ#7>{UI7ct-g-Wo%}JB)5&_#(Qd`IWz@XxxnUWUYE}A# zki!j%)&;sEn04cGOx;W(qg|vdTBq~khm6+R_9ASx(iuB@e1_8PiD(GV3t%p`&a!K~ z7^S(iX~=O^HrECn>E(9h-TM;l1d0XMq+Q}qjmn59=zWOx_LxU zEVVI~>n4Zv9EfaV%AezxI&+qs<~@*A+YJkj!!D3oElmR>#Y_;53(n&qg8|C-gOS31 zDQ7qL*TFTeau8tUD|3{bi5t)a1I+)YFWXYyLuO$nl+sN9`{v4FHUhF2$N{qCCX^1T znhB6}k_6~xS2>^)i}C-ZQivc?2F1wi@zSN}aCV{7nK!edYrr?wD2MVC*g+p~3w;DQ z?CkOJsV`Po?3aUxSJ$}#NLhh00@D$?NKjUjT?nc~CKJXFCsbud0KU=r&YJ+lT!Gt? znwNMK15uA7pF$({Tf-}mIUCOWETpjzLb#W}ksTODEd<^%*K}(Tn3_7h`u8PMj}>O< zx;AeZIG6-1vNTCh0Rl@C(8(c;30UIVI_YGJ38bs?u~nmDLoPz;h}3**7JwTT7$+xw zXl5MD`-oQ~0HbqY!cQH#%!v6YUX9fZb(WO`k&9AUGBW8)SsO6!yCEQ<(fg?pyRBui zB=$9Mf|YsoA` zbJ$kx{Nl4Ik;;J*jMr_QJp29#Qv2N!4Drx%<66l_;r8rMeSTtQRkz>#D=;t8&D>Q- zRLhr+?4nl_Wmlne8N*bcq8cT`W`W9*5)OiDEqe|je>^wdCjG8Km1v~o zR|z_$n=na}k=>5y1P!pdQxxxp*l_w!Ljsq8FUX9fX9$qFFOj=3!?qDtMj}pePELD( zj8$SYaDTmqPEuxpI|!XzF$=H>C0Ou$Y4_W;V$`|rHA$^3L$>snq|8qX3gMtyu?Ta) z%FAcr?;iuLbi1{0O!ZwSz&#~7E%}Ft7L|#d=2P>5(dEgfbR`|XYiuXOi}xiH*L4v^ zq0dCXN%xkCnlVM!&9}p_&K`$ykv+1l+ScwqZKy}TxVDnf zqu-2~z9{aqWkk_Tlr-;5MX4Z;KLPp6G83}Y+3DxG&VcB1Gt5N$@>%YJOms#W3d(f( zZXNzQf#i`uHyU(&F4NGZ%q80ci>fn^U^PQ?7|x*d4XIb64ZD(_CFCaaNdz)vkt)ts z*rrSU;}Lqb>G=dW|DTevYo9zyoFiC%rLce5bOpX@@u#Lv50e&V;E(B|h><@xyR)mC z`dky|a&q4YS#^6xP5P!S4~XoCXa!CPSfOJ=1>W+;!I2N8?%G>W-YQ>I&88J25=!`j zo@#ko_|(pXuevR_iK-Wz5Z9(3*SPurb^!S0{a4wWdzRos8T)!Ys=@_3tbVC9{U(Q9 zcmAuk-NNe8mYBiofKRlvjlw7ny$dzaKHCQz^JE_r{6zF*PbaD>vKAdD8FG8~JoDX! zF`A9=a%Xoz(>K0cuY^B)8SI`?fEijIwLd&12(^xPSI5r0rMY+ypB@{scE1f+tLm#T z)IHq%7Y`F)1)#xf@n%Dz^CdZD`AI>;ISbn?%UMNRRrn>M$7!Kr?(%eunm1N;_-k`= zHoeYyTQCeak7-6m9qsryG+F-Bj_LcD*DrFg9*N%(zetZ#G8Yb8NcWmtUtPrkOo$KS1Icr$(?wr>ucHgRYP0YWRYbz z=;uH<^AC^Kuyq$vzwP*;z=FpXk$b*d@6izt-$D*VkE}uJr%!_bcKgNPpJS@vDwbAE zbIf_seSL(0xvSf&Rm`l6ET0yd6j;DzIjV9#oJDntFl}cfA^lnjmGJlXmlJe?h@5FA!)!8w0-XFN^gD)mjJ8;kmRY zxkF2UUbGQ5z1a1GTi@-vEx?VXdBJqqs!E+q3J=>s@i*t>TJ;=Ab4kpOeExX0Fw!Uv ztC{rzes^n2e?CcVEI7W*anN1I973M?WQXd?C~%xbmgwxXkF0Dee?D*Rz{;4&+=1U& zv)Qh4baHX8_LWohNsCqZOWp9pMM1y^hwM%{L*-17l1kfEo#`QQtu5!n%-t$#hw#aQ zlN@#=^5V^oDYnGLhkqfwX)lY~G8MAkyGv>l?ebwE4KkgPqnfMf5Yg*Q%6s#q5;pj6nzv9MGz3$7~K#^ z8S)nZ?TURb6QJQ7NKu74^#Jm?ucoWppdW+1CAEQ6e6^M3_FB45XEb^3$0Q)Mc-2>Qt&pE6Org!acH}Pr7sGDQk`_nj(y0f*#MOVZ3*1Y78sVGTrzHxAsrvjEYMS}!L zFiEfEy2}B=I*kXIQ{@Vf($H$&p=s5+ba&8g0~!gsmap;t3!yrd{G~3z%~uUzV!Sr* z1LQu4_a4?kf)m0B5M+!9$W6a@zBARyfD)G|1R=~n!oV0ENW1Xr_CZR5RS|>)x3q$O zhUPlpQUm1eF1CKEv=a6yStfD04%}<;&TW8Rj${3B4OEuc^f%dbHA2-Ucr_kV|2YN2PK2d>cWL*Edm5kb3nEq z2t2Pv}1MwY|ddYGI zqoA;*DgZ@6TZU>z5QPi_?^_^LjF~b*bR=V&!^qAyx*>Ln$KV8rtEcE_8$;&OK{zIK zi_TM>I^G)`uw{T*kO~zi>9nE7e!iDl;1I?UPm|?Prw}#0w?JGvl#(1V9=f(N@NxzZ zgmCX2+^Ve#;|%$_IIMOd-r!`6y`>{`PqLwirz*WKVXn;b(fX1A`Ye z8>D5slc4ew`SifkuA_me-ephPQm)u{nMd{(@?Eum&a6D33felkigyfDx#2b#p_T^_ zTDSpZL|2egIc7gu$umT*-o$p$MD)RKcl@~V&YLjh!H}Ms*uFywkKIYTxUO@a-0iIF z?)I29JcnDUZIbYKD~Tol{F8~IqgK8(P_LBKC8OcT#qI@~l^Fzm@}y^})Qz#|qqzt- zb$YjD(lfljhDGFlZae8e9nRDk8vu)_&cL}14N2CLYA~#6oWYy zSs7Y8Vh%-tGs0~2UrnCOTM1v81wV|z|D@SD=g5f#@lsg~A;gZmPhb}S76A6ite0@) zH02ibmXi<()wVT?wy4ivH(#YiQ}hcNlMx+JGE?bx@gUjyUZWy(utO83_I5TwbywID zpy`5%qS+`UwG(O9OME7O4g^Q8@YA}VDrkpia^n)ogrwdrAX=ptjT|Za@l&OCDUcmt z{cl$%ewmrc`HB46;Oo0gT$o=-($TTI6V7_cXo_Kh=rWb|!ZpFxr^vFk>dymXdDdNW zi10#%FN>|zR=?A-ngQu^jR9r$##(;mxYOnNDpqF`DzVPeR>XScRAK7=1-IR-I%Jt+ z1ju(xo%)j4+AE2V@@&6M-by$a@9F+nCTR?5Lku5=III5ILTIY!={q~_AHIM3 zKNP2-*Y=~gyMH?FD?V@H(7)o3$hM?2k>NrIW={jssO6R}EGjsOCN)1j9zHS-9wytQ z8hR%^0hatChkEy5@ZXU_am|jLpY_S}vfxh~{R9g?+AN+2JX*X@qBq_EN5i#M2ZO)7 zz5KMrqb$pL#clnLi-os9CCZ@!dZ(ZDM4-fFHHc}t&)OWN2fTaTP40LcT4Aan0C&=s z0QvVbU6p?wQ&D{v->u<)9IBgsTeT<5oR{UYUpK$w*9|Mk_Bos1Jl2OHIg2ioDbao08R~d%20`dL$^-`KwVhIp z1UPF43g26iK+neh+AAsY`i+!1;V8|djUgL5p6;l&h-56u2)dyYx9(NSIu6(dhq;OC zgZI}se+cDFNNf|ydAwA=o9wc4K{K%GX+evXM6E0i$3?{5E2FlTJ#@BDf$H;6^BKI< zK>z~e_NpLr8J}CWwW5%?$v-9d^E8^ii2APr=bztG zlH^(^Ym3S)&!Nf{3B?kVYW_zKdArHcLjqHbU&#|fmdaY{?T0MDFzKuI5K*j6AX`Dt zazQYM3M3n3#r~?*zb$M*ldPXsff}&utAl^rjXkg)(d9As+}RV@`Z3nch3rEsZCUtC znMdtw!(J`B6Q2v}asvAz_R1nNiO<^Df_eg|NqbtM_G|4)Ki5#$eB8o3w{iiVssWQp z>uK=G9B=W3xM4oVa>XA>l;1-n0#zd3iUWxz zLU29H1NX7CD$FxO85k_0NL(&q3&1fMdaq(So$dw=v#%l6MV-U>0y1d zV7xE;*TuXzMISYqXazs3PUY47G$oruM~&T$ngb|n6cPQz;93Y5z>>VdR6aQ3EKkF~ zAZLP9zPk4k9_z%Gr;)-YTX5x%tkr;$Sxm9YPPPUmXkee}gOaQoHbEf4`g|FHxz z(Ii|zF)ZGRdHQ=UZPuFtW?Txn4eTL9ZJ2W@h1fdbDn)c)d8nhkeJKPTB0aH{QHL?m zKW&92SxM=K^EBjGc3O66W3L6}$8M4nZ%r%gO==uXgGs89Q+tR6ZB!exs2urPBt`#5 zdR=zlu$4|PPSC|g1y4?@z^IU9D4OKF-KOS6rBD5}wb1J~f@@AJ?wBo{HMtj#RB2yE z1dQh9RizwNqVJ6F#}Q{TUNf*bH7R=bK~yG|E=P9t{(kzNn#vyWt$oQbzb9Fr;ru&} zC+?sR=?g?xbz`HwRlfEe=0$9EsLX~cY;R4Bc-Zh2Dq zm2Z407@lg4uBoy6UFP09KdaZ>ZH+r89PX{r>tbFqQYX}fjd{s)8*yVI@rF$S@iZNJ zP-@HWCAtrzx1rBv1O-yK4E8uju|0q%CedsD-*q5=zqtRGyJhUZ9p=lvKRHYJFKx--b}PzZ9*91@~Xq1p84ad$;**^&yO=uNghk}f?J=?8>zhtq zET|0kaFEF?Mq(Pi&u|=j>-^WfTlZ5?zgyjDbiR&+;lBQrnYEj~)nv0?WE1ewCue@1 zf_YL*dT%*-P(9E-obsYmR@5rcc@a>~H*WMX^MsL5h z{TUDxTPW+z|1f!^7iMG~MkJibt6jU(TnK9rWdA03owBM^k+PNXbLdd-2n;@8&Nsz= zZMk!7E!$&C?3|9%RqPdKJ>7E~dHq}MZat57&%uQ$@XzhV z-LqXx=1*P^_TH&uzk#jFlD^}_ZwH^YO7RFe6z4dkssB0jk8P>f4DJa^l#&z@_t1gi z@#gY3Gec!Gtv1np{gL}1i&MaC+wHWQ-2pq>cwaLrOH7(sJb+gfJ$LSSn>8L%8ghv* zZET|9cOROth~wwPgYx>+_)b2B@j4@Jz+>EE=xm~k4ZcT9fwa>ZMyLE{mmuN6_&``52nK0yX?m%0ptFNm{_G#V!u zi-pxwWj{y$m{Pk#v4$^z)(&iedd6VY>mX|mi9920k2tr$CBC8RD{o_8c=?T2yh+%( z`ad0f;CinuC&5Wmy<06hq?$QNT+tr+O<>?kHTKQ>Up8CMoc!~$23K#NV!%E8hmZT` zp!}b&e@3tR7yACs>;HWF$MZM;vl^Ez`)f`^(+q!>)Lf<+o>h+|JU;QdF(V^mAm!U_ z>vom)w8(Ti-G%g%uMHh}7$<>V| zvi(&^`ZEf}Z3Fe2PAbWuOLQ;e-z{Qp>c&w!?~wP6&;VHiQhf}kVChDsL^ zkgh1ARB6%)Riqmb5JHHfA_@o!0!oX5fPjP&N@9Regh&@DflxvZEeQ}v2x;GTX3jY? zbI*Ivx!-&DpS4o<+G{^+J!L&rW1z9|L37U}TEJvexctSzS}}i7G6qy+9z7$+GZX43O6T_sd`5U*4>Ln%MAu0)gPxEG9`E10P%j39Qo>rcfekQ zm_Z;IqkPMPdhcFITK)CHWu?4ixRmC-FHl}DcSJ8FfEf`UUhAW-sw(rxGa83-|7m;v z(_^=0k8JFzc^SRy_rarX{ngdc_2{XT z8+gR65_xeTn|mzMgKe<^?3P=i{qM0RizG^5wLTis%2}JKA58|AOWJn)GkI z;cGs?B>s6l7?wV;>-($(j?|Ke>-&_)V9}+wzLzp?3>)cS%0DPgH#z;sT0h|XE68dt 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

    `(3c@)d?`pMNKuI;J{UG3x!l^nm45y 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 diff --git a/docs/my-website/release_notes/v1.81.0/index.md b/docs/my-website/release_notes/v1.81.0/index.md index e61d7d2d593..d69a62b6941 100644 --- a/docs/my-website/release_notes/v1.81.0/index.md +++ b/docs/my-website/release_notes/v1.81.0/index.md @@ -1,5 +1,5 @@ --- -title: "v1.81.0-stable - Claude Code - Web Search Across All Providers" +title: "v1.81.0 - Claude Code - Web Search Across All Providers" slug: "v1-81-0" date: 2026-01-18T10:00:00 authors: @@ -27,7 +27,7 @@ import TabItem from '@theme/TabItem'; docker run \ -e STORE_MODEL_IN_DB=True \ -p 4000:4000 \ -docker.litellm.ai/berriai/litellm:v1.81.0-stable +docker.litellm.ai/berriai/litellm:v1.81.0.rc.1 ``` diff --git a/docs/my-website/release_notes/v1.81.3-stable/index.md b/docs/my-website/release_notes/v1.81.3-stable/index.md deleted file mode 100644 index 22b6f43deef..00000000000 --- a/docs/my-website/release_notes/v1.81.3-stable/index.md +++ /dev/null @@ -1,423 +0,0 @@ ---- -title: "v1.81.3-stable - Performance - 25% CPU Usage Reduction" -slug: "v1-81-3" -date: 2026-01-26T10:00:00 -authors: - - name: Krrish Dholakia - title: CEO, LiteLLM - url: https://www.linkedin.com/in/krish-d/ - image_url: https://pbs.twimg.com/profile_images/1298587542745358340/DZv3Oj-h_400x400.jpg - - name: Ishaan Jaff - title: CTO, LiteLLM - url: https://www.linkedin.com/in/reffajnaahsi/ - image_url: https://pbs.twimg.com/profile_images/1613813310264340481/lz54oEiB_400x400.jpg -hide_table_of_contents: false ---- - -import Image from '@theme/IdealImage'; -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - -## Deploy this version - - - - -``` showLineNumbers title="docker run litellm" -docker run \ --e STORE_MODEL_IN_DB=True \ --p 4000:4000 \ -docker.litellm.ai/berriai/litellm:v1.81.3.rc.2 -``` - - - - - -``` showLineNumbers title="pip install litellm" -pip install litellm==1.81.3.rc.2 -``` - - - - ---- - -## New Models / Updated Models - -### New Model Support - -| Provider | Model | Context Window | Input ($/1M tokens) | Output ($/1M tokens) | Deprecation Date | -| -------- | ----- | -------------- | ------------------- | -------------------- | ---------------- | -| OpenAI | `gpt-audio`, `gpt-audio-2025-08-28` | 128K | $32/1M audio tokens, $2.5/1M text tokens | $64/1M audio tokens, $10/1M text tokens | - | -| OpenAI | `gpt-audio-mini`, `gpt-audio-mini-2025-08-28` | 128K | $10/1M audio tokens, $0.6/1M text tokens | $20/1M audio tokens, $2.4/1M text tokens | - | -| Deepinfra, Vertex AI, Google AI Studio, OpenRouter, Vercel AI Gateway | `gemini-2.0-flash-001`, `gemini-2.0-flash` | - | - | - | 2026-03-31 | -| Groq | `openai/gpt-oss-120b` | 131K | 0.075/1M cache read | 0.6/1M output tokens | - | -| Groq | `groq/openai/gpt-oss-20b` | 131K | 0.0375/1M cache read, $0.075/1M text tokens | 0.3/1M output tokens | - | -| Vertex AI | `gemini-2.5-computer-use-preview-10-2025` | 128K | $1.25 | $10 | - | -| Azure AI | `claude-haiku-4-5` | $1.25/1M cache read, $2/1M cache read above 1 hr, $0.1/1M text tokens | $5/1M output tokens | - | -| Azure AI | `claude-sonnet-4-5` | $3.75/1M cache read, $6/1M cache read above 1 hr, $3/1M text tokens | $15/1M output tokens | - | -| Azure AI | `claude-opus-4-5` | $6.25/1M cache read, $10/1M cache read above 1 hr, $0.5/1M text tokens | $25/1M output tokens | - | -| Azure AI | `claude-opus-4-1` | $18.75/1M cache read, $30/1M cache read above 1 hr, $1.5/1M text tokens | $75/1M output tokens | - | - -### Features - -- **[OpenAI](../../docs/providers/openai)** - - Add gpt-audio and gpt-audio-mini models to pricing - [PR #19509](https://github.com/BerriAI/litellm/pull/19509) - - correct audio token costs for gpt-4o-audio-preview models - [PR #19500](https://github.com/BerriAI/litellm/pull/19500) - - Limit stop sequence as per openai spec (ensures JetBrains IDE compatibility) - [PR #19562](https://github.com/BerriAI/litellm/pull/19562) - -- **[VertexAI](../../docs/providers/vertex)** - - Docs - Google Workload Identity Federation (WIF) support - [PR #19320](https://github.com/BerriAI/litellm/pull/19320) - -- **[Agentcore](../../docs/providers/bedrock_agentcore)** - - Fixes streaming issues with AWS Bedrock AgentCore where responses would stop after the first chunk, particularly affecting OAuth-enabled agents - [PR #17141](https://github.com/BerriAI/litellm/pull/17141) - -- **[Chatgpt](../../docs/providers/chatgpt)** - - Adds support for calling chatgpt subscription via LiteLLM - [PR #19030](https://github.com/BerriAI/litellm/pull/19030) - - Adds responses API bridge support for chatgpt subscription provider - [PR #19030](https://github.com/BerriAI/litellm/pull/19030) - -- **[Bedrock](../../docs/providers/bedrock)** - - support for output format for bedrock invoke via v1/messages - [PR #19560](https://github.com/BerriAI/litellm/pull/19560) - -- **[Azure](../../docs/providers/azure/azure)** - - Add support for Azure OpenAI v1 API - [PR #19313](https://github.com/BerriAI/litellm/pull/19313) - - preserve content_policy_violation details for images (#19328) - [PR #19372](https://github.com/BerriAI/litellm/pull/19372) - - Support OpenAI-format nested tool definitions for Responses API - [PR #19526](https://github.com/BerriAI/litellm/pull/19526) - -- **Gemini([Vertex AI](../../docs/providers/vertex), [Google AI Studio](../../docs/providers/gemini))** - - use responseJsonSchema for Gemini 2.0+ models - [PR #19314](https://github.com/BerriAI/litellm/pull/19314) - -- **[Volcengine](../../docs/providers/volcano)** - - Support Volcengine responses api - [PR #18508](https://github.com/BerriAI/litellm/pull/18508) - -- **[Anthropic](../../docs/providers/anthropic)** - - Add Support for calling Claude Code Max subscriptions via LiteLLM - [PR #19453](https://github.com/BerriAI/litellm/pull/19453) - - Add Structured output for /v1/messages with Anthropic API, Azure Anthropic API, Bedrock Converse - [PR #19545](https://github.com/BerriAI/litellm/pull/19545) - -- **[Brave Search](../../docs/search/brave)** - - New Search provider - [PR #19433](https://github.com/BerriAI/litellm/pull/19433) - -- **Sarvam ai** - - Add support for new sarvam models - [PR #19479](https://github.com/BerriAI/litellm/pull/19479) - -- **[GMI](../../docs/providers/gmi)** - - add GMI Cloud provider support - [PR #19376](https://github.com/BerriAI/litellm/pull/19376) - - -### Bug Fixes - -- **[Anthropic](../../docs/providers/anthropic)** - - Fix anthropic-beta sent client side being overridden instead of appended to - [PR #19343](https://github.com/BerriAI/litellm/pull/19343) - - Filter out unsupported fields from JSON schema for Anthropic's output_format API - [PR #19482](https://github.com/BerriAI/litellm/pull/19482) - -- **[Bedrock](../../docs/providers/bedrock)** - - Expose stability models via /image_edits endpoint and ensure proper request transformation - [PR #19323](https://github.com/BerriAI/litellm/pull/19323) - - Claude Code x Bedrock Invoke fails with advanced-tool-use-2025-11-20 - [PR #19373](https://github.com/BerriAI/litellm/pull/19373) - - deduplicate tool calls in assistant history - [PR #19324](https://github.com/BerriAI/litellm/pull/19324) - - fix: correct us.anthropic.claude-opus-4-5 In-region pricing - [PR #19310](https://github.com/BerriAI/litellm/pull/19310) - - Fix request validation errors when using Claude 4 via bedrock invoke - [PR #19381](https://github.com/BerriAI/litellm/pull/19381) - - Handle thinking with tool calls for Claude 4 models - [PR #19506](https://github.com/BerriAI/litellm/pull/19506) - - correct streaming choice index for tool calls - [PR #19506](https://github.com/BerriAI/litellm/pull/19506) - -- **[Ollama](../../docs/providers/ollama)** - - Fix tool call errors due with improved message extraction - [PR #19369](https://github.com/BerriAI/litellm/pull/19369) - -- **[VertexAI](../../docs/providers/vertex)** - - Removed optional vertex_count_tokens_location param before request is sent to vertex - [PR #19359](https://github.com/BerriAI/litellm/pull/19359) - -- **Gemini([Vertex AI](../../docs/providers/vertex), [Google AI Studio](../../docs/providers/gemini))** - - Supports setting media_resolution and fps parameters on each video file, when using Gemini video understanding - [PR #19273](https://github.com/BerriAI/litellm/pull/19273) - - handle reasoning_effort as dict from OpenAI Agents SDK - [PR #19419](https://github.com/BerriAI/litellm/pull/19419) - - add file content support in tool results - [PR #19416](https://github.com/BerriAI/litellm/pull/19416) - -- **[Azure](../../docs/providers/azure_ai)** - - Fix Azure AI costs for Anthropic models - [PR #19530](https://github.com/BerriAI/litellm/pull/19530) - -- **[Giga Chat](../../docs/providers/gigachat)** - - Add tool choice mapping - [PR #19645](https://github.com/BerriAI/litellm/pull/19645) ---- - -## AI API Endpoints (LLMs, MCP, Agents) - -### Features - -- **[Files API](../../docs/files_endpoints)** - - Add managed files support when load_balancing is True - [PR #19338](https://github.com/BerriAI/litellm/pull/19338) - -- **[Claude Plugin Marketplace](../../docs/tutorials/claude_code_plugin_marketplace)** - - Add self hosted Claude Code Plugin Marketplace - [PR #19378](https://github.com/BerriAI/litellm/pull/19378) - -- **[MCP](../../docs/mcp)** - - Add MCP Protocol version 2025-11-25 support - [PR #19379](https://github.com/BerriAI/litellm/pull/19379) - - Log MCP tool calls and list tools in the LiteLLM Spend Logs table for easier debugging - [PR #19469](https://github.com/BerriAI/litellm/pull/19469) - -- **[Vertex AI](../../docs/providers/vertex)** - - Ensure only anthropic betas are forwarded down to LLM API (by default) - [PR #19542](https://github.com/BerriAI/litellm/pull/19542) - - Allow overriding to support forwarding incoming headers are forwarded down to target - [PR #19524](https://github.com/BerriAI/litellm/pull/19524) - -- **[Chat/Completions](../../docs/completion/input)** - - Add MCP tools response to chat completions - [PR #19552](https://github.com/BerriAI/litellm/pull/19552) - - Add custom vertex ai finish reasons to the output - [PR #19558](https://github.com/BerriAI/litellm/pull/19558) - - Return MCP execution in /chat/completions before model output during streaming - [PR #19623](https://github.com/BerriAI/litellm/pull/19623) - -### Bugs - -- **[Responses API](../../docs/response_api)** - - Fix duplicate messages during MCP streaming tool execution - [PR #19317](https://github.com/BerriAI/litellm/pull/19317) - - Fix pickle error when using OpenAI's Responses API with stream=True and tool_choice of type allowed_tools (an OpenAI-native parameter) - [PR #17205](https://github.com/BerriAI/litellm/pull/17205) - - stream tool call events for non-openai models - [PR #19368](https://github.com/BerriAI/litellm/pull/19368) - - preserve tool output ordering for gemini in responses bridge - [PR #19360](https://github.com/BerriAI/litellm/pull/19360) - - Add ID caching to prevent ID mismatch text-start and text-delta - [PR #19390](https://github.com/BerriAI/litellm/pull/19390) - - Include output_item, reasoning_summary_Text_done and reasoning_summary_part_done events for non-openai models - [PR #19472](https://github.com/BerriAI/litellm/pull/19472) - -- **[Chat/Completions](../../docs/completion/input)** - - fix: drop_params not dropping prompt_cache_key for non-OpenAI providers - [PR #19346](https://github.com/BerriAI/litellm/pull/19346) - -- **[Realtime API](../../docs/realtime)** - - disable SSL for ws:// WebSocket connections - [PR #19345](https://github.com/BerriAI/litellm/pull/19345) - -- **[Generate Content](../../docs/generateContent)** - - Log actual user input when google genai/vertex endpoints are called client-side - [PR #19156](https://github.com/BerriAI/litellm/pull/19156) - -- **[/messages/count_tokens Anthropic Token Counting](../../docs/anthropic_count_tokens)** - - ensure it works for Anthropic, Azure AI Anthropic on AI Gateway - [PR #19432](https://github.com/BerriAI/litellm/pull/19432) - -- **[MCP](../../docs/mcp)** - - forward static_headers to MCP servers - [PR #19366](https://github.com/BerriAI/litellm/pull/19366) - -- **[Batch API](../../docs/batches)** - - Fix: generation config empty for batch - [PR #19556](https://github.com/BerriAI/litellm/pull/19556) - -- **[Pass Through Endpoints](../../docs/proxy/pass_through)** - - Always reupdate registry - [PR #19420](https://github.com/BerriAI/litellm/pull/19420) ---- - -## Management Endpoints / UI - -### Features - -- **Cost Estimator** - - Fix model dropdown - [PR #19529](https://github.com/BerriAI/litellm/pull/19529) - -- **Claude Code Plugins** - - Allow Adding Claude Code Plugins via UI - [PR #19387](https://github.com/BerriAI/litellm/pull/19387) - -- **Guardrails** - - New Policy management UI - [PR #19668](https://github.com/BerriAI/litellm/pull/19668) - - Allow adding policies on Keys/Teams + Viewing on Info panels - [PR #19688](https://github.com/BerriAI/litellm/pull/19688) - -- **General** - - respects custom authentication header override - [PR #19276](https://github.com/BerriAI/litellm/pull/19276) - -- **Playground** - - Button to Fill Custom API Base - [PR #19440](https://github.com/BerriAI/litellm/pull/19440) - - display mcp output on the play ground - [PR #19553](https://github.com/BerriAI/litellm/pull/19553) - -- **Models** - - Paginate /v2/models/info - [PR #19521](https://github.com/BerriAI/litellm/pull/19521) - - All Model Tab Pagination - [PR #19525](https://github.com/BerriAI/litellm/pull/19525) - - Adding Optional scope Param to /models - [PR #19539](https://github.com/BerriAI/litellm/pull/19539) - - Model Search - [PR #19622](https://github.com/BerriAI/litellm/pull/19622) - - Filter by Model ID and Team ID - [PR #19713](https://github.com/BerriAI/litellm/pull/19713) - -- **MCP Servers** - - MCP Tools Tab Resetting to Overview - [PR #19468](https://github.com/BerriAI/litellm/pull/19468) - -- **Organizations** - - Prevent org admin from creating a new user with proxy_admin permissions - [PR #19296](https://github.com/BerriAI/litellm/pull/19296) - - Edit Page: Reusable Model Select - [PR #19601](https://github.com/BerriAI/litellm/pull/19601) - -- **Teams** - - Reusable Model Select - [PR #19543](https://github.com/BerriAI/litellm/pull/19543) - - [Fix] Team Update with Organization having All Proxy Models - [PR #19604](https://github.com/BerriAI/litellm/pull/19604) - -- **Logs** - - Include tool arguments in spend logs table - [PR #19640](https://github.com/BerriAI/litellm/pull/19640) - -- **Fallbacks / Loadbalancing** - - New fallbacks modal - [PR #19673](https://github.com/BerriAI/litellm/pull/19673) - - Set fallbacks/loadbalancing by team/key - [PR #19686](https://github.com/BerriAI/litellm/pull/19686) - -### Bugs - -- **Playground** - - increase model selector width in playground Compare view - [PR #19423](https://github.com/BerriAI/litellm/pull/19423) - -- **Virtual Keys** - - Sorting Shows Incorrect Entries - [PR #19534](https://github.com/BerriAI/litellm/pull/19534) - -- **General** - - UI 404 error when SERVER_ROOT_PATH is set - [PR #19467](https://github.com/BerriAI/litellm/pull/19467) - - Redirect to ui/login on expired JWT - [PR #19687](https://github.com/BerriAI/litellm/pull/19687) - -- **SSO** - - Fix SSO user roles not updating for existing users - [PR #19621](https://github.com/BerriAI/litellm/pull/19621) - -- **Guardrails** - - ensure guardrail patterns persist on edit and mode toggle - [PR #19265](https://github.com/BerriAI/litellm/pull/19265) ---- - -## AI Integrations - -### Logging - -- **General Logging** - - prevent printing duplicate StandardLoggingPayload logs - [PR #19325](https://github.com/BerriAI/litellm/pull/19325) - - Fix: log duplication when json_logs is enabled - [PR #19705](https://github.com/BerriAI/litellm/pull/19705) -- **Langfuse OTEL** - - ignore service logs and fix callback shadowing - [PR #19298](https://github.com/BerriAI/litellm/pull/19298) -- **Langfuse** - - Send litellm_trace_id - [PR #19528](https://github.com/BerriAI/litellm/pull/19528) - - Add Langfuse mock mode for testing without API calls - [PR #19676](https://github.com/BerriAI/litellm/pull/19676) -- **GCS Bucket** - - prevent unbounded queue growth due to slow API calls - [PR #19297](https://github.com/BerriAI/litellm/pull/19297) - - Add GCS mock mode for testing without API calls - [PR #19683](https://github.com/BerriAI/litellm/pull/19683) -- **Responses API Logging** - - Fix pydantic serialization error - [PR #19486](https://github.com/BerriAI/litellm/pull/19486) -- **Arize Phoenix** - - add openinference span kinds to arize phoenix - [PR #19267](https://github.com/BerriAI/litellm/pull/19267) -- **Prometheus** - - Added new prometheus metrics for user count and team count - [PR #19520](https://github.com/BerriAI/litellm/pull/19520) - -### Guardrails - -- **Bedrock Guardrails** - - Ensure post_call guardrail checks input+output - [PR #19151](https://github.com/BerriAI/litellm/pull/19151) -- **Prompt Security** - - fixing prompt-security's guardrail implementation - [PR #19374](https://github.com/BerriAI/litellm/pull/19374) -- **Presidio** - - Fixes crash in Presidio Guardrail when running in background threads (logging_hook) - [PR #19714](https://github.com/BerriAI/litellm/pull/19714) -- **Pillar Security** - - Migrate Pillar Security to Generic Guardrail API - [PR #19364](https://github.com/BerriAI/litellm/pull/19364) -- **Policy Engine** - - New LiteLLM Policy engine - create policies to manage guardrails, conditions - permissions per Key, Team - [PR #19612](https://github.com/BerriAI/litellm/pull/19612) -- **General** - - add case-insensitive support for guardrail mode and actions - [PR #19480](https://github.com/BerriAI/litellm/pull/19480) - -### Prompt Management - -- **General** - - fix prompt info lookup and delete using correct IDs - [PR #19358](https://github.com/BerriAI/litellm/pull/19358) - -### Secret Manager - -- **AWS Secret Manager** - - ensure auto-rotation updates existing AWS secret instead of creating new one - [PR #19455](https://github.com/BerriAI/litellm/pull/19455) -- **Hashicorp Vault** - - Ensure key rotations work with Vault - [PR #19634](https://github.com/BerriAI/litellm/pull/19634) - ---- - -## Spend Tracking, Budgets and Rate Limiting - -- **Pricing Updates** - - Add openai/dall-e base pricing entries - [PR #19133](https://github.com/BerriAI/litellm/pull/19133) - - Add `input_cost_per_video_per_second` in ModelInfoBase - [PR #19398](https://github.com/BerriAI/litellm/pull/19398) - ---- - -## Performance / Loadbalancing / Reliability improvements - - -- **General** - - Fix date overflow/division by zero in proxy utils - [PR #19527](https://github.com/BerriAI/litellm/pull/19527) - - Fix in-flight request termination on SIGTERM when health-check runs in a separate process - [PR #19427](https://github.com/BerriAI/litellm/pull/19427) - - Fix Pass through routes to work with server root path - [PR #19383](https://github.com/BerriAI/litellm/pull/19383) - - Fix logging error for stop iteration - [PR #19649](https://github.com/BerriAI/litellm/pull/19649) - - prevent retrying 4xx client errors - [PR #19275](https://github.com/BerriAI/litellm/pull/19275) - - add better error handling for misconfig on health check - [PR #19441](https://github.com/BerriAI/litellm/pull/19441) - -- **Router** - - Fix Azure RPM calculation formula - [PR #19513](https://github.com/BerriAI/litellm/pull/19513) - - Persist scheduler request queue to redis - [PR #19304](https://github.com/BerriAI/litellm/pull/19304) - - pass search_tools to Router during DB-triggered initialization - [PR #19388](https://github.com/BerriAI/litellm/pull/19388) - - Fixed PromptCachingCache to correctly handle messages where cache_control is a sibling key of string content - [PR #19266](https://github.com/BerriAI/litellm/pull/19266) - -- **Memory Leaks/OOM** - - prevent OOM with nested $defs in tool schemas - [PR #19112](https://github.com/BerriAI/litellm/pull/19112) - - fix: HTTP client memory leaks in Presidio, OpenAI, and Gemini - [PR #19190](https://github.com/BerriAI/litellm/pull/19190) - -- **Non root** - - fix logfile and pidfile of supervisor for non root environment - [PR #17267](https://github.com/BerriAI/litellm/pull/17267) - - resolve Read-only file system error in non-root images - [PR #19449](https://github.com/BerriAI/litellm/pull/19449) - -- **Dockerfile** - - Redis Semantic Caching - add missing redisvl dependency to requirements.txt - [PR #19417](https://github.com/BerriAI/litellm/pull/19417) - - Bump OTEL versions to support a2a dependency - resolves modulenotfounderror for Microsoft Agents by @Harshit28j in #18991 - -- **DB** - - Handle PostgreSQL cached plan errors during rolling deployments - [PR #19424](https://github.com/BerriAI/litellm/pull/19424) - -- **Timeouts** - - Fix: total timeout is not respected - [PR #19389](https://github.com/BerriAI/litellm/pull/19389) - -- **SDK** - - Field-Existence Checks to Type Classes to Prevent Attribute Errors - [PR #18321](https://github.com/BerriAI/litellm/pull/18321) - - add google-cloud-aiplatform as optional dependency with clear error message - [PR #19437](https://github.com/BerriAI/litellm/pull/19437) - - Make grpc dependency optional - [PR #19447](https://github.com/BerriAI/litellm/pull/19447) - - Add support for retry policies - [PR #19645](https://github.com/BerriAI/litellm/pull/19645) - -- **Performance** - - Cut chat_completion latency by ~21% by reducing pre-call processing time - [PR #19535](https://github.com/BerriAI/litellm/pull/19535) - - Optimize strip_trailing_slash with O(1) index check - [PR #19679](https://github.com/BerriAI/litellm/pull/19679) - - Optimize use_custom_pricing_for_model with set intersection - [PR #19677](https://github.com/BerriAI/litellm/pull/19677) - - perf: skip pattern_router.route() for non-wildcard models - [PR #19664](https://github.com/BerriAI/litellm/pull/19664) - - perf: Add LRU caching to get_model_info for faster cost lookups - [PR #19606](https://github.com/BerriAI/litellm/pull/19606) - ---- - -## General Proxy Improvements - -### Doc Improvements - - new tutorial for adding MCPs to Cursor via LiteLLM - [PR #19317](https://github.com/BerriAI/litellm/pull/19317) - - fix vertex_region to vertex_location in Vertex AI pass-through docs - [PR #19380](https://github.com/BerriAI/litellm/pull/19380) - - clarify Gemini and Vertex AI model prefix in json file - [PR #19443](https://github.com/BerriAI/litellm/pull/19443) - - update Claude Code integration guides - [PR #19415](https://github.com/BerriAI/litellm/pull/19415) - - adjust opencode tutorial - [PR #19605](https://github.com/BerriAI/litellm/pull/19605) - - add spend-queue-troubleshooting docs - [PR #19659](https://github.com/BerriAI/litellm/pull/19659) - - docs: add litellm-enterprise requirement for managed files - [PR #19689](https://github.com/BerriAI/litellm/pull/19689) - -### Helm - - Add support for keda in helm chart - [PR #19337](https://github.com/BerriAI/litellm/pull/19337) - - sync Helm chart version with LiteLLM release version - [PR #19438](https://github.com/BerriAI/litellm/pull/19438) - - Enable PreStop hook configuration in values.yaml - [PR #19613](https://github.com/BerriAI/litellm/pull/19613) - -### General - - Add health check scripts and parallel execution support - [PR #19295](https://github.com/BerriAI/litellm/pull/19295) - - ---- - -## New Contributors - - -* @dushyantzz made their first contribution in [PR #19158](https://github.com/BerriAI/litellm/pull/19158) -* @obod-mpw made their first contribution in [PR #19133](https://github.com/BerriAI/litellm/pull/19133) -* @msexxeta made their first contribution in [PR #19030](https://github.com/BerriAI/litellm/pull/19030) -* @rsicart made their first contribution in [PR #19337](https://github.com/BerriAI/litellm/pull/19337) -* @cluebbehusen made their first contribution in [PR #19311](https://github.com/BerriAI/litellm/pull/19311) -* @Lucky-Lodhi2004 made their first contribution in [PR #19315](https://github.com/BerriAI/litellm/pull/19315) -* @binbandit made their first contribution in [PR #19324](https://github.com/BerriAI/litellm/pull/19324) -* @flex-myeonghyeon made their first contribution in [PR #19381](https://github.com/BerriAI/litellm/pull/19381) -* @Lrakotoson made their first contribution in [PR #18321](https://github.com/BerriAI/litellm/pull/18321) -* @bensi94 made their first contribution in [PR #18787](https://github.com/BerriAI/litellm/pull/18787) -* @victorigualada made their first contribution in [PR #19368](https://github.com/BerriAI/litellm/pull/19368) -* @VedantMadane made their first contribution in #19266 -* @stiyyagura0901 made their first contribution in #19276 -* @kamilio made their first contribution in [PR #19447](https://github.com/BerriAI/litellm/pull/19447) -* @jonathansampson made their first contribution in [PR #19433](https://github.com/BerriAI/litellm/pull/19433) -* @rynecarbone made their first contribution in [PR #19416](https://github.com/BerriAI/litellm/pull/19416) -* @jayy-77 made their first contribution in #19366 -* @davida-ps made their first contribution in [PR #19374](https://github.com/BerriAI/litellm/pull/19374) -* @joaodinissf made their first contribution in [PR #19506](https://github.com/BerriAI/litellm/pull/19506) -* @ecao310 made their first contribution in [PR #19520](https://github.com/BerriAI/litellm/pull/19520) -* @mpcusack-altos made their first contribution in [PR #19577](https://github.com/BerriAI/litellm/pull/19577) -* @milan-berri made their first contribution in [PR #19602](https://github.com/BerriAI/litellm/pull/19602) -* @xqe2011 made their first contribution in #19621 - ---- - -## Full Changelog - -**[View complete changelog on GitHub](https://github.com/BerriAI/litellm/releases/tag/v1.81.3.rc)** diff --git a/docs/my-website/sidebars.js b/docs/my-website/sidebars.js index 4cc46f97727..a72f295c597 100644 --- a/docs/my-website/sidebars.js +++ b/docs/my-website/sidebars.js @@ -274,19 +274,11 @@ const sidebars = { "proxy/custom_sso", "proxy/ai_hub", "proxy/model_compare_ui", + "proxy/public_teams", + "proxy/self_serve", + "proxy/ui/bulk_edit_users", "proxy/ui_credentials", "tutorials/scim_litellm", - { - type: "category", - label: "UI User/Team Management", - items: [ - "proxy/access_control", - "proxy/public_teams", - "proxy/self_serve", - "proxy/ui/bulk_edit_users", - "proxy/ui/page_visibility", - ] - }, { type: "category", label: "UI Usage Tracking", @@ -372,7 +364,6 @@ const sidebars = { label: "Load Balancing, Routing, Fallbacks", href: "https://docs.litellm.ai/docs/routing-load-balancing", }, - "traffic_mirroring", { type: "category", label: "Logging, Alerting, Metrics", @@ -784,7 +775,6 @@ const sidebars = { "providers/oci", "providers/ollama", "providers/openrouter", - "providers/sarvam", "providers/ovhcloud", "providers/perplexity", "providers/petals", @@ -853,7 +843,6 @@ const sidebars = { "completion/image_generation_chat", "completion/json_mode", "completion/knowledgebase", - "providers/anthropic_tool_search", "guides/code_interpreter", "completion/message_trimming", "completion/model_alias", @@ -890,7 +879,6 @@ const sidebars = { "scheduler", "proxy/auto_routing", "proxy/load_balancing", - "proxy/keys_teams_router_settings", "proxy/provider_budget_routing", "proxy/reliability", "proxy/fallback_management", diff --git a/enterprise/litellm_enterprise/proxy/auth/route_checks.py b/enterprise/litellm_enterprise/proxy/auth/route_checks.py index 6f7cf9143f4..6cce781faf3 100644 --- a/enterprise/litellm_enterprise/proxy/auth/route_checks.py +++ b/enterprise/litellm_enterprise/proxy/auth/route_checks.py @@ -36,7 +36,7 @@ def is_management_routes_disabled() -> bool: if not premium_user: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail=f"🚨🚨🚨 DISABLING ADMIN ENDPOINTS is an Enterprise feature\n🚨 {CommonProxyErrors.not_premium_user.value}", + detail=f"🚨🚨🚨 DISABLING LLM API ENDPOINTS is an Enterprise feature\n🚨 {CommonProxyErrors.not_premium_user.value}", ) return get_secret_bool("DISABLE_ADMIN_ENDPOINTS") is True diff --git a/enterprise/litellm_enterprise/proxy/hooks/managed_files.py b/enterprise/litellm_enterprise/proxy/hooks/managed_files.py index dd0613f87ff..445d2b242b4 100644 --- a/enterprise/litellm_enterprise/proxy/hooks/managed_files.py +++ b/enterprise/litellm_enterprise/proxy/hooks/managed_files.py @@ -244,78 +244,6 @@ async def can_user_call_unified_object_id( return managed_object.created_by == user_id return True # don't raise error if managed object is not found - async def list_user_batches( - self, - user_api_key_dict: UserAPIKeyAuth, - limit: Optional[int] = None, - after: Optional[str] = None, - provider: Optional[str] = None, - target_model_names: Optional[str] = None, - llm_router: Optional[Router] = None, - ) -> Dict[str, Any]: - # Provider filtering is not supported for managed batches - # This is because the encoded object ids stored in the managed objects table do not contain the provider information - # To support provider filtering, we would need to store the provider information in the encoded object ids - if provider: - raise Exception( - "Filtering by 'provider' is not supported when using managed batches." - ) - - # Model name filtering is not supported for managed batches - # This is because the encoded object ids stored in the managed objects table do not contain the model name - # A hash of the model name + litellm_params for the model name is encoded as the model id. This is not sufficient to reliably map the target model names to the model ids. - if target_model_names: - raise Exception( - "Filtering by 'target_model_names' is not supported when using managed batches." - ) - - where_clause: Dict[str, Any] = {"file_purpose": "batch"} - - # Filter by user who created the batch - if user_api_key_dict.user_id: - where_clause["created_by"] = user_api_key_dict.user_id - - if after: - where_clause["id"] = {"gt": after} - - # Fetch more than needed to allow for post-fetch filtering - fetch_limit = limit or 20 - if target_model_names: - # Fetch extra to account for filtering - fetch_limit = max(fetch_limit * 3, 100) - - batches = await self.prisma_client.db.litellm_managedobjecttable.find_many( - where=where_clause, - take=fetch_limit, - order={"created_at": "desc"}, - ) - - batch_objects: List[LiteLLMBatch] = [] - for batch in batches: - try: - # Stop once we have enough after filtering - if len(batch_objects) >= (limit or 20): - break - - batch_data = json.loads(batch.file_object) if isinstance(batch.file_object, str) else batch.file_object - batch_obj = LiteLLMBatch(**batch_data) - batch_obj.id = batch.unified_object_id - batch_objects.append(batch_obj) - - except Exception as e: - verbose_logger.warning( - f"Failed to parse batch object {batch.unified_object_id}: {e}" - ) - continue - - return { - "object": "list", - "data": batch_objects, - "first_id": batch_objects[0].id if batch_objects else None, - "last_id": batch_objects[-1].id if batch_objects else None, - "has_more": len(batch_objects) == (limit or 20), - } - async def get_user_created_file_ids( self, user_api_key_dict: UserAPIKeyAuth, model_object_ids: List[str] ) -> List[OpenAIFileObject]: @@ -745,7 +673,6 @@ async def return_unified_file_id( bytes=file_objects[0].bytes, filename=file_objects[0].filename, status="uploaded", - expires_at=file_objects[0].expires_at, ) return response diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.4.27-py3-none-any.whl b/litellm-proxy-extras/dist/litellm_proxy_extras-0.4.27-py3-none-any.whl deleted file mode 100644 index f1dc450a0fc47e58436c5f40a1679a82d6ab5bc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50073 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 Le4CJXUi|fc(Nseq diff --git a/litellm-proxy-extras/dist/litellm_proxy_extras-0.4.27.tar.gz b/litellm-proxy-extras/dist/litellm_proxy_extras-0.4.27.tar.gz deleted file mode 100644 index 742b129eaa8b36f33a67d96b200588c819402cde..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23269 zcmX7vbyQT}*TzXnLApa)>FzG+ZUpHL0cjXgLPEMrN;;)s=_hbf6&3FFhX6R*d006*I+?n8lyGQlrum#hs|IY+ur1Rcf4YHkke7_HC)`%1jdJQ-KPCBV1!uwO0H~ zQ(oBhkJcsM)nk$gazeKy0G;)6h>k#%z@=^Tgwvf^-P|;JtCU@f`)4%)-12t)SVe|( zmtxlLTiad=9uk`%`J(-yDu-9!JE4J1=j`s*F8aCd5R&C~OI!hu$6Ye!bfI>->!|&W z#BjVY^&W5>%aVKNhdMa!A8Uq$d6d66Z-=T0wqu}IxQ8y=bR+#aJ>z8fU(-6|0wO%k zg%>N|yc=}c!FxKD8EQ4eBq5iwd7cyr}*F!^~CQMZ&E+hO{MD~#l?fY-=+^9CC1 zWZI53b%~q5V+A?+%iPi!s>%1q#1L1a!z+Ase1x@fNep}oJS&ezOss%lxLAQmDgT?N z!MqCYuYIeQB;M1-(kIJeK{5A_YWb-Cp#vmWyYoS(PHDJrD#I$$lLtA?Ma4r3>fci% z5TfZmm0k{p+_|5*25}-Z6&)iji(b;_t2)RLj^e6(-wcCoVGZxEoK%3ROfZKp6SGaT zp*$j##2(~w$KLxEws#ql4F(H{x06de3{9UNU*6s!-*S2L3v}8`)m+A5 z28K}WU7u}_pn2*D`(qb^yRQ-o8*cL0zq@RjBsAMF4k3C!*~8Ha`+wv5^0}udP8BQS z!gJ(myS%UF_o^8Lq`+!z1{AYCR}_hzD=jhV*rXIvjADGhWD4qR>djj1{T!)gUnMHntY7;EqpEh0y>Srb8s+N! ze3R@`GxjbPF`Wb^8~M-YO=1C_GgK6GbLAYPbjk*}nN7-Mih@9{X1U6izRXrr2vHSi zqq(#Y=QqiW?Y!~2vpv)XcHY)WjhmZ$CI zPsWu;W#wOE%SAOAQL=GkNJ*kM72GK;??sI_>z4 z>E^Nhc(DT6G&00a>d9L9=wOn6>f+IQLkL zbrvt)i%Thdht2V!EUPE2u0i5>;nSbgUY8T&?(DIYdEX76W)^GfM z7aOu>X&f?4?4sZWmycu)|IaMXYXonV`kmIJWm-p*bwS^o{b|mm!JmBms0iY4qM|#5 zv{2UVq~`O8NamrJ`QO0Z^{I!4+x;7-qGzPFstcZ;e#Fs@_w1$!iXp{X5mE0cLUAuO zSuh;8!@3;izhTy6O~Z8rmC5Tb9K8LF%grIV;`+#5)-#4`>jg{gbg4aVeVR@twfnA` zTq*Dkdgdz7Gp_j0O4q&+HuRk!E`iBQs$L$pERnbm8l)Qs-7M51;@OB^8yGdQmh}7S zi1neW))u#TaiC0j+KZUpg@g)5t8V3Ga|r6>8JWsee##-w>l`|mWPc;yH@3afBc}Udf6+tAP1b!RH@HUFt(_R=4#=XURN8`T*&sUloqu$LA?!M?0wF`A854`j+9K@zLw$F zTeH~?t-4v&BgG&DMWx7jVvaI`p)i?2k&A;gY^mA&6EV2>a8ZK;?9$5x)(id|R|<>C#{DHGZAj=|`!T`cQx#pU0- z8^`2yDx=Z59~jOX6%{D7W;tu=BtEV$*MAPjE(+goGbwgEcv#Mm9*wJ@j$E{6w9A2F z8Ov1^5OL&T)=ZzECc9L2hrG${{FRt*#$9oPE~$mN70j)IS8}FYxzA#b>_L|$WoNa) zP1Mar$2agdUSQ206`2W6F8RXBe5-7Tqlxck!?w}s>{D@|F7YY-udDvN?^oV}d1DXZ z2&D2eXEZiKi@g*xGasmu=pmK?&ry)!km`h0JhsX*YB;jT8(Hm62yyfj`KZvxr5*~3 zHm_WZ7}O8PEBoPzF!sBu(bIbTt`AE#lMi-(*@=8)2gf+BB@yZZTGgu0kbGouPFg;s zJy4`+oPW|p&@M$&|KJfC!eR5fQ9{Zq10kfG)`8So=y|^{385JNC%@ugO;g0U8E3sC zSy&y$@Tmr>K zE%9jH^nd+2zkk?HM1v4&qJ>9`_2D$W)!14;k|Dhn3fSb_+KX-fT@p&rrm^&{lq9Eo zS~ex7NnLIA^NP~*T;74#)%!C41s@(PC1d86kX-vpOG4wX`GK%CW(Su z9!mQFA91*sUGK~I5b9`cWAso8*IGz^njAx_)q*753xU+vpBPq@%eyRg63E?@l^TH)+j)r6Xy5yn)aCd_(0DV+n5%d_Q#MgRx~F4+);ZfDIoDigO7 zcTmFV36UEAL&R8^)!xa&gexNI?q&NfulM*5`ot;qbaZ)rbm^_`^L_T*YjZpiIeGBA zvkA!;2b(nH%4%z_xiNT~Dx*xh@sA!_$^v1Y&YJ6QcC)f_BKFWGvgCWCy6j@?JaezD zv%iUepbK7G+>ny56>YaS3{@@dV6>Q$xBE1@v?J{<=FUFWE(8g`6VBQ)21kE-=GOm9 zPG0{lvOZ0I;o>AlPVA4zlXH)?H^FJOCT2@&;;tHXA|cE=(r{Td!SdDm2q*PXsH=B; zT(ZsO)=tbx3_8|&w_jzkqI&u5d06m)D(}hRqI44Y!^zl9cv#5ud=WIzpP3ko zB}WpqZ8oG>_n}xx6>hh}4SR;oOBZ}M6)C>~)7!F705dB4pi`+QM0eOjPc|SbSNSW@ zb%gKmyuLlmaQLI7BJvfl&lQSQ0@oU*tYH9(H%2KZ`n|lic1?p);&nhNX@7!M=jjIo z2ab;h&Ddtm$zBcDO)}+-s`UiExc!~ZYP}Rji`Yht70&8=a6f63#uH+xO|(}&M;jlV zU+aLgDz84*{qnjy@fcdh--?HA*;(BIo>NDF(G1WIjXefX&TOhYOJxZpjgNL*-$W`| zV2hYQ!T4uZPgHAAXd`Tk^9g7w0jMTv&Y$L9Xy;bNZ{%}3KwgUGouckoN`>2`3C??< zIG`pk1wfI5xeNhbwXc_S+*LkQE>QVQ9?l5BaX;n3{v_PTo50e3b@BjyrD>_aS#>L5 z)eZv(H)ju>gY%{&VZZ{oYp;|Wi+$wpEmU~cJA|JB!sA`9l#8kMw8c#4cOz=6J$iNE z_leo3x;NZ~D97U$ZIXP(Ta~yWrZ_4CGde!SrMqg`8OLwUqzaM12u2hJ@`SPI1Cvu0ra%pI=t_+V-50n9Pi16>o7C;yE9c|eJ>}* z0Jp}p5nwWqkrwcigMpauLH1vXE~1N>-Q6-+Yz8APH&y`@r(FQd{$rS#K{u;co=~8+FP?0yrK(@-Ers+j#W_P^QyjkUXWbk{f zczQo2P2N8zP(WCfcSV~CF_y9jEuFzb-Wfc$d|uT8b8hIrSKwkWGf7Egw6VlLoQdK^ zYu0)7xy8cLW&j}rXpPG)`0NOj6MGEGS!}qM1PlKfvDQz#NJw6vV+xAb0+?m}>>xvu z%)7wK1sU`r_z}bUxof;BqEHA~9dJq)q}sK*r#;kT4o94mw( z56$AWnV#tT&Z3wS60}7%{Ha;dx~lVNExn5?W)vl$P)d7g?W?B7WF(1QT7Eij- z)G~vfqS7LLgq!K?FBUgb-C&~FBF~_VczBck?AT{zP7+I5U1BT4h2dU(v#n0(lHKcP zFk%3PJWs*S4x#s^;Egjes+C}HK8yKrEA>ZF5v*vbxwqM^yRw6X{*L#iXscs8;)W<0 z&^+g{Jzygh>V@fTLE3#au;Rn(H1+8VEx^wR2(!`x7fP@PU$SIi>iLWk1F6=U8{j4# zgK@d_CfIH#dGrvuqY^v)T}uOA3zsO65C{Bg`k!UR?gz5`KzYds+LG;pFta`2W8ATbSGg=D454DWf53)e=*~ z0dgb-ctIxY_X9GSaRO+EE@1JQJ!mvqxE+QZ<73=DAUU-MbiJn3N;-7Q=}(@QpYgj$ z8TGvEuX`wk?_j&>(z)>(u(ZNX%*O5r=c81hrAUHMF7Nb_w5cb{;R9u_l@y4h(BC6J`cOPeLJ-PD4M89ZJT_S(^3V zoUW?p@}Pe#!R5c&Vu1N^UxT-Vx~skfzH=2bNq@Y!kc8<;_?1D#1%_7vQCfg14k9iD zF5>I@c-Oj-$9Ped;Se6JJ(;vPM$IUcX&q_sD4G16EkM*e?UNYxHvVfUXH3>ovV7)- z!?y>amtUEGVw~k>&ZHK&-2Q}e6-#J$bm^3)mojVXa3$Vf-ytKb7_z>XBw50y?1zEc zUnB5!{k*XGSO5c>e6pd;o;K1gf!+ARsFQI=Un;s$6uHnrlFODo5d7-c9;jw*Y7b;j z_5yN%fz}u>UBY%^IXV)C8L2f;jjHKJx2Qi=pd{9aca{E#-qlBE?~Km{R{X9H7s!hA zyhkicM(219wQU#C5c1mTVahQ8NcbAOF!2n;Lc#P;Tbub1(4yaBAR$?ZH%BCc(I?Hm zxP!S?LAcB1JrLTe(iEuKXypYg{J&IAI|cHPwZ`0mi5=k9Cx3;N@>(eE{_Y~x{JC1i zVrR5w-XpwwxSnk^fZe7s{H6td0Xb*s`1opb&-574}$>Ft}w22qQn{V!{=s zA)bea=v_?3(u`J)<&aSwv;OK!%KpWHn=6$V9o}b-K~Lv-GfkQi@1JRu zW@gBXBKXIJZe(tqQ6TILayMxjt?rpO(jS8ip@S(NL?5*q9vq9V7C!C1pBagP@Lz+Z zufd4ehR$DcsVQ-6_khCx6`nPq&vNP*g8exO*e*B)u6Sf>HZqdjf6`>#P=7Y(YM=>J zm`7TL=hWZEmugG!_!w3$&-93-|F^!pXYZI*X)31$jrEYSJfHjH2N}lk(LE;q#(r}W z76^yDd|P{TgS|;KkA&_g=>+(PgY(?E#vDlo464IeNZ!sBU-w{M4G8B#yb?YF= z4{CVXxK?6C*jr5Z^hDb30^HX?*7U31Kuu~EtkZ&GI`$p;dOad$szwli^t=BQ^#EjN za|;r|wY&u)3IL)(V5Xw}xbv%&*}9A+sR~ul^KBdJ;h+kubZ#BnMtuVCkPcK?T!Yus zAQ#RofWx7|ivf7aDoP?5>902>i@V5jKfEaJlWFw*>|@@mmX*G${A+j#l6;!o6hyu| zKo_6|D%Jp$%$F_S*MyaYdGVzHPI(O1_781^bp&z2nQ}`?e*a_&uVVLACNjYC9|7k4 z*ZTXg);SI{9U2ClMnD}vry{J(YZ9`G)=TEqQ+3$EqOBk)i9vHRt@u>E2a8TL+4o9Q zbi)Ttj5yv#2NGrBxE<3);Y{h@+PV>wJiR{B_dU>yLFpW5(I-^}$(bgIvJS#7?-vC@ zxe;du+8JP8M%Q4Gpaa%{e>gNcZ}T*!KaRQ=MO+9U$--z&wnWV%G6lq8o#! zkQ7p$lU>^a^F(qCQ(%uF2E3LBW~adED`a)uf;UU9#m~LE<1V}mU+m^+6%J(95&2Mg!ao_Ni_Ye!&N`%xf#ii_OG2qKO(g?e4o-`$a`8Bdp-p z#!>$ff*edQ5}3{gcyYTwolgI<&YbhmNxAVD;ZqM%c26H%rXfYhjA||)vO^ZWtvLLaYelA60sLm>3 zgoHd~-o^~2;tvHCBE^+^p3a)dopPld{p?q;fM{HOo@7K_hF0T)AlB3PnP_a`-}3sM z_u8@3>Uz>9St~(rQ%p#o3JrKsCfddtTs^#h`=!m-(L>Vszk|5uyQ%Dx@{H9fj~^Be zb;j{@k-v5j@?q^RtY}|d_LDsLA$#;v>mhm6FY~`W;`R1?{WAfmfwQ#$ocdvFE*a3R zmwI3|D;f|ADiNxJs{U|6TCI*(9w7FQUxzWv`yD@lLzN+V6*i|}mjS>5d5$;HCl30w zetp^zRuK1~aHuv(DD&hvQ_&|k*KNwSQ&3bDZB?7AqQME3JQtw!L=TIo11h3`bJ8a; z!PC~6lQK-)!Rr~t$rC3zbDjz@BpE_2$LuX~{p!c|U%=2)s3`;R5Sjq6z)l$30@;tR zClZ2JvqZ)TYwG}|Q=rQlSlR>D5~1L-8(`{^+_ZGfDYk#3pJDbz_$NRxZQ={)F}uUS z8=P0BYl*=AAu#p9x?&@{r;Pf-y?Crkh79|(gdGhtt9?ewPP?0}z2bdg{(JbR>h^co zyAZEMU~BcY-U{CXu)#eb@WkhpOJfltoXHKjmwqu&|9G)(k2+%Dj_xT;{EwVdfE;BQ zNEz*w7d`g?;b0A}E5sfDuYJRJC1KUGm&j(e^!Qb;yKRk`QNr)Xkms8Uq|P2=Acvqu zlee3gYGtStT@0ZhO!gW!g9n0-?;R8h!dg^3$vr_D z`|U_xj)IsimtoY5NZ2B8x|TupjZbT19?Iy62G1kEu!y!(xA9o|GFs z#k(w{fjc;wyvh}?pHl~B+5d$y$n+ZAPylgps@+|EfqK?RBla9w)j~Qj$55=}5Jcpj zOp(uuuRt#wF%Xxm7tpIQV2=gTzB;qPxUWIqp0@a}Ko1PS%YQb-XzE2&7p^7*J{ni5 zy9Gk^stA%Vq}N~z2(T3c(Ytis11A83FhJ}Kc)ig}#{-KhlAOC0%T8#+!SvQ{^8be+ zRF@B^r~{~?A*S1K{-k#YsQC#1127eu`rmTSIsaL!vgu?~LyFEgiWvb!hyOGF8^D^K z%?={zg0t})%ao3=8Y^ynUSATJT4(`w%@RNx1nDz$9F&f$=cD+UYz%CF0FV0VqGt1 z<2S62AVUUVuJZ|Gm^BLsZFtr|V;B+8DVT}3I6|k7g5wQ<*MgG)TeA16f1*->9QMrs zY#(%MIJ%@45Uo58t^9wE?VZG=TuU)+h}Q1Cvm>^kJYX33Z1}u zQ$6#BDg~wo{~vIMIzsfO`a$C4Q1&eN+_v&^`Y@{>u((|D#o?vPr>geWtdD8hQwtf< z`7N#f_2Hd#EyK@f7zyh?XKZhU3IV5ipgB(zSQ2}^pYARAzGv_j?0oWyr5=y6u9r?M zs>mcx7dR)N*Fpsb7?XgSZ(m+hM+s;@c@if$Y%_XMhP@g*45+wM5&(3)>fh7go;WIe zM@xzm5^~&`cY?!!-4|~$??Ma_zW>n5?J2JlD7D!GnrQ&~Y_jcFpb@$@O#+&o{?}6R z(mDiIyBo0Epy%)eNWnKX#dx!Ybkr!0V>uhMeP*}%@fz@y3I7348RWwD9N>KbMDU+L zG5Q_#C26NJCJYYFG1nK=pQ{r9Q%P9!!-EP8{E`Tq+5DF#hA%mrNAHk=sg&i%rZa^Y z)_1S|*H9S-ocXf=aQF-8e^{3`1X6$dmnGdW_r)dJuNpmBCh$=+_O{GF%Y-1m!iv?H zFgyR{Qv+d|9r850=^dXwfj;_y>vhnoqXDX|p9My|2NdLe@;e(eifu~^eSCj&5Zotj= zvB1OjGAIJS!M;U&z|(ma`~KTNKB)M78U1vJ8$K%@I)!l#ZVxCpe!o=xGrx+L!F;$T zP(Z?2NK!*rF9~P!XM$bwhu8Qs0l1&G&eec5eOR;Si%@V8(pbD9WGzY%E?! zVCb4}tnn*6b@(#_vq@|+M6%^X*;?wAl(#7I)N~6*Pdxd9d!WB{8DLZWfYT?Km(ZCi zc zz0buMX%J>Q1LJ=HHu7GX;sucS;o#*v^?XW0yiR5EU9}qlHeoVdnDQT55CTghgFy4W z3ar#=1c<%@Ax;Hir&kd^6U_yqy>Od>;yF&$Ofa*eAGKClQ17(}cMQJ|1rEYX?uwsJlm%+LR+$!CSiBqxkvxh9d<(U za#4Msw*qvEztsGZe5qLyv~Bp&Z7?3$3W2uQ0*ceGP%V07`2d=Lny%ddt9%9Cv}l{d z{okxTBVjMS4u6+AIRhUv%UA!OFnoqh{ka`0yQoZz$zhPO2qO077jc*R<^)+40&6MV zqc#R<#j5cj`aZ?zJX#rXd-@W$ISbzFtxDi*3^;5dSzap*`Eoo+lumqj@!I)%Eh~foxVSpNa*n(o6g)^4?y}0h>s4qqC6CXq%k5q zASxreImL?4=17Qlky-CdlJ8=9^Zd6~R@Y$npRbKB=Zwdis#o!TGF@p4cstfKZ>+Ly ziWKHlxnae@EomJ;1=NfH);r*4OW?vq73O6K)%`(%WL_qo@h}<|Bal@7s)E@178W+Sr`x4;(y-iTLc=vqQ7eM6;N3R%q?aE z7sSAnE=0UDb^z3v7fR>7>BKD`gyt+6fda9~)l^YKF)Yj^4UTutMzZ9!JAo7r(O z_>`nJfhsO^i=7k!o`qQ&e-X(PBZ`=ohz9@AU{n%SXd0Z19r@a+<6oQg-Tm9MuW$;J4*f|-vm7W z`uT~%3<9~rmQR!F2`DKkPxt+j-@RPS0UB02fza8UY`CtFp8;p_zb3zFmg$Ik%_r}>(BxDWb&rdXmh@7_1BRSM1iMIYMmtClcoJHL>y zSmE3&^%{+B`NW@cKS`e)kIUB$+)rft%ru;s*eERI1}NsmrGVD7XS|3%7|f=6mQLYHqKQQ@-b?vndUOzn zs|IDS{0@tk11iGqXK%orr%!oZt$>};v+42ER^g3Oo2xt9*ZS0%SSr*9eSayh=2SLf z0WG5Bj#;;H1&6rjK=JFXb-)Ak%JrO2TP}UTw-s494?i+sObR|0;nI8mwR8E}0zG}G ze-O`n0fR}NYW{Yx#EgD&rv1uT)V=@rjqO`o7askx5*S-|molxN&^hDQ z)to&XCIdyd{sSr8C-By}i; zqC^|!;GwWoI&9z(M)``Que-1>pbb?9So@sQYwHzp1xT9hvZV3V_BaXoRUt^r6Ggpv zGFExyqV`IJF9uJbFaKlBmoFCAdEr5t%zYW5SDd|=M7Cf3IS~MyvH#z#g9b7HYk@Tu zdqC3w zQgi>6#Byjh10HkC@G^Ri=n@76y9ezSEpGxfmW6tI`C30~Id^usmFl%i(hAAL`+a~@ zi3&`YB`NtMx-;0sW{A^o#$h5lVi|R~UWR2rLpr_|Hjg=Q73DukzZlePOn#**K>1El zILnH&V1<`f#jiRE6KnY^MrK&r)o^n-;Xa9C26(l-Hq`@0fX%@@kRKI$$i>ACUbj7) z`iC=SUff{b{_>6)tgcs0jl0);0cQyUbH}$a5D@h}i0|b@&mD2EG@NHMXvhJ0b*vW} zFqb2k={uwx=U1w``tg@gEFG0*G0hsG)I}nRO2yd5nk)m*-+T4jW9PuheZv(vfEEB# zJh7*G8W66jFvDk^c{$)IS3+vmX9gwpb3YzsbHVZIyt6^~X$^Tiq=Q#$3p&~8mieV< z7gnOgT#GoC6FwaOu|y~JBl6@ru%}(ge=oXbCGEYp5=7T%-vCd~Wbz(O#Nn1By7Fpb z{fZ{VzVZ?JoQxL-)rK+H|J0RX7oOA?<@8$UjgO+!T%N;?h#vXnG5u^S5dMgpY(u+g zc`&E`yRW}E02#^-a}WFQl9eEyx4#OKg;7mEXhUn}hJL<#W!h~VoZLP7daX8LgnRuB z7QzPD-ASI+lOr1ff40#ARJ`>Byz%dT4wk3-l5evJ=u#>#4sbapUX3H;s01QL#QV8dvAv2Jm$bdR9Z zCrpH%D4*~rUdJ4L5m|kzJmiaEp%5WXeQrugeeV6cEh8zmLOA|h009IW@MKtYBjin0 zT5>);m3Xb3_}9J%MlIlE%N_wJ+!@BcR&c$}p_Y%0C=!b#H9 z68aq*CZFh!t2h1ALc4UMHFN=&0QUvQH1fH>;Q=zm;d7nV`bV9+MTzzE)^!)oNF8OX z;z`G%S-)^%;|xWaMl0=;jAo3%(-H0fJJY-brTfv?XSk*U%}>o2E|qFnQO@MJA<;uU z$g#gxRoztnYFjkAN?PnZ%Ffb=50sFR;BQ)lV;II%+RZMf@GkJmjN$)DFt#P!Y{8&u z=hz&mF(|Cm`~*SsQ5*W6fL|@o5>l*yj?t!T6{hX-xmxxS7bHJHhrs?@S%KA#1J&^h zTJ^xq)%6B^|{!Jny76!IDL7=z`+XSTh zor89+RK*`7?;_IbuHjfbDEl&+ADJX$I7$v9+|9wRY*X6NJ+KTYh;5D4Dw`KT#Y zyIB^WVA(|QCAhBV!@sa1rRf^0RgBX2AH!dVJ-K4rq^<%rKgJU$4j!l7JWAulc+jQ1 zNoyL9V<|!+*%u4lO^*+TN+Oi1;0^?e;&K!4tq3+ZMMo zu^t~!h5NXFSjl*(^~M|DCCnjJ3KTOy{MSm+Dt!W#>lzJ@upRCawa@Nz?O|$uSpxp$ z?jV!&{$UHAYU-3yQu}_SBXV)NW3+TiJ%=Y}hQ_^EFFQC!BOKVkV6Zo zKr+)M@qny2e9@*3ie|dPTeX*hU0Y8lFvAirOqNDvs-US&m}-b&qQ^myA&0~~k~-d+ zDl{{snMwTKyqPc8HE>4XOWqPA9EX+9JKSHZkL3ZD6_$YgSVFs&C7Ac+Gc&m!PT^>q zcDS8f`zRjKzuC!8(esBC#UMWEKf9KE;{TrUBow^xo1qd#f4679FN~IaAKu~oW8AQe zICwg(J^J3}L+VhMMi0sOiuqtPKbtu|Pb5hcf&&Dn6+BuqH$$Oqsaa4KAV9=O?{BOn zT8(xijImyJvYoHL9RoM43(;W4XteU+dav{SM|iem$(~G#RQ>v=$H?9!4+NP2^b@*l zd7s-IdZQxkMSNuqX75kAM+&+A?~B-z2<3%NONtY{Z)ZP1QSFKe^hgZUky-8P)C(qc z>1Do2Ciwndr*`bzG_aok&+Yc9&9eh z_%5`#66aXGQt$bFYl7aEW3C+S)?NhtE zorDj+D;FM3TvwmBpWf*NHa1@J~Y&zau-3tOe6U%gEWYcxj-2%k;!_O$kKjHVu_tM?Uqp9@zT|BWJN@& zdSIr^VU?Anve0>3yF%Lie#Dn4~v!9+{=2KlLK(!|V` z5w3yq5SjcBC-;}@1})%HIA#}5ViaXR?L+LsfkWNrKO!l7VAVH@1K-T+N<>KI#d73# zGO1?B#-z$BH@~v8-*C)zF`O4Lcw$@+(p^w;4D3~5C#&)PLHdj&^LnlaJu2BVjrpNn zJtR(}ocKK4W4vPev!a3!^S%GIA^KLD>ClX<{V`K*hwC;ijr5?I{7N#fmaMfijH4Ed(yz1VNp6z{;{6M#-dMVZ0F*Mbcj{o@XRgml#P!n^Io) zdaR&Gh&;MBrS+?Z0n5(4%!Z<(Y0qygz1HCmOAS+x<79*fhd-GIU(_YC9n2}YvVRH_ zA9FN_$=0Eal0^MF+;!+t!$)L7+d?cRd8DEicDap|wT(~`D563sTTYdp}It9AJC_9n03|X&)dYPi3>ssP|2O`gex!%=`C4_mi#gdQJEYD($`0S1sUE zWE=Z_Yg5&Lae?V$y6{;wEvN3=8qGD;!Qy%*=MJk zmEY!N#G~_glgcsj`!t3unFwXO?>dn);CqxgvemEQp8YrIMt>WwB}%)?M$R0W6A!zZ zg{U4q>2&aJ+Y=(Y|M1h^czhRjRAg9{3s+GvYzd}x9okfIplkI@s`pLQldC9CK2xfy zt6{XGdhU$>*A7ZF(e%+%p4IxelrW!Qd`WP@YD18s!>5PgC9t$o$GQ@_e!6HEezrYv zR(R<3D^N!IiLY#Yr(e~f9y?37-mQs_JN8j>U_$q|PslSI zbA|_IJw=$by@ke=-QL?UUPe#p@FBw`V>vsei?3tlStj(fb`#1&Weuykgc&5PitYVe znTbvF%`IAQxnDN<$~E$Scd1Mu7kK&!y|h_s3F|73-Z$#VDvRyOrLcbs&G54~cajgn zp_ZksxMx@-{xO5_$DR%EJq@vvoP3I9)*M9#h*h$*$IWqO$cBOH;o~ythuoKhahF?RPqm5suD3g|6-!R#cwDG$mh!)6Sc&D)%TLhE4^D3Z-s|G zxJ)`FVFqn<$6O%^tN+Ct?azZFwi#=U_#w8`^Lft5u{DMrfm2+m>0P+_FAXKQq#M~H z!i6+)X-NiH;_P!`I*eK|e0E4?C@zHM5LM04HO!t2e$kpf{K(KuzL@*{(`xFGXz7}q2JJjBel};=KlhYa_s>fbsJASo# zFfP;aDNJu~b!zDSh%wB{;{BGu0~zsYU;1+xVo@x=U4w*8E4_#@9oF<(fIr=DEmjT< z3gYzw7KZIoUY*!2ghOE`{WzC!brIK*s%a{(5osyOLnlm+?Itybn`gsiku(G^G}SJL z-_!ayaTR^x__&t3&x-GM($VyNsD&Pn`J${J1vgbZP?hiUhC*uc^{m&IL_S^3YZ)a? zzL-M&>(Tme0;GMziZX<1d5FfTr<~l;;d4K3m|OnzEs^}V>gFd54PuZXN&cl@Q1-j< z*uPofBWg~TK|S21tIN8XVb9p1-2Ad}KAig($u;M6NH=e_=v~c$e1W@#GrDyR=Nw!W zzcqHSE!8htl$_6~8I0Y9W!9x7>QC%$$1)-T8ZAH04GA$PLuhIV4vNfEifp0dSpF&v zP?H(|E^$0O?`jG^R!@bUQYPg#b&9v>=)V=pi&7POt+Mv2xDm%R9NFLl^>4}FN)rj( zB>yAbS+Hi*OceN3cV@Spp$SQv4)ymhURypIeA4?-t~#Ktg+4{;F|D5B>QZd0c<-yD zgrW1HwTG>B4C~aB@Er`~NpU=QLljtDSgUWnQpUMt-pcBpN*230xXZFR^iErrgS5sa zLodF*A$*rz{|fY+omHpJ@8Q>^Orp6Fsn1ySHR8wbOQu$)UvDV7>BKDh;jjpFa<0bR zW?t6v`-$1gD*Jx)I7eN4e$o9Bv6tj9bFEA|r=m&!E;!TU+;PzGyPVx_UM0zmtnIpp zIX<8AkKm}3U-><&LhRTT`#-SV403MdZ-XTX$iee;)%+K6%+AYrW6!V*-U2&oKRUU@oYAvoXjk)|a_GDn0*v5AIWJ^5 z!^|HhnQIvn2NC03llv%*FJ~Ck`W`o}lJq!#<@?wTHH|@ur!=~@%^(ND7k;`9@@_D?VJq+*~y@_aHl`RO0cQITYBcdx;~*I8`bnRNw(> zE;wXnrD}@uP3k%U&m`mbWJ4aoOL5EQv{D3xAocmy-gElow7LMz^ZAKE3hCxkybD3N z3Mm?nT(KHORtMZ|93(~D(ZEor*6vJ_h7#Yo^qqdWK#yr zDd8G%pdr-@sO~qBB&mqqc&o{7^FtG4Dol3*76}pgR@&*-L<14DvLjVCCY1oUTHLdQ z6V_BkcB?-!UqTGI!HbHyo-&#E8(LiXGQpod?x*F#sh9`-SoiO-H|r99z~JMsB7t9u&$HiDu@lo23*U$_CIkZbn>0JJ9G0Wan725LaQZu~a%tK+ z`M*nvN;_QQtzUGI34cH>=REDNO>$ZPxHI2raOpby8Ln1{ zw9Q?GZiNQ7_$va7J5BXz({x+7-C^`0-_e<;U_5Lv25qLBKGi6|n|#O*d2$*1s0VFp zvdv;yjHG6N)>0dfXc7E7ws5FQb$!R8ti$>?-GG4{YcOEMq`!|emy+`HTM+4Kt%odv z<#Hq(ncbJ&yh|G19pBRn0p7&rt4T)POgc8Pjt_$(NpYSfFFy)!WE--lb)GM5Qel$H z4+@c>u(-%MiA2|qedA0%n%D^<*gLJMH{Bf#BGWBrOSOS14wBI|ML{}mZ0qFlelt)7 zC}|#>_ULo|^aP_|pd#`*X+(XY&quW+)6cnB8)VF8^O>}?{fqgyw*78s&`s!5GxGlh zkr{60E*5bHA8cr5@w01UNOFcP`8YH^u?VHf%mu8(!LD>nuKfgaHXz<67Dk{Gm`res zGfSdkZOrSeOoeV4)*@38S&bfQ)D_0@gF{9 z9`4H8#-vnIyI0BS9A1LFzc@is3D{mY8(qkcUQ|1Zr9F2=@(y0fmZK&qjI#Nql8i1G zi_;>*HK#_LC?e$Aia9GB+7c|zg#1i|(M;kE~WbDkvJ zQX(go@(r_nVHMDN_`O0jB@c~%L*91>Dq4?-h?a_CkZYu?@-dIdexkWH8E6y6CuiWy z9O=#1OVc$|`l#|vfA~`=5+4c@SJqX7cqwq>6WrRnAb-reGLI*X*h6$^@g6!qS ziySG6X=jn1=v`i-Mtdh0B%+Cp!$VQQXLk&t~xqo;VCuy$xOaxz|g$xNnF zdXNjR!a$Txz7h+$ygW-~BBr29!{G8vI+30;;W}P=z}jNkBm7h{UT$#YWukS6B(VZ- zqa?Hva#)Qu(6TB0gd^|>9XJ(GNXu0~Vw^upppm`!T8KoWdx&SXSnK8Uct4B_7foa7 z#zSUjZrraqh0BlbOv`2XsQ2cKLP?{KxIDzf$NaS120vUZBgr4Np#*bDD-P^q0Z7@GvCPUNNp5nis#& zE~r~xbQAascU-5QjtITRLZe6qOYIEIXXa3+-m6MSh7)0xoX>7%2p_`Bh|0imB_OM0=G@spBI|IP1iO&za~!?BB# znUjiqgXHHeCsneO)H2DuRGxBVz-jJEs3Jf(=u6&G_Gik zm?gWQ3I%d90wo6-2KOT|0K-PISn%2SaW$mk?D~*l8c#IDOaMxz@KlaFsbt{H{ZCGA zHas9x+m#PXM0w{~tav6?2GTrMFMCM7GNr5tLqq6j3( zoaSzkvX)L<>QG_Mqd37JuBlrsZ5_tVNO!i!?=sgTtWIST0Wrs~pdQu>^1QLXaB?%? z;gQ)Ve|kcvH=X&{=q1Any1OiLT!oYoS`8L7s1yNMwxeq>ZX5J?+KaeNu;c?^JbV95@aqefW_rR8 zvAH2R^*x8ZrTIOnhnu{{bICR71ufphq=7+W2a}34>Y&fktqyhz68`6w{)gTp&&M^w zL*R?R4d>R#@jf-^IBa(uu^#L7`Wq+0t3lkr_oy`cWCbpYB5~gaR^25xfTtPT!I{9n zEFl$6Lzp;@-Gs(iUfsAm@)A(p#QbH5K_M6?j<0@xF}!?tI68a%`eb-I zpr;w@J39${{(w3??$|-=Fw_uJgMY$tvyrl^K9Qk=f{)|H^w%@rvctHAWO%>SPtU=W zJUe|od^0+~7`z@_h>q(YVC)RSWfhMOkKVHK(lj#P0WnWO4S3q52Iy07F&DXh8Ge(- zHJIamgwY?J4C8i02F>xz9pU0dG{}Hs5ZPPM=AK@o z$pjkKQx9f=JC{o!+^0==%?l>jlSX3`5)>n>kJT|87D@VH7q}MI`9b1hbUiG|@-XnAG1>wDJjX z7(>Sxgz#Ico!_N_NEDYUl@BPE>Xs!s6v&llmYPKxgH@)1sI}A6NH>%-k90BJM247G z6)YuxiK)3@2;{RBP)!}tFu{bcxRqE-4U!jXDBVu#(m3N*^&@VQx>C0ee4Vn{n8htoHjrxVGfgw$2OsHz_u}=gaGttYDe#PEz%N+7 zssWXH$FG<-lCzw@uuHY(4)kO59Lp-JvfUuXrZ}sL{}w!pt^z*rxjW_VY7kBVb$s5| z;u@IyD3K$-)K7+21L`OpzPUKO8lIhwj)xb(foaYuz9e)l?qZ2>xuD`3H>GFHTC=ZN zie1az^D)Y25;nCX=PM>@8fUAr0R7Msx?OynYU|Sl1i#QIX^hzJ{z%6^)XM78qI8~W zoh`~;g2Gq0mO`agb_Hv@N-bl~AmmmlQwJcTtr^3dxDmj4lBtUv*2N?bNSR?1!$^>H zvhdOLOK+?Q#u5jnqsMG9ng(`hKReo1>@d={qJ=uOIW#oT+c?J52zJIWNok~4*G~K98>YJjpm0;EOozQy{G4k3K`DomT z@>5D{pp^x;m=9}OE1S3uXL=eekYj4eT3Vsb_E9V1Xlz0w&Lo_qY9jgqs3s>iBUp!*n%u1#P3*(@0)Re8qDk z-buRFQ&LahRmY#L5f-o4WCejuGb#9#6_U7kx~t~=BVFj!n;BA)-X$ptPqaY}8XB{u zFxun8tHW1^mxIy!ixXARLXj-j)2bhIZ&_`HRt%j;uVo|#8JjuEq~$`foDi@1=8?vX zfEi`%vt;g3aGPfD?PhW*VnR=s|8v4(sjhEnkhMj9f2cy-^6Ljd?2VTJbsvMQqwjKc zvO4d9X(?&qZ8n=J_{5*6(1Iz&G$m6|GyK;~RfQ6pz8NgNMutiJqUB~K3pzCd?38Yycb)>ly7R`iuO^j_MTw89cyk8PANuc>OQP5c>5L)Kf80iY5Qf;d3G zZxjCm*8Xqmcz%B>DGq;nstSvpn%-mZnp)ex%@i(3JKOnP9vj-@sqUmUIbr<5G^3p+ zQ%9O~2aV>SM7t!_{)a;F2mWkE!`3BTQAGy>zXEp3I<4d)8HK@Nix}z*ZOS12n#xBN z7W#{xQ%YP>;(*BQ*gW>=Ja&l+lN3i29BV(tvGTaw*jhvw_z!g!P%T>^ht2I2qmqq& zB+#-kj0(PAuiq;|V)64WAj1viTj`kIu0)0wSYh$svBwt~7`t^{#Fe_9jo~i1OP@#^ z={i(ex|xW?^VFwM+#-8=c7^h34g>(JHo^9;IARq8J27uun_3<0_z5Qa`QnV1n0i&p zEGzYW7)(P|D5W5Am6;x8+uUKv=^<(Ff^xxBlN5?n+%tf=AxrX~hRH4ytHj3>5}#d3 zz$)~e;7;tb1EH%bSWrI}fMZ7F7fZ2AE|vrUU@`MqG#f_PL8G_gW)5lINh`uxftF6}ewA$oY5D5r`e59V z**#7K7x(0<+99=Yirna`qc`;lY&H>4)1(1wV66rd{MmT&$DjW=|D*lKw|{*1$IB-> zzbDRe>RGF0E!m7mQw+L_PdH`055zq;8cQ9ZUO!Ju>pHGy7<|LgtiUqcp6~l+G=M!c z=>OMSdg6kE*ygvdo77CxZU|}vZrJwa=fGw0q>23v?;X~GMAP-m7kOoqjZ&YfGF9d> zMcSEUsiDk)nD0bf(UDlenONqkmfh9)&gg0m>BOzgfVziOXkcwYvyvz&Y&F-_o#WUn zb8Z${s418EME@1d(R_KRP6ByRJdfjRQPepjcd zsuuQjY=p;Zh2Bgk=3f^qZ%pN8nZA=@U!dJ#*wxD|Y--rodHWH3XDT}d;c!`MVJr+d0;7a@vmn2f`v3R; z{9h!s7UIn~$*)xZnw*VM`1aYFbb2k9ugO+`R{2k}wTx|4#FJ86Fooe8#oIM`J0KU- z;zQ<=+6AGFD7zpMm{BuRi>g~3w6Z$042LTki@eFDwwfl^$|}}Z@@rSs9?G)3ZVGvm{@b&3mXd^Ox&l!5^yPgZ^G|x6MAQ}P8Sor6~#YD#>beB(~p*& z<>2rGNr6}_!z8%*JsyFRw_>GpD|__Z${stnB0}zq{E?DyB@MczMcoE*STP#{D@8+% zl-d$7NCW2%)&G9u(D|^F2sd6by|{?^L2o$Ow~n8Q>)>s zKDoL+OjX;ny05JZ+?I|a<<_pODX%JG_=G;}7PeF-OsWc%m4!=1A+wsW$rn0>dTYur zo3Fc8YBr};o=2A2h6S{QHeG0WZgk5HS?Wd$0jB6Vn)5t(DW6m|g7?E{FOf8ICs_kd zam8vEbeRKR_oSnxW$P%TuD(>mpVq@MwJOf@XRe?ne~o50IyR(_l-g5R_k|LA<-Cxi zukuGt-O1fn>v_Fgc}eJx;(5%Dy0E;yl6J!4j6_70viDaF?;}dU!0nRVr^1SCKkV1W z|JwgGYW`{G*Q6z2abik^E$kG2btmbuy(k?I&vu+Z2!Ce3cmQm_?2GTKWEbM27^ zlBH1tG?5(+fi)Jd>f_2TSt$%lT0$V6Q3lam#CKV| z&J6fn@ldJ6=qnPVusm*M)sszgW@@?27tW3$RBCFcnC-3v=_D#kGo0O`IOirAD(5Nj zU8|_E2>Q^U>NxDt#5LHs%<}6WY&K(juiGxx6?`nq)r}CvMNwdDid zc~L=?SvfYgLYqR5PAktaYo3s$I{B=lH8aimoznXYA{6PW+H*BQnDWoRB-Mtuw$`lI z+^gvV=xnPmy^o&%*{dQ;t7-v^?5e5(|L^}Ts{tvWuh6LNrNi>&$&te`sfOt!4f)-j zGug!qUde&W9JeeI8JZiUZOx6qhg%A&Mnm-m=ZhP$K$r5xzpk-X>b9Mw5f}whX&nX6+V?vhRTvM=S+&YSye8D z8zU%iMJOxbYztb0*?JCo2ryBT=Cn&l`3W_VniZH9b748fn4qdpuELQ$N3e>*kq!IL z#`S07`QR znyn>@CiM$n$}yF{BVLWZs*Ut32>Uez{nv$RHqs@_qN5ut63f26LgSo8#Agz?!-d_z z6K(-h`6pf<7Q#}Fzp5sBaeAbL<-KS2455ZPXKs5mUmTN*T$`Y$1g(h^-By(!E9p^_ zy4*irn*}O|6QI(x#A|TSqNXvjn61s7+*Z~MtWefCG=78XrqEh8P9+7aRvmeNpy{dA z2pMJwxgNT=LexQ-^SySL9h2NJ0gRa?b?lZ$pp8-Wrg8IoGd~QAq6Vt$3Y6^x=s}w2 zkXkL$GP|34$Rk~T6Cp4EMcTh7VV0UTNY4$0GsjspSf<}5{=>p#`n#mv-`Q9|8Xr?Q znmH2;1L?xTH)+-K zeJS?z9szPN?AsN*yve?D8kkK+9At#)s}ujYSm_YYe8Cja|3o?r0Bujax> z{_~;6?V`FaRJC3c_vJtVMj`c@e60z*KD5~dB9^!lN1Qn1_i8W&w+Yosc`-Jtv6CHbZP3e*|*a9ICPLyMdZ_hN8({BF>k+n6R-o>6ld z%)$?~8-MOB@Z>&}6?=`zHen3O%Px+ukrF!jR zUgAcp2)3!`Y>L)v$CXQ}u&^CGeGLk$>i|qxj&7{}-!Hq(XU+ER|JiG{cFF$%zn(V_ zu=4fNo!NYs6~XgEh(EgGkDmCWFaFpUe?U96BWBaP4)hJvnFbc{F}!*Y zbnzt$kQXmRns@lCyK4F7^Ob9~TdP-TuU@6IdX?2@-|p4U88_a0e{u4HD1vS`FG@(Q zBSd*pJg;OTqLZ@u0$QzWuQ9Tl$|DO_8`*K9gY6x$Z0~zlw+mP<7(w_H_xSL#f?6$i zg)Y`vnYAO9OlAh7q=95%a)rB+oI>hM;V96=l`rlZ*(Jf!dr_f06IoND9pONie4{dnK}wHVfM{Uon=uBodCX%T^O(mx<}r_X%wrz&n8!TkF^_r7V;=LEXFJdT55=?RL;%180FB~W Ay8r+H diff --git a/litellm-proxy-extras/litellm_proxy_extras/_logging.py b/litellm-proxy-extras/litellm_proxy_extras/_logging.py index 15173005ce8..118caecf488 100644 --- a/litellm-proxy-extras/litellm_proxy_extras/_logging.py +++ b/litellm-proxy-extras/litellm_proxy_extras/_logging.py @@ -1,40 +1,12 @@ -import json import logging -import os -from datetime import datetime - - -class JsonFormatter(logging.Formatter): - def formatTime(self, record, datefmt=None): - dt = datetime.fromtimestamp(record.created) - return dt.isoformat() - - def format(self, record): - json_record = { - "message": record.getMessage(), - "level": record.levelname, - "timestamp": self.formatTime(record), - } - if record.exc_info: - json_record["stacktrace"] = self.formatException(record.exc_info) - return json.dumps(json_record) - - -def _is_json_enabled(): - try: - import litellm - return getattr(litellm, 'json_logs', False) - except (ImportError, AttributeError): - return os.getenv("JSON_LOGS", "false").lower() == "true" - +# Set up package logger logger = logging.getLogger("litellm_proxy_extras") - -if not logger.handlers: +if not logger.handlers: # Only add handler if none exists handler = logging.StreamHandler() - if _is_json_enabled(): - handler.setFormatter(JsonFormatter()) - else: - handler.setFormatter(logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")) + formatter = logging.Formatter( + "%(asctime)s - %(name)s - %(levelname)s - %(message)s" + ) + handler.setFormatter(formatter) logger.addHandler(handler) logger.setLevel(logging.INFO) diff --git a/litellm-proxy-extras/litellm_proxy_extras/migrations/20251119131227_add_prompt_versioning/migration.sql b/litellm-proxy-extras/litellm_proxy_extras/migrations/20251119131227_add_prompt_versioning/migration.sql index 43eb2401422..a9d9528bd24 100644 --- a/litellm-proxy-extras/litellm_proxy_extras/migrations/20251119131227_add_prompt_versioning/migration.sql +++ b/litellm-proxy-extras/litellm_proxy_extras/migrations/20251119131227_add_prompt_versioning/migration.sql @@ -1,12 +1,12 @@ -- DropIndex -DROP INDEX IF EXISTS "LiteLLM_PromptTable_prompt_id_key"; +DROP INDEX "LiteLLM_PromptTable_prompt_id_key"; -- AlterTable -ALTER TABLE "LiteLLM_PromptTable" -ADD COLUMN "version" INTEGER NOT NULL DEFAULT 1; +ALTER TABLE "LiteLLM_PromptTable" ADD COLUMN "version" INTEGER NOT NULL DEFAULT 1; -- CreateIndex -CREATE INDEX "LiteLLM_PromptTable_prompt_id_idx" ON "LiteLLM_PromptTable" ("prompt_id"); +CREATE INDEX "LiteLLM_PromptTable_prompt_id_idx" ON "LiteLLM_PromptTable"("prompt_id"); -- CreateIndex -CREATE UNIQUE INDEX "LiteLLM_PromptTable_prompt_id_version_key" ON "LiteLLM_PromptTable" ("prompt_id", "version"); \ No newline at end of file +CREATE UNIQUE INDEX "LiteLLM_PromptTable_prompt_id_version_key" ON "LiteLLM_PromptTable"("prompt_id", "version"); + diff --git a/litellm-proxy-extras/litellm_proxy_extras/schema.prisma b/litellm-proxy-extras/litellm_proxy_extras/schema.prisma index ca60b9e1bec..d7aa6e9f0d0 100644 --- a/litellm-proxy-extras/litellm_proxy_extras/schema.prisma +++ b/litellm-proxy-extras/litellm_proxy_extras/schema.prisma @@ -760,11 +760,6 @@ model LiteLLM_ManagedVectorStoresTable { updated_at DateTime @updatedAt litellm_credential_name String? litellm_params Json? - team_id String? - user_id String? - - @@index([team_id]) - @@index([user_id]) } // Guardrails table for storing guardrail configurations diff --git a/litellm-proxy-extras/litellm_proxy_extras/utils.py b/litellm-proxy-extras/litellm_proxy_extras/utils.py index f3155722187..7ffbe95be13 100644 --- a/litellm-proxy-extras/litellm_proxy_extras/utils.py +++ b/litellm-proxy-extras/litellm_proxy_extras/utils.py @@ -18,15 +18,14 @@ def str_to_bool(value: Optional[str]) -> bool: return value.lower() in ("true", "1", "t", "y", "yes") + def _get_prisma_env() -> dict: """Get environment variables for Prisma, handling offline mode if configured.""" prisma_env = os.environ.copy() if str_to_bool(os.getenv("PRISMA_OFFLINE_MODE")): # These env vars prevent Prisma from attempting downloads prisma_env["NPM_CONFIG_PREFER_OFFLINE"] = "true" - prisma_env["NPM_CONFIG_CACHE"] = os.getenv( - "NPM_CONFIG_CACHE", "/app/.cache/npm" - ) + prisma_env["NPM_CONFIG_CACHE"] = os.getenv("NPM_CONFIG_CACHE", "/app/.cache/npm") return prisma_env @@ -35,28 +34,29 @@ def _get_prisma_command() -> str: if str_to_bool(os.getenv("PRISMA_OFFLINE_MODE")): # Primary location where Prisma Python package installs the CLI default_cli_path = "/app/.cache/prisma-python/binaries/node_modules/.bin/prisma" - + # Check if custom path is provided (for flexibility) custom_cli_path = os.getenv("PRISMA_CLI_PATH") if custom_cli_path and os.path.exists(custom_cli_path): logger.info(f"Using custom Prisma CLI at {custom_cli_path}") return custom_cli_path - + # Check the default location if os.path.exists(default_cli_path): logger.info(f"Using cached Prisma CLI at {default_cli_path}") return default_cli_path - + # If not found, log warning and fall back logger.warning( f"Prisma CLI not found at {default_cli_path}. " "Falling back to Python wrapper (may attempt downloads)" ) - + # Fall back to the Python wrapper (will work in online mode) return "prisma" + class ProxyExtrasDBManager: @staticmethod def _get_prisma_dir() -> str: @@ -119,7 +119,7 @@ def _create_baseline_migration(schema_path: str) -> bool: stdout=open(migration_file, "w"), check=True, timeout=30, - env=prisma_env, + env=prisma_env ) # 3. Mark the migration as applied since it represents current state @@ -134,7 +134,7 @@ def _create_baseline_migration(schema_path: str) -> bool: ], check=True, timeout=30, - env=prisma_env, + env=prisma_env ) return True @@ -159,20 +159,14 @@ def _get_migration_names(migrations_dir: str) -> list: @staticmethod def _roll_back_migration(migration_name: str): """Mark a specific migration as rolled back""" - # Set up environment for offline mode if configured + # Set up environment for offline mode if configured prisma_env = _get_prisma_env() subprocess.run( - [ - _get_prisma_command(), - "migrate", - "resolve", - "--rolled-back", - migration_name, - ], + [_get_prisma_command(), "migrate", "resolve", "--rolled-back", migration_name], timeout=60, check=True, capture_output=True, - env=prisma_env, + env=prisma_env ) @staticmethod @@ -184,7 +178,7 @@ def _resolve_specific_migration(migration_name: str): timeout=60, check=True, capture_output=True, - env=prisma_env, + env=prisma_env ) @staticmethod @@ -234,8 +228,6 @@ def _is_idempotent_error(error_message: str) -> bool: r"duplicate key value violates", r"relation .* already exists", r"constraint .* already exists", - r"does not exist", - r"Can't drop database.* because it doesn't exist", ] for pattern in idempotent_patterns: @@ -256,7 +248,7 @@ def _resolve_all_migrations( if not database_url: logger.error("DATABASE_URL not set") return - + diff_dir = ( Path(migrations_dir) / "migrations" @@ -291,7 +283,7 @@ def _resolve_all_migrations( check=True, timeout=60, stdout=f, - env=_get_prisma_env(), + env=_get_prisma_env() ) except subprocess.CalledProcessError as e: logger.warning(f"Failed to generate migration diff: {e.stderr}") @@ -321,7 +313,7 @@ def _resolve_all_migrations( check=True, capture_output=True, text=True, - env=_get_prisma_env(), + env=_get_prisma_env() ) logger.info(f"prisma db execute stdout: {result.stdout}") logger.info("✅ Migration diff applied successfully") @@ -339,18 +331,12 @@ def _resolve_all_migrations( try: logger.info(f"Resolving migration: {migration_name}") subprocess.run( - [ - _get_prisma_command(), - "migrate", - "resolve", - "--applied", - migration_name, - ], + [_get_prisma_command(), "migrate", "resolve", "--applied", migration_name], timeout=60, check=True, capture_output=True, text=True, - env=_get_prisma_env(), + env=_get_prisma_env() ) logger.debug(f"Resolved migration: {migration_name}") except subprocess.CalledProcessError as e: @@ -389,7 +375,7 @@ def setup_database(use_migrate: bool = False) -> bool: check=True, capture_output=True, text=True, - env=_get_prisma_env(), + env=_get_prisma_env() ) logger.info(f"prisma migrate deploy stdout: {result.stdout}") @@ -411,42 +397,27 @@ def setup_database(use_migrate: bool = False) -> bool: ) if migration_match: failed_migration = migration_match.group(1) - if ProxyExtrasDBManager._is_idempotent_error(e.stderr): - logger.info( - f"Migration {failed_migration} failed due to idempotent error (e.g., column already exists), resolving as applied" - ) - ProxyExtrasDBManager._roll_back_migration( - failed_migration - ) - ProxyExtrasDBManager._resolve_specific_migration( - failed_migration - ) - logger.info( - f"✅ Migration {failed_migration} resolved." - ) - return True - else: - logger.info( - f"Found failed migration: {failed_migration}, marking as rolled back" - ) - # Mark the failed migration as rolled back - subprocess.run( - [ - _get_prisma_command(), - "migrate", - "resolve", - "--rolled-back", - failed_migration, - ], - timeout=60, - check=True, - capture_output=True, - text=True, - env=_get_prisma_env(), - ) - logger.info( - f"✅ Migration {failed_migration} marked as rolled back... retrying" - ) + logger.info( + f"Found failed migration: {failed_migration}, marking as rolled back" + ) + # Mark the failed migration as rolled back + subprocess.run( + [ + _get_prisma_command(), + "migrate", + "resolve", + "--rolled-back", + failed_migration, + ], + timeout=60, + check=True, + capture_output=True, + text=True, + env=_get_prisma_env() + ) + logger.info( + f"✅ Migration {failed_migration} marked as rolled back... retrying" + ) elif ( "P3005" in e.stderr and "database schema is not empty" in e.stderr diff --git a/litellm-proxy-extras/pyproject.toml b/litellm-proxy-extras/pyproject.toml index 5a0aa364e7d..862ebaffe2a 100644 --- a/litellm-proxy-extras/pyproject.toml +++ b/litellm-proxy-extras/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "litellm-proxy-extras" -version = "0.4.27" +version = "0.4.26" description = "Additional files for the LiteLLM Proxy. Reduces the size of the main litellm package." authors = ["BerriAI"] readme = "README.md" @@ -22,7 +22,7 @@ requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "0.4.27" +version = "0.4.26" version_files = [ "pyproject.toml:version", "../requirements.txt:litellm-proxy-extras==", diff --git a/litellm/__init__.py b/litellm/__init__.py index f5db57f76fd..e5c09702b9b 100644 --- a/litellm/__init__.py +++ b/litellm/__init__.py @@ -80,8 +80,6 @@ litellm_mode = os.getenv("LITELLM_MODE", "DEV") # "PRODUCTION", "DEV" if litellm_mode == "DEV": dotenv.load_dotenv() - - #################################################### if set_verbose: _turn_on_debug() diff --git a/litellm/_logging.py b/litellm/_logging.py index e222627e76c..b3156b15ba7 100644 --- a/litellm/_logging.py +++ b/litellm/_logging.py @@ -166,66 +166,6 @@ def _initialize_loggers_with_handler(handler: logging.Handler): lg.propagate = False # prevent bubbling to parent/root -def _get_uvicorn_json_log_config(): - """ - Generate a uvicorn log_config dictionary that applies JSON formatting to all loggers. - - This ensures that uvicorn's access logs, error logs, and all application logs - are formatted as JSON when json_logs is enabled. - """ - json_formatter_class = "litellm._logging.JsonFormatter" - - # Use the module-level log_level variable for consistency - uvicorn_log_level = log_level.upper() - - log_config = { - "version": 1, - "disable_existing_loggers": False, - "formatters": { - "json": { - "()": json_formatter_class, - }, - "default": { - "()": json_formatter_class, - }, - "access": { - "()": json_formatter_class, - }, - }, - "handlers": { - "default": { - "formatter": "json", - "class": "logging.StreamHandler", - "stream": "ext://sys.stdout", - }, - "access": { - "formatter": "access", - "class": "logging.StreamHandler", - "stream": "ext://sys.stdout", - }, - }, - "loggers": { - "uvicorn": { - "handlers": ["default"], - "level": uvicorn_log_level, - "propagate": False, - }, - "uvicorn.error": { - "handlers": ["default"], - "level": uvicorn_log_level, - "propagate": False, - }, - "uvicorn.access": { - "handlers": ["access"], - "level": uvicorn_log_level, - "propagate": False, - }, - }, - } - - return log_config - - def _turn_on_json(): """ Turn on JSON logging diff --git a/litellm/a2a_protocol/card_resolver.py b/litellm/a2a_protocol/card_resolver.py deleted file mode 100644 index 7c4c5af149d..00000000000 --- a/litellm/a2a_protocol/card_resolver.py +++ /dev/null @@ -1,97 +0,0 @@ -""" -Custom A2A Card Resolver for LiteLLM. - -Extends the A2A SDK's card resolver to support multiple well-known paths. -""" - -from typing import TYPE_CHECKING, Any, Dict, Optional - -from litellm._logging import verbose_logger - -if TYPE_CHECKING: - from a2a.types import AgentCard - -# Runtime imports with availability check -_A2ACardResolver: Any = None -AGENT_CARD_WELL_KNOWN_PATH: str = "/.well-known/agent-card.json" -PREV_AGENT_CARD_WELL_KNOWN_PATH: str = "/.well-known/agent.json" - -try: - from a2a.client import A2ACardResolver as _A2ACardResolver # type: ignore[no-redef] - from a2a.utils.constants import ( # type: ignore[no-redef] - AGENT_CARD_WELL_KNOWN_PATH, - PREV_AGENT_CARD_WELL_KNOWN_PATH, - ) -except ImportError: - pass - - -class LiteLLMA2ACardResolver(_A2ACardResolver): # type: ignore[misc] - """ - Custom A2A card resolver that supports multiple well-known paths. - - Extends the base A2ACardResolver to try both: - - /.well-known/agent-card.json (standard) - - /.well-known/agent.json (previous/alternative) - """ - - async def get_agent_card( - self, - relative_card_path: Optional[str] = None, - http_kwargs: Optional[Dict[str, Any]] = None, - ) -> "AgentCard": - """ - Fetch the agent card, trying multiple well-known paths. - - First tries the standard path, then falls back to the previous path. - - Args: - relative_card_path: Optional path to the agent card endpoint. - If None, tries both well-known paths. - http_kwargs: Optional dictionary of keyword arguments to pass to httpx.get - - Returns: - AgentCard from the A2A agent - - Raises: - A2AClientHTTPError or A2AClientJSONError if both paths fail - """ - # If a specific path is provided, use the parent implementation - if relative_card_path is not None: - return await super().get_agent_card( - relative_card_path=relative_card_path, - http_kwargs=http_kwargs, - ) - - # Try both well-known paths - paths = [ - AGENT_CARD_WELL_KNOWN_PATH, - PREV_AGENT_CARD_WELL_KNOWN_PATH, - ] - - last_error = None - for path in paths: - try: - verbose_logger.debug( - f"Attempting to fetch agent card from {self.base_url}{path}" - ) - return await super().get_agent_card( - relative_card_path=path, - http_kwargs=http_kwargs, - ) - except Exception as e: - verbose_logger.debug( - f"Failed to fetch agent card from {self.base_url}{path}: {e}" - ) - last_error = e - continue - - # If we get here, all paths failed - re-raise the last error - if last_error is not None: - raise last_error - - # This shouldn't happen, but just in case - raise Exception( - f"Failed to fetch agent card from {self.base_url}. " - f"Tried paths: {', '.join(paths)}" - ) diff --git a/litellm/a2a_protocol/main.py b/litellm/a2a_protocol/main.py index b326f9e7ed5..ae95faede22 100644 --- a/litellm/a2a_protocol/main.py +++ b/litellm/a2a_protocol/main.py @@ -6,7 +6,6 @@ import asyncio import datetime -import uuid from typing import TYPE_CHECKING, Any, AsyncIterator, Coroutine, Dict, Optional, Union import litellm @@ -21,6 +20,7 @@ ) from litellm.types.agents import LiteLLMSendMessageResponse from litellm.utils import client +import uuid if TYPE_CHECKING: from a2a.client import A2AClient as A2AClientType @@ -36,18 +36,13 @@ _A2AClient: Any = None try: + from a2a.client import A2ACardResolver # type: ignore[no-redef] from a2a.client import A2AClient as _A2AClient # type: ignore[no-redef] A2A_SDK_AVAILABLE = True except ImportError: pass -# Import our custom card resolver that supports multiple well-known paths -from litellm.a2a_protocol.card_resolver import LiteLLMA2ACardResolver - -# Use our custom resolver instead of the default A2A SDK resolver -A2ACardResolver = LiteLLMA2ACardResolver - def _set_usage_on_logging_obj( kwargs: Dict[str, Any], diff --git a/litellm/constants.py b/litellm/constants.py index 91cdc0ebdfc..49ca3a509b1 100644 --- a/litellm/constants.py +++ b/litellm/constants.py @@ -1165,12 +1165,6 @@ LITELLM_CLI_SESSION_TOKEN_PREFIX = "litellm-session-token" CLI_SSO_SESSION_CACHE_KEY_PREFIX = "cli_sso_session" CLI_JWT_TOKEN_NAME = "cli-jwt-token" -# Support both CLI_JWT_EXPIRATION_HOURS and LITELLM_CLI_JWT_EXPIRATION_HOURS for backwards compatibility -CLI_JWT_EXPIRATION_HOURS = int( - os.getenv("CLI_JWT_EXPIRATION_HOURS") - or os.getenv("LITELLM_CLI_JWT_EXPIRATION_HOURS") - or 24 -) ########################### DB CRON JOB NAMES ########################### DB_SPEND_UPDATE_JOB_NAME = "db_spend_update_job" @@ -1332,13 +1326,6 @@ DEFAULT_CHUNK_SIZE = int(os.getenv("DEFAULT_CHUNK_SIZE", 1000)) DEFAULT_CHUNK_OVERLAP = int(os.getenv("DEFAULT_CHUNK_OVERLAP", 200)) -########################### S3 Vectors RAG Constants ########################### -S3_VECTORS_DEFAULT_DIMENSION = int(os.getenv("S3_VECTORS_DEFAULT_DIMENSION", 1024)) -S3_VECTORS_DEFAULT_DISTANCE_METRIC = str( - os.getenv("S3_VECTORS_DEFAULT_DISTANCE_METRIC", "cosine") -) -S3_VECTORS_DEFAULT_NON_FILTERABLE_METADATA_KEYS = ["source_text"] - ########################### Microsoft SSO Constants ########################### MICROSOFT_USER_EMAIL_ATTRIBUTE = str( os.getenv("MICROSOFT_USER_EMAIL_ATTRIBUTE", "userPrincipalName") diff --git a/litellm/cost_calculator.py b/litellm/cost_calculator.py index 490f0288b00..1ab7e260a83 100644 --- a/litellm/cost_calculator.py +++ b/litellm/cost_calculator.py @@ -23,11 +23,7 @@ from litellm.litellm_core_utils.llm_cost_calc.utils import ( CostCalculatorUtils, _generic_cost_per_character, - _get_service_tier_cost_key, - _parse_prompt_tokens_details, - calculate_cost_component, generic_cost_per_token, - get_billable_input_tokens, select_cost_metric_for_model, ) from litellm.llms.anthropic.cost_calculation import ( @@ -435,18 +431,12 @@ def cost_per_token( # noqa: PLR0915 model=model, custom_llm_provider=custom_llm_provider ) - if ( - model_info.get("input_cost_per_token", 0) > 0 - or model_info.get("output_cost_per_token", 0) > 0 - ): - return generic_cost_per_token( - model=model, - usage=usage_block, - custom_llm_provider=custom_llm_provider, - service_tier=service_tier, + if model_info["input_cost_per_token"] > 0: + ## COST PER TOKEN ## + prompt_tokens_cost_usd_dollar = ( + model_info["input_cost_per_token"] * prompt_tokens ) - - if ( + elif ( model_info.get("input_cost_per_second", None) is not None and response_time_ms is not None ): @@ -461,7 +451,11 @@ def cost_per_token( # noqa: PLR0915 model_info["input_cost_per_second"] * response_time_ms / 1000 # type: ignore ) - if ( + if model_info["output_cost_per_token"] > 0: + completion_tokens_cost_usd_dollar = ( + model_info["output_cost_per_token"] * completion_tokens + ) + elif ( model_info.get("output_cost_per_second", None) is not None and response_time_ms is not None ): @@ -961,10 +955,7 @@ def completion_cost( # noqa: PLR0915 router_model_id=router_model_id, ) - potential_model_names = [ - selected_model, - _get_response_model(completion_response), - ] + potential_model_names = [selected_model, _get_response_model(completion_response)] if model is not None: potential_model_names.append(model) @@ -1719,16 +1710,10 @@ def default_image_cost_calculator( ) # Priority 1: Use per-image pricing if available (for gpt-image-1 and similar models) - if ( - "input_cost_per_image" in cost_info - and cost_info["input_cost_per_image"] is not None - ): + if "input_cost_per_image" in cost_info and cost_info["input_cost_per_image"] is not None: return cost_info["input_cost_per_image"] * n # Priority 2: Fall back to per-pixel pricing for backward compatibility - elif ( - "input_cost_per_pixel" in cost_info - and cost_info["input_cost_per_pixel"] is not None - ): + elif "input_cost_per_pixel" in cost_info and cost_info["input_cost_per_pixel"] is not None: return cost_info["input_cost_per_pixel"] * height * width * n else: raise Exception( @@ -1848,22 +1833,9 @@ 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: - # Subtract cached tokens from prompt_tokens before calculating cost - # Fixes issue where cached tokens are being charged again total_prompt_cost = ( - get_billable_input_tokens(usage) * (input_cost_per_token) / 2 + usage.prompt_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 - ) if output_cost_per_token_batches: total_completion_cost = usage.completion_tokens * output_cost_per_token_batches elif output_cost_per_token: diff --git a/litellm/experimental_mcp_client/client.py b/litellm/experimental_mcp_client/client.py index e2de3cd5021..582d044023c 100644 --- a/litellm/experimental_mcp_client/client.py +++ b/litellm/experimental_mcp_client/client.py @@ -4,26 +4,22 @@ import asyncio import base64 -from typing import Any, Awaitable, Callable, Dict, List, Optional, Tuple, TypeVar, Union +from typing import Awaitable, Callable, Dict, List, Optional, TypeVar, Union import httpx from mcp import ClientSession, ReadResourceResult, Resource, StdioServerParameters from mcp.client.sse import sse_client from mcp.client.stdio import stdio_client - -try: - from mcp.client.streamable_http import streamable_http_client # type: ignore -except ImportError: - streamable_http_client = None -from mcp.types import CallToolRequestParams as MCPCallToolRequestParams -from mcp.types import CallToolResult as MCPCallToolResult +from mcp.client.streamable_http import streamable_http_client from mcp.types import ( + CallToolRequestParams as MCPCallToolRequestParams, GetPromptRequestParams, GetPromptResult, Prompt, ResourceTemplate, - TextContent, ) +from mcp.types import CallToolResult as MCPCallToolResult +from mcp.types import TextContent from mcp.types import Tool as MCPTool from pydantic import AnyUrl @@ -78,91 +74,57 @@ def __init__( if auth_value: self.update_auth_value(auth_value) - def _create_transport_context( - self, - ) -> Tuple[Any, Optional[httpx.AsyncClient]]: - """ - Create the appropriate transport context based on transport type. - - Returns: - Tuple of (transport_context, http_client). - http_client is only set for HTTP transport and needs cleanup. - """ - http_client: Optional[httpx.AsyncClient] = None - - if self.transport_type == MCPTransport.stdio: - if not self.stdio_config: - raise ValueError("stdio_config is required for stdio transport") - server_params = StdioServerParameters( - command=self.stdio_config.get("command", ""), - args=self.stdio_config.get("args", []), - env=self.stdio_config.get("env", {}), - ) - return stdio_client(server_params), None - - if self.transport_type == MCPTransport.sse: - headers = self._get_auth_headers() - httpx_client_factory = self._create_httpx_client_factory() - return sse_client( - url=self.server_url, - timeout=self.timeout, - headers=headers, - httpx_client_factory=httpx_client_factory, - ), None - - # HTTP transport (default) - headers = self._get_auth_headers() - httpx_client_factory = self._create_httpx_client_factory() - verbose_logger.debug( - "litellm headers for streamable_http_client: %s", headers - ) - http_client = httpx_client_factory( - headers=headers, - timeout=httpx.Timeout(self.timeout), - ) - transport_ctx = streamable_http_client( - url=self.server_url, - http_client=http_client, - ) - return transport_ctx, http_client - - async def _execute_session_operation( - self, - transport_ctx: Any, - operation: Callable[[ClientSession], Awaitable[TSessionResult]], - ) -> TSessionResult: - """ - Execute an operation within a transport and session context. - - Handles entering/exiting contexts and running the operation. - """ - transport = await transport_ctx.__aenter__() - try: - read_stream, write_stream = transport[0], transport[1] - session_ctx = ClientSession(read_stream, write_stream) - session = await session_ctx.__aenter__() - try: - await session.initialize() - return await operation(session) - finally: - try: - await session_ctx.__aexit__(None, None, None) - except BaseException as e: - verbose_logger.debug(f"Error during session context exit: {e}") - finally: - try: - await transport_ctx.__aexit__(None, None, None) - except BaseException as e: - verbose_logger.debug(f"Error during transport context exit: {e}") - async def run_with_session( self, operation: Callable[[ClientSession], Awaitable[TSessionResult]] ) -> TSessionResult: """Open a session, run the provided coroutine, and clean up.""" + transport_ctx = None http_client: Optional[httpx.AsyncClient] = None + try: - transport_ctx, http_client = self._create_transport_context() - return await self._execute_session_operation(transport_ctx, operation) + if self.transport_type == MCPTransport.stdio: + if not self.stdio_config: + raise ValueError("stdio_config is required for stdio transport") + + server_params = StdioServerParameters( + command=self.stdio_config.get("command", ""), + args=self.stdio_config.get("args", []), + env=self.stdio_config.get("env", {}), + ) + transport_ctx = stdio_client(server_params) + elif self.transport_type == MCPTransport.sse: + headers = self._get_auth_headers() + httpx_client_factory = self._create_httpx_client_factory() + transport_ctx = sse_client( + url=self.server_url, + timeout=self.timeout, + headers=headers, + httpx_client_factory=httpx_client_factory, + ) + else: + headers = self._get_auth_headers() + httpx_client_factory = self._create_httpx_client_factory() + verbose_logger.debug( + "litellm headers for streamable_http_client: %s", headers + ) + http_client = httpx_client_factory( + headers=headers, + timeout=httpx.Timeout(self.timeout), + ) + transport_ctx = streamable_http_client( + url=self.server_url, + http_client=http_client, + ) + + if transport_ctx is None: + raise RuntimeError("Failed to create transport context") + + async with transport_ctx as transport: + read_stream, write_stream = transport[0], transport[1] + session_ctx = ClientSession(read_stream, write_stream) + async with session_ctx as session: + await session.initialize() + return await operation(session) except Exception: verbose_logger.warning( "MCP client run_with_session failed for %s", self.server_url or "stdio" @@ -170,10 +132,7 @@ async def run_with_session( raise finally: if http_client is not None: - try: - await http_client.aclose() - except BaseException as e: - verbose_logger.debug(f"Error during http_client cleanup: {e}") + await http_client.aclose() def update_auth_value(self, mcp_auth_value: Union[str, Dict[str, str]]): """ @@ -286,9 +245,7 @@ async def _list_tools_operation(session: ClientSession): return [] async def call_tool( - self, - call_tool_request_params: MCPCallToolRequestParams, - host_progress_callback: Optional[Callable] = None + self, call_tool_request_params: MCPCallToolRequestParams ) -> MCPCallToolResult: """ Call an MCP Tool. @@ -297,28 +254,13 @@ async def call_tool( f"MCP client calling tool '{call_tool_request_params.name}' with arguments: {call_tool_request_params.arguments}" ) - async def on_progress(progress: float, total: float | None, message: str | None): - percentage = (progress / total * 100) if total else 0 - verbose_logger.info( - f"MCP Tool '{call_tool_request_params.name}' progress: " - f"{progress}/{total} ({percentage:.0f}%) - {message or ''}" - ) - - # Forward to Host if callback provided - if host_progress_callback: - try: - await host_progress_callback(progress, total) - except Exception as e: - verbose_logger.warning(f"Failed to forward to Host: {e}") - async def _call_tool_operation(session: ClientSession): verbose_logger.debug("MCP client sending tool call to session") return await session.call_tool( name=call_tool_request_params.name, arguments=call_tool_request_params.arguments, - progress_callback=on_progress, - ) + try: tool_result = await self.run_with_session(_call_tool_operation) verbose_logger.info( diff --git a/litellm/integrations/callback_configs.json b/litellm/integrations/callback_configs.json index 6a003b8c499..6b30b6b736e 100644 --- a/litellm/integrations/callback_configs.json +++ b/litellm/integrations/callback_configs.json @@ -83,33 +83,6 @@ }, "description": "Datadog Logging Integration" }, - { - "id": "datadog_cost_management", - "displayName": "Datadog Cost Management", - "logo": "datadog.png", - "supports_key_team_logging": false, - "dynamic_params": { - "dd_api_key": { - "type": "password", - "ui_name": "API Key", - "description": "Datadog API key for authentication", - "required": true - }, - "dd_app_key": { - "type": "password", - "ui_name": "App Key", - "description": "Datadog Application Key for Cloud Cost Management", - "required": true - }, - "dd_site": { - "type": "text", - "ui_name": "Site", - "description": "Datadog site URL (e.g., us5.datadoghq.com)", - "required": true - } - }, - "description": "Datadog Cloud Cost Management Integration" - }, { "id": "lago", "displayName": "Lago", @@ -434,4 +407,4 @@ }, "description": "SQS Queue (AWS) Logging Integration" } -] \ No newline at end of file +] diff --git a/litellm/integrations/custom_guardrail.py b/litellm/integrations/custom_guardrail.py index a5bb530fc56..6a76b57e7f7 100644 --- a/litellm/integrations/custom_guardrail.py +++ b/litellm/integrations/custom_guardrail.py @@ -516,9 +516,7 @@ def add_standard_logging_guardrail_information_to_request_data( from litellm.types.utils import GuardrailMode # Use event_type if provided, otherwise fall back to self.event_hook - guardrail_mode: Union[ - GuardrailEventHooks, GuardrailMode, List[GuardrailEventHooks] - ] + guardrail_mode: Union[GuardrailEventHooks, GuardrailMode, List[GuardrailEventHooks]] if event_type is not None: guardrail_mode = event_type elif isinstance(self.event_hook, Mode): @@ -526,21 +524,11 @@ def add_standard_logging_guardrail_information_to_request_data( else: guardrail_mode = self.event_hook # type: ignore[assignment] - from litellm.litellm_core_utils.core_helpers import ( - filter_exceptions_from_params, - ) - - # Sanitize the response to ensure it's JSON serializable and free of circular refs - # This prevents RecursionErrors in downstream loggers (Langfuse, Datadog, etc.) - clean_guardrail_response = filter_exceptions_from_params( - guardrail_json_response - ) - slg = StandardLoggingGuardrailInformation( guardrail_name=self.guardrail_name, guardrail_provider=guardrail_provider, guardrail_mode=guardrail_mode, - guardrail_response=clean_guardrail_response, + guardrail_response=guardrail_json_response, guardrail_status=guardrail_status, start_time=start_time, end_time=end_time, diff --git a/litellm/integrations/datadog/datadog.py b/litellm/integrations/datadog/datadog.py index 735d1005d2c..503e8d8c87a 100644 --- a/litellm/integrations/datadog/datadog.py +++ b/litellm/integrations/datadog/datadog.py @@ -32,7 +32,6 @@ get_datadog_service, get_datadog_source, get_datadog_tags, - get_datadog_base_url_from_env, ) from litellm.litellm_core_utils.dd_tracing import tracer from litellm.llms.custom_httpx.http_handler import ( @@ -101,9 +100,7 @@ def __init__( self._configure_dd_direct_api() # Optional override for testing - dd_base_url = get_datadog_base_url_from_env() - if dd_base_url: - self.intake_url = f"{dd_base_url}/api/v2/logs" + self._apply_dd_base_url_override() self.sync_client = _get_httpx_client() asyncio.create_task(self.periodic_flush()) self.flush_lock = asyncio.Lock() @@ -162,6 +159,18 @@ def _configure_dd_direct_api(self) -> None: self.DD_API_KEY = os.getenv("DD_API_KEY") self.intake_url = f"https://http-intake.logs.{os.getenv('DD_SITE')}/api/v2/logs" + def _apply_dd_base_url_override(self) -> None: + """ + Apply base URL override for testing purposes + """ + dd_base_url: Optional[str] = ( + os.getenv("_DATADOG_BASE_URL") + or os.getenv("DATADOG_BASE_URL") + or os.getenv("DD_BASE_URL") + ) + if dd_base_url is not None: + self.intake_url = f"{dd_base_url}/api/v2/logs" + async def async_log_success_event(self, kwargs, response_obj, start_time, end_time): """ Async Log success events to Datadog diff --git a/litellm/integrations/datadog/datadog_cost_management.py b/litellm/integrations/datadog/datadog_cost_management.py deleted file mode 100644 index 2eb94b59dd8..00000000000 --- a/litellm/integrations/datadog/datadog_cost_management.py +++ /dev/null @@ -1,204 +0,0 @@ -import asyncio -import os -import time -from datetime import datetime -from typing import Dict, List, Optional, Tuple - -from litellm._logging import verbose_logger -from litellm.integrations.custom_batch_logger import CustomBatchLogger -from litellm.llms.custom_httpx.http_handler import ( - get_async_httpx_client, - httpxSpecialProvider, -) -from litellm.types.integrations.datadog_cost_management import ( - DatadogFOCUSCostEntry, -) -from litellm.types.utils import StandardLoggingPayload - - -class DatadogCostManagementLogger(CustomBatchLogger): - def __init__(self, **kwargs): - self.dd_api_key = os.getenv("DD_API_KEY") - self.dd_app_key = os.getenv("DD_APP_KEY") - self.dd_site = os.getenv("DD_SITE", "datadoghq.com") - - if not self.dd_api_key or not self.dd_app_key: - verbose_logger.warning( - "Datadog Cost Management: DD_API_KEY and DD_APP_KEY are required. Integration will not work." - ) - - self.upload_url = f"https://api.{self.dd_site}/api/v2/cost/custom_costs" - - self.async_client = get_async_httpx_client( - llm_provider=httpxSpecialProvider.LoggingCallback - ) - - # Initialize lock and start periodic flush task - self.flush_lock = asyncio.Lock() - asyncio.create_task(self.periodic_flush()) - - # Check if flush_lock is already in kwargs to avoid double passing (unlikely but safe) - if "flush_lock" not in kwargs: - kwargs["flush_lock"] = self.flush_lock - - super().__init__(**kwargs) - - async def async_log_success_event(self, kwargs, response_obj, start_time, end_time): - try: - standard_logging_object: Optional[StandardLoggingPayload] = kwargs.get( - "standard_logging_object", None - ) - - if standard_logging_object is None: - return - - # Only log if there is a cost associated - if standard_logging_object.get("response_cost", 0) > 0: - self.log_queue.append(standard_logging_object) - - if len(self.log_queue) >= self.batch_size: - await self.async_send_batch() - - except Exception as e: - verbose_logger.exception( - f"Datadog Cost Management: Error in async_log_success_event: {str(e)}" - ) - - async def async_send_batch(self): - if not self.log_queue: - return - - try: - # Aggregate costs from the batch - aggregated_entries = self._aggregate_costs(self.log_queue) - - if not aggregated_entries: - return - - # Send to Datadog - await self._upload_to_datadog(aggregated_entries) - - # Clear queue only on success (or if we decide to drop on failure) - # CustomBatchLogger clears queue in flush_queue, so we just process here - - except Exception as e: - verbose_logger.exception( - f"Datadog Cost Management: Error in async_send_batch: {str(e)}" - ) - - def _aggregate_costs( - self, logs: List[StandardLoggingPayload] - ) -> List[DatadogFOCUSCostEntry]: - """ - Aggregates costs by Provider, Model, and Date. - Returns a list of DatadogFOCUSCostEntry. - """ - aggregator: Dict[Tuple[str, str, str, Tuple[Tuple[str, str], ...]], DatadogFOCUSCostEntry] = {} - - for log in logs: - try: - # Extract keys for aggregation - provider = log.get("custom_llm_provider") or "unknown" - model = log.get("model") or "unknown" - cost = log.get("response_cost", 0) - - if cost == 0: - continue - - # Get date strings (FOCUS format requires specific keys, but for aggregation we group by Day) - # UTC date - # We interpret "ChargePeriod" as the day of the request. - ts = log.get("startTime") or time.time() - dt = datetime.fromtimestamp(ts) - date_str = dt.strftime("%Y-%m-%d") - - # ChargePeriodStart and End - # If we want daily granularity, end date is usually same day or next day? - # Datadog Custom Costs usually expects periods. - # "ChargePeriodStart": "2023-01-01", "ChargePeriodEnd": "2023-12-31" in example. - # If we send daily, we can say Start=Date, End=Date. - - # Grouping Key: Provider + Model + Date + Tags? - # For simplicity, let's aggregate by Provider + Model + Date first. - # If we handle tags, we need to include them in the key. - - tags = self._extract_tags(log) - tags_key = tuple(sorted(tags.items())) if tags else () - - key = (provider, model, date_str, tags_key) - - if key not in aggregator: - aggregator[key] = { - "ProviderName": provider, - "ChargeDescription": f"LLM Usage for {model}", - "ChargePeriodStart": date_str, - "ChargePeriodEnd": date_str, - "BilledCost": 0.0, - "BillingCurrency": "USD", - "Tags": tags if tags else None, - } - - aggregator[key]["BilledCost"] += cost - - except Exception as e: - verbose_logger.warning( - f"Error processing log for cost aggregation: {e}" - ) - continue - - return list(aggregator.values()) - - def _extract_tags(self, log: StandardLoggingPayload) -> Dict[str, str]: - from litellm.integrations.datadog.datadog_handler import ( - get_datadog_env, - get_datadog_hostname, - get_datadog_pod_name, - get_datadog_service, - ) - - tags = { - "env": get_datadog_env(), - "service": get_datadog_service(), - "host": get_datadog_hostname(), - "pod_name": get_datadog_pod_name(), - } - - # Add metadata as tags - metadata = log.get("metadata", {}) - if metadata: - # Add user info - if "user_api_key_alias" in metadata: - tags["user"] = str(metadata["user_api_key_alias"]) - if "user_api_key_team_alias" in metadata: - tags["team"] = str(metadata["user_api_key_team_alias"]) - # model_group is not in StandardLoggingMetadata TypedDict, so we need to access it via dict.get() - model_group = metadata.get("model_group") # type: ignore[misc] - if model_group: - tags["model_group"] = str(model_group) - - return tags - - async def _upload_to_datadog(self, payload: List[Dict]): - if not self.dd_api_key or not self.dd_app_key: - return - - headers = { - "Content-Type": "application/json", - "DD-API-KEY": self.dd_api_key, - "DD-APPLICATION-KEY": self.dd_app_key, - } - - # The API endpoint expects a list of objects directly in the body (file content behavior) - from litellm.litellm_core_utils.safe_json_dumps import safe_dumps - - data_json = safe_dumps(payload) - - response = await self.async_client.put( - self.upload_url, content=data_json, headers=headers - ) - - response.raise_for_status() - - verbose_logger.debug( - f"Datadog Cost Management: Uploaded {len(payload)} cost entries. Status: {response.status_code}" - ) diff --git a/litellm/integrations/datadog/datadog_handler.py b/litellm/integrations/datadog/datadog_handler.py index e2f30f2f614..26fab77759e 100644 --- a/litellm/integrations/datadog/datadog_handler.py +++ b/litellm/integrations/datadog/datadog_handler.py @@ -20,14 +20,6 @@ def get_datadog_hostname() -> str: return os.getenv("HOSTNAME", "") -def get_datadog_base_url_from_env() -> Optional[str]: - """ - Get base URL override from common DD_BASE_URL env var. - This is useful for testing or custom endpoints. - """ - return os.getenv("DD_BASE_URL") - - def get_datadog_env() -> str: return os.getenv("DD_ENV", "unknown") diff --git a/litellm/integrations/datadog/datadog_llm_obs.py b/litellm/integrations/datadog/datadog_llm_obs.py index 4f6a5b339a7..6ffdbc0a005 100644 --- a/litellm/integrations/datadog/datadog_llm_obs.py +++ b/litellm/integrations/datadog/datadog_llm_obs.py @@ -21,7 +21,6 @@ from litellm.integrations.datadog.datadog_handler import ( get_datadog_service, get_datadog_tags, - get_datadog_base_url_from_env, ) from litellm.litellm_core_utils.dd_tracing import tracer from litellm.litellm_core_utils.prompt_templates.common_utils import ( @@ -44,22 +43,24 @@ class DataDogLLMObsLogger(CustomBatchLogger): def __init__(self, **kwargs): try: verbose_logger.debug("DataDogLLMObs: Initializing logger") - # Configure DataDog endpoint (Agent or Direct API) - # Use LITELLM_DD_AGENT_HOST to avoid conflicts with ddtrace's DD_AGENT_HOST - dd_agent_host = os.getenv("LITELLM_DD_AGENT_HOST") + if os.getenv("DD_API_KEY", None) is None: + raise Exception("DD_API_KEY is not set, set 'DD_API_KEY=<>'") + if os.getenv("DD_SITE", None) is None: + raise Exception( + "DD_SITE is not set, set 'DD_SITE=<>', example sit = `us5.datadoghq.com`" + ) self.async_client = get_async_httpx_client( llm_provider=httpxSpecialProvider.LoggingCallback ) self.DD_API_KEY = os.getenv("DD_API_KEY") + self.DD_SITE = os.getenv("DD_SITE") + self.intake_url = ( + f"https://api.{self.DD_SITE}/api/intake/llm-obs/v1/trace/spans" + ) - if dd_agent_host: - self._configure_dd_agent(dd_agent_host=dd_agent_host) - else: - self._configure_dd_direct_api() - - # Optional override for testing - dd_base_url = get_datadog_base_url_from_env() + # testing base url + dd_base_url = os.getenv("DD_BASE_URL") if dd_base_url: self.intake_url = f"{dd_base_url}/api/intake/llm-obs/v1/trace/spans" @@ -77,38 +78,6 @@ def __init__(self, **kwargs): verbose_logger.exception(f"DataDogLLMObs: Error initializing - {str(e)}") raise e - def _configure_dd_agent(self, dd_agent_host: str): - """ - Configure the Datadog logger to send traces to the Agent. - """ - # When using the Agent, LLM Observability Intake does NOT require the API Key - # Reference: https://docs.datadoghq.com/llm_observability/setup/sdk/#agent-setup - - # Use specific port for LLM Obs (Trace Agent) to avoid conflict with Logs Agent (10518) - agent_port = os.getenv("LITELLM_DD_LLM_OBS_PORT", "8126") - self.DD_SITE = "localhost" # Not used for URL construction in agent mode - self.intake_url = ( - f"http://{dd_agent_host}:{agent_port}/api/intake/llm-obs/v1/trace/spans" - ) - verbose_logger.debug(f"DataDogLLMObs: Using DD Agent at {self.intake_url}") - - def _configure_dd_direct_api(self): - """ - Configure the Datadog logger to send traces directly to the Datadog API. - """ - if not self.DD_API_KEY: - raise Exception("DD_API_KEY is not set, set 'DD_API_KEY=<>'") - - self.DD_SITE = os.getenv("DD_SITE") - if not self.DD_SITE: - raise Exception( - "DD_SITE is not set, set 'DD_SITE=<>', example site = `us5.datadoghq.com`" - ) - - self.intake_url = ( - f"https://api.{self.DD_SITE}/api/intake/llm-obs/v1/trace/spans" - ) - def _get_datadog_llm_obs_params(self) -> Dict: """ Get the datadog_llm_observability_params from litellm.datadog_llm_observability_params @@ -195,14 +164,13 @@ async def async_send_batch(self): json_payload = safe_dumps(payload) - headers = {"Content-Type": "application/json"} - if self.DD_API_KEY: - headers["DD-API-KEY"] = self.DD_API_KEY - response = await self.async_client.post( url=self.intake_url, content=json_payload, - headers=headers, + headers={ + "DD-API-KEY": self.DD_API_KEY, + "Content-Type": "application/json", + }, ) if response.status_code != 202: diff --git a/litellm/integrations/langfuse/langfuse.py b/litellm/integrations/langfuse/langfuse.py index 7bf97665fd2..46ada3c3930 100644 --- a/litellm/integrations/langfuse/langfuse.py +++ b/litellm/integrations/langfuse/langfuse.py @@ -23,7 +23,6 @@ from litellm.litellm_core_utils.core_helpers import ( safe_deep_copy, reconstruct_model_name, - filter_exceptions_from_params, ) from litellm.litellm_core_utils.redact_messages import redact_user_api_key_info from litellm.integrations.langfuse.langfuse_mock_client import ( @@ -76,8 +75,9 @@ def _extract_cache_read_input_tokens(usage_obj) -> int: # Check prompt_tokens_details.cached_tokens (used by Gemini and other providers) if hasattr(usage_obj, "prompt_tokens_details"): prompt_tokens_details = getattr(usage_obj, "prompt_tokens_details", None) - if prompt_tokens_details is not None and hasattr( - prompt_tokens_details, "cached_tokens" + if ( + prompt_tokens_details is not None + and hasattr(prompt_tokens_details, "cached_tokens") ): cached_tokens = getattr(prompt_tokens_details, "cached_tokens", None) if ( @@ -540,6 +540,7 @@ def _log_langfuse_v2( # noqa: PLR0915 verbose_logger.debug("Langfuse Layer Logging - logging to langfuse v2") try: + metadata = metadata or {} standard_logging_object: Optional[StandardLoggingPayload] = cast( Optional[StandardLoggingPayload], kwargs.get("standard_logging_object", None), @@ -705,10 +706,9 @@ def _log_langfuse_v2( # noqa: PLR0915 clean_metadata["litellm_response_cost"] = cost if standard_logging_object is not None: - hidden_params = standard_logging_object.get("hidden_params", {}) - clean_metadata["hidden_params"] = filter_exceptions_from_params( - hidden_params - ) + clean_metadata["hidden_params"] = standard_logging_object[ + "hidden_params" + ] if ( litellm.langfuse_default_tags is not None diff --git a/litellm/integrations/langfuse/langfuse_prompt_management.py b/litellm/integrations/langfuse/langfuse_prompt_management.py index 3986fc6a6ef..8f73eabad44 100644 --- a/litellm/integrations/langfuse/langfuse_prompt_management.py +++ b/litellm/integrations/langfuse/langfuse_prompt_management.py @@ -300,59 +300,43 @@ def log_failure_event(self, kwargs, response_obj, start_time, end_time): ) async def async_log_success_event(self, kwargs, response_obj, start_time, end_time): - try: - standard_callback_dynamic_params = kwargs.get( - "standard_callback_dynamic_params" - ) - langfuse_logger_to_use = LangFuseHandler.get_langfuse_logger_for_request( - globalLangfuseLogger=self, - standard_callback_dynamic_params=standard_callback_dynamic_params, - in_memory_dynamic_logger_cache=in_memory_dynamic_logger_cache, - ) - langfuse_logger_to_use.log_event_on_langfuse( - kwargs=kwargs, - response_obj=response_obj, - start_time=start_time, - end_time=end_time, - user_id=kwargs.get("user", None), - ) - except Exception as e: - from litellm._logging import verbose_logger - - verbose_logger.exception( - f"Langfuse Layer Error - Exception occurred while logging success event: {str(e)}" - ) - self.handle_callback_failure(callback_name="langfuse") + standard_callback_dynamic_params = kwargs.get( + "standard_callback_dynamic_params" + ) + langfuse_logger_to_use = LangFuseHandler.get_langfuse_logger_for_request( + globalLangfuseLogger=self, + standard_callback_dynamic_params=standard_callback_dynamic_params, + in_memory_dynamic_logger_cache=in_memory_dynamic_logger_cache, + ) + langfuse_logger_to_use.log_event_on_langfuse( + kwargs=kwargs, + response_obj=response_obj, + start_time=start_time, + end_time=end_time, + user_id=kwargs.get("user", None), + ) async def async_log_failure_event(self, kwargs, response_obj, start_time, end_time): - try: - standard_callback_dynamic_params = kwargs.get( - "standard_callback_dynamic_params" - ) - langfuse_logger_to_use = LangFuseHandler.get_langfuse_logger_for_request( - globalLangfuseLogger=self, - standard_callback_dynamic_params=standard_callback_dynamic_params, - in_memory_dynamic_logger_cache=in_memory_dynamic_logger_cache, - ) - standard_logging_object = cast( - Optional[StandardLoggingPayload], - kwargs.get("standard_logging_object", None), - ) - if standard_logging_object is None: - return - langfuse_logger_to_use.log_event_on_langfuse( - start_time=start_time, - end_time=end_time, - response_obj=None, - user_id=kwargs.get("user", None), - status_message=standard_logging_object["error_str"], - level="ERROR", - kwargs=kwargs, - ) - except Exception as e: - from litellm._logging import verbose_logger - - verbose_logger.exception( - f"Langfuse Layer Error - Exception occurred while logging failure event: {str(e)}" - ) - self.handle_callback_failure(callback_name="langfuse") + standard_callback_dynamic_params = kwargs.get( + "standard_callback_dynamic_params" + ) + langfuse_logger_to_use = LangFuseHandler.get_langfuse_logger_for_request( + globalLangfuseLogger=self, + standard_callback_dynamic_params=standard_callback_dynamic_params, + in_memory_dynamic_logger_cache=in_memory_dynamic_logger_cache, + ) + standard_logging_object = cast( + Optional[StandardLoggingPayload], + kwargs.get("standard_logging_object", None), + ) + if standard_logging_object is None: + return + langfuse_logger_to_use.log_event_on_langfuse( + start_time=start_time, + end_time=end_time, + response_obj=None, + user_id=kwargs.get("user", None), + status_message=standard_logging_object["error_str"], + level="ERROR", + kwargs=kwargs, + ) diff --git a/litellm/integrations/opentelemetry.py b/litellm/integrations/opentelemetry.py index 2da747f1100..a8a7fa77b3d 100644 --- a/litellm/integrations/opentelemetry.py +++ b/litellm/integrations/opentelemetry.py @@ -144,7 +144,6 @@ def __init__( self.OTEL_EXPORTER = self.config.exporter self.OTEL_ENDPOINT = self.config.endpoint self.OTEL_HEADERS = self.config.headers - self._tracer_provider_cache: Dict[str, Any] = {} self._init_tracing(tracer_provider) _debug_otel = str(os.getenv("DEBUG_OTEL", "False")).lower() @@ -616,20 +615,12 @@ def _get_tracer_with_dynamic_headers(self, dynamic_headers: dict): """Create a temporary tracer with dynamic headers for this request only.""" from opentelemetry.sdk.trace import TracerProvider - # Prevents thread exhaustion by reusing providers for the same credential sets (e.g. per-team keys) - cache_key = str(sorted(dynamic_headers.items())) - if cache_key in self._tracer_provider_cache: - return self._tracer_provider_cache[cache_key].get_tracer(LITELLM_TRACER_NAME) - # Create a temporary tracer provider with dynamic headers temp_provider = TracerProvider(resource=self._get_litellm_resource(self.config)) temp_provider.add_span_processor( self._get_span_processor(dynamic_headers=dynamic_headers) ) - # Store in cache for reuse - self._tracer_provider_cache[cache_key] = temp_provider - return temp_provider.get_tracer(LITELLM_TRACER_NAME) def construct_dynamic_otel_headers( @@ -1006,7 +997,7 @@ def _emit_semantic_logs(self, kwargs, response_obj, span: Span): try: from opentelemetry.sdk._logs import LogRecord as SdkLogRecord # type: ignore[attr-defined] # OTEL < 1.39.0 except ImportError: - from opentelemetry.sdk._logs._internal import LogRecord as SdkLogRecord # type: ignore[attr-defined, no-redef] # OTEL >= 1.39.0 + from opentelemetry.sdk._logs._internal import LogRecord as SdkLogRecord # OTEL >= 1.39.0 otel_logger = get_logger(LITELLM_LOGGER_NAME) @@ -1627,7 +1618,6 @@ def set_attributes( # noqa: PLR0915 ) except Exception as e: - self.handle_callback_failure(callback_name= self.callback_name) verbose_logger.exception( "OpenTelemetry logging error in set_attributes %s", str(e) ) diff --git a/litellm/integrations/prometheus.py b/litellm/integrations/prometheus.py index 2c897cb0692..bafb0d88c82 100644 --- a/litellm/integrations/prometheus.py +++ b/litellm/integrations/prometheus.py @@ -229,18 +229,14 @@ def __init__( # noqa: PLR0915 self.litellm_remaining_api_key_requests_for_model = self._gauge_factory( "litellm_remaining_api_key_requests_for_model", "Remaining Requests API Key can make for model (model based rpm limit on key)", - labelnames=self.get_labels_for_metric( - "litellm_remaining_api_key_requests_for_model" - ), + labelnames=["hashed_api_key", "api_key_alias", "model"], ) # Remaining MODEL TPM limit for API Key self.litellm_remaining_api_key_tokens_for_model = self._gauge_factory( "litellm_remaining_api_key_tokens_for_model", "Remaining Tokens API Key can make for model (model based tpm limit on key)", - labelnames=self.get_labels_for_metric( - "litellm_remaining_api_key_tokens_for_model" - ), + labelnames=["hashed_api_key", "api_key_alias", "model"], ) ######################################## @@ -316,18 +312,6 @@ def __init__( # noqa: PLR0915 labelnames=self.get_labels_for_metric("litellm_deployment_state"), ) - self.litellm_deployment_tpm_limit = self._gauge_factory( - "litellm_deployment_tpm_limit", - "Deployment TPM limit found in config", - labelnames=self.get_labels_for_metric("litellm_deployment_tpm_limit"), - ) - - self.litellm_deployment_rpm_limit = self._gauge_factory( - "litellm_deployment_rpm_limit", - "Deployment RPM limit found in config", - labelnames=self.get_labels_for_metric("litellm_deployment_rpm_limit"), - ) - self.litellm_deployment_cooled_down = self._counter_factory( "litellm_deployment_cooled_down", "LLM Deployment Analytics - Number of times a deployment has been cooled down by LiteLLM load balancing logic. exception_status is the status of the exception that caused the deployment to be cooled down", @@ -389,9 +373,15 @@ def __init__( # noqa: PLR0915 self.litellm_llm_api_failed_requests_metric = self._counter_factory( name="litellm_llm_api_failed_requests_metric", documentation="deprecated - use litellm_proxy_failed_requests_metric", - labelnames=self.get_labels_for_metric( - "litellm_llm_api_failed_requests_metric" - ), + labelnames=[ + "end_user", + "hashed_api_key", + "api_key_alias", + "model", + "team", + "team_alias", + "user", + ], ) self.litellm_requests_metric = self._counter_factory( @@ -901,7 +891,7 @@ async def async_log_success_event(self, kwargs, response_obj, start_time, end_ti model = kwargs.get("model", "") litellm_params = kwargs.get("litellm_params", {}) or {} - _metadata = litellm_params.get("metadata") or {} + _metadata = litellm_params.get("metadata", {}) get_end_user_id_for_cost_tracking = _get_cached_end_user_id_for_cost_tracking() end_user_id = get_end_user_id_for_cost_tracking( @@ -964,8 +954,6 @@ async def async_log_success_event(self, kwargs, response_obj, start_time, end_ti route=standard_logging_payload["metadata"].get( "user_api_key_request_route" ), - client_ip=standard_logging_payload["metadata"].get("requester_ip_address"), - user_agent=standard_logging_payload["metadata"].get("user_agent"), ) if ( @@ -1023,7 +1011,6 @@ async def async_log_success_event(self, kwargs, response_obj, start_time, end_ti user_api_key_alias=user_api_key_alias, kwargs=kwargs, metadata=_metadata, - model_id=enum_values.model_id, ) # set latency metrics @@ -1178,15 +1165,26 @@ async def _increment_remaining_budget_metrics( response_cost: float, user_id: Optional[str] = None, ): - _metadata = litellm_params.get("metadata") or {} - _team_spend = _metadata.get("user_api_key_team_spend", None) - _team_max_budget = _metadata.get("user_api_key_team_max_budget", None) + _team_spend = litellm_params.get("metadata", {}).get( + "user_api_key_team_spend", None + ) + _team_max_budget = litellm_params.get("metadata", {}).get( + "user_api_key_team_max_budget", None + ) - _api_key_spend = _metadata.get("user_api_key_spend", None) - _api_key_max_budget = _metadata.get("user_api_key_max_budget", None) + _api_key_spend = litellm_params.get("metadata", {}).get( + "user_api_key_spend", None + ) + _api_key_max_budget = litellm_params.get("metadata", {}).get( + "user_api_key_max_budget", None + ) - _user_spend = _metadata.get("user_api_key_user_spend", None) - _user_max_budget = _metadata.get("user_api_key_user_max_budget", None) + _user_spend = litellm_params.get("metadata", {}).get( + "user_api_key_user_spend", None + ) + _user_max_budget = litellm_params.get("metadata", {}).get( + "user_api_key_user_max_budget", None + ) await self._set_api_key_budget_metrics_after_api_request( user_api_key=user_api_key, @@ -1247,7 +1245,6 @@ def _set_virtual_key_rate_limit_metrics( user_api_key_alias: Optional[str], kwargs: dict, metadata: dict, - model_id: Optional[str] = None, ): from litellm.proxy.common_utils.callback_utils import ( get_model_group_from_litellm_kwargs, @@ -1269,11 +1266,11 @@ def _set_virtual_key_rate_limit_metrics( ) self.litellm_remaining_api_key_requests_for_model.labels( - user_api_key, user_api_key_alias, model_group, model_id + user_api_key, user_api_key_alias, model_group ).set(remaining_requests) self.litellm_remaining_api_key_tokens_for_model.labels( - user_api_key, user_api_key_alias, model_group, model_id + user_api_key, user_api_key_alias, model_group ).set(remaining_tokens) def _set_latency_metrics( @@ -1299,14 +1296,12 @@ def _set_latency_metrics( time_to_first_token_seconds is not None and kwargs.get("stream", False) is True # only emit for streaming requests ): - _ttft_labels = prometheus_label_factory( - supported_enum_labels=self.get_labels_for_metric( - metric_name="litellm_llm_api_time_to_first_token_metric" - ), - enum_values=enum_values, - ) self.litellm_llm_api_time_to_first_token_metric.labels( - **_ttft_labels + model, + user_api_key, + user_api_key_alias, + user_api_team, + user_api_team_alias, ).observe(time_to_first_token_seconds) else: verbose_logger.debug( @@ -1346,7 +1341,7 @@ def _set_latency_metrics( # request queue time (time from arrival to processing start) _litellm_params = kwargs.get("litellm_params", {}) or {} - queue_time_seconds = (_litellm_params.get("metadata") or {}).get( + queue_time_seconds = _litellm_params.get("metadata", {}).get( "queue_time_seconds" ) if queue_time_seconds is not None and queue_time_seconds >= 0: @@ -1370,14 +1365,14 @@ async def async_log_failure_event(self, kwargs, response_obj, start_time, end_ti standard_logging_payload: StandardLoggingPayload = kwargs.get( "standard_logging_object", {} ) - + if self._should_skip_metrics_for_invalid_key( kwargs=kwargs, standard_logging_payload=standard_logging_payload ): return - + model = kwargs.get("model", "") - + litellm_params = kwargs.get("litellm_params", {}) or {} get_end_user_id_for_cost_tracking = _get_cached_end_user_id_for_cost_tracking() @@ -1401,7 +1396,6 @@ async def async_log_failure_event(self, kwargs, response_obj, start_time, end_ti user_api_team, user_api_team_alias, user_id, - standard_logging_payload.get("model_id", ""), ).inc() self.set_llm_deployment_failure_metrics(kwargs) except Exception as e: @@ -1419,57 +1413,49 @@ def _extract_status_code( ) -> Optional[int]: """ Extract HTTP status code from various input formats for validation. - + This is a centralized helper to extract status code from different callback function signatures. Handles both ProxyException (uses 'code') and standard exceptions (uses 'status_code'). - + Args: kwargs: Dictionary potentially containing 'exception' key enum_values: Object with 'status_code' attribute exception: Exception object to extract status code from directly - + Returns: Status code as integer if found, None otherwise """ status_code = None - + # Try from enum_values first (most common in our callbacks) - if ( - enum_values - and hasattr(enum_values, "status_code") - and enum_values.status_code - ): + if enum_values and hasattr(enum_values, "status_code") and enum_values.status_code: try: status_code = int(enum_values.status_code) except (ValueError, TypeError): pass - + if not status_code and exception: # ProxyException uses 'code' attribute, other exceptions may use 'status_code' - status_code = getattr(exception, "status_code", None) or getattr( - exception, "code", None - ) + status_code = getattr(exception, "status_code", None) or getattr(exception, "code", None) if status_code is not None: try: status_code = int(status_code) except (ValueError, TypeError): status_code = None - + if not status_code and kwargs: exception_in_kwargs = kwargs.get("exception") if exception_in_kwargs: - status_code = getattr( - exception_in_kwargs, "status_code", None - ) or getattr(exception_in_kwargs, "code", None) + status_code = getattr(exception_in_kwargs, "status_code", None) or getattr(exception_in_kwargs, "code", None) if status_code is not None: try: status_code = int(status_code) except (ValueError, TypeError): status_code = None - + return status_code - + def _is_invalid_api_key_request( self, status_code: Optional[int], @@ -1477,23 +1463,23 @@ def _is_invalid_api_key_request( ) -> bool: """ Determine if a request has an invalid API key based on status code and exception. - + This method prevents invalid authentication attempts from being recorded in Prometheus metrics. A 401 status code is the definitive indicator of authentication failure. Additionally, we check exception messages for authentication error patterns to catch cases where the exception hasn't been converted to a ProxyException yet. - + Args: status_code: HTTP status code (401 indicates authentication error) exception: Exception object to check for auth-related error messages - + Returns: True if the request has an invalid API key and metrics should be skipped, False otherwise """ if status_code == 401: return True - + # Handle cases where AssertionError is raised before conversion to ProxyException if exception is not None: exception_str = str(exception).lower() @@ -1506,9 +1492,9 @@ def _is_invalid_api_key_request( ] if any(pattern in exception_str for pattern in auth_error_patterns): return True - + return False - + def _should_skip_metrics_for_invalid_key( self, kwargs: Optional[dict] = None, @@ -1519,18 +1505,18 @@ def _should_skip_metrics_for_invalid_key( ) -> bool: """ Determine if Prometheus metrics should be skipped for invalid API key requests. - + This is a centralized validation method that extracts status code and exception information from various callback function signatures and determines if the request represents an invalid API key attempt that should be filtered from metrics. - + Args: kwargs: Dictionary potentially containing exception and other data user_api_key_dict: User API key authentication object (currently unused) enum_values: Object with status_code attribute standard_logging_payload: Standard logging payload dictionary exception: Exception object to check directly - + Returns: True if metrics should be skipped (invalid key detected), False otherwise """ @@ -1539,17 +1525,17 @@ def _should_skip_metrics_for_invalid_key( enum_values=enum_values, exception=exception, ) - + if exception is None and kwargs: exception = kwargs.get("exception") - + if self._is_invalid_api_key_request(status_code, exception=exception): verbose_logger.debug( "Skipping Prometheus metrics for invalid API key request: " f"status_code={status_code}, exception={type(exception).__name__ if exception else None}" ) return True - + return False async def async_post_call_failure_hook( @@ -1590,10 +1576,6 @@ async def async_post_call_failure_hook( litellm_params=request_data, proxy_server_request=request_data.get("proxy_server_request", {}), ) - _metadata = request_data.get("metadata", {}) or {} - model_id = _metadata.get("model_info", {}).get("id") or request_data.get( - "model_info", {} - ).get("id") enum_values = UserAPIKeyLabelValues( end_user=user_api_key_dict.end_user_id, user=user_api_key_dict.user_id, @@ -1608,9 +1590,6 @@ async def async_post_call_failure_hook( exception_class=self._get_exception_class_name(original_exception), tags=_tags, route=user_api_key_dict.request_route, - client_ip=_metadata.get("requester_ip_address"), - user_agent=_metadata.get("user_agent"), - model_id=model_id, ) _labels = prometheus_label_factory( supported_enum_labels=self.get_labels_for_metric( @@ -1650,7 +1629,6 @@ async def async_post_call_success_hook( ): return - _metadata = data.get("metadata", {}) or {} enum_values = UserAPIKeyLabelValues( end_user=user_api_key_dict.end_user_id, hashed_api_key=user_api_key_dict.api_key, @@ -1666,8 +1644,6 @@ async def async_post_call_success_hook( litellm_params=data, proxy_server_request=data.get("proxy_server_request", {}), ), - client_ip=_metadata.get("requester_ip_address"), - user_agent=_metadata.get("user_agent"), ) _labels = prometheus_label_factory( supported_enum_labels=self.get_labels_for_metric( @@ -1708,7 +1684,7 @@ def set_llm_deployment_failure_metrics(self, request_kwargs: dict): exception = request_kwargs.get("exception", None) llm_provider = _litellm_params.get("custom_llm_provider", None) - + if self._should_skip_metrics_for_invalid_key( kwargs=request_kwargs, standard_logging_payload=standard_logging_payload, @@ -1740,10 +1716,6 @@ def set_llm_deployment_failure_metrics(self, request_kwargs: dict): "user_api_key_team_alias" ], tags=standard_logging_payload.get("request_tags", []), - client_ip=standard_logging_payload["metadata"].get( - "requester_ip_address" - ), - user_agent=standard_logging_payload["metadata"].get("user_agent"), ) """ @@ -1781,49 +1753,6 @@ def set_llm_deployment_failure_metrics(self, request_kwargs: dict): ) ) - def _set_deployment_tpm_rpm_limit_metrics( - self, - model_info: dict, - litellm_params: dict, - litellm_model_name: Optional[str], - model_id: Optional[str], - api_base: Optional[str], - llm_provider: Optional[str], - ): - """ - Set the deployment TPM and RPM limits metrics - """ - tpm = model_info.get("tpm") or litellm_params.get("tpm") - rpm = model_info.get("rpm") or litellm_params.get("rpm") - - if tpm is not None: - _labels = prometheus_label_factory( - supported_enum_labels=self.get_labels_for_metric( - metric_name="litellm_deployment_tpm_limit" - ), - enum_values=UserAPIKeyLabelValues( - litellm_model_name=litellm_model_name, - model_id=model_id, - api_base=api_base, - api_provider=llm_provider, - ), - ) - self.litellm_deployment_tpm_limit.labels(**_labels).set(tpm) - - if rpm is not None: - _labels = prometheus_label_factory( - supported_enum_labels=self.get_labels_for_metric( - metric_name="litellm_deployment_rpm_limit" - ), - enum_values=UserAPIKeyLabelValues( - litellm_model_name=litellm_model_name, - model_id=model_id, - api_base=api_base, - api_provider=llm_provider, - ), - ) - self.litellm_deployment_rpm_limit.labels(**_labels).set(rpm) - def set_llm_deployment_success_metrics( self, request_kwargs: dict, @@ -1857,16 +1786,6 @@ def set_llm_deployment_success_metrics( _model_info = _metadata.get("model_info") or {} model_id = _model_info.get("id", None) - if _model_info or _litellm_params: - self._set_deployment_tpm_rpm_limit_metrics( - model_info=_model_info, - litellm_params=_litellm_params, - litellm_model_name=litellm_model_name, - model_id=model_id, - api_base=api_base, - llm_provider=llm_provider, - ) - remaining_requests: Optional[int] = None remaining_tokens: Optional[int] = None if additional_headers := standard_logging_payload["hidden_params"][ @@ -2344,10 +2263,7 @@ async def _initialize_api_key_budget_metrics(self): async def fetch_keys( page_size: int, page: int - ) -> Tuple[ - List[Union[str, UserAPIKeyAuth, LiteLLM_DeletedVerificationToken]], - Optional[int], - ]: + ) -> Tuple[List[Union[str, UserAPIKeyAuth, LiteLLM_DeletedVerificationToken]], Optional[int]]: key_list_response = await _list_key_helper( prisma_client=prisma_client, page=page, @@ -2463,16 +2379,12 @@ async def _initialize_user_and_team_count_metrics(self): # Get total user count total_users = await prisma_client.db.litellm_usertable.count() self.litellm_total_users_metric.set(total_users) - verbose_logger.debug( - f"Prometheus: set litellm_total_users to {total_users}" - ) + verbose_logger.debug(f"Prometheus: set litellm_total_users to {total_users}") # Get total team count total_teams = await prisma_client.db.litellm_teamtable.count() self.litellm_teams_count_metric.set(total_teams) - verbose_logger.debug( - f"Prometheus: set litellm_teams_count to {total_teams}" - ) + verbose_logger.debug(f"Prometheus: set litellm_teams_count to {total_teams}") except Exception as e: verbose_logger.exception( f"Error initializing user/team count metrics: {str(e)}" @@ -2500,8 +2412,8 @@ async def _set_team_budget_metrics_after_api_request( self, user_api_team: Optional[str], user_api_team_alias: Optional[str], - team_spend: Optional[float], - team_max_budget: Optional[float], + team_spend: float, + team_max_budget: float, response_cost: float, ): """ @@ -2663,7 +2575,7 @@ async def _set_api_key_budget_metrics_after_api_request( user_api_key: Optional[str], user_api_key_alias: Optional[str], response_cost: float, - key_max_budget: Optional[float], + key_max_budget: float, key_spend: Optional[float], ): if user_api_key: @@ -2680,7 +2592,7 @@ async def _assemble_key_object( self, user_api_key: str, user_api_key_alias: str, - key_max_budget: Optional[float], + key_max_budget: float, key_spend: Optional[float], response_cost: float, ) -> UserAPIKeyAuth: diff --git a/litellm/litellm_core_utils/get_litellm_params.py b/litellm/litellm_core_utils/get_litellm_params.py index 060e98fd49f..e290101f8bf 100644 --- a/litellm/litellm_core_utils/get_litellm_params.py +++ b/litellm/litellm_core_utils/get_litellm_params.py @@ -93,11 +93,8 @@ def get_litellm_params( "text_completion": text_completion, "azure_ad_token_provider": azure_ad_token_provider, "user_continue_message": user_continue_message, - "base_model": base_model - or ( - _get_base_model_from_litellm_call_metadata(metadata=metadata) - if metadata - else None + "base_model": base_model or ( + _get_base_model_from_litellm_call_metadata(metadata=metadata) if metadata else None ), "litellm_trace_id": litellm_trace_id, "litellm_session_id": litellm_session_id, @@ -142,7 +139,5 @@ def get_litellm_params( "aws_sts_endpoint": kwargs.get("aws_sts_endpoint"), "aws_external_id": kwargs.get("aws_external_id"), "aws_bedrock_runtime_endpoint": kwargs.get("aws_bedrock_runtime_endpoint"), - "tpm": kwargs.get("tpm"), - "rpm": kwargs.get("rpm"), } return litellm_params diff --git a/litellm/litellm_core_utils/litellm_logging.py b/litellm/litellm_core_utils/litellm_logging.py index 0d9245a686a..d3bcfe8200e 100644 --- a/litellm/litellm_core_utils/litellm_logging.py +++ b/litellm/litellm_core_utils/litellm_logging.py @@ -205,11 +205,6 @@ ### GLOBAL VARIABLES ### -# Cache custom pricing keys as frozenset for O(1) lookups instead of looping through 49 keys -_CUSTOM_PRICING_KEYS: frozenset = frozenset( - CustomPricingLiteLLMParams.model_fields.keys() -) - sentry_sdk_instance = None capture_exception = None add_breadcrumb = None @@ -335,9 +330,7 @@ def __init__( self.start_time = start_time # log the call start time self.call_type = call_type self.litellm_call_id = litellm_call_id - self.litellm_trace_id: str = ( - litellm_trace_id if litellm_trace_id else str(uuid.uuid4()) - ) + self.litellm_trace_id: str = litellm_trace_id if litellm_trace_id else str(uuid.uuid4()) self.function_id = function_id self.streaming_chunks: List[Any] = [] # for generating complete stream response self.sync_streaming_chunks: List[ @@ -546,11 +539,10 @@ def update_environment_variables( if "stream_options" in additional_params: self.stream_options = additional_params["stream_options"] ## check if custom pricing set ## - if any( - litellm_params.get(key) is not None - for key in _CUSTOM_PRICING_KEYS & litellm_params.keys() - ): - self.custom_pricing = True + custom_pricing_keys = CustomPricingLiteLLMParams.model_fields.keys() + for key in custom_pricing_keys: + if litellm_params.get(key) is not None: + self.custom_pricing = True if "custom_llm_provider" in self.model_call_details: self.custom_llm_provider = self.model_call_details["custom_llm_provider"] @@ -1638,19 +1630,11 @@ def _transform_usage_objects(self, result): "standard_logging_object" ) ) is not None: - response_dict = ( + standard_logging_payload["response"] = ( result.model_dump() if hasattr(result, "model_dump") else dict(result) ) - # Ensure usage is properly included with transformed chat format - if transformed_usage is not None: - response_dict["usage"] = ( - transformed_usage.model_dump() - if hasattr(transformed_usage, "model_dump") - else dict(transformed_usage) - ) - standard_logging_payload["response"] = response_dict elif isinstance(result, TranscriptionResponse): from litellm.litellm_core_utils.llm_cost_calc.usage_object_transformation import ( TranscriptionUsageObjectTransformation, @@ -3312,7 +3296,6 @@ def _get_masked_values( "token", "key", "secret", - "vertex_credentials", ] return { k: ( @@ -4265,21 +4248,15 @@ def use_custom_pricing_for_model(litellm_params: Optional[dict]) -> bool: if litellm_params is None: return False - # Check litellm_params using set intersection (only check keys that exist in both) - matching_keys = _CUSTOM_PRICING_KEYS & litellm_params.keys() - for key in matching_keys: - if litellm_params.get(key) is not None: - return True - - # Check model_info metadata: dict = litellm_params.get("metadata", {}) or {} model_info: dict = metadata.get("model_info", {}) or {} - if model_info: - matching_keys = _CUSTOM_PRICING_KEYS & model_info.keys() - for key in matching_keys: - if model_info.get(key) is not None: - return True + custom_pricing_keys = CustomPricingLiteLLMParams.model_fields.keys() + for key in custom_pricing_keys: + if litellm_params.get(key, None) is not None: + return True + elif model_info.get(key, None) is not None: + return True return False @@ -4467,7 +4444,6 @@ def get_standard_logging_metadata( user_api_key_request_route=None, spend_logs_metadata=None, requester_ip_address=None, - user_agent=None, requester_metadata=None, prompt_management_metadata=prompt_management_metadata, applied_guardrails=applied_guardrails, @@ -4548,10 +4524,6 @@ def get_usage_from_response_obj( ) elif isinstance(usage, Usage): return usage - elif isinstance(usage, ResponseAPIUsage): - return ResponseAPILoggingUtils._transform_response_api_usage_to_chat_usage( - usage - ) elif isinstance(usage, dict): if ResponseAPILoggingUtils._is_response_api_usage(usage): return ( @@ -4680,10 +4652,7 @@ def get_hidden_params( @staticmethod def strip_trailing_slash(api_base: Optional[str]) -> Optional[str]: if api_base: - if api_base.endswith("//"): - return api_base.rstrip("/") - if api_base[-1] == "/": - return api_base[:-1] + return api_base.rstrip("/") return api_base @staticmethod @@ -5157,7 +5126,6 @@ def get_standard_logging_object_payload( model_group=_model_group, model_id=_model_id, requester_ip_address=clean_metadata.get("requester_ip_address", None), - user_agent=clean_metadata.get("user_agent", None), messages=StandardLoggingPayloadSetup.append_system_prompt_messages( kwargs=kwargs, messages=kwargs.get("messages") ), @@ -5223,7 +5191,6 @@ def get_standard_logging_metadata( user_api_key_team_alias=None, spend_logs_metadata=None, requester_ip_address=None, - user_agent=None, requester_metadata=None, user_api_key_end_user_id=None, prompt_management_metadata=None, diff --git a/litellm/litellm_core_utils/llm_cost_calc/utils.py b/litellm/litellm_core_utils/llm_cost_calc/utils.py index fe06641a389..785976ed319 100644 --- a/litellm/litellm_core_utils/llm_cost_calc/utils.py +++ b/litellm/litellm_core_utils/llm_cost_calc/utils.py @@ -23,15 +23,6 @@ def _is_above_128k(tokens: float) -> bool: return False -def get_billable_input_tokens(usage: Usage) -> int: - """ - Returns the number of billable input tokens. - Subtracts cached tokens from prompt tokens if applicable. - """ - details = _parse_prompt_tokens_details(usage) - return usage.prompt_tokens - details["cache_hit_tokens"] - - def select_cost_metric_for_model( model_info: ModelInfo, ) -> Literal["cost_per_character", "cost_per_token"]: @@ -199,6 +190,7 @@ def _get_token_base_cost( 1000 if "k" in threshold_str else 1 ) if usage.prompt_tokens > threshold: + prompt_base_cost = cast( float, _get_cost_per_unit(model_info, key, prompt_base_cost) ) @@ -574,28 +566,14 @@ def generic_cost_per_token( # noqa: PLR0915 if usage.prompt_tokens_details: prompt_tokens_details = _parse_prompt_tokens_details(usage) - ## EDGE CASE - text tokens not set or includes cached tokens (double-counting) - ## Some providers (like xAI) report text_tokens = prompt_tokens (including cached) - ## We detect this when: text_tokens + cached_tokens + other > prompt_tokens - ## Ref: https://github.com/BerriAI/litellm/issues/19680, #14874, #14875 - - cache_hit = prompt_tokens_details["cache_hit_tokens"] - text_tokens = prompt_tokens_details["text_tokens"] - audio_tokens = prompt_tokens_details["audio_tokens"] - cache_creation = prompt_tokens_details["cache_creation_tokens"] - image_tokens = prompt_tokens_details["image_tokens"] - - # Check for double-counting: sum of details > prompt_tokens means overlap - total_details = text_tokens + cache_hit + audio_tokens + cache_creation + image_tokens - has_double_counting = cache_hit > 0 and total_details > usage.prompt_tokens + ## EDGE CASE - text tokens not set inside PromptTokensDetails - if text_tokens == 0 or has_double_counting: + if prompt_tokens_details["text_tokens"] == 0: text_tokens = ( usage.prompt_tokens - - cache_hit - - audio_tokens - - cache_creation - - image_tokens + - prompt_tokens_details["cache_hit_tokens"] + - prompt_tokens_details["audio_tokens"] + - prompt_tokens_details["cache_creation_tokens"] ) prompt_tokens_details["text_tokens"] = text_tokens @@ -641,11 +619,7 @@ def generic_cost_per_token( # noqa: PLR0915 # Calculate text tokens as remainder when we have a breakdown # This handles cases like OpenAI's reasoning models where text_tokens isn't provided text_tokens = max( - 0, - usage.completion_tokens - - reasoning_tokens - - audio_tokens - - image_tokens, + 0, usage.completion_tokens - reasoning_tokens - audio_tokens - image_tokens ) else: # No breakdown at all, all tokens are text tokens 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 25ad0a570cb..bbe28e3ec2c 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 @@ -21,13 +21,11 @@ ChatCompletionMessageToolCall, ChatCompletionRedactedThinkingBlock, Choices, - CompletionTokensDetailsWrapper, Delta, EmbeddingResponse, Function, HiddenParams, ImageResponse, - PromptTokensDetailsWrapper, ) from litellm.types.utils import Logprobs as TextCompletionLogprobs from litellm.types.utils import ( @@ -306,22 +304,6 @@ def convert_to_image_response( "text_tokens": 0, } - # Map Responses API naming to Chat Completions API naming for cost calculator - if usage.get("prompt_tokens") is None: - usage["prompt_tokens"] = usage.get("input_tokens", 0) - if usage.get("completion_tokens") is None: - usage["completion_tokens"] = usage.get("output_tokens", 0) - - # Convert dicts to wrapper objects so getattr() works in cost calculation - if isinstance(usage.get("input_tokens_details"), dict): - usage["prompt_tokens_details"] = PromptTokensDetailsWrapper( - **usage["input_tokens_details"] - ) - if isinstance(usage.get("output_tokens_details"), dict): - usage["completion_tokens_details"] = CompletionTokensDetailsWrapper( - **usage["output_tokens_details"] - ) - if model_response_object is None: model_response_object = ImageResponse(**response_object) return model_response_object diff --git a/litellm/litellm_core_utils/logging_worker.py b/litellm/litellm_core_utils/logging_worker.py index d5eca9eeb55..13a83956edd 100644 --- a/litellm/litellm_core_utils/logging_worker.py +++ b/litellm/litellm_core_utils/logging_worker.py @@ -415,28 +415,6 @@ def _safe_log(self, level: str, message: str) -> None: """ Safely log a message during shutdown, suppressing errors if logging is closed. """ - # Check if logger has valid handlers before attempting to log - # During shutdown, handlers may be closed, causing ValueError when writing - if not hasattr(verbose_logger, 'handlers') or not verbose_logger.handlers: - return - - # Check if any handler has a valid stream - has_valid_handler = False - for handler in verbose_logger.handlers: - try: - if hasattr(handler, 'stream') and handler.stream and not handler.stream.closed: - has_valid_handler = True - break - elif not hasattr(handler, 'stream'): - # Non-stream handlers (like NullHandler) are always valid - has_valid_handler = True - break - except (AttributeError, ValueError): - continue - - if not has_valid_handler: - return - try: if level == "debug": verbose_logger.debug(message) diff --git a/litellm/litellm_core_utils/prompt_templates/factory.py b/litellm/litellm_core_utils/prompt_templates/factory.py index 03488ad0183..30263543fc6 100644 --- a/litellm/litellm_core_utils/prompt_templates/factory.py +++ b/litellm/litellm_core_utils/prompt_templates/factory.py @@ -1677,16 +1677,13 @@ def convert_to_anthropic_tool_result( ] = [] for content in content_list: if content["type"] == "text": - # Only include cache_control if explicitly set and not None - # to avoid sending "cache_control": null which breaks some API channels - text_content: AnthropicMessagesToolResultContent = { - "type": "text", - "text": content["text"], - } - cache_control_value = content.get("cache_control") - if cache_control_value is not None: - text_content["cache_control"] = cache_control_value - anthropic_content_list.append(text_content) + anthropic_content_list.append( + AnthropicMessagesToolResultContent( + type="text", + text=content["text"], + cache_control=content.get("cache_control", None), + ) + ) elif content["type"] == "image_url": format = ( content["image_url"].get("format") @@ -4411,7 +4408,7 @@ def _bedrock_tools_pt(tools: List) -> List[BedrockToolBlock]: ] """ """ - Bedrock toolConfig looks like: + Bedrock toolConfig looks like: "tools": [ { "toolSpec": { @@ -4439,7 +4436,6 @@ def _bedrock_tools_pt(tools: List) -> List[BedrockToolBlock]: tool_block_list: List[BedrockToolBlock] = [] for tool in tools: - # Handle regular function tools parameters = tool.get("function", {}).get( "parameters", {"type": "object", "properties": {}} ) diff --git a/litellm/litellm_core_utils/prompt_templates/image_handling.py b/litellm/litellm_core_utils/prompt_templates/image_handling.py index 7137a4e4222..5d0bedb776d 100644 --- a/litellm/litellm_core_utils/prompt_templates/image_handling.py +++ b/litellm/litellm_core_utils/prompt_templates/image_handling.py @@ -31,19 +31,15 @@ def _process_image_response(response: Response, url: str) -> str: f"Error: Image size ({size_mb:.2f}MB) exceeds maximum allowed size ({MAX_IMAGE_URL_DOWNLOAD_SIZE_MB}MB). url={url}" ) - # Stream download with size checking to prevent downloading huge files - max_bytes = int(MAX_IMAGE_URL_DOWNLOAD_SIZE_MB * 1024 * 1024) - image_bytes = bytearray() - bytes_downloaded = 0 + image_bytes = response.content - for chunk in response.iter_bytes(chunk_size=8192): - bytes_downloaded += len(chunk) - if bytes_downloaded > max_bytes: - size_mb = bytes_downloaded / (1024 * 1024) + # Check actual size after download if Content-Length was not available + if content_length is None: + size_mb = len(image_bytes) / (1024 * 1024) + if size_mb > MAX_IMAGE_URL_DOWNLOAD_SIZE_MB: raise litellm.ImageFetchError( f"Error: Image size ({size_mb:.2f}MB) exceeds maximum allowed size ({MAX_IMAGE_URL_DOWNLOAD_SIZE_MB}MB). url={url}" ) - image_bytes.extend(chunk) base64_image = base64.b64encode(image_bytes).decode("utf-8") diff --git a/litellm/llms/anthropic/chat/transformation.py b/litellm/llms/anthropic/chat/transformation.py index 1b61b533275..82eccee596d 100644 --- a/litellm/llms/anthropic/chat/transformation.py +++ b/litellm/llms/anthropic/chat/transformation.py @@ -290,19 +290,10 @@ def _map_tool_choice( elif tool_choice == "none": _tool_choice = AnthropicMessagesToolChoice(type="none") elif isinstance(tool_choice, dict): - if "type" in tool_choice and "function" not in tool_choice: - tool_type = tool_choice.get("type") - if tool_type == "auto": - _tool_choice = AnthropicMessagesToolChoice(type="auto") - elif tool_type == "required" or tool_type == "any": - _tool_choice = AnthropicMessagesToolChoice(type="any") - elif tool_type == "none": - _tool_choice = AnthropicMessagesToolChoice(type="none") - else: - _tool_name = tool_choice.get("function", {}).get("name") - if _tool_name is not None: - _tool_choice = AnthropicMessagesToolChoice(type="tool") - _tool_choice["name"] = _tool_name + _tool_name = tool_choice.get("function", {}).get("name") + _tool_choice = AnthropicMessagesToolChoice(type="tool") + if _tool_name is not None: + _tool_choice["name"] = _tool_name if parallel_tool_use is not None: # Anthropic uses 'disable_parallel_tool_use' flag to determine if parallel tool use is allowed @@ -1378,7 +1369,7 @@ def calculate_usage( else 0 ) completion_token_details = CompletionTokensDetailsWrapper( - reasoning_tokens=reasoning_tokens if reasoning_tokens > 0 else 0, + reasoning_tokens=reasoning_tokens if reasoning_tokens > 0 else None, text_tokens=completion_tokens - reasoning_tokens if reasoning_tokens > 0 else completion_tokens, ) total_tokens = prompt_tokens + completion_tokens diff --git a/litellm/llms/anthropic/experimental_pass_through/adapters/transformation.py b/litellm/llms/anthropic/experimental_pass_through/adapters/transformation.py index 5ba0754b744..1706f045f14 100644 --- a/litellm/llms/anthropic/experimental_pass_through/adapters/transformation.py +++ b/litellm/llms/anthropic/experimental_pass_through/adapters/transformation.py @@ -168,36 +168,6 @@ def _extract_signature_from_tool_use_content( return provider_specific_fields.get("signature") return None - def _add_cache_control_if_applicable( - self, - source: Any, - target: Any, - model: Optional[str], - ) -> None: - """ - Extract cache_control from source and add to target if it should be preserved. - - This method accepts Any type to support both regular dicts and TypedDict objects. - TypedDict objects (like ChatCompletionTextObject, ChatCompletionImageObject, etc.) - are dicts at runtime but have specific types at type-check time. Using Any allows - this method to work with both while maintaining runtime correctness. - - Args: - source: Dict or TypedDict containing potential cache_control field - target: Dict or TypedDict to add cache_control to - model: Model name to check if cache_control should be preserved - """ - # TypedDict objects are dicts at runtime, so .get() works - cache_control = source.get("cache_control") if isinstance(source, dict) else getattr(source, "cache_control", None) - if cache_control and model and self.is_anthropic_claude_model(model): - # TypedDict objects support dict operations at runtime - # Use type ignore consistent with codebase pattern (see anthropic/chat/transformation.py:432) - if isinstance(target, dict): - target["cache_control"] = cache_control # type: ignore[typeddict-item] - else: - # Fallback for non-dict objects (shouldn't happen in practice) - cast(Dict[str, Any], target)["cache_control"] = cache_control - def translatable_anthropic_params(self) -> List: """ Which anthropic params, we need to translate to the openai format. @@ -235,8 +205,12 @@ def translate_anthropic_messages_to_openai( # noqa: PLR0915 text_obj = ChatCompletionTextObject( type="text", text=content.get("text", "") ) - self._add_cache_control_if_applicable(content, text_obj, model) - new_user_content_list.append(text_obj) # type: ignore + # Preserve cache_control if present (for prompt caching) + # Only for Anthropic models that support prompt caching + cache_control = content.get("cache_control") + if cache_control and model and self.is_anthropic_claude_model(model): + text_obj["cache_control"] = cache_control # type: ignore + new_user_content_list.append(text_obj) elif content.get("type") == "image": # Convert Anthropic image format to OpenAI format source = content.get("source", {}) @@ -251,24 +225,7 @@ def translate_anthropic_messages_to_openai( # noqa: PLR0915 image_obj = ChatCompletionImageObject( type="image_url", image_url=image_url_obj ) - self._add_cache_control_if_applicable(content, image_obj, model) - new_user_content_list.append(image_obj) # type: ignore - elif content.get("type") == "document": - # Convert Anthropic document format (PDF, etc.) to OpenAI format - source = content.get("source", {}) - openai_image_url = ( - self._translate_anthropic_image_to_openai(cast(dict, source)) - ) - - if openai_image_url: - image_url_obj = ChatCompletionImageUrlObject( - url=openai_image_url - ) - doc_obj = ChatCompletionImageObject( - type="image_url", image_url=image_url_obj - ) - self._add_cache_control_if_applicable(content, doc_obj, model) - new_user_content_list.append(doc_obj) # type: ignore + new_user_content_list.append(image_obj) elif content.get("type") == "tool_result": if "content" not in content: tool_result = ChatCompletionToolMessage( @@ -276,16 +233,14 @@ def translate_anthropic_messages_to_openai( # noqa: PLR0915 tool_call_id=content.get("tool_use_id", ""), content="", ) - self._add_cache_control_if_applicable(content, tool_result, model) - tool_message_list.append(tool_result) # type: ignore[arg-type] + tool_message_list.append(tool_result) elif isinstance(content.get("content"), str): tool_result = ChatCompletionToolMessage( role="tool", tool_call_id=content.get("tool_use_id", ""), content=str(content.get("content", "")), ) - self._add_cache_control_if_applicable(content, tool_result, model) - tool_message_list.append(tool_result) # type: ignore[arg-type] + tool_message_list.append(tool_result) elif isinstance(content.get("content"), list): # Combine all content items into a single tool message # to avoid creating multiple tool_result blocks with the same ID @@ -301,8 +256,7 @@ def translate_anthropic_messages_to_openai( # noqa: PLR0915 tool_call_id=content.get("tool_use_id", ""), content=c, ) - self._add_cache_control_if_applicable(content, tool_result, model) - tool_message_list.append(tool_result) # type: ignore[arg-type] + tool_message_list.append(tool_result) elif isinstance(c, dict): if c.get("type") == "text": tool_result = ChatCompletionToolMessage( @@ -312,8 +266,7 @@ def translate_anthropic_messages_to_openai( # noqa: PLR0915 ), content=c.get("text", ""), ) - self._add_cache_control_if_applicable(content, tool_result, model) - tool_message_list.append(tool_result) # type: ignore[arg-type] + tool_message_list.append(tool_result) elif c.get("type") == "image": source = c.get("source", {}) openai_image_url = ( @@ -329,8 +282,7 @@ def translate_anthropic_messages_to_openai( # noqa: PLR0915 ), content=openai_image_url, ) - self._add_cache_control_if_applicable(content, tool_result, model) - tool_message_list.append(tool_result) # type: ignore[arg-type] + tool_message_list.append(tool_result) else: # For multiple content items, combine into a single tool message # with list content to preserve all items while having one tool_use_id @@ -379,8 +331,7 @@ def translate_anthropic_messages_to_openai( # noqa: PLR0915 tool_call_id=content.get("tool_use_id", ""), content=combined_content_parts, # type: ignore ) - self._add_cache_control_if_applicable(content, tool_result, model) - tool_message_list.append(tool_result) # type: ignore[arg-type] + tool_message_list.append(tool_result) if len(tool_message_list) > 0: new_messages.extend(tool_message_list) @@ -393,8 +344,6 @@ def translate_anthropic_messages_to_openai( # noqa: PLR0915 ## ASSISTANT MESSAGE ## assistant_message_str: Optional[str] = None - assistant_content_list: List[Dict[str, Any]] = [] # For content blocks with cache_control - has_cache_control_in_text = False tool_calls: List[ChatCompletionAssistantToolCall] = [] thinking_blocks: List[ Union[ChatCompletionThinkingBlock, ChatCompletionRedactedThinkingBlock] @@ -408,14 +357,10 @@ def translate_anthropic_messages_to_openai( # noqa: PLR0915 assistant_message_str = str(content) elif isinstance(content, dict): if content.get("type") == "text": - text_block: Dict[str, Any] = { - "type": "text", - "text": content.get("text", ""), - } - self._add_cache_control_if_applicable(content, text_block, model) - if "cache_control" in text_block: - has_cache_control_in_text = True - assistant_content_list.append(text_block) + if assistant_message_str is None: + assistant_message_str = content.get("text", "") + else: + assistant_message_str += content.get("text", "") elif content.get("type") == "tool_use": function_chunk: ChatCompletionToolCallFunctionChunk = { "name": content.get("name", ""), @@ -439,13 +384,13 @@ def translate_anthropic_messages_to_openai( # noqa: PLR0915 provider_specific_fields ) - tool_call = ChatCompletionAssistantToolCall( - id=content.get("id", ""), - type="function", - function=function_chunk, + tool_calls.append( + ChatCompletionAssistantToolCall( + id=content.get("id", ""), + type="function", + function=function_chunk, + ) ) - self._add_cache_control_if_applicable(content, tool_call, model) - tool_calls.append(tool_call) elif content.get("type") == "thinking": thinking_block = ChatCompletionThinkingBlock( type="thinking", @@ -466,30 +411,18 @@ def translate_anthropic_messages_to_openai( # noqa: PLR0915 if ( assistant_message_str is not None - or len(assistant_content_list) > 0 or len(tool_calls) > 0 or len(thinking_blocks) > 0 ): - # Use list format if any text block has cache_control, otherwise use string - if has_cache_control_in_text and len(assistant_content_list) > 0: - assistant_content: Any = assistant_content_list - elif len(assistant_content_list) > 0 and not has_cache_control_in_text: - # Concatenate text blocks into string when no cache_control - assistant_content = "".join( - block.get("text", "") for block in assistant_content_list - ) - else: - assistant_content = assistant_message_str - assistant_message = ChatCompletionAssistantMessage( role="assistant", - content=assistant_content, + content=assistant_message_str, thinking_blocks=( thinking_blocks if len(thinking_blocks) > 0 else None ), ) if len(tool_calls) > 0: - assistant_message["tool_calls"] = tool_calls # type: ignore + assistant_message["tool_calls"] = tool_calls if len(thinking_blocks) > 0: assistant_message["thinking_blocks"] = thinking_blocks # type: ignore new_messages.append(assistant_message) @@ -599,10 +532,10 @@ def translate_anthropic_tool_choice_to_openai( ) def translate_anthropic_tools_to_openai( - self, tools: List[AllAnthropicToolsValues], model: Optional[str] = None + self, tools: List[AllAnthropicToolsValues] ) -> List[ChatCompletionToolParam]: new_tools: List[ChatCompletionToolParam] = [] - mapped_tool_params = ["name", "input_schema", "description", "cache_control"] + mapped_tool_params = ["name", "input_schema", "description"] for tool in tools: function_chunk = ChatCompletionToolParamFunctionChunk( name=tool["name"], @@ -615,11 +548,11 @@ def translate_anthropic_tools_to_openai( for k, v in tool.items(): if k not in mapped_tool_params: # pass additional computer kwargs function_chunk.setdefault("parameters", {}).update({k: v}) - tool_param = ChatCompletionToolParam(type="function", function=function_chunk) - self._add_cache_control_if_applicable(tool, tool_param, model) - new_tools.append(tool_param) # type: ignore[arg-type] + new_tools.append( + ChatCompletionToolParam(type="function", function=function_chunk) + ) - return new_tools # type: ignore[return-value] + return new_tools def translate_anthropic_output_format_to_openai( self, output_format: Any @@ -657,41 +590,6 @@ def translate_anthropic_output_format_to_openai( }, } - def _add_system_message_to_messages( - self, - new_messages: List[AllMessageValues], - anthropic_message_request: AnthropicMessagesRequest, - ) -> None: - """Add system message to messages list if present in request.""" - if "system" not in anthropic_message_request: - return - system_content = anthropic_message_request["system"] - if not system_content: - return - # Handle system as string or array of content blocks - if isinstance(system_content, str): - new_messages.insert( - 0, - ChatCompletionSystemMessage(role="system", content=system_content), - ) - elif isinstance(system_content, list): - # Convert Anthropic system content blocks to OpenAI format - openai_system_content: List[Dict[str, Any]] = [] - model_name = anthropic_message_request.get("model", "") - for block in system_content: - if isinstance(block, dict) and block.get("type") == "text": - text_block: Dict[str, Any] = { - "type": "text", - "text": block.get("text", ""), - } - self._add_cache_control_if_applicable(block, text_block, model_name) - openai_system_content.append(text_block) - if openai_system_content: - new_messages.insert( - 0, - ChatCompletionSystemMessage(role="system", content=openai_system_content), # type: ignore - ) - def translate_anthropic_to_openai( self, anthropic_message_request: AnthropicMessagesRequest ) -> ChatCompletionRequest: @@ -720,7 +618,13 @@ def translate_anthropic_to_openai( model=anthropic_message_request.get("model"), ) ## ADD SYSTEM MESSAGE TO MESSAGES - self._add_system_message_to_messages(new_messages, anthropic_message_request) + if "system" in anthropic_message_request: + system_content = anthropic_message_request["system"] + if system_content: + new_messages.insert( + 0, + ChatCompletionSystemMessage(role="system", content=system_content), + ) new_kwargs: ChatCompletionRequest = { "model": anthropic_message_request["model"], @@ -751,8 +655,7 @@ def translate_anthropic_to_openai( tools = anthropic_message_request["tools"] if tools: new_kwargs["tools"] = self.translate_anthropic_tools_to_openai( - tools=cast(List[AllAnthropicToolsValues], tools), - model=new_kwargs.get("model"), + tools=cast(List[AllAnthropicToolsValues], tools) ) ## CONVERT THINKING @@ -940,7 +843,7 @@ def translate_openai_response_to_anthropic( role="assistant", model=response.model or "unknown-model", stop_sequence=None, - usage=anthropic_usage, # type: ignore + usage=anthropic_usage, content=anthropic_content, # type: ignore stop_reason=anthropic_finish_reason, ) @@ -1089,7 +992,7 @@ def translate_streaming_openai_response_to_anthropic( else: usage_delta = UsageDelta(input_tokens=0, output_tokens=0) return MessageBlockDelta( - type="message_delta", delta=delta, usage=usage_delta # type: ignore + type="message_delta", delta=delta, usage=usage_delta ) ( type_of_content, diff --git a/litellm/llms/azure/chat/gpt_5_transformation.py b/litellm/llms/azure/chat/gpt_5_transformation.py index eeb55911ecf..506b7fdfe5e 100644 --- a/litellm/llms/azure/chat/gpt_5_transformation.py +++ b/litellm/llms/azure/chat/gpt_5_transformation.py @@ -22,8 +22,7 @@ def is_model_gpt_5_model(cls, model: str) -> bool: Accepts both explicit gpt-5 model names and the ``gpt5_series/`` prefix used for manual routing. """ - # gpt-5-chat* is a chat model and shouldn't go through GPT-5 reasoning restrictions. - return ("gpt-5" in model and "gpt-5-chat" not in model) or "gpt5_series" in model + return "gpt-5" in model or "gpt5_series" in model def get_supported_openai_params(self, model: str) -> List[str]: """Get supported parameters for Azure OpenAI GPT-5 models. @@ -38,11 +37,6 @@ def get_supported_openai_params(self, model: str) -> List[str]: """ params = OpenAIGPT5Config.get_supported_openai_params(self, model=model) - # Azure supports tool_choice for GPT-5 deployments, but the base GPT-5 config - # can drop it when the deployment name isn't in the OpenAI model registry. - if "tool_choice" not in params: - params.append("tool_choice") - # Only gpt-5.2 has been verified to support logprobs on Azure if self.is_model_gpt_5_2_model(model): azure_supported_params = ["logprobs", "top_logprobs"] diff --git a/litellm/llms/azure/cost_calculation.py b/litellm/llms/azure/cost_calculation.py index 5b411095ea1..96c58d95ff2 100644 --- a/litellm/llms/azure/cost_calculation.py +++ b/litellm/llms/azure/cost_calculation.py @@ -1,12 +1,11 @@ """ Helper util for handling azure openai-specific cost calculation -- e.g.: prompt caching, audio tokens +- e.g.: prompt caching """ from typing import Optional, Tuple from litellm._logging import verbose_logger -from litellm.litellm_core_utils.llm_cost_calc.utils import generic_cost_per_token from litellm.types.utils import Usage from litellm.utils import get_model_info @@ -19,15 +18,34 @@ def cost_per_token( Input: - model: str, the model name without provider prefix - - usage: LiteLLM Usage block, containing caching and audio token information + - usage: LiteLLM Usage block, containing anthropic caching information Returns: Tuple[float, float] - prompt_cost_in_usd, completion_cost_in_usd """ ## GET MODEL INFO model_info = get_model_info(model=model, custom_llm_provider="azure") + cached_tokens: Optional[int] = None + ## CALCULATE INPUT COST + non_cached_text_tokens = usage.prompt_tokens + if usage.prompt_tokens_details and usage.prompt_tokens_details.cached_tokens: + cached_tokens = usage.prompt_tokens_details.cached_tokens + non_cached_text_tokens = non_cached_text_tokens - cached_tokens + prompt_cost: float = non_cached_text_tokens * model_info["input_cost_per_token"] + + ## CALCULATE OUTPUT COST + completion_cost: float = ( + usage["completion_tokens"] * model_info["output_cost_per_token"] + ) + + ## Prompt Caching cost calculation + if model_info.get("cache_read_input_token_cost") is not None and cached_tokens: + # Note: We read ._cache_read_input_tokens from the Usage - since cost_calculator.py standardizes the cache read tokens on usage._cache_read_input_tokens + prompt_cost += cached_tokens * ( + model_info.get("cache_read_input_token_cost", 0) or 0 + ) - ## Speech / Audio cost calculation (cost per second for TTS models) + ## Speech / Audio cost calculation if ( "output_cost_per_second" in model_info and model_info["output_cost_per_second"] is not None @@ -37,14 +55,7 @@ def cost_per_token( f"For model={model} - output_cost_per_second: {model_info.get('output_cost_per_second')}; response time: {response_time_ms}" ) ## COST PER SECOND ## - prompt_cost = 0.0 + prompt_cost = 0 completion_cost = model_info["output_cost_per_second"] * response_time_ms / 1000 - return prompt_cost, completion_cost - - ## Use generic cost calculator for all other cases - ## This properly handles: text tokens, audio tokens, cached tokens, reasoning tokens, etc. - return generic_cost_per_token( - model=model, - usage=usage, - custom_llm_provider="azure", - ) + + return prompt_cost, completion_cost diff --git a/litellm/llms/base_llm/vector_store/transformation.py b/litellm/llms/base_llm/vector_store/transformation.py index 935fd53c199..89f2094d5df 100644 --- a/litellm/llms/base_llm/vector_store/transformation.py +++ b/litellm/llms/base_llm/vector_store/transformation.py @@ -5,8 +5,8 @@ from litellm.types.router import GenericLiteLLMParams from litellm.types.vector_stores import ( - VECTOR_STORE_OPENAI_PARAMS, BaseVectorStoreAuthCredentials, + VECTOR_STORE_OPENAI_PARAMS, VectorStoreCreateOptionalRequestParams, VectorStoreCreateResponse, VectorStoreIndexEndpoints, @@ -64,30 +64,6 @@ def transform_search_vector_store_request( pass - async def atransform_search_vector_store_request( - self, - vector_store_id: str, - query: Union[str, List[str]], - vector_store_search_optional_params: VectorStoreSearchOptionalRequestParams, - api_base: str, - litellm_logging_obj: LiteLLMLoggingObj, - litellm_params: dict, - ) -> Tuple[str, Dict]: - """ - Optional async version of transform_search_vector_store_request. - If not implemented, the handler will fall back to the sync version. - Providers that need to make async calls (e.g., generating embeddings) should override this. - """ - # Default implementation: call the sync version - return self.transform_search_vector_store_request( - vector_store_id=vector_store_id, - query=query, - vector_store_search_optional_params=vector_store_search_optional_params, - api_base=api_base, - litellm_logging_obj=litellm_logging_obj, - litellm_params=litellm_params, - ) - @abstractmethod def transform_search_vector_store_response( self, response: httpx.Response, litellm_logging_obj: LiteLLMLoggingObj diff --git a/litellm/llms/bedrock/base_aws_llm.py b/litellm/llms/bedrock/base_aws_llm.py index 1de1c40c438..642d15fe3ed 100644 --- a/litellm/llms/bedrock/base_aws_llm.py +++ b/litellm/llms/bedrock/base_aws_llm.py @@ -1163,7 +1163,7 @@ def _filter_headers_for_aws_signature(self, headers: dict) -> dict: def _sign_request( self, - service_name: Literal["bedrock", "sagemaker", "bedrock-agentcore", "s3vectors"], + service_name: Literal["bedrock", "sagemaker", "bedrock-agentcore"], headers: dict, optional_params: dict, request_data: dict, diff --git a/litellm/llms/bedrock/chat/converse_transformation.py b/litellm/llms/bedrock/chat/converse_transformation.py index ec665142073..cb26a22edfa 100644 --- a/litellm/llms/bedrock/chat/converse_transformation.py +++ b/litellm/llms/bedrock/chat/converse_transformation.py @@ -298,39 +298,6 @@ def _is_nova_lite_2_model(self, model: str) -> bool: # Check if the model is specifically Nova Lite 2 return "nova-2-lite" in model_without_region - def _map_web_search_options( - self, - web_search_options: dict, - model: str - ) -> Optional[BedrockToolBlock]: - """ - Map web_search_options to Nova grounding systemTool. - - Nova grounding (web search) is only supported on Amazon Nova models. - Returns None for non-Nova models. - - Args: - web_search_options: The web_search_options dict from the request - model: The model identifier string - - Returns: - BedrockToolBlock with systemTool for Nova models, None otherwise - - Reference: https://docs.aws.amazon.com/nova/latest/userguide/grounding.html - """ - # Only Nova models support nova_grounding - # Model strings can be like: "amazon.nova-pro-v1:0", "us.amazon.nova-pro-v1:0", etc. - if "nova" not in model.lower(): - verbose_logger.debug( - f"web_search_options passed but model {model} is not a Nova model. " - "Nova grounding is only supported on Amazon Nova models." - ) - return None - - # Nova doesn't support search_context_size or user_location params - # (unlike Anthropic), so we just enable grounding with no options - return BedrockToolBlock(systemTool={"name": "nova_grounding"}) - def _transform_reasoning_effort_to_reasoning_config( self, reasoning_effort: str ) -> dict: @@ -471,10 +438,6 @@ def get_supported_openai_params(self, model: str) -> List[str]: ): supported_params.append("tools") - # Nova models support web_search_options (mapped to nova_grounding systemTool) - if base_model.startswith("amazon.nova"): - supported_params.append("web_search_options") - if litellm.utils.supports_tool_choice( model=model, custom_llm_provider=self.custom_llm_provider ) or litellm.utils.supports_tool_choice( @@ -767,13 +730,6 @@ def map_openai_params( if bedrock_tier in ("default", "flex", "priority"): optional_params["serviceTier"] = {"type": bedrock_tier} - if param == "web_search_options" and value and isinstance(value, dict): - grounding_tool = self._map_web_search_options(value, model) - if grounding_tool is not None: - optional_params = self._add_tools_to_optional_params( - optional_params=optional_params, tools=[grounding_tool] - ) - # Only update thinking tokens for non-GPT-OSS models and non-Nova-Lite-2 models # Nova Lite 2 handles token budgeting differently through reasoningConfig if "gpt-oss" not in model and not self._is_nova_lite_2_model(model): @@ -1432,23 +1388,20 @@ def _translate_message_content(self, content_blocks: List[ContentBlock]) -> Tupl str, List[ChatCompletionToolCallChunk], Optional[List[BedrockConverseReasoningContentBlock]], - Optional[List[CitationsContentBlock]], ]: """ - Translate the message content to a string and a list of tool calls, reasoning content blocks, and citations. + Translate the message content to a string and a list of tool calls and reasoning content blocks Returns: content_str: str tools: List[ChatCompletionToolCallChunk] reasoningContentBlocks: Optional[List[BedrockConverseReasoningContentBlock]] - citationsContentBlocks: Optional[List[CitationsContentBlock]] - Citations from Nova grounding """ content_str = "" tools: List[ChatCompletionToolCallChunk] = [] reasoningContentBlocks: Optional[List[BedrockConverseReasoningContentBlock]] = ( None ) - citationsContentBlocks: Optional[List[CitationsContentBlock]] = None for idx, content in enumerate(content_blocks): """ - Content is either a tool response or text @@ -1493,15 +1446,10 @@ def _translate_message_content(self, content_blocks: List[ContentBlock]) -> Tupl if reasoningContentBlocks is None: reasoningContentBlocks = [] reasoningContentBlocks.append(content["reasoningContent"]) - # Handle Nova grounding citations content - if "citationsContent" in content: - if citationsContentBlocks is None: - citationsContentBlocks = [] - citationsContentBlocks.append(content["citationsContent"]) - return content_str, tools, reasoningContentBlocks, citationsContentBlocks + return content_str, tools, reasoningContentBlocks - def _transform_response( # noqa: PLR0915 + def _transform_response( self, model: str, response: httpx.Response, @@ -1577,27 +1525,18 @@ def _transform_response( # noqa: PLR0915 reasoningContentBlocks: Optional[List[BedrockConverseReasoningContentBlock]] = ( None ) - citationsContentBlocks: Optional[List[CitationsContentBlock]] = None if message is not None: ( content_str, tools, reasoningContentBlocks, - citationsContentBlocks, ) = self._translate_message_content(message["content"]) - # Initialize provider_specific_fields if we have any special content blocks - provider_specific_fields: dict = {} - if reasoningContentBlocks is not None: - provider_specific_fields["reasoningContentBlocks"] = reasoningContentBlocks - if citationsContentBlocks is not None: - provider_specific_fields["citationsContent"] = citationsContentBlocks - - if provider_specific_fields: - chat_completion_message["provider_specific_fields"] = provider_specific_fields - if reasoningContentBlocks is not None: + chat_completion_message["provider_specific_fields"] = { + "reasoningContentBlocks": reasoningContentBlocks, + } chat_completion_message["reasoning_content"] = ( self._transform_reasoning_content(reasoningContentBlocks) ) diff --git a/litellm/llms/bedrock/chat/invoke_handler.py b/litellm/llms/bedrock/chat/invoke_handler.py index 1c58a11eebe..17474fa022b 100644 --- a/litellm/llms/bedrock/chat/invoke_handler.py +++ b/litellm/llms/bedrock/chat/invoke_handler.py @@ -1476,11 +1476,6 @@ def _handle_converse_delta_event( reasoning_content = ( "" # set to non-empty string to ensure consistency with Anthropic ) - elif "citationsContent" in delta_obj: - # Handle Nova grounding citations in streaming responses - provider_specific_fields = { - "citationsContent": delta_obj["citationsContent"], - } return ( text, tool_use, diff --git a/litellm/llms/bedrock/chat/invoke_transformations/anthropic_claude3_transformation.py b/litellm/llms/bedrock/chat/invoke_transformations/anthropic_claude3_transformation.py index c936b2cd23c..53e08229799 100644 --- a/litellm/llms/bedrock/chat/invoke_transformations/anthropic_claude3_transformation.py +++ b/litellm/llms/bedrock/chat/invoke_transformations/anthropic_claude3_transformation.py @@ -53,26 +53,13 @@ def map_openai_params( model: str, drop_params: bool, ) -> dict: - # Force tool-based structured outputs for Bedrock Invoke - # (similar to VertexAI fix in #19201) - # Bedrock Invoke doesn't support output_format parameter - original_model = model - if "response_format" in non_default_params: - # Use a model name that forces tool-based approach - model = "claude-3-sonnet-20240229" - - optional_params = AnthropicConfig.map_openai_params( + return AnthropicConfig.map_openai_params( self, non_default_params, optional_params, model, drop_params, ) - - # Restore original model name - model = original_model - - return optional_params def transform_request( @@ -103,8 +90,6 @@ def transform_request( _anthropic_request.pop("model", None) _anthropic_request.pop("stream", None) - # Bedrock Invoke doesn't support output_format parameter - _anthropic_request.pop("output_format", None) if "anthropic_version" not in _anthropic_request: _anthropic_request["anthropic_version"] = self.anthropic_version @@ -132,26 +117,6 @@ def transform_request( if "opus-4" in model.lower() or "opus_4" in model.lower(): beta_set.add("tool-search-tool-2025-10-19") - # Filter out beta headers that Bedrock Invoke doesn't support - # AWS Bedrock only supports a specific whitelist of beta flags - # Reference: https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages-request-response.html - BEDROCK_SUPPORTED_BETAS = { - "computer-use-2024-10-22", # Legacy computer use - "computer-use-2025-01-24", # Current computer use (Claude 3.7 Sonnet) - "token-efficient-tools-2025-02-19", # Tool use (Claude 3.7+ and Claude 4+) - "interleaved-thinking-2025-05-14", # Interleaved thinking (Claude 4+) - "output-128k-2025-02-19", # 128K output tokens (Claude 3.7 Sonnet) - "dev-full-thinking-2025-05-14", # Developer mode for raw thinking (Claude 4+) - "context-1m-2025-08-07", # 1 million tokens (Claude Sonnet 4) - "context-management-2025-06-27", # Context management (Claude Sonnet/Haiku 4.5) - "effort-2025-11-24", # Effort parameter (Claude Opus 4.5) - "tool-search-tool-2025-10-19", # Tool search (Claude Opus 4.5) - "tool-examples-2025-10-29", # Tool use examples (Claude Opus 4.5) - } - - # Only keep beta headers that Bedrock supports - beta_set = {beta for beta in beta_set if beta in BEDROCK_SUPPORTED_BETAS} - if beta_set: _anthropic_request["anthropic_beta"] = list(beta_set) diff --git a/litellm/llms/bedrock/common_utils.py b/litellm/llms/bedrock/common_utils.py index 65d237bdbdf..89b42f5e947 100644 --- a/litellm/llms/bedrock/common_utils.py +++ b/litellm/llms/bedrock/common_utils.py @@ -797,7 +797,7 @@ def _parse_message_from_event(self, event) -> Optional[str]: def get_anthropic_beta_from_headers(headers: dict) -> List[str]: """ Extract anthropic-beta header values and convert them to a list. - Supports both JSON array format and comma-separated values from user headers. + Supports comma-separated values from user headers. Used by both converse and invoke transformations for consistent handling of anthropic-beta headers that should be passed to AWS Bedrock. @@ -812,25 +812,8 @@ def get_anthropic_beta_from_headers(headers: dict) -> List[str]: if not anthropic_beta_header: return [] - # If it's already a list, return it - if isinstance(anthropic_beta_header, list): - return anthropic_beta_header - - # Try to parse as JSON array first (e.g., '["interleaved-thinking-2025-05-14", "claude-code-20250219"]') - if isinstance(anthropic_beta_header, str): - anthropic_beta_header = anthropic_beta_header.strip() - if anthropic_beta_header.startswith("[") and anthropic_beta_header.endswith("]"): - try: - parsed = json.loads(anthropic_beta_header) - if isinstance(parsed, list): - return [str(beta).strip() for beta in parsed] - except json.JSONDecodeError: - pass # Fall through to comma-separated parsing - - # Fall back to comma-separated values - return [beta.strip() for beta in anthropic_beta_header.split(",")] - - return [] + # Split comma-separated values and strip whitespace + return [beta.strip() for beta in anthropic_beta_header.split(",")] class CommonBatchFilesUtils: 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 fc4220c054e..a7065caece2 100644 --- a/litellm/llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py +++ b/litellm/llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py @@ -162,49 +162,6 @@ def _supports_extended_thinking_on_bedrock(self, model: str) -> bool: return any(pattern in model_lower for pattern in supported_patterns) - def _is_claude_opus_4_5(self, model: str) -> bool: - """ - Check if the model is Claude Opus 4.5. - - Args: - model: The model name - - Returns: - True if the model is Claude Opus 4.5 - """ - model_lower = model.lower() - opus_4_5_patterns = [ - "opus-4.5", "opus_4.5", "opus-4-5", "opus_4_5", - ] - return any(pattern in model_lower for pattern in opus_4_5_patterns) - - def _supports_tool_search_on_bedrock(self, model: str) -> bool: - """ - Check if the model supports tool search on Bedrock. - - On Amazon Bedrock, server-side tool search is supported on Claude Opus 4.5 - and Claude Sonnet 4.5 with the tool-search-tool-2025-10-19 beta header. - - Ref: https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool - - Args: - model: The model name - - Returns: - True if the model supports tool search on Bedrock - """ - model_lower = model.lower() - - # Supported models for tool search on Bedrock - supported_patterns = [ - # Opus 4.5 - "opus-4.5", "opus_4.5", "opus-4-5", "opus_4_5", - # Sonnet 4.5 - "sonnet-4.5", "sonnet_4.5", "sonnet-4-5", "sonnet_4_5", - ] - - return any(pattern in model_lower for pattern in supported_patterns) - def _filter_unsupported_beta_headers_for_bedrock( self, model: str, beta_set: set ) -> None: @@ -212,33 +169,25 @@ def _filter_unsupported_beta_headers_for_bedrock( Remove beta headers that are not supported on Bedrock for the given model. Extended thinking beta headers are only supported on specific Claude 4+ models. - Advanced tool use headers are not supported on Bedrock Invoke API, but need to be - translated to Bedrock-specific headers for models that support tool search - (Claude Opus 4.5, Sonnet 4.5). + Advanced tool use headers are not supported on Bedrock Invoke API. This prevents 400 "invalid beta flag" errors on Bedrock. Note: Bedrock Invoke API fails with a 400 error when unsupported beta headers are sent, returning: {"message":"invalid beta flag"} - Translation for models supporting tool search (Opus 4.5, Sonnet 4.5): - - advanced-tool-use-2025-11-20 -> tool-search-tool-2025-10-19 + tool-examples-2025-10-29 - Args: model: The model name beta_set: The set of beta headers to filter in-place """ beta_headers_to_remove = set() - has_advanced_tool_use = False - # 1. Filter out beta headers that are universally unsupported on Bedrock Invoke and track if advanced-tool-use header is present + # 1. Filter out beta headers that are universally unsupported on Bedrock Invoke for beta in beta_set: for unsupported_pattern in self.UNSUPPORTED_BEDROCK_INVOKE_BETA_PATTERNS: if unsupported_pattern in beta.lower(): beta_headers_to_remove.add(beta) - has_advanced_tool_use = True break - - + # 2. Filter out extended thinking headers for models that don't support them extended_thinking_patterns = [ "extended-thinking", @@ -255,14 +204,6 @@ def _filter_unsupported_beta_headers_for_bedrock( for beta in beta_headers_to_remove: beta_set.discard(beta) - # 3. Translate advanced-tool-use to Bedrock-specific headers for models that support tool search - # Ref: https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages-request-response.html - # Ref: https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool - if has_advanced_tool_use and self._supports_tool_search_on_bedrock(model): - beta_set.add("tool-search-tool-2025-10-19") - beta_set.add("tool-examples-2025-10-29") - - def _get_tool_search_beta_header_for_bedrock( self, model: str, @@ -315,7 +256,7 @@ def _convert_output_format_to_inline_schema( Ref: https://aws.amazon.com/blogs/machine-learning/structured-data-response-with-amazon-bedrock-prompt-engineering-and-tool-use/ """ import json - + # Extract schema from output_format schema = output_format.get("schema") if not schema: diff --git a/litellm/llms/custom_httpx/llm_http_handler.py b/litellm/llms/custom_httpx/llm_http_handler.py index d2ea7e872a2..6a87967c3aa 100644 --- a/litellm/llms/custom_httpx/llm_http_handler.py +++ b/litellm/llms/custom_httpx/llm_http_handler.py @@ -7033,31 +7033,17 @@ async def async_vector_store_search_handler( litellm_params=dict(litellm_params), ) - # Check if provider has async transform method - if hasattr(vector_store_provider_config, "atransform_search_vector_store_request"): - ( - url, - request_body, - ) = await vector_store_provider_config.atransform_search_vector_store_request( - vector_store_id=vector_store_id, - query=query, - vector_store_search_optional_params=vector_store_search_optional_params, - api_base=api_base, - litellm_logging_obj=logging_obj, - litellm_params=dict(litellm_params), - ) - else: - ( - url, - request_body, - ) = vector_store_provider_config.transform_search_vector_store_request( - vector_store_id=vector_store_id, - query=query, - vector_store_search_optional_params=vector_store_search_optional_params, - api_base=api_base, - litellm_logging_obj=logging_obj, - litellm_params=dict(litellm_params), - ) + ( + url, + request_body, + ) = vector_store_provider_config.transform_search_vector_store_request( + vector_store_id=vector_store_id, + query=query, + vector_store_search_optional_params=vector_store_search_optional_params, + api_base=api_base, + litellm_logging_obj=logging_obj, + litellm_params=dict(litellm_params), + ) all_optional_params: Dict[str, Any] = dict(litellm_params) all_optional_params.update(vector_store_search_optional_params or {}) headers, signed_json_body = vector_store_provider_config.sign_request( diff --git a/litellm/llms/gemini/chat/transformation.py b/litellm/llms/gemini/chat/transformation.py index d5a5ab667a6..f6d075392b2 100644 --- a/litellm/llms/gemini/chat/transformation.py +++ b/litellm/llms/gemini/chat/transformation.py @@ -92,7 +92,7 @@ def get_supported_openai_params(self, model: str) -> List[str]: "parallel_tool_calls", "web_search_options", ] - if supports_reasoning(model, custom_llm_provider="gemini"): + if supports_reasoning(model): supported_params.append("reasoning_effort") supported_params.append("thinking") if self.is_model_gemini_audio_model(model): diff --git a/litellm/llms/gigachat/chat/transformation.py b/litellm/llms/gigachat/chat/transformation.py index ba14de1f65d..90cf67da6b2 100644 --- a/litellm/llms/gigachat/chat/transformation.py +++ b/litellm/llms/gigachat/chat/transformation.py @@ -31,16 +31,6 @@ GIGACHAT_BASE_URL = "https://gigachat.devices.sberbank.ru/api/v1" -def is_valid_json(value: str) -> bool: - """Checks whether the value passed is a valid serialized JSON string""" - try: - json.loads(value) - except json.JSONDecodeError: - return False - else: - return True - - class GigaChatError(BaseLLMException): """GigaChat API error.""" @@ -111,11 +101,7 @@ def validate_environment( Set up headers with OAuth token. """ # Get access token - credentials = ( - api_key - or get_secret_str("GIGACHAT_CREDENTIALS") - or get_secret_str("GIGACHAT_API_KEY") - ) + credentials = api_key or get_secret_str("GIGACHAT_CREDENTIALS") or get_secret_str("GIGACHAT_API_KEY") access_token = get_access_token(credentials=credentials) # Store credentials for image uploads @@ -207,13 +193,11 @@ def _convert_tools_to_functions(self, tools: List[dict]) -> List[dict]: for tool in tools: if tool.get("type") == "function": func = tool.get("function", {}) - functions.append( - { - "name": func.get("name", ""), - "description": func.get("description", ""), - "parameters": func.get("parameters", {}), - } - ) + functions.append({ + "name": func.get("name", ""), + "description": func.get("description", ""), + "parameters": func.get("parameters", {}), + }) return functions def _map_tool_choice( @@ -297,14 +281,8 @@ def transform_request( } # Add optional params - for key in [ - "temperature", - "top_p", - "max_tokens", - "stream", - "repetition_penalty", - "profanity_check", - ]: + for key in ["temperature", "top_p", "max_tokens", "stream", + "repetition_penalty", "profanity_check"]: if key in optional_params: request_data[key] = optional_params[key] @@ -336,7 +314,7 @@ def _transform_messages(self, messages: List[AllMessageValues]) -> List[dict]: elif role == "tool": message["role"] = "function" content = message.get("content", "") - if not isinstance(content, str) or not is_valid_json(content): + if not isinstance(content, str): message["content"] = json.dumps(content, ensure_ascii=False) # Handle None content @@ -463,16 +441,14 @@ def transform_response( # Convert to tool_calls format if isinstance(args, dict): args = json.dumps(args, ensure_ascii=False) - message_data["tool_calls"] = [ - { - "id": f"call_{uuid.uuid4().hex[:24]}", - "type": "function", - "function": { - "name": func_call.get("name", ""), - "arguments": args, - }, + message_data["tool_calls"] = [{ + "id": f"call_{uuid.uuid4().hex[:24]}", + "type": "function", + "function": { + "name": func_call.get("name", ""), + "arguments": args, } - ] + }] message_data.pop("function_call", None) finish_reason = "tool_calls" diff --git a/litellm/llms/groq/chat/transformation.py b/litellm/llms/groq/chat/transformation.py index 34ea7b03dd9..a75ecd8cc7b 100644 --- a/litellm/llms/groq/chat/transformation.py +++ b/litellm/llms/groq/chat/transformation.py @@ -323,12 +323,4 @@ def chunk_parser(self, chunk: dict) -> ModelResponseStream: status_code=error.get("code"), message=error.get("message"), body=error ) - # Map Groq's 'reasoning' field to LiteLLM's 'reasoning_content' field - # Groq returns delta.reasoning, but LiteLLM expects delta.reasoning_content - choices = chunk.get("choices", []) - for choice in choices: - delta = choice.get("delta", {}) - if "reasoning" in delta: - delta["reasoning_content"] = delta.pop("reasoning") - return super().chunk_parser(chunk) diff --git a/litellm/llms/hosted_vllm/chat/transformation.py b/litellm/llms/hosted_vllm/chat/transformation.py index e955800b947..1d21490ea31 100644 --- a/litellm/llms/hosted_vllm/chat/transformation.py +++ b/litellm/llms/hosted_vllm/chat/transformation.py @@ -23,7 +23,7 @@ class HostedVLLMChatConfig(OpenAIGPTConfig): def get_supported_openai_params(self, model: str) -> List[str]: params = super().get_supported_openai_params(model) - params.extend(["reasoning_effort", "thinking"]) + params.append("reasoning_effort") return params def map_openai_params( @@ -41,27 +41,6 @@ def map_openai_params( _tools = _remove_strict_from_schema(_tools) if _tools is not None: non_default_params["tools"] = _tools - - # Handle thinking parameter - convert Anthropic-style to OpenAI-style reasoning_effort - # vLLM is OpenAI-compatible, so it understands reasoning_effort, not thinking - # Reference: https://github.com/BerriAI/litellm/issues/19761 - thinking = non_default_params.pop("thinking", None) - if thinking is not None and isinstance(thinking, dict): - if thinking.get("type") == "enabled": - # Only convert if reasoning_effort not already set - if "reasoning_effort" not in non_default_params: - budget_tokens = thinking.get("budget_tokens", 0) - # Map budget_tokens to reasoning_effort level - # Same logic as Anthropic adapter (translate_anthropic_thinking_to_reasoning_effort) - if budget_tokens >= 10000: - non_default_params["reasoning_effort"] = "high" - elif budget_tokens >= 5000: - non_default_params["reasoning_effort"] = "medium" - elif budget_tokens >= 2000: - non_default_params["reasoning_effort"] = "low" - else: - non_default_params["reasoning_effort"] = "minimal" - return super().map_openai_params( non_default_params, optional_params, model, drop_params ) diff --git a/litellm/llms/minimax/chat/transformation.py b/litellm/llms/minimax/chat/transformation.py index 3e9dc0209f2..ed80ff8aed1 100644 --- a/litellm/llms/minimax/chat/transformation.py +++ b/litellm/llms/minimax/chat/transformation.py @@ -1,12 +1,11 @@ """ MiniMax OpenAI transformation config - extends OpenAI chat config for MiniMax's OpenAI-compatible API """ -from typing import List, Optional, Tuple +from typing import Optional import litellm from litellm.llms.openai.chat.gpt_transformation import OpenAIGPTConfig from litellm.secret_managers.main import get_secret_str -from litellm.types.llms.openai import AllMessageValues, ChatCompletionToolParam class MinimaxChatConfig(OpenAIGPTConfig): @@ -74,33 +73,11 @@ def get_complete_url( else: return f"{base_url}/v1/chat/completions" - def remove_cache_control_flag_from_messages_and_tools( - self, - model: str, - messages: List[AllMessageValues], - tools: Optional[List[ChatCompletionToolParam]] = None, - ) -> Tuple[List[AllMessageValues], Optional[List[ChatCompletionToolParam]]]: - """ - Override to preserve cache_control for MiniMax. - MiniMax supports cache_control - don't strip it. - """ - # MiniMax supports cache_control, so return messages and tools unchanged - return messages, tools - def get_supported_openai_params(self, model: str) -> list: """ Get supported OpenAI parameters for MiniMax. - Adds reasoning_split and thinking to the list of supported params. + Adds reasoning_split to the list of supported params. """ base_params = super().get_supported_openai_params(model=model) - additional_params = ["reasoning_split"] - - # Add thinking parameter if model supports reasoning - try: - if litellm.supports_reasoning(model=model, custom_llm_provider="minimax"): - additional_params.append("thinking") - except Exception: - pass - - return base_params + additional_params + return base_params + ["reasoning_split"] diff --git a/litellm/llms/oci/chat/transformation.py b/litellm/llms/oci/chat/transformation.py index 84f39ef2525..7af7be2094a 100644 --- a/litellm/llms/oci/chat/transformation.py +++ b/litellm/llms/oci/chat/transformation.py @@ -32,7 +32,6 @@ OCICompletionResponse, OCIContentPartUnion, OCIImageContentPart, - OCIImageUrl, OCIMessage, OCIRoles, OCIServingMode, @@ -1130,7 +1129,7 @@ def adapt_messages_to_generic_oci_standard_content_message( image_url = image_url.get("url") if not isinstance(image_url, str): raise Exception("Prop `image_url` must be a string or an object with a `url` property") - new_content.append(OCIImageContentPart(imageUrl=OCIImageUrl(url=image_url))) + new_content.append(OCIImageContentPart(imageUrl=image_url)) return OCIMessage( role=open_ai_to_generic_oci_role_map[role], diff --git a/litellm/llms/openai/chat/gpt_5_transformation.py b/litellm/llms/openai/chat/gpt_5_transformation.py index 05c003c8b7a..3fffa335fdc 100644 --- a/litellm/llms/openai/chat/gpt_5_transformation.py +++ b/litellm/llms/openai/chat/gpt_5_transformation.py @@ -19,9 +19,7 @@ class OpenAIGPT5Config(OpenAIGPTConfig): @classmethod def is_model_gpt_5_model(cls, model: str) -> bool: - # gpt-5-chat* behaves like a regular chat model (supports temperature, etc.) - # Don't route it through GPT-5 reasoning-specific parameter restrictions. - return "gpt-5" in model and "gpt-5-chat" not in model + return "gpt-5" in model @classmethod def is_model_gpt_5_codex_model(cls, model: str) -> bool: diff --git a/litellm/llms/openai/image_generation/cost_calculator.py b/litellm/llms/openai/image_generation/cost_calculator.py index 988d5626134..35caaf6e9b1 100644 --- a/litellm/llms/openai/image_generation/cost_calculator.py +++ b/litellm/llms/openai/image_generation/cost_calculator.py @@ -8,7 +8,8 @@ from litellm import verbose_logger from litellm.litellm_core_utils.llm_cost_calc.utils import generic_cost_per_token -from litellm.types.utils import ImageResponse, Usage +from litellm.responses.utils import ResponseAPILoggingUtils +from litellm.types.utils import ImageResponse def cost_calculator( @@ -38,18 +39,11 @@ def cost_calculator( ) return 0.0 - # If usage is already a Usage object with completion_tokens_details set, - # use it directly (it was already transformed in convert_to_image_response) - if isinstance(usage, Usage) and usage.completion_tokens_details is not None: - chat_usage = usage - else: - # Transform ImageUsage to Usage using the existing helper - # ImageUsage has the same format as ResponseAPIUsage - from litellm.responses.utils import ResponseAPILoggingUtils - - chat_usage = ResponseAPILoggingUtils._transform_response_api_usage_to_chat_usage( - usage - ) + # Transform ImageUsage to Usage using the existing helper + # ImageUsage has the same format as ResponseAPIUsage + chat_usage = ResponseAPILoggingUtils._transform_response_api_usage_to_chat_usage( + usage + ) # Use generic_cost_per_token for cost calculation prompt_cost, completion_cost = generic_cost_per_token( diff --git a/litellm/llms/openrouter/chat/transformation.py b/litellm/llms/openrouter/chat/transformation.py index e3770dbbf49..b5610852fd2 100644 --- a/litellm/llms/openrouter/chat/transformation.py +++ b/litellm/llms/openrouter/chat/transformation.py @@ -26,9 +26,6 @@ class CacheControlSupportedModels(str, Enum): """Models that support cache_control in content blocks.""" CLAUDE = "claude" GEMINI = "gemini" - MINIMAX = "minimax" - GLM = "glm" - ZAI = "z-ai" class OpenrouterConfig(OpenAIGPTConfig): @@ -42,7 +39,6 @@ def get_supported_openai_params(self, model: str) -> list: model=model, custom_llm_provider="openrouter" ) or litellm.supports_reasoning(model=model): supported_params.append("reasoning_effort") - supported_params.append("thinking") except Exception: pass return list(dict.fromkeys(supported_params)) diff --git a/litellm/llms/s3_vectors/__init__.py b/litellm/llms/s3_vectors/__init__.py deleted file mode 100644 index e8367949c3e..00000000000 --- a/litellm/llms/s3_vectors/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# S3 Vectors LLM integration diff --git a/litellm/llms/s3_vectors/vector_stores/__init__.py b/litellm/llms/s3_vectors/vector_stores/__init__.py deleted file mode 100644 index ac24b4a38da..00000000000 --- a/litellm/llms/s3_vectors/vector_stores/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# S3 Vectors vector store integration diff --git a/litellm/llms/s3_vectors/vector_stores/transformation.py b/litellm/llms/s3_vectors/vector_stores/transformation.py deleted file mode 100644 index df81a78289a..00000000000 --- a/litellm/llms/s3_vectors/vector_stores/transformation.py +++ /dev/null @@ -1,254 +0,0 @@ -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union - -import httpx - -from litellm.llms.base_llm.vector_store.transformation import BaseVectorStoreConfig -from litellm.llms.bedrock.base_aws_llm import BaseAWSLLM -from litellm.types.router import GenericLiteLLMParams -from litellm.types.vector_stores import ( - VECTOR_STORE_OPENAI_PARAMS, - BaseVectorStoreAuthCredentials, - VectorStoreIndexEndpoints, - VectorStoreResultContent, - VectorStoreSearchOptionalRequestParams, - VectorStoreSearchResponse, - VectorStoreSearchResult, -) - -if TYPE_CHECKING: - from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj -else: - LiteLLMLoggingObj = Any - - -class S3VectorsVectorStoreConfig(BaseVectorStoreConfig, BaseAWSLLM): - """Vector store configuration for AWS S3 Vectors.""" - - def __init__(self) -> None: - BaseVectorStoreConfig.__init__(self) - BaseAWSLLM.__init__(self) - - def get_auth_credentials( - self, litellm_params: dict - ) -> BaseVectorStoreAuthCredentials: - return {} - - def get_vector_store_endpoints_by_type(self) -> VectorStoreIndexEndpoints: - return { - "read": [("POST", "/QueryVectors")], - "write": [], - } - - def get_supported_openai_params( - self, model: str - ) -> List[VECTOR_STORE_OPENAI_PARAMS]: - return ["max_num_results"] - - def map_openai_params( - self, - non_default_params: dict, - optional_params: dict, - drop_params: bool, - ) -> dict: - for param, value in non_default_params.items(): - if param == "max_num_results": - optional_params["maxResults"] = value - return optional_params - - def validate_environment( - self, headers: dict, litellm_params: Optional[GenericLiteLLMParams] - ) -> dict: - headers = headers or {} - headers.setdefault("Content-Type", "application/json") - return headers - - def get_complete_url(self, api_base: Optional[str], litellm_params: dict) -> str: - aws_region_name = litellm_params.get("aws_region_name") - if not aws_region_name: - raise ValueError("aws_region_name is required for S3 Vectors") - return f"https://s3vectors.{aws_region_name}.api.aws" - - def transform_search_vector_store_request( - self, - vector_store_id: str, - query: Union[str, List[str]], - vector_store_search_optional_params: VectorStoreSearchOptionalRequestParams, - api_base: str, - litellm_logging_obj: LiteLLMLoggingObj, - litellm_params: dict, - ) -> Tuple[str, Dict]: - """Sync version - generates embedding synchronously.""" - # For S3 Vectors, vector_store_id should be in format: bucket_name:index_name - # If not in that format, try to construct it from litellm_params - bucket_name: str - index_name: str - - if ":" in vector_store_id: - bucket_name, index_name = vector_store_id.split(":", 1) - else: - # Try to get bucket_name from litellm_params - bucket_name_from_params = litellm_params.get("vector_bucket_name") - if not bucket_name_from_params or not isinstance(bucket_name_from_params, str): - raise ValueError( - "vector_store_id must be in format 'bucket_name:index_name' for S3 Vectors, " - "or vector_bucket_name must be provided in litellm_params" - ) - bucket_name = bucket_name_from_params - index_name = vector_store_id - - if isinstance(query, list): - query = " ".join(query) - - # Generate embedding for the query - embedding_model = litellm_params.get("embedding_model", "text-embedding-3-small") - - import litellm as litellm_module - embedding_response = litellm_module.embedding(model=embedding_model, input=[query]) - query_embedding = embedding_response.data[0]["embedding"] - - url = f"{api_base}/QueryVectors" - - request_body: Dict[str, Any] = { - "vectorBucketName": bucket_name, - "indexName": index_name, - "queryVector": {"float32": query_embedding}, - "topK": vector_store_search_optional_params.get("max_num_results", 5), # Default to 5 - "returnDistance": True, - "returnMetadata": True, - } - - litellm_logging_obj.model_call_details["query"] = query - return url, request_body - - async def atransform_search_vector_store_request( - self, - vector_store_id: str, - query: Union[str, List[str]], - vector_store_search_optional_params: VectorStoreSearchOptionalRequestParams, - api_base: str, - litellm_logging_obj: LiteLLMLoggingObj, - litellm_params: dict, - ) -> Tuple[str, Dict]: - """Async version - generates embedding asynchronously.""" - # For S3 Vectors, vector_store_id should be in format: bucket_name:index_name - # If not in that format, try to construct it from litellm_params - bucket_name: str - index_name: str - - if ":" in vector_store_id: - bucket_name, index_name = vector_store_id.split(":", 1) - else: - # Try to get bucket_name from litellm_params - bucket_name_from_params = litellm_params.get("vector_bucket_name") - if not bucket_name_from_params or not isinstance(bucket_name_from_params, str): - raise ValueError( - "vector_store_id must be in format 'bucket_name:index_name' for S3 Vectors, " - "or vector_bucket_name must be provided in litellm_params" - ) - bucket_name = bucket_name_from_params - index_name = vector_store_id - - if isinstance(query, list): - query = " ".join(query) - - # Generate embedding for the query asynchronously - embedding_model = litellm_params.get("embedding_model", "text-embedding-3-small") - - import litellm as litellm_module - embedding_response = await litellm_module.aembedding(model=embedding_model, input=[query]) - query_embedding = embedding_response.data[0]["embedding"] - - url = f"{api_base}/QueryVectors" - - request_body: Dict[str, Any] = { - "vectorBucketName": bucket_name, - "indexName": index_name, - "queryVector": {"float32": query_embedding}, - "topK": vector_store_search_optional_params.get("max_num_results", 5), # Default to 5 - "returnDistance": True, - "returnMetadata": True, - } - - litellm_logging_obj.model_call_details["query"] = query - return url, request_body - - def sign_request( - self, - headers: dict, - optional_params: Dict, - request_data: Dict, - api_base: str, - api_key: Optional[str] = None, - ) -> Tuple[dict, Optional[bytes]]: - return self._sign_request( - service_name="s3vectors", - headers=headers, - optional_params=optional_params, - request_data=request_data, - api_base=api_base, - api_key=api_key, - ) - - def transform_search_vector_store_response( - self, response: httpx.Response, litellm_logging_obj: LiteLLMLoggingObj - ) -> VectorStoreSearchResponse: - try: - response_data = response.json() - results: List[VectorStoreSearchResult] = [] - - for item in response_data.get("vectors", []) or []: - metadata = item.get("metadata", {}) or {} - source_text = metadata.get("source_text", "") - - if not source_text: - continue - - # Extract file information from metadata - chunk_index = metadata.get("chunk_index", "0") - file_id = f"s3-vectors-chunk-{chunk_index}" - filename = metadata.get("filename", f"document-{chunk_index}") - - # S3 Vectors returns distance, convert to similarity score (0-1) - # Lower distance = higher similarity - # We'll normalize using 1 / (1 + distance) to get a 0-1 score - distance = item.get("distance") - score = None - if distance is not None: - # Convert distance to similarity score between 0 and 1 - # For cosine distance: similarity = 1 - distance - # For euclidean: use 1 / (1 + distance) - # Assuming cosine distance here - score = max(0.0, min(1.0, 1.0 - float(distance))) - - results.append( - VectorStoreSearchResult( - score=score, - content=[VectorStoreResultContent(text=source_text, type="text")], - file_id=file_id, - filename=filename, - attributes=metadata, - ) - ) - - return VectorStoreSearchResponse( - object="vector_store.search_results.page", - search_query=litellm_logging_obj.model_call_details.get("query", ""), - data=results, - ) - except Exception as e: - raise self.get_error_class( - error_message=str(e), - status_code=response.status_code, - headers=response.headers, - ) - - # Vector store creation is not yet implemented - def transform_create_vector_store_request( - self, - vector_store_create_optional_params, - api_base: str, - ) -> Tuple[str, Dict]: - raise NotImplementedError - - def transform_create_vector_store_response(self, response: httpx.Response): - raise NotImplementedError diff --git a/litellm/llms/vercel_ai_gateway/embedding/__init__.py b/litellm/llms/vercel_ai_gateway/embedding/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/litellm/llms/vercel_ai_gateway/embedding/transformation.py b/litellm/llms/vercel_ai_gateway/embedding/transformation.py deleted file mode 100644 index 7238b05f10d..00000000000 --- a/litellm/llms/vercel_ai_gateway/embedding/transformation.py +++ /dev/null @@ -1,176 +0,0 @@ -""" -Vercel AI Gateway Embedding API Configuration. - -This module provides the configuration for Vercel AI Gateway's Embedding API. -Vercel AI Gateway is OpenAI-compatible and supports embeddings via the /v1/embeddings endpoint. - -Docs: https://vercel.com/docs/ai-gateway/openai-compat/embeddings -""" - -from typing import TYPE_CHECKING, Any, Optional - -import httpx - -from litellm.llms.base_llm.embedding.transformation import BaseEmbeddingConfig -from litellm.secret_managers.main import get_secret_str -from litellm.types.llms.openai import AllEmbeddingInputValues -from litellm.types.utils import EmbeddingResponse -from litellm.utils import convert_to_model_response_object - -from ..common_utils import VercelAIGatewayException - -if TYPE_CHECKING: - from litellm.litellm_core_utils.litellm_logging import Logging as _LiteLLMLoggingObj - - LiteLLMLoggingObj = _LiteLLMLoggingObj -else: - LiteLLMLoggingObj = Any - - -class VercelAIGatewayEmbeddingConfig(BaseEmbeddingConfig): - """ - Configuration for Vercel AI Gateway's Embedding API. - - Reference: https://vercel.com/docs/ai-gateway/openai-compat/embeddings - """ - - def validate_environment( - self, - headers: dict, - model: str, - messages: list, - optional_params: dict, - litellm_params: dict, - api_key: Optional[str] = None, - api_base: Optional[str] = None, - ) -> dict: - """ - Validate environment and set up headers for Vercel AI Gateway API. - - Vercel AI Gateway requires: - - Authorization header with Bearer token (API key or OIDC token) - """ - vercel_headers = { - "Content-Type": "application/json", - } - - # Add Authorization header if api_key is provided - if api_key: - vercel_headers["Authorization"] = f"Bearer {api_key}" - - # Merge with existing headers (user's extra_headers take priority) - merged_headers = {**vercel_headers, **headers} - - return merged_headers - - 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: - """ - Get the complete URL for Vercel AI Gateway Embedding API endpoint. - """ - if api_base: - api_base = api_base.rstrip("/") - else: - api_base = ( - get_secret_str("VERCEL_AI_GATEWAY_API_BASE") - or "https://ai-gateway.vercel.sh/v1" - ) - - return f"{api_base}/embeddings" - - def transform_embedding_request( - self, - model: str, - input: AllEmbeddingInputValues, - optional_params: dict, - headers: dict, - ) -> dict: - """ - Transform embedding request to Vercel AI Gateway format (OpenAI-compatible). - """ - # Ensure input is a list - if isinstance(input, str): - input = [input] - - # Strip 'vercel_ai_gateway/' prefix if present - if model.startswith("vercel_ai_gateway/"): - model = model.replace("vercel_ai_gateway/", "", 1) - - return { - "model": model, - "input": input, - **optional_params, - } - - def transform_embedding_response( - self, - model: str, - raw_response: httpx.Response, - model_response: EmbeddingResponse, - logging_obj: LiteLLMLoggingObj, - api_key: Optional[str], - request_data: dict, - optional_params: dict, - litellm_params: dict, - ) -> EmbeddingResponse: - """ - Transform embedding response from Vercel AI Gateway format (OpenAI-compatible). - """ - logging_obj.post_call(original_response=raw_response.text) - - # Vercel AI Gateway returns standard OpenAI-compatible embedding response - response_json = raw_response.json() - - return convert_to_model_response_object( - response_object=response_json, - model_response_object=model_response, - response_type="embedding", - ) - - def get_supported_openai_params(self, model: str) -> list: - """ - Get list of supported OpenAI parameters for Vercel AI Gateway embeddings. - - Vercel AI Gateway supports the standard OpenAI embeddings parameters - and auto-maps 'dimensions' to each provider's expected field. - """ - return [ - "timeout", - "dimensions", - "encoding_format", - "user", - ] - - def map_openai_params( - self, - non_default_params: dict, - optional_params: dict, - model: str, - drop_params: bool, - ) -> dict: - """ - Map OpenAI parameters to Vercel AI Gateway format. - """ - for param, value in non_default_params.items(): - if param in self.get_supported_openai_params(model): - optional_params[param] = value - return optional_params - - def get_error_class( - self, error_message: str, status_code: int, headers: Any - ) -> Any: - """ - Get the error class for Vercel AI Gateway errors. - """ - return VercelAIGatewayException( - message=error_message, - status_code=status_code, - headers=headers, - ) diff --git a/litellm/llms/vertex_ai/common_utils.py b/litellm/llms/vertex_ai/common_utils.py index a0e2ddf5e98..152b99ca4db 100644 --- a/litellm/llms/vertex_ai/common_utils.py +++ b/litellm/llms/vertex_ai/common_utils.py @@ -849,7 +849,7 @@ def get_vertex_model_id_from_url(url: str) -> Optional[str]: `https://${LOCATION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/publishers/google/models/${MODEL_ID}:streamGenerateContent` """ - match = re.search(r"/models/([^:]+)", url) + match = re.search(r"/models/([^/:]+)", url) return match.group(1) if match else None 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 a9ac21bb56f..b78ac8f9e98 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 @@ -1657,17 +1657,7 @@ def _calculate_usage( # noqa: PLR0915 ## This is necessary because promptTokensDetails includes both cached and non-cached tokens ## See: https://github.com/BerriAI/litellm/issues/18750 if cached_text_tokens is not None and prompt_text_tokens is not None: - # Explicit caching: subtract cached tokens per modality from cacheTokensDetails prompt_text_tokens = prompt_text_tokens - cached_text_tokens - elif ( - cached_tokens is not None - and prompt_text_tokens is not None - and cached_text_tokens is None - ): - # Implicit caching: only cachedContentTokenCount is provided (no cacheTokensDetails) - # Subtract from text tokens since implicit caching is primarily for text content - # See: https://github.com/BerriAI/litellm/issues/16341 - prompt_text_tokens = prompt_text_tokens - cached_tokens if cached_audio_tokens is not None and prompt_audio_tokens is not None: prompt_audio_tokens = prompt_audio_tokens - cached_audio_tokens if cached_image_tokens is not None and prompt_image_tokens is not None: diff --git a/litellm/llms/xai/responses/transformation.py b/litellm/llms/xai/responses/transformation.py index 90a7faf5a7b..bd422c8d81e 100644 --- a/litellm/llms/xai/responses/transformation.py +++ b/litellm/llms/xai/responses/transformation.py @@ -1,11 +1,10 @@ -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union +from typing import TYPE_CHECKING, Any, Dict, List, Optional import litellm from litellm._logging import verbose_logger from litellm.llms.openai.responses.transformation import OpenAIResponsesAPIConfig from litellm.secret_managers.main import get_secret_str from litellm.types.llms.openai import ResponsesAPIOptionalRequestParams -from litellm.types.llms.xai import XAIWebSearchTool, XAIXSearchTool from litellm.types.router import GenericLiteLLMParams from litellm.types.utils import LlmProviders @@ -50,85 +49,6 @@ def get_supported_openai_params(self, model: str) -> list: return supported_params - def _transform_web_search_tool(self, tool: Dict[str, Any]) -> Union[XAIWebSearchTool, Dict[str, Any]]: - """ - Transform web_search tool to XAI format. - - XAI supports web_search with specific filters: - - allowed_domains (max 5) - - excluded_domains (max 5) - - enable_image_understanding - - XAI does NOT support search_context_size (OpenAI-specific). - """ - xai_tool: Dict[str, Any] = {"type": "web_search"} - - # Remove search_context_size if present (not supported by XAI) - if "search_context_size" in tool: - verbose_logger.info( - "XAI does not support 'search_context_size' parameter. Removing it from web_search tool." - ) - - # Handle filters (XAI-specific structure) - filters = {} - if "allowed_domains" in tool: - allowed_domains = tool["allowed_domains"] - filters["allowed_domains"] = allowed_domains - - if "excluded_domains" in tool: - excluded_domains = tool["excluded_domains"] - filters["excluded_domains"] = excluded_domains - - # Add filters if any were specified - if filters: - xai_tool["filters"] = filters - - # Handle enable_image_understanding (top-level in XAI format) - if "enable_image_understanding" in tool: - xai_tool["enable_image_understanding"] = tool["enable_image_understanding"] - - return xai_tool - - def _transform_x_search_tool(self, tool: Dict[str, Any]) -> Union[XAIXSearchTool, Dict[str, Any]]: - """ - Transform x_search tool to XAI format. - - XAI supports x_search with specific parameters: - - allowed_x_handles (max 10) - - excluded_x_handles (max 10) - - from_date (ISO8601: YYYY-MM-DD) - - to_date (ISO8601: YYYY-MM-DD) - - enable_image_understanding - - enable_video_understanding - """ - xai_tool: Dict[str, Any] = {"type": "x_search"} - - # Handle allowed_x_handles - if "allowed_x_handles" in tool: - allowed_handles = tool["allowed_x_handles"] - xai_tool["allowed_x_handles"] = allowed_handles - - # Handle excluded_x_handles - if "excluded_x_handles" in tool: - excluded_handles = tool["excluded_x_handles"] - xai_tool["excluded_x_handles"] = excluded_handles - - # Handle date range - if "from_date" in tool: - xai_tool["from_date"] = tool["from_date"] - - if "to_date" in tool: - xai_tool["to_date"] = tool["to_date"] - - # Handle media understanding flags - if "enable_image_understanding" in tool: - xai_tool["enable_image_understanding"] = tool["enable_image_understanding"] - - if "enable_video_understanding" in tool: - xai_tool["enable_video_understanding"] = tool["enable_video_understanding"] - - return xai_tool - def map_openai_params( self, response_api_optional_params: ResponsesAPIOptionalRequestParams, @@ -141,9 +61,7 @@ def map_openai_params( Handles XAI-specific transformations: 1. Drops 'instructions' parameter (not supported) 2. Transforms code_interpreter tools to remove 'container' field - 3. Transforms web_search tools to XAI format (removes search_context_size, adds filters) - 4. Transforms x_search tools to XAI format - 5. Sets store=false when images are detected (recommended by XAI) + 3. Sets store=false when images are detected (recommended by XAI) """ params = dict(response_api_optional_params) @@ -154,7 +72,7 @@ def map_openai_params( ) params.pop("instructions") - # Transform tools + # Transform code_interpreter tools - remove container field if "tools" in params and params["tools"]: tools_list = params["tools"] # Ensure tools is a list for iteration @@ -163,36 +81,15 @@ def map_openai_params( transformed_tools: List[Any] = [] for tool in tools_list: - if isinstance(tool, dict): - tool_type = tool.get("type") - - if tool_type == "code_interpreter": - # XAI supports code_interpreter but doesn't use the container field - verbose_logger.debug( - "XAI: Transforming code_interpreter tool, removing container field" - ) - transformed_tools.append({"type": "code_interpreter"}) - - elif tool_type == "web_search": - # Transform web_search to XAI format - verbose_logger.debug( - "XAI: Transforming web_search tool to XAI format" - ) - transformed_tools.append(self._transform_web_search_tool(tool)) - - elif tool_type == "x_search": - # Transform x_search to XAI format - verbose_logger.debug( - "XAI: Transforming x_search tool to XAI format" - ) - transformed_tools.append(self._transform_x_search_tool(tool)) - - else: - # Keep other tools as-is - transformed_tools.append(tool) + if isinstance(tool, dict) and tool.get("type") == "code_interpreter": + # XAI supports code_interpreter but doesn't use the container field + # Keep only the type field + verbose_logger.debug( + "XAI: Transforming code_interpreter tool, removing container field" + ) + transformed_tools.append({"type": "code_interpreter"}) else: transformed_tools.append(tool) - params["tools"] = transformed_tools return params diff --git a/litellm/llms/zai/chat/transformation.py b/litellm/llms/zai/chat/transformation.py index fb1d67df357..4380256f0a4 100644 --- a/litellm/llms/zai/chat/transformation.py +++ b/litellm/llms/zai/chat/transformation.py @@ -1,7 +1,6 @@ -from typing import List, Optional, Tuple +from typing import Optional, Tuple from litellm.secret_managers.main import get_secret_str -from litellm.types.llms.openai import AllMessageValues, ChatCompletionToolParam from ...openai.chat.gpt_transformation import OpenAIGPTConfig @@ -20,19 +19,6 @@ def _get_openai_compatible_provider_info( dynamic_api_key = api_key or get_secret_str("ZAI_API_KEY") return api_base, dynamic_api_key - def remove_cache_control_flag_from_messages_and_tools( - self, - model: str, - messages: List[AllMessageValues], - tools: Optional[List[ChatCompletionToolParam]] = None, - ) -> Tuple[List[AllMessageValues], Optional[List[ChatCompletionToolParam]]]: - """ - Override to preserve cache_control for GLM/ZAI. - GLM supports cache_control - don't strip it. - """ - # GLM/ZAI supports cache_control, so return messages and tools unchanged - return messages, tools - def get_supported_openai_params(self, model: str) -> list: base_params = [ "max_tokens", diff --git a/litellm/main.py b/litellm/main.py index 99bf224c5b7..ce84c8988e0 100644 --- a/litellm/main.py +++ b/litellm/main.py @@ -148,7 +148,7 @@ validate_and_fix_openai_messages, validate_and_fix_openai_tools, validate_chat_completion_tool_choice, - validate_openai_optional_params, + validate_openai_optional_params ) from ._logging import verbose_logger @@ -368,7 +368,7 @@ async def create(self, messages, model=None, **kwargs): @tracer.wrap() @client -async def acompletion( # noqa: PLR0915 +async def acompletion( # noqa: PLR0915 model: str, # Optional OpenAI params: see https://platform.openai.com/docs/api-reference/chat/create messages: List = [], @@ -599,8 +599,16 @@ async def acompletion( # noqa: PLR0915 # Add the context to the function ctx = contextvars.copy_context() func_with_context = partial(ctx.run, func) + + if timeout is not None and isinstance(timeout, (int, float)): + timeout_value = float(timeout) + init_response = await asyncio.wait_for( + loop.run_in_executor(None, func_with_context), + timeout=timeout_value + ) + else: + init_response = await loop.run_in_executor(None, func_with_context) - init_response = await loop.run_in_executor(None, func_with_context) if isinstance(init_response, dict) or isinstance( init_response, ModelResponse ): ## CACHING SCENARIO @@ -608,7 +616,11 @@ async def acompletion( # noqa: PLR0915 response = ModelResponse(**init_response) response = init_response elif asyncio.iscoroutine(init_response): - response = await init_response + if timeout is not None and isinstance(timeout, (int, float)): + timeout_value = float(timeout) + response = await asyncio.wait_for(init_response, timeout=timeout_value) + else: + response = await init_response else: response = init_response # type: ignore @@ -625,6 +637,14 @@ async def acompletion( # noqa: PLR0915 loop=loop ) # sets the logging event loop if the user does sync streaming (e.g. on proxy for sagemaker calls) return response + except asyncio.TimeoutError: + custom_llm_provider = custom_llm_provider or "openai" + from litellm.exceptions import Timeout + raise Timeout( + message=f"Request timed out after {timeout} seconds", + model=model, + llm_provider=custom_llm_provider, + ) except Exception as e: custom_llm_provider = custom_llm_provider or "openai" raise exception_type( @@ -1098,6 +1118,7 @@ def completion( # type: ignore # noqa: PLR0915 # validate optional params stop = validate_openai_optional_params(stop=stop) + ######### unpacking kwargs ##################### args = locals() @@ -1114,9 +1135,7 @@ def completion( # type: ignore # noqa: PLR0915 # Check if MCP tools are present (following responses pattern) # Cast tools to Optional[Iterable[ToolParam]] for type checking tools_for_mcp = cast(Optional[Iterable[ToolParam]], tools) - if LiteLLM_Proxy_MCP_Handler._should_use_litellm_mcp_gateway( - tools=tools_for_mcp - ): + if LiteLLM_Proxy_MCP_Handler._should_use_litellm_mcp_gateway(tools=tools_for_mcp): # Return coroutine - acompletion will await it # completion() can return a coroutine when MCP tools are present, which acompletion() awaits return acompletion_with_mcp( # type: ignore[return-value] @@ -1517,8 +1536,6 @@ def completion( # type: ignore # noqa: PLR0915 max_retries=max_retries, timeout=timeout, litellm_request_debug=kwargs.get("litellm_request_debug", False), - tpm=kwargs.get("tpm"), - rpm=kwargs.get("rpm"), ) cast(LiteLLMLoggingObj, logging).update_environment_variables( model=model, @@ -2344,7 +2361,11 @@ def completion( # type: ignore # noqa: PLR0915 input=messages, api_key=api_key, original_response=response ) elif custom_llm_provider == "minimax": - api_key = api_key or get_secret_str("MINIMAX_API_KEY") or litellm.api_key + api_key = ( + api_key + or get_secret_str("MINIMAX_API_KEY") + or litellm.api_key + ) api_base = ( api_base @@ -2392,9 +2413,7 @@ def completion( # type: ignore # noqa: PLR0915 or custom_llm_provider == "wandb" or custom_llm_provider == "clarifai" or custom_llm_provider in litellm.openai_compatible_providers - or JSONProviderRegistry.exists( - custom_llm_provider - ) # JSON-configured providers + or JSONProviderRegistry.exists(custom_llm_provider) # JSON-configured providers or "ft:gpt-3.5-turbo" in model # finetune gpt-3.5-turbo ): # allow user to make an openai call with a custom base # note: if a user sets a custom base - we should ensure this works @@ -4705,7 +4724,7 @@ def embedding( # noqa: PLR0915 if headers is not None and headers != {}: optional_params["extra_headers"] = headers - + if encoding_format is not None: optional_params["encoding_format"] = encoding_format else: @@ -4847,36 +4866,6 @@ def embedding( # noqa: PLR0915 headers = openrouter_headers - response = base_llm_http_handler.embedding( - model=model, - input=input, - custom_llm_provider=custom_llm_provider, - api_base=api_base, - api_key=api_key, - logging_obj=logging, - timeout=timeout, - model_response=EmbeddingResponse(), - optional_params=optional_params, - client=client, - aembedding=aembedding, - litellm_params=litellm_params_dict, - headers=headers, - ) - elif custom_llm_provider == "vercel_ai_gateway": - api_base = ( - api_base - or litellm.api_base - or get_secret_str("VERCEL_AI_GATEWAY_API_BASE") - or "https://ai-gateway.vercel.sh/v1" - ) - - api_key = ( - api_key - or litellm.api_key - or get_secret_str("VERCEL_AI_GATEWAY_API_KEY") - or get_secret_str("VERCEL_OIDC_TOKEN") - ) - response = base_llm_http_handler.embedding( model=model, input=input, @@ -6770,7 +6759,9 @@ def speech( # noqa: PLR0915 if text_to_speech_provider_config is None: text_to_speech_provider_config = MinimaxTextToSpeechConfig() - minimax_config = cast(MinimaxTextToSpeechConfig, text_to_speech_provider_config) + minimax_config = cast( + MinimaxTextToSpeechConfig, text_to_speech_provider_config + ) if api_base is not None: litellm_params_dict["api_base"] = api_base @@ -6910,7 +6901,7 @@ async def ahealth_check( custom_llm_provider_from_params = model_params.get("custom_llm_provider", None) api_base_from_params = model_params.get("api_base", None) api_key_from_params = model_params.get("api_key", None) - + model, custom_llm_provider, _, _ = get_llm_provider( model=model, custom_llm_provider=custom_llm_provider_from_params, @@ -7280,16 +7271,12 @@ def _get_encoding(): def __getattr__(name: str) -> Any: """Lazy import handler for main module""" if name == "encoding": - # Use _get_default_encoding which properly sets TIKTOKEN_CACHE_DIR - # before loading tiktoken, ensuring the local cache is used - # instead of downloading from the internet - from litellm._lazy_imports import _get_default_encoding - _encoding = _get_default_encoding() + # Lazy load encoding to avoid heavy tiktoken import at module load time + _encoding = tiktoken.get_encoding("cl100k_base") # Cache it in the module's __dict__ for subsequent accesses import sys - sys.modules[__name__].__dict__["encoding"] = _encoding global _encoding_cache _encoding_cache = _encoding return _encoding - raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") \ No newline at end of file diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index fad5f243fff..209c0794e50 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -3130,7 +3130,7 @@ "supports_reasoning": true, "supports_response_schema": true, "supports_system_messages": true, - "supports_tool_choice": true, + "supports_tool_choice": false, "supports_vision": true }, "azure/gpt-5-chat-latest": { @@ -3162,7 +3162,7 @@ "supports_reasoning": true, "supports_response_schema": true, "supports_system_messages": true, - "supports_tool_choice": true, + "supports_tool_choice": false, "supports_vision": true }, "azure/gpt-5-codex": { @@ -3653,9 +3653,10 @@ "max_input_tokens": 128000, "max_output_tokens": 16384, "max_tokens": 16384, - "mode": "responses", + "mode": "chat", "output_cost_per_token": 1.4e-05, "supported_endpoints": [ + "/v1/chat/completions", "/v1/responses" ], "supported_modalities": [ @@ -9787,7 +9788,6 @@ "supports_tool_choice": true }, "deepinfra/google/gemini-2.0-flash-001": { - "deprecation_date": "2026-03-31", "max_tokens": 1000000, "max_input_tokens": 1000000, "max_output_tokens": 1000000, @@ -10231,48 +10231,6 @@ "mode": "completion", "output_cost_per_token": 5e-07 }, - "deepseek-v3-2-251201": { - "input_cost_per_token": 0.0, - "litellm_provider": "volcengine", - "max_input_tokens": 98304, - "max_output_tokens": 32768, - "max_tokens": 32768, - "mode": "chat", - "output_cost_per_token": 0.0, - "supports_assistant_prefill": true, - "supports_function_calling": true, - "supports_prompt_caching": true, - "supports_reasoning": true, - "supports_tool_choice": true - }, - "glm-4-7-251222": { - "input_cost_per_token": 0.0, - "litellm_provider": "volcengine", - "max_input_tokens": 204800, - "max_output_tokens": 131072, - "max_tokens": 131072, - "mode": "chat", - "output_cost_per_token": 0.0, - "supports_assistant_prefill": true, - "supports_function_calling": true, - "supports_prompt_caching": true, - "supports_reasoning": true, - "supports_tool_choice": true - }, - "kimi-k2-thinking-251104": { - "input_cost_per_token": 0.0, - "litellm_provider": "volcengine", - "max_input_tokens": 229376, - "max_output_tokens": 32768, - "max_tokens": 32768, - "mode": "chat", - "output_cost_per_token": 0.0, - "supports_assistant_prefill": true, - "supports_function_calling": true, - "supports_prompt_caching": true, - "supports_reasoning": true, - "supports_tool_choice": true - }, "doubao-embedding": { "input_cost_per_token": 0.0, "litellm_provider": "volcengine", @@ -12147,7 +12105,6 @@ }, "gemini-2.0-flash": { "cache_read_input_token_cost": 2.5e-08, - "deprecation_date": "2026-03-31", "input_cost_per_audio_token": 7e-07, "input_cost_per_token": 1e-07, "litellm_provider": "vertex_ai-language-models", @@ -12187,7 +12144,7 @@ }, "gemini-2.0-flash-001": { "cache_read_input_token_cost": 3.75e-08, - "deprecation_date": "2026-03-31", + "deprecation_date": "2026-02-05", "input_cost_per_audio_token": 1e-06, "input_cost_per_token": 1.5e-07, "litellm_provider": "vertex_ai-language-models", @@ -12273,7 +12230,6 @@ }, "gemini-2.0-flash-lite": { "cache_read_input_token_cost": 1.875e-08, - "deprecation_date": "2026-03-31", "input_cost_per_audio_token": 7.5e-08, "input_cost_per_token": 7.5e-08, "litellm_provider": "vertex_ai-language-models", @@ -12309,7 +12265,7 @@ }, "gemini-2.0-flash-lite-001": { "cache_read_input_token_cost": 1.875e-08, - "deprecation_date": "2026-03-31", + "deprecation_date": "2026-02-25", "input_cost_per_audio_token": 7.5e-08, "input_cost_per_token": 7.5e-08, "litellm_provider": "vertex_ai-language-models", @@ -13521,79 +13477,6 @@ "supports_vision": true, "supports_web_search": true }, - "gemini-robotics-er-1.5-preview": { - "cache_read_input_token_cost": 0, - "input_cost_per_token": 3e-07, - "input_cost_per_audio_token": 1e-06, - "litellm_provider": "vertex_ai-language-models", - "max_input_tokens": 1048576, - "max_output_tokens": 65535, - "max_tokens": 65535, - "mode": "chat", - "output_cost_per_token": 2.5e-06, - "output_cost_per_reasoning_token": 2.5e-06, - "source": "https://ai.google.dev/gemini-api/docs/models#gemini-robotics-er-1-5-preview", - "supported_endpoints": [ - "/v1/chat/completions", - "/v1/completions" - ], - "supported_modalities": [ - "text", - "image", - "video", - "audio" - ], - "supported_output_modalities": [ - "text" - ], - "supports_audio_output": false, - "supports_function_calling": true, - "supports_parallel_function_calling": true, - "supports_prompt_caching": false, - "supports_reasoning": true, - "supports_response_schema": true, - "supports_system_messages": true, - "supports_tool_choice": true, - "supports_url_context": true, - "supports_vision": true - }, - "gemini/gemini-robotics-er-1.5-preview": { - "cache_read_input_token_cost": 0, - "input_cost_per_token": 3e-07, - "input_cost_per_audio_token": 1e-06, - "litellm_provider": "gemini", - "max_input_tokens": 1048576, - "max_output_tokens": 65535, - "max_tokens": 65535, - "mode": "chat", - "output_cost_per_token": 2.5e-06, - "output_cost_per_reasoning_token": 2.5e-06, - "source": "https://ai.google.dev/gemini-api/docs/models#gemini-robotics-er-1-5-preview", - "supported_endpoints": [ - "/v1/chat/completions", - "/v1/completions" - ], - "supported_modalities": [ - "text", - "image", - "video", - "audio" - ], - "supported_output_modalities": [ - "text" - ], - "supports_audio_output": false, - "supports_function_calling": true, - "supports_parallel_function_calling": true, - "supports_prompt_caching": false, - "supports_reasoning": true, - "supports_response_schema": true, - "supports_system_messages": true, - "supports_tool_choice": true, - "supports_url_context": true, - "supports_vision": true, - "supports_web_search": true - }, "gemini-2.5-computer-use-preview-10-2025": { "input_cost_per_token": 1.25e-06, "input_cost_per_token_above_200k_tokens": 2.5e-06, @@ -14047,7 +13930,6 @@ }, "gemini/gemini-2.0-flash": { "cache_read_input_token_cost": 2.5e-08, - "deprecation_date": "2026-03-31", "input_cost_per_audio_token": 7e-07, "input_cost_per_token": 1e-07, "litellm_provider": "gemini", @@ -14088,7 +13970,6 @@ }, "gemini/gemini-2.0-flash-001": { "cache_read_input_token_cost": 2.5e-08, - "deprecation_date": "2026-03-31", "input_cost_per_audio_token": 7e-07, "input_cost_per_token": 1e-07, "litellm_provider": "gemini", @@ -14176,7 +14057,6 @@ }, "gemini/gemini-2.0-flash-lite": { "cache_read_input_token_cost": 1.875e-08, - "deprecation_date": "2026-03-31", "input_cost_per_audio_token": 7.5e-08, "input_cost_per_token": 7.5e-08, "litellm_provider": "gemini", @@ -20663,7 +20543,6 @@ "supports_function_calling": true, "supports_tool_choice": true, "supports_prompt_caching": true, - "supports_reasoning": true, "supports_system_messages": true, "max_input_tokens": 1000000, "max_output_tokens": 8192 @@ -20678,7 +20557,6 @@ "supports_function_calling": true, "supports_tool_choice": true, "supports_prompt_caching": true, - "supports_reasoning": true, "supports_system_messages": true, "max_input_tokens": 1000000, "max_output_tokens": 8192 @@ -20693,7 +20571,6 @@ "supports_function_calling": true, "supports_tool_choice": true, "supports_prompt_caching": true, - "supports_reasoning": true, "supports_system_messages": true, "max_input_tokens": 200000, "max_output_tokens": 8192 @@ -23281,7 +23158,6 @@ "supports_tool_choice": true }, "openrouter/google/gemini-2.0-flash-001": { - "deprecation_date": "2026-03-31", "input_cost_per_audio_token": 7e-07, "input_cost_per_token": 1e-07, "litellm_provider": "openrouter", @@ -23578,7 +23454,7 @@ "mode": "chat", "output_cost_per_token": 1.02e-06, "supports_function_calling": true, - "supports_prompt_caching": true, + "supports_prompt_caching": false, "supports_reasoning": true, "supports_tool_choice": true }, @@ -23930,11 +23806,8 @@ "max_input_tokens": 400000, "max_output_tokens": 128000, "max_tokens": 128000, - "mode": "responses", + "mode": "chat", "output_cost_per_token": 1.4e-05, - "supported_endpoints": [ - "/v1/responses" - ], "supported_modalities": [ "text", "image" @@ -24273,7 +24146,6 @@ "output_cost_per_token": 1.75e-06, "source": "https://openrouter.ai/z-ai/glm-4.6", "supports_function_calling": true, - "supports_prompt_caching": true, "supports_reasoning": true, "supports_tool_choice": true }, @@ -24287,76 +24159,9 @@ "output_cost_per_token": 1.9e-06, "source": "https://openrouter.ai/z-ai/glm-4.6:exacto", "supports_function_calling": true, - "supports_prompt_caching": true, "supports_reasoning": true, "supports_tool_choice": true }, - "openrouter/xiaomi/mimo-v2-flash": { - "input_cost_per_token": 9e-08, - "output_cost_per_token": 2.9e-07, - "cache_creation_input_token_cost": 0.0, - "cache_read_input_token_cost": 0.0, - "litellm_provider": "openrouter", - "max_input_tokens": 262144, - "max_output_tokens": 16384, - "max_tokens": 16384, - "mode": "chat", - "supports_function_calling": true, - "supports_tool_choice": true, - "supports_reasoning": true, - "supports_vision": false, - "supports_prompt_caching": false - }, - "openrouter/z-ai/glm-4.7": { - "input_cost_per_token": 4e-07, - "output_cost_per_token": 1.5e-06, - "cache_creation_input_token_cost": 0.0, - "cache_read_input_token_cost": 0.0, - "litellm_provider": "openrouter", - "max_input_tokens": 202752, - "max_output_tokens": 64000, - "max_tokens": 64000, - "mode": "chat", - "supports_function_calling": true, - "supports_tool_choice": true, - "supports_reasoning": true, - "supports_vision": true, - "supports_prompt_caching": false, - "supports_assistant_prefill": true - }, - "openrouter/z-ai/glm-4.7-flash": { - "input_cost_per_token": 7e-08, - "output_cost_per_token": 4e-07, - "cache_creation_input_token_cost": 0.0, - "cache_read_input_token_cost": 0.0, - "litellm_provider": "openrouter", - "max_input_tokens": 200000, - "max_output_tokens": 32000, - "max_tokens": 32000, - "mode": "chat", - "supports_function_calling": true, - "supports_tool_choice": true, - "supports_reasoning": true, - "supports_vision": true, - "supports_prompt_caching": false - }, - "openrouter/minimax/minimax-m2.1": { - "input_cost_per_token": 2.7e-07, - "output_cost_per_token": 1.2e-06, - "cache_creation_input_token_cost": 0.0, - "cache_read_input_token_cost": 0.0, - "litellm_provider": "openrouter", - "max_input_tokens": 204000, - "max_output_tokens": 64000, - "max_tokens": 64000, - "mode": "chat", - "supports_function_calling": true, - "supports_tool_choice": true, - "supports_reasoning": true, - "supports_vision": true, - "supports_prompt_caching": false, - "supports_computer_use": false - }, "ovhcloud/DeepSeek-R1-Distill-Llama-70B": { "input_cost_per_token": 6.7e-07, "litellm_provider": "ovhcloud", @@ -27890,7 +27695,6 @@ "output_cost_per_token": 9e-07 }, "vercel_ai_gateway/google/gemini-2.0-flash": { - "deprecation_date": "2026-03-31", "input_cost_per_token": 1.5e-07, "litellm_provider": "vercel_ai_gateway", "max_input_tokens": 1048576, @@ -27900,7 +27704,6 @@ "output_cost_per_token": 6e-07 }, "vercel_ai_gateway/google/gemini-2.0-flash-lite": { - "deprecation_date": "2026-03-31", "input_cost_per_token": 7.5e-08, "litellm_provider": "vercel_ai_gateway", "max_input_tokens": 1048576, @@ -30570,7 +30373,6 @@ "supports_web_search": true }, "xai/grok-3": { - "cache_read_input_token_cost": 7.5e-07, "input_cost_per_token": 3e-06, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30585,7 +30387,6 @@ "supports_web_search": true }, "xai/grok-3-beta": { - "cache_read_input_token_cost": 7.5e-07, "input_cost_per_token": 3e-06, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30600,7 +30401,6 @@ "supports_web_search": true }, "xai/grok-3-fast-beta": { - "cache_read_input_token_cost": 1.25e-06, "input_cost_per_token": 5e-06, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30615,7 +30415,6 @@ "supports_web_search": true }, "xai/grok-3-fast-latest": { - "cache_read_input_token_cost": 1.25e-06, "input_cost_per_token": 5e-06, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30630,7 +30429,6 @@ "supports_web_search": true }, "xai/grok-3-latest": { - "cache_read_input_token_cost": 7.5e-07, "input_cost_per_token": 3e-06, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30645,7 +30443,6 @@ "supports_web_search": true }, "xai/grok-3-mini": { - "cache_read_input_token_cost": 7.5e-08, "input_cost_per_token": 3e-07, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30661,7 +30458,6 @@ "supports_web_search": true }, "xai/grok-3-mini-beta": { - "cache_read_input_token_cost": 7.5e-08, "input_cost_per_token": 3e-07, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30677,7 +30473,6 @@ "supports_web_search": true }, "xai/grok-3-mini-fast": { - "cache_read_input_token_cost": 1.5e-07, "input_cost_per_token": 6e-07, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30693,7 +30488,6 @@ "supports_web_search": true }, "xai/grok-3-mini-fast-beta": { - "cache_read_input_token_cost": 1.5e-07, "input_cost_per_token": 6e-07, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30709,7 +30503,6 @@ "supports_web_search": true }, "xai/grok-3-mini-fast-latest": { - "cache_read_input_token_cost": 1.5e-07, "input_cost_per_token": 6e-07, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30725,7 +30518,6 @@ "supports_web_search": true }, "xai/grok-3-mini-latest": { - "cache_read_input_token_cost": 7.5e-08, "input_cost_per_token": 3e-07, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30992,14 +30784,11 @@ "max_output_tokens": 128000, "mode": "chat", "supports_function_calling": true, - "supports_prompt_caching": true, "supports_reasoning": true, "supports_tool_choice": true, "source": "https://docs.z.ai/guides/overview/pricing" }, "zai/glm-4.6": { - "cache_creation_input_token_cost": 0, - "cache_read_input_token_cost": 1.1e-07, "input_cost_per_token": 6e-07, "output_cost_per_token": 2.2e-06, "litellm_provider": "zai", @@ -31007,8 +30796,6 @@ "max_output_tokens": 128000, "mode": "chat", "supports_function_calling": true, - "supports_prompt_caching": true, - "supports_reasoning": true, "supports_tool_choice": true, "source": "https://docs.z.ai/guides/overview/pricing" }, @@ -34656,4 +34443,4 @@ "output_cost_per_token": 0, "supports_reasoning": true } -} \ No newline at end of file +} diff --git a/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py b/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py index 56feff548ad..ded591a8f53 100644 --- a/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py +++ b/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py @@ -387,57 +387,25 @@ async def callback(code: str, state: str): 1. Try resource_metadata from WWW-Authenticate header (if present) 2. Fall back to path-based well-known URI: /.well-known/oauth-protected-resource/{path} ( - If the resource identifier value contains a path or query component, any terminating slash (/) - following the host component MUST be removed before inserting /.well-known/ and the well-known - URI path suffix between the host component and the path(include root path) and/or query components. + If the resource identifier value contains a path or query component, any terminating slash (/) + following the host component MUST be removed before inserting /.well-known/ and the well-known + URI path suffix between the host component and the path(include root path) and/or query components. https://datatracker.ietf.org/doc/html/rfc9728#section-3.1) 3. Fall back to root-based well-known URI: /.well-known/oauth-protected-resource - - Dual Pattern Support: - - Standard MCP pattern: /mcp/{server_name} (recommended, used by mcp-inspector, VSCode Copilot) - - LiteLLM legacy pattern: /{server_name}/mcp (backward compatibility) - - The resource URL returned matches the pattern used in the discovery request. """ - - -def _build_oauth_protected_resource_response( - request: Request, - mcp_server_name: Optional[str], - use_standard_pattern: bool, -) -> dict: - """ - Build OAuth protected resource response with the appropriate URL pattern. - - Args: - request: FastAPI Request object - mcp_server_name: Name of the MCP server - use_standard_pattern: If True, use /mcp/{server_name} pattern; - if False, use /{server_name}/mcp pattern - - Returns: - OAuth protected resource metadata dict - """ +@router.get(f"/.well-known/oauth-protected-resource{'' if get_server_root_path() == '/' else get_server_root_path()}/{{mcp_server_name}}/mcp") +@router.get("/.well-known/oauth-protected-resource") +async def oauth_protected_resource_mcp( + request: Request, mcp_server_name: Optional[str] = None +): from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( global_mcp_server_manager, ) - + # Get the correct base URL considering X-Forwarded-* headers request_base_url = get_request_base_url(request) mcp_server: Optional[MCPServer] = None if mcp_server_name: mcp_server = global_mcp_server_manager.get_mcp_server_by_name(mcp_server_name) - - # Build resource URL based on the pattern - if mcp_server_name: - if use_standard_pattern: - # Standard MCP pattern: /mcp/{server_name} - resource_url = f"{request_base_url}/mcp/{mcp_server_name}" - else: - # LiteLLM legacy pattern: /{server_name}/mcp - resource_url = f"{request_base_url}/{mcp_server_name}/mcp" - else: - resource_url = f"{request_base_url}/mcp" - return { "authorization_servers": [ ( @@ -446,55 +414,14 @@ def _build_oauth_protected_resource_response( else f"{request_base_url}" ) ], - "resource": resource_url, + "resource": ( + f"{request_base_url}/{mcp_server_name}/mcp" + if mcp_server_name + else f"{request_base_url}/mcp" + ), # this is what Claude will call "scopes_supported": mcp_server.scopes if mcp_server else [], } - -# 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(f"/.well-known/oauth-protected-resource{'' if get_server_root_path() == '/' else get_server_root_path()}/mcp/{{mcp_server_name}}") -async def oauth_protected_resource_mcp_standard( - request: Request, mcp_server_name: str -): - """ - OAuth protected resource discovery endpoint using standard MCP URL pattern. - - Standard pattern: /mcp/{server_name} - Discovery path: /.well-known/oauth-protected-resource/mcp/{server_name} - - This endpoint is compliant with MCP specification and works with standard - MCP clients like mcp-inspector and VSCode Copilot. - """ - return _build_oauth_protected_resource_response( - request=request, - mcp_server_name=mcp_server_name, - use_standard_pattern=True, - ) - - -# LiteLLM legacy pattern: /.well-known/oauth-protected-resource/{server_name}/mcp -# Kept for backward compatibility with existing deployments -@router.get(f"/.well-known/oauth-protected-resource{'' if get_server_root_path() == '/' else get_server_root_path()}/{{mcp_server_name}}/mcp") -@router.get("/.well-known/oauth-protected-resource") -async def oauth_protected_resource_mcp( - request: Request, mcp_server_name: Optional[str] = None -): - """ - OAuth protected resource discovery endpoint using LiteLLM legacy URL pattern. - - Legacy pattern: /{server_name}/mcp - Discovery path: /.well-known/oauth-protected-resource/{server_name}/mcp - - This endpoint is kept for backward compatibility. New integrations should - use the standard MCP pattern (/mcp/{server_name}) instead. - """ - return _build_oauth_protected_resource_response( - request=request, - mcp_server_name=mcp_server_name, - use_standard_pattern=False, - ) - """ https://datatracker.ietf.org/doc/html/rfc8414#section-3.1 RFC 8414: Path-aware OAuth discovery @@ -503,26 +430,15 @@ async def oauth_protected_resource_mcp( the well-known URI suffix between the host component and the path(include root path) component. """ - - -def _build_oauth_authorization_server_response( - request: Request, - mcp_server_name: Optional[str], -) -> dict: - """ - Build OAuth authorization server metadata response. - - Args: - request: FastAPI Request object - mcp_server_name: Name of the MCP server - - Returns: - OAuth authorization server metadata dict - """ +@router.get(f"/.well-known/oauth-authorization-server{'' if get_server_root_path() == '/' else get_server_root_path()}/{{mcp_server_name}}") +@router.get("/.well-known/oauth-authorization-server") +async def oauth_authorization_server_mcp( + request: Request, mcp_server_name: Optional[str] = None +): from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( global_mcp_server_manager, ) - + # Get the correct base URL considering X-Forwarded-* headers request_base_url = get_request_base_url(request) authorization_endpoint = ( @@ -554,58 +470,18 @@ def _build_oauth_authorization_server_response( } -# Standard MCP pattern: /.well-known/oauth-authorization-server/mcp/{server_name} -@router.get(f"/.well-known/oauth-authorization-server{'' if get_server_root_path() == '/' else get_server_root_path()}/mcp/{{mcp_server_name}}") -async def oauth_authorization_server_mcp_standard( - request: Request, mcp_server_name: str -): - """ - OAuth authorization server discovery endpoint using standard MCP URL pattern. - - Standard pattern: /mcp/{server_name} - Discovery path: /.well-known/oauth-authorization-server/mcp/{server_name} - """ - return _build_oauth_authorization_server_response( - request=request, - mcp_server_name=mcp_server_name, - ) - - -# LiteLLM legacy pattern and root endpoint -@router.get(f"/.well-known/oauth-authorization-server{'' if get_server_root_path() == '/' else get_server_root_path()}/{{mcp_server_name}}") -@router.get("/.well-known/oauth-authorization-server") -async def oauth_authorization_server_mcp( - request: Request, mcp_server_name: Optional[str] = None -): - """ - OAuth authorization server discovery endpoint. - - Supports both legacy pattern (/{server_name}) and root endpoint. - """ - return _build_oauth_authorization_server_response( - request=request, - mcp_server_name=mcp_server_name, - ) - - # Alias for standard OpenID discovery @router.get("/.well-known/openid-configuration") async def openid_configuration(request: Request): return await oauth_authorization_server_mcp(request) -# Additional legacy pattern support @router.get("/.well-known/oauth-authorization-server/{mcp_server_name}/mcp") -async def oauth_authorization_server_legacy( - request: Request, mcp_server_name: str +@router.get("/.well-known/oauth-authorization-server") +async def oauth_authorization_server_root( + request: Request, mcp_server_name: Optional[str] = None ): - """ - OAuth authorization server discovery for legacy /{server_name}/mcp pattern. - """ - return _build_oauth_authorization_server_response( - request=request, - mcp_server_name=mcp_server_name, - ) + return await oauth_authorization_server_mcp(request, mcp_server_name) @router.post("/{mcp_server_name}/register") diff --git a/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py b/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py index 92fd54e8775..e0217cd9e00 100644 --- a/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py +++ b/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py @@ -11,7 +11,7 @@ import hashlib import json import re -from typing import Any, Dict, List, Literal, Optional, Set, Tuple, Union, cast, Callable +from typing import Any, Dict, List, Literal, Optional, Set, Tuple, Union, cast from urllib.parse import urlparse from fastapi import HTTPException @@ -63,20 +63,7 @@ MCPOAuthMetadata, MCPServer, ) - -try: - from mcp.shared.tool_name_validation import SEP_986_URL, validate_tool_name # type: ignore -except ImportError: - SEP_986_URL = "https://github.com/modelcontextprotocol/protocol/blob/main/proposals/0001-tool-name-validation.md" - - def validate_tool_name(name: str): - from pydantic import BaseModel - - class MockResult(BaseModel): - is_valid: bool = True - warnings: list = [] - - return MockResult() +from mcp.shared.tool_name_validation import SEP_986_URL, validate_tool_name # Probe includes characters on both sides of the separator to mimic real prefixed tool names. @@ -103,9 +90,7 @@ def _warn(field_name: str, value: Optional[str]) -> None: if result.is_valid: return - warning_text = ( - "; ".join(result.warnings) if result.warnings else "Validation failed" - ) + warning_text = "; ".join(result.warnings) if result.warnings else "Validation failed" verbose_logger.warning( "MCP server '%s' has invalid %s '%s': %s", server_id, @@ -118,6 +103,7 @@ def _warn(field_name: str, value: Optional[str]) -> None: _warn("server_name", server_name) + def _deserialize_json_dict(data: Any) -> Optional[Dict[str, str]]: """ Deserialize optional JSON mappings stored in the database. @@ -405,13 +391,10 @@ def _register_openapi_tools(self, spec_path: str, server: MCPServer, base_url: s # Note: `extra_headers` on MCPServer is a List[str] of header names to forward # from the client request (not available in this OpenAPI tool generation step). # `static_headers` is a dict of concrete headers to always send. - headers = ( - merge_mcp_headers( - extra_headers=headers, - static_headers=server.static_headers, - ) - or {} - ) + headers = merge_mcp_headers( + extra_headers=headers, + static_headers=server.static_headers, + ) or {} verbose_logger.debug( f"Using headers for OpenAPI tools (excluding sensitive values): " @@ -1842,7 +1825,6 @@ async def _call_regular_mcp_tool( oauth2_headers: Optional[Dict[str, str]], raw_headers: Optional[Dict[str, str]], proxy_logging_obj: Optional[ProxyLogging], - host_progress_callback: Optional[Callable] = None, ) -> CallToolResult: """ Call a regular MCP tool using the MCP client. @@ -1927,7 +1909,7 @@ async def _call_regular_mcp_tool( ) async def _call_tool_via_client(client, params): - return await client.call_tool(params, host_progress_callback=host_progress_callback) + return await client.call_tool(params) tasks.append( asyncio.create_task(_call_tool_via_client(client, call_tool_params)) @@ -1964,8 +1946,6 @@ async def call_tool( proxy_logging_obj: Optional[ProxyLogging] = None, oauth2_headers: Optional[Dict[str, str]] = None, raw_headers: Optional[Dict[str, str]] = None, - host_progress_callback: Optional[Callable] = None, - ) -> CallToolResult: """ Call a tool with the given name and arguments @@ -2041,7 +2021,6 @@ async def call_tool( oauth2_headers=oauth2_headers, raw_headers=raw_headers, proxy_logging_obj=proxy_logging_obj, - host_progress_callback=host_progress_callback, ) # For OpenAPI tools, await outside the client context diff --git a/litellm/proxy/_experimental/mcp_server/server.py b/litellm/proxy/_experimental/mcp_server/server.py index 6d54c3871e5..03652ae155e 100644 --- a/litellm/proxy/_experimental/mcp_server/server.py +++ b/litellm/proxy/_experimental/mcp_server/server.py @@ -8,7 +8,8 @@ from datetime import datetime import traceback import uuid -from typing import Any, AsyncIterator, Dict, List, Optional, Tuple, Union, cast, Callable +from typing import Any, AsyncIterator, Dict, List, Optional, Tuple, Union, cast + from fastapi import FastAPI, HTTPException from pydantic import AnyUrl, ConfigDict from starlette.types import Receive, Scope, Send @@ -73,11 +74,7 @@ AuthContextMiddleware, auth_context_var, ) - - try: - from mcp.server.streamable_http_manager import StreamableHTTPSessionManager - except ImportError: - StreamableHTTPSessionManager = None # type: ignore + from mcp.server.streamable_http_manager import StreamableHTTPSessionManager from mcp.types import ( CallToolResult, EmbeddedResource, @@ -127,8 +124,8 @@ class ListMCPToolsRestAPIResponseObject(MCPTool): session_manager = StreamableHTTPSessionManager( app=server, event_store=None, - json_response=False, # enables SSE streaming - stateless=False, # enables session state + json_response=True, # Use JSON responses instead of SSE by default + stateless=True, ) # Create SSE session manager @@ -281,30 +278,6 @@ async def mcp_server_tool_call( 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: float | None): - """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: # Create a body date for logging body_data = {"name": name, "arguments": arguments} @@ -334,7 +307,6 @@ async def forward_progress(progress: float, total: float | None): mcp_server_auth_headers=mcp_server_auth_headers, oauth2_headers=oauth2_headers, raw_headers=raw_headers, - host_progress_callback=host_progress_callback, **data, # for logging ) except BlockedPiiEntityError as e: @@ -1369,7 +1341,6 @@ async def execute_mcp_tool( 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, - host_progress_callback: Optional[Callable] = None, **kwargs: Any, ) -> CallToolResult: """ @@ -1467,7 +1438,6 @@ async def execute_mcp_tool( oauth2_headers=oauth2_headers, raw_headers=raw_headers, litellm_logging_obj=litellm_logging_obj, - host_progress_callback=host_progress_callback, ) # Fall back to local tool registry with original name (legacy support) @@ -1715,7 +1685,6 @@ async def _handle_managed_mcp_tool( oauth2_headers: Optional[Dict[str, str]] = None, raw_headers: Optional[Dict[str, str]] = None, litellm_logging_obj: Optional[Any] = None, - host_progress_callback: Optional[Callable] = None, ) -> CallToolResult: """Handle tool execution for managed server tools""" # Import here to avoid circular import @@ -1731,7 +1700,6 @@ async def _handle_managed_mcp_tool( oauth2_headers=oauth2_headers, raw_headers=raw_headers, proxy_logging_obj=proxy_logging_obj, - host_progress_callback=host_progress_callback, ) verbose_logger.debug("CALL TOOL RESULT: %s", call_tool_result) return call_tool_result diff --git a/litellm/proxy/_experimental/out/404.html b/litellm/proxy/_experimental/out/404.html deleted file mode 100644 index a8ef84a338e..00000000000 --- a/litellm/proxy/_experimental/out/404.html +++ /dev/null @@ -1 +0,0 @@ -404: This page could not be found.LiteLLM Dashboard

    404

    \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/1098-a1702da59647cf14.js b/litellm/proxy/_experimental/out/_next/static/chunks/1098-a1702da59647cf14.js deleted file mode 100644 index 8bdb738f169..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/1098-a1702da59647cf14.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1098],{30280:function(e,t,l){l.d(t,{EX:function(){return c},Km:function(){return o},Tv:function(){return u}});var s=l(11713),a=l(45345),r=l(90246),i=l(19250),n=l(39760);let o=(0,r.n)("keys"),d=async function(e,t,l){let s=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};try{let a=(0,i.getProxyBaseUrl)(),r=new URLSearchParams(Object.entries({team_id:s.teamID,organization_id:s.organizationID,key_alias:s.selectedKeyAlias,key_hash:s.keyHash,user_id:s.userID,page:t,size:l,sort_by:s.sortBy,sort_order:s.sortOrder,expand:s.expand,status:s.status,return_full_object:"true",include_team_keys:"true",include_created_by_keys:"true"}).filter(e=>{let[,t]=e;return null!=t}).map(e=>{let[t,l]=e;return[t,String(l)]})),n="".concat(a?"".concat(a,"/key/list"):"/key/list","?").concat(r),o=await fetch(n,{method:"GET",headers:{[(0,i.getGlobalLitellmHeaderName)()]:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!o.ok){let e=await o.json(),t=(0,i.deriveErrorMessage)(e);throw(0,i.handleError)(t),Error(t)}let d=await o.json();return console.log("/key/list API Response:",d),d}catch(e){throw console.error("Failed to list keys:",e),e}},c=function(e,t){let l=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},{accessToken:r}=(0,n.Z)();return(0,s.a)({queryKey:o.list({page:e,limit:t,...l}),queryFn:async()=>await d(r,e,t,l),enabled:!!r,staleTime:3e4,placeholderData:a.Wk})},m=(0,r.n)("deletedKeys"),u=function(e,t){let l=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},{accessToken:r}=(0,n.Z)();return(0,s.a)({queryKey:m.list({page:e,limit:t,...l}),queryFn:async()=>await d(r,e,t,{...l,status:"deleted"}),enabled:!!r,staleTime:3e4,placeholderData:a.Wk})}},89348:function(e,t,l){l.d(t,{$:function(){return x}});var s=l(57437),a=l(16312),r=l(42264),i=l(65869),n=l(99397),o=l(2265),d=l(37592),c=l(99981),m=l(49322),u=l(15051),h=l(32489);function g(e){let{group:t,onChange:l,availableModels:a,maxFallbacks:r}=e,i=a.filter(e=>e!==t.primaryModel),n=e=>{let s=t.fallbackModels.filter((t,l)=>l!==e);l({...t,fallbackModels:s})},o=t.fallbackModels.length{let s=[...t.fallbackModels];s.includes(e)&&(s=s.filter(t=>t!==e)),l({...t,primaryModel:e,fallbackModels:s})},showSearch:!0,filterOption:(e,t)=>{var l;return(null!==(l=null==t?void 0:t.label)&&void 0!==l?l:"").toLowerCase().includes(e.toLowerCase())},options:a.map(e=>({label:e,value:e}))}),!t.primaryModel&&(0,s.jsxs)("div",{className:"mt-2 flex items-center gap-2 text-amber-600 text-xs bg-amber-50 p-2 rounded",children:[(0,s.jsx)(m.Z,{className:"w-4 h-4"}),(0,s.jsx)("span",{children:"Select a model to begin configuring fallbacks"})]})]}),(0,s.jsx)("div",{className:"flex items-center justify-center -my-4 z-10",children:(0,s.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-sm",children:[(0,s.jsx)(u.Z,{className:"w-4 h-4"}),"IF FAILS, TRY..."]})}),(0,s.jsxs)("div",{className:"transition-opacity duration-300 ".concat(t.primaryModel?"opacity-100":"opacity-50 pointer-events-none"),children:[(0,s.jsxs)("label",{className:"block text-sm font-semibold text-gray-700 mb-2",children:["Fallback Chain ",(0,s.jsx)("span",{className:"text-red-500",children:"*"}),(0,s.jsxs)("span",{className:"text-xs text-gray-500 font-normal ml-2",children:["(Max ",r," fallbacks at a time)"]})]}),(0,s.jsxs)("div",{className:"bg-gray-50 rounded-xl p-4 border border-gray-200",children:[(0,s.jsxs)("div",{className:"mb-4",children:[(0,s.jsx)(d.default,{mode:"multiple",className:"w-full",size:"large",placeholder:o?"Select fallback models to add...":"Maximum ".concat(r," fallbacks reached"),value:t.fallbackModels,onChange:e=>{let s=e.slice(0,r);l({...t,fallbackModels:s})},disabled:!t.primaryModel,options:i.map(e=>({label:e,value:e})),optionRender:(e,l)=>{let a=t.fallbackModels.includes(e.value),r=a?t.fallbackModels.indexOf(e.value)+1:null;return(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[a&&null!==r&&(0,s.jsx)("span",{className:"flex items-center justify-center w-5 h-5 rounded bg-indigo-100 text-indigo-600 text-xs font-bold",children:r}),(0,s.jsx)("span",{children:e.label})]})},maxTagCount:"responsive",maxTagPlaceholder:e=>(0,s.jsx)(c.Z,{styles:{root:{pointerEvents:"none"}},title:e.map(e=>{let{value:t}=e;return t}).join(", "),children:(0,s.jsxs)("span",{children:["+",e.length," more"]})}),showSearch:!0,filterOption:(e,t)=>{var l;return(null!==(l=null==t?void 0:t.label)&&void 0!==l?l:"").toLowerCase().includes(e.toLowerCase())}}),(0,s.jsx)("p",{className:"text-xs text-gray-500 mt-1 ml-1",children:o?"Search and select multiple models. Selected models will appear below in order. (".concat(t.fallbackModels.length,"/").concat(r," used)"):"Maximum ".concat(r," fallbacks reached. Remove some to add more.")})]}),(0,s.jsx)("div",{className:"space-y-2 min-h-[100px]",children:0===t.fallbackModels.length?(0,s.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,s.jsx)("span",{className:"text-sm",children:"No fallback models selected"}),(0,s.jsx)("span",{className:"text-xs mt-1",children:"Add models from the dropdown above"})]}):t.fallbackModels.map((e,t)=>(0,s.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-sm transition-all",children:[(0,s.jsxs)("div",{className:"flex items-center gap-3",children:[(0,s.jsx)("div",{className:"flex items-center justify-center w-6 h-6 rounded bg-gray-100 text-gray-400 group-hover:text-indigo-500 group-hover:bg-indigo-50",children:(0,s.jsx)("span",{className:"text-xs font-bold",children:t+1})}),(0,s.jsx)("div",{children:(0,s.jsx)("span",{className:"font-medium text-gray-800",children:e})})]}),(0,s.jsx)("button",{type:"button",onClick:()=>n(t),className:"opacity-0 group-hover:opacity-100 transition-opacity text-gray-400 hover:text-red-500 p-1",children:(0,s.jsx)(h.Z,{className:"w-4 h-4"})})]},"".concat(e,"-").concat(t)))})]})]})]})}function x(e){let{groups:t,onGroupsChange:l,availableModels:d,maxFallbacks:c=5,maxGroups:m=5}=e,[u,h]=(0,o.useState)(t.length>0?t[0].id:"1");(0,o.useEffect)(()=>{t.length>0?t.some(e=>e.id===u)||h(t[0].id):h("1")},[t]);let x=()=>{if(t.length>=m)return;let e=Date.now().toString();l([...t,{id:e,primaryModel:null,fallbackModels:[]}]),h(e)},p=e=>{if(1===t.length){r.ZP.warning("At least one group is required");return}let s=t.filter(t=>t.id!==e);l(s),u===e&&s.length>0&&h(s[s.length-1].id)},y=e=>{l(t.map(t=>t.id===e.id?e:t))},f=t.map((e,l)=>{let a=e.primaryModel?e.primaryModel:"Group ".concat(l+1);return{key:e.id,label:a,closable:t.length>1,children:(0,s.jsx)(g,{group:e,onChange:y,availableModels:d,maxFallbacks:c})}});return 0===t.length?(0,s.jsxs)("div",{className:"text-center py-12 bg-gray-50 rounded-lg border border-dashed border-gray-300",children:[(0,s.jsx)("p",{className:"text-gray-500 mb-4",children:"No fallback groups configured"}),(0,s.jsx)(a.z,{variant:"primary",onClick:x,icon:()=>(0,s.jsx)(n.Z,{className:"w-4 h-4"}),children:"Create First Group"})]}):(0,s.jsx)(i.default,{type:"editable-card",activeKey:u,onChange:h,onEdit:(e,l)=>{"add"===l?x():"remove"===l&&t.length>1&&p(e)},items:f,className:"fallback-tabs",tabBarStyle:{marginBottom:0},hideAdd:t.length>=m})}},62099:function(e,t,l){var s=l(57437),a=l(2265),r=l(37592),i=l(99981),n=l(23496),o=l(63709),d=l(15424),c=l(31283);let{Option:m}=r.default;t.Z=e=>{var t;let{form:l,autoRotationEnabled:u,onAutoRotationChange:h,rotationInterval:g,onRotationIntervalChange:x,isCreateMode:p=!1}=e,y=g&&!["7d","30d","90d","180d","365d"].includes(g),[f,j]=(0,a.useState)(y),[b,v]=(0,a.useState)(y?g:""),[_,N]=(0,a.useState)((null==l?void 0:null===(t=l.getFieldValue)||void 0===t?void 0:t.call(l,"duration"))||"");return(0,s.jsxs)("div",{className:"space-y-6",children:[(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Key Expiry Settings"}),(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,s.jsx)("span",{children:"Expire Key"}),(0,s.jsx)(i.Z,{title:p?"Set when this key should expire. Format: 30s (seconds), 30m (minutes), 30h (hours), 30d (days). Leave empty to never expire.":"Set when this key should expire. Format: 30s (seconds), 30m (minutes), 30h (hours), 30d (days). Use -1 to never expire.",children:(0,s.jsx)(d.Z,{className:"text-gray-400 cursor-help text-xs"})})]}),(0,s.jsx)(c.o,{name:"duration",placeholder:p?"e.g., 30d or leave empty to never expire":"e.g., 30d or -1 to never expire",className:"w-full",value:_,onValueChange:e=>{N(e),l&&"function"==typeof l.setFieldValue?l.setFieldValue("duration",e):l&&"function"==typeof l.setFieldsValue&&l.setFieldsValue({duration:e})}})]})]}),(0,s.jsx)(n.Z,{}),(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Auto-Rotation Settings"}),(0,s.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,s.jsx)("span",{children:"Enable Auto-Rotation"}),(0,s.jsx)(i.Z,{title:"Key will automatically regenerate at the specified interval for enhanced security.",children:(0,s.jsx)(d.Z,{className:"text-gray-400 cursor-help text-xs"})})]}),(0,s.jsx)(o.Z,{checked:u,onChange:h,size:"default",className:u?"":"bg-gray-400"})]}),u&&(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,s.jsx)("span",{children:"Rotation Interval"}),(0,s.jsx)(i.Z,{title:"How often the key should be automatically rotated. Choose the interval that best fits your security requirements.",children:(0,s.jsx)(d.Z,{className:"text-gray-400 cursor-help text-xs"})})]}),(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsxs)(r.default,{value:f?"custom":g,onChange:e=>{"custom"===e?j(!0):(j(!1),v(""),x(e))},className:"w-full",placeholder:"Select interval",children:[(0,s.jsx)(m,{value:"7d",children:"7 days"}),(0,s.jsx)(m,{value:"30d",children:"30 days"}),(0,s.jsx)(m,{value:"90d",children:"90 days"}),(0,s.jsx)(m,{value:"180d",children:"180 days"}),(0,s.jsx)(m,{value:"365d",children:"365 days"}),(0,s.jsx)(m,{value:"custom",children:"Custom interval"})]}),f&&(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)(c.o,{value:b,onChange:e=>{let t=e.target.value;v(t),x(t)},placeholder:"e.g., 1s, 5m, 2h, 14d"}),(0,s.jsx)("div",{className:"text-xs text-gray-500",children:"Supported formats: seconds (s), minutes (m), hours (h), days (d)"})]})]})]})]}),u&&(0,s.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."})]})]})}},72885:function(e,t,l){var s=l(57437),a=l(2265),r=l(77355),i=l(93416),n=l(74998),o=l(95704),d=l(76593),c=l(9114);t.Z=e=>{let{accessToken:t,initialModelAliases:l={},onAliasUpdate:m,showExampleConfig:u=!0}=e,[h,g]=(0,a.useState)([]),[x,p]=(0,a.useState)({aliasName:"",targetModel:""}),[y,f]=(0,a.useState)(null);(0,a.useEffect)(()=>{g(Object.entries(l).map((e,t)=>{let[l,s]=e;return{id:"".concat(t,"-").concat(l),aliasName:l,targetModel:s}}))},[l]);let j=e=>{f({...e})},b=()=>{if(!y)return;if(!y.aliasName||!y.targetModel){c.Z.fromBackend("Please provide both alias name and target model");return}if(h.some(e=>e.id!==y.id&&e.aliasName===y.aliasName)){c.Z.fromBackend("An alias with this name already exists");return}let e=h.map(e=>e.id===y.id?y:e);g(e),f(null);let t={};e.forEach(e=>{t[e.aliasName]=e.targetModel}),m&&m(t),c.Z.success("Alias updated successfully")},v=()=>{f(null)},_=e=>{let t=h.filter(t=>t.id!==e);g(t);let l={};t.forEach(e=>{l[e.aliasName]=e.targetModel}),m&&m(l),c.Z.success("Alias deleted successfully")},N=h.reduce((e,t)=>(e[t.aliasName]=t.targetModel,e),{});return(0,s.jsxs)("div",{className:"mt-4",children:[(0,s.jsxs)("div",{className:"mb-6",children:[(0,s.jsx)(o.xv,{className:"text-sm font-medium text-gray-700 mb-2",children:"Add New Alias"}),(0,s.jsxs)("div",{className:"grid grid-cols-3 gap-4",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"block text-xs text-gray-500 mb-1",children:"Alias Name"}),(0,s.jsx)("input",{type:"text",value:x.aliasName,onChange:e=>p({...x,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,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"block text-xs text-gray-500 mb-1",children:"Target Model"}),(0,s.jsx)(d.Z,{accessToken:t,value:x.targetModel,placeholder:"Select target model",onChange:e=>p({...x,targetModel:e}),showLabel:!1})]}),(0,s.jsx)("div",{className:"flex items-end",children:(0,s.jsxs)("button",{onClick:()=>{if(!x.aliasName||!x.targetModel){c.Z.fromBackend("Please provide both alias name and target model");return}if(h.some(e=>e.aliasName===x.aliasName)){c.Z.fromBackend("An alias with this name already exists");return}let e=[...h,{id:"".concat(Date.now(),"-").concat(x.aliasName),aliasName:x.aliasName,targetModel:x.targetModel}];g(e),p({aliasName:"",targetModel:""});let t={};e.forEach(e=>{t[e.aliasName]=e.targetModel}),m&&m(t),c.Z.success("Alias added successfully")},disabled:!x.aliasName||!x.targetModel,className:"flex items-center px-4 py-2 rounded-md text-sm ".concat(x.aliasName&&x.targetModel?"bg-green-600 text-white hover:bg-green-700":"bg-gray-300 text-gray-500 cursor-not-allowed"),children:[(0,s.jsx)(r.Z,{className:"w-4 h-4 mr-1"}),"Add Alias"]})})]})]}),(0,s.jsx)(o.xv,{className:"text-sm font-medium text-gray-700 mb-2",children:"Manage Existing Aliases"}),(0,s.jsx)("div",{className:"rounded-lg custom-border relative mb-6",children:(0,s.jsx)("div",{className:"overflow-x-auto",children:(0,s.jsxs)(o.iA,{className:"[&_td]:py-0.5 [&_th]:py-1",children:[(0,s.jsx)(o.ss,{children:(0,s.jsxs)(o.SC,{children:[(0,s.jsx)(o.xs,{className:"py-1 h-8",children:"Alias Name"}),(0,s.jsx)(o.xs,{className:"py-1 h-8",children:"Target Model"}),(0,s.jsx)(o.xs,{className:"py-1 h-8",children:"Actions"})]})}),(0,s.jsxs)(o.RM,{children:[h.map(e=>(0,s.jsx)(o.SC,{className:"h-8",children:y&&y.id===e.id?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(o.pj,{className:"py-0.5",children:(0,s.jsx)("input",{type:"text",value:y.aliasName,onChange:e=>f({...y,aliasName:e.target.value}),className:"w-full px-2 py-1 border border-gray-300 rounded-md text-sm"})}),(0,s.jsx)(o.pj,{className:"py-0.5",children:(0,s.jsx)(d.Z,{accessToken:t,value:y.targetModel,onChange:e=>f({...y,targetModel:e}),showLabel:!1,style:{height:"32px"}})}),(0,s.jsx)(o.pj,{className:"py-0.5 whitespace-nowrap",children:(0,s.jsxs)("div",{className:"flex space-x-2",children:[(0,s.jsx)("button",{onClick:b,className:"text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded hover:bg-blue-100",children:"Save"}),(0,s.jsx)("button",{onClick:v,className:"text-xs bg-gray-50 text-gray-600 px-2 py-1 rounded hover:bg-gray-100",children:"Cancel"})]})})]}):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(o.pj,{className:"py-0.5 text-sm text-gray-900",children:e.aliasName}),(0,s.jsx)(o.pj,{className:"py-0.5 text-sm text-gray-500",children:e.targetModel}),(0,s.jsx)(o.pj,{className:"py-0.5 whitespace-nowrap",children:(0,s.jsxs)("div",{className:"flex space-x-2",children:[(0,s.jsx)("button",{onClick:()=>j(e),className:"text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded hover:bg-blue-100",children:(0,s.jsx)(i.Z,{className:"w-3 h-3"})}),(0,s.jsx)("button",{onClick:()=>_(e.id),className:"text-xs bg-red-50 text-red-600 px-2 py-1 rounded hover:bg-red-100",children:(0,s.jsx)(n.Z,{className:"w-3 h-3"})})]})})]})},e.id)),0===h.length&&(0,s.jsx)(o.SC,{children:(0,s.jsx)(o.pj,{colSpan:3,className:"py-0.5 text-sm text-gray-500 text-center",children:"No aliases added yet. Add a new alias above."})})]})]})})}),u&&(0,s.jsxs)(o.Zb,{children:[(0,s.jsx)(o.Dx,{className:"mb-4",children:"Configuration Example"}),(0,s.jsx)(o.xv,{className:"text-gray-600 mb-4",children:"Here's how your current aliases would look in the config:"}),(0,s.jsx)("div",{className:"bg-gray-100 rounded-lg p-4 font-mono text-sm",children:(0,s.jsxs)("div",{className:"text-gray-700",children:["model_aliases:",0===Object.keys(N).length?(0,s.jsxs)("span",{className:"text-gray-500",children:[(0,s.jsx)("br",{}),"\xa0\xa0# No aliases configured yet"]}):Object.entries(N).map(e=>{let[t,l]=e;return(0,s.jsxs)("span",{children:[(0,s.jsx)("br",{}),'\xa0\xa0"',t,'": "',l,'"']},t)})]})})]})]})}},76593:function(e,t,l){var s=l(57437),a=l(2265),r=l(56522),i=l(37592),n=l(69993),o=l(10703);t.Z=e=>{let{accessToken:t,value:l,placeholder:d="Select a Model",onChange:c,disabled:m=!1,style:u,className:h,showLabel:g=!0,labelText:x="Select Model"}=e,[p,y]=(0,a.useState)(l),[f,j]=(0,a.useState)(!1),[b,v]=(0,a.useState)([]),_=(0,a.useRef)(null);return(0,a.useEffect)(()=>{y(l)},[l]),(0,a.useEffect)(()=>{t&&(async()=>{try{let e=await (0,o.p)(t);console.log("Fetched models for selector:",e),e.length>0&&v(e)}catch(e){console.error("Error fetching model info:",e)}})()},[t]),(0,s.jsxs)("div",{children:[g&&(0,s.jsxs)(r.x,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,s.jsx)(n.Z,{className:"mr-2"})," ",x]}),(0,s.jsx)(i.default,{value:p,placeholder:d,onChange:e=>{"custom"===e?(j(!0),y(void 0)):(j(!1),y(e),c&&c(e))},options:[...Array.from(new Set(b.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%",...u},showSearch:!0,className:"rounded-md ".concat(h||""),disabled:m}),f&&(0,s.jsx)(r.o,{className:"mt-2",placeholder:"Enter custom model name",onValueChange:e=>{_.current&&clearTimeout(_.current),_.current=setTimeout(()=>{y(e),c&&c(e)},500)},disabled:m})]})}},2597:function(e,t,l){var s=l(57437);l(2265);var a=l(92280),r=l(54507);t.Z=function(e){let{value:t,onChange:l,premiumUser:i=!1,disabledCallbacks:n=[],onDisabledCallbacksChange:o}=e;return i?(0,s.jsx)(r.Z,{value:t,onChange:l,disabledCallbacks:n,onDisabledCallbacksChange:o}):(0,s.jsxs)("div",{children:[(0,s.jsxs)("div",{className:"flex flex-wrap gap-2 mb-3",children:[(0,s.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,s.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,s.jsx)("div",{className:"p-3 bg-yellow-50 border border-yellow-200 rounded-lg",children:(0,s.jsxs)(a.x,{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,s.jsx)("a",{href:"https://www.litellm.ai/#pricing",target:"_blank",rel:"noopener noreferrer",className:"underline",children:"here"}),"."]})})]})}},65895:function(e,t,l){var s=l(57437);l(2265);var a=l(37592),r=l(10032),i=l(99981),n=l(15424);let{Option:o}=a.default;t.Z=e=>{let{type:t,name:l,showDetailedDescriptions:d=!0,className:c="",initialValue:m=null,form:u,onChange:h}=e,g=t.toUpperCase(),x=t.toLowerCase(),p="Select 'guaranteed_throughput' to prevent overallocating ".concat(g," limit when the key belongs to a Team with specific ").concat(g," limits.");return(0,s.jsx)(r.Z.Item,{label:(0,s.jsxs)("span",{children:[g," Rate Limit Type"," ",(0,s.jsx)(i.Z,{title:p,children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:l,initialValue:m,className:c,children:(0,s.jsx)(a.default,{defaultValue:d?"default":void 0,placeholder:"Select rate limit type",style:{width:"100%"},optionLabelProp:d?"label":void 0,onChange:e=>{u&&u.setFieldValue(l,e),h&&h(e)},children:d?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(o,{value:"best_effort_throughput",label:"Default",children:(0,s.jsxs)("div",{style:{padding:"4px 0"},children:[(0,s.jsx)("div",{style:{fontWeight:500},children:"Default"}),(0,s.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["Best effort throughput - no error if we're overallocating ",x," (Team/Key Limits checked at runtime)."]})]})}),(0,s.jsx)(o,{value:"guaranteed_throughput",label:"Guaranteed throughput",children:(0,s.jsxs)("div",{style:{padding:"4px 0"},children:[(0,s.jsx)("div",{style:{fontWeight:500},children:"Guaranteed throughput"}),(0,s.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["Guaranteed throughput - raise an error if we're overallocating ",x," (also checks model-specific limits)"]})]})}),(0,s.jsx)(o,{value:"dynamic",label:"Dynamic",children:(0,s.jsxs)("div",{style:{padding:"4px 0"},children:[(0,s.jsx)("div",{style:{fontWeight:500},children:"Dynamic"}),(0,s.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["If the key has a set ",g," (e.g. 2 ",g,") and there are no 429 errors, it can dynamically exceed the limit when the model being called is not erroring."]})]})})]}):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(o,{value:"best_effort_throughput",children:"Best effort throughput"}),(0,s.jsx)(o,{value:"guaranteed_throughput",children:"Guaranteed throughput"}),(0,s.jsx)(o,{value:"dynamic",children:"Dynamic"})]})})})}},76364:function(e,t,l){var s=l(57437),a=l(2265),r=l(58643),i=l(19250),n=l(56334),o=l(89348),d=l(10703);let c=(0,a.forwardRef)((e,t)=>{let{accessToken:l,value:c,onChange:m,modelData:u}=e,[h,g]=(0,a.useState)({routerSettings:{},selectedStrategy:null,enableTagFiltering:!1}),[x,p]=(0,a.useState)([]),[y,f]=(0,a.useState)([]),[j,b]=(0,a.useState)([]),[v,_]=(0,a.useState)([]),[N,w]=(0,a.useState)({}),[k,S]=(0,a.useState)({}),Z=(0,a.useRef)(!1),C=(0,a.useRef)(null),M=e=>e&&0!==e.length?e.map((e,t)=>{let[l,s]=Object.entries(e)[0];return{id:(t+1).toString(),primaryModel:l||null,fallbackModels:s||[]}}):[{id:"1",primaryModel:null,fallbackModels:[]}],T=e=>e.filter(e=>e.primaryModel&&e.fallbackModels.length>0).map(e=>({[e.primaryModel]:e.fallbackModels}));(0,a.useEffect)(()=>{let e=(null==c?void 0:c.router_settings)?JSON.stringify({routing_strategy:c.router_settings.routing_strategy,fallbacks:c.router_settings.fallbacks,enable_tag_filtering:c.router_settings.enable_tag_filtering}):null;if(Z.current&&e===C.current){Z.current=!1;return}if(Z.current&&e!==C.current&&(Z.current=!1),e!==C.current){if(C.current=e,null==c?void 0:c.router_settings){var t;let e=c.router_settings,{fallbacks:l,...s}=e;g({routerSettings:s,selectedStrategy:e.routing_strategy||null,enableTagFiltering:null!==(t=e.enable_tag_filtering)&&void 0!==t&&t});let a=e.fallbacks||[];p(a),f(M(a))}else g({routerSettings:{},selectedStrategy:null,enableTagFiltering:!1}),p([]),f([{id:"1",primaryModel:null,fallbackModels:[]}])}},[c]),(0,a.useEffect)(()=>{l&&(0,i.getRouterSettingsCall)(l).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}}),w(t);let l=e.fields.find(e=>"routing_strategy"===e.field_name);(null==l?void 0:l.options)&&_(l.options),e.routing_strategy_descriptions&&S(e.routing_strategy_descriptions)}})},[l]),(0,a.useEffect)(()=>{l&&(async()=>{try{let e=await (0,d.p)(l);b(e)}catch(e){console.error("Error fetching model info for fallbacks:",e)}})()},[l]);let L=()=>{let e=new Set(["allowed_fails","cooldown_time","num_retries","timeout","retry_after"]),t=new Set(["model_group_alias","retry_policy"]),l=(l,s,a)=>{if(null==s)return a;let r=String(s).trim();if(""===r||"null"===r.toLowerCase())return null;if(e.has(l)){let e=Number(r);return Number.isNaN(e)?a:e}if(t.has(l)){if(""===r)return null;try{return JSON.parse(r)}catch(e){return a}}return"true"===r.toLowerCase()||"false"!==r.toLowerCase()&&r},s=Object.fromEntries(Object.entries({...h.routerSettings,enable_tag_filtering:h.enableTagFiltering,routing_strategy:h.selectedStrategy,fallbacks:x.length>0?x:null}).map(e=>{let[t,s]=e;if("routing_strategy_args"!==t&&"routing_strategy"!==t&&"enable_tag_filtering"!==t&&"fallbacks"!==t){let e=document.querySelector('input[name="'.concat(t,'"]'));if(e&&void 0!==e.value&&""!==e.value){let a=l(t,e.value,s);return[t,a]}}else if("routing_strategy"===t)return[t,h.selectedStrategy];else if("enable_tag_filtering"===t)return[t,h.enableTagFiltering];else if("fallbacks"===t)return[t,x.length>0?x:null];else if("routing_strategy_args"===t&&"latency-based-routing"===h.selectedStrategy){let e=document.querySelector('input[name="lowest_latency_buffer"]'),t=document.querySelector('input[name="ttl"]'),l={};return(null==e?void 0:e.value)&&(l.lowest_latency_buffer=Number(e.value)),(null==t?void 0:t.value)&&(l.ttl=Number(t.value)),["routing_strategy_args",Object.keys(l).length>0?l:null]}return[t,s]}).filter(e=>null!=e)),a=function(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return 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:a(s.routing_strategy),allowed_fails:a(s.allowed_fails,!0),cooldown_time:a(s.cooldown_time,!0),num_retries:a(s.num_retries,!0),timeout:a(s.timeout,!0),retry_after:a(s.retry_after,!0),fallbacks:x.length>0?x:null,context_window_fallbacks:a(s.context_window_fallbacks),retry_policy:a(s.retry_policy),model_group_alias:a(s.model_group_alias),enable_tag_filtering:h.enableTagFiltering,routing_strategy_args:a(s.routing_strategy_args)}};(0,a.useEffect)(()=>{if(!m)return;let e=setTimeout(()=>{Z.current=!0,m({router_settings:L()})},100);return()=>clearTimeout(e)},[h,x]);let F=Array.from(new Set(j.map(e=>e.model_group))).sort();return((0,a.useImperativeHandle)(t,()=>({getValue:()=>({router_settings:L()})})),l)?(0,s.jsx)("div",{className:"w-full",children:(0,s.jsxs)(r.v0,{className:"w-full",children:[(0,s.jsxs)(r.td,{variant:"line",defaultValue:"1",className:"px-8 pt-4",children:[(0,s.jsx)(r.OK,{value:"1",children:"Loadbalancing"}),(0,s.jsx)(r.OK,{value:"2",children:"Fallbacks"})]}),(0,s.jsxs)(r.nP,{className:"px-8 py-6",children:[(0,s.jsx)(r.x4,{children:(0,s.jsx)(n.Z,{value:h,onChange:g,routerFieldsMetadata:N,availableRoutingStrategies:v,routingStrategyDescriptions:k})}),(0,s.jsx)(r.x4,{children:(0,s.jsx)(o.$,{groups:y,onGroupsChange:e=>{f(e),p(T(e))},availableModels:F,maxFallbacks:5,maxGroups:5})})]})]})}):null});c.displayName="RouterSettingsAccordion",t.Z=c},71098:function(e,t,l){l.d(t,{ZP:function(){return et},wk:function(){return X},Nr:function(){return ee}});var s=l(57437),a=l(30280),r=l(39760),i=l(59872),n=l(15424),o=l(29827),d=l(87452),c=l(88829),m=l(72208),u=l(78489),h=l(49804),g=l(67101),x=l(84264),p=l(49566),y=l(96761),f=l(37592),j=l(10032),b=l(22116),v=l(99981),_=l(29967),N=l(5545),w=l(63709),k=l(4260),S=l(7310),Z=l.n(S),C=l(2265),M=l(29233),T=l(20347),L=l(82586),F=l(97434),P=l(65925),A=l(63610),E=l(62099),I=l(72885),V=l(95096),R=l(2597),O=l(65895),D=l(76364),K=l(84376),U=l(7765),q=l(46468),B=l(97492),G=l(68473),z=l(9114),J=l(19250),W=l(24199),H=l(97415);let Y=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: ".concat(e);let l=t;try{if(!e||"object"!=typeof e||e instanceof Error){let e=t.match(/\{[\s\S]*\}/);if(e){let t=JSON.parse(e[0]),s=(null==t?void 0:t.error)||t;(null==s?void 0:s.message)&&(l=s.message)}}else{let t=(null==e?void 0:e.error)||e;(null==t?void 0:t.message)&&(l=t.message)}}catch(e){}return t.includes("team_member_permission_error")||l.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: ".concat(e)},{Option:$}=f.default,Q=e=>{let t=[];if(console.log("data:",JSON.stringify(e)),e)for(let l of e)l.metadata&&l.metadata.tags&&t.push(...l.metadata.tags);let l=Array.from(new Set(t)).map(e=>({value:e,label:e}));return console.log("uniqueTags:",l),l},X=async(e,t,l,s)=>{try{if(null===e||null===t)return[];if(null!==l){let a=(await (0,J.modelAvailableCall)(l,e,t,!0,s,!0)).data.map(e=>e.id);return console.log("available_model_names:",a),a}return[]}catch(e){return console.error("Error fetching user models:",e),[]}},ee=async(e,t,l,s)=>{try{if(null===e||null===t)return;if(null!==l){let a=(await (0,J.modelAvailableCall)(l,e,t)).data.map(e=>e.id);console.log("available_model_names:",a),s(a)}}catch(e){console.error("Error fetching user models:",e)}};var et=e=>{let{team:t,teams:l,data:S,addKey:et}=e,{accessToken:el,userId:es,userRole:ea,premiumUser:er}=(0,r.Z)(),ei=(0,o.NL)(),[en]=j.Z.useForm(),[eo,ed]=(0,C.useState)(!1),[ec,em]=(0,C.useState)(null),[eu,eh]=(0,C.useState)(null),[eg,ex]=(0,C.useState)([]),[ep,ey]=(0,C.useState)([]),[ef,ej]=(0,C.useState)("you"),[eb,ev]=(0,C.useState)(Q(S)),[e_,eN]=(0,C.useState)([]),[ew,ek]=(0,C.useState)([]),[eS,eZ]=(0,C.useState)([]),[eC,eM]=(0,C.useState)([]),[eT,eL]=(0,C.useState)(t),[eF,eP]=(0,C.useState)(!1),[eA,eE]=(0,C.useState)(null),[eI,eV]=(0,C.useState)({}),[eR,eO]=(0,C.useState)([]),[eD,eK]=(0,C.useState)(!1),[eU,eq]=(0,C.useState)([]),[eB,eG]=(0,C.useState)([]),[ez,eJ]=(0,C.useState)("llm_api"),[eW,eH]=(0,C.useState)({}),[eY,e$]=(0,C.useState)(!1),[eQ,eX]=(0,C.useState)("30d"),[e0,e4]=(0,C.useState)(null),[e1,e2]=(0,C.useState)(0),e5=()=>{ed(!1),en.resetFields(),eM([]),eG([]),eJ("llm_api"),eH({}),e$(!1),eX("30d"),e4(null),e2(e=>e+1)},e3=()=>{ed(!1),em(null),eL(null),en.resetFields(),eM([]),eG([]),eJ("llm_api"),eH({}),e$(!1),eX("30d"),e4(null),e2(e=>e+1)};(0,C.useEffect)(()=>{es&&ea&&el&&ee(es,ea,el,ex)},[el,es,ea]),(0,C.useEffect)(()=>{let e=async()=>{try{let e=(await (0,J.getPoliciesList)(el)).policies.map(e=>e.policy_name);ek(e)}catch(e){console.error("Failed to fetch policies:",e)}},t=async()=>{try{let e=await (0,J.getPromptsList)(el);eZ(e.prompts.map(e=>e.prompt_id))}catch(e){console.error("Failed to fetch prompts:",e)}};(async()=>{try{let e=(await (0,J.getGuardrailsList)(el)).guardrails.map(e=>e.guardrail_name);eN(e)}catch(e){console.error("Failed to fetch guardrails:",e)}})(),e(),t()},[el]),(0,C.useEffect)(()=>{(async()=>{try{if(el){let e=sessionStorage.getItem("possibleUserRoles");if(e)eV(JSON.parse(e));else{let e=await (0,J.getPossibleUserRoles)(el);sessionStorage.setItem("possibleUserRoles",JSON.stringify(e)),eV(e)}}}catch(e){console.error("Error fetching possible user roles:",e)}})()},[el]);let e7=ep.includes("no-default-models")&&!eT,e6=async e=>{try{var t,l,s,r,i,n,o;let d;let c=null!==(i=null==e?void 0:e.key_alias)&&void 0!==i?i:"",m=null!==(n=null==e?void 0:e.team_id)&&void 0!==n?n:null;if((null!==(o=null==S?void 0:S.filter(e=>e.team_id===m).map(e=>e.key_alias))&&void 0!==o?o:[]).includes(c))throw Error("Key alias ".concat(c," already exists for team with ID ").concat(m,", please provide another key alias"));z.Z.info("Making API Call"),ed(!0),"you"===ef&&(e.user_id=es);let u={};try{u=JSON.parse(e.metadata||"{}")}catch(e){console.error("Error parsing metadata:",e)}if("service_account"===ef&&(u.service_account_id=e.key_alias),eC.length>0&&(u={...u,logging:eC.filter(e=>e.callback_name)}),eB.length>0){let e=(0,F.Z3)(eB);u={...u,litellm_disabled_callbacks:e}}if(eY&&(e.auto_rotate=!0,e.rotation_interval=eQ),e.duration&&""!==e.duration.trim()||(e.duration=null),e.metadata=JSON.stringify(u),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&&((null===(t=e.allowed_mcp_servers_and_groups.servers)||void 0===t?void 0:t.length)>0||(null===(l=e.allowed_mcp_servers_and_groups.accessGroups)||void 0===l?void 0:l.length)>0)){e.object_permission||(e.object_permission={});let{servers:t,accessGroups:l}=e.allowed_mcp_servers_and_groups;t&&t.length>0&&(e.object_permission.mcp_servers=t),l&&l.length>0&&(e.object_permission.mcp_access_groups=l),delete e.allowed_mcp_servers_and_groups}let h=e.mcp_tool_permissions||{};if(Object.keys(h).length>0&&(e.object_permission||(e.object_permission={}),e.object_permission.mcp_tool_permissions=h),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&&((null===(s=e.allowed_agents_and_groups.agents)||void 0===s?void 0:s.length)>0||(null===(r=e.allowed_agents_and_groups.accessGroups)||void 0===r?void 0:r.length)>0)){e.object_permission||(e.object_permission={});let{agents:t,accessGroups:l}=e.allowed_agents_and_groups;t&&t.length>0&&(e.object_permission.agents=t),l&&l.length>0&&(e.object_permission.agent_access_groups=l),delete e.allowed_agents_and_groups}Object.keys(eW).length>0&&(e.aliases=JSON.stringify(eW)),(null==e0?void 0:e0.router_settings)&&Object.values(e0.router_settings).some(e=>null!=e&&""!==e)&&(e.router_settings=e0.router_settings),d="service_account"===ef?await (0,J.keyCreateServiceAccountCall)(el,e):await (0,J.keyCreateCall)(el,es,e),console.log("key create Response:",d),et(d),ei.invalidateQueries({queryKey:a.Km.lists()}),em(d.key),eh(d.soft_budget),z.Z.success("Virtual Key Created"),en.resetFields(),localStorage.removeItem("userData"+es)}catch(t){console.log("error in create key:",t);let e=Y(t);z.Z.fromBackend(e)}};(0,C.useEffect)(()=>{if(es&&ea&&el){var e;X(es,ea,el,null!==(e=null==eT?void 0:eT.team_id)&&void 0!==e?e:null).then(e=>{var t;ey(Array.from(new Set([...null!==(t=null==eT?void 0:eT.models)&&void 0!==t?t:[],...e])))})}en.setFieldValue("models",[])},[eT,el,es,ea]);let e9=async e=>{if(!e){eO([]);return}eK(!0);try{let t=new URLSearchParams;if(t.append("user_email",e),null==el)return;let l=(await (0,J.userFilterUICall)(el,t)).map(e=>({label:"".concat(e.user_email," (").concat(e.user_id,")"),value:e.user_id,user:e}));eO(l)}catch(e){console.error("Error fetching users:",e),z.Z.fromBackend("Failed to search for users")}finally{eK(!1)}},e8=(0,C.useCallback)(Z()(e=>e9(e),300),[el]),te=(e,t)=>{let l=t.user;en.setFieldsValue({user_id:l.user_id})};return(0,s.jsxs)("div",{children:[ea&&T.LQ.includes(ea)&&(0,s.jsx)(u.Z,{className:"mx-auto",onClick:()=>ed(!0),children:"+ Create New Key"}),(0,s.jsx)(b.Z,{open:eo,width:1e3,footer:null,onOk:e5,onCancel:e3,children:(0,s.jsxs)(j.Z,{form:en,onFinish:e6,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,s.jsxs)("div",{className:"mb-8",children:[(0,s.jsx)(y.Z,{className:"mb-4",children:"Key Ownership"}),(0,s.jsx)(j.Z.Item,{label:(0,s.jsxs)("span",{children:["Owned By"," ",(0,s.jsx)(v.Z,{title:"Select who will own this Virtual Key",children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),className:"mb-4",children:(0,s.jsxs)(_.ZP.Group,{onChange:e=>ej(e.target.value),value:ef,children:[(0,s.jsx)(_.ZP,{value:"you",children:"You"}),(0,s.jsx)(_.ZP,{value:"service_account",children:"Service Account"}),"Admin"===ea&&(0,s.jsx)(_.ZP,{value:"another_user",children:"Another User"})]})}),"another_user"===ef&&(0,s.jsx)(j.Z.Item,{label:(0,s.jsxs)("span",{children:["User ID"," ",(0,s.jsx)(v.Z,{title:"The user who will own this key and be responsible for its usage",children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"user_id",className:"mt-4",rules:[{required:"another_user"===ef,message:"Please input the user ID of the user you are assigning the key to"}],children:(0,s.jsxs)("div",{children:[(0,s.jsxs)("div",{style:{display:"flex",marginBottom:"8px"},children:[(0,s.jsx)(f.default,{showSearch:!0,placeholder:"Type email to search for users",filterOption:!1,onSearch:e=>{e8(e)},onSelect:(e,t)=>te(e,t),options:eR,loading:eD,allowClear:!0,style:{width:"100%"},notFoundContent:eD?"Searching...":"No users found"}),(0,s.jsx)(N.ZP,{onClick:()=>eP(!0),style:{marginLeft:"8px"},children:"Create User"})]}),(0,s.jsx)("div",{className:"text-xs text-gray-500",children:"Search by email to find users"})]})}),(0,s.jsx)(j.Z.Item,{label:(0,s.jsxs)("span",{children:["Team"," ",(0,s.jsx)(v.Z,{title:"The team this key belongs to, which determines available models and budget limits",children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"team_id",initialValue:t?t.team_id:null,className:"mt-4",rules:[{required:"service_account"===ef,message:"Please select a team for the service account"}],help:"service_account"===ef?"required":"",children:(0,s.jsx)(K.Z,{teams:l,onChange:e=>{eL((null==l?void 0:l.find(t=>t.team_id===e))||null)}})})]}),e7&&(0,s.jsx)("div",{className:"mb-8 p-4 bg-blue-50 border border-blue-200 rounded-md",children:(0,s.jsx)(x.Z,{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."})}),!e7&&(0,s.jsxs)("div",{className:"mb-8",children:[(0,s.jsx)(y.Z,{className:"mb-4",children:"Key Details"}),(0,s.jsx)(j.Z.Item,{label:(0,s.jsxs)("span",{children:["you"===ef||"another_user"===ef?"Key Name":"Service Account ID"," ",(0,s.jsx)(v.Z,{title:"you"===ef||"another_user"===ef?"A descriptive name to identify this key":"Unique identifier for this service account",children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"key_alias",rules:[{required:!0,message:"Please input a ".concat("you"===ef?"key name":"service account ID")}],help:"required",children:(0,s.jsx)(p.Z,{placeholder:""})}),(0,s.jsx)(j.Z.Item,{label:(0,s.jsxs)("span",{children:["Models"," ",(0,s.jsx)(v.Z,{title:"Select which models this key can access. Choose 'All Team Models' to grant access to all models available to the team",children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"models",rules:"management"===ez||"read_only"===ez?[]:[{required:!0,message:"Please select a model"}],help:"management"===ez||"read_only"===ez?"Models field is disabled for this key type":"required",className:"mt-4",children:(0,s.jsxs)(f.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},disabled:"management"===ez||"read_only"===ez,onChange:e=>{e.includes("all-team-models")&&en.setFieldsValue({models:["all-team-models"]})},children:[(0,s.jsx)($,{value:"all-team-models",children:"All Team Models"},"all-team-models"),ep.map(e=>(0,s.jsx)($,{value:e,children:(0,q.W0)(e)},e))]})}),(0,s.jsx)(j.Z.Item,{label:(0,s.jsxs)("span",{children:["Key Type"," ",(0,s.jsx)(v.Z,{title:"Select the type of key to determine what routes and operations this key can access",children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"key_type",initialValue:"llm_api",className:"mt-4",children:(0,s.jsxs)(f.default,{defaultValue:"llm_api",placeholder:"Select key type",style:{width:"100%"},optionLabelProp:"label",onChange:e=>{eJ(e),("management"===e||"read_only"===e)&&en.setFieldsValue({models:[]})},children:[(0,s.jsx)($,{value:"default",label:"Default",children:(0,s.jsxs)("div",{style:{padding:"4px 0"},children:[(0,s.jsx)("div",{style:{fontWeight:500},children:"Default"}),(0,s.jsx)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:"Can call LLM API + Management routes"})]})}),(0,s.jsx)($,{value:"llm_api",label:"LLM API",children:(0,s.jsxs)("div",{style:{padding:"4px 0"},children:[(0,s.jsx)("div",{style:{fontWeight:500},children:"LLM API"}),(0,s.jsx)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:"Can call only LLM API routes (chat/completions, embeddings, etc.)"})]})}),(0,s.jsx)($,{value:"management",label:"Management",children:(0,s.jsxs)("div",{style:{padding:"4px 0"},children:[(0,s.jsx)("div",{style:{fontWeight:500},children:"Management"}),(0,s.jsx)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:"Can call only management routes (user/team/key management)"})]})})]})})]}),!e7&&(0,s.jsx)("div",{className:"mb-8",children:(0,s.jsxs)(d.Z,{className:"mt-4 mb-4",children:[(0,s.jsx)(m.Z,{children:(0,s.jsx)(y.Z,{className:"m-0",children:"Optional Settings"})}),(0,s.jsxs)(c.Z,{children:[(0,s.jsx)(j.Z.Item,{className:"mt-4",label:(0,s.jsxs)("span",{children:["Max Budget (USD)"," ",(0,s.jsx)(v.Z,{title:"Maximum amount in USD this key can spend. When reached, the key will be blocked from making further requests",children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"max_budget",help:"Budget cannot exceed team max budget: $".concat((null==t?void 0:t.max_budget)!==null&&(null==t?void 0:t.max_budget)!==void 0?null==t?void 0:t.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.max_budget&&l>t.max_budget)throw Error("Budget cannot exceed team max budget: $".concat((0,i.pw)(t.max_budget,4)))}}],children:(0,s.jsx)(W.Z,{step:.01,precision:2,width:200})}),(0,s.jsx)(j.Z.Item,{className:"mt-4",label:(0,s.jsxs)("span",{children:["Reset Budget"," ",(0,s.jsx)(v.Z,{title:"How often the budget should reset. For example, setting 'daily' will reset the budget every 24 hours",children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"budget_duration",help:"Team Reset Budget: ".concat((null==t?void 0:t.budget_duration)!==null&&(null==t?void 0:t.budget_duration)!==void 0?null==t?void 0:t.budget_duration:"None"),children:(0,s.jsx)(P.Z,{onChange:e=>en.setFieldValue("budget_duration",e)})}),(0,s.jsx)(j.Z.Item,{className:"mt-4",label:(0,s.jsxs)("span",{children:["Tokens per minute Limit (TPM)"," ",(0,s.jsx)(v.Z,{title:"Maximum number of tokens this key can process per minute. Helps control usage and costs",children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"tpm_limit",help:"TPM cannot exceed team TPM limit: ".concat((null==t?void 0:t.tpm_limit)!==null&&(null==t?void 0:t.tpm_limit)!==void 0?null==t?void 0:t.tpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.tpm_limit&&l>t.tpm_limit)throw Error("TPM limit cannot exceed team TPM limit: ".concat(t.tpm_limit))}}],children:(0,s.jsx)(W.Z,{step:1,width:400})}),(0,s.jsx)(O.Z,{type:"tpm",name:"tpm_limit_type",className:"mt-4",initialValue:null,form:en,showDetailedDescriptions:!0}),(0,s.jsx)(j.Z.Item,{className:"mt-4",label:(0,s.jsxs)("span",{children:["Requests per minute Limit (RPM)"," ",(0,s.jsx)(v.Z,{title:"Maximum number of API requests this key can make per minute. Helps prevent abuse and manage load",children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"rpm_limit",help:"RPM cannot exceed team RPM limit: ".concat((null==t?void 0:t.rpm_limit)!==null&&(null==t?void 0:t.rpm_limit)!==void 0?null==t?void 0:t.rpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.rpm_limit&&l>t.rpm_limit)throw Error("RPM limit cannot exceed team RPM limit: ".concat(t.rpm_limit))}}],children:(0,s.jsx)(W.Z,{step:1,width:400})}),(0,s.jsx)(O.Z,{type:"rpm",name:"rpm_limit_type",className:"mt-4",initialValue:null,form:en,showDetailedDescriptions:!0}),(0,s.jsx)(j.Z.Item,{label:(0,s.jsxs)("span",{children:["Guardrails"," ",(0,s.jsx)(v.Z,{title:"Apply safety guardrails to this key to filter content or enforce policies",children:(0,s.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/quick_start",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})})]}),name:"guardrails",className:"mt-4",help:er?"Select existing guardrails or enter new ones":"Premium feature - Upgrade to set guardrails by key",children:(0,s.jsx)(f.default,{mode:"tags",style:{width:"100%"},disabled:!er,placeholder:er?"Select or enter guardrails":"Premium feature - Upgrade to set guardrails by key",options:e_.map(e=>({value:e,label:e}))})}),(0,s.jsx)(j.Z.Item,{label:(0,s.jsxs)("span",{children:["Disable Global Guardrails"," ",(0,s.jsx)(v.Z,{title:"When enabled, this key will bypass any guardrails configured to run on every request (global guardrails)",children:(0,s.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/quick_start",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})})]}),name:"disable_global_guardrails",className:"mt-4",valuePropName:"checked",help:er?"Bypass global guardrails for this key":"Premium feature - Upgrade to disable global guardrails by key",children:(0,s.jsx)(w.Z,{disabled:!er,checkedChildren:"Yes",unCheckedChildren:"No"})}),(0,s.jsx)(j.Z.Item,{label:(0,s.jsxs)("span",{children:["Policies"," ",(0,s.jsx)(v.Z,{title:"Apply policies to this key to control guardrails and other settings",children:(0,s.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/guardrail_policies",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})})]}),name:"policies",className:"mt-4",help:er?"Select existing policies or enter new ones":"Premium feature - Upgrade to set policies by key",children:(0,s.jsx)(f.default,{mode:"tags",style:{width:"100%"},disabled:!er,placeholder:er?"Select or enter policies":"Premium feature - Upgrade to set policies by key",options:ew.map(e=>({value:e,label:e}))})}),(0,s.jsx)(j.Z.Item,{label:(0,s.jsxs)("span",{children:["Prompts"," ",(0,s.jsx)(v.Z,{title:"Allow this key to use specific prompt templates",children:(0,s.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/prompt_management",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})})]}),name:"prompts",className:"mt-4",help:er?"Select existing prompts or enter new ones":"Premium feature - Upgrade to set prompts by key",children:(0,s.jsx)(f.default,{mode:"tags",style:{width:"100%"},disabled:!er,placeholder:er?"Select or enter prompts":"Premium feature - Upgrade to set prompts by key",options:eS.map(e=>({value:e,label:e}))})}),(0,s.jsx)(j.Z.Item,{label:(0,s.jsxs)("span",{children:["Allowed Pass Through Routes"," ",(0,s.jsx)(v.Z,{title:"Allow this key to use specific pass through routes",children:(0,s.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/pass_through",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})})]}),name:"allowed_passthrough_routes",className:"mt-4",help:er?"Select existing pass through routes or enter new ones":"Premium feature - Upgrade to set pass through routes by key",children:(0,s.jsx)(V.Z,{onChange:e=>en.setFieldValue("allowed_passthrough_routes",e),value:en.getFieldValue("allowed_passthrough_routes"),accessToken:el,placeholder:er?"Select or enter pass through routes":"Premium feature - Upgrade to set pass through routes by key",disabled:!er,teamId:eT?eT.team_id:null})}),(0,s.jsx)(j.Z.Item,{label:(0,s.jsxs)("span",{children:["Allowed Vector Stores"," ",(0,s.jsx)(v.Z,{title:"Select which vector stores this key can access. If none selected, the key will have access to all available vector stores",children:(0,s.jsx)(n.Z,{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,s.jsx)(H.Z,{onChange:e=>en.setFieldValue("allowed_vector_store_ids",e),value:en.getFieldValue("allowed_vector_store_ids"),accessToken:el,placeholder:"Select vector stores (optional)"})}),(0,s.jsx)(j.Z.Item,{label:(0,s.jsxs)("span",{children:["Metadata"," ",(0,s.jsx)(v.Z,{title:"JSON object with additional information about this key. Used for tracking or custom logic",children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"metadata",className:"mt-4",children:(0,s.jsx)(k.default.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,s.jsx)(j.Z.Item,{label:(0,s.jsxs)("span",{children:["Tags"," ",(0,s.jsx)(v.Z,{title:"Tags for tracking spend and/or doing tag-based routing. Used for analytics and filtering",children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"tags",className:"mt-4",help:"Tags for tracking spend and/or doing tag-based routing.",children:(0,s.jsx)(f.default,{mode:"tags",style:{width:"100%"},placeholder:"Enter tags",tokenSeparators:[","],options:eb})}),(0,s.jsxs)(d.Z,{className:"mt-4 mb-4",children:[(0,s.jsx)(m.Z,{children:(0,s.jsx)("b",{children:"MCP Settings"})}),(0,s.jsxs)(c.Z,{children:[(0,s.jsx)(j.Z.Item,{label:(0,s.jsxs)("span",{children:["Allowed MCP Servers"," ",(0,s.jsx)(v.Z,{title:"Select which MCP servers or access groups this key can access",children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"allowed_mcp_servers_and_groups",help:"Select MCP servers or access groups this key can access",children:(0,s.jsx)(B.Z,{onChange:e=>en.setFieldValue("allowed_mcp_servers_and_groups",e),value:en.getFieldValue("allowed_mcp_servers_and_groups"),accessToken:el,placeholder:"Select MCP servers or access groups (optional)"})}),(0,s.jsx)(j.Z.Item,{name:"mcp_tool_permissions",initialValue:{},hidden:!0,children:(0,s.jsx)(k.default,{type:"hidden"})}),(0,s.jsx)(j.Z.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:()=>{var e;return(0,s.jsx)("div",{className:"mt-6",children:(0,s.jsx)(G.Z,{accessToken:el,selectedServers:(null===(e=en.getFieldValue("allowed_mcp_servers_and_groups"))||void 0===e?void 0:e.servers)||[],toolPermissions:en.getFieldValue("mcp_tool_permissions")||{},onChange:e=>en.setFieldsValue({mcp_tool_permissions:e})})})}})]})]}),(0,s.jsxs)(d.Z,{className:"mt-4 mb-4",children:[(0,s.jsx)(m.Z,{children:(0,s.jsx)("b",{children:"Agent Settings"})}),(0,s.jsx)(c.Z,{children:(0,s.jsx)(j.Z.Item,{label:(0,s.jsxs)("span",{children:["Allowed Agents"," ",(0,s.jsx)(v.Z,{title:"Select which agents or access groups this key can access",children:(0,s.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"allowed_agents_and_groups",help:"Select agents or access groups this key can access",children:(0,s.jsx)(L.Z,{onChange:e=>en.setFieldValue("allowed_agents_and_groups",e),value:en.getFieldValue("allowed_agents_and_groups"),accessToken:el,placeholder:"Select agents or access groups (optional)"})})})]}),er?(0,s.jsxs)(d.Z,{className:"mt-4 mb-4",children:[(0,s.jsx)(m.Z,{children:(0,s.jsx)("b",{children:"Logging Settings"})}),(0,s.jsx)(c.Z,{children:(0,s.jsx)("div",{className:"mt-4",children:(0,s.jsx)(R.Z,{value:eC,onChange:eM,premiumUser:!0,disabledCallbacks:eB,onDisabledCallbacksChange:eG})})})]}):(0,s.jsx)(v.Z,{title:(0,s.jsxs)("span",{children:["Key-level logging settings is an enterprise feature, get in touch -",(0,s.jsx)("a",{href:"https://www.litellm.ai/enterprise",target:"_blank",children:"https://www.litellm.ai/enterprise"})]}),placement:"top",children:(0,s.jsxs)("div",{style:{position:"relative"},children:[(0,s.jsx)("div",{style:{opacity:.5},children:(0,s.jsxs)(d.Z,{className:"mt-4 mb-4",children:[(0,s.jsx)(m.Z,{children:(0,s.jsx)("b",{children:"Logging Settings"})}),(0,s.jsx)(c.Z,{children:(0,s.jsx)("div",{className:"mt-4",children:(0,s.jsx)(R.Z,{value:eC,onChange:eM,premiumUser:!1,disabledCallbacks:eB,onDisabledCallbacksChange:eG})})})]})}),(0,s.jsx)("div",{style:{position:"absolute",inset:0,cursor:"not-allowed"}})]})}),(0,s.jsxs)(d.Z,{className:"mt-4 mb-4",children:[(0,s.jsx)(m.Z,{children:(0,s.jsx)("b",{children:"Router Settings"})}),(0,s.jsx)(c.Z,{children:(0,s.jsx)("div",{className:"mt-4 w-full",children:(0,s.jsx)(D.Z,{accessToken:el||"",value:e0||void 0,onChange:e4,modelData:eg.length>0?{data:eg.map(e=>({model_name:e}))}:void 0},e1)})})]},"router-settings-accordion-".concat(e1)),(0,s.jsxs)(d.Z,{className:"mt-4 mb-4",children:[(0,s.jsx)(m.Z,{children:(0,s.jsx)("b",{children:"Model Aliases"})}),(0,s.jsx)(c.Z,{children:(0,s.jsxs)("div",{className:"mt-4",children:[(0,s.jsx)(x.Z,{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,s.jsx)(I.Z,{accessToken:el,initialModelAliases:eW,onAliasUpdate:eH,showExampleConfig:!1})]})})]}),(0,s.jsxs)(d.Z,{className:"mt-4 mb-4",children:[(0,s.jsx)(m.Z,{children:(0,s.jsx)("b",{children:"Key Lifecycle"})}),(0,s.jsx)(c.Z,{children:(0,s.jsx)("div",{className:"mt-4",children:(0,s.jsx)(E.Z,{form:en,autoRotationEnabled:eY,onAutoRotationChange:e$,rotationInterval:eQ,onRotationIntervalChange:eX,isCreateMode:!0})})}),(0,s.jsx)(j.Z.Item,{name:"duration",hidden:!0,initialValue:null,children:(0,s.jsx)(k.default,{})})]}),(0,s.jsxs)(d.Z,{className:"mt-4 mb-4",children:[(0,s.jsx)(m.Z,{children:(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("b",{children:"Advanced Settings"}),(0,s.jsx)(v.Z,{title:(0,s.jsxs)("span",{children:["Learn more about advanced settings in our"," ",(0,s.jsx)("a",{href:J.proxyBaseUrl?"".concat(J.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,s.jsx)(n.Z,{className:"text-gray-400 hover:text-gray-300 cursor-help"})})]})}),(0,s.jsx)(c.Z,{children:(0,s.jsx)(A.Z,{schemaComponent:"GenerateKeyRequest",form:en,excludedFields:["key_alias","team_id","models","duration","metadata","tags","guardrails","max_budget","budget_duration","tpm_limit","rpm_limit"]})})]})]})]})}),(0,s.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,s.jsx)(N.ZP,{htmlType:"submit",disabled:e7,style:{opacity:e7?.5:1},children:"Create Key"})})]})}),eF&&(0,s.jsx)(b.Z,{title:"Create New User",visible:eF,onCancel:()=>eP(!1),footer:null,width:800,children:(0,s.jsx)(U.Z,{userID:es,accessToken:el,teams:l,possibleUIRoles:eI,onUserCreated:e=>{eE(e),en.setFieldsValue({user_id:e}),eP(!1)},isEmbedded:!0})}),ec&&(0,s.jsx)(b.Z,{visible:eo,onOk:e5,onCancel:e3,footer:null,children:(0,s.jsxs)(g.Z,{numItems:1,className:"gap-2 w-full",children:[(0,s.jsx)(y.Z,{children:"Save your Key"}),(0,s.jsx)(h.Z,{numColSpan:1,children:(0,s.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons,"," ",(0,s.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,s.jsx)(h.Z,{numColSpan:1,children:null!=ec?(0,s.jsxs)("div",{children:[(0,s.jsx)(x.Z,{className:"mt-3",children:"Virtual Key:"}),(0,s.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,s.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal"},children:ec})}),(0,s.jsx)(M.CopyToClipboard,{text:ec,onCopy:()=>{z.Z.success("Virtual Key copied to clipboard")},children:(0,s.jsx)(u.Z,{className:"mt-3",children:"Copy Virtual Key"})})]}):(0,s.jsx)(x.Z,{children:"Key being created, this might take 30s"})})]})})]})}},56334:function(e,t,l){l.d(t,{Z:function(){return u}});var s=l(57437);l(2265);var a=l(31283);let r={ttl:3600,lowest_latency_buffer:0};var i=e=>{let{routingStrategyArgs:t}=e,l={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,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)("div",{className:"space-y-6",children:[(0,s.jsxs)("div",{className:"max-w-3xl",children:[(0,s.jsx)("h3",{className:"text-sm font-medium text-gray-900",children:"Latency-Based Configuration"}),(0,s.jsx)("p",{className:"text-xs text-gray-500 mt-1",children:"Fine-tune latency-based routing behavior"})]}),(0,s.jsx)("div",{className:"grid grid-cols-1 gap-6 lg:grid-cols-2 xl:grid-cols-3",children:Object.entries(t||r).map(e=>{let[t,r]=e;return(0,s.jsx)("div",{className:"space-y-2",children:(0,s.jsxs)("label",{className:"block",children:[(0,s.jsx)("span",{className:"text-xs font-medium text-gray-700 uppercase tracking-wide",children:t.replace(/_/g," ")}),(0,s.jsx)("p",{className:"text-xs text-gray-500 mt-0.5 mb-2",children:l[t]||""}),(0,s.jsx)(a.o,{name:t,defaultValue:"object"==typeof r?JSON.stringify(r,null,2):null==r?void 0:r.toString(),className:"font-mono text-sm w-full"})]})},t)})})]}),(0,s.jsx)("div",{className:"border-t border-gray-200"})]})},n=e=>{let{routerSettings:t,routerFieldsMetadata:l}=e;return(0,s.jsxs)("div",{className:"space-y-6",children:[(0,s.jsxs)("div",{className:"max-w-3xl",children:[(0,s.jsx)("h3",{className:"text-sm font-medium text-gray-900",children:"Reliability & Retries"}),(0,s.jsx)("p",{className:"text-xs text-gray-500 mt-1",children:"Configure retry logic and failure handling"})]}),(0,s.jsx)("div",{className:"grid grid-cols-1 gap-6 lg:grid-cols-2 xl:grid-cols-3",children:Object.entries(t).filter(e=>{let[t,l]=e;return"fallbacks"!=t&&"context_window_fallbacks"!=t&&"routing_strategy_args"!=t&&"routing_strategy"!=t&&"enable_tag_filtering"!=t}).map(e=>{var t,r;let[i,n]=e;return(0,s.jsx)("div",{className:"space-y-2",children:(0,s.jsxs)("label",{className:"block",children:[(0,s.jsx)("span",{className:"text-xs font-medium text-gray-700 uppercase tracking-wide",children:(null===(t=l[i])||void 0===t?void 0:t.ui_field_name)||i}),(0,s.jsx)("p",{className:"text-xs text-gray-500 mt-0.5 mb-2",children:(null===(r=l[i])||void 0===r?void 0:r.field_description)||""}),(0,s.jsx)(a.o,{name:i,defaultValue:null==n||"null"===n?"":"object"==typeof n?JSON.stringify(n,null,2):(null==n?void 0:n.toString())||"",placeholder:"—",className:"font-mono text-sm w-full"})]})},i)})})]})},o=l(37592),d=e=>{var t,l;let{selectedStrategy:a,availableStrategies:r,routingStrategyDescriptions:i,routerFieldsMetadata:n,onStrategyChange:d}=e;return(0,s.jsxs)("div",{className:"space-y-2 max-w-3xl",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-xs font-medium text-gray-700 uppercase tracking-wide",children:(null===(t=n.routing_strategy)||void 0===t?void 0:t.ui_field_name)||"Routing Strategy"}),(0,s.jsx)("p",{className:"text-xs text-gray-500 mt-0.5 mb-2",children:(null===(l=n.routing_strategy)||void 0===l?void 0:l.field_description)||""})]}),(0,s.jsx)("div",{className:"routing-strategy-select max-w-3xl",children:(0,s.jsx)(o.default,{value:a,onChange:d,style:{width:"100%"},size:"large",children:r.map(e=>(0,s.jsx)(o.default.Option,{value:e,label:e,children:(0,s.jsxs)("div",{className:"flex flex-col gap-0.5 py-1",children:[(0,s.jsx)("span",{className:"font-mono text-sm font-medium",children:e}),i[e]&&(0,s.jsx)("span",{className:"text-xs text-gray-500 font-normal",children:i[e]})]})},e))})})]})},c=l(59341),m=e=>{var t,l,a;let{enabled:r,routerFieldsMetadata:i,onToggle:n}=e;return(0,s.jsx)("div",{className:"space-y-3 max-w-3xl",children:(0,s.jsxs)("div",{className:"flex items-start justify-between",children:[(0,s.jsxs)("div",{className:"flex-1",children:[(0,s.jsx)("label",{className:"text-xs font-medium text-gray-700 uppercase tracking-wide",children:(null===(t=i.enable_tag_filtering)||void 0===t?void 0:t.ui_field_name)||"Enable Tag Filtering"}),(0,s.jsxs)("p",{className:"text-xs text-gray-500 mt-0.5",children:[(null===(l=i.enable_tag_filtering)||void 0===l?void 0:l.field_description)||"",(null===(a=i.enable_tag_filtering)||void 0===a?void 0:a.link)&&(0,s.jsxs)(s.Fragment,{children:[" ",(0,s.jsx)("a",{href:i.enable_tag_filtering.link,target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 hover:text-blue-800 underline",children:"Learn more"})]})]})]}),(0,s.jsx)(c.Z,{checked:r,onChange:n,className:"ml-4"})]})})},u=e=>{let{value:t,onChange:l,routerFieldsMetadata:a,availableRoutingStrategies:r,routingStrategyDescriptions:o}=e;return(0,s.jsxs)("div",{className:"w-full space-y-8 py-2",children:[(0,s.jsxs)("div",{className:"space-y-6",children:[(0,s.jsxs)("div",{className:"max-w-3xl",children:[(0,s.jsx)("h3",{className:"text-sm font-medium text-gray-900",children:"Routing Settings"}),(0,s.jsx)("p",{className:"text-xs text-gray-500 mt-1",children:"Configure how requests are routed to deployments"})]}),r.length>0&&(0,s.jsx)(d,{selectedStrategy:t.selectedStrategy||t.routerSettings.routing_strategy||null,availableStrategies:r,routingStrategyDescriptions:o,routerFieldsMetadata:a,onStrategyChange:e=>{l({...t,selectedStrategy:e})}}),(0,s.jsx)(m,{enabled:t.enableTagFiltering,routerFieldsMetadata:a,onToggle:e=>{l({...t,enableTagFiltering:e})}})]}),(0,s.jsx)("div",{className:"border-t border-gray-200"}),"latency-based-routing"===t.selectedStrategy&&(0,s.jsx)(i,{routingStrategyArgs:t.routerSettings.routing_strategy_args}),(0,s.jsx)(n,{routerSettings:t.routerSettings,routerFieldsMetadata:a})]})}}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/1098-c3e95c9684ff5e95.js b/litellm/proxy/_experimental/out/_next/static/chunks/1098-c3e95c9684ff5e95.js new file mode 100644 index 00000000000..6f31d1f0843 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/1098-c3e95c9684ff5e95.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1098],{30280:function(e,s,t){t.d(s,{EX:function(){return c},Km:function(){return o},Tv:function(){return u}});var a=t(11713),l=t(45345),r=t(90246),i=t(19250),n=t(80443);let o=(0,r.n)("keys"),d=async function(e,s,t){let a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};try{let l=(0,i.getProxyBaseUrl)(),r=new URLSearchParams(Object.entries({team_id:a.teamID,organization_id:a.organizationID,key_alias:a.selectedKeyAlias,key_hash:a.keyHash,user_id:a.userID,page:s,size:t,sort_by:a.sortBy,sort_order:a.sortOrder,expand:a.expand,status:a.status,return_full_object:"true",include_team_keys:"true",include_created_by_keys:"true"}).filter(e=>{let[,s]=e;return null!=s}).map(e=>{let[s,t]=e;return[s,String(t)]})),n="".concat(l?"".concat(l,"/key/list"):"/key/list","?").concat(r),o=await fetch(n,{method:"GET",headers:{[(0,i.getGlobalLitellmHeaderName)()]:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!o.ok){let e=await o.json(),s=(0,i.deriveErrorMessage)(e);throw(0,i.handleError)(s),Error(s)}let d=await o.json();return console.log("/key/list API Response:",d),d}catch(e){throw console.error("Failed to list keys:",e),e}},c=(e,s)=>{let{accessToken:t}=(0,n.Z)();return(0,a.a)({queryKey:o.list({page:e,limit:s}),queryFn:async()=>await d(t,e,s),enabled:!!t,staleTime:3e4,placeholderData:l.Wk})},m=(0,r.n)("deletedKeys"),u=function(e,s){let t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},{accessToken:r}=(0,n.Z)();return(0,a.a)({queryKey:m.list({page:e,limit:s,...t}),queryFn:async()=>await d(r,e,s,{...t,status:"deleted"}),enabled:!!r,staleTime:3e4,placeholderData:l.Wk})}},62099:function(e,s,t){var a=t(57437),l=t(2265),r=t(37592),i=t(99981),n=t(23496),o=t(63709),d=t(15424),c=t(31283);let{Option:m}=r.default;s.Z=e=>{var s;let{form:t,autoRotationEnabled:u,onAutoRotationChange:h,rotationInterval:p,onRotationIntervalChange:x}=e,g=p&&!["7d","30d","90d","180d","365d"].includes(p),[y,j]=(0,l.useState)(g),[f,b]=(0,l.useState)(g?p:""),[v,_]=(0,l.useState)((null==t?void 0:null===(s=t.getFieldValue)||void 0===s?void 0:s.call(t,"duration"))||"");return(0,a.jsxs)("div",{className:"space-y-6",children:[(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Key Expiry Settings"}),(0,a.jsxs)("div",{className:"space-y-2",children:[(0,a.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,a.jsx)("span",{children:"Expire Key"}),(0,a.jsx)(i.Z,{title:"Set when this key should expire. Format: 30s (seconds), 30m (minutes), 30h (hours), 30d (days). Use -1 to never expire.",children:(0,a.jsx)(d.Z,{className:"text-gray-400 cursor-help text-xs"})})]}),(0,a.jsx)(c.o,{name:"duration",placeholder:"e.g., 30d or -1 to never expire",className:"w-full",value:v,onValueChange:e=>{_(e),t&&"function"==typeof t.setFieldValue?t.setFieldValue("duration",e):t&&"function"==typeof t.setFieldsValue&&t.setFieldsValue({duration:e})}})]})]}),(0,a.jsx)(n.Z,{}),(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Auto-Rotation Settings"}),(0,a.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,a.jsxs)("div",{className:"space-y-2",children:[(0,a.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,a.jsx)("span",{children:"Enable Auto-Rotation"}),(0,a.jsx)(i.Z,{title:"Key will automatically regenerate at the specified interval for enhanced security.",children:(0,a.jsx)(d.Z,{className:"text-gray-400 cursor-help text-xs"})})]}),(0,a.jsx)(o.Z,{checked:u,onChange:h,size:"default",className:u?"":"bg-gray-400"})]}),u&&(0,a.jsxs)("div",{className:"space-y-2",children:[(0,a.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,a.jsx)("span",{children:"Rotation Interval"}),(0,a.jsx)(i.Z,{title:"How often the key should be automatically rotated. Choose the interval that best fits your security requirements.",children:(0,a.jsx)(d.Z,{className:"text-gray-400 cursor-help text-xs"})})]}),(0,a.jsxs)("div",{className:"space-y-2",children:[(0,a.jsxs)(r.default,{value:y?"custom":p,onChange:e=>{"custom"===e?j(!0):(j(!1),b(""),x(e))},className:"w-full",placeholder:"Select interval",children:[(0,a.jsx)(m,{value:"7d",children:"7 days"}),(0,a.jsx)(m,{value:"30d",children:"30 days"}),(0,a.jsx)(m,{value:"90d",children:"90 days"}),(0,a.jsx)(m,{value:"180d",children:"180 days"}),(0,a.jsx)(m,{value:"365d",children:"365 days"}),(0,a.jsx)(m,{value:"custom",children:"Custom interval"})]}),y&&(0,a.jsxs)("div",{className:"space-y-1",children:[(0,a.jsx)(c.o,{value:f,onChange:e=>{let s=e.target.value;b(s),x(s)},placeholder:"e.g., 1s, 5m, 2h, 14d"}),(0,a.jsx)("div",{className:"text-xs text-gray-500",children:"Supported formats: seconds (s), minutes (m), hours (h), days (d)"})]})]})]})]}),u&&(0,a.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."})]})]})}},72885:function(e,s,t){var a=t(57437),l=t(2265),r=t(77355),i=t(93416),n=t(74998),o=t(95704),d=t(76593),c=t(9114);s.Z=e=>{let{accessToken:s,initialModelAliases:t={},onAliasUpdate:m,showExampleConfig:u=!0}=e,[h,p]=(0,l.useState)([]),[x,g]=(0,l.useState)({aliasName:"",targetModel:""}),[y,j]=(0,l.useState)(null);(0,l.useEffect)(()=>{p(Object.entries(t).map((e,s)=>{let[t,a]=e;return{id:"".concat(s,"-").concat(t),aliasName:t,targetModel:a}}))},[t]);let f=e=>{j({...e})},b=()=>{if(!y)return;if(!y.aliasName||!y.targetModel){c.Z.fromBackend("Please provide both alias name and target model");return}if(h.some(e=>e.id!==y.id&&e.aliasName===y.aliasName)){c.Z.fromBackend("An alias with this name already exists");return}let e=h.map(e=>e.id===y.id?y:e);p(e),j(null);let s={};e.forEach(e=>{s[e.aliasName]=e.targetModel}),m&&m(s),c.Z.success("Alias updated successfully")},v=()=>{j(null)},_=e=>{let s=h.filter(s=>s.id!==e);p(s);let t={};s.forEach(e=>{t[e.aliasName]=e.targetModel}),m&&m(t),c.Z.success("Alias deleted successfully")},w=h.reduce((e,s)=>(e[s.aliasName]=s.targetModel,e),{});return(0,a.jsxs)("div",{className:"mt-4",children:[(0,a.jsxs)("div",{className:"mb-6",children:[(0,a.jsx)(o.xv,{className:"text-sm font-medium text-gray-700 mb-2",children:"Add New Alias"}),(0,a.jsxs)("div",{className:"grid grid-cols-3 gap-4",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-xs text-gray-500 mb-1",children:"Alias Name"}),(0,a.jsx)("input",{type:"text",value:x.aliasName,onChange:e=>g({...x,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,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-xs text-gray-500 mb-1",children:"Target Model"}),(0,a.jsx)(d.Z,{accessToken:s,value:x.targetModel,placeholder:"Select target model",onChange:e=>g({...x,targetModel:e}),showLabel:!1})]}),(0,a.jsx)("div",{className:"flex items-end",children:(0,a.jsxs)("button",{onClick:()=>{if(!x.aliasName||!x.targetModel){c.Z.fromBackend("Please provide both alias name and target model");return}if(h.some(e=>e.aliasName===x.aliasName)){c.Z.fromBackend("An alias with this name already exists");return}let e=[...h,{id:"".concat(Date.now(),"-").concat(x.aliasName),aliasName:x.aliasName,targetModel:x.targetModel}];p(e),g({aliasName:"",targetModel:""});let s={};e.forEach(e=>{s[e.aliasName]=e.targetModel}),m&&m(s),c.Z.success("Alias added successfully")},disabled:!x.aliasName||!x.targetModel,className:"flex items-center px-4 py-2 rounded-md text-sm ".concat(x.aliasName&&x.targetModel?"bg-green-600 text-white hover:bg-green-700":"bg-gray-300 text-gray-500 cursor-not-allowed"),children:[(0,a.jsx)(r.Z,{className:"w-4 h-4 mr-1"}),"Add Alias"]})})]})]}),(0,a.jsx)(o.xv,{className:"text-sm font-medium text-gray-700 mb-2",children:"Manage Existing Aliases"}),(0,a.jsx)("div",{className:"rounded-lg custom-border relative mb-6",children:(0,a.jsx)("div",{className:"overflow-x-auto",children:(0,a.jsxs)(o.iA,{className:"[&_td]:py-0.5 [&_th]:py-1",children:[(0,a.jsx)(o.ss,{children:(0,a.jsxs)(o.SC,{children:[(0,a.jsx)(o.xs,{className:"py-1 h-8",children:"Alias Name"}),(0,a.jsx)(o.xs,{className:"py-1 h-8",children:"Target Model"}),(0,a.jsx)(o.xs,{className:"py-1 h-8",children:"Actions"})]})}),(0,a.jsxs)(o.RM,{children:[h.map(e=>(0,a.jsx)(o.SC,{className:"h-8",children:y&&y.id===e.id?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(o.pj,{className:"py-0.5",children:(0,a.jsx)("input",{type:"text",value:y.aliasName,onChange:e=>j({...y,aliasName:e.target.value}),className:"w-full px-2 py-1 border border-gray-300 rounded-md text-sm"})}),(0,a.jsx)(o.pj,{className:"py-0.5",children:(0,a.jsx)(d.Z,{accessToken:s,value:y.targetModel,onChange:e=>j({...y,targetModel:e}),showLabel:!1,style:{height:"32px"}})}),(0,a.jsx)(o.pj,{className:"py-0.5 whitespace-nowrap",children:(0,a.jsxs)("div",{className:"flex space-x-2",children:[(0,a.jsx)("button",{onClick:b,className:"text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded hover:bg-blue-100",children:"Save"}),(0,a.jsx)("button",{onClick:v,className:"text-xs bg-gray-50 text-gray-600 px-2 py-1 rounded hover:bg-gray-100",children:"Cancel"})]})})]}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(o.pj,{className:"py-0.5 text-sm text-gray-900",children:e.aliasName}),(0,a.jsx)(o.pj,{className:"py-0.5 text-sm text-gray-500",children:e.targetModel}),(0,a.jsx)(o.pj,{className:"py-0.5 whitespace-nowrap",children:(0,a.jsxs)("div",{className:"flex space-x-2",children:[(0,a.jsx)("button",{onClick:()=>f(e),className:"text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded hover:bg-blue-100",children:(0,a.jsx)(i.Z,{className:"w-3 h-3"})}),(0,a.jsx)("button",{onClick:()=>_(e.id),className:"text-xs bg-red-50 text-red-600 px-2 py-1 rounded hover:bg-red-100",children:(0,a.jsx)(n.Z,{className:"w-3 h-3"})})]})})]})},e.id)),0===h.length&&(0,a.jsx)(o.SC,{children:(0,a.jsx)(o.pj,{colSpan:3,className:"py-0.5 text-sm text-gray-500 text-center",children:"No aliases added yet. Add a new alias above."})})]})]})})}),u&&(0,a.jsxs)(o.Zb,{children:[(0,a.jsx)(o.Dx,{className:"mb-4",children:"Configuration Example"}),(0,a.jsx)(o.xv,{className:"text-gray-600 mb-4",children:"Here's how your current aliases would look in the config:"}),(0,a.jsx)("div",{className:"bg-gray-100 rounded-lg p-4 font-mono text-sm",children:(0,a.jsxs)("div",{className:"text-gray-700",children:["model_aliases:",0===Object.keys(w).length?(0,a.jsxs)("span",{className:"text-gray-500",children:[(0,a.jsx)("br",{}),"\xa0\xa0# No aliases configured yet"]}):Object.entries(w).map(e=>{let[s,t]=e;return(0,a.jsxs)("span",{children:[(0,a.jsx)("br",{}),'\xa0\xa0"',s,'": "',t,'"']},s)})]})})]})]})}},76593:function(e,s,t){var a=t(57437),l=t(2265),r=t(56522),i=t(37592),n=t(69993),o=t(10703);s.Z=e=>{let{accessToken:s,value:t,placeholder:d="Select a Model",onChange:c,disabled:m=!1,style:u,className:h,showLabel:p=!0,labelText:x="Select Model"}=e,[g,y]=(0,l.useState)(t),[j,f]=(0,l.useState)(!1),[b,v]=(0,l.useState)([]),_=(0,l.useRef)(null);return(0,l.useEffect)(()=>{y(t)},[t]),(0,l.useEffect)(()=>{s&&(async()=>{try{let e=await (0,o.p)(s);console.log("Fetched models for selector:",e),e.length>0&&v(e)}catch(e){console.error("Error fetching model info:",e)}})()},[s]),(0,a.jsxs)("div",{children:[p&&(0,a.jsxs)(r.x,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,a.jsx)(n.Z,{className:"mr-2"})," ",x]}),(0,a.jsx)(i.default,{value:g,placeholder:d,onChange:e=>{"custom"===e?(f(!0),y(void 0)):(f(!1),y(e),c&&c(e))},options:[...Array.from(new Set(b.map(e=>e.model_group))).map((e,s)=>({value:e,label:e,key:s})),{value:"custom",label:"Enter custom model",key:"custom"}],style:{width:"100%",...u},showSearch:!0,className:"rounded-md ".concat(h||""),disabled:m}),j&&(0,a.jsx)(r.o,{className:"mt-2",placeholder:"Enter custom model name",onValueChange:e=>{_.current&&clearTimeout(_.current),_.current=setTimeout(()=>{y(e),c&&c(e)},500)},disabled:m})]})}},2597:function(e,s,t){var a=t(57437);t(2265);var l=t(92280),r=t(54507);s.Z=function(e){let{value:s,onChange:t,premiumUser:i=!1,disabledCallbacks:n=[],onDisabledCallbacksChange:o}=e;return i?(0,a.jsx)(r.Z,{value:s,onChange:t,disabledCallbacks:n,onDisabledCallbacksChange:o}):(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"flex flex-wrap gap-2 mb-3",children:[(0,a.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,a.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,a.jsx)("div",{className:"p-3 bg-yellow-50 border border-yellow-200 rounded-lg",children:(0,a.jsxs)(l.x,{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,a.jsx)("a",{href:"https://www.litellm.ai/#pricing",target:"_blank",rel:"noopener noreferrer",className:"underline",children:"here"}),"."]})})]})}},65895:function(e,s,t){var a=t(57437);t(2265);var l=t(37592),r=t(10032),i=t(99981),n=t(15424);let{Option:o}=l.default;s.Z=e=>{let{type:s,name:t,showDetailedDescriptions:d=!0,className:c="",initialValue:m=null,form:u,onChange:h}=e,p=s.toUpperCase(),x=s.toLowerCase(),g="Select 'guaranteed_throughput' to prevent overallocating ".concat(p," limit when the key belongs to a Team with specific ").concat(p," limits.");return(0,a.jsx)(r.Z.Item,{label:(0,a.jsxs)("span",{children:[p," Rate Limit Type"," ",(0,a.jsx)(i.Z,{title:g,children:(0,a.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:t,initialValue:m,className:c,children:(0,a.jsx)(l.default,{defaultValue:d?"default":void 0,placeholder:"Select rate limit type",style:{width:"100%"},optionLabelProp:d?"label":void 0,onChange:e=>{u&&u.setFieldValue(t,e),h&&h(e)},children:d?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(o,{value:"best_effort_throughput",label:"Default",children:(0,a.jsxs)("div",{style:{padding:"4px 0"},children:[(0,a.jsx)("div",{style:{fontWeight:500},children:"Default"}),(0,a.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["Best effort throughput - no error if we're overallocating ",x," (Team/Key Limits checked at runtime)."]})]})}),(0,a.jsx)(o,{value:"guaranteed_throughput",label:"Guaranteed throughput",children:(0,a.jsxs)("div",{style:{padding:"4px 0"},children:[(0,a.jsx)("div",{style:{fontWeight:500},children:"Guaranteed throughput"}),(0,a.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["Guaranteed throughput - raise an error if we're overallocating ",x," (also checks model-specific limits)"]})]})}),(0,a.jsx)(o,{value:"dynamic",label:"Dynamic",children:(0,a.jsxs)("div",{style:{padding:"4px 0"},children:[(0,a.jsx)("div",{style:{fontWeight:500},children:"Dynamic"}),(0,a.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,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(o,{value:"best_effort_throughput",children:"Best effort throughput"}),(0,a.jsx)(o,{value:"guaranteed_throughput",children:"Guaranteed throughput"}),(0,a.jsx)(o,{value:"dynamic",children:"Dynamic"})]})})})}},71098:function(e,s,t){t.d(s,{ZP:function(){return ee},wk:function(){return $},Nr:function(){return X}});var a=t(57437),l=t(30280),r=t(80443),i=t(59872),n=t(15424),o=t(29827),d=t(87452),c=t(88829),m=t(72208),u=t(78489),h=t(49804),p=t(67101),x=t(84264),g=t(49566),y=t(96761),j=t(37592),f=t(10032),b=t(22116),v=t(99981),_=t(29967),w=t(5545),Z=t(63709),N=t(4260),k=t(7310),S=t.n(k),C=t(2265),M=t(29233),P=t(20347),A=t(82586),L=t(97434),T=t(65925),I=t(63610),E=t(62099),F=t(72885),V=t(95096),U=t(2597),D=t(65895),K=t(84376),R=t(7765),O=t(46468),q=t(97492),B=t(68473),G=t(9114),W=t(19250),z=t(24199),J=t(97415);let H=e=>{let s;if(!(s=!e||"object"!=typeof e||e instanceof Error?String(e):JSON.stringify(e)).includes("/key/generate")&&!s.includes("KeyManagementRoutes.KEY_GENERATE"))return"Error creating the key: ".concat(e);let t=s;try{if(!e||"object"!=typeof e||e instanceof Error){let e=s.match(/\{[\s\S]*\}/);if(e){let s=JSON.parse(e[0]),a=(null==s?void 0:s.error)||s;(null==a?void 0:a.message)&&(t=a.message)}}else{let s=(null==e?void 0:e.error)||e;(null==s?void 0:s.message)&&(t=s.message)}}catch(e){}return s.includes("team_member_permission_error")||t.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: ".concat(e)},{Option:Y}=j.default,Q=e=>{let s=[];if(console.log("data:",JSON.stringify(e)),e)for(let t of e)t.metadata&&t.metadata.tags&&s.push(...t.metadata.tags);let t=Array.from(new Set(s)).map(e=>({value:e,label:e}));return console.log("uniqueTags:",t),t},$=async(e,s,t,a)=>{try{if(null===e||null===s)return[];if(null!==t){let l=(await (0,W.modelAvailableCall)(t,e,s,!0,a,!0)).data.map(e=>e.id);return console.log("available_model_names:",l),l}return[]}catch(e){return console.error("Error fetching user models:",e),[]}},X=async(e,s,t,a)=>{try{if(null===e||null===s)return;if(null!==t){let l=(await (0,W.modelAvailableCall)(t,e,s)).data.map(e=>e.id);console.log("available_model_names:",l),a(l)}}catch(e){console.error("Error fetching user models:",e)}};var ee=e=>{let{team:s,teams:t,data:k,addKey:ee}=e,{accessToken:es,userId:et,userRole:ea,premiumUser:el}=(0,r.Z)(),er=(0,o.NL)(),[ei]=f.Z.useForm(),[en,eo]=(0,C.useState)(!1),[ed,ec]=(0,C.useState)(null),[em,eu]=(0,C.useState)(null),[eh,ep]=(0,C.useState)([]),[ex,eg]=(0,C.useState)([]),[ey,ej]=(0,C.useState)("you"),[ef,eb]=(0,C.useState)(Q(k)),[ev,e_]=(0,C.useState)([]),[ew,eZ]=(0,C.useState)([]),[eN,ek]=(0,C.useState)([]),[eS,eC]=(0,C.useState)(s),[eM,eP]=(0,C.useState)(!1),[eA,eL]=(0,C.useState)(null),[eT,eI]=(0,C.useState)({}),[eE,eF]=(0,C.useState)([]),[eV,eU]=(0,C.useState)(!1),[eD,eK]=(0,C.useState)([]),[eR,eO]=(0,C.useState)([]),[eq,eB]=(0,C.useState)("default"),[eG,eW]=(0,C.useState)({}),[ez,eJ]=(0,C.useState)(!1),[eH,eY]=(0,C.useState)("30d"),eQ=()=>{eo(!1),ei.resetFields(),ek([]),eO([]),eB("default"),eW({}),eJ(!1),eY("30d")},e$=()=>{eo(!1),ec(null),eC(null),ei.resetFields(),ek([]),eO([]),eB("default"),eW({}),eJ(!1),eY("30d")};(0,C.useEffect)(()=>{et&&ea&&es&&X(et,ea,es,ep)},[es,et,ea]),(0,C.useEffect)(()=>{let e=async()=>{try{let e=await (0,W.getPromptsList)(es);eZ(e.prompts.map(e=>e.prompt_id))}catch(e){console.error("Failed to fetch prompts:",e)}};(async()=>{try{let e=(await (0,W.getGuardrailsList)(es)).guardrails.map(e=>e.guardrail_name);e_(e)}catch(e){console.error("Failed to fetch guardrails:",e)}})(),e()},[es]),(0,C.useEffect)(()=>{(async()=>{try{if(es){let e=sessionStorage.getItem("possibleUserRoles");if(e)eI(JSON.parse(e));else{let e=await (0,W.getPossibleUserRoles)(es);sessionStorage.setItem("possibleUserRoles",JSON.stringify(e)),eI(e)}}}catch(e){console.error("Error fetching possible user roles:",e)}})()},[es]);let eX=ex.includes("no-default-models")&&!eS,e0=async e=>{try{var s,t,a,r,i,n,o;let d;let c=null!==(i=null==e?void 0:e.key_alias)&&void 0!==i?i:"",m=null!==(n=null==e?void 0:e.team_id)&&void 0!==n?n:null;if((null!==(o=null==k?void 0:k.filter(e=>e.team_id===m).map(e=>e.key_alias))&&void 0!==o?o:[]).includes(c))throw Error("Key alias ".concat(c," already exists for team with ID ").concat(m,", please provide another key alias"));G.Z.info("Making API Call"),eo(!0),"you"===ey&&(e.user_id=et);let u={};try{u=JSON.parse(e.metadata||"{}")}catch(e){console.error("Error parsing metadata:",e)}if("service_account"===ey&&(u.service_account_id=e.key_alias),eN.length>0&&(u={...u,logging:eN.filter(e=>e.callback_name)}),eR.length>0){let e=(0,L.Z3)(eR);u={...u,litellm_disabled_callbacks:e}}if(ez&&(e.auto_rotate=!0,e.rotation_interval=eH),e.duration&&(e.duration=e.duration),e.metadata=JSON.stringify(u),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&&((null===(s=e.allowed_mcp_servers_and_groups.servers)||void 0===s?void 0:s.length)>0||(null===(t=e.allowed_mcp_servers_and_groups.accessGroups)||void 0===t?void 0:t.length)>0)){e.object_permission||(e.object_permission={});let{servers:s,accessGroups:t}=e.allowed_mcp_servers_and_groups;s&&s.length>0&&(e.object_permission.mcp_servers=s),t&&t.length>0&&(e.object_permission.mcp_access_groups=t),delete e.allowed_mcp_servers_and_groups}let h=e.mcp_tool_permissions||{};if(Object.keys(h).length>0&&(e.object_permission||(e.object_permission={}),e.object_permission.mcp_tool_permissions=h),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&&((null===(a=e.allowed_agents_and_groups.agents)||void 0===a?void 0:a.length)>0||(null===(r=e.allowed_agents_and_groups.accessGroups)||void 0===r?void 0:r.length)>0)){e.object_permission||(e.object_permission={});let{agents:s,accessGroups:t}=e.allowed_agents_and_groups;s&&s.length>0&&(e.object_permission.agents=s),t&&t.length>0&&(e.object_permission.agent_access_groups=t),delete e.allowed_agents_and_groups}Object.keys(eG).length>0&&(e.aliases=JSON.stringify(eG)),d="service_account"===ey?await (0,W.keyCreateServiceAccountCall)(es,e):await (0,W.keyCreateCall)(es,et,e),console.log("key create Response:",d),ee(d),er.invalidateQueries({queryKey:l.Km.lists()}),ec(d.key),eu(d.soft_budget),G.Z.success("Virtual Key Created"),ei.resetFields(),localStorage.removeItem("userData"+et)}catch(s){console.log("error in create key:",s);let e=H(s);G.Z.fromBackend(e)}};(0,C.useEffect)(()=>{if(et&&ea&&es){var e;$(et,ea,es,null!==(e=null==eS?void 0:eS.team_id)&&void 0!==e?e:null).then(e=>{var s;eg(Array.from(new Set([...null!==(s=null==eS?void 0:eS.models)&&void 0!==s?s:[],...e])))})}ei.setFieldValue("models",[])},[eS,es,et,ea]);let e4=async e=>{if(!e){eF([]);return}eU(!0);try{let s=new URLSearchParams;if(s.append("user_email",e),null==es)return;let t=(await (0,W.userFilterUICall)(es,s)).map(e=>({label:"".concat(e.user_email," (").concat(e.user_id,")"),value:e.user_id,user:e}));eF(t)}catch(e){console.error("Error fetching users:",e),G.Z.fromBackend("Failed to search for users")}finally{eU(!1)}},e1=(0,C.useCallback)(S()(e=>e4(e),300),[es]),e2=(e,s)=>{let t=s.user;ei.setFieldsValue({user_id:t.user_id})};return(0,a.jsxs)("div",{children:[ea&&P.LQ.includes(ea)&&(0,a.jsx)(u.Z,{className:"mx-auto",onClick:()=>eo(!0),children:"+ Create New Key"}),(0,a.jsx)(b.Z,{open:en,width:1e3,footer:null,onOk:eQ,onCancel:e$,children:(0,a.jsxs)(f.Z,{form:ei,onFinish:e0,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)("div",{className:"mb-8",children:[(0,a.jsx)(y.Z,{className:"mb-4",children:"Key Ownership"}),(0,a.jsx)(f.Z.Item,{label:(0,a.jsxs)("span",{children:["Owned By"," ",(0,a.jsx)(v.Z,{title:"Select who will own this Virtual Key",children:(0,a.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),className:"mb-4",children:(0,a.jsxs)(_.ZP.Group,{onChange:e=>ej(e.target.value),value:ey,children:[(0,a.jsx)(_.ZP,{value:"you",children:"You"}),(0,a.jsx)(_.ZP,{value:"service_account",children:"Service Account"}),"Admin"===ea&&(0,a.jsx)(_.ZP,{value:"another_user",children:"Another User"})]})}),"another_user"===ey&&(0,a.jsx)(f.Z.Item,{label:(0,a.jsxs)("span",{children:["User ID"," ",(0,a.jsx)(v.Z,{title:"The user who will own this key and be responsible for its usage",children:(0,a.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"user_id",className:"mt-4",rules:[{required:"another_user"===ey,message:"Please input the user ID of the user you are assigning the key to"}],children:(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{style:{display:"flex",marginBottom:"8px"},children:[(0,a.jsx)(j.default,{showSearch:!0,placeholder:"Type email to search for users",filterOption:!1,onSearch:e=>{e1(e)},onSelect:(e,s)=>e2(e,s),options:eE,loading:eV,allowClear:!0,style:{width:"100%"},notFoundContent:eV?"Searching...":"No users found"}),(0,a.jsx)(w.ZP,{onClick:()=>eP(!0),style:{marginLeft:"8px"},children:"Create User"})]}),(0,a.jsx)("div",{className:"text-xs text-gray-500",children:"Search by email to find users"})]})}),(0,a.jsx)(f.Z.Item,{label:(0,a.jsxs)("span",{children:["Team"," ",(0,a.jsx)(v.Z,{title:"The team this key belongs to, which determines available models and budget limits",children:(0,a.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"team_id",initialValue:s?s.team_id:null,className:"mt-4",rules:[{required:"service_account"===ey,message:"Please select a team for the service account"}],help:"service_account"===ey?"required":"",children:(0,a.jsx)(K.Z,{teams:t,onChange:e=>{eC((null==t?void 0:t.find(s=>s.team_id===e))||null)}})})]}),eX&&(0,a.jsx)("div",{className:"mb-8 p-4 bg-blue-50 border border-blue-200 rounded-md",children:(0,a.jsx)(x.Z,{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."})}),!eX&&(0,a.jsxs)("div",{className:"mb-8",children:[(0,a.jsx)(y.Z,{className:"mb-4",children:"Key Details"}),(0,a.jsx)(f.Z.Item,{label:(0,a.jsxs)("span",{children:["you"===ey||"another_user"===ey?"Key Name":"Service Account ID"," ",(0,a.jsx)(v.Z,{title:"you"===ey||"another_user"===ey?"A descriptive name to identify this key":"Unique identifier for this service account",children:(0,a.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"key_alias",rules:[{required:!0,message:"Please input a ".concat("you"===ey?"key name":"service account ID")}],help:"required",children:(0,a.jsx)(g.Z,{placeholder:""})}),(0,a.jsx)(f.Z.Item,{label:(0,a.jsxs)("span",{children:["Models"," ",(0,a.jsx)(v.Z,{title:"Select which models this key can access. Choose 'All Team Models' to grant access to all models available to the team",children:(0,a.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"models",rules:"management"===eq||"read_only"===eq?[]:[{required:!0,message:"Please select a model"}],help:"management"===eq||"read_only"===eq?"Models field is disabled for this key type":"required",className:"mt-4",children:(0,a.jsxs)(j.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},disabled:"management"===eq||"read_only"===eq,onChange:e=>{e.includes("all-team-models")&&ei.setFieldsValue({models:["all-team-models"]})},children:[(0,a.jsx)(Y,{value:"all-team-models",children:"All Team Models"},"all-team-models"),ex.map(e=>(0,a.jsx)(Y,{value:e,children:(0,O.W0)(e)},e))]})}),(0,a.jsx)(f.Z.Item,{label:(0,a.jsxs)("span",{children:["Key Type"," ",(0,a.jsx)(v.Z,{title:"Select the type of key to determine what routes and operations this key can access",children:(0,a.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"key_type",initialValue:"default",className:"mt-4",children:(0,a.jsxs)(j.default,{defaultValue:"default",placeholder:"Select key type",style:{width:"100%"},optionLabelProp:"label",onChange:e=>{eB(e),("management"===e||"read_only"===e)&&ei.setFieldsValue({models:[]})},children:[(0,a.jsx)(Y,{value:"default",label:"Default",children:(0,a.jsxs)("div",{style:{padding:"4px 0"},children:[(0,a.jsx)("div",{style:{fontWeight:500},children:"Default"}),(0,a.jsx)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:"Can call LLM API + Management routes"})]})}),(0,a.jsx)(Y,{value:"llm_api",label:"LLM API",children:(0,a.jsxs)("div",{style:{padding:"4px 0"},children:[(0,a.jsx)("div",{style:{fontWeight:500},children:"LLM API"}),(0,a.jsx)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:"Can call only LLM API routes (chat/completions, embeddings, etc.)"})]})}),(0,a.jsx)(Y,{value:"management",label:"Management",children:(0,a.jsxs)("div",{style:{padding:"4px 0"},children:[(0,a.jsx)("div",{style:{fontWeight:500},children:"Management"}),(0,a.jsx)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:"Can call only management routes (user/team/key management)"})]})})]})})]}),!eX&&(0,a.jsx)("div",{className:"mb-8",children:(0,a.jsxs)(d.Z,{className:"mt-4 mb-4",children:[(0,a.jsx)(m.Z,{children:(0,a.jsx)(y.Z,{className:"m-0",children:"Optional Settings"})}),(0,a.jsxs)(c.Z,{children:[(0,a.jsx)(f.Z.Item,{className:"mt-4",label:(0,a.jsxs)("span",{children:["Max Budget (USD)"," ",(0,a.jsx)(v.Z,{title:"Maximum amount in USD this key can spend. When reached, the key will be blocked from making further requests",children:(0,a.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"max_budget",help:"Budget cannot exceed team max budget: $".concat((null==s?void 0:s.max_budget)!==null&&(null==s?void 0:s.max_budget)!==void 0?null==s?void 0:s.max_budget:"unlimited"),rules:[{validator:async(e,t)=>{if(t&&s&&null!==s.max_budget&&t>s.max_budget)throw Error("Budget cannot exceed team max budget: $".concat((0,i.pw)(s.max_budget,4)))}}],children:(0,a.jsx)(z.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(f.Z.Item,{className:"mt-4",label:(0,a.jsxs)("span",{children:["Reset Budget"," ",(0,a.jsx)(v.Z,{title:"How often the budget should reset. For example, setting 'daily' will reset the budget every 24 hours",children:(0,a.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"budget_duration",help:"Team Reset Budget: ".concat((null==s?void 0:s.budget_duration)!==null&&(null==s?void 0:s.budget_duration)!==void 0?null==s?void 0:s.budget_duration:"None"),children:(0,a.jsx)(T.Z,{onChange:e=>ei.setFieldValue("budget_duration",e)})}),(0,a.jsx)(f.Z.Item,{className:"mt-4",label:(0,a.jsxs)("span",{children:["Tokens per minute Limit (TPM)"," ",(0,a.jsx)(v.Z,{title:"Maximum number of tokens this key can process per minute. Helps control usage and costs",children:(0,a.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"tpm_limit",help:"TPM cannot exceed team TPM limit: ".concat((null==s?void 0:s.tpm_limit)!==null&&(null==s?void 0:s.tpm_limit)!==void 0?null==s?void 0:s.tpm_limit:"unlimited"),rules:[{validator:async(e,t)=>{if(t&&s&&null!==s.tpm_limit&&t>s.tpm_limit)throw Error("TPM limit cannot exceed team TPM limit: ".concat(s.tpm_limit))}}],children:(0,a.jsx)(z.Z,{step:1,width:400})}),(0,a.jsx)(D.Z,{type:"tpm",name:"tpm_limit_type",className:"mt-4",initialValue:null,form:ei,showDetailedDescriptions:!0}),(0,a.jsx)(f.Z.Item,{className:"mt-4",label:(0,a.jsxs)("span",{children:["Requests per minute Limit (RPM)"," ",(0,a.jsx)(v.Z,{title:"Maximum number of API requests this key can make per minute. Helps prevent abuse and manage load",children:(0,a.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"rpm_limit",help:"RPM cannot exceed team RPM limit: ".concat((null==s?void 0:s.rpm_limit)!==null&&(null==s?void 0:s.rpm_limit)!==void 0?null==s?void 0:s.rpm_limit:"unlimited"),rules:[{validator:async(e,t)=>{if(t&&s&&null!==s.rpm_limit&&t>s.rpm_limit)throw Error("RPM limit cannot exceed team RPM limit: ".concat(s.rpm_limit))}}],children:(0,a.jsx)(z.Z,{step:1,width:400})}),(0,a.jsx)(D.Z,{type:"rpm",name:"rpm_limit_type",className:"mt-4",initialValue:null,form:ei,showDetailedDescriptions:!0}),(0,a.jsx)(f.Z.Item,{label:(0,a.jsxs)("span",{children:["Guardrails"," ",(0,a.jsx)(v.Z,{title:"Apply safety guardrails to this key to filter content or enforce policies",children:(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/quick_start",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,a.jsx)(n.Z,{style:{marginLeft:"4px"}})})})]}),name:"guardrails",className:"mt-4",help:el?"Select existing guardrails or enter new ones":"Premium feature - Upgrade to set guardrails by key",children:(0,a.jsx)(j.default,{mode:"tags",style:{width:"100%"},disabled:!el,placeholder:el?"Select or enter guardrails":"Premium feature - Upgrade to set guardrails by key",options:ev.map(e=>({value:e,label:e}))})}),(0,a.jsx)(f.Z.Item,{label:(0,a.jsxs)("span",{children:["Disable Global Guardrails"," ",(0,a.jsx)(v.Z,{title:"When enabled, this key will bypass any guardrails configured to run on every request (global guardrails)",children:(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/quick_start",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,a.jsx)(n.Z,{style:{marginLeft:"4px"}})})})]}),name:"disable_global_guardrails",className:"mt-4",valuePropName:"checked",help:el?"Bypass global guardrails for this key":"Premium feature - Upgrade to disable global guardrails by key",children:(0,a.jsx)(Z.Z,{disabled:!el,checkedChildren:"Yes",unCheckedChildren:"No"})}),(0,a.jsx)(f.Z.Item,{label:(0,a.jsxs)("span",{children:["Prompts"," ",(0,a.jsx)(v.Z,{title:"Allow this key to use specific prompt templates",children:(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/prompt_management",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,a.jsx)(n.Z,{style:{marginLeft:"4px"}})})})]}),name:"prompts",className:"mt-4",help:el?"Select existing prompts or enter new ones":"Premium feature - Upgrade to set prompts by key",children:(0,a.jsx)(j.default,{mode:"tags",style:{width:"100%"},disabled:!el,placeholder:el?"Select or enter prompts":"Premium feature - Upgrade to set prompts by key",options:ew.map(e=>({value:e,label:e}))})}),(0,a.jsx)(f.Z.Item,{label:(0,a.jsxs)("span",{children:["Allowed Pass Through Routes"," ",(0,a.jsx)(v.Z,{title:"Allow this key to use specific pass through routes",children:(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/pass_through",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,a.jsx)(n.Z,{style:{marginLeft:"4px"}})})})]}),name:"allowed_passthrough_routes",className:"mt-4",help:el?"Select existing pass through routes or enter new ones":"Premium feature - Upgrade to set pass through routes by key",children:(0,a.jsx)(V.Z,{onChange:e=>ei.setFieldValue("allowed_passthrough_routes",e),value:ei.getFieldValue("allowed_passthrough_routes"),accessToken:es,placeholder:el?"Select or enter pass through routes":"Premium feature - Upgrade to set pass through routes by key",disabled:!el,teamId:eS?eS.team_id:null})}),(0,a.jsx)(f.Z.Item,{label:(0,a.jsxs)("span",{children:["Allowed Vector Stores"," ",(0,a.jsx)(v.Z,{title:"Select which vector stores this key can access. If none selected, the key will have access to all available vector stores",children:(0,a.jsx)(n.Z,{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,a.jsx)(J.Z,{onChange:e=>ei.setFieldValue("allowed_vector_store_ids",e),value:ei.getFieldValue("allowed_vector_store_ids"),accessToken:es,placeholder:"Select vector stores (optional)"})}),(0,a.jsx)(f.Z.Item,{label:(0,a.jsxs)("span",{children:["Metadata"," ",(0,a.jsx)(v.Z,{title:"JSON object with additional information about this key. Used for tracking or custom logic",children:(0,a.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"metadata",className:"mt-4",children:(0,a.jsx)(N.default.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,a.jsx)(f.Z.Item,{label:(0,a.jsxs)("span",{children:["Tags"," ",(0,a.jsx)(v.Z,{title:"Tags for tracking spend and/or doing tag-based routing. Used for analytics and filtering",children:(0,a.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"tags",className:"mt-4",help:"Tags for tracking spend and/or doing tag-based routing.",children:(0,a.jsx)(j.default,{mode:"tags",style:{width:"100%"},placeholder:"Enter tags",tokenSeparators:[","],options:ef})}),(0,a.jsxs)(d.Z,{className:"mt-4 mb-4",children:[(0,a.jsx)(m.Z,{children:(0,a.jsx)("b",{children:"MCP Settings"})}),(0,a.jsxs)(c.Z,{children:[(0,a.jsx)(f.Z.Item,{label:(0,a.jsxs)("span",{children:["Allowed MCP Servers"," ",(0,a.jsx)(v.Z,{title:"Select which MCP servers or access groups this key can access",children:(0,a.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"allowed_mcp_servers_and_groups",help:"Select MCP servers or access groups this key can access",children:(0,a.jsx)(q.Z,{onChange:e=>ei.setFieldValue("allowed_mcp_servers_and_groups",e),value:ei.getFieldValue("allowed_mcp_servers_and_groups"),accessToken:es,placeholder:"Select MCP servers or access groups (optional)"})}),(0,a.jsx)(f.Z.Item,{name:"mcp_tool_permissions",initialValue:{},hidden:!0,children:(0,a.jsx)(N.default,{type:"hidden"})}),(0,a.jsx)(f.Z.Item,{noStyle:!0,shouldUpdate:(e,s)=>e.allowed_mcp_servers_and_groups!==s.allowed_mcp_servers_and_groups||e.mcp_tool_permissions!==s.mcp_tool_permissions,children:()=>{var e;return(0,a.jsx)("div",{className:"mt-6",children:(0,a.jsx)(B.Z,{accessToken:es,selectedServers:(null===(e=ei.getFieldValue("allowed_mcp_servers_and_groups"))||void 0===e?void 0:e.servers)||[],toolPermissions:ei.getFieldValue("mcp_tool_permissions")||{},onChange:e=>ei.setFieldsValue({mcp_tool_permissions:e})})})}})]})]}),(0,a.jsxs)(d.Z,{className:"mt-4 mb-4",children:[(0,a.jsx)(m.Z,{children:(0,a.jsx)("b",{children:"Agent Settings"})}),(0,a.jsx)(c.Z,{children:(0,a.jsx)(f.Z.Item,{label:(0,a.jsxs)("span",{children:["Allowed Agents"," ",(0,a.jsx)(v.Z,{title:"Select which agents or access groups this key can access",children:(0,a.jsx)(n.Z,{style:{marginLeft:"4px"}})})]}),name:"allowed_agents_and_groups",help:"Select agents or access groups this key can access",children:(0,a.jsx)(A.Z,{onChange:e=>ei.setFieldValue("allowed_agents_and_groups",e),value:ei.getFieldValue("allowed_agents_and_groups"),accessToken:es,placeholder:"Select agents or access groups (optional)"})})})]}),el?(0,a.jsxs)(d.Z,{className:"mt-4 mb-4",children:[(0,a.jsx)(m.Z,{children:(0,a.jsx)("b",{children:"Logging Settings"})}),(0,a.jsx)(c.Z,{children:(0,a.jsx)("div",{className:"mt-4",children:(0,a.jsx)(U.Z,{value:eN,onChange:ek,premiumUser:!0,disabledCallbacks:eR,onDisabledCallbacksChange:eO})})})]}):(0,a.jsx)(v.Z,{title:(0,a.jsxs)("span",{children:["Key-level logging settings is an enterprise feature, get in touch -",(0,a.jsx)("a",{href:"https://www.litellm.ai/enterprise",target:"_blank",children:"https://www.litellm.ai/enterprise"})]}),placement:"top",children:(0,a.jsxs)("div",{style:{position:"relative"},children:[(0,a.jsx)("div",{style:{opacity:.5},children:(0,a.jsxs)(d.Z,{className:"mt-4 mb-4",children:[(0,a.jsx)(m.Z,{children:(0,a.jsx)("b",{children:"Logging Settings"})}),(0,a.jsx)(c.Z,{children:(0,a.jsx)("div",{className:"mt-4",children:(0,a.jsx)(U.Z,{value:eN,onChange:ek,premiumUser:!1,disabledCallbacks:eR,onDisabledCallbacksChange:eO})})})]})}),(0,a.jsx)("div",{style:{position:"absolute",inset:0,cursor:"not-allowed"}})]})}),(0,a.jsxs)(d.Z,{className:"mt-4 mb-4",children:[(0,a.jsx)(m.Z,{children:(0,a.jsx)("b",{children:"Model Aliases"})}),(0,a.jsx)(c.Z,{children:(0,a.jsxs)("div",{className:"mt-4",children:[(0,a.jsx)(x.Z,{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,a.jsx)(F.Z,{accessToken:es,initialModelAliases:eG,onAliasUpdate:eW,showExampleConfig:!1})]})})]}),(0,a.jsxs)(d.Z,{className:"mt-4 mb-4",children:[(0,a.jsx)(m.Z,{children:(0,a.jsx)("b",{children:"Key Lifecycle"})}),(0,a.jsx)(c.Z,{children:(0,a.jsx)("div",{className:"mt-4",children:(0,a.jsx)(E.Z,{form:ei,autoRotationEnabled:ez,onAutoRotationChange:eJ,rotationInterval:eH,onRotationIntervalChange:eY})})}),(0,a.jsx)(f.Z.Item,{name:"duration",hidden:!0,initialValue:null,children:(0,a.jsx)(N.default,{})})]}),(0,a.jsxs)(d.Z,{className:"mt-4 mb-4",children:[(0,a.jsx)(m.Z,{children:(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)("b",{children:"Advanced Settings"}),(0,a.jsx)(v.Z,{title:(0,a.jsxs)("span",{children:["Learn more about advanced settings in our"," ",(0,a.jsx)("a",{href:W.proxyBaseUrl?"".concat(W.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,a.jsx)(n.Z,{className:"text-gray-400 hover:text-gray-300 cursor-help"})})]})}),(0,a.jsx)(c.Z,{children:(0,a.jsx)(I.Z,{schemaComponent:"GenerateKeyRequest",form:ei,excludedFields:["key_alias","team_id","models","duration","metadata","tags","guardrails","max_budget","budget_duration","tpm_limit","rpm_limit"]})})]})]})]})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(w.ZP,{htmlType:"submit",disabled:eX,style:{opacity:eX?.5:1},children:"Create Key"})})]})}),eM&&(0,a.jsx)(b.Z,{title:"Create New User",visible:eM,onCancel:()=>eP(!1),footer:null,width:800,children:(0,a.jsx)(R.Z,{userID:et,accessToken:es,teams:t,possibleUIRoles:eT,onUserCreated:e=>{eL(e),ei.setFieldsValue({user_id:e}),eP(!1)},isEmbedded:!0})}),ed&&(0,a.jsx)(b.Z,{visible:en,onOk:eQ,onCancel:e$,footer:null,children:(0,a.jsxs)(p.Z,{numItems:1,className:"gap-2 w-full",children:[(0,a.jsx)(y.Z,{children:"Save your Key"}),(0,a.jsx)(h.Z,{numColSpan:1,children:(0,a.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons,"," ",(0,a.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,a.jsx)(h.Z,{numColSpan:1,children:null!=ed?(0,a.jsxs)("div",{children:[(0,a.jsx)(x.Z,{className:"mt-3",children:"Virtual Key:"}),(0,a.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,a.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal"},children:ed})}),(0,a.jsx)(M.CopyToClipboard,{text:ed,onCopy:()=>{G.Z.success("Virtual Key copied to clipboard")},children:(0,a.jsx)(u.Z,{className:"mt-3",children:"Copy Virtual Key"})})]}):(0,a.jsx)(x.Z,{children:"Key being created, this might take 30s"})})]})})]})}}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/1108-8b678b0704cb239b.js b/litellm/proxy/_experimental/out/_next/static/chunks/1108-8b678b0704cb239b.js deleted file mode 100644 index 89c5291477d..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/1108-8b678b0704cb239b.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1108],{40278:function(t,e,r){"use strict";r.d(e,{Z:function(){return S}});var n=r(5853),o=r(7084),i=r(26898),a=r(13241),u=r(1153),c=r(2265),l=r(47625),s=r(93765),f=r(31699),p=r(97059),h=r(62994),d=r(25311),y=(0,s.z)({chartName:"BarChart",GraphicalChild:f.$,defaultTooltipEventType:"axis",validateTooltipEventTypes:["axis","item"],axisComponents:[{axisType:"xAxis",AxisComp:p.K},{axisType:"yAxis",AxisComp:h.B}],formatAxisMap:d.t9}),v=r(56940),m=r(26680),b=r(8147),g=r(22190),x=r(65278),w=r(98593),O=r(92666),j=r(32644);let S=c.forwardRef((t,e)=>{let{data:r=[],categories:s=[],index:d,colors:S=i.s,valueFormatter:P=u.Cj,layout:E="horizontal",stack:k=!1,relative:A=!1,startEndOnly:M=!1,animationDuration:_=900,showAnimation:T=!1,showXAxis:C=!0,showYAxis:N=!0,yAxisWidth:D=56,intervalType:I="equidistantPreserveStart",showTooltip:L=!0,showLegend:B=!0,showGridLines:R=!0,autoMinValue:z=!1,minValue:U,maxValue:F,allowDecimals:$=!0,noDataText:q,onValueChange:Z,enableLegendSlider:W=!1,customTooltip:Y,rotateLabelX:H,barCategoryGap:X,tickGap:G=5,xAxisLabel:V,yAxisLabel:K,className:Q,padding:J=C||N?{left:20,right:20}:{left:0,right:0}}=t,tt=(0,n._T)(t,["data","categories","index","colors","valueFormatter","layout","stack","relative","startEndOnly","animationDuration","showAnimation","showXAxis","showYAxis","yAxisWidth","intervalType","showTooltip","showLegend","showGridLines","autoMinValue","minValue","maxValue","allowDecimals","noDataText","onValueChange","enableLegendSlider","customTooltip","rotateLabelX","barCategoryGap","tickGap","xAxisLabel","yAxisLabel","className","padding"]),[te,tr]=(0,c.useState)(60),tn=(0,j.me)(s,S),[to,ti]=c.useState(void 0),[ta,tu]=(0,c.useState)(void 0),tc=!!Z;function tl(t,e,r){var n,o,i,a;r.stopPropagation(),Z&&((0,j.vZ)(to,Object.assign(Object.assign({},t.payload),{value:t.value}))?(tu(void 0),ti(void 0),null==Z||Z(null)):(tu(null===(o=null===(n=t.tooltipPayload)||void 0===n?void 0:n[0])||void 0===o?void 0:o.dataKey),ti(Object.assign(Object.assign({},t.payload),{value:t.value})),null==Z||Z(Object.assign({eventType:"bar",categoryClicked:null===(a=null===(i=t.tooltipPayload)||void 0===i?void 0:i[0])||void 0===a?void 0:a.dataKey},t.payload))))}let ts=(0,j.i4)(z,U,F);return c.createElement("div",Object.assign({ref:e,className:(0,a.q)("w-full h-80",Q)},tt),c.createElement(l.h,{className:"h-full w-full"},(null==r?void 0:r.length)?c.createElement(y,{barCategoryGap:X,data:r,stackOffset:k?"sign":A?"expand":"none",layout:"vertical"===E?"vertical":"horizontal",onClick:tc&&(ta||to)?()=>{ti(void 0),tu(void 0),null==Z||Z(null)}:void 0,margin:{bottom:V?30:void 0,left:K?20:void 0,right:K?5:void 0,top:5}},R?c.createElement(v.q,{className:(0,a.q)("stroke-1","stroke-tremor-border","dark:stroke-dark-tremor-border"),horizontal:"vertical"!==E,vertical:"vertical"===E}):null,"vertical"!==E?c.createElement(p.K,{padding:J,hide:!C,dataKey:d,interval:M?"preserveStartEnd":I,tick:{transform:"translate(0, 6)"},ticks:M?[r[0][d],r[r.length-1][d]]:void 0,fill:"",stroke:"",className:(0,a.q)("mt-4 text-tremor-label","fill-tremor-content","dark:fill-dark-tremor-content"),tickLine:!1,axisLine:!1,angle:null==H?void 0:H.angle,dy:null==H?void 0:H.verticalShift,height:null==H?void 0:H.xAxisHeight,minTickGap:G},V&&c.createElement(m._,{position:"insideBottom",offset:-20,className:"fill-tremor-content-emphasis text-tremor-default font-medium dark:fill-dark-tremor-content-emphasis"},V)):c.createElement(p.K,{hide:!C,type:"number",tick:{transform:"translate(-3, 0)"},domain:ts,fill:"",stroke:"",className:(0,a.q)("text-tremor-label","fill-tremor-content","dark:fill-dark-tremor-content"),tickLine:!1,axisLine:!1,tickFormatter:P,minTickGap:G,allowDecimals:$,angle:null==H?void 0:H.angle,dy:null==H?void 0:H.verticalShift,height:null==H?void 0:H.xAxisHeight},V&&c.createElement(m._,{position:"insideBottom",offset:-20,className:"fill-tremor-content-emphasis text-tremor-default font-medium dark:fill-dark-tremor-content-emphasis"},V)),"vertical"!==E?c.createElement(h.B,{width:D,hide:!N,axisLine:!1,tickLine:!1,type:"number",domain:ts,tick:{transform:"translate(-3, 0)"},fill:"",stroke:"",className:(0,a.q)("text-tremor-label","fill-tremor-content","dark:fill-dark-tremor-content"),tickFormatter:A?t=>"".concat((100*t).toString()," %"):P,allowDecimals:$},K&&c.createElement(m._,{position:"insideLeft",style:{textAnchor:"middle"},angle:-90,offset:-15,className:"fill-tremor-content-emphasis text-tremor-default font-medium dark:fill-dark-tremor-content-emphasis"},K)):c.createElement(h.B,{width:D,hide:!N,dataKey:d,axisLine:!1,tickLine:!1,ticks:M?[r[0][d],r[r.length-1][d]]:void 0,type:"category",interval:"preserveStartEnd",tick:{transform:"translate(0, 6)"},fill:"",stroke:"",className:(0,a.q)("text-tremor-label","fill-tremor-content","dark:fill-dark-tremor-content")},K&&c.createElement(m._,{position:"insideLeft",style:{textAnchor:"middle"},angle:-90,offset:-15,className:"fill-tremor-content-emphasis text-tremor-default font-medium dark:fill-dark-tremor-content-emphasis"},K)),c.createElement(b.u,{wrapperStyle:{outline:"none"},isAnimationActive:!1,cursor:{fill:"#d1d5db",opacity:"0.15"},content:L?t=>{let{active:e,payload:r,label:n}=t;return Y?c.createElement(Y,{payload:null==r?void 0:r.map(t=>{var e;return Object.assign(Object.assign({},t),{color:null!==(e=tn.get(t.dataKey))&&void 0!==e?e:o.fr.Gray})}),active:e,label:n}):c.createElement(w.ZP,{active:e,payload:r,label:n,valueFormatter:P,categoryColors:tn})}:c.createElement(c.Fragment,null),position:{y:0}}),B?c.createElement(g.D,{verticalAlign:"top",height:te,content:t=>{let{payload:e}=t;return(0,x.Z)({payload:e},tn,tr,ta,tc?t=>{tc&&(t!==ta||to?(tu(t),null==Z||Z({eventType:"category",categoryClicked:t})):(tu(void 0),null==Z||Z(null)),ti(void 0))}:void 0,W)}}):null,s.map(t=>{var e;return c.createElement(f.$,{className:(0,a.q)((0,u.bM)(null!==(e=tn.get(t))&&void 0!==e?e:o.fr.Gray,i.K.background).fillColor,Z?"cursor-pointer":""),key:t,name:t,type:"linear",stackId:k||A?"a":void 0,dataKey:t,fill:"",isAnimationActive:T,animationDuration:_,shape:t=>((t,e,r,n)=>{let{fillOpacity:o,name:i,payload:a,value:u}=t,{x:l,width:s,y:f,height:p}=t;return"horizontal"===n&&p<0?(f+=p,p=Math.abs(p)):"vertical"===n&&s<0&&(l+=s,s=Math.abs(s)),c.createElement("rect",{x:l,y:f,width:s,height:p,opacity:e||r&&r!==i?(0,j.vZ)(e,Object.assign(Object.assign({},a),{value:u}))?o:.3:o})})(t,to,ta,E),onClick:tl})})):c.createElement(O.Z,{noDataText:q})))});S.displayName="BarChart"},65278:function(t,e,r){"use strict";r.d(e,{Z:function(){return y}});var n=r(2265);let o=t=>{n.useEffect(()=>{let e=()=>{t()};return e(),window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)},[t])};var i=r(5853),a=r(26898),u=r(13241),c=r(1153);let l=t=>{var e=(0,i._T)(t,[]);return n.createElement("svg",Object.assign({},e,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"}),n.createElement("path",{d:"M8 12L14 6V18L8 12Z"}))},s=t=>{var e=(0,i._T)(t,[]);return n.createElement("svg",Object.assign({},e,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"}),n.createElement("path",{d:"M16 12L10 18V6L16 12Z"}))},f=(0,c.fn)("Legend"),p=t=>{let{name:e,color:r,onClick:o,activeLegend:i}=t,l=!!o;return n.createElement("li",{className:(0,u.q)(f("legendItem"),"group inline-flex items-center px-2 py-0.5 rounded-tremor-small transition whitespace-nowrap",l?"cursor-pointer":"cursor-default","text-tremor-content",l?"hover:bg-tremor-background-subtle":"","dark:text-dark-tremor-content",l?"dark:hover:bg-dark-tremor-background-subtle":""),onClick:t=>{t.stopPropagation(),null==o||o(e,r)}},n.createElement("svg",{className:(0,u.q)("flex-none h-2 w-2 mr-1.5",(0,c.bM)(r,a.K.text).textColor,i&&i!==e?"opacity-40":"opacity-100"),fill:"currentColor",viewBox:"0 0 8 8"},n.createElement("circle",{cx:4,cy:4,r:4})),n.createElement("p",{className:(0,u.q)("whitespace-nowrap truncate text-tremor-default","text-tremor-content",l?"group-hover:text-tremor-content-emphasis":"","dark:text-dark-tremor-content",i&&i!==e?"opacity-40":"opacity-100",l?"dark:group-hover:text-dark-tremor-content-emphasis":"")},e))},h=t=>{let{icon:e,onClick:r,disabled:o}=t,[i,a]=n.useState(!1),c=n.useRef(null);return n.useEffect(()=>(i?c.current=setInterval(()=>{null==r||r()},300):clearInterval(c.current),()=>clearInterval(c.current)),[i,r]),(0,n.useEffect)(()=>{o&&(clearInterval(c.current),a(!1))},[o]),n.createElement("button",{type:"button",className:(0,u.q)(f("legendSliderButton"),"w-5 group inline-flex items-center truncate rounded-tremor-small transition",o?"cursor-not-allowed":"cursor-pointer",o?"text-tremor-content-subtle":"text-tremor-content hover:text-tremor-content-emphasis hover:bg-tremor-background-subtle",o?"dark:text-dark-tremor-subtle":"dark:text-dark-tremor dark:hover:text-tremor-content-emphasis dark:hover:bg-dark-tremor-background-subtle"),disabled:o,onClick:t=>{t.stopPropagation(),null==r||r()},onMouseDown:t=>{t.stopPropagation(),a(!0)},onMouseUp:t=>{t.stopPropagation(),a(!1)}},n.createElement(e,{className:"w-full"}))},d=n.forwardRef((t,e)=>{let{categories:r,colors:o=a.s,className:c,onClickLegendItem:d,activeLegend:y,enableLegendSlider:v=!1}=t,m=(0,i._T)(t,["categories","colors","className","onClickLegendItem","activeLegend","enableLegendSlider"]),b=n.useRef(null),g=n.useRef(null),[x,w]=n.useState(null),[O,j]=n.useState(null),S=n.useRef(null),P=(0,n.useCallback)(()=>{let t=null==b?void 0:b.current;t&&w({left:t.scrollLeft>0,right:t.scrollWidth-t.clientWidth>t.scrollLeft})},[w]),E=(0,n.useCallback)(t=>{var e,r;let n=null==b?void 0:b.current,o=null==g?void 0:g.current,i=null!==(e=null==n?void 0:n.clientWidth)&&void 0!==e?e:0,a=null!==(r=null==o?void 0:o.clientWidth)&&void 0!==r?r:0;n&&v&&(n.scrollTo({left:"left"===t?n.scrollLeft-i+a:n.scrollLeft+i-a,behavior:"smooth"}),setTimeout(()=>{P()},400))},[v,P]);n.useEffect(()=>{let t=t=>{"ArrowLeft"===t?E("left"):"ArrowRight"===t&&E("right")};return O?(t(O),S.current=setInterval(()=>{t(O)},300)):clearInterval(S.current),()=>clearInterval(S.current)},[O,E]);let k=t=>{t.stopPropagation(),"ArrowLeft"!==t.key&&"ArrowRight"!==t.key||(t.preventDefault(),j(t.key))},A=t=>{t.stopPropagation(),j(null)};return n.useEffect(()=>{let t=null==b?void 0:b.current;return v&&(P(),null==t||t.addEventListener("keydown",k),null==t||t.addEventListener("keyup",A)),()=>{null==t||t.removeEventListener("keydown",k),null==t||t.removeEventListener("keyup",A)}},[P,v]),n.createElement("ol",Object.assign({ref:e,className:(0,u.q)(f("root"),"relative overflow-hidden",c)},m),n.createElement("div",{ref:b,tabIndex:0,className:(0,u.q)("h-full flex",v?(null==x?void 0:x.right)||(null==x?void 0:x.left)?"pl-4 pr-12 items-center overflow-auto snap-mandatory [&::-webkit-scrollbar]:hidden [scrollbar-width:none]":"":"flex-wrap")},r.map((t,e)=>n.createElement(p,{key:"item-".concat(e),name:t,color:o[e%o.length],onClick:d,activeLegend:y}))),v&&((null==x?void 0:x.right)||(null==x?void 0:x.left))?n.createElement(n.Fragment,null,n.createElement("div",{className:(0,u.q)("bg-tremor-background","dark:bg-dark-tremor-background","absolute flex top-0 pr-1 bottom-0 right-0 items-center justify-center h-full"),ref:g},n.createElement(h,{icon:l,onClick:()=>{j(null),E("left")},disabled:!(null==x?void 0:x.left)}),n.createElement(h,{icon:s,onClick:()=>{j(null),E("right")},disabled:!(null==x?void 0:x.right)}))):null)});d.displayName="Legend";let y=(t,e,r,i,a,u)=>{let{payload:c}=t,l=(0,n.useRef)(null);o(()=>{var t,e;r((e=null===(t=l.current)||void 0===t?void 0:t.clientHeight)?Number(e)+20:60)});let s=c.filter(t=>"none"!==t.type);return n.createElement("div",{ref:l,className:"flex items-center justify-end"},n.createElement(d,{categories:s.map(t=>t.value),colors:s.map(t=>e.get(t.value)),onClickLegendItem:a,activeLegend:i,enableLegendSlider:u}))}},98593:function(t,e,r){"use strict";r.d(e,{$B:function(){return c},ZP:function(){return s},zX:function(){return l}});var n=r(2265),o=r(7084),i=r(26898),a=r(13241),u=r(1153);let c=t=>{let{children:e}=t;return n.createElement("div",{className:(0,a.q)("rounded-tremor-default text-tremor-default border","bg-tremor-background shadow-tremor-dropdown border-tremor-border","dark:bg-dark-tremor-background dark:shadow-dark-tremor-dropdown dark:border-dark-tremor-border")},e)},l=t=>{let{value:e,name:r,color:o}=t;return n.createElement("div",{className:"flex items-center justify-between space-x-8"},n.createElement("div",{className:"flex items-center space-x-2"},n.createElement("span",{className:(0,a.q)("shrink-0 rounded-tremor-full border-2 h-3 w-3","border-tremor-background shadow-tremor-card","dark:border-dark-tremor-background dark:shadow-dark-tremor-card",(0,u.bM)(o,i.K.background).bgColor)}),n.createElement("p",{className:(0,a.q)("text-right whitespace-nowrap","text-tremor-content","dark:text-dark-tremor-content")},r)),n.createElement("p",{className:(0,a.q)("font-medium tabular-nums text-right whitespace-nowrap","text-tremor-content-emphasis","dark:text-dark-tremor-content-emphasis")},e))},s=t=>{let{active:e,payload:r,label:i,categoryColors:u,valueFormatter:s}=t;if(e&&r){let t=r.filter(t=>"none"!==t.type);return n.createElement(c,null,n.createElement("div",{className:(0,a.q)("border-tremor-border border-b px-4 py-2","dark:border-dark-tremor-border")},n.createElement("p",{className:(0,a.q)("font-medium","text-tremor-content-emphasis","dark:text-dark-tremor-content-emphasis")},i)),n.createElement("div",{className:(0,a.q)("px-4 py-2 space-y-1")},t.map((t,e)=>{var r;let{value:i,name:a}=t;return n.createElement(l,{key:"id-".concat(e),value:s(i),name:a,color:null!==(r=u.get(a))&&void 0!==r?r:o.fr.Blue})})))}return null}},92666:function(t,e,r){"use strict";r.d(e,{Z:function(){return i}});var n=r(13241),o=r(2265);let i=t=>{let{className:e,noDataText:r="No data"}=t;return o.createElement("div",{className:(0,n.q)("flex items-center justify-center w-full h-full border border-dashed rounded-tremor-default","border-tremor-border","dark:border-dark-tremor-border",e)},o.createElement("p",{className:(0,n.q)("text-tremor-content text-tremor-default","dark:text-dark-tremor-content")},r))}},32644:function(t,e,r){"use strict";r.d(e,{FB:function(){return i},i4:function(){return o},me:function(){return n},vZ:function(){return function t(e,r){if(e===r)return!0;if("object"!=typeof e||"object"!=typeof r||null===e||null===r)return!1;let n=Object.keys(e),o=Object.keys(r);if(n.length!==o.length)return!1;for(let i of n)if(!o.includes(i)||!t(e[i],r[i]))return!1;return!0}}});let n=(t,e)=>{let r=new Map;return t.forEach((t,n)=>{r.set(t,e[n%e.length])}),r},o=(t,e,r)=>[t?"auto":null!=e?e:0,null!=r?r:"auto"];function i(t,e){let r=[];for(let n of t)if(Object.prototype.hasOwnProperty.call(n,e)&&(r.push(n[e]),r.length>1))return!1;return!0}},49804:function(t,e,r){"use strict";r.d(e,{Z:function(){return l}});var n=r(5853),o=r(13241),i=r(1153),a=r(2265),u=r(9496);let c=(0,i.fn)("Col"),l=a.forwardRef((t,e)=>{let{numColSpan:r=1,numColSpanSm:i,numColSpanMd:l,numColSpanLg:s,children:f,className:p}=t,h=(0,n._T)(t,["numColSpan","numColSpanSm","numColSpanMd","numColSpanLg","children","className"]),d=(t,e)=>t&&Object.keys(e).includes(String(t))?e[t]:"";return a.createElement("div",Object.assign({ref:e,className:(0,o.q)(c("root"),(()=>{let t=d(r,u.PT),e=d(i,u.SP),n=d(l,u.VS),a=d(s,u._w);return(0,o.q)(t,e,n,a)})(),p)},h),f)});l.displayName="Col"},97765:function(t,e,r){"use strict";r.d(e,{Z:function(){return c}});var n=r(5853),o=r(26898),i=r(13241),a=r(1153),u=r(2265);let c=u.forwardRef((t,e)=>{let{color:r,children:c,className:l}=t,s=(0,n._T)(t,["color","children","className"]);return u.createElement("p",Object.assign({ref:e,className:(0,i.q)(r?(0,a.bM)(r,o.K.lightText).textColor:"text-tremor-content-emphasis dark:text-dark-tremor-content-emphasis",l)},s),c)});c.displayName="Subtitle"},61134:function(t,e,r){var n;!function(o){"use strict";var i,a={precision:20,rounding:4,toExpNeg:-7,toExpPos:21,LN10:"2.302585092994045684017991454684364207601101488628772976033327900967572609677352480235997205089598298341967784042286"},u=!0,c="[DecimalError] ",l=c+"Invalid argument: ",s=c+"Exponent out of range: ",f=Math.floor,p=Math.pow,h=/^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,d=f(1286742750677284.5),y={};function v(t,e){var r,n,o,i,a,c,l,s,f=t.constructor,p=f.precision;if(!t.s||!e.s)return e.s||(e=new f(t)),u?E(e,p):e;if(l=t.d,s=e.d,a=t.e,o=e.e,l=l.slice(),i=a-o){for(i<0?(n=l,i=-i,c=s.length):(n=s,o=a,c=l.length),i>(c=(a=Math.ceil(p/7))>c?a+1:c+1)&&(i=c,n.length=1),n.reverse();i--;)n.push(0);n.reverse()}for((c=l.length)-(i=s.length)<0&&(i=c,n=s,s=l,l=n),r=0;i;)r=(l[--i]=l[i]+s[i]+r)/1e7|0,l[i]%=1e7;for(r&&(l.unshift(r),++o),c=l.length;0==l[--c];)l.pop();return e.d=l,e.e=o,u?E(e,p):e}function m(t,e,r){if(t!==~~t||tr)throw Error(l+t)}function b(t){var e,r,n,o=t.length-1,i="",a=t[0];if(o>0){for(i+=a,e=1;et.e^this.s<0?1:-1;for(e=0,r=(n=this.d.length)<(o=t.d.length)?n:o;et.d[e]^this.s<0?1:-1;return n===o?0:n>o^this.s<0?1:-1},y.decimalPlaces=y.dp=function(){var t=this.d.length-1,e=(t-this.e)*7;if(t=this.d[t])for(;t%10==0;t/=10)e--;return e<0?0:e},y.dividedBy=y.div=function(t){return g(this,new this.constructor(t))},y.dividedToIntegerBy=y.idiv=function(t){var e=this.constructor;return E(g(this,new e(t),0,1),e.precision)},y.equals=y.eq=function(t){return!this.cmp(t)},y.exponent=function(){return w(this)},y.greaterThan=y.gt=function(t){return this.cmp(t)>0},y.greaterThanOrEqualTo=y.gte=function(t){return this.cmp(t)>=0},y.isInteger=y.isint=function(){return this.e>this.d.length-2},y.isNegative=y.isneg=function(){return this.s<0},y.isPositive=y.ispos=function(){return this.s>0},y.isZero=function(){return 0===this.s},y.lessThan=y.lt=function(t){return 0>this.cmp(t)},y.lessThanOrEqualTo=y.lte=function(t){return 1>this.cmp(t)},y.logarithm=y.log=function(t){var e,r=this.constructor,n=r.precision,o=n+5;if(void 0===t)t=new r(10);else if((t=new r(t)).s<1||t.eq(i))throw Error(c+"NaN");if(this.s<1)throw Error(c+(this.s?"NaN":"-Infinity"));return this.eq(i)?new r(0):(u=!1,e=g(S(this,o),S(t,o),o),u=!0,E(e,n))},y.minus=y.sub=function(t){return t=new this.constructor(t),this.s==t.s?k(this,t):v(this,(t.s=-t.s,t))},y.modulo=y.mod=function(t){var e,r=this.constructor,n=r.precision;if(!(t=new r(t)).s)throw Error(c+"NaN");return this.s?(u=!1,e=g(this,t,0,1).times(t),u=!0,this.minus(e)):E(new r(this),n)},y.naturalExponential=y.exp=function(){return x(this)},y.naturalLogarithm=y.ln=function(){return S(this)},y.negated=y.neg=function(){var t=new this.constructor(this);return t.s=-t.s||0,t},y.plus=y.add=function(t){return t=new this.constructor(t),this.s==t.s?v(this,t):k(this,(t.s=-t.s,t))},y.precision=y.sd=function(t){var e,r,n;if(void 0!==t&&!!t!==t&&1!==t&&0!==t)throw Error(l+t);if(e=w(this)+1,r=7*(n=this.d.length-1)+1,n=this.d[n]){for(;n%10==0;n/=10)r--;for(n=this.d[0];n>=10;n/=10)r++}return t&&e>r?e:r},y.squareRoot=y.sqrt=function(){var t,e,r,n,o,i,a,l=this.constructor;if(this.s<1){if(!this.s)return new l(0);throw Error(c+"NaN")}for(t=w(this),u=!1,0==(o=Math.sqrt(+this))||o==1/0?(((e=b(this.d)).length+t)%2==0&&(e+="0"),o=Math.sqrt(e),t=f((t+1)/2)-(t<0||t%2),n=new l(e=o==1/0?"5e"+t:(e=o.toExponential()).slice(0,e.indexOf("e")+1)+t)):n=new l(o.toString()),o=a=(r=l.precision)+3;;)if(n=(i=n).plus(g(this,i,a+2)).times(.5),b(i.d).slice(0,a)===(e=b(n.d)).slice(0,a)){if(e=e.slice(a-3,a+1),o==a&&"4999"==e){if(E(i,r+1,0),i.times(i).eq(this)){n=i;break}}else if("9999"!=e)break;a+=4}return u=!0,E(n,r)},y.times=y.mul=function(t){var e,r,n,o,i,a,c,l,s,f=this.constructor,p=this.d,h=(t=new f(t)).d;if(!this.s||!t.s)return new f(0);for(t.s*=this.s,r=this.e+t.e,(l=p.length)<(s=h.length)&&(i=p,p=h,h=i,a=l,l=s,s=a),i=[],n=a=l+s;n--;)i.push(0);for(n=s;--n>=0;){for(e=0,o=l+n;o>n;)c=i[o]+h[n]*p[o-n-1]+e,i[o--]=c%1e7|0,e=c/1e7|0;i[o]=(i[o]+e)%1e7|0}for(;!i[--a];)i.pop();return e?++r:i.shift(),t.d=i,t.e=r,u?E(t,f.precision):t},y.toDecimalPlaces=y.todp=function(t,e){var r=this,n=r.constructor;return(r=new n(r),void 0===t)?r:(m(t,0,1e9),void 0===e?e=n.rounding:m(e,0,8),E(r,t+w(r)+1,e))},y.toExponential=function(t,e){var r,n=this,o=n.constructor;return void 0===t?r=A(n,!0):(m(t,0,1e9),void 0===e?e=o.rounding:m(e,0,8),r=A(n=E(new o(n),t+1,e),!0,t+1)),r},y.toFixed=function(t,e){var r,n,o=this.constructor;return void 0===t?A(this):(m(t,0,1e9),void 0===e?e=o.rounding:m(e,0,8),r=A((n=E(new o(this),t+w(this)+1,e)).abs(),!1,t+w(n)+1),this.isneg()&&!this.isZero()?"-"+r:r)},y.toInteger=y.toint=function(){var t=this.constructor;return E(new t(this),w(this)+1,t.rounding)},y.toNumber=function(){return+this},y.toPower=y.pow=function(t){var e,r,n,o,a,l,s=this,p=s.constructor,h=+(t=new p(t));if(!t.s)return new p(i);if(!(s=new p(s)).s){if(t.s<1)throw Error(c+"Infinity");return s}if(s.eq(i))return s;if(n=p.precision,t.eq(i))return E(s,n);if(l=(e=t.e)>=(r=t.d.length-1),a=s.s,l){if((r=h<0?-h:h)<=9007199254740991){for(o=new p(i),e=Math.ceil(n/7+4),u=!1;r%2&&M((o=o.times(s)).d,e),0!==(r=f(r/2));)M((s=s.times(s)).d,e);return u=!0,t.s<0?new p(i).div(o):E(o,n)}}else if(a<0)throw Error(c+"NaN");return a=a<0&&1&t.d[Math.max(e,r)]?-1:1,s.s=1,u=!1,o=t.times(S(s,n+12)),u=!0,(o=x(o)).s=a,o},y.toPrecision=function(t,e){var r,n,o=this,i=o.constructor;return void 0===t?(r=w(o),n=A(o,r<=i.toExpNeg||r>=i.toExpPos)):(m(t,1,1e9),void 0===e?e=i.rounding:m(e,0,8),r=w(o=E(new i(o),t,e)),n=A(o,t<=r||r<=i.toExpNeg,t)),n},y.toSignificantDigits=y.tosd=function(t,e){var r=this.constructor;return void 0===t?(t=r.precision,e=r.rounding):(m(t,1,1e9),void 0===e?e=r.rounding:m(e,0,8)),E(new r(this),t,e)},y.toString=y.valueOf=y.val=y.toJSON=function(){var t=w(this),e=this.constructor;return A(this,t<=e.toExpNeg||t>=e.toExpPos)};var g=function(){function t(t,e){var r,n=0,o=t.length;for(t=t.slice();o--;)r=t[o]*e+n,t[o]=r%1e7|0,n=r/1e7|0;return n&&t.unshift(n),t}function e(t,e,r,n){var o,i;if(r!=n)i=r>n?1:-1;else for(o=i=0;oe[o]?1:-1;break}return i}function r(t,e,r){for(var n=0;r--;)t[r]-=n,n=t[r]1;)t.shift()}return function(n,o,i,a){var u,l,s,f,p,h,d,y,v,m,b,g,x,O,j,S,P,k,A=n.constructor,M=n.s==o.s?1:-1,_=n.d,T=o.d;if(!n.s)return new A(n);if(!o.s)throw Error(c+"Division by zero");for(s=0,l=n.e-o.e,P=T.length,j=_.length,y=(d=new A(M)).d=[];T[s]==(_[s]||0);)++s;if(T[s]>(_[s]||0)&&--l,(g=null==i?i=A.precision:a?i+(w(n)-w(o))+1:i)<0)return new A(0);if(g=g/7+2|0,s=0,1==P)for(f=0,T=T[0],g++;(s1&&(T=t(T,f),_=t(_,f),P=T.length,j=_.length),O=P,m=(v=_.slice(0,P)).length;m=1e7/2&&++S;do f=0,(u=e(T,v,P,m))<0?(b=v[0],P!=m&&(b=1e7*b+(v[1]||0)),(f=b/S|0)>1?(f>=1e7&&(f=1e7-1),h=(p=t(T,f)).length,m=v.length,1==(u=e(p,v,h,m))&&(f--,r(p,P16)throw Error(s+w(t));if(!t.s)return new h(i);for(null==e?(u=!1,c=d):c=e,a=new h(.03125);t.abs().gte(.1);)t=t.times(a),f+=5;for(c+=Math.log(p(2,f))/Math.LN10*2+5|0,r=n=o=new h(i),h.precision=c;;){if(n=E(n.times(t),c),r=r.times(++l),b((a=o.plus(g(n,r,c))).d).slice(0,c)===b(o.d).slice(0,c)){for(;f--;)o=E(o.times(o),c);return h.precision=d,null==e?(u=!0,E(o,d)):o}o=a}}function w(t){for(var e=7*t.e,r=t.d[0];r>=10;r/=10)e++;return e}function O(t,e,r){if(e>t.LN10.sd())throw u=!0,r&&(t.precision=r),Error(c+"LN10 precision limit exceeded");return E(new t(t.LN10),e)}function j(t){for(var e="";t--;)e+="0";return e}function S(t,e){var r,n,o,a,l,s,f,p,h,d=1,y=t,v=y.d,m=y.constructor,x=m.precision;if(y.s<1)throw Error(c+(y.s?"NaN":"-Infinity"));if(y.eq(i))return new m(0);if(null==e?(u=!1,p=x):p=e,y.eq(10))return null==e&&(u=!0),O(m,p);if(p+=10,m.precision=p,n=(r=b(v)).charAt(0),!(15e14>Math.abs(a=w(y))))return f=O(m,p+2,x).times(a+""),y=S(new m(n+"."+r.slice(1)),p-10).plus(f),m.precision=x,null==e?(u=!0,E(y,x)):y;for(;n<7&&1!=n||1==n&&r.charAt(1)>3;)n=(r=b((y=y.times(t)).d)).charAt(0),d++;for(a=w(y),n>1?(y=new m("0."+r),a++):y=new m(n+"."+r.slice(1)),s=l=y=g(y.minus(i),y.plus(i),p),h=E(y.times(y),p),o=3;;){if(l=E(l.times(h),p),b((f=s.plus(g(l,new m(o),p))).d).slice(0,p)===b(s.d).slice(0,p))return s=s.times(2),0!==a&&(s=s.plus(O(m,p+2,x).times(a+""))),s=g(s,new m(d),p),m.precision=x,null==e?(u=!0,E(s,x)):s;s=f,o+=2}}function P(t,e){var r,n,o;for((r=e.indexOf("."))>-1&&(e=e.replace(".","")),(n=e.search(/e/i))>0?(r<0&&(r=n),r+=+e.slice(n+1),e=e.substring(0,n)):r<0&&(r=e.length),n=0;48===e.charCodeAt(n);)++n;for(o=e.length;48===e.charCodeAt(o-1);)--o;if(e=e.slice(n,o)){if(o-=n,r=r-n-1,t.e=f(r/7),t.d=[],n=(r+1)%7,r<0&&(n+=7),nd||t.e<-d))throw Error(s+r)}else t.s=0,t.e=0,t.d=[0];return t}function E(t,e,r){var n,o,i,a,c,l,h,y,v=t.d;for(a=1,i=v[0];i>=10;i/=10)a++;if((n=e-a)<0)n+=7,o=e,h=v[y=0];else{if((y=Math.ceil((n+1)/7))>=(i=v.length))return t;for(a=1,h=i=v[y];i>=10;i/=10)a++;n%=7,o=n-7+a}if(void 0!==r&&(c=h/(i=p(10,a-o-1))%10|0,l=e<0||void 0!==v[y+1]||h%i,l=r<4?(c||l)&&(0==r||r==(t.s<0?3:2)):c>5||5==c&&(4==r||l||6==r&&(n>0?o>0?h/p(10,a-o):0:v[y-1])%10&1||r==(t.s<0?8:7))),e<1||!v[0])return l?(i=w(t),v.length=1,e=e-i-1,v[0]=p(10,(7-e%7)%7),t.e=f(-e/7)||0):(v.length=1,v[0]=t.e=t.s=0),t;if(0==n?(v.length=y,i=1,y--):(v.length=y+1,i=p(10,7-n),v[y]=o>0?(h/p(10,a-o)%p(10,o)|0)*i:0),l)for(;;){if(0==y){1e7==(v[0]+=i)&&(v[0]=1,++t.e);break}if(v[y]+=i,1e7!=v[y])break;v[y--]=0,i=1}for(n=v.length;0===v[--n];)v.pop();if(u&&(t.e>d||t.e<-d))throw Error(s+w(t));return t}function k(t,e){var r,n,o,i,a,c,l,s,f,p,h=t.constructor,d=h.precision;if(!t.s||!e.s)return e.s?e.s=-e.s:e=new h(t),u?E(e,d):e;if(l=t.d,p=e.d,n=e.e,s=t.e,l=l.slice(),a=s-n){for((f=a<0)?(r=l,a=-a,c=p.length):(r=p,n=s,c=l.length),a>(o=Math.max(Math.ceil(d/7),c)+2)&&(a=o,r.length=1),r.reverse(),o=a;o--;)r.push(0);r.reverse()}else{for((f=(o=l.length)<(c=p.length))&&(c=o),o=0;o0;--o)l[c++]=0;for(o=p.length;o>a;){if(l[--o]0?i=i.charAt(0)+"."+i.slice(1)+j(n):a>1&&(i=i.charAt(0)+"."+i.slice(1)),i=i+(o<0?"e":"e+")+o):o<0?(i="0."+j(-o-1)+i,r&&(n=r-a)>0&&(i+=j(n))):o>=a?(i+=j(o+1-a),r&&(n=r-o-1)>0&&(i=i+"."+j(n))):((n=o+1)0&&(o+1===a&&(i+="."),i+=j(n))),t.s<0?"-"+i:i}function M(t,e){if(t.length>e)return t.length=e,!0}function _(t){if(!t||"object"!=typeof t)throw Error(c+"Object expected");var e,r,n,o=["precision",1,1e9,"rounding",0,8,"toExpNeg",-1/0,0,"toExpPos",0,1/0];for(e=0;e=o[e+1]&&n<=o[e+2])this[r]=n;else throw Error(l+r+": "+n)}if(void 0!==(n=t[r="LN10"])){if(n==Math.LN10)this[r]=new this(n);else throw Error(l+r+": "+n)}return this}(a=function t(e){var r,n,o;function i(t){if(!(this instanceof i))return new i(t);if(this.constructor=i,t instanceof i){this.s=t.s,this.e=t.e,this.d=(t=t.d)?t.slice():t;return}if("number"==typeof t){if(0*t!=0)throw Error(l+t);if(t>0)this.s=1;else if(t<0)t=-t,this.s=-1;else{this.s=0,this.e=0,this.d=[0];return}if(t===~~t&&t<1e7){this.e=0,this.d=[t];return}return P(this,t.toString())}if("string"!=typeof t)throw Error(l+t);if(45===t.charCodeAt(0)?(t=t.slice(1),this.s=-1):this.s=1,h.test(t))P(this,t);else throw Error(l+t)}if(i.prototype=y,i.ROUND_UP=0,i.ROUND_DOWN=1,i.ROUND_CEIL=2,i.ROUND_FLOOR=3,i.ROUND_HALF_UP=4,i.ROUND_HALF_DOWN=5,i.ROUND_HALF_EVEN=6,i.ROUND_HALF_CEIL=7,i.ROUND_HALF_FLOOR=8,i.clone=t,i.config=i.set=_,void 0===e&&(e={}),e)for(r=0,o=["precision","rounding","toExpNeg","toExpPos","LN10"];r-1}},56883:function(t){t.exports=function(t,e,r){for(var n=-1,o=null==t?0:t.length;++n0&&i(s)?r>1?t(s,r-1,i,a,u):n(u,s):a||(u[u.length]=s)}return u}},63321:function(t,e,r){var n=r(33023)();t.exports=n},98060:function(t,e,r){var n=r(63321),o=r(43228);t.exports=function(t,e){return t&&n(t,e,o)}},92167:function(t,e,r){var n=r(67906),o=r(70235);t.exports=function(t,e){e=n(e,t);for(var r=0,i=e.length;null!=t&&re}},93012:function(t){t.exports=function(t,e){return null!=t&&e in Object(t)}},47909:function(t,e,r){var n=r(8235),o=r(31953),i=r(35281);t.exports=function(t,e,r){return e==e?i(t,e,r):n(t,o,r)}},90370:function(t,e,r){var n=r(54506),o=r(10303);t.exports=function(t){return o(t)&&"[object Arguments]"==n(t)}},56318:function(t,e,r){var n=r(6791),o=r(10303);t.exports=function t(e,r,i,a,u){return e===r||(null!=e&&null!=r&&(o(e)||o(r))?n(e,r,i,a,t,u):e!=e&&r!=r)}},6791:function(t,e,r){var n=r(85885),o=r(97638),i=r(88030),a=r(64974),u=r(81690),c=r(25614),l=r(98051),s=r(9792),f="[object Arguments]",p="[object Array]",h="[object Object]",d=Object.prototype.hasOwnProperty;t.exports=function(t,e,r,y,v,m){var b=c(t),g=c(e),x=b?p:u(t),w=g?p:u(e);x=x==f?h:x,w=w==f?h:w;var O=x==h,j=w==h,S=x==w;if(S&&l(t)){if(!l(e))return!1;b=!0,O=!1}if(S&&!O)return m||(m=new n),b||s(t)?o(t,e,r,y,v,m):i(t,e,x,r,y,v,m);if(!(1&r)){var P=O&&d.call(t,"__wrapped__"),E=j&&d.call(e,"__wrapped__");if(P||E){var k=P?t.value():t,A=E?e.value():e;return m||(m=new n),v(k,A,r,y,m)}}return!!S&&(m||(m=new n),a(t,e,r,y,v,m))}},62538:function(t,e,r){var n=r(85885),o=r(56318);t.exports=function(t,e,r,i){var a=r.length,u=a,c=!i;if(null==t)return!u;for(t=Object(t);a--;){var l=r[a];if(c&&l[2]?l[1]!==t[l[0]]:!(l[0]in t))return!1}for(;++ao?0:o+e),(r=r>o?o:r)<0&&(r+=o),o=e>r?0:r-e>>>0,e>>>=0;for(var i=Array(o);++n=200){var y=e?null:u(t);if(y)return c(y);p=!1,s=a,d=new n}else d=e?[]:h;t:for(;++l=o?t:n(t,e,r)}},1536:function(t,e,r){var n=r(78371);t.exports=function(t,e){if(t!==e){var r=void 0!==t,o=null===t,i=t==t,a=n(t),u=void 0!==e,c=null===e,l=e==e,s=n(e);if(!c&&!s&&!a&&t>e||a&&u&&l&&!c&&!s||o&&u&&l||!r&&l||!i)return 1;if(!o&&!a&&!s&&t=c)return l;return l*("desc"==r[o]?-1:1)}}return t.index-e.index}},92077:function(t,e,r){var n=r(74288)["__core-js_shared__"];t.exports=n},97930:function(t,e,r){var n=r(5629);t.exports=function(t,e){return function(r,o){if(null==r)return r;if(!n(r))return t(r,o);for(var i=r.length,a=e?i:-1,u=Object(r);(e?a--:++a-1?u[c?e[l]:l]:void 0}}},35464:function(t,e,r){var n=r(19608),o=r(49639),i=r(175);t.exports=function(t){return function(e,r,a){return a&&"number"!=typeof a&&o(e,r,a)&&(r=a=void 0),e=i(e),void 0===r?(r=e,e=0):r=i(r),a=void 0===a?es))return!1;var p=c.get(t),h=c.get(e);if(p&&h)return p==e&&h==t;var d=-1,y=!0,v=2&r?new n:void 0;for(c.set(t,e),c.set(e,t);++d-1&&t%1==0&&t-1}},13368:function(t,e,r){var n=r(24457);t.exports=function(t,e){var r=this.__data__,o=n(r,t);return o<0?(++this.size,r.push([t,e])):r[o][1]=e,this}},38764:function(t,e,r){var n=r(9855),o=r(99078),i=r(88675);t.exports=function(){this.size=0,this.__data__={hash:new n,map:new(i||o),string:new n}}},78615:function(t,e,r){var n=r(1507);t.exports=function(t){var e=n(this,t).delete(t);return this.size-=e?1:0,e}},83391:function(t,e,r){var n=r(1507);t.exports=function(t){return n(this,t).get(t)}},53483:function(t,e,r){var n=r(1507);t.exports=function(t){return n(this,t).has(t)}},74724:function(t,e,r){var n=r(1507);t.exports=function(t,e){var r=n(this,t),o=r.size;return r.set(t,e),this.size+=r.size==o?0:1,this}},22523:function(t){t.exports=function(t){var e=-1,r=Array(t.size);return t.forEach(function(t,n){r[++e]=[n,t]}),r}},47073:function(t){t.exports=function(t,e){return function(r){return null!=r&&r[t]===e&&(void 0!==e||t in Object(r))}}},23787:function(t,e,r){var n=r(50967);t.exports=function(t){var e=n(t,function(t){return 500===r.size&&r.clear(),t}),r=e.cache;return e}},20453:function(t,e,r){var n=r(39866)(Object,"create");t.exports=n},77184:function(t,e,r){var n=r(45070)(Object.keys,Object);t.exports=n},39931:function(t,e,r){t=r.nmd(t);var n=r(17071),o=e&&!e.nodeType&&e,i=o&&t&&!t.nodeType&&t,a=i&&i.exports===o&&n.process,u=function(){try{var t=i&&i.require&&i.require("util").types;if(t)return t;return a&&a.binding&&a.binding("util")}catch(t){}}();t.exports=u},45070:function(t){t.exports=function(t,e){return function(r){return t(e(r))}}},49478:function(t,e,r){var n=r(60493),o=Math.max;t.exports=function(t,e,r){return e=o(void 0===e?t.length-1:e,0),function(){for(var i=arguments,a=-1,u=o(i.length-e,0),c=Array(u);++a0){if(++r>=800)return arguments[0]}else r=0;return t.apply(void 0,arguments)}}},84092:function(t,e,r){var n=r(99078);t.exports=function(){this.__data__=new n,this.size=0}},31663:function(t){t.exports=function(t){var e=this.__data__,r=e.delete(t);return this.size=e.size,r}},69135:function(t){t.exports=function(t){return this.__data__.get(t)}},39552:function(t){t.exports=function(t){return this.__data__.has(t)}},63960:function(t,e,r){var n=r(99078),o=r(88675),i=r(76219);t.exports=function(t,e){var r=this.__data__;if(r instanceof n){var a=r.__data__;if(!o||a.length<199)return a.push([t,e]),this.size=++r.size,this;r=this.__data__=new i(a)}return r.set(t,e),this.size=r.size,this}},35281:function(t){t.exports=function(t,e,r){for(var n=r-1,o=t.length;++n-1&&t%1==0&&t<=9007199254740991}},82559:function(t,e,r){var n=r(22345);t.exports=function(t){return n(t)&&t!=+t}},77571:function(t){t.exports=function(t){return null==t}},22345:function(t,e,r){var n=r(54506),o=r(10303);t.exports=function(t){return"number"==typeof t||o(t)&&"[object Number]"==n(t)}},90231:function(t,e,r){var n=r(54506),o=r(62602),i=r(10303),a=Object.prototype,u=Function.prototype.toString,c=a.hasOwnProperty,l=u.call(Object);t.exports=function(t){if(!i(t)||"[object Object]"!=n(t))return!1;var e=o(t);if(null===e)return!0;var r=c.call(e,"constructor")&&e.constructor;return"function"==typeof r&&r instanceof r&&u.call(r)==l}},42715:function(t,e,r){var n=r(54506),o=r(25614),i=r(10303);t.exports=function(t){return"string"==typeof t||!o(t)&&i(t)&&"[object String]"==n(t)}},9792:function(t,e,r){var n=r(59332),o=r(23305),i=r(39931),a=i&&i.isTypedArray,u=a?o(a):n;t.exports=u},43228:function(t,e,r){var n=r(28579),o=r(4578),i=r(5629);t.exports=function(t){return i(t)?n(t):o(t)}},86185:function(t){t.exports=function(t){var e=null==t?0:t.length;return e?t[e-1]:void 0}},89238:function(t,e,r){var n=r(73819),o=r(88157),i=r(24240),a=r(25614);t.exports=function(t,e){return(a(t)?n:i)(t,o(e,3))}},41443:function(t,e,r){var n=r(83023),o=r(98060),i=r(88157);t.exports=function(t,e){var r={};return e=i(e,3),o(t,function(t,o,i){n(r,o,e(t,o,i))}),r}},95645:function(t,e,r){var n=r(67646),o=r(58905),i=r(79586);t.exports=function(t){return t&&t.length?n(t,i,o):void 0}},50967:function(t,e,r){var n=r(76219);function o(t,e){if("function"!=typeof t||null!=e&&"function"!=typeof e)throw TypeError("Expected a function");var r=function(){var n=arguments,o=e?e.apply(this,n):n[0],i=r.cache;if(i.has(o))return i.get(o);var a=t.apply(this,n);return r.cache=i.set(o,a)||i,a};return r.cache=new(o.Cache||n),r}o.Cache=n,t.exports=o},99008:function(t,e,r){var n=r(67646),o=r(20121),i=r(79586);t.exports=function(t){return t&&t.length?n(t,i,o):void 0}},93810:function(t){t.exports=function(){}},22350:function(t,e,r){var n=r(18155),o=r(73584),i=r(67352),a=r(70235);t.exports=function(t){return i(t)?n(a(t)):o(t)}},99676:function(t,e,r){var n=r(35464)();t.exports=n},33645:function(t,e,r){var n=r(25253),o=r(88157),i=r(12327),a=r(25614),u=r(49639);t.exports=function(t,e,r){var c=a(t)?n:i;return r&&u(t,e,r)&&(e=void 0),c(t,o(e,3))}},34935:function(t,e,r){var n=r(72569),o=r(84046),i=r(44843),a=r(49639),u=i(function(t,e){if(null==t)return[];var r=e.length;return r>1&&a(t,e[0],e[1])?e=[]:r>2&&a(e[0],e[1],e[2])&&(e=[e[0]]),o(t,n(e,1),[])});t.exports=u},55716:function(t){t.exports=function(){return[]}},7406:function(t){t.exports=function(){return!1}},37065:function(t,e,r){var n=r(7310),o=r(28302);t.exports=function(t,e,r){var i=!0,a=!0;if("function"!=typeof t)throw TypeError("Expected a function");return o(r)&&(i="leading"in r?!!r.leading:i,a="trailing"in r?!!r.trailing:a),n(t,e,{leading:i,maxWait:e,trailing:a})}},175:function(t,e,r){var n=r(6660),o=1/0;t.exports=function(t){return t?(t=n(t))===o||t===-o?(t<0?-1:1)*17976931348623157e292:t==t?t:0:0===t?t:0}},85759:function(t,e,r){var n=r(175);t.exports=function(t){var e=n(t),r=e%1;return e==e?r?e-r:e:0}},3641:function(t,e,r){var n=r(65020);t.exports=function(t){return null==t?"":n(t)}},47230:function(t,e,r){var n=r(88157),o=r(13826);t.exports=function(t,e){return t&&t.length?o(t,n(e,2)):[]}},75551:function(t,e,r){var n=r(80675)("toUpperCase");t.exports=n},48049:function(t,e,r){"use strict";var n=r(14397);function o(){}function i(){}i.resetWarningCache=o,t.exports=function(){function t(t,e,r,o,i,a){if(a!==n){var u=Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw u.name="Invariant Violation",u}}function e(){return t}t.isRequired=t;var r={array:t,bigint:t,bool:t,func:t,number:t,object:t,string:t,symbol:t,any:t,arrayOf:e,element:t,elementType:t,instanceOf:e,node:t,objectOf:e,oneOf:e,oneOfType:e,shape:e,exact:e,checkPropTypes:i,resetWarningCache:o};return r.PropTypes=r,r}},40718:function(t,e,r){t.exports=r(48049)()},14397:function(t){"use strict";t.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},84735:function(t,e,r){"use strict";r.d(e,{ZP:function(){return tS}});var n=r(2265),o=r(40718),i=r.n(o),a=Object.getOwnPropertyNames,u=Object.getOwnPropertySymbols,c=Object.prototype.hasOwnProperty;function l(t,e){return function(r,n,o){return t(r,n,o)&&e(r,n,o)}}function s(t){return function(e,r,n){if(!e||!r||"object"!=typeof e||"object"!=typeof r)return t(e,r,n);var o=n.cache,i=o.get(e),a=o.get(r);if(i&&a)return i===r&&a===e;o.set(e,r),o.set(r,e);var u=t(e,r,n);return o.delete(e),o.delete(r),u}}function f(t){return a(t).concat(u(t))}var p=Object.hasOwn||function(t,e){return c.call(t,e)};function h(t,e){return t===e||!t&&!e&&t!=t&&e!=e}var d=Object.getOwnPropertyDescriptor,y=Object.keys;function v(t,e,r){var n=t.length;if(e.length!==n)return!1;for(;n-- >0;)if(!r.equals(t[n],e[n],n,n,t,e,r))return!1;return!0}function m(t,e){return h(t.getTime(),e.getTime())}function b(t,e){return t.name===e.name&&t.message===e.message&&t.cause===e.cause&&t.stack===e.stack}function g(t,e){return t===e}function x(t,e,r){var n,o,i=t.size;if(i!==e.size)return!1;if(!i)return!0;for(var a=Array(i),u=t.entries(),c=0;(n=u.next())&&!n.done;){for(var l=e.entries(),s=!1,f=0;(o=l.next())&&!o.done;){if(a[f]){f++;continue}var p=n.value,h=o.value;if(r.equals(p[0],h[0],c,f,t,e,r)&&r.equals(p[1],h[1],p[0],h[0],t,e,r)){s=a[f]=!0;break}f++}if(!s)return!1;c++}return!0}function w(t,e,r){var n=y(t),o=n.length;if(y(e).length!==o)return!1;for(;o-- >0;)if(!A(t,e,r,n[o]))return!1;return!0}function O(t,e,r){var n,o,i,a=f(t),u=a.length;if(f(e).length!==u)return!1;for(;u-- >0;)if(!A(t,e,r,n=a[u])||(o=d(t,n),i=d(e,n),(o||i)&&(!o||!i||o.configurable!==i.configurable||o.enumerable!==i.enumerable||o.writable!==i.writable)))return!1;return!0}function j(t,e){return h(t.valueOf(),e.valueOf())}function S(t,e){return t.source===e.source&&t.flags===e.flags}function P(t,e,r){var n,o,i=t.size;if(i!==e.size)return!1;if(!i)return!0;for(var a=Array(i),u=t.values();(n=u.next())&&!n.done;){for(var c=e.values(),l=!1,s=0;(o=c.next())&&!o.done;){if(!a[s]&&r.equals(n.value,o.value,n.value,o.value,t,e,r)){l=a[s]=!0;break}s++}if(!l)return!1}return!0}function E(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}function k(t,e){return t.hostname===e.hostname&&t.pathname===e.pathname&&t.protocol===e.protocol&&t.port===e.port&&t.hash===e.hash&&t.username===e.username&&t.password===e.password}function A(t,e,r,n){return("_owner"===n||"__o"===n||"__v"===n)&&(!!t.$$typeof||!!e.$$typeof)||p(e,n)&&r.equals(t[n],e[n],n,n,t,e,r)}var M=Array.isArray,_="undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView:null,T=Object.assign,C=Object.prototype.toString.call.bind(Object.prototype.toString),N=D();function D(t){void 0===t&&(t={});var e,r,n,o,i,a,u,c,f,p,d,y,A,N,D=t.circular,I=t.createInternalComparator,L=t.createState,B=t.strict,R=(r=(e=function(t){var e=t.circular,r=t.createCustomConfig,n=t.strict,o={areArraysEqual:n?O:v,areDatesEqual:m,areErrorsEqual:b,areFunctionsEqual:g,areMapsEqual:n?l(x,O):x,areNumbersEqual:h,areObjectsEqual:n?O:w,arePrimitiveWrappersEqual:j,areRegExpsEqual:S,areSetsEqual:n?l(P,O):P,areTypedArraysEqual:n?O:E,areUrlsEqual:k,unknownTagComparators:void 0};if(r&&(o=T({},o,r(o))),e){var i=s(o.areArraysEqual),a=s(o.areMapsEqual),u=s(o.areObjectsEqual),c=s(o.areSetsEqual);o=T({},o,{areArraysEqual:i,areMapsEqual:a,areObjectsEqual:u,areSetsEqual:c})}return o}(t)).areArraysEqual,n=e.areDatesEqual,o=e.areErrorsEqual,i=e.areFunctionsEqual,a=e.areMapsEqual,u=e.areNumbersEqual,c=e.areObjectsEqual,f=e.arePrimitiveWrappersEqual,p=e.areRegExpsEqual,d=e.areSetsEqual,y=e.areTypedArraysEqual,A=e.areUrlsEqual,N=e.unknownTagComparators,function(t,e,l){if(t===e)return!0;if(null==t||null==e)return!1;var s=typeof t;if(s!==typeof e)return!1;if("object"!==s)return"number"===s?u(t,e,l):"function"===s&&i(t,e,l);var h=t.constructor;if(h!==e.constructor)return!1;if(h===Object)return c(t,e,l);if(M(t))return r(t,e,l);if(null!=_&&_(t))return y(t,e,l);if(h===Date)return n(t,e,l);if(h===RegExp)return p(t,e,l);if(h===Map)return a(t,e,l);if(h===Set)return d(t,e,l);var v=C(t);if("[object Date]"===v)return n(t,e,l);if("[object RegExp]"===v)return p(t,e,l);if("[object Map]"===v)return a(t,e,l);if("[object Set]"===v)return d(t,e,l);if("[object Object]"===v)return"function"!=typeof t.then&&"function"!=typeof e.then&&c(t,e,l);if("[object URL]"===v)return A(t,e,l);if("[object Error]"===v)return o(t,e,l);if("[object Arguments]"===v)return c(t,e,l);if("[object Boolean]"===v||"[object Number]"===v||"[object String]"===v)return f(t,e,l);if(N){var m=N[v];if(!m){var b=null!=t?t[Symbol.toStringTag]:void 0;b&&(m=N[b])}if(m)return m(t,e,l)}return!1}),z=I?I(R):function(t,e,r,n,o,i,a){return R(t,e,a)};return function(t){var e=t.circular,r=t.comparator,n=t.createState,o=t.equals,i=t.strict;if(n)return function(t,a){var u=n(),c=u.cache;return r(t,a,{cache:void 0===c?e?new WeakMap:void 0:c,equals:o,meta:u.meta,strict:i})};if(e)return function(t,e){return r(t,e,{cache:new WeakMap,equals:o,meta:void 0,strict:i})};var a={cache:void 0,equals:o,meta:void 0,strict:i};return function(t,e){return r(t,e,a)}}({circular:void 0!==D&&D,comparator:R,createState:L,equals:z,strict:void 0!==B&&B})}function I(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r=-1;requestAnimationFrame(function n(o){if(r<0&&(r=o),o-r>e)t(o),r=-1;else{var i;i=n,"undefined"!=typeof requestAnimationFrame&&requestAnimationFrame(i)}})}function L(t){return(L="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function B(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);rt.length)&&(e=t.length);for(var r=0,n=Array(e);r=0&&t<=1}),"[configBezier]: arguments should be x1, y1, x2, y2 of [0, 1] instead received %s",n);var p=V(i,u),h=V(a,c),d=(t=i,e=u,function(r){var n;return G([].concat(function(t){if(Array.isArray(t))return H(t)}(n=X(t,e).map(function(t,e){return t*e}).slice(1))||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(n)||Y(n)||function(){throw TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(),[0]),r)}),y=function(t){for(var e=t>1?1:t,r=e,n=0;n<8;++n){var o,i=p(r)-e,a=d(r);if(1e-4>Math.abs(i-e)||a<1e-4)break;r=(o=r-i/a)>1?1:o<0?0:o}return h(r)};return y.isStepper=!1,y},Q=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.stiff,r=void 0===e?100:e,n=t.damping,o=void 0===n?8:n,i=t.dt,a=void 0===i?17:i,u=function(t,e,n){var i=n+(-(t-e)*r-n*o)*a/1e3,u=n*a/1e3+t;return 1e-4>Math.abs(u-e)&&1e-4>Math.abs(i)?[e,0]:[u,i]};return u.isStepper=!0,u.dt=a,u},J=function(){for(var t=arguments.length,e=Array(t),r=0;rt.length)&&(e=t.length);for(var r=0,n=Array(e);rt.length)&&(e=t.length);for(var r=0,n=Array(e);r0?r[o-1]:n,p=l||Object.keys(c);if("function"==typeof u||"spring"===u)return[].concat(th(t),[e.runJSAnimation.bind(e,{from:f.style,to:c,duration:i,easing:u}),i]);var h=Z(p,i,u),d=tv(tv(tv({},f.style),c),{},{transition:h});return[].concat(th(t),[d,i,s]).filter($)},[a,Math.max(void 0===u?0:u,n)])),[t.onAnimationEnd]))}},{key:"runAnimation",value:function(t){if(!this.manager){var e,r,n;this.manager=(e=function(){return null},r=!1,n=function t(n){if(!r){if(Array.isArray(n)){if(!n.length)return;var o=function(t){if(Array.isArray(t))return t}(n)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(n)||function(t,e){if(t){if("string"==typeof t)return B(t,void 0);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return B(t,void 0)}}(n)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(),i=o[0],a=o.slice(1);if("number"==typeof i){I(t.bind(null,a),i);return}t(i),I(t.bind(null,a));return}"object"===L(n)&&e(n),"function"==typeof n&&n()}},{stop:function(){r=!0},start:function(t){r=!1,n(t)},subscribe:function(t){return e=t,function(){e=function(){return null}}}})}var o=t.begin,i=t.duration,a=t.attributeName,u=t.to,c=t.easing,l=t.onAnimationStart,s=t.onAnimationEnd,f=t.steps,p=t.children,h=this.manager;if(this.unSubscribe=h.subscribe(this.handleStyleChange),"function"==typeof c||"function"==typeof p||"spring"===c){this.runJSAnimation(t);return}if(f.length>1){this.runStepAnimation(t);return}var d=a?tm({},a,u):u,y=Z(Object.keys(d),i,c);h.start([l,o,tv(tv({},d),{},{transition:y}),i,s])}},{key:"render",value:function(){var t=this.props,e=t.children,r=(t.begin,t.duration),o=(t.attributeName,t.easing,t.isActive),i=(t.steps,t.from,t.to,t.canBegin,t.onAnimationEnd,t.shouldReAnimate,t.onAnimationReStart,function(t,e){if(null==t)return{};var r,n,o=function(t,e){if(null==t)return{};var r,n,o={},i=Object.keys(t);for(n=0;n=0||(o[r]=t[r]);return o}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(t,tp)),a=n.Children.count(e),u=this.state.style;if("function"==typeof e)return e(u);if(!o||0===a||r<=0)return e;var c=function(t){var e=t.props,r=e.style,o=e.className;return(0,n.cloneElement)(t,tv(tv({},i),{},{style:tv(tv({},void 0===r?{}:r),u),className:o}))};return 1===a?c(n.Children.only(e)):n.createElement("div",null,n.Children.map(e,function(t){return c(t)}))}}],function(t,e){for(var r=0;r=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(t,w),i=parseInt("".concat(r),10),a=parseInt("".concat(n),10),u=parseInt("".concat(e.height||o.height),10),c=parseInt("".concat(e.width||o.width),10);return P(P(P(P(P({},e),o),i?{x:i}:{}),a?{y:a}:{}),{},{height:u,width:c,name:e.name,radius:e.radius})}function k(t){return n.createElement(x.bn,j({shapeType:"rectangle",propTransformer:E,activeClassName:"recharts-active-bar"},t))}var A=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return function(r,n){if("number"==typeof t)return t;var o=(0,d.hj)(r)||(0,d.Rw)(r);return o?t(r,n):(o||(0,g.Z)(!1),e)}},M=["value","background"];function _(t){return(_="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function T(){return(T=Object.assign?Object.assign.bind():function(t){for(var e=1;e=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(e,M);if(!u)return null;var l=N(N(N(N(N({},c),{},{fill:"#eee"},u),a),(0,b.bw)(t.props,e,r)),{},{onAnimationStart:t.handleAnimationStart,onAnimationEnd:t.handleAnimationEnd,dataKey:o,index:r,className:"recharts-bar-background-rectangle"});return n.createElement(k,T({key:"background-bar-".concat(r),option:t.props.background,isActive:r===i},l))})}},{key:"renderErrorBar",value:function(t,e){if(this.props.isAnimationActive&&!this.state.isAnimationFinished)return null;var r=this.props,o=r.data,i=r.xAxis,a=r.yAxis,u=r.layout,c=r.children,l=(0,y.NN)(c,f.W);if(!l)return null;var p="vertical"===u?o[0].height/2:o[0].width/2,h=function(t,e){var r=Array.isArray(t.value)?t.value[1]:t.value;return{x:t.x,y:t.y,value:r,errorVal:(0,m.F$)(t,e)}};return n.createElement(s.m,{clipPath:t?"url(#clipPath-".concat(e,")"):null},l.map(function(t){return n.cloneElement(t,{key:"error-bar-".concat(e,"-").concat(t.props.dataKey),data:o,xAxis:i,yAxis:a,layout:u,offset:p,dataPointFormatter:h})}))}},{key:"render",value:function(){var t=this.props,e=t.hide,r=t.data,i=t.className,a=t.xAxis,u=t.yAxis,c=t.left,f=t.top,p=t.width,d=t.height,y=t.isAnimationActive,v=t.background,m=t.id;if(e||!r||!r.length)return null;var b=this.state.isAnimationFinished,g=(0,o.Z)("recharts-bar",i),x=a&&a.allowDataOverflow,w=u&&u.allowDataOverflow,O=x||w,j=l()(m)?this.id:m;return n.createElement(s.m,{className:g},x||w?n.createElement("defs",null,n.createElement("clipPath",{id:"clipPath-".concat(j)},n.createElement("rect",{x:x?c:c-p/2,y:w?f:f-d/2,width:x?p:2*p,height:w?d:2*d}))):null,n.createElement(s.m,{className:"recharts-bar-rectangles",clipPath:O?"url(#clipPath-".concat(j,")"):null},v?this.renderBackground():null,this.renderRectangles()),this.renderErrorBar(O,j),(!y||b)&&h.e.renderCallByParent(this.props,r))}}],r=[{key:"getDerivedStateFromProps",value:function(t,e){return t.animationId!==e.prevAnimationId?{prevAnimationId:t.animationId,curData:t.data,prevData:e.curData}:t.data!==e.curData?{curData:t.data}:null}}],e&&D(a.prototype,e),r&&D(a,r),Object.defineProperty(a,"prototype",{writable:!1}),a}(n.PureComponent);R(U,"displayName","Bar"),R(U,"defaultProps",{xAxisId:0,yAxisId:0,legendType:"rect",minPointSize:0,hide:!1,data:[],layout:"vertical",activeBar:!1,isAnimationActive:!v.x.isSsr,animationBegin:0,animationDuration:400,animationEasing:"ease"}),R(U,"getComposedData",function(t){var e=t.props,r=t.item,n=t.barPosition,o=t.bandSize,i=t.xAxis,a=t.yAxis,u=t.xAxisTicks,c=t.yAxisTicks,l=t.stackedData,s=t.dataStartIndex,f=t.displayedData,h=t.offset,v=(0,m.Bu)(n,r);if(!v)return null;var b=e.layout,g=r.type.defaultProps,x=void 0!==g?N(N({},g),r.props):r.props,w=x.dataKey,O=x.children,j=x.minPointSize,S="horizontal"===b?a:i,P=l?S.scale.domain():null,E=(0,m.Yj)({numericAxis:S}),k=(0,y.NN)(O,p.b),M=f.map(function(t,e){l?f=(0,m.Vv)(l[s+e],P):Array.isArray(f=(0,m.F$)(t,w))||(f=[E,f]);var n=A(j,U.defaultProps.minPointSize)(f[1],e);if("horizontal"===b){var f,p,h,y,g,x,O,S=[a.scale(f[0]),a.scale(f[1])],M=S[0],_=S[1];p=(0,m.Fy)({axis:i,ticks:u,bandSize:o,offset:v.offset,entry:t,index:e}),h=null!==(O=null!=_?_:M)&&void 0!==O?O:void 0,y=v.size;var T=M-_;if(g=Number.isNaN(T)?0:T,x={x:p,y:a.y,width:y,height:a.height},Math.abs(n)>0&&Math.abs(g)0&&Math.abs(y)=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}function P(t,e){for(var r=0;r0?this.props:d)),o<=0||a<=0||!y||!y.length)?null:n.createElement(s.m,{className:(0,c.Z)("recharts-cartesian-axis",l),ref:function(e){t.layerReference=e}},r&&this.renderAxisLine(),this.renderTicks(y,this.state.fontSize,this.state.letterSpacing),p._.renderCallByParent(this.props))}}],r=[{key:"renderTickItem",value:function(t,e,r){var o=(0,c.Z)(e.className,"recharts-cartesian-axis-tick-value");return n.isValidElement(t)?n.cloneElement(t,j(j({},e),{},{className:o})):i()(t)?t(j(j({},e),{},{className:o})):n.createElement(f.x,w({},e,{className:"recharts-cartesian-axis-tick-value"}),r)}}],e&&P(o.prototype,e),r&&P(o,r),Object.defineProperty(o,"prototype",{writable:!1}),o}(n.Component);M(T,"displayName","CartesianAxis"),M(T,"defaultProps",{x:0,y:0,width:0,height:0,viewBox:{x:0,y:0,width:0,height:0},orientation:"bottom",ticks:[],stroke:"#666",tickLine:!0,axisLine:!0,tick:!0,mirror:!1,minTickGap:5,tickSize:6,tickMargin:2,interval:"preserveEnd"})},56940:function(t,e,r){"use strict";r.d(e,{q:function(){return M}});var n=r(2265),o=r(86757),i=r.n(o),a=r(1175),u=r(16630),c=r(82944),l=r(85355),s=r(78242),f=r(80285),p=r(25739),h=["x1","y1","x2","y2","key"],d=["offset"];function y(t){return(y="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function v(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,n)}return r}function m(t){for(var e=1;e=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}var x=function(t){var e=t.fill;if(!e||"none"===e)return null;var r=t.fillOpacity,o=t.x,i=t.y,a=t.width,u=t.height,c=t.ry;return n.createElement("rect",{x:o,y:i,ry:c,width:a,height:u,stroke:"none",fill:e,fillOpacity:r,className:"recharts-cartesian-grid-bg"})};function w(t,e){var r;if(n.isValidElement(t))r=n.cloneElement(t,e);else if(i()(t))r=t(e);else{var o=e.x1,a=e.y1,u=e.x2,l=e.y2,s=e.key,f=g(e,h),p=(0,c.L6)(f,!1),y=(p.offset,g(p,d));r=n.createElement("line",b({},y,{x1:o,y1:a,x2:u,y2:l,fill:"none",key:s}))}return r}function O(t){var e=t.x,r=t.width,o=t.horizontal,i=void 0===o||o,a=t.horizontalPoints;if(!i||!a||!a.length)return null;var u=a.map(function(n,o){return w(i,m(m({},t),{},{x1:e,y1:n,x2:e+r,y2:n,key:"line-".concat(o),index:o}))});return n.createElement("g",{className:"recharts-cartesian-grid-horizontal"},u)}function j(t){var e=t.y,r=t.height,o=t.vertical,i=void 0===o||o,a=t.verticalPoints;if(!i||!a||!a.length)return null;var u=a.map(function(n,o){return w(i,m(m({},t),{},{x1:n,y1:e,x2:n,y2:e+r,key:"line-".concat(o),index:o}))});return n.createElement("g",{className:"recharts-cartesian-grid-vertical"},u)}function S(t){var e=t.horizontalFill,r=t.fillOpacity,o=t.x,i=t.y,a=t.width,u=t.height,c=t.horizontalPoints,l=t.horizontal;if(!(void 0===l||l)||!e||!e.length)return null;var s=c.map(function(t){return Math.round(t+i-i)}).sort(function(t,e){return t-e});i!==s[0]&&s.unshift(0);var f=s.map(function(t,c){var l=s[c+1]?s[c+1]-t:i+u-t;if(l<=0)return null;var f=c%e.length;return n.createElement("rect",{key:"react-".concat(c),y:t,x:o,height:l,width:a,stroke:"none",fill:e[f],fillOpacity:r,className:"recharts-cartesian-grid-bg"})});return n.createElement("g",{className:"recharts-cartesian-gridstripes-horizontal"},f)}function P(t){var e=t.vertical,r=t.verticalFill,o=t.fillOpacity,i=t.x,a=t.y,u=t.width,c=t.height,l=t.verticalPoints;if(!(void 0===e||e)||!r||!r.length)return null;var s=l.map(function(t){return Math.round(t+i-i)}).sort(function(t,e){return t-e});i!==s[0]&&s.unshift(0);var f=s.map(function(t,e){var l=s[e+1]?s[e+1]-t:i+u-t;if(l<=0)return null;var f=e%r.length;return n.createElement("rect",{key:"react-".concat(e),x:t,y:a,width:l,height:c,stroke:"none",fill:r[f],fillOpacity:o,className:"recharts-cartesian-grid-bg"})});return n.createElement("g",{className:"recharts-cartesian-gridstripes-vertical"},f)}var E=function(t,e){var r=t.xAxis,n=t.width,o=t.height,i=t.offset;return(0,l.Rf)((0,s.f)(m(m(m({},f.O.defaultProps),r),{},{ticks:(0,l.uY)(r,!0),viewBox:{x:0,y:0,width:n,height:o}})),i.left,i.left+i.width,e)},k=function(t,e){var r=t.yAxis,n=t.width,o=t.height,i=t.offset;return(0,l.Rf)((0,s.f)(m(m(m({},f.O.defaultProps),r),{},{ticks:(0,l.uY)(r,!0),viewBox:{x:0,y:0,width:n,height:o}})),i.top,i.top+i.height,e)},A={horizontal:!0,vertical:!0,stroke:"#ccc",fill:"none",verticalFill:[],horizontalFill:[]};function M(t){var e,r,o,c,l,s,f=(0,p.zn)(),h=(0,p.Mw)(),d=(0,p.qD)(),v=m(m({},t),{},{stroke:null!==(e=t.stroke)&&void 0!==e?e:A.stroke,fill:null!==(r=t.fill)&&void 0!==r?r:A.fill,horizontal:null!==(o=t.horizontal)&&void 0!==o?o:A.horizontal,horizontalFill:null!==(c=t.horizontalFill)&&void 0!==c?c:A.horizontalFill,vertical:null!==(l=t.vertical)&&void 0!==l?l:A.vertical,verticalFill:null!==(s=t.verticalFill)&&void 0!==s?s:A.verticalFill,x:(0,u.hj)(t.x)?t.x:d.left,y:(0,u.hj)(t.y)?t.y:d.top,width:(0,u.hj)(t.width)?t.width:d.width,height:(0,u.hj)(t.height)?t.height:d.height}),g=v.x,w=v.y,M=v.width,_=v.height,T=v.syncWithTicks,C=v.horizontalValues,N=v.verticalValues,D=(0,p.CW)(),I=(0,p.Nf)();if(!(0,u.hj)(M)||M<=0||!(0,u.hj)(_)||_<=0||!(0,u.hj)(g)||g!==+g||!(0,u.hj)(w)||w!==+w)return null;var L=v.verticalCoordinatesGenerator||E,B=v.horizontalCoordinatesGenerator||k,R=v.horizontalPoints,z=v.verticalPoints;if((!R||!R.length)&&i()(B)){var U=C&&C.length,F=B({yAxis:I?m(m({},I),{},{ticks:U?C:I.ticks}):void 0,width:f,height:h,offset:d},!!U||T);(0,a.Z)(Array.isArray(F),"horizontalCoordinatesGenerator should return Array but instead it returned [".concat(y(F),"]")),Array.isArray(F)&&(R=F)}if((!z||!z.length)&&i()(L)){var $=N&&N.length,q=L({xAxis:D?m(m({},D),{},{ticks:$?N:D.ticks}):void 0,width:f,height:h,offset:d},!!$||T);(0,a.Z)(Array.isArray(q),"verticalCoordinatesGenerator should return Array but instead it returned [".concat(y(q),"]")),Array.isArray(q)&&(z=q)}return n.createElement("g",{className:"recharts-cartesian-grid"},n.createElement(x,{fill:v.fill,fillOpacity:v.fillOpacity,x:v.x,y:v.y,width:v.width,height:v.height,ry:v.ry}),n.createElement(O,b({},v,{offset:d,horizontalPoints:R,xAxis:D,yAxis:I})),n.createElement(j,b({},v,{offset:d,verticalPoints:z,xAxis:D,yAxis:I})),n.createElement(S,b({},v,{horizontalPoints:R})),n.createElement(P,b({},v,{verticalPoints:z})))}M.displayName="CartesianGrid"},13137:function(t,e,r){"use strict";r.d(e,{W:function(){return v}});var n=r(2265),o=r(69398),i=r(9841),a=r(82944),u=["offset","layout","width","dataKey","data","dataPointFormatter","xAxis","yAxis"];function c(t){return(c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function l(){return(l=Object.assign?Object.assign.bind():function(t){for(var e=1;et.length)&&(e=t.length);for(var r=0,n=Array(e);r=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(t,u),m=(0,a.L6)(v,!1);"x"===this.props.direction&&"number"!==d.type&&(0,o.Z)(!1);var b=p.map(function(t){var o,a,u=h(t,f),p=u.x,v=u.y,b=u.value,g=u.errorVal;if(!g)return null;var x=[];if(Array.isArray(g)){var w=function(t){if(Array.isArray(t))return t}(g)||function(t,e){var r=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=r){var n,o,i,a,u=[],c=!0,l=!1;try{for(i=(r=r.call(t)).next;!(c=(n=i.call(r)).done)&&(u.push(n.value),2!==u.length);c=!0);}catch(t){l=!0,o=t}finally{try{if(!c&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(l)throw o}}return u}}(g,2)||function(t,e){if(t){if("string"==typeof t)return s(t,2);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return s(t,2)}}(g,2)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}();o=w[0],a=w[1]}else o=a=g;if("vertical"===r){var O=d.scale,j=v+e,S=j+c,P=j-c,E=O(b-o),k=O(b+a);x.push({x1:k,y1:S,x2:k,y2:P}),x.push({x1:E,y1:j,x2:k,y2:j}),x.push({x1:E,y1:S,x2:E,y2:P})}else if("horizontal"===r){var A=y.scale,M=p+e,_=M-c,T=M+c,C=A(b-o),N=A(b+a);x.push({x1:_,y1:N,x2:T,y2:N}),x.push({x1:M,y1:C,x2:M,y2:N}),x.push({x1:_,y1:C,x2:T,y2:C})}return n.createElement(i.m,l({className:"recharts-errorBar",key:"bar-".concat(x.map(function(t){return"".concat(t.x1,"-").concat(t.x2,"-").concat(t.y1,"-").concat(t.y2)}))},m),x.map(function(t){return n.createElement("line",l({},t,{key:"line-".concat(t.x1,"-").concat(t.x2,"-").concat(t.y1,"-").concat(t.y2)}))}))});return n.createElement(i.m,{className:"recharts-errorBars"},b)}}],function(t,e){for(var r=0;rt*o)return!1;var i=r();return t*(e-t*i/2-n)>=0&&t*(e+t*i/2-o)<=0}function f(t){return(f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function p(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,n)}return r}function h(t){for(var e=1;e=2?(0,i.uY)(m[1].coordinate-m[0].coordinate):1,M=(n="width"===P,f=b.x,p=b.y,d=b.width,y=b.height,1===A?{start:n?f:p,end:n?f+d:p+y}:{start:n?f+d:p+y,end:n?f:p});return"equidistantPreserveStart"===w?function(t,e,r,n,o){for(var i,a=(n||[]).slice(),u=e.start,c=e.end,f=0,p=1,h=u;p<=a.length;)if(i=function(){var e,i=null==n?void 0:n[f];if(void 0===i)return{v:l(n,p)};var a=f,d=function(){return void 0===e&&(e=r(i,a)),e},y=i.coordinate,v=0===f||s(t,y,d,h,c);v||(f=0,h=u,p+=1),v&&(h=y+t*(d()/2+o),f+=p)}())return i.v;return[]}(A,M,k,m,g):("preserveStart"===w||"preserveStartEnd"===w?function(t,e,r,n,o,i){var a=(n||[]).slice(),u=a.length,c=e.start,l=e.end;if(i){var f=n[u-1],p=r(f,u-1),d=t*(f.coordinate+t*p/2-l);a[u-1]=f=h(h({},f),{},{tickCoord:d>0?f.coordinate-d*t:f.coordinate}),s(t,f.tickCoord,function(){return p},c,l)&&(l=f.tickCoord-t*(p/2+o),a[u-1]=h(h({},f),{},{isShow:!0}))}for(var y=i?u-1:u,v=function(e){var n,i=a[e],u=function(){return void 0===n&&(n=r(i,e)),n};if(0===e){var f=t*(i.coordinate-t*u()/2-c);a[e]=i=h(h({},i),{},{tickCoord:f<0?i.coordinate-f*t:i.coordinate})}else a[e]=i=h(h({},i),{},{tickCoord:i.coordinate});s(t,i.tickCoord,u,c,l)&&(c=i.tickCoord+t*(u()/2+o),a[e]=h(h({},i),{},{isShow:!0}))},m=0;m0?l.coordinate-p*t:l.coordinate})}else i[e]=l=h(h({},l),{},{tickCoord:l.coordinate});s(t,l.tickCoord,f,u,c)&&(c=l.tickCoord-t*(f()/2+o),i[e]=h(h({},l),{},{isShow:!0}))},f=a-1;f>=0;f--)l(f);return i}(A,M,k,m,g)).filter(function(t){return t.isShow})}},93765:function(t,e,r){"use strict";r.d(e,{z:function(){return eD}});var n,o,i=r(2265),a=r(77571),u=r.n(a),c=r(86757),l=r.n(c),s=r(99676),f=r.n(s),p=r(13735),h=r.n(p),d=r(34935),y=r.n(d),v=r(37065),m=r.n(v),b=r(61994),g=r(69398),x=r(48777),w=r(9841),O=r(8147),j=r(22190),S=r(81889),P=r(73649),E=r(82944),k=r(55284),A=r(58811),M=r(85355),_=r(16630);function T(t){return(T="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function C(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,n)}return r}function N(t){for(var e=1;e0&&e.handleDrag(t.changedTouches[0])}),W(e,"handleDragEnd",function(){e.setState({isTravellerMoving:!1,isSlideMoving:!1},function(){var t=e.props,r=t.endIndex,n=t.onDragEnd,o=t.startIndex;null==n||n({endIndex:r,startIndex:o})}),e.detachDragEndListener()}),W(e,"handleLeaveWrapper",function(){(e.state.isTravellerMoving||e.state.isSlideMoving)&&(e.leaveTimer=window.setTimeout(e.handleDragEnd,e.props.leaveTimeOut))}),W(e,"handleEnterSlideOrTraveller",function(){e.setState({isTextActive:!0})}),W(e,"handleLeaveSlideOrTraveller",function(){e.setState({isTextActive:!1})}),W(e,"handleSlideDragStart",function(t){var r=X(t)?t.changedTouches[0]:t;e.setState({isTravellerMoving:!1,isSlideMoving:!0,slideMoveStartX:r.pageX}),e.attachDragEndListener()}),e.travellerDragStartHandlers={startX:e.handleTravellerDragStart.bind(e,"startX"),endX:e.handleTravellerDragStart.bind(e,"endX")},e.state={},e}return!function(t,e){if("function"!=typeof e&&null!==e)throw TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&Z(t,e)}(n,t),e=[{key:"componentWillUnmount",value:function(){this.leaveTimer&&(clearTimeout(this.leaveTimer),this.leaveTimer=null),this.detachDragEndListener()}},{key:"getIndex",value:function(t){var e=t.startX,r=t.endX,o=this.state.scaleValues,i=this.props,a=i.gap,u=i.data.length-1,c=n.getIndexInRange(o,Math.min(e,r)),l=n.getIndexInRange(o,Math.max(e,r));return{startIndex:c-c%a,endIndex:l===u?u:l-l%a}}},{key:"getTextOfTick",value:function(t){var e=this.props,r=e.data,n=e.tickFormatter,o=e.dataKey,i=(0,M.F$)(r[t],o,t);return l()(n)?n(i,t):i}},{key:"attachDragEndListener",value:function(){window.addEventListener("mouseup",this.handleDragEnd,!0),window.addEventListener("touchend",this.handleDragEnd,!0),window.addEventListener("mousemove",this.handleDrag,!0)}},{key:"detachDragEndListener",value:function(){window.removeEventListener("mouseup",this.handleDragEnd,!0),window.removeEventListener("touchend",this.handleDragEnd,!0),window.removeEventListener("mousemove",this.handleDrag,!0)}},{key:"handleSlideDrag",value:function(t){var e=this.state,r=e.slideMoveStartX,n=e.startX,o=e.endX,i=this.props,a=i.x,u=i.width,c=i.travellerWidth,l=i.startIndex,s=i.endIndex,f=i.onChange,p=t.pageX-r;p>0?p=Math.min(p,a+u-c-o,a+u-c-n):p<0&&(p=Math.max(p,a-n,a-o));var h=this.getIndex({startX:n+p,endX:o+p});(h.startIndex!==l||h.endIndex!==s)&&f&&f(h),this.setState({startX:n+p,endX:o+p,slideMoveStartX:t.pageX})}},{key:"handleTravellerDragStart",value:function(t,e){var r=X(e)?e.changedTouches[0]:e;this.setState({isSlideMoving:!1,isTravellerMoving:!0,movingTravellerId:t,brushMoveStartX:r.pageX}),this.attachDragEndListener()}},{key:"handleTravellerMove",value:function(t){var e=this.state,r=e.brushMoveStartX,n=e.movingTravellerId,o=e.endX,i=e.startX,a=this.state[n],u=this.props,c=u.x,l=u.width,s=u.travellerWidth,f=u.onChange,p=u.gap,h=u.data,d={startX:this.state.startX,endX:this.state.endX},y=t.pageX-r;y>0?y=Math.min(y,c+l-s-a):y<0&&(y=Math.max(y,c-a)),d[n]=a+y;var v=this.getIndex(d),m=v.startIndex,b=v.endIndex,g=function(){var t=h.length-1;return"startX"===n&&(o>i?m%p==0:b%p==0)||oi?b%p==0:m%p==0)||o>i&&b===t};this.setState(W(W({},n,a+y),"brushMoveStartX",t.pageX),function(){f&&g()&&f(v)})}},{key:"handleTravellerMoveKeyboard",value:function(t,e){var r=this,n=this.state,o=n.scaleValues,i=n.startX,a=n.endX,u=this.state[e],c=o.indexOf(u);if(-1!==c){var l=c+t;if(-1!==l&&!(l>=o.length)){var s=o[l];"startX"===e&&s>=a||"endX"===e&&s<=i||this.setState(W({},e,s),function(){r.props.onChange(r.getIndex({startX:r.state.startX,endX:r.state.endX}))})}}}},{key:"renderBackground",value:function(){var t=this.props,e=t.x,r=t.y,n=t.width,o=t.height,a=t.fill,u=t.stroke;return i.createElement("rect",{stroke:u,fill:a,x:e,y:r,width:n,height:o})}},{key:"renderPanorama",value:function(){var t=this.props,e=t.x,r=t.y,n=t.width,o=t.height,a=t.data,u=t.children,c=t.padding,l=i.Children.only(u);return l?i.cloneElement(l,{x:e,y:r,width:n,height:o,margin:c,compact:!0,data:a}):null}},{key:"renderTravellerLayer",value:function(t,e){var r,o,a=this,u=this.props,c=u.y,l=u.travellerWidth,s=u.height,f=u.traveller,p=u.ariaLabel,h=u.data,d=u.startIndex,y=u.endIndex,v=Math.max(t,this.props.x),m=U(U({},(0,E.L6)(this.props,!1)),{},{x:v,y:c,width:l,height:s}),b=p||"Min value: ".concat(null===(r=h[d])||void 0===r?void 0:r.name,", Max value: ").concat(null===(o=h[y])||void 0===o?void 0:o.name);return i.createElement(w.m,{tabIndex:0,role:"slider","aria-label":b,"aria-valuenow":t,className:"recharts-brush-traveller",onMouseEnter:this.handleEnterSlideOrTraveller,onMouseLeave:this.handleLeaveSlideOrTraveller,onMouseDown:this.travellerDragStartHandlers[e],onTouchStart:this.travellerDragStartHandlers[e],onKeyDown:function(t){["ArrowLeft","ArrowRight"].includes(t.key)&&(t.preventDefault(),t.stopPropagation(),a.handleTravellerMoveKeyboard("ArrowRight"===t.key?1:-1,e))},onFocus:function(){a.setState({isTravellerFocused:!0})},onBlur:function(){a.setState({isTravellerFocused:!1})},style:{cursor:"col-resize"}},n.renderTraveller(f,m))}},{key:"renderSlide",value:function(t,e){var r=this.props,n=r.y,o=r.height,a=r.stroke,u=r.travellerWidth;return i.createElement("rect",{className:"recharts-brush-slide",onMouseEnter:this.handleEnterSlideOrTraveller,onMouseLeave:this.handleLeaveSlideOrTraveller,onMouseDown:this.handleSlideDragStart,onTouchStart:this.handleSlideDragStart,style:{cursor:"move"},stroke:"none",fill:a,fillOpacity:.2,x:Math.min(t,e)+u,y:n,width:Math.max(Math.abs(e-t)-u,0),height:o})}},{key:"renderText",value:function(){var t=this.props,e=t.startIndex,r=t.endIndex,n=t.y,o=t.height,a=t.travellerWidth,u=t.stroke,c=this.state,l=c.startX,s=c.endX,f={pointerEvents:"none",fill:u};return i.createElement(w.m,{className:"recharts-brush-texts"},i.createElement(A.x,R({textAnchor:"end",verticalAnchor:"middle",x:Math.min(l,s)-5,y:n+o/2},f),this.getTextOfTick(e)),i.createElement(A.x,R({textAnchor:"start",verticalAnchor:"middle",x:Math.max(l,s)+a+5,y:n+o/2},f),this.getTextOfTick(r)))}},{key:"render",value:function(){var t=this.props,e=t.data,r=t.className,n=t.children,o=t.x,a=t.y,u=t.width,c=t.height,l=t.alwaysShowText,s=this.state,f=s.startX,p=s.endX,h=s.isTextActive,d=s.isSlideMoving,y=s.isTravellerMoving,v=s.isTravellerFocused;if(!e||!e.length||!(0,_.hj)(o)||!(0,_.hj)(a)||!(0,_.hj)(u)||!(0,_.hj)(c)||u<=0||c<=0)return null;var m=(0,b.Z)("recharts-brush",r),g=1===i.Children.count(n),x=L("userSelect","none");return i.createElement(w.m,{className:m,onMouseLeave:this.handleLeaveWrapper,onTouchMove:this.handleTouchMove,style:x},this.renderBackground(),g&&this.renderPanorama(),this.renderSlide(f,p),this.renderTravellerLayer(f,"startX"),this.renderTravellerLayer(p,"endX"),(h||d||y||v||l)&&this.renderText())}}],r=[{key:"renderDefaultTraveller",value:function(t){var e=t.x,r=t.y,n=t.width,o=t.height,a=t.stroke,u=Math.floor(r+o/2)-1;return i.createElement(i.Fragment,null,i.createElement("rect",{x:e,y:r,width:n,height:o,fill:a,stroke:"none"}),i.createElement("line",{x1:e+1,y1:u,x2:e+n-1,y2:u,fill:"none",stroke:"#fff"}),i.createElement("line",{x1:e+1,y1:u+2,x2:e+n-1,y2:u+2,fill:"none",stroke:"#fff"}))}},{key:"renderTraveller",value:function(t,e){return i.isValidElement(t)?i.cloneElement(t,e):l()(t)?t(e):n.renderDefaultTraveller(e)}},{key:"getDerivedStateFromProps",value:function(t,e){var r=t.data,n=t.width,o=t.x,i=t.travellerWidth,a=t.updateId,u=t.startIndex,c=t.endIndex;if(r!==e.prevData||a!==e.prevUpdateId)return U({prevData:r,prevTravellerWidth:i,prevUpdateId:a,prevX:o,prevWidth:n},r&&r.length?H({data:r,width:n,x:o,travellerWidth:i,startIndex:u,endIndex:c}):{scale:null,scaleValues:null});if(e.scale&&(n!==e.prevWidth||o!==e.prevX||i!==e.prevTravellerWidth)){e.scale.range([o,o+n-i]);var l=e.scale.domain().map(function(t){return e.scale(t)});return{prevData:r,prevTravellerWidth:i,prevUpdateId:a,prevX:o,prevWidth:n,startX:e.scale(t.startIndex),endX:e.scale(t.endIndex),scaleValues:l}}return null}},{key:"getIndexInRange",value:function(t,e){for(var r=t.length,n=0,o=r-1;o-n>1;){var i=Math.floor((n+o)/2);t[i]>e?o=i:n=i}return e>=t[o]?o:n}}],e&&F(n.prototype,e),r&&F(n,r),Object.defineProperty(n,"prototype",{writable:!1}),n}(i.PureComponent);W(G,"displayName","Brush"),W(G,"defaultProps",{height:40,travellerWidth:5,gap:1,fill:"#fff",stroke:"#666",padding:{top:1,right:1,bottom:1,left:1},leaveTimeOut:1e3,alwaysShowText:!1});var V=r(4094),K=r(38569),Q=r(26680),J=function(t,e){var r=t.alwaysShow,n=t.ifOverflow;return r&&(n="extendDomain"),n===e},tt=r(25311),te=r(1175);function tr(){return(tr=Object.assign?Object.assign.bind():function(t){for(var e=1;et.length)&&(e=t.length);for(var r=0,n=Array(e);rt.length)&&(e=t.length);for(var r=0,n=Array(e);r=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(t,t2));return(0,_.hj)(r)&&(0,_.hj)(o)&&(0,_.hj)(f)&&(0,_.hj)(h)&&(0,_.hj)(u)&&(0,_.hj)(l)?i.createElement("path",t5({},(0,E.L6)(y,!0),{className:(0,b.Z)("recharts-cross",d),d:"M".concat(r,",").concat(u,"v").concat(h,"M").concat(l,",").concat(o,"h").concat(f)})):null};function t7(t){var e=t.cx,r=t.cy,n=t.radius,o=t.startAngle,i=t.endAngle;return{points:[(0,tq.op)(e,r,n,o),(0,tq.op)(e,r,n,i)],cx:e,cy:r,radius:n,startAngle:o,endAngle:i}}var t4=r(60474);function t8(t){return(t8="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function t9(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,n)}return r}function et(t){for(var e=1;e=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}function ec(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(t){}return(ec=function(){return!!t})()}function el(t){return(el=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function es(t,e){return(es=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t})(t,e)}function ef(t){return function(t){if(Array.isArray(t))return eh(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||ep(t)||function(){throw TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function ep(t,e){if(t){if("string"==typeof t)return eh(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return eh(t,e)}}function eh(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);r0?i:t&&t.length&&(0,_.hj)(n)&&(0,_.hj)(o)?t.slice(n,o+1):[]};function eS(t){return"number"===t?[0,"auto"]:void 0}var eP=function(t,e,r,n){var o=t.graphicalItems,i=t.tooltipAxis,a=ej(e,t);return r<0||!o||!o.length||r>=a.length?null:o.reduce(function(o,u){var c,l,s=null!==(c=u.props.data)&&void 0!==c?c:e;if(s&&t.dataStartIndex+t.dataEndIndex!==0&&t.dataEndIndex-t.dataStartIndex>=r&&(s=s.slice(t.dataStartIndex,t.dataEndIndex+1)),i.dataKey&&!i.allowDuplicatedCategory){var f=void 0===s?a:s;l=(0,_.Ap)(f,i.dataKey,n)}else l=s&&s[r]||a[r];return l?[].concat(ef(o),[(0,M.Qo)(u,l)]):o},[])},eE=function(t,e,r,n){var o=n||{x:t.chartX,y:t.chartY},i="horizontal"===r?o.x:"vertical"===r?o.y:"centric"===r?o.angle:o.radius,a=t.orderedTooltipTicks,u=t.tooltipAxis,c=t.tooltipTicks,l=(0,M.VO)(i,a,c,u);if(l>=0&&c){var s=c[l]&&c[l].value,f=eP(t,e,l,s),p=eO(r,a,l,o);return{activeTooltipIndex:l,activeLabel:s,activePayload:f,activeCoordinate:p}}return null},ek=function(t,e){var r=e.axes,n=e.graphicalItems,o=e.axisType,i=e.axisIdKey,a=e.stackGroups,c=e.dataStartIndex,l=e.dataEndIndex,s=t.layout,p=t.children,h=t.stackOffset,d=(0,M.NA)(s,o);return r.reduce(function(e,r){var y=void 0!==r.type.defaultProps?ey(ey({},r.type.defaultProps),r.props):r.props,v=y.type,m=y.dataKey,b=y.allowDataOverflow,g=y.allowDuplicatedCategory,x=y.scale,w=y.ticks,O=y.includeHidden,j=y[i];if(e[j])return e;var S=ej(t.data,{graphicalItems:n.filter(function(t){var e;return(i in t.props?t.props[i]:null===(e=t.type.defaultProps)||void 0===e?void 0:e[i])===j}),dataStartIndex:c,dataEndIndex:l}),P=S.length;(function(t,e,r){if("number"===r&&!0===e&&Array.isArray(t)){var n=null==t?void 0:t[0],o=null==t?void 0:t[1];if(n&&o&&(0,_.hj)(n)&&(0,_.hj)(o))return!0}return!1})(y.domain,b,v)&&(A=(0,M.LG)(y.domain,null,b),d&&("number"===v||"auto"!==x)&&(C=(0,M.gF)(S,m,"category")));var E=eS(v);if(!A||0===A.length){var k,A,T,C,N,D=null!==(N=y.domain)&&void 0!==N?N:E;if(m){if(A=(0,M.gF)(S,m,v),"category"===v&&d){var I=(0,_.bv)(A);g&&I?(T=A,A=f()(0,P)):g||(A=(0,M.ko)(D,A,r).reduce(function(t,e){return t.indexOf(e)>=0?t:[].concat(ef(t),[e])},[]))}else if("category"===v)A=g?A.filter(function(t){return""!==t&&!u()(t)}):(0,M.ko)(D,A,r).reduce(function(t,e){return t.indexOf(e)>=0||""===e||u()(e)?t:[].concat(ef(t),[e])},[]);else if("number"===v){var L=(0,M.ZI)(S,n.filter(function(t){var e,r,n=i in t.props?t.props[i]:null===(e=t.type.defaultProps)||void 0===e?void 0:e[i],o="hide"in t.props?t.props.hide:null===(r=t.type.defaultProps)||void 0===r?void 0:r.hide;return n===j&&(O||!o)}),m,o,s);L&&(A=L)}d&&("number"===v||"auto"!==x)&&(C=(0,M.gF)(S,m,"category"))}else A=d?f()(0,P):a&&a[j]&&a[j].hasStack&&"number"===v?"expand"===h?[0,1]:(0,M.EB)(a[j].stackGroups,c,l):(0,M.s6)(S,n.filter(function(t){var e=i in t.props?t.props[i]:t.type.defaultProps[i],r="hide"in t.props?t.props.hide:t.type.defaultProps.hide;return e===j&&(O||!r)}),v,s,!0);"number"===v?(A=t$(p,A,j,o,w),D&&(A=(0,M.LG)(D,A,b))):"category"===v&&D&&A.every(function(t){return D.indexOf(t)>=0})&&(A=D)}return ey(ey({},e),{},ev({},j,ey(ey({},y),{},{axisType:o,domain:A,categoricalDomain:C,duplicateDomain:T,originalDomain:null!==(k=y.domain)&&void 0!==k?k:E,isCategorical:d,layout:s})))},{})},eA=function(t,e){var r=e.graphicalItems,n=e.Axis,o=e.axisType,i=e.axisIdKey,a=e.stackGroups,u=e.dataStartIndex,c=e.dataEndIndex,l=t.layout,s=t.children,p=ej(t.data,{graphicalItems:r,dataStartIndex:u,dataEndIndex:c}),d=p.length,y=(0,M.NA)(l,o),v=-1;return r.reduce(function(t,e){var m,b=(void 0!==e.type.defaultProps?ey(ey({},e.type.defaultProps),e.props):e.props)[i],g=eS("number");return t[b]?t:(v++,m=y?f()(0,d):a&&a[b]&&a[b].hasStack?t$(s,m=(0,M.EB)(a[b].stackGroups,u,c),b,o):t$(s,m=(0,M.LG)(g,(0,M.s6)(p,r.filter(function(t){var e,r,n=i in t.props?t.props[i]:null===(e=t.type.defaultProps)||void 0===e?void 0:e[i],o="hide"in t.props?t.props.hide:null===(r=t.type.defaultProps)||void 0===r?void 0:r.hide;return n===b&&!o}),"number",l),n.defaultProps.allowDataOverflow),b,o),ey(ey({},t),{},ev({},b,ey(ey({axisType:o},n.defaultProps),{},{hide:!0,orientation:h()(eb,"".concat(o,".").concat(v%2),null),domain:m,originalDomain:g,isCategorical:y,layout:l}))))},{})},eM=function(t,e){var r=e.axisType,n=void 0===r?"xAxis":r,o=e.AxisComp,i=e.graphicalItems,a=e.stackGroups,u=e.dataStartIndex,c=e.dataEndIndex,l=t.children,s="".concat(n,"Id"),f=(0,E.NN)(l,o),p={};return f&&f.length?p=ek(t,{axes:f,graphicalItems:i,axisType:n,axisIdKey:s,stackGroups:a,dataStartIndex:u,dataEndIndex:c}):i&&i.length&&(p=eA(t,{Axis:o,graphicalItems:i,axisType:n,axisIdKey:s,stackGroups:a,dataStartIndex:u,dataEndIndex:c})),p},e_=function(t){var e=(0,_.Kt)(t),r=(0,M.uY)(e,!1,!0);return{tooltipTicks:r,orderedTooltipTicks:y()(r,function(t){return t.coordinate}),tooltipAxis:e,tooltipAxisBandSize:(0,M.zT)(e,r)}},eT=function(t){var e=t.children,r=t.defaultShowTooltip,n=(0,E.sP)(e,G),o=0,i=0;return t.data&&0!==t.data.length&&(i=t.data.length-1),n&&n.props&&(n.props.startIndex>=0&&(o=n.props.startIndex),n.props.endIndex>=0&&(i=n.props.endIndex)),{chartX:0,chartY:0,dataStartIndex:o,dataEndIndex:i,activeTooltipIndex:-1,isTooltipActive:!!r}},eC=function(t){return"horizontal"===t?{numericAxisName:"yAxis",cateAxisName:"xAxis"}:"vertical"===t?{numericAxisName:"xAxis",cateAxisName:"yAxis"}:"centric"===t?{numericAxisName:"radiusAxis",cateAxisName:"angleAxis"}:{numericAxisName:"angleAxis",cateAxisName:"radiusAxis"}},eN=function(t,e){var r=t.props,n=t.graphicalItems,o=t.xAxisMap,i=void 0===o?{}:o,a=t.yAxisMap,u=void 0===a?{}:a,c=r.width,l=r.height,s=r.children,f=r.margin||{},p=(0,E.sP)(s,G),d=(0,E.sP)(s,j.D),y=Object.keys(u).reduce(function(t,e){var r=u[e],n=r.orientation;return r.mirror||r.hide?t:ey(ey({},t),{},ev({},n,t[n]+r.width))},{left:f.left||0,right:f.right||0}),v=Object.keys(i).reduce(function(t,e){var r=i[e],n=r.orientation;return r.mirror||r.hide?t:ey(ey({},t),{},ev({},n,h()(t,"".concat(n))+r.height))},{top:f.top||0,bottom:f.bottom||0}),m=ey(ey({},v),y),b=m.bottom;p&&(m.bottom+=p.props.height||G.defaultProps.height),d&&e&&(m=(0,M.By)(m,n,r,e));var g=c-m.left-m.right,x=l-m.top-m.bottom;return ey(ey({brushBottom:b},m),{},{width:Math.max(g,0),height:Math.max(x,0)})},eD=function(t){var e=t.chartName,r=t.GraphicalChild,n=t.defaultTooltipEventType,o=void 0===n?"axis":n,a=t.validateTooltipEventTypes,c=void 0===a?["axis"]:a,s=t.axisComponents,f=t.legendContent,p=t.formatAxisMap,d=t.defaultProps,y=function(t,e){var r=e.graphicalItems,n=e.stackGroups,o=e.offset,i=e.updateId,a=e.dataStartIndex,c=e.dataEndIndex,l=t.barSize,f=t.layout,p=t.barGap,h=t.barCategoryGap,d=t.maxBarSize,y=eC(f),v=y.numericAxisName,m=y.cateAxisName,b=!!r&&!!r.length&&r.some(function(t){var e=(0,E.Gf)(t&&t.type);return e&&e.indexOf("Bar")>=0}),x=[];return r.forEach(function(r,y){var w=ej(t.data,{graphicalItems:[r],dataStartIndex:a,dataEndIndex:c}),O=void 0!==r.type.defaultProps?ey(ey({},r.type.defaultProps),r.props):r.props,j=O.dataKey,S=O.maxBarSize,P=O["".concat(v,"Id")],k=O["".concat(m,"Id")],A=s.reduce(function(t,r){var n=e["".concat(r.axisType,"Map")],o=O["".concat(r.axisType,"Id")];n&&n[o]||"zAxis"===r.axisType||(0,g.Z)(!1);var i=n[o];return ey(ey({},t),{},ev(ev({},r.axisType,i),"".concat(r.axisType,"Ticks"),(0,M.uY)(i)))},{}),_=A[m],T=A["".concat(m,"Ticks")],C=n&&n[P]&&n[P].hasStack&&(0,M.O3)(r,n[P].stackGroups),N=(0,E.Gf)(r.type).indexOf("Bar")>=0,D=(0,M.zT)(_,T),I=[],L=b&&(0,M.pt)({barSize:l,stackGroups:n,totalSize:"xAxis"===m?A[m].width:"yAxis"===m?A[m].height:void 0});if(N){var B,R,z=u()(S)?d:S,U=null!==(B=null!==(R=(0,M.zT)(_,T,!0))&&void 0!==R?R:z)&&void 0!==B?B:0;I=(0,M.qz)({barGap:p,barCategoryGap:h,bandSize:U!==D?U:D,sizeList:L[k],maxBarSize:z}),U!==D&&(I=I.map(function(t){return ey(ey({},t),{},{position:ey(ey({},t.position),{},{offset:t.position.offset-U/2})})}))}var F=r&&r.type&&r.type.getComposedData;F&&x.push({props:ey(ey({},F(ey(ey({},A),{},{displayedData:w,props:t,dataKey:j,item:r,bandSize:D,barPosition:I,offset:o,stackedData:C,layout:f,dataStartIndex:a,dataEndIndex:c}))),{},ev(ev(ev({key:r.key||"item-".concat(y)},v,A[v]),m,A[m]),"animationId",i)),childIndex:(0,E.$R)(r,t.children),item:r})}),x},v=function(t,n){var o=t.props,i=t.dataStartIndex,a=t.dataEndIndex,u=t.updateId;if(!(0,E.TT)({props:o}))return null;var c=o.children,l=o.layout,f=o.stackOffset,h=o.data,d=o.reverseStackOrder,v=eC(l),m=v.numericAxisName,b=v.cateAxisName,g=(0,E.NN)(c,r),x=(0,M.wh)(h,g,"".concat(m,"Id"),"".concat(b,"Id"),f,d),w=s.reduce(function(t,e){var r="".concat(e.axisType,"Map");return ey(ey({},t),{},ev({},r,eM(o,ey(ey({},e),{},{graphicalItems:g,stackGroups:e.axisType===m&&x,dataStartIndex:i,dataEndIndex:a}))))},{}),O=eN(ey(ey({},w),{},{props:o,graphicalItems:g}),null==n?void 0:n.legendBBox);Object.keys(w).forEach(function(t){w[t]=p(o,w[t],O,t.replace("Map",""),e)});var j=e_(w["".concat(b,"Map")]),S=y(o,ey(ey({},w),{},{dataStartIndex:i,dataEndIndex:a,updateId:u,graphicalItems:g,stackGroups:x,offset:O}));return ey(ey({formattedGraphicalItems:S,graphicalItems:g,offset:O,stackGroups:x},j),w)},j=function(t){var r;function n(t){var r,o,a,c,s;return!function(t,e){if(!(t instanceof e))throw TypeError("Cannot call a class as a function")}(this,n),c=n,s=[t],c=el(c),ev(a=function(t,e){if(e&&("object"===eo(e)||"function"==typeof e))return e;if(void 0!==e)throw TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}(this,ec()?Reflect.construct(c,s||[],el(this).constructor):c.apply(this,s)),"eventEmitterSymbol",Symbol("rechartsEventEmitter")),ev(a,"accessibilityManager",new tQ),ev(a,"handleLegendBBoxUpdate",function(t){if(t){var e=a.state,r=e.dataStartIndex,n=e.dataEndIndex,o=e.updateId;a.setState(ey({legendBBox:t},v({props:a.props,dataStartIndex:r,dataEndIndex:n,updateId:o},ey(ey({},a.state),{},{legendBBox:t}))))}}),ev(a,"handleReceiveSyncEvent",function(t,e,r){a.props.syncId===t&&(r!==a.eventEmitterSymbol||"function"==typeof a.props.syncMethod)&&a.applySyncEvent(e)}),ev(a,"handleBrushChange",function(t){var e=t.startIndex,r=t.endIndex;if(e!==a.state.dataStartIndex||r!==a.state.dataEndIndex){var n=a.state.updateId;a.setState(function(){return ey({dataStartIndex:e,dataEndIndex:r},v({props:a.props,dataStartIndex:e,dataEndIndex:r,updateId:n},a.state))}),a.triggerSyncEvent({dataStartIndex:e,dataEndIndex:r})}}),ev(a,"handleMouseEnter",function(t){var e=a.getMouseInfo(t);if(e){var r=ey(ey({},e),{},{isTooltipActive:!0});a.setState(r),a.triggerSyncEvent(r);var n=a.props.onMouseEnter;l()(n)&&n(r,t)}}),ev(a,"triggeredAfterMouseMove",function(t){var e=a.getMouseInfo(t),r=e?ey(ey({},e),{},{isTooltipActive:!0}):{isTooltipActive:!1};a.setState(r),a.triggerSyncEvent(r);var n=a.props.onMouseMove;l()(n)&&n(r,t)}),ev(a,"handleItemMouseEnter",function(t){a.setState(function(){return{isTooltipActive:!0,activeItem:t,activePayload:t.tooltipPayload,activeCoordinate:t.tooltipPosition||{x:t.cx,y:t.cy}}})}),ev(a,"handleItemMouseLeave",function(){a.setState(function(){return{isTooltipActive:!1}})}),ev(a,"handleMouseMove",function(t){t.persist(),a.throttleTriggeredAfterMouseMove(t)}),ev(a,"handleMouseLeave",function(t){a.throttleTriggeredAfterMouseMove.cancel();var e={isTooltipActive:!1};a.setState(e),a.triggerSyncEvent(e);var r=a.props.onMouseLeave;l()(r)&&r(e,t)}),ev(a,"handleOuterEvent",function(t){var e,r=(0,E.Bh)(t),n=h()(a.props,"".concat(r));r&&l()(n)&&n(null!==(e=/.*touch.*/i.test(r)?a.getMouseInfo(t.changedTouches[0]):a.getMouseInfo(t))&&void 0!==e?e:{},t)}),ev(a,"handleClick",function(t){var e=a.getMouseInfo(t);if(e){var r=ey(ey({},e),{},{isTooltipActive:!0});a.setState(r),a.triggerSyncEvent(r);var n=a.props.onClick;l()(n)&&n(r,t)}}),ev(a,"handleMouseDown",function(t){var e=a.props.onMouseDown;l()(e)&&e(a.getMouseInfo(t),t)}),ev(a,"handleMouseUp",function(t){var e=a.props.onMouseUp;l()(e)&&e(a.getMouseInfo(t),t)}),ev(a,"handleTouchMove",function(t){null!=t.changedTouches&&t.changedTouches.length>0&&a.throttleTriggeredAfterMouseMove(t.changedTouches[0])}),ev(a,"handleTouchStart",function(t){null!=t.changedTouches&&t.changedTouches.length>0&&a.handleMouseDown(t.changedTouches[0])}),ev(a,"handleTouchEnd",function(t){null!=t.changedTouches&&t.changedTouches.length>0&&a.handleMouseUp(t.changedTouches[0])}),ev(a,"handleDoubleClick",function(t){var e=a.props.onDoubleClick;l()(e)&&e(a.getMouseInfo(t),t)}),ev(a,"handleContextMenu",function(t){var e=a.props.onContextMenu;l()(e)&&e(a.getMouseInfo(t),t)}),ev(a,"triggerSyncEvent",function(t){void 0!==a.props.syncId&&tY.emit(tH,a.props.syncId,t,a.eventEmitterSymbol)}),ev(a,"applySyncEvent",function(t){var e=a.props,r=e.layout,n=e.syncMethod,o=a.state.updateId,i=t.dataStartIndex,u=t.dataEndIndex;if(void 0!==t.dataStartIndex||void 0!==t.dataEndIndex)a.setState(ey({dataStartIndex:i,dataEndIndex:u},v({props:a.props,dataStartIndex:i,dataEndIndex:u,updateId:o},a.state)));else if(void 0!==t.activeTooltipIndex){var c=t.chartX,l=t.chartY,s=t.activeTooltipIndex,f=a.state,p=f.offset,h=f.tooltipTicks;if(!p)return;if("function"==typeof n)s=n(h,t);else if("value"===n){s=-1;for(var d=0;d=0){if(s.dataKey&&!s.allowDuplicatedCategory){var A="function"==typeof s.dataKey?function(t){return"function"==typeof s.dataKey?s.dataKey(t.payload):null}:"payload.".concat(s.dataKey.toString());C=(0,_.Ap)(v,A,p),N=m&&b&&(0,_.Ap)(b,A,p)}else C=null==v?void 0:v[f],N=m&&b&&b[f];if(S||j){var T=void 0!==t.props.activeIndex?t.props.activeIndex:f;return[(0,i.cloneElement)(t,ey(ey(ey({},n.props),P),{},{activeIndex:T})),null,null]}if(!u()(C))return[k].concat(ef(a.renderActivePoints({item:n,activePoint:C,basePoint:N,childIndex:f,isRange:m})))}else{var C,N,D,I=(null!==(D=a.getItemByXY(a.state.activeCoordinate))&&void 0!==D?D:{graphicalItem:k}).graphicalItem,L=I.item,B=void 0===L?t:L,R=I.childIndex,z=ey(ey(ey({},n.props),P),{},{activeIndex:R});return[(0,i.cloneElement)(B,z),null,null]}}return m?[k,null,null]:[k,null]}),ev(a,"renderCustomized",function(t,e,r){return(0,i.cloneElement)(t,ey(ey({key:"recharts-customized-".concat(r)},a.props),a.state))}),ev(a,"renderMap",{CartesianGrid:{handler:ew,once:!0},ReferenceArea:{handler:a.renderReferenceElement},ReferenceLine:{handler:ew},ReferenceDot:{handler:a.renderReferenceElement},XAxis:{handler:ew},YAxis:{handler:ew},Brush:{handler:a.renderBrush,once:!0},Bar:{handler:a.renderGraphicChild},Line:{handler:a.renderGraphicChild},Area:{handler:a.renderGraphicChild},Radar:{handler:a.renderGraphicChild},RadialBar:{handler:a.renderGraphicChild},Scatter:{handler:a.renderGraphicChild},Pie:{handler:a.renderGraphicChild},Funnel:{handler:a.renderGraphicChild},Tooltip:{handler:a.renderCursor,once:!0},PolarGrid:{handler:a.renderPolarGrid,once:!0},PolarAngleAxis:{handler:a.renderPolarAxis},PolarRadiusAxis:{handler:a.renderPolarAxis},Customized:{handler:a.renderCustomized}}),a.clipPathId="".concat(null!==(r=t.id)&&void 0!==r?r:(0,_.EL)("recharts"),"-clip"),a.throttleTriggeredAfterMouseMove=m()(a.triggeredAfterMouseMove,null!==(o=t.throttleDelay)&&void 0!==o?o:1e3/60),a.state={},a}return!function(t,e){if("function"!=typeof e&&null!==e)throw TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&es(t,e)}(n,t),r=[{key:"componentDidMount",value:function(){var t,e;this.addListener(),this.accessibilityManager.setDetails({container:this.container,offset:{left:null!==(t=this.props.margin.left)&&void 0!==t?t:0,top:null!==(e=this.props.margin.top)&&void 0!==e?e:0},coordinateList:this.state.tooltipTicks,mouseHandlerCallback:this.triggeredAfterMouseMove,layout:this.props.layout}),this.displayDefaultTooltip()}},{key:"displayDefaultTooltip",value:function(){var t=this.props,e=t.children,r=t.data,n=t.height,o=t.layout,i=(0,E.sP)(e,O.u);if(i){var a=i.props.defaultIndex;if("number"==typeof a&&!(a<0)&&!(a>this.state.tooltipTicks.length-1)){var u=this.state.tooltipTicks[a]&&this.state.tooltipTicks[a].value,c=eP(this.state,r,a,u),l=this.state.tooltipTicks[a].coordinate,s=(this.state.offset.top+n)/2,f="horizontal"===o?{x:l,y:s}:{y:l,x:s},p=this.state.formattedGraphicalItems.find(function(t){return"Scatter"===t.item.type.name});p&&(f=ey(ey({},f),p.props.points[a].tooltipPosition),c=p.props.points[a].tooltipPayload);var h={activeTooltipIndex:a,isTooltipActive:!0,activeLabel:u,activePayload:c,activeCoordinate:f};this.setState(h),this.renderCursor(i),this.accessibilityManager.setIndex(a)}}}},{key:"getSnapshotBeforeUpdate",value:function(t,e){if(!this.props.accessibilityLayer)return null;if(this.state.tooltipTicks!==e.tooltipTicks&&this.accessibilityManager.setDetails({coordinateList:this.state.tooltipTicks}),this.props.layout!==t.layout&&this.accessibilityManager.setDetails({layout:this.props.layout}),this.props.margin!==t.margin){var r,n;this.accessibilityManager.setDetails({offset:{left:null!==(r=this.props.margin.left)&&void 0!==r?r:0,top:null!==(n=this.props.margin.top)&&void 0!==n?n:0}})}return null}},{key:"componentDidUpdate",value:function(t){(0,E.rL)([(0,E.sP)(t.children,O.u)],[(0,E.sP)(this.props.children,O.u)])||this.displayDefaultTooltip()}},{key:"componentWillUnmount",value:function(){this.removeListener(),this.throttleTriggeredAfterMouseMove.cancel()}},{key:"getTooltipEventType",value:function(){var t=(0,E.sP)(this.props.children,O.u);if(t&&"boolean"==typeof t.props.shared){var e=t.props.shared?"axis":"item";return c.indexOf(e)>=0?e:o}return o}},{key:"getMouseInfo",value:function(t){if(!this.container)return null;var e=this.container,r=e.getBoundingClientRect(),n=(0,V.os)(r),o={chartX:Math.round(t.pageX-n.left),chartY:Math.round(t.pageY-n.top)},i=r.width/e.offsetWidth||1,a=this.inRange(o.chartX,o.chartY,i);if(!a)return null;var u=this.state,c=u.xAxisMap,l=u.yAxisMap,s=this.getTooltipEventType(),f=eE(this.state,this.props.data,this.props.layout,a);if("axis"!==s&&c&&l){var p=(0,_.Kt)(c).scale,h=(0,_.Kt)(l).scale,d=p&&p.invert?p.invert(o.chartX):null,y=h&&h.invert?h.invert(o.chartY):null;return ey(ey({},o),{},{xValue:d,yValue:y},f)}return f?ey(ey({},o),f):null}},{key:"inRange",value:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1,n=this.props.layout,o=t/r,i=e/r;if("horizontal"===n||"vertical"===n){var a=this.state.offset;return o>=a.left&&o<=a.left+a.width&&i>=a.top&&i<=a.top+a.height?{x:o,y:i}:null}var u=this.state,c=u.angleAxisMap,l=u.radiusAxisMap;if(c&&l){var s=(0,_.Kt)(c);return(0,tq.z3)({x:o,y:i},s)}return null}},{key:"parseEventsOfWrapper",value:function(){var t=this.props.children,e=this.getTooltipEventType(),r=(0,E.sP)(t,O.u),n={};return r&&"axis"===e&&(n="click"===r.props.trigger?{onClick:this.handleClick}:{onMouseEnter:this.handleMouseEnter,onDoubleClick:this.handleDoubleClick,onMouseMove:this.handleMouseMove,onMouseLeave:this.handleMouseLeave,onTouchMove:this.handleTouchMove,onTouchStart:this.handleTouchStart,onTouchEnd:this.handleTouchEnd,onContextMenu:this.handleContextMenu}),ey(ey({},(0,tX.Ym)(this.props,this.handleOuterEvent)),n)}},{key:"addListener",value:function(){tY.on(tH,this.handleReceiveSyncEvent)}},{key:"removeListener",value:function(){tY.removeListener(tH,this.handleReceiveSyncEvent)}},{key:"filterFormatItem",value:function(t,e,r){for(var n=this.state.formattedGraphicalItems,o=0,i=n.length;ot.length)&&(e=t.length);for(var r=0,n=Array(e);r=0?1:-1;"insideStart"===u?(o=b+S*l,a=w):"insideEnd"===u?(o=g-S*l,a=!w):"end"===u&&(o=g+S*l,a=w),a=j<=0?a:!a;var P=(0,d.op)(p,y,O,o),E=(0,d.op)(p,y,O,o+(a?1:-1)*359),k="M".concat(P.x,",").concat(P.y,"\n A").concat(O,",").concat(O,",0,1,").concat(a?0:1,",\n ").concat(E.x,",").concat(E.y),A=i()(t.id)?(0,h.EL)("recharts-radial-line-"):t.id;return n.createElement("text",x({},r,{dominantBaseline:"central",className:(0,s.Z)("recharts-radial-bar-label",f)}),n.createElement("defs",null,n.createElement("path",{id:A,d:k})),n.createElement("textPath",{xlinkHref:"#".concat(A)},e))},j=function(t){var e=t.viewBox,r=t.offset,n=t.position,o=e.cx,i=e.cy,a=e.innerRadius,u=e.outerRadius,c=(e.startAngle+e.endAngle)/2;if("outside"===n){var l=(0,d.op)(o,i,u+r,c),s=l.x;return{x:s,y:l.y,textAnchor:s>=o?"start":"end",verticalAnchor:"middle"}}if("center"===n)return{x:o,y:i,textAnchor:"middle",verticalAnchor:"middle"};if("centerTop"===n)return{x:o,y:i,textAnchor:"middle",verticalAnchor:"start"};if("centerBottom"===n)return{x:o,y:i,textAnchor:"middle",verticalAnchor:"end"};var f=(0,d.op)(o,i,(a+u)/2,c);return{x:f.x,y:f.y,textAnchor:"middle",verticalAnchor:"middle"}},S=function(t){var e=t.viewBox,r=t.parentViewBox,n=t.offset,o=t.position,i=e.x,a=e.y,u=e.width,c=e.height,s=c>=0?1:-1,f=s*n,p=s>0?"end":"start",d=s>0?"start":"end",y=u>=0?1:-1,v=y*n,m=y>0?"end":"start",b=y>0?"start":"end";if("top"===o)return g(g({},{x:i+u/2,y:a-s*n,textAnchor:"middle",verticalAnchor:p}),r?{height:Math.max(a-r.y,0),width:u}:{});if("bottom"===o)return g(g({},{x:i+u/2,y:a+c+f,textAnchor:"middle",verticalAnchor:d}),r?{height:Math.max(r.y+r.height-(a+c),0),width:u}:{});if("left"===o){var x={x:i-v,y:a+c/2,textAnchor:m,verticalAnchor:"middle"};return g(g({},x),r?{width:Math.max(x.x-r.x,0),height:c}:{})}if("right"===o){var w={x:i+u+v,y:a+c/2,textAnchor:b,verticalAnchor:"middle"};return g(g({},w),r?{width:Math.max(r.x+r.width-w.x,0),height:c}:{})}var O=r?{width:u,height:c}:{};return"insideLeft"===o?g({x:i+v,y:a+c/2,textAnchor:b,verticalAnchor:"middle"},O):"insideRight"===o?g({x:i+u-v,y:a+c/2,textAnchor:m,verticalAnchor:"middle"},O):"insideTop"===o?g({x:i+u/2,y:a+f,textAnchor:"middle",verticalAnchor:d},O):"insideBottom"===o?g({x:i+u/2,y:a+c-f,textAnchor:"middle",verticalAnchor:p},O):"insideTopLeft"===o?g({x:i+v,y:a+f,textAnchor:b,verticalAnchor:d},O):"insideTopRight"===o?g({x:i+u-v,y:a+f,textAnchor:m,verticalAnchor:d},O):"insideBottomLeft"===o?g({x:i+v,y:a+c-f,textAnchor:b,verticalAnchor:p},O):"insideBottomRight"===o?g({x:i+u-v,y:a+c-f,textAnchor:m,verticalAnchor:p},O):l()(o)&&((0,h.hj)(o.x)||(0,h.hU)(o.x))&&((0,h.hj)(o.y)||(0,h.hU)(o.y))?g({x:i+(0,h.h1)(o.x,u),y:a+(0,h.h1)(o.y,c),textAnchor:"end",verticalAnchor:"end"},O):g({x:i+u/2,y:a+c/2,textAnchor:"middle",verticalAnchor:"middle"},O)};function P(t){var e,r=t.offset,o=g({offset:void 0===r?5:r},function(t,e){if(null==t)return{};var r,n,o=function(t,e){if(null==t)return{};var r={};for(var n in t)if(Object.prototype.hasOwnProperty.call(t,n)){if(e.indexOf(n)>=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(t,v)),a=o.viewBox,c=o.position,l=o.value,d=o.children,y=o.content,m=o.className,b=o.textBreakAll;if(!a||i()(l)&&i()(d)&&!(0,n.isValidElement)(y)&&!u()(y))return null;if((0,n.isValidElement)(y))return(0,n.cloneElement)(y,o);if(u()(y)){if(e=(0,n.createElement)(y,o),(0,n.isValidElement)(e))return e}else e=w(o);var P="cx"in a&&(0,h.hj)(a.cx),E=(0,p.L6)(o,!0);if(P&&("insideStart"===c||"insideEnd"===c||"end"===c))return O(o,e,E);var k=P?j(o):S(o);return n.createElement(f.x,x({className:(0,s.Z)("recharts-label",void 0===m?"":m)},E,k,{breakAll:b}),e)}P.displayName="Label";var E=function(t){var e=t.cx,r=t.cy,n=t.angle,o=t.startAngle,i=t.endAngle,a=t.r,u=t.radius,c=t.innerRadius,l=t.outerRadius,s=t.x,f=t.y,p=t.top,d=t.left,y=t.width,v=t.height,m=t.clockWise,b=t.labelViewBox;if(b)return b;if((0,h.hj)(y)&&(0,h.hj)(v)){if((0,h.hj)(s)&&(0,h.hj)(f))return{x:s,y:f,width:y,height:v};if((0,h.hj)(p)&&(0,h.hj)(d))return{x:p,y:d,width:y,height:v}}return(0,h.hj)(s)&&(0,h.hj)(f)?{x:s,y:f,width:0,height:0}:(0,h.hj)(e)&&(0,h.hj)(r)?{cx:e,cy:r,startAngle:o||n||0,endAngle:i||n||0,innerRadius:c||0,outerRadius:l||u||a||0,clockWise:m}:t.viewBox?t.viewBox:{}};P.parseViewBox=E,P.renderCallByParent=function(t,e){var r,o,i=!(arguments.length>2)||void 0===arguments[2]||arguments[2];if(!t||!t.children&&i&&!t.label)return null;var a=t.children,c=E(t),s=(0,p.NN)(a,P).map(function(t,r){return(0,n.cloneElement)(t,{viewBox:e||c,key:"label-".concat(r)})});return i?[(r=t.label,o=e||c,r?!0===r?n.createElement(P,{key:"label-implicit",viewBox:o}):(0,h.P2)(r)?n.createElement(P,{key:"label-implicit",viewBox:o,value:r}):(0,n.isValidElement)(r)?r.type===P?(0,n.cloneElement)(r,{key:"label-implicit",viewBox:o}):n.createElement(P,{key:"label-implicit",content:r,viewBox:o}):u()(r)?n.createElement(P,{key:"label-implicit",content:r,viewBox:o}):l()(r)?n.createElement(P,x({viewBox:o},r,{key:"label-implicit"})):null:null)].concat(function(t){if(Array.isArray(t))return m(t)}(s)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(s)||function(t,e){if(t){if("string"==typeof t)return m(t,void 0);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return m(t,void 0)}}(s)||function(){throw TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()):s}},58772:function(t,e,r){"use strict";r.d(e,{e:function(){return P}});var n=r(2265),o=r(77571),i=r.n(o),a=r(28302),u=r.n(a),c=r(86757),l=r.n(c),s=r(86185),f=r.n(s),p=r(26680),h=r(9841),d=r(82944),y=r(85355);function v(t){return(v="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var m=["valueAccessor"],b=["data","dataKey","clockWise","id","textBreakAll"];function g(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);r=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}var S=function(t){return Array.isArray(t.value)?f()(t.value):t.value};function P(t){var e=t.valueAccessor,r=void 0===e?S:e,o=j(t,m),a=o.data,u=o.dataKey,c=o.clockWise,l=o.id,s=o.textBreakAll,f=j(o,b);return a&&a.length?n.createElement(h.m,{className:"recharts-label-list"},a.map(function(t,e){var o=i()(u)?r(t,e):(0,y.F$)(t&&t.payload,u),a=i()(l)?{}:{id:"".concat(l,"-").concat(e)};return n.createElement(p._,x({},(0,d.L6)(t,!0),f,a,{parentViewBox:t.parentViewBox,value:o,textBreakAll:s,viewBox:p._.parseViewBox(i()(c)?t:O(O({},t),{},{clockWise:c})),key:"label-".concat(e),index:e}))})):null}P.displayName="LabelList",P.renderCallByParent=function(t,e){var r,o=!(arguments.length>2)||void 0===arguments[2]||arguments[2];if(!t||!t.children&&o&&!t.label)return null;var i=t.children,a=(0,d.NN)(i,P).map(function(t,r){return(0,n.cloneElement)(t,{data:e,key:"labelList-".concat(r)})});return o?[(r=t.label)?!0===r?n.createElement(P,{key:"labelList-implicit",data:e}):n.isValidElement(r)||l()(r)?n.createElement(P,{key:"labelList-implicit",data:e,content:r}):u()(r)?n.createElement(P,x({data:e},r,{key:"labelList-implicit"})):null:null].concat(function(t){if(Array.isArray(t))return g(t)}(a)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(a)||function(t,e){if(t){if("string"==typeof t)return g(t,void 0);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return g(t,void 0)}}(a)||function(){throw TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()):a}},22190:function(t,e,r){"use strict";r.d(e,{D:function(){return N}});var n=r(2265),o=r(86757),i=r.n(o),a=r(61994),u=r(1175),c=r(48777),l=r(14870),s=r(41637);function f(t){return(f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function p(){return(p=Object.assign?Object.assign.bind():function(t){for(var e=1;e');var x=e.inactive?h:e.color;return n.createElement("li",p({className:b,style:y,key:"legend-item-".concat(r)},(0,s.bw)(t.props,e,r)),n.createElement(c.T,{width:o,height:o,viewBox:d,style:v},t.renderIcon(e)),n.createElement("span",{className:"recharts-legend-item-text",style:{color:x}},l?l(g,e,r):g))})}},{key:"render",value:function(){var t=this.props,e=t.payload,r=t.layout,o=t.align;return e&&e.length?n.createElement("ul",{className:"recharts-default-legend",style:{padding:0,margin:0,textAlign:"horizontal"===r?o:"left"}},this.renderItems()):null}}],function(t,e){for(var r=0;r1||Math.abs(e.height-this.lastBoundingBox.height)>1)&&(this.lastBoundingBox.width=e.width,this.lastBoundingBox.height=e.height,t&&t(e)):(-1!==this.lastBoundingBox.width||-1!==this.lastBoundingBox.height)&&(this.lastBoundingBox.width=-1,this.lastBoundingBox.height=-1,t&&t(null))}},{key:"getBBoxSnapshot",value:function(){return this.lastBoundingBox.width>=0&&this.lastBoundingBox.height>=0?P({},this.lastBoundingBox):{width:0,height:0}}},{key:"getDefaultPosition",value:function(t){var e,r,n=this.props,o=n.layout,i=n.align,a=n.verticalAlign,u=n.margin,c=n.chartWidth,l=n.chartHeight;return t&&(void 0!==t.left&&null!==t.left||void 0!==t.right&&null!==t.right)||(e="center"===i&&"vertical"===o?{left:((c||0)-this.getBBoxSnapshot().width)/2}:"right"===i?{right:u&&u.right||0}:{left:u&&u.left||0}),t&&(void 0!==t.top&&null!==t.top||void 0!==t.bottom&&null!==t.bottom)||(r="middle"===a?{top:((l||0)-this.getBBoxSnapshot().height)/2}:"bottom"===a?{bottom:u&&u.bottom||0}:{top:u&&u.top||0}),P(P({},e),r)}},{key:"render",value:function(){var t=this,e=this.props,r=e.content,o=e.width,i=e.height,a=e.wrapperStyle,u=e.payloadUniqBy,c=e.payload,l=P(P({position:"absolute",width:o||"auto",height:i||"auto"},this.getDefaultPosition(a)),a);return n.createElement("div",{className:"recharts-legend-wrapper",style:l,ref:function(e){t.wrapperNode=e}},function(t,e){if(n.isValidElement(t))return n.cloneElement(t,e);if("function"==typeof t)return n.createElement(t,e);e.ref;var r=function(t,e){if(null==t)return{};var r,n,o=function(t,e){if(null==t)return{};var r={};for(var n in t)if(Object.prototype.hasOwnProperty.call(t,n)){if(e.indexOf(n)>=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(e,j);return n.createElement(g,r)}(r,P(P({},this.props),{},{payload:(0,w.z)(c,u,C)})))}}],r=[{key:"getWithHeight",value:function(t,e){var r=P(P({},this.defaultProps),t.props).layout;return"vertical"===r&&(0,x.hj)(t.props.height)?{height:t.props.height}:"horizontal"===r?{width:t.props.width||e}:null}}],e&&E(o.prototype,e),r&&E(o,r),Object.defineProperty(o,"prototype",{writable:!1}),o}(n.PureComponent);_(N,"displayName","Legend"),_(N,"defaultProps",{iconSize:14,layout:"horizontal",align:"center",verticalAlign:"bottom"})},47625:function(t,e,r){"use strict";r.d(e,{h:function(){return d}});var n=r(61994),o=r(2265),i=r(37065),a=r.n(i),u=r(16630),c=r(1175),l=r(82944);function s(t){return(s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function f(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,n)}return r}function p(t){for(var e=1;et.length)&&(e=t.length);for(var r=0,n=Array(e);r0&&(t=a()(t,S,{trailing:!0,leading:!1}));var e=new ResizeObserver(t),r=M.current.getBoundingClientRect();return D(r.width,r.height),e.observe(M.current),function(){e.disconnect()}},[D,S]);var I=(0,o.useMemo)(function(){var t=C.containerWidth,e=C.containerHeight;if(t<0||e<0)return null;(0,c.Z)((0,u.hU)(y)||(0,u.hU)(m),"The width(%s) and height(%s) are both fixed numbers,\n maybe you don't need to use a ResponsiveContainer.",y,m),(0,c.Z)(!i||i>0,"The aspect(%s) must be greater than zero.",i);var r=(0,u.hU)(y)?t:y,n=(0,u.hU)(m)?e:m;i&&i>0&&(r?n=r/i:n&&(r=n*i),w&&n>w&&(n=w)),(0,c.Z)(r>0||n>0,"The width(%s) and height(%s) of chart should be greater than 0,\n please check the style of container, or the props width(%s) and height(%s),\n or add a minWidth(%s) or minHeight(%s) or use aspect(%s) to control the\n height and width.",r,n,y,m,g,x,i);var a=!Array.isArray(O)&&(0,l.Gf)(O.type).endsWith("Chart");return o.Children.map(O,function(t){return o.isValidElement(t)?(0,o.cloneElement)(t,p({width:r,height:n},a?{style:p({height:"100%",width:"100%",maxHeight:n,maxWidth:r},t.props.style)}:{})):t})},[i,O,m,w,x,g,C,y]);return o.createElement("div",{id:P?"".concat(P):void 0,className:(0,n.Z)("recharts-responsive-container",E),style:p(p({},void 0===A?{}:A),{},{width:y,height:m,minWidth:g,minHeight:x,maxHeight:w}),ref:M},I)})},58811:function(t,e,r){"use strict";r.d(e,{x:function(){return B}});var n=r(2265),o=r(77571),i=r.n(o),a=r(61994),u=r(16630),c=r(34067),l=r(82944),s=r(4094);function f(t){return(f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function p(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var r=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=r){var n,o,i,a,u=[],c=!0,l=!1;try{if(i=(r=r.call(t)).next,0===e){if(Object(r)!==r)return;c=!1}else for(;!(c=(n=i.call(r)).done)&&(u.push(n.value),u.length!==e);c=!0);}catch(t){l=!0,o=t}finally{try{if(!c&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(l)throw o}}return u}}(t,e)||function(t,e){if(t){if("string"==typeof t)return h(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return h(t,e)}}(t,e)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function h(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);r=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}function M(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var r=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=r){var n,o,i,a,u=[],c=!0,l=!1;try{if(i=(r=r.call(t)).next,0===e){if(Object(r)!==r)return;c=!1}else for(;!(c=(n=i.call(r)).done)&&(u.push(n.value),u.length!==e);c=!0);}catch(t){l=!0,o=t}finally{try{if(!c&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(l)throw o}}return u}}(t,e)||function(t,e){if(t){if("string"==typeof t)return _(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return _(t,e)}}(t,e)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function _(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);r0&&void 0!==arguments[0]?arguments[0]:[];return t.reduce(function(t,e){var i=e.word,a=e.width,u=t[t.length-1];return u&&(null==n||o||u.width+a+ra||e.reduce(function(t,e){return t.width>e.width?t:e}).width>Number(n),e]},y=0,v=c.length-1,m=0;y<=v&&m<=c.length-1;){var b=Math.floor((y+v)/2),g=M(d(b-1),2),x=g[0],w=g[1],O=M(d(b),1)[0];if(x||O||(y=b+1),x&&O&&(v=b-1),!x&&O){i=w;break}m++}return i||h},D=function(t){return[{words:i()(t)?[]:t.toString().split(T)}]},I=function(t){var e=t.width,r=t.scaleToFit,n=t.children,o=t.style,i=t.breakAll,a=t.maxLines;if((e||r)&&!c.x.isSsr){var u=C({breakAll:i,children:n,style:o});return u?N({breakAll:i,children:n,maxLines:a,style:o},u.wordsWithComputedWidth,u.spaceWidth,e,r):D(n)}return D(n)},L="#808080",B=function(t){var e,r=t.x,o=void 0===r?0:r,i=t.y,c=void 0===i?0:i,s=t.lineHeight,f=void 0===s?"1em":s,p=t.capHeight,h=void 0===p?"0.71em":p,d=t.scaleToFit,y=void 0!==d&&d,v=t.textAnchor,m=t.verticalAnchor,b=t.fill,g=void 0===b?L:b,x=A(t,P),w=(0,n.useMemo)(function(){return I({breakAll:x.breakAll,children:x.children,maxLines:x.maxLines,scaleToFit:y,style:x.style,width:x.width})},[x.breakAll,x.children,x.maxLines,y,x.style,x.width]),O=x.dx,j=x.dy,M=x.angle,_=x.className,T=x.breakAll,C=A(x,E);if(!(0,u.P2)(o)||!(0,u.P2)(c))return null;var N=o+((0,u.hj)(O)?O:0),D=c+((0,u.hj)(j)?j:0);switch(void 0===m?"end":m){case"start":e=S("calc(".concat(h,")"));break;case"middle":e=S("calc(".concat((w.length-1)/2," * -").concat(f," + (").concat(h," / 2))"));break;default:e=S("calc(".concat(w.length-1," * -").concat(f,")"))}var B=[];if(y){var R=w[0].width,z=x.width;B.push("scale(".concat(((0,u.hj)(z)?z/R:1)/R,")"))}return M&&B.push("rotate(".concat(M,", ").concat(N,", ").concat(D,")")),B.length&&(C.transform=B.join(" ")),n.createElement("text",k({},(0,l.L6)(C,!0),{x:N,y:D,className:(0,a.Z)("recharts-text",_),textAnchor:void 0===v?"start":v,fill:g.includes("url")?L:g}),w.map(function(t,r){var o=t.words.join(T?"":" ");return n.createElement("tspan",{x:N,dy:0===r?e:f,key:"".concat(o,"-").concat(r)},o)}))}},8147:function(t,e,r){"use strict";r.d(e,{u:function(){return $}});var n=r(2265),o=r(34935),i=r.n(o),a=r(77571),u=r.n(a),c=r(61994),l=r(16630);function s(t){return(s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function f(){return(f=Object.assign?Object.assign.bind():function(t){for(var e=1;et.length)&&(e=t.length);for(var r=0,n=Array(e);rc[n]+s?Math.max(f,c[n]):Math.max(p,c[n])}function O(t){return(O="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function j(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,n)}return r}function S(t){for(var e=1;e1||Math.abs(t.height-this.state.lastBoundingBox.height)>1)&&this.setState({lastBoundingBox:{width:t.width,height:t.height}})}else(-1!==this.state.lastBoundingBox.width||-1!==this.state.lastBoundingBox.height)&&this.setState({lastBoundingBox:{width:-1,height:-1}})}},{key:"componentDidMount",value:function(){document.addEventListener("keydown",this.handleKeyDown),this.updateBBox()}},{key:"componentWillUnmount",value:function(){document.removeEventListener("keydown",this.handleKeyDown)}},{key:"componentDidUpdate",value:function(){var t,e;this.props.active&&this.updateBBox(),this.state.dismissed&&((null===(t=this.props.coordinate)||void 0===t?void 0:t.x)!==this.state.dismissedAtCoordinate.x||(null===(e=this.props.coordinate)||void 0===e?void 0:e.y)!==this.state.dismissedAtCoordinate.y)&&(this.state.dismissed=!1)}},{key:"render",value:function(){var t,e,r,o,i,a,u,s,f,p,h,d,y,v,m,O,j,P,E,k=this,A=this.props,M=A.active,_=A.allowEscapeViewBox,T=A.animationDuration,C=A.animationEasing,N=A.children,D=A.coordinate,I=A.hasPayload,L=A.isAnimationActive,B=A.offset,R=A.position,z=A.reverseDirection,U=A.useTranslate3d,F=A.viewBox,$=A.wrapperStyle,q=(d=(t={allowEscapeViewBox:_,coordinate:D,offsetTopLeft:B,position:R,reverseDirection:z,tooltipBox:this.state.lastBoundingBox,useTranslate3d:U,viewBox:F}).allowEscapeViewBox,y=t.coordinate,v=t.offsetTopLeft,m=t.position,O=t.reverseDirection,j=t.tooltipBox,P=t.useTranslate3d,E=t.viewBox,j.height>0&&j.width>0&&y?(r=(e={translateX:p=w({allowEscapeViewBox:d,coordinate:y,key:"x",offsetTopLeft:v,position:m,reverseDirection:O,tooltipDimension:j.width,viewBox:E,viewBoxDimension:E.width}),translateY:h=w({allowEscapeViewBox:d,coordinate:y,key:"y",offsetTopLeft:v,position:m,reverseDirection:O,tooltipDimension:j.height,viewBox:E,viewBoxDimension:E.height}),useTranslate3d:P}).translateX,o=e.translateY,f={transform:e.useTranslate3d?"translate3d(".concat(r,"px, ").concat(o,"px, 0)"):"translate(".concat(r,"px, ").concat(o,"px)")}):f=x,{cssProperties:f,cssClasses:(a=(i={translateX:p,translateY:h,coordinate:y}).coordinate,u=i.translateX,s=i.translateY,(0,c.Z)(g,b(b(b(b({},"".concat(g,"-right"),(0,l.hj)(u)&&a&&(0,l.hj)(a.x)&&u>=a.x),"".concat(g,"-left"),(0,l.hj)(u)&&a&&(0,l.hj)(a.x)&&u=a.y),"".concat(g,"-top"),(0,l.hj)(s)&&a&&(0,l.hj)(a.y)&&s0;return n.createElement(_,{allowEscapeViewBox:i,animationDuration:a,animationEasing:u,isAnimationActive:f,active:o,coordinate:l,hasPayload:O,offset:p,position:y,reverseDirection:m,useTranslate3d:b,viewBox:g,wrapperStyle:x},(t=I(I({},this.props),{},{payload:w}),n.isValidElement(c)?n.cloneElement(c,t):"function"==typeof c?n.createElement(c,t):n.createElement(v,t)))}}],function(t,e){for(var r=0;r=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(t,a),s=(0,o.Z)("recharts-layer",c);return n.createElement("g",u({className:s},(0,i.L6)(l,!0),{ref:e}),r)})},48777:function(t,e,r){"use strict";r.d(e,{T:function(){return c}});var n=r(2265),o=r(61994),i=r(82944),a=["children","width","height","viewBox","className","style","title","desc"];function u(){return(u=Object.assign?Object.assign.bind():function(t){for(var e=1;e=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(t,a),y=l||{width:r,height:c,x:0,y:0},v=(0,o.Z)("recharts-surface",s);return n.createElement("svg",u({},(0,i.L6)(d,!0,"svg"),{className:v,width:r,height:c,style:f,viewBox:"".concat(y.x," ").concat(y.y," ").concat(y.width," ").concat(y.height)}),n.createElement("title",null,p),n.createElement("desc",null,h),e)}},25739:function(t,e,r){"use strict";r.d(e,{br:function(){return g},CW:function(){return O},Mw:function(){return A},zn:function(){return k},sp:function(){return x},qD:function(){return E},d2:function(){return P},bH:function(){return w},Ud:function(){return S},Nf:function(){return j}});var n=r(2265),o=r(69398),i=r(84173),a=r.n(i),u=r(32242),c=r.n(u),l=r(50967),s=r.n(l)()(function(t){return{x:t.left,y:t.top,width:t.width,height:t.height}},function(t){return["l",t.left,"t",t.top,"w",t.width,"h",t.height].join("")}),f=r(16630),p=(0,n.createContext)(void 0),h=(0,n.createContext)(void 0),d=(0,n.createContext)(void 0),y=(0,n.createContext)({}),v=(0,n.createContext)(void 0),m=(0,n.createContext)(0),b=(0,n.createContext)(0),g=function(t){var e=t.state,r=e.xAxisMap,o=e.yAxisMap,i=e.offset,a=t.clipPathId,u=t.children,c=t.width,l=t.height,f=s(i);return n.createElement(p.Provider,{value:r},n.createElement(h.Provider,{value:o},n.createElement(y.Provider,{value:i},n.createElement(d.Provider,{value:f},n.createElement(v.Provider,{value:a},n.createElement(m.Provider,{value:l},n.createElement(b.Provider,{value:c},u)))))))},x=function(){return(0,n.useContext)(v)},w=function(t){var e=(0,n.useContext)(p);null!=e||(0,o.Z)(!1);var r=e[t];return null!=r||(0,o.Z)(!1),r},O=function(){var t=(0,n.useContext)(p);return(0,f.Kt)(t)},j=function(){var t=(0,n.useContext)(h);return a()(t,function(t){return c()(t.domain,Number.isFinite)})||(0,f.Kt)(t)},S=function(t){var e=(0,n.useContext)(h);null!=e||(0,o.Z)(!1);var r=e[t];return null!=r||(0,o.Z)(!1),r},P=function(){return(0,n.useContext)(d)},E=function(){return(0,n.useContext)(y)},k=function(){return(0,n.useContext)(b)},A=function(){return(0,n.useContext)(m)}},57165:function(t,e,r){"use strict";r.d(e,{H:function(){return H}});var n=r(2265);function o(){}function i(t,e,r){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+r)/6)}function a(t){this._context=t}function u(t){this._context=t}function c(t){this._context=t}a.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:i(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:i(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},u.prototype={areaStart:o,areaEnd:o,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:i(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},c.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var r=(this._x0+4*this._x1+t)/6,n=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(r,n):this._context.moveTo(r,n);break;case 3:this._point=4;default:i(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};class l{constructor(t,e){this._context=t,this._x=e}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line}point(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._x?this._context.bezierCurveTo(this._x0=(this._x0+t)/2,this._y0,this._x0,e,t,e):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+e)/2,t,this._y0,t,e)}this._x0=t,this._y0=e}}function s(t){this._context=t}function f(t){this._context=t}function p(t){return new f(t)}function h(t,e,r){var n=t._x1-t._x0,o=e-t._x1,i=(t._y1-t._y0)/(n||o<0&&-0),a=(r-t._y1)/(o||n<0&&-0);return((i<0?-1:1)+(a<0?-1:1))*Math.min(Math.abs(i),Math.abs(a),.5*Math.abs((i*o+a*n)/(n+o)))||0}function d(t,e){var r=t._x1-t._x0;return r?(3*(t._y1-t._y0)/r-e)/2:e}function y(t,e,r){var n=t._x0,o=t._y0,i=t._x1,a=t._y1,u=(i-n)/3;t._context.bezierCurveTo(n+u,o+u*e,i-u,a-u*r,i,a)}function v(t){this._context=t}function m(t){this._context=new b(t)}function b(t){this._context=t}function g(t){this._context=t}function x(t){var e,r,n=t.length-1,o=Array(n),i=Array(n),a=Array(n);for(o[0]=0,i[0]=2,a[0]=t[0]+2*t[1],e=1;e=0;--e)o[e]=(a[e]-o[e+1])/i[e];for(e=0,i[n-1]=(t[n]+o[n-1])/2;e=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var r=this._x*(1-this._t)+t*this._t;this._context.lineTo(r,this._y),this._context.lineTo(r,e)}}this._x=t,this._y=e}};var O=r(22516),j=r(76115),S=r(67790);function P(t){return t[0]}function E(t){return t[1]}function k(t,e){var r=(0,j.Z)(!0),n=null,o=p,i=null,a=(0,S.d)(u);function u(u){var c,l,s,f=(u=(0,O.Z)(u)).length,p=!1;for(null==n&&(i=o(s=a())),c=0;c<=f;++c)!(c=f;--p)u.point(m[p],b[p]);u.lineEnd(),u.areaEnd()}}v&&(m[s]=+t(h,s,l),b[s]=+e(h,s,l),u.point(n?+n(h,s,l):m[s],r?+r(h,s,l):b[s]))}if(d)return u=null,d+""||null}function s(){return k().defined(o).curve(a).context(i)}return t="function"==typeof t?t:void 0===t?P:(0,j.Z)(+t),e="function"==typeof e?e:void 0===e?(0,j.Z)(0):(0,j.Z)(+e),r="function"==typeof r?r:void 0===r?E:(0,j.Z)(+r),l.x=function(e){return arguments.length?(t="function"==typeof e?e:(0,j.Z)(+e),n=null,l):t},l.x0=function(e){return arguments.length?(t="function"==typeof e?e:(0,j.Z)(+e),l):t},l.x1=function(t){return arguments.length?(n=null==t?null:"function"==typeof t?t:(0,j.Z)(+t),l):n},l.y=function(t){return arguments.length?(e="function"==typeof t?t:(0,j.Z)(+t),r=null,l):e},l.y0=function(t){return arguments.length?(e="function"==typeof t?t:(0,j.Z)(+t),l):e},l.y1=function(t){return arguments.length?(r=null==t?null:"function"==typeof t?t:(0,j.Z)(+t),l):r},l.lineX0=l.lineY0=function(){return s().x(t).y(e)},l.lineY1=function(){return s().x(t).y(r)},l.lineX1=function(){return s().x(n).y(e)},l.defined=function(t){return arguments.length?(o="function"==typeof t?t:(0,j.Z)(!!t),l):o},l.curve=function(t){return arguments.length?(a=t,null!=i&&(u=a(i)),l):a},l.context=function(t){return arguments.length?(null==t?i=u=null:u=a(i=t),l):i},l}var M=r(75551),_=r.n(M),T=r(86757),C=r.n(T),N=r(61994),D=r(41637),I=r(82944),L=r(16630);function B(t){return(B="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function R(){return(R=Object.assign?Object.assign.bind():function(t){for(var e=1;et.length)&&(e=t.length);for(var r=0,n=Array(e);r=0?1:-1,c=r>=0?1:-1,l=n>=0&&r>=0||n<0&&r<0?1:0;if(a>0&&o instanceof Array){for(var s=[0,0,0,0],f=0;f<4;f++)s[f]=o[f]>a?a:o[f];i="M".concat(t,",").concat(e+u*s[0]),s[0]>0&&(i+="A ".concat(s[0],",").concat(s[0],",0,0,").concat(l,",").concat(t+c*s[0],",").concat(e)),i+="L ".concat(t+r-c*s[1],",").concat(e),s[1]>0&&(i+="A ".concat(s[1],",").concat(s[1],",0,0,").concat(l,",\n ").concat(t+r,",").concat(e+u*s[1])),i+="L ".concat(t+r,",").concat(e+n-u*s[2]),s[2]>0&&(i+="A ".concat(s[2],",").concat(s[2],",0,0,").concat(l,",\n ").concat(t+r-c*s[2],",").concat(e+n)),i+="L ".concat(t+c*s[3],",").concat(e+n),s[3]>0&&(i+="A ".concat(s[3],",").concat(s[3],",0,0,").concat(l,",\n ").concat(t,",").concat(e+n-u*s[3])),i+="Z"}else if(a>0&&o===+o&&o>0){var p=Math.min(a,o);i="M ".concat(t,",").concat(e+u*p,"\n A ").concat(p,",").concat(p,",0,0,").concat(l,",").concat(t+c*p,",").concat(e,"\n L ").concat(t+r-c*p,",").concat(e,"\n A ").concat(p,",").concat(p,",0,0,").concat(l,",").concat(t+r,",").concat(e+u*p,"\n L ").concat(t+r,",").concat(e+n-u*p,"\n A ").concat(p,",").concat(p,",0,0,").concat(l,",").concat(t+r-c*p,",").concat(e+n,"\n L ").concat(t+c*p,",").concat(e+n,"\n A ").concat(p,",").concat(p,",0,0,").concat(l,",").concat(t,",").concat(e+n-u*p," Z")}else i="M ".concat(t,",").concat(e," h ").concat(r," v ").concat(n," h ").concat(-r," Z");return i},h=function(t,e){if(!t||!e)return!1;var r=t.x,n=t.y,o=e.x,i=e.y,a=e.width,u=e.height;return!!(Math.abs(a)>0&&Math.abs(u)>0)&&r>=Math.min(o,o+a)&&r<=Math.max(o,o+a)&&n>=Math.min(i,i+u)&&n<=Math.max(i,i+u)},d={x:0,y:0,width:0,height:0,radius:0,isAnimationActive:!1,isUpdateAnimationActive:!1,animationBegin:0,animationDuration:1500,animationEasing:"ease"},y=function(t){var e,r=f(f({},d),t),u=(0,n.useRef)(),s=function(t){if(Array.isArray(t))return t}(e=(0,n.useState)(-1))||function(t,e){var r=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=r){var n,o,i,a,u=[],c=!0,l=!1;try{for(i=(r=r.call(t)).next;!(c=(n=i.call(r)).done)&&(u.push(n.value),2!==u.length);c=!0);}catch(t){l=!0,o=t}finally{try{if(!c&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(l)throw o}}return u}}(e,2)||function(t,e){if(t){if("string"==typeof t)return l(t,2);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return l(t,2)}}(e,2)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(),h=s[0],y=s[1];(0,n.useEffect)(function(){if(u.current&&u.current.getTotalLength)try{var t=u.current.getTotalLength();t&&y(t)}catch(t){}},[]);var v=r.x,m=r.y,b=r.width,g=r.height,x=r.radius,w=r.className,O=r.animationEasing,j=r.animationDuration,S=r.animationBegin,P=r.isAnimationActive,E=r.isUpdateAnimationActive;if(v!==+v||m!==+m||b!==+b||g!==+g||0===b||0===g)return null;var k=(0,o.Z)("recharts-rectangle",w);return E?n.createElement(i.ZP,{canBegin:h>0,from:{width:b,height:g,x:v,y:m},to:{width:b,height:g,x:v,y:m},duration:j,animationEasing:O,isActive:E},function(t){var e=t.width,o=t.height,l=t.x,s=t.y;return n.createElement(i.ZP,{canBegin:h>0,from:"0px ".concat(-1===h?1:h,"px"),to:"".concat(h,"px 0px"),attributeName:"strokeDasharray",begin:S,duration:j,isActive:P,easing:O},n.createElement("path",c({},(0,a.L6)(r,!0),{className:k,d:p(l,s,e,o,x),ref:u})))}):n.createElement("path",c({},(0,a.L6)(r,!0),{className:k,d:p(v,m,b,g,x)}))}},60474:function(t,e,r){"use strict";r.d(e,{L:function(){return v}});var n=r(2265),o=r(61994),i=r(82944),a=r(39206),u=r(16630);function c(t){return(c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function l(){return(l=Object.assign?Object.assign.bind():function(t){for(var e=1;e180),",").concat(+(c>s),",\n ").concat(p.x,",").concat(p.y,"\n ");if(o>0){var d=(0,a.op)(r,n,o,c),y=(0,a.op)(r,n,o,s);h+="L ".concat(y.x,",").concat(y.y,"\n A ").concat(o,",").concat(o,",0,\n ").concat(+(Math.abs(l)>180),",").concat(+(c<=s),",\n ").concat(d.x,",").concat(d.y," Z")}else h+="L ".concat(r,",").concat(n," Z");return h},d=function(t){var e=t.cx,r=t.cy,n=t.innerRadius,o=t.outerRadius,i=t.cornerRadius,a=t.forceCornerRadius,c=t.cornerIsExternal,l=t.startAngle,s=t.endAngle,f=(0,u.uY)(s-l),d=p({cx:e,cy:r,radius:o,angle:l,sign:f,cornerRadius:i,cornerIsExternal:c}),y=d.circleTangency,v=d.lineTangency,m=d.theta,b=p({cx:e,cy:r,radius:o,angle:s,sign:-f,cornerRadius:i,cornerIsExternal:c}),g=b.circleTangency,x=b.lineTangency,w=b.theta,O=c?Math.abs(l-s):Math.abs(l-s)-m-w;if(O<0)return a?"M ".concat(v.x,",").concat(v.y,"\n a").concat(i,",").concat(i,",0,0,1,").concat(2*i,",0\n a").concat(i,",").concat(i,",0,0,1,").concat(-(2*i),",0\n "):h({cx:e,cy:r,innerRadius:n,outerRadius:o,startAngle:l,endAngle:s});var j="M ".concat(v.x,",").concat(v.y,"\n A").concat(i,",").concat(i,",0,0,").concat(+(f<0),",").concat(y.x,",").concat(y.y,"\n A").concat(o,",").concat(o,",0,").concat(+(O>180),",").concat(+(f<0),",").concat(g.x,",").concat(g.y,"\n A").concat(i,",").concat(i,",0,0,").concat(+(f<0),",").concat(x.x,",").concat(x.y,"\n ");if(n>0){var S=p({cx:e,cy:r,radius:n,angle:l,sign:f,isExternal:!0,cornerRadius:i,cornerIsExternal:c}),P=S.circleTangency,E=S.lineTangency,k=S.theta,A=p({cx:e,cy:r,radius:n,angle:s,sign:-f,isExternal:!0,cornerRadius:i,cornerIsExternal:c}),M=A.circleTangency,_=A.lineTangency,T=A.theta,C=c?Math.abs(l-s):Math.abs(l-s)-k-T;if(C<0&&0===i)return"".concat(j,"L").concat(e,",").concat(r,"Z");j+="L".concat(_.x,",").concat(_.y,"\n A").concat(i,",").concat(i,",0,0,").concat(+(f<0),",").concat(M.x,",").concat(M.y,"\n A").concat(n,",").concat(n,",0,").concat(+(C>180),",").concat(+(f>0),",").concat(P.x,",").concat(P.y,"\n A").concat(i,",").concat(i,",0,0,").concat(+(f<0),",").concat(E.x,",").concat(E.y,"Z")}else j+="L".concat(e,",").concat(r,"Z");return j},y={cx:0,cy:0,innerRadius:0,outerRadius:0,startAngle:0,endAngle:0,cornerRadius:0,forceCornerRadius:!1,cornerIsExternal:!1},v=function(t){var e,r=f(f({},y),t),a=r.cx,c=r.cy,s=r.innerRadius,p=r.outerRadius,v=r.cornerRadius,m=r.forceCornerRadius,b=r.cornerIsExternal,g=r.startAngle,x=r.endAngle,w=r.className;if(p0&&360>Math.abs(g-x)?d({cx:a,cy:c,innerRadius:s,outerRadius:p,cornerRadius:Math.min(S,j/2),forceCornerRadius:m,cornerIsExternal:b,startAngle:g,endAngle:x}):h({cx:a,cy:c,innerRadius:s,outerRadius:p,startAngle:g,endAngle:x}),n.createElement("path",l({},(0,i.L6)(r,!0),{className:O,d:e,role:"img"}))}},14870:function(t,e,r){"use strict";r.d(e,{v:function(){return N}});var n=r(2265),o=r(75551),i=r.n(o);let a=Math.cos,u=Math.sin,c=Math.sqrt,l=Math.PI,s=2*l;var f={draw(t,e){let r=c(e/l);t.moveTo(r,0),t.arc(0,0,r,0,s)}};let p=c(1/3),h=2*p,d=u(l/10)/u(7*l/10),y=u(s/10)*d,v=-a(s/10)*d,m=c(3),b=c(3)/2,g=1/c(12),x=(g/2+1)*3;var w=r(76115),O=r(67790);c(3),c(3);var j=r(61994),S=r(82944);function P(t){return(P="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var E=["type","size","sizeType"];function k(){return(k=Object.assign?Object.assign.bind():function(t){for(var e=1;e=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(t,E)),{},{type:o,size:u,sizeType:l}),p=s.className,h=s.cx,d=s.cy,y=(0,S.L6)(s,!0);return h===+h&&d===+d&&u===+u?n.createElement("path",k({},y,{className:(0,j.Z)("recharts-symbols",p),transform:"translate(".concat(h,", ").concat(d,")"),d:(e=_["symbol".concat(i()(o))]||f,(function(t,e){let r=null,n=(0,O.d)(o);function o(){let o;if(r||(r=o=n()),t.apply(this,arguments).draw(r,+e.apply(this,arguments)),o)return r=null,o+""||null}return t="function"==typeof t?t:(0,w.Z)(t||f),e="function"==typeof e?e:(0,w.Z)(void 0===e?64:+e),o.type=function(e){return arguments.length?(t="function"==typeof e?e:(0,w.Z)(e),o):t},o.size=function(t){return arguments.length?(e="function"==typeof t?t:(0,w.Z)(+t),o):e},o.context=function(t){return arguments.length?(r=null==t?null:t,o):r},o})().type(e).size(C(u,l,o))())})):null};N.registerSymbol=function(t,e){_["symbol".concat(i()(t))]=e}},11638:function(t,e,r){"use strict";r.d(e,{bn:function(){return C},a3:function(){return z},lT:function(){return N},V$:function(){return D},w7:function(){return I}});var n=r(2265),o=r(86757),i=r.n(o),a=r(90231),u=r.n(a),c=r(24342),l=r.n(c),s=r(21652),f=r.n(s),p=r(73649),h=r(61994),d=r(84735),y=r(82944);function v(t){return(v="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function m(){return(m=Object.assign?Object.assign.bind():function(t){for(var e=1;et.length)&&(e=t.length);for(var r=0,n=Array(e);r0,from:{upperWidth:0,lowerWidth:0,height:p,x:c,y:l},to:{upperWidth:s,lowerWidth:f,height:p,x:c,y:l},duration:j,animationEasing:g,isActive:P},function(t){var e=t.upperWidth,i=t.lowerWidth,u=t.height,c=t.x,l=t.y;return n.createElement(d.ZP,{canBegin:a>0,from:"0px ".concat(-1===a?1:a,"px"),to:"".concat(a,"px 0px"),attributeName:"strokeDasharray",begin:S,duration:j,easing:g},n.createElement("path",m({},(0,y.L6)(r,!0),{className:E,d:w(c,l,e,i,u),ref:o})))}):n.createElement("g",null,n.createElement("path",m({},(0,y.L6)(r,!0),{className:E,d:w(c,l,s,f,p)})))},S=r(60474),P=r(9841),E=r(14870),k=["option","shapeType","propTransformer","activeClassName","isActive"];function A(t){return(A="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function M(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,n)}return r}function _(t){for(var e=1;e=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(t,k);if((0,n.isValidElement)(r))e=(0,n.cloneElement)(r,_(_({},f),(0,n.isValidElement)(r)?r.props:r));else if(i()(r))e=r(f);else if(u()(r)&&!l()(r)){var p=(void 0===a?function(t,e){return _(_({},e),t)}:a)(r,f);e=n.createElement(T,{shapeType:o,elementProps:p})}else e=n.createElement(T,{shapeType:o,elementProps:f});return s?n.createElement(P.m,{className:void 0===c?"recharts-active-shape":c},e):e}function N(t,e){return null!=e&&"trapezoids"in t.props}function D(t,e){return null!=e&&"sectors"in t.props}function I(t,e){return null!=e&&"points"in t.props}function L(t,e){var r,n,o=t.x===(null==e||null===(r=e.labelViewBox)||void 0===r?void 0:r.x)||t.x===e.x,i=t.y===(null==e||null===(n=e.labelViewBox)||void 0===n?void 0:n.y)||t.y===e.y;return o&&i}function B(t,e){var r=t.endAngle===e.endAngle,n=t.startAngle===e.startAngle;return r&&n}function R(t,e){var r=t.x===e.x,n=t.y===e.y,o=t.z===e.z;return r&&n&&o}function z(t){var e,r,n,o=t.activeTooltipItem,i=t.graphicalItem,a=t.itemData,u=(N(i,o)?e="trapezoids":D(i,o)?e="sectors":I(i,o)&&(e="points"),e),c=N(i,o)?null===(r=o.tooltipPayload)||void 0===r||null===(r=r[0])||void 0===r||null===(r=r.payload)||void 0===r?void 0:r.payload:D(i,o)?null===(n=o.tooltipPayload)||void 0===n||null===(n=n[0])||void 0===n||null===(n=n.payload)||void 0===n?void 0:n.payload:I(i,o)?o.payload:{},l=a.filter(function(t,e){var r=f()(c,t),n=i.props[u].filter(function(t){var e;return(N(i,o)?e=L:D(i,o)?e=B:I(i,o)&&(e=R),e)(t,o)}),a=i.props[u].indexOf(n[n.length-1]);return r&&e===a});return a.indexOf(l[l.length-1])}},25311:function(t,e,r){"use strict";r.d(e,{Ky:function(){return w},O1:function(){return b},_b:function(){return g},t9:function(){return m},xE:function(){return O}});var n=r(41443),o=r.n(n),i=r(32242),a=r.n(i),u=r(85355),c=r(82944),l=r(16630),s=r(31699);function f(t){return(f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function p(t,e){for(var r=0;r0&&(A=Math.min((t||0)-(M[e-1]||0),A))}),Number.isFinite(A)){var _=A/k,T="vertical"===g.layout?r.height:r.width;if("gap"===g.padding&&(c=_*T/2),"no-gap"===g.padding){var C=(0,l.h1)(t.barCategoryGap,_*T),N=_*T/2;c=N-C-(N-C)/T*C}}}s="xAxis"===n?[r.left+(j.left||0)+(c||0),r.left+r.width-(j.right||0)-(c||0)]:"yAxis"===n?"horizontal"===f?[r.top+r.height-(j.bottom||0),r.top+(j.top||0)]:[r.top+(j.top||0)+(c||0),r.top+r.height-(j.bottom||0)-(c||0)]:g.range,P&&(s=[s[1],s[0]]);var D=(0,u.Hq)(g,o,m),I=D.scale,L=D.realScaleType;I.domain(w).range(s),(0,u.zF)(I);var B=(0,u.g$)(I,d(d({},g),{},{realScaleType:L}));"xAxis"===n?(b="top"===x&&!S||"bottom"===x&&S,p=r.left,h=v[E]-b*g.height):"yAxis"===n&&(b="left"===x&&!S||"right"===x&&S,p=v[E]-b*g.width,h=r.top);var R=d(d(d({},g),B),{},{realScaleType:L,x:p,y:h,scale:I,width:"xAxis"===n?r.width:g.width,height:"yAxis"===n?r.height:g.height});return R.bandSize=(0,u.zT)(R,B),g.hide||"xAxis"!==n?g.hide||(v[E]+=(b?-1:1)*R.width):v[E]+=(b?-1:1)*R.height,d(d({},i),{},y({},a,R))},{})},b=function(t,e){var r=t.x,n=t.y,o=e.x,i=e.y;return{x:Math.min(r,o),y:Math.min(n,i),width:Math.abs(o-r),height:Math.abs(i-n)}},g=function(t){return b({x:t.x1,y:t.y1},{x:t.x2,y:t.y2})},x=function(){var t,e;function r(t){!function(t,e){if(!(t instanceof e))throw TypeError("Cannot call a class as a function")}(this,r),this.scale=t}return t=[{key:"domain",get:function(){return this.scale.domain}},{key:"range",get:function(){return this.scale.range}},{key:"rangeMin",get:function(){return this.range()[0]}},{key:"rangeMax",get:function(){return this.range()[1]}},{key:"bandwidth",get:function(){return this.scale.bandwidth}},{key:"apply",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=e.bandAware,n=e.position;if(void 0!==t){if(n)switch(n){case"start":default:return this.scale(t);case"middle":var o=this.bandwidth?this.bandwidth()/2:0;return this.scale(t)+o;case"end":var i=this.bandwidth?this.bandwidth():0;return this.scale(t)+i}if(r){var a=this.bandwidth?this.bandwidth()/2:0;return this.scale(t)+a}return this.scale(t)}}},{key:"isInRange",value:function(t){var e=this.range(),r=e[0],n=e[e.length-1];return r<=n?t>=r&&t<=n:t>=n&&t<=r}}],e=[{key:"create",value:function(t){return new r(t)}}],t&&p(r.prototype,t),e&&p(r,e),Object.defineProperty(r,"prototype",{writable:!1}),r}();y(x,"EPS",1e-4);var w=function(t){var e=Object.keys(t).reduce(function(e,r){return d(d({},e),{},y({},r,x.create(t[r])))},{});return d(d({},e),{},{apply:function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=r.bandAware,i=r.position;return o()(t,function(t,r){return e[r].apply(t,{bandAware:n,position:i})})},isInRange:function(t){return a()(t,function(t,r){return e[r].isInRange(t)})}})},O=function(t){var e=t.width,r=t.height,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,o=(n%180+180)%180*Math.PI/180,i=Math.atan(r/e);return Math.abs(o>i&&otx(e,t()).base(e.base()),tj.o.apply(e,arguments),e}},scaleOrdinal:function(){return tX.Z},scalePoint:function(){return f.x},scalePow:function(){return tJ},scaleQuantile:function(){return function t(){var e,r=[],n=[],o=[];function i(){var t=0,e=Math.max(1,n.length);for(o=Array(e-1);++t=1)return+r(t[n-1],n-1,t);var n,o=(n-1)*e,i=Math.floor(o),a=+r(t[i],i,t);return a+(+r(t[i+1],i+1,t)-a)*(o-i)}}(r,t/e);return a}function a(t){return null==t||isNaN(t=+t)?e:n[P(o,t)]}return a.invertExtent=function(t){var e=n.indexOf(t);return e<0?[NaN,NaN]:[e>0?o[e-1]:r[0],e=o?[i[o-1],n]:[i[e-1],i[e]]},u.unknown=function(t){return arguments.length&&(e=t),u},u.thresholds=function(){return i.slice()},u.copy=function(){return t().domain([r,n]).range(a).unknown(e)},tj.o.apply(tI(u),arguments)}},scaleRadial:function(){return function t(){var e,r=tO(),n=[0,1],o=!1;function i(t){var n,i=Math.sign(n=r(t))*Math.sqrt(Math.abs(n));return isNaN(i)?e:o?Math.round(i):i}return i.invert=function(t){return r.invert(t1(t))},i.domain=function(t){return arguments.length?(r.domain(t),i):r.domain()},i.range=function(t){return arguments.length?(r.range((n=Array.from(t,td)).map(t1)),i):n.slice()},i.rangeRound=function(t){return i.range(t).round(!0)},i.round=function(t){return arguments.length?(o=!!t,i):o},i.clamp=function(t){return arguments.length?(r.clamp(t),i):r.clamp()},i.unknown=function(t){return arguments.length?(e=t,i):e},i.copy=function(){return t(r.domain(),n).round(o).clamp(r.clamp()).unknown(e)},tj.o.apply(i,arguments),tI(i)}},scaleSequential:function(){return function t(){var e=tI(rX()(tv));return e.copy=function(){return rG(e,t())},tj.O.apply(e,arguments)}},scaleSequentialLog:function(){return function t(){var e=tZ(rX()).domain([1,10]);return e.copy=function(){return rG(e,t()).base(e.base())},tj.O.apply(e,arguments)}},scaleSequentialPow:function(){return rV},scaleSequentialQuantile:function(){return function t(){var e=[],r=tv;function n(t){if(null!=t&&!isNaN(t=+t))return r((P(e,t,1)-1)/(e.length-1))}return n.domain=function(t){if(!arguments.length)return e.slice();for(let r of(e=[],t))null==r||isNaN(r=+r)||e.push(r);return e.sort(g),n},n.interpolator=function(t){return arguments.length?(r=t,n):r},n.range=function(){return e.map((t,n)=>r(n/(e.length-1)))},n.quantiles=function(t){return Array.from({length:t+1},(r,n)=>(function(t,e,r){if(!(!(n=(t=Float64Array.from(function*(t,e){if(void 0===e)for(let e of t)null!=e&&(e=+e)>=e&&(yield e);else{let r=-1;for(let n of t)null!=(n=e(n,++r,t))&&(n=+n)>=n&&(yield n)}}(t,void 0))).length)||isNaN(e=+e))){if(e<=0||n<2)return t5(t);if(e>=1)return t2(t);var n,o=(n-1)*e,i=Math.floor(o),a=t2((function t(e,r,n=0,o=1/0,i){if(r=Math.floor(r),n=Math.floor(Math.max(0,n)),o=Math.floor(Math.min(e.length-1,o)),!(n<=r&&r<=o))return e;for(i=void 0===i?t6:function(t=g){if(t===g)return t6;if("function"!=typeof t)throw TypeError("compare is not a function");return(e,r)=>{let n=t(e,r);return n||0===n?n:(0===t(r,r))-(0===t(e,e))}}(i);o>n;){if(o-n>600){let a=o-n+1,u=r-n+1,c=Math.log(a),l=.5*Math.exp(2*c/3),s=.5*Math.sqrt(c*l*(a-l)/a)*(u-a/2<0?-1:1),f=Math.max(n,Math.floor(r-u*l/a+s)),p=Math.min(o,Math.floor(r+(a-u)*l/a+s));t(e,r,f,p,i)}let a=e[r],u=n,c=o;for(t3(e,n,r),i(e[o],a)>0&&t3(e,n,o);ui(e[u],a);)++u;for(;i(e[c],a)>0;)--c}0===i(e[n],a)?t3(e,n,c):t3(e,++c,o),c<=r&&(n=c+1),r<=c&&(o=c-1)}return e})(t,i).subarray(0,i+1));return a+(t5(t.subarray(i+1))-a)*(o-i)}})(e,n/t))},n.copy=function(){return t(r).domain(e)},tj.O.apply(n,arguments)}},scaleSequentialSqrt:function(){return rK},scaleSequentialSymlog:function(){return function t(){var e=tH(rX());return e.copy=function(){return rG(e,t()).constant(e.constant())},tj.O.apply(e,arguments)}},scaleSqrt:function(){return t0},scaleSymlog:function(){return function t(){var e=tH(tw());return e.copy=function(){return tx(e,t()).constant(e.constant())},tj.o.apply(e,arguments)}},scaleThreshold:function(){return function t(){var e,r=[.5],n=[0,1],o=1;function i(t){return null!=t&&t<=t?n[P(r,t,0,o)]:e}return i.domain=function(t){return arguments.length?(o=Math.min((r=Array.from(t)).length,n.length-1),i):r.slice()},i.range=function(t){return arguments.length?(n=Array.from(t),o=Math.min(r.length,n.length-1),i):n.slice()},i.invertExtent=function(t){var e=n.indexOf(t);return[r[e-1],r[e]]},i.unknown=function(t){return arguments.length?(e=t,i):e},i.copy=function(){return t().domain(r).range(n).unknown(e)},tj.o.apply(i,arguments)}},scaleTime:function(){return rY},scaleUtc:function(){return rH},tickFormat:function(){return tD}});var f=r(55284);let p=Math.sqrt(50),h=Math.sqrt(10),d=Math.sqrt(2);function y(t,e,r){let n,o,i;let a=(e-t)/Math.max(0,r),u=Math.floor(Math.log10(a)),c=a/Math.pow(10,u),l=c>=p?10:c>=h?5:c>=d?2:1;return(u<0?(n=Math.round(t*(i=Math.pow(10,-u)/l)),o=Math.round(e*i),n/ie&&--o,i=-i):(n=Math.round(t/(i=Math.pow(10,u)*l)),o=Math.round(e/i),n*ie&&--o),o0))return[];if(t===e)return[t];let n=e=o))return[];let u=i-o+1,c=Array(u);if(n){if(a<0)for(let t=0;te?1:t>=e?0:NaN}function x(t,e){return null==t||null==e?NaN:et?1:e>=t?0:NaN}function w(t){let e,r,n;function o(t,n,o=0,i=t.length){if(o>>1;0>r(t[e],n)?o=e+1:i=e}while(og(t(e),r),n=(e,r)=>t(e)-r):(e=t===g||t===x?t:O,r=t,n=t),{left:o,center:function(t,e,r=0,i=t.length){let a=o(t,e,r,i-1);return a>r&&n(t[a-1],e)>-n(t[a],e)?a-1:a},right:function(t,n,o=0,i=t.length){if(o>>1;0>=r(t[e],n)?o=e+1:i=e}while(o>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):8===r?Z(e>>24&255,e>>16&255,e>>8&255,(255&e)/255):4===r?Z(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|240&e,((15&e)<<4|15&e)/255):null):(e=N.exec(t))?new Y(e[1],e[2],e[3],1):(e=D.exec(t))?new Y(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=I.exec(t))?Z(e[1],e[2],e[3],e[4]):(e=L.exec(t))?Z(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=B.exec(t))?Q(e[1],e[2]/100,e[3]/100,1):(e=R.exec(t))?Q(e[1],e[2]/100,e[3]/100,e[4]):z.hasOwnProperty(t)?q(z[t]):"transparent"===t?new Y(NaN,NaN,NaN,0):null}function q(t){return new Y(t>>16&255,t>>8&255,255&t,1)}function Z(t,e,r,n){return n<=0&&(t=e=r=NaN),new Y(t,e,r,n)}function W(t,e,r,n){var o;return 1==arguments.length?((o=t)instanceof A||(o=$(o)),o)?new Y((o=o.rgb()).r,o.g,o.b,o.opacity):new Y:new Y(t,e,r,null==n?1:n)}function Y(t,e,r,n){this.r=+t,this.g=+e,this.b=+r,this.opacity=+n}function H(){return`#${K(this.r)}${K(this.g)}${K(this.b)}`}function X(){let t=G(this.opacity);return`${1===t?"rgb(":"rgba("}${V(this.r)}, ${V(this.g)}, ${V(this.b)}${1===t?")":`, ${t})`}`}function G(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function V(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function K(t){return((t=V(t))<16?"0":"")+t.toString(16)}function Q(t,e,r,n){return n<=0?t=e=r=NaN:r<=0||r>=1?t=e=NaN:e<=0&&(t=NaN),new tt(t,e,r,n)}function J(t){if(t instanceof tt)return new tt(t.h,t.s,t.l,t.opacity);if(t instanceof A||(t=$(t)),!t)return new tt;if(t instanceof tt)return t;var e=(t=t.rgb()).r/255,r=t.g/255,n=t.b/255,o=Math.min(e,r,n),i=Math.max(e,r,n),a=NaN,u=i-o,c=(i+o)/2;return u?(a=e===i?(r-n)/u+(r0&&c<1?0:a,new tt(a,u,c,t.opacity)}function tt(t,e,r,n){this.h=+t,this.s=+e,this.l=+r,this.opacity=+n}function te(t){return(t=(t||0)%360)<0?t+360:t}function tr(t){return Math.max(0,Math.min(1,t||0))}function tn(t,e,r){return(t<60?e+(r-e)*t/60:t<180?r:t<240?e+(r-e)*(240-t)/60:e)*255}function to(t,e,r,n,o){var i=t*t,a=i*t;return((1-3*t+3*i-a)*e+(4-6*i+3*a)*r+(1+3*t+3*i-3*a)*n+a*o)/6}E(A,$,{copy(t){return Object.assign(new this.constructor,this,t)},displayable(){return this.rgb().displayable()},hex:U,formatHex:U,formatHex8:function(){return this.rgb().formatHex8()},formatHsl:function(){return J(this).formatHsl()},formatRgb:F,toString:F}),E(Y,W,k(A,{brighter(t){return t=null==t?1.4285714285714286:Math.pow(1.4285714285714286,t),new Y(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=null==t?.7:Math.pow(.7,t),new Y(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new Y(V(this.r),V(this.g),V(this.b),G(this.opacity))},displayable(){return -.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:H,formatHex:H,formatHex8:function(){return`#${K(this.r)}${K(this.g)}${K(this.b)}${K((isNaN(this.opacity)?1:this.opacity)*255)}`},formatRgb:X,toString:X})),E(tt,function(t,e,r,n){return 1==arguments.length?J(t):new tt(t,e,r,null==n?1:n)},k(A,{brighter(t){return t=null==t?1.4285714285714286:Math.pow(1.4285714285714286,t),new tt(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=null==t?.7:Math.pow(.7,t),new tt(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+(this.h<0)*360,e=isNaN(t)||isNaN(this.s)?0:this.s,r=this.l,n=r+(r<.5?r:1-r)*e,o=2*r-n;return new Y(tn(t>=240?t-240:t+120,o,n),tn(t,o,n),tn(t<120?t+240:t-120,o,n),this.opacity)},clamp(){return new tt(te(this.h),tr(this.s),tr(this.l),G(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){let t=G(this.opacity);return`${1===t?"hsl(":"hsla("}${te(this.h)}, ${100*tr(this.s)}%, ${100*tr(this.l)}%${1===t?")":`, ${t})`}`}}));var ti=t=>()=>t;function ta(t,e){var r=e-t;return r?function(e){return t+e*r}:ti(isNaN(t)?e:t)}var tu=function t(e){var r,n=1==(r=+(r=e))?ta:function(t,e){var n,o,i;return e-t?(n=t,o=e,n=Math.pow(n,i=r),o=Math.pow(o,i)-n,i=1/i,function(t){return Math.pow(n+t*o,i)}):ti(isNaN(t)?e:t)};function o(t,e){var r=n((t=W(t)).r,(e=W(e)).r),o=n(t.g,e.g),i=n(t.b,e.b),a=ta(t.opacity,e.opacity);return function(e){return t.r=r(e),t.g=o(e),t.b=i(e),t.opacity=a(e),t+""}}return o.gamma=t,o}(1);function tc(t){return function(e){var r,n,o=e.length,i=Array(o),a=Array(o),u=Array(o);for(r=0;r=1?(r=1,e-1):Math.floor(r*e),o=t[n],i=t[n+1],a=n>0?t[n-1]:2*o-i,u=nu&&(a=e.slice(u,a),l[c]?l[c]+=a:l[++c]=a),(o=o[0])===(i=i[0])?l[c]?l[c]+=i:l[++c]=i:(l[++c]=null,s.push({i:c,x:tl(o,i)})),u=tf.lastIndex;return ue&&(r=t,t=e,e=r),l=function(r){return Math.max(t,Math.min(e,r))}),n=c>2?tg:tb,o=i=null,f}function f(e){return null==e||isNaN(e=+e)?r:(o||(o=n(a.map(t),u,c)))(t(l(e)))}return f.invert=function(r){return l(e((i||(i=n(u,a.map(t),tl)))(r)))},f.domain=function(t){return arguments.length?(a=Array.from(t,td),s()):a.slice()},f.range=function(t){return arguments.length?(u=Array.from(t),s()):u.slice()},f.rangeRound=function(t){return u=Array.from(t),c=th,s()},f.clamp=function(t){return arguments.length?(l=!!t||tv,s()):l!==tv},f.interpolate=function(t){return arguments.length?(c=t,s()):c},f.unknown=function(t){return arguments.length?(r=t,f):r},function(r,n){return t=r,e=n,s()}}function tO(){return tw()(tv,tv)}var tj=r(89999),tS=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function tP(t){var e;if(!(e=tS.exec(t)))throw Error("invalid format: "+t);return new tE({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}function tE(t){this.fill=void 0===t.fill?" ":t.fill+"",this.align=void 0===t.align?">":t.align+"",this.sign=void 0===t.sign?"-":t.sign+"",this.symbol=void 0===t.symbol?"":t.symbol+"",this.zero=!!t.zero,this.width=void 0===t.width?void 0:+t.width,this.comma=!!t.comma,this.precision=void 0===t.precision?void 0:+t.precision,this.trim=!!t.trim,this.type=void 0===t.type?"":t.type+""}function tk(t,e){if((r=(t=e?t.toExponential(e-1):t.toExponential()).indexOf("e"))<0)return null;var r,n=t.slice(0,r);return[n.length>1?n[0]+n.slice(2):n,+t.slice(r+1)]}function tA(t){return(t=tk(Math.abs(t)))?t[1]:NaN}function tM(t,e){var r=tk(t,e);if(!r)return t+"";var n=r[0],o=r[1];return o<0?"0."+Array(-o).join("0")+n:n.length>o+1?n.slice(0,o+1)+"."+n.slice(o+1):n+Array(o-n.length+2).join("0")}tP.prototype=tE.prototype,tE.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};var t_={"%":(t,e)=>(100*t).toFixed(e),b:t=>Math.round(t).toString(2),c:t=>t+"",d:function(t){return Math.abs(t=Math.round(t))>=1e21?t.toLocaleString("en").replace(/,/g,""):t.toString(10)},e:(t,e)=>t.toExponential(e),f:(t,e)=>t.toFixed(e),g:(t,e)=>t.toPrecision(e),o:t=>Math.round(t).toString(8),p:(t,e)=>tM(100*t,e),r:tM,s:function(t,e){var r=tk(t,e);if(!r)return t+"";var o=r[0],i=r[1],a=i-(n=3*Math.max(-8,Math.min(8,Math.floor(i/3))))+1,u=o.length;return a===u?o:a>u?o+Array(a-u+1).join("0"):a>0?o.slice(0,a)+"."+o.slice(a):"0."+Array(1-a).join("0")+tk(t,Math.max(0,e+a-1))[0]},X:t=>Math.round(t).toString(16).toUpperCase(),x:t=>Math.round(t).toString(16)};function tT(t){return t}var tC=Array.prototype.map,tN=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"];function tD(t,e,r,n){var o,u,c=b(t,e,r);switch((n=tP(null==n?",f":n)).type){case"s":var l=Math.max(Math.abs(t),Math.abs(e));return null!=n.precision||isNaN(u=Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(tA(l)/3)))-tA(Math.abs(c))))||(n.precision=u),a(n,l);case"":case"e":case"g":case"p":case"r":null!=n.precision||isNaN(u=Math.max(0,tA(Math.abs(Math.max(Math.abs(t),Math.abs(e)))-(o=Math.abs(o=c)))-tA(o))+1)||(n.precision=u-("e"===n.type));break;case"f":case"%":null!=n.precision||isNaN(u=Math.max(0,-tA(Math.abs(c))))||(n.precision=u-("%"===n.type)*2)}return i(n)}function tI(t){var e=t.domain;return t.ticks=function(t){var r=e();return v(r[0],r[r.length-1],null==t?10:t)},t.tickFormat=function(t,r){var n=e();return tD(n[0],n[n.length-1],null==t?10:t,r)},t.nice=function(r){null==r&&(r=10);var n,o,i=e(),a=0,u=i.length-1,c=i[a],l=i[u],s=10;for(l0;){if((o=m(c,l,r))===n)return i[a]=c,i[u]=l,e(i);if(o>0)c=Math.floor(c/o)*o,l=Math.ceil(l/o)*o;else if(o<0)c=Math.ceil(c*o)/o,l=Math.floor(l*o)/o;else break;n=o}return t},t}function tL(){var t=tO();return t.copy=function(){return tx(t,tL())},tj.o.apply(t,arguments),tI(t)}function tB(t,e){t=t.slice();var r,n=0,o=t.length-1,i=t[n],a=t[o];return a-t(-e,r)}function tZ(t){let e,r;let n=t(tR,tz),o=n.domain,a=10;function u(){var i,u;return e=(i=a)===Math.E?Math.log:10===i&&Math.log10||2===i&&Math.log2||(i=Math.log(i),t=>Math.log(t)/i),r=10===(u=a)?t$:u===Math.E?Math.exp:t=>Math.pow(u,t),o()[0]<0?(e=tq(e),r=tq(r),t(tU,tF)):t(tR,tz),n}return n.base=function(t){return arguments.length?(a=+t,u()):a},n.domain=function(t){return arguments.length?(o(t),u()):o()},n.ticks=t=>{let n,i;let u=o(),c=u[0],l=u[u.length-1],s=l0){for(;f<=p;++f)for(n=1;nl)break;d.push(i)}}else for(;f<=p;++f)for(n=a-1;n>=1;--n)if(!((i=f>0?n/r(-f):n*r(f))l)break;d.push(i)}2*d.length{if(null==t&&(t=10),null==o&&(o=10===a?"s":","),"function"!=typeof o&&(a%1||null!=(o=tP(o)).precision||(o.trim=!0),o=i(o)),t===1/0)return o;let u=Math.max(1,a*t/n.ticks().length);return t=>{let n=t/r(Math.round(e(t)));return n*ao(tB(o(),{floor:t=>r(Math.floor(e(t))),ceil:t=>r(Math.ceil(e(t)))})),n}function tW(t){return function(e){return Math.sign(e)*Math.log1p(Math.abs(e/t))}}function tY(t){return function(e){return Math.sign(e)*Math.expm1(Math.abs(e))*t}}function tH(t){var e=1,r=t(tW(1),tY(e));return r.constant=function(r){return arguments.length?t(tW(e=+r),tY(e)):e},tI(r)}i=(o=function(t){var e,r,o,i=void 0===t.grouping||void 0===t.thousands?tT:(e=tC.call(t.grouping,Number),r=t.thousands+"",function(t,n){for(var o=t.length,i=[],a=0,u=e[0],c=0;o>0&&u>0&&(c+u+1>n&&(u=Math.max(1,n-c)),i.push(t.substring(o-=u,o+u)),!((c+=u+1)>n));)u=e[a=(a+1)%e.length];return i.reverse().join(r)}),a=void 0===t.currency?"":t.currency[0]+"",u=void 0===t.currency?"":t.currency[1]+"",c=void 0===t.decimal?".":t.decimal+"",l=void 0===t.numerals?tT:(o=tC.call(t.numerals,String),function(t){return t.replace(/[0-9]/g,function(t){return o[+t]})}),s=void 0===t.percent?"%":t.percent+"",f=void 0===t.minus?"−":t.minus+"",p=void 0===t.nan?"NaN":t.nan+"";function h(t){var e=(t=tP(t)).fill,r=t.align,o=t.sign,h=t.symbol,d=t.zero,y=t.width,v=t.comma,m=t.precision,b=t.trim,g=t.type;"n"===g?(v=!0,g="g"):t_[g]||(void 0===m&&(m=12),b=!0,g="g"),(d||"0"===e&&"="===r)&&(d=!0,e="0",r="=");var x="$"===h?a:"#"===h&&/[boxX]/.test(g)?"0"+g.toLowerCase():"",w="$"===h?u:/[%p]/.test(g)?s:"",O=t_[g],j=/[defgprs%]/.test(g);function S(t){var a,u,s,h=x,S=w;if("c"===g)S=O(t)+S,t="";else{var P=(t=+t)<0||1/t<0;if(t=isNaN(t)?p:O(Math.abs(t),m),b&&(t=function(t){e:for(var e,r=t.length,n=1,o=-1;n0&&(o=0)}return o>0?t.slice(0,o)+t.slice(e+1):t}(t)),P&&0==+t&&"+"!==o&&(P=!1),h=(P?"("===o?o:f:"-"===o||"("===o?"":o)+h,S=("s"===g?tN[8+n/3]:"")+S+(P&&"("===o?")":""),j){for(a=-1,u=t.length;++a(s=t.charCodeAt(a))||s>57){S=(46===s?c+t.slice(a+1):t.slice(a))+S,t=t.slice(0,a);break}}}v&&!d&&(t=i(t,1/0));var E=h.length+t.length+S.length,k=E>1)+h+t+S+k.slice(E);break;default:t=k+h+t+S}return l(t)}return m=void 0===m?6:/[gprs]/.test(g)?Math.max(1,Math.min(21,m)):Math.max(0,Math.min(20,m)),S.toString=function(){return t+""},S}return{format:h,formatPrefix:function(t,e){var r=h(((t=tP(t)).type="f",t)),n=3*Math.max(-8,Math.min(8,Math.floor(tA(e)/3))),o=Math.pow(10,-n),i=tN[8+n/3];return function(t){return r(o*t)+i}}}}({thousands:",",grouping:[3],currency:["$",""]})).format,a=o.formatPrefix;var tX=r(36967);function tG(t){return function(e){return e<0?-Math.pow(-e,t):Math.pow(e,t)}}function tV(t){return t<0?-Math.sqrt(-t):Math.sqrt(t)}function tK(t){return t<0?-t*t:t*t}function tQ(t){var e=t(tv,tv),r=1;return e.exponent=function(e){return arguments.length?1==(r=+e)?t(tv,tv):.5===r?t(tV,tK):t(tG(r),tG(1/r)):r},tI(e)}function tJ(){var t=tQ(tw());return t.copy=function(){return tx(t,tJ()).exponent(t.exponent())},tj.o.apply(t,arguments),t}function t0(){return tJ.apply(null,arguments).exponent(.5)}function t1(t){return Math.sign(t)*t*t}function t2(t,e){let r;if(void 0===e)for(let e of t)null!=e&&(r=e)&&(r=e);else{let n=-1;for(let o of t)null!=(o=e(o,++n,t))&&(r=o)&&(r=o)}return r}function t5(t,e){let r;if(void 0===e)for(let e of t)null!=e&&(r>e||void 0===r&&e>=e)&&(r=e);else{let n=-1;for(let o of t)null!=(o=e(o,++n,t))&&(r>o||void 0===r&&o>=o)&&(r=o)}return r}function t6(t,e){return(null==t||!(t>=t))-(null==e||!(e>=e))||(te?1:0)}function t3(t,e,r){let n=t[e];t[e]=t[r],t[r]=n}let t7=new Date,t4=new Date;function t8(t,e,r,n){function o(e){return t(e=0==arguments.length?new Date:new Date(+e)),e}return o.floor=e=>(t(e=new Date(+e)),e),o.ceil=r=>(t(r=new Date(r-1)),e(r,1),t(r),r),o.round=t=>{let e=o(t),r=o.ceil(t);return t-e(e(t=new Date(+t),null==r?1:Math.floor(r)),t),o.range=(r,n,i)=>{let a;let u=[];if(r=o.ceil(r),i=null==i?1:Math.floor(i),!(r0))return u;do u.push(a=new Date(+r)),e(r,i),t(r);while(at8(e=>{if(e>=e)for(;t(e),!r(e);)e.setTime(e-1)},(t,n)=>{if(t>=t){if(n<0)for(;++n<=0;)for(;e(t,-1),!r(t););else for(;--n>=0;)for(;e(t,1),!r(t););}}),r&&(o.count=(e,n)=>(t7.setTime(+e),t4.setTime(+n),t(t7),t(t4),Math.floor(r(t7,t4))),o.every=t=>isFinite(t=Math.floor(t))&&t>0?t>1?o.filter(n?e=>n(e)%t==0:e=>o.count(0,e)%t==0):o:null),o}let t9=t8(()=>{},(t,e)=>{t.setTime(+t+e)},(t,e)=>e-t);t9.every=t=>isFinite(t=Math.floor(t))&&t>0?t>1?t8(e=>{e.setTime(Math.floor(e/t)*t)},(e,r)=>{e.setTime(+e+r*t)},(e,r)=>(r-e)/t):t9:null,t9.range;let et=t8(t=>{t.setTime(t-t.getMilliseconds())},(t,e)=>{t.setTime(+t+1e3*e)},(t,e)=>(e-t)/1e3,t=>t.getUTCSeconds());et.range;let ee=t8(t=>{t.setTime(t-t.getMilliseconds()-1e3*t.getSeconds())},(t,e)=>{t.setTime(+t+6e4*e)},(t,e)=>(e-t)/6e4,t=>t.getMinutes());ee.range;let er=t8(t=>{t.setUTCSeconds(0,0)},(t,e)=>{t.setTime(+t+6e4*e)},(t,e)=>(e-t)/6e4,t=>t.getUTCMinutes());er.range;let en=t8(t=>{t.setTime(t-t.getMilliseconds()-1e3*t.getSeconds()-6e4*t.getMinutes())},(t,e)=>{t.setTime(+t+36e5*e)},(t,e)=>(e-t)/36e5,t=>t.getHours());en.range;let eo=t8(t=>{t.setUTCMinutes(0,0,0)},(t,e)=>{t.setTime(+t+36e5*e)},(t,e)=>(e-t)/36e5,t=>t.getUTCHours());eo.range;let ei=t8(t=>t.setHours(0,0,0,0),(t,e)=>t.setDate(t.getDate()+e),(t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*6e4)/864e5,t=>t.getDate()-1);ei.range;let ea=t8(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/864e5,t=>t.getUTCDate()-1);ea.range;let eu=t8(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/864e5,t=>Math.floor(t/864e5));function ec(t){return t8(e=>{e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)},(t,e)=>{t.setDate(t.getDate()+7*e)},(t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*6e4)/6048e5)}eu.range;let el=ec(0),es=ec(1),ef=ec(2),ep=ec(3),eh=ec(4),ed=ec(5),ey=ec(6);function ev(t){return t8(e=>{e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+7*e)},(t,e)=>(e-t)/6048e5)}el.range,es.range,ef.range,ep.range,eh.range,ed.range,ey.range;let em=ev(0),eb=ev(1),eg=ev(2),ex=ev(3),ew=ev(4),eO=ev(5),ej=ev(6);em.range,eb.range,eg.range,ex.range,ew.range,eO.range,ej.range;let eS=t8(t=>{t.setDate(1),t.setHours(0,0,0,0)},(t,e)=>{t.setMonth(t.getMonth()+e)},(t,e)=>e.getMonth()-t.getMonth()+(e.getFullYear()-t.getFullYear())*12,t=>t.getMonth());eS.range;let eP=t8(t=>{t.setUTCDate(1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCMonth(t.getUTCMonth()+e)},(t,e)=>e.getUTCMonth()-t.getUTCMonth()+(e.getUTCFullYear()-t.getUTCFullYear())*12,t=>t.getUTCMonth());eP.range;let eE=t8(t=>{t.setMonth(0,1),t.setHours(0,0,0,0)},(t,e)=>{t.setFullYear(t.getFullYear()+e)},(t,e)=>e.getFullYear()-t.getFullYear(),t=>t.getFullYear());eE.every=t=>isFinite(t=Math.floor(t))&&t>0?t8(e=>{e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)},(e,r)=>{e.setFullYear(e.getFullYear()+r*t)}):null,eE.range;let ek=t8(t=>{t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCFullYear(t.getUTCFullYear()+e)},(t,e)=>e.getUTCFullYear()-t.getUTCFullYear(),t=>t.getUTCFullYear());function eA(t,e,r,n,o,i){let a=[[et,1,1e3],[et,5,5e3],[et,15,15e3],[et,30,3e4],[i,1,6e4],[i,5,3e5],[i,15,9e5],[i,30,18e5],[o,1,36e5],[o,3,108e5],[o,6,216e5],[o,12,432e5],[n,1,864e5],[n,2,1728e5],[r,1,6048e5],[e,1,2592e6],[e,3,7776e6],[t,1,31536e6]];function u(e,r,n){let o=Math.abs(r-e)/n,i=w(([,,t])=>t).right(a,o);if(i===a.length)return t.every(b(e/31536e6,r/31536e6,n));if(0===i)return t9.every(Math.max(b(e,r,n),1));let[u,c]=a[o/a[i-1][2]isFinite(t=Math.floor(t))&&t>0?t8(e=>{e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)},(e,r)=>{e.setUTCFullYear(e.getUTCFullYear()+r*t)}):null,ek.range;let[eM,e_]=eA(ek,eP,em,eu,eo,er),[eT,eC]=eA(eE,eS,el,ei,en,ee);function eN(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function eD(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function eI(t,e,r){return{y:t,m:e,d:r,H:0,M:0,S:0,L:0}}var eL={"-":"",_:" ",0:"0"},eB=/^\s*\d+/,eR=/^%/,ez=/[\\^$*+?|[\]().{}]/g;function eU(t,e,r){var n=t<0?"-":"",o=(n?-t:t)+"",i=o.length;return n+(i[t.toLowerCase(),e]))}function eZ(t,e,r){var n=eB.exec(e.slice(r,r+1));return n?(t.w=+n[0],r+n[0].length):-1}function eW(t,e,r){var n=eB.exec(e.slice(r,r+1));return n?(t.u=+n[0],r+n[0].length):-1}function eY(t,e,r){var n=eB.exec(e.slice(r,r+2));return n?(t.U=+n[0],r+n[0].length):-1}function eH(t,e,r){var n=eB.exec(e.slice(r,r+2));return n?(t.V=+n[0],r+n[0].length):-1}function eX(t,e,r){var n=eB.exec(e.slice(r,r+2));return n?(t.W=+n[0],r+n[0].length):-1}function eG(t,e,r){var n=eB.exec(e.slice(r,r+4));return n?(t.y=+n[0],r+n[0].length):-1}function eV(t,e,r){var n=eB.exec(e.slice(r,r+2));return n?(t.y=+n[0]+(+n[0]>68?1900:2e3),r+n[0].length):-1}function eK(t,e,r){var n=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(r,r+6));return n?(t.Z=n[1]?0:-(n[2]+(n[3]||"00")),r+n[0].length):-1}function eQ(t,e,r){var n=eB.exec(e.slice(r,r+1));return n?(t.q=3*n[0]-3,r+n[0].length):-1}function eJ(t,e,r){var n=eB.exec(e.slice(r,r+2));return n?(t.m=n[0]-1,r+n[0].length):-1}function e0(t,e,r){var n=eB.exec(e.slice(r,r+2));return n?(t.d=+n[0],r+n[0].length):-1}function e1(t,e,r){var n=eB.exec(e.slice(r,r+3));return n?(t.m=0,t.d=+n[0],r+n[0].length):-1}function e2(t,e,r){var n=eB.exec(e.slice(r,r+2));return n?(t.H=+n[0],r+n[0].length):-1}function e5(t,e,r){var n=eB.exec(e.slice(r,r+2));return n?(t.M=+n[0],r+n[0].length):-1}function e6(t,e,r){var n=eB.exec(e.slice(r,r+2));return n?(t.S=+n[0],r+n[0].length):-1}function e3(t,e,r){var n=eB.exec(e.slice(r,r+3));return n?(t.L=+n[0],r+n[0].length):-1}function e7(t,e,r){var n=eB.exec(e.slice(r,r+6));return n?(t.L=Math.floor(n[0]/1e3),r+n[0].length):-1}function e4(t,e,r){var n=eR.exec(e.slice(r,r+1));return n?r+n[0].length:-1}function e8(t,e,r){var n=eB.exec(e.slice(r));return n?(t.Q=+n[0],r+n[0].length):-1}function e9(t,e,r){var n=eB.exec(e.slice(r));return n?(t.s=+n[0],r+n[0].length):-1}function rt(t,e){return eU(t.getDate(),e,2)}function re(t,e){return eU(t.getHours(),e,2)}function rr(t,e){return eU(t.getHours()%12||12,e,2)}function rn(t,e){return eU(1+ei.count(eE(t),t),e,3)}function ro(t,e){return eU(t.getMilliseconds(),e,3)}function ri(t,e){return ro(t,e)+"000"}function ra(t,e){return eU(t.getMonth()+1,e,2)}function ru(t,e){return eU(t.getMinutes(),e,2)}function rc(t,e){return eU(t.getSeconds(),e,2)}function rl(t){var e=t.getDay();return 0===e?7:e}function rs(t,e){return eU(el.count(eE(t)-1,t),e,2)}function rf(t){var e=t.getDay();return e>=4||0===e?eh(t):eh.ceil(t)}function rp(t,e){return t=rf(t),eU(eh.count(eE(t),t)+(4===eE(t).getDay()),e,2)}function rh(t){return t.getDay()}function rd(t,e){return eU(es.count(eE(t)-1,t),e,2)}function ry(t,e){return eU(t.getFullYear()%100,e,2)}function rv(t,e){return eU((t=rf(t)).getFullYear()%100,e,2)}function rm(t,e){return eU(t.getFullYear()%1e4,e,4)}function rb(t,e){var r=t.getDay();return eU((t=r>=4||0===r?eh(t):eh.ceil(t)).getFullYear()%1e4,e,4)}function rg(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+eU(e/60|0,"0",2)+eU(e%60,"0",2)}function rx(t,e){return eU(t.getUTCDate(),e,2)}function rw(t,e){return eU(t.getUTCHours(),e,2)}function rO(t,e){return eU(t.getUTCHours()%12||12,e,2)}function rj(t,e){return eU(1+ea.count(ek(t),t),e,3)}function rS(t,e){return eU(t.getUTCMilliseconds(),e,3)}function rP(t,e){return rS(t,e)+"000"}function rE(t,e){return eU(t.getUTCMonth()+1,e,2)}function rk(t,e){return eU(t.getUTCMinutes(),e,2)}function rA(t,e){return eU(t.getUTCSeconds(),e,2)}function rM(t){var e=t.getUTCDay();return 0===e?7:e}function r_(t,e){return eU(em.count(ek(t)-1,t),e,2)}function rT(t){var e=t.getUTCDay();return e>=4||0===e?ew(t):ew.ceil(t)}function rC(t,e){return t=rT(t),eU(ew.count(ek(t),t)+(4===ek(t).getUTCDay()),e,2)}function rN(t){return t.getUTCDay()}function rD(t,e){return eU(eb.count(ek(t)-1,t),e,2)}function rI(t,e){return eU(t.getUTCFullYear()%100,e,2)}function rL(t,e){return eU((t=rT(t)).getUTCFullYear()%100,e,2)}function rB(t,e){return eU(t.getUTCFullYear()%1e4,e,4)}function rR(t,e){var r=t.getUTCDay();return eU((t=r>=4||0===r?ew(t):ew.ceil(t)).getUTCFullYear()%1e4,e,4)}function rz(){return"+0000"}function rU(){return"%"}function rF(t){return+t}function r$(t){return Math.floor(+t/1e3)}function rq(t){return new Date(t)}function rZ(t){return t instanceof Date?+t:+new Date(+t)}function rW(t,e,r,n,o,i,a,u,c,l){var s=tO(),f=s.invert,p=s.domain,h=l(".%L"),d=l(":%S"),y=l("%I:%M"),v=l("%I %p"),m=l("%a %d"),b=l("%b %d"),g=l("%B"),x=l("%Y");function w(t){return(c(t)1)for(var r,n,o,i=1,a=t[e[0]],u=a.length;i=12)]},q:function(t){return 1+~~(t.getMonth()/3)},Q:rF,s:r$,S:rc,u:rl,U:rs,V:rp,w:rh,W:rd,x:null,X:null,y:ry,Y:rm,Z:rg,"%":rU},x={a:function(t){return a[t.getUTCDay()]},A:function(t){return i[t.getUTCDay()]},b:function(t){return c[t.getUTCMonth()]},B:function(t){return u[t.getUTCMonth()]},c:null,d:rx,e:rx,f:rP,g:rL,G:rR,H:rw,I:rO,j:rj,L:rS,m:rE,M:rk,p:function(t){return o[+(t.getUTCHours()>=12)]},q:function(t){return 1+~~(t.getUTCMonth()/3)},Q:rF,s:r$,S:rA,u:rM,U:r_,V:rC,w:rN,W:rD,x:null,X:null,y:rI,Y:rB,Z:rz,"%":rU},w={a:function(t,e,r){var n=h.exec(e.slice(r));return n?(t.w=d.get(n[0].toLowerCase()),r+n[0].length):-1},A:function(t,e,r){var n=f.exec(e.slice(r));return n?(t.w=p.get(n[0].toLowerCase()),r+n[0].length):-1},b:function(t,e,r){var n=m.exec(e.slice(r));return n?(t.m=b.get(n[0].toLowerCase()),r+n[0].length):-1},B:function(t,e,r){var n=y.exec(e.slice(r));return n?(t.m=v.get(n[0].toLowerCase()),r+n[0].length):-1},c:function(t,r,n){return S(t,e,r,n)},d:e0,e:e0,f:e7,g:eV,G:eG,H:e2,I:e2,j:e1,L:e3,m:eJ,M:e5,p:function(t,e,r){var n=l.exec(e.slice(r));return n?(t.p=s.get(n[0].toLowerCase()),r+n[0].length):-1},q:eQ,Q:e8,s:e9,S:e6,u:eW,U:eY,V:eH,w:eZ,W:eX,x:function(t,e,n){return S(t,r,e,n)},X:function(t,e,r){return S(t,n,e,r)},y:eV,Y:eG,Z:eK,"%":e4};function O(t,e){return function(r){var n,o,i,a=[],u=-1,c=0,l=t.length;for(r instanceof Date||(r=new Date(+r));++u53)return null;"w"in i||(i.w=1),"Z"in i?(n=(o=(n=eD(eI(i.y,0,1))).getUTCDay())>4||0===o?eb.ceil(n):eb(n),n=ea.offset(n,(i.V-1)*7),i.y=n.getUTCFullYear(),i.m=n.getUTCMonth(),i.d=n.getUTCDate()+(i.w+6)%7):(n=(o=(n=eN(eI(i.y,0,1))).getDay())>4||0===o?es.ceil(n):es(n),n=ei.offset(n,(i.V-1)*7),i.y=n.getFullYear(),i.m=n.getMonth(),i.d=n.getDate()+(i.w+6)%7)}else("W"in i||"U"in i)&&("w"in i||(i.w="u"in i?i.u%7:"W"in i?1:0),o="Z"in i?eD(eI(i.y,0,1)).getUTCDay():eN(eI(i.y,0,1)).getDay(),i.m=0,i.d="W"in i?(i.w+6)%7+7*i.W-(o+5)%7:i.w+7*i.U-(o+6)%7);return"Z"in i?(i.H+=i.Z/100|0,i.M+=i.Z%100,eD(i)):eN(i)}}function S(t,e,r,n){for(var o,i,a=0,u=e.length,c=r.length;a=c)return -1;if(37===(o=e.charCodeAt(a++))){if(!(i=w[(o=e.charAt(a++))in eL?e.charAt(a++):o])||(n=i(t,r,n))<0)return -1}else if(o!=r.charCodeAt(n++))return -1}return n}return g.x=O(r,g),g.X=O(n,g),g.c=O(e,g),x.x=O(r,x),x.X=O(n,x),x.c=O(e,x),{format:function(t){var e=O(t+="",g);return e.toString=function(){return t},e},parse:function(t){var e=j(t+="",!1);return e.toString=function(){return t},e},utcFormat:function(t){var e=O(t+="",x);return e.toString=function(){return t},e},utcParse:function(t){var e=j(t+="",!0);return e.toString=function(){return t},e}}}({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]})).format,u.parse,l=u.utcFormat,u.utcParse;var r2=r(22516),r5=r(76115);function r6(t){for(var e=t.length,r=Array(e);--e>=0;)r[e]=e;return r}function r3(t,e){return t[e]}function r7(t){let e=[];return e.key=t,e}var r4=r(95645),r8=r.n(r4),r9=r(99008),nt=r.n(r9),ne=r(77571),nr=r.n(ne),nn=r(86757),no=r.n(nn),ni=r(42715),na=r.n(ni),nu=r(13735),nc=r.n(nu),nl=r(11314),ns=r.n(nl),nf=r(82559),np=r.n(nf),nh=r(75551),nd=r.n(nh),ny=r(21652),nv=r.n(ny),nm=r(34935),nb=r.n(nm),ng=r(61134),nx=r.n(ng);function nw(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);r=e?r.apply(void 0,o):t(e-a,nP(function(){for(var t=arguments.length,e=Array(t),n=0;nt.length)&&(e=t.length);for(var r=0,n=Array(e);rn&&(o=n,i=r),[o,i]}function nR(t,e,r){if(t.lte(0))return new(nx())(0);var n=nC.getDigitCount(t.toNumber()),o=new(nx())(10).pow(n),i=t.div(o),a=1!==n?.05:.1,u=new(nx())(Math.ceil(i.div(a).toNumber())).add(r).mul(a).mul(o);return e?u:new(nx())(Math.ceil(u))}function nz(t,e,r){var n=1,o=new(nx())(t);if(!o.isint()&&r){var i=Math.abs(t);i<1?(n=new(nx())(10).pow(nC.getDigitCount(t)-1),o=new(nx())(Math.floor(o.div(n).toNumber())).mul(n)):i>1&&(o=new(nx())(Math.floor(t)))}else 0===t?o=new(nx())(Math.floor((e-1)/2)):r||(o=new(nx())(Math.floor(t)));var a=Math.floor((e-1)/2);return nM(nA(function(t){return o.add(new(nx())(t-a).mul(n)).toNumber()}),nk)(0,e)}var nU=nT(function(t){var e=nD(t,2),r=e[0],n=e[1],o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:6,i=!(arguments.length>2)||void 0===arguments[2]||arguments[2],a=Math.max(o,2),u=nD(nB([r,n]),2),c=u[0],l=u[1];if(c===-1/0||l===1/0){var s=l===1/0?[c].concat(nN(nk(0,o-1).map(function(){return 1/0}))):[].concat(nN(nk(0,o-1).map(function(){return-1/0})),[l]);return r>n?n_(s):s}if(c===l)return nz(c,o,i);var f=function t(e,r,n,o){var i,a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0;if(!Number.isFinite((r-e)/(n-1)))return{step:new(nx())(0),tickMin:new(nx())(0),tickMax:new(nx())(0)};var u=nR(new(nx())(r).sub(e).div(n-1),o,a),c=Math.ceil((i=e<=0&&r>=0?new(nx())(0):(i=new(nx())(e).add(r).div(2)).sub(new(nx())(i).mod(u))).sub(e).div(u).toNumber()),l=Math.ceil(new(nx())(r).sub(i).div(u).toNumber()),s=c+l+1;return s>n?t(e,r,n,o,a+1):(s0?l+(n-s):l,c=r>0?c:c+(n-s)),{step:u,tickMin:i.sub(new(nx())(c).mul(u)),tickMax:i.add(new(nx())(l).mul(u))})}(c,l,a,i),p=f.step,h=f.tickMin,d=f.tickMax,y=nC.rangeStep(h,d.add(new(nx())(.1).mul(p)),p);return r>n?n_(y):y});nT(function(t){var e=nD(t,2),r=e[0],n=e[1],o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:6,i=!(arguments.length>2)||void 0===arguments[2]||arguments[2],a=Math.max(o,2),u=nD(nB([r,n]),2),c=u[0],l=u[1];if(c===-1/0||l===1/0)return[r,n];if(c===l)return nz(c,o,i);var s=nR(new(nx())(l).sub(c).div(a-1),i,0),f=nM(nA(function(t){return new(nx())(c).add(new(nx())(t).mul(s)).toNumber()}),nk)(0,a).filter(function(t){return t>=c&&t<=l});return r>n?n_(f):f});var nF=nT(function(t,e){var r=nD(t,2),n=r[0],o=r[1],i=!(arguments.length>2)||void 0===arguments[2]||arguments[2],a=nD(nB([n,o]),2),u=a[0],c=a[1];if(u===-1/0||c===1/0)return[n,o];if(u===c)return[u];var l=nR(new(nx())(c).sub(u).div(Math.max(e,2)-1),i,0),s=[].concat(nN(nC.rangeStep(new(nx())(u),new(nx())(c).sub(new(nx())(.99).mul(l)),l)),[c]);return n>o?n_(s):s}),n$=r(13137),nq=r(16630),nZ=r(82944),nW=r(38569);function nY(t){return(nY="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function nH(t){return function(t){if(Array.isArray(t))return nX(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(t){if("string"==typeof t)return nX(t,void 0);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return nX(t,void 0)}}(t)||function(){throw TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function nX(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);r1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2?arguments[2]:void 0,o=arguments.length>3?arguments[3]:void 0,i=-1,a=null!==(e=null==r?void 0:r.length)&&void 0!==e?e:0;if(a<=1)return 0;if(o&&"angleAxis"===o.axisType&&1e-6>=Math.abs(Math.abs(o.range[1]-o.range[0])-360))for(var u=o.range,c=0;c0?n[c-1].coordinate:n[a-1].coordinate,s=n[c].coordinate,f=c>=a-1?n[0].coordinate:n[c+1].coordinate,p=void 0;if((0,nq.uY)(s-l)!==(0,nq.uY)(f-s)){var h=[];if((0,nq.uY)(f-s)===(0,nq.uY)(u[1]-u[0])){p=f;var d=s+u[1]-u[0];h[0]=Math.min(d,(d+l)/2),h[1]=Math.max(d,(d+l)/2)}else{p=l;var y=f+u[1]-u[0];h[0]=Math.min(s,(y+s)/2),h[1]=Math.max(s,(y+s)/2)}var v=[Math.min(s,(p+s)/2),Math.max(s,(p+s)/2)];if(t>v[0]&&t<=v[1]||t>=h[0]&&t<=h[1]){i=n[c].index;break}}else{var m=Math.min(l,f),b=Math.max(l,f);if(t>(m+s)/2&&t<=(b+s)/2){i=n[c].index;break}}}else for(var g=0;g0&&g(r[g].coordinate+r[g-1].coordinate)/2&&t<=(r[g].coordinate+r[g+1].coordinate)/2||g===a-1&&t>(r[g].coordinate+r[g-1].coordinate)/2){i=r[g].index;break}return i},n1=function(t){var e,r,n=t.type.displayName,o=null!==(e=t.type)&&void 0!==e&&e.defaultProps?nV(nV({},t.type.defaultProps),t.props):t.props,i=o.stroke,a=o.fill;switch(n){case"Line":r=i;break;case"Area":case"Radar":r=i&&"none"!==i?i:a;break;default:r=a}return r},n2=function(t){var e=t.barSize,r=t.totalSize,n=t.stackGroups,o=void 0===n?{}:n;if(!o)return{};for(var i={},a=Object.keys(o),u=0,c=a.length;u=0});if(v&&v.length){var m=v[0].type.defaultProps,b=void 0!==m?nV(nV({},m),v[0].props):v[0].props,g=b.barSize,x=b[y];i[x]||(i[x]=[]);var w=nr()(g)?e:g;i[x].push({item:v[0],stackList:v.slice(1),barSize:nr()(w)?void 0:(0,nq.h1)(w,r,0)})}}return i},n5=function(t){var e,r=t.barGap,n=t.barCategoryGap,o=t.bandSize,i=t.sizeList,a=void 0===i?[]:i,u=t.maxBarSize,c=a.length;if(c<1)return null;var l=(0,nq.h1)(r,o,0,!0),s=[];if(a[0].barSize===+a[0].barSize){var f=!1,p=o/c,h=a.reduce(function(t,e){return t+e.barSize||0},0);(h+=(c-1)*l)>=o&&(h-=(c-1)*l,l=0),h>=o&&p>0&&(f=!0,p*=.9,h=c*p);var d={offset:((o-h)/2>>0)-l,size:0};e=a.reduce(function(t,e){var r={item:e.item,position:{offset:d.offset+d.size+l,size:f?p:e.barSize}},n=[].concat(nH(t),[r]);return d=n[n.length-1].position,e.stackList&&e.stackList.length&&e.stackList.forEach(function(t){n.push({item:t,position:d})}),n},s)}else{var y=(0,nq.h1)(n,o,0,!0);o-2*y-(c-1)*l<=0&&(l=0);var v=(o-2*y-(c-1)*l)/c;v>1&&(v>>=0);var m=u===+u?Math.min(v,u):v;e=a.reduce(function(t,e,r){var n=[].concat(nH(t),[{item:e.item,position:{offset:y+(v+l)*r+(v-m)/2,size:m}}]);return e.stackList&&e.stackList.length&&e.stackList.forEach(function(t){n.push({item:t,position:n[n.length-1].position})}),n},s)}return e},n6=function(t,e,r,n){var o=r.children,i=r.width,a=r.margin,u=i-(a.left||0)-(a.right||0),c=(0,nW.z)({children:o,legendWidth:u});if(c){var l=n||{},s=l.width,f=l.height,p=c.align,h=c.verticalAlign,d=c.layout;if(("vertical"===d||"horizontal"===d&&"middle"===h)&&"center"!==p&&(0,nq.hj)(t[p]))return nV(nV({},t),{},nK({},p,t[p]+(s||0)));if(("horizontal"===d||"vertical"===d&&"center"===p)&&"middle"!==h&&(0,nq.hj)(t[h]))return nV(nV({},t),{},nK({},h,t[h]+(f||0)))}return t},n3=function(t,e,r,n,o){var i=e.props.children,a=(0,nZ.NN)(i,n$.W).filter(function(t){var e;return e=t.props.direction,!!nr()(o)||("horizontal"===n?"yAxis"===o:"vertical"===n||"x"===e?"xAxis"===o:"y"!==e||"yAxis"===o)});if(a&&a.length){var u=a.map(function(t){return t.props.dataKey});return t.reduce(function(t,e){var n=nQ(e,r);if(nr()(n))return t;var o=Array.isArray(n)?[nt()(n),r8()(n)]:[n,n],i=u.reduce(function(t,r){var n=nQ(e,r,0),i=o[0]-Math.abs(Array.isArray(n)?n[0]:n),a=o[1]+Math.abs(Array.isArray(n)?n[1]:n);return[Math.min(i,t[0]),Math.max(a,t[1])]},[1/0,-1/0]);return[Math.min(i[0],t[0]),Math.max(i[1],t[1])]},[1/0,-1/0])}return null},n7=function(t,e,r,n,o){var i=e.map(function(e){return n3(t,e,r,o,n)}).filter(function(t){return!nr()(t)});return i&&i.length?i.reduce(function(t,e){return[Math.min(t[0],e[0]),Math.max(t[1],e[1])]},[1/0,-1/0]):null},n4=function(t,e,r,n,o){var i=e.map(function(e){var i=e.props.dataKey;return"number"===r&&i&&n3(t,e,i,n)||nJ(t,i,r,o)});if("number"===r)return i.reduce(function(t,e){return[Math.min(t[0],e[0]),Math.max(t[1],e[1])]},[1/0,-1/0]);var a={};return i.reduce(function(t,e){for(var r=0,n=e.length;r=2?2*(0,nq.uY)(a[0]-a[1])*c:c,e&&(t.ticks||t.niceTicks))?(t.ticks||t.niceTicks).map(function(t){return{coordinate:n(o?o.indexOf(t):t)+c,value:t,offset:c}}).filter(function(t){return!np()(t.coordinate)}):t.isCategorical&&t.categoricalDomain?t.categoricalDomain.map(function(t,e){return{coordinate:n(t)+c,value:t,index:e,offset:c}}):n.ticks&&!r?n.ticks(t.tickCount).map(function(t){return{coordinate:n(t)+c,value:t,offset:c}}):n.domain().map(function(t,e){return{coordinate:n(t)+c,value:o?o[t]:t,index:e,offset:c}})},oe=new WeakMap,or=function(t,e){if("function"!=typeof e)return t;oe.has(t)||oe.set(t,new WeakMap);var r=oe.get(t);if(r.has(e))return r.get(e);var n=function(){t.apply(void 0,arguments),e.apply(void 0,arguments)};return r.set(e,n),n},on=function(t,e,r){var n=t.scale,o=t.type,i=t.layout,a=t.axisType;if("auto"===n)return"radial"===i&&"radiusAxis"===a?{scale:f.Z(),realScaleType:"band"}:"radial"===i&&"angleAxis"===a?{scale:tL(),realScaleType:"linear"}:"category"===o&&e&&(e.indexOf("LineChart")>=0||e.indexOf("AreaChart")>=0||e.indexOf("ComposedChart")>=0&&!r)?{scale:f.x(),realScaleType:"point"}:"category"===o?{scale:f.Z(),realScaleType:"band"}:{scale:tL(),realScaleType:"linear"};if(na()(n)){var u="scale".concat(nd()(n));return{scale:(s[u]||f.x)(),realScaleType:s[u]?u:"point"}}return no()(n)?{scale:n}:{scale:f.x(),realScaleType:"point"}},oo=function(t){var e=t.domain();if(e&&!(e.length<=2)){var r=e.length,n=t.range(),o=Math.min(n[0],n[1])-1e-4,i=Math.max(n[0],n[1])+1e-4,a=t(e[0]),u=t(e[r-1]);(ai||ui)&&t.domain([e[0],e[r-1]])}},oi=function(t,e){if(!t)return null;for(var r=0,n=t.length;rn)&&(o[1]=n),o[0]>n&&(o[0]=n),o[1]=0?(t[a][r][0]=o,t[a][r][1]=o+u,o=t[a][r][1]):(t[a][r][0]=i,t[a][r][1]=i+u,i=t[a][r][1])}},expand:function(t,e){if((n=t.length)>0){for(var r,n,o,i=0,a=t[0].length;i0){for(var r,n=0,o=t[e[0]],i=o.length;n0&&(n=(r=t[e[0]]).length)>0){for(var r,n,o,i=0,a=1;a=0?(t[i][r][0]=o,t[i][r][1]=o+a,o=t[i][r][1]):(t[i][r][0]=0,t[i][r][1]=0)}}},oc=function(t,e,r){var n=e.map(function(t){return t.props.dataKey}),o=ou[r];return(function(){var t=(0,r5.Z)([]),e=r6,r=r1,n=r3;function o(o){var i,a,u=Array.from(t.apply(this,arguments),r7),c=u.length,l=-1;for(let t of o)for(i=0,++l;i=0?0:o<0?o:n}return r[0]},od=function(t,e){var r,n=(null!==(r=t.type)&&void 0!==r&&r.defaultProps?nV(nV({},t.type.defaultProps),t.props):t.props).stackId;if((0,nq.P2)(n)){var o=e[n];if(o){var i=o.items.indexOf(t);return i>=0?o.stackedData[i]:null}}return null},oy=function(t,e,r){return Object.keys(t).reduce(function(n,o){var i=t[o].stackedData.reduce(function(t,n){var o=n.slice(e,r+1).reduce(function(t,e){return[nt()(e.concat([t[0]]).filter(nq.hj)),r8()(e.concat([t[1]]).filter(nq.hj))]},[1/0,-1/0]);return[Math.min(t[0],o[0]),Math.max(t[1],o[1])]},[1/0,-1/0]);return[Math.min(i[0],n[0]),Math.max(i[1],n[1])]},[1/0,-1/0]).map(function(t){return t===1/0||t===-1/0?0:t})},ov=/^dataMin[\s]*-[\s]*([0-9]+([.]{1}[0-9]+){0,1})$/,om=/^dataMax[\s]*\+[\s]*([0-9]+([.]{1}[0-9]+){0,1})$/,ob=function(t,e,r){if(no()(t))return t(e,r);if(!Array.isArray(t))return e;var n=[];if((0,nq.hj)(t[0]))n[0]=r?t[0]:Math.min(t[0],e[0]);else if(ov.test(t[0])){var o=+ov.exec(t[0])[1];n[0]=e[0]-o}else no()(t[0])?n[0]=t[0](e[0]):n[0]=e[0];if((0,nq.hj)(t[1]))n[1]=r?t[1]:Math.max(t[1],e[1]);else if(om.test(t[1])){var i=+om.exec(t[1])[1];n[1]=e[1]+i}else no()(t[1])?n[1]=t[1](e[1]):n[1]=e[1];return n},og=function(t,e,r){if(t&&t.scale&&t.scale.bandwidth){var n=t.scale.bandwidth();if(!r||n>0)return n}if(t&&e&&e.length>=2){for(var o=nb()(e,function(t){return t.coordinate}),i=1/0,a=1,u=o.length;a1&&void 0!==arguments[1]?arguments[1]:{};if(null==t||n.x.isSsr)return{width:0,height:0};var o=(Object.keys(e=a({},r)).forEach(function(t){e[t]||delete e[t]}),e),i=JSON.stringify({text:t,copyStyle:o});if(u.widthCache[i])return u.widthCache[i];try{var s=document.getElementById(l);s||((s=document.createElement("span")).setAttribute("id",l),s.setAttribute("aria-hidden","true"),document.body.appendChild(s));var f=a(a({},c),o);Object.assign(s.style,f),s.textContent="".concat(t);var p=s.getBoundingClientRect(),h={width:p.width,height:p.height};return u.widthCache[i]=h,++u.cacheCount>2e3&&(u.cacheCount=0,u.widthCache={}),h}catch(t){return{width:0,height:0}}},f=function(t){return{top:t.top+window.scrollY-document.documentElement.clientTop,left:t.left+window.scrollX-document.documentElement.clientLeft}}},16630:function(t,e,r){"use strict";r.d(e,{Ap:function(){return S},EL:function(){return g},Kt:function(){return w},P2:function(){return m},Rw:function(){return v},bv:function(){return O},fC:function(){return P},h1:function(){return x},hU:function(){return d},hj:function(){return y},k4:function(){return j},uY:function(){return h}});var n=r(42715),o=r.n(n),i=r(82559),a=r.n(i),u=r(13735),c=r.n(u),l=r(22345),s=r.n(l),f=r(77571),p=r.n(f),h=function(t){return 0===t?0:t>0?1:-1},d=function(t){return o()(t)&&t.indexOf("%")===t.length-1},y=function(t){return s()(t)&&!a()(t)},v=function(t){return p()(t)},m=function(t){return y(t)||o()(t)},b=0,g=function(t){var e=++b;return"".concat(t||"").concat(e)},x=function(t,e){var r,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,i=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(!y(t)&&!o()(t))return n;if(d(t)){var u=t.indexOf("%");r=e*parseFloat(t.slice(0,u))/100}else r=+t;return a()(r)&&(r=n),i&&r>e&&(r=e),r},w=function(t){if(!t)return null;var e=Object.keys(t);return e&&e.length?t[e[0]]:null},O=function(t){if(!Array.isArray(t))return!1;for(var e=t.length,r={},n=0;n2?r-2:0),o=2;ot.length)&&(e=t.length);for(var r=0,n=Array(e);r2&&void 0!==arguments[2]?arguments[2]:{top:0,right:0,bottom:0,left:0};return Math.min(Math.abs(t-(r.left||0)-(r.right||0)),Math.abs(e-(r.top||0)-(r.bottom||0)))/2},b=function(t,e,r,n,i){var a=t.width,u=t.height,s=t.startAngle,f=t.endAngle,y=(0,c.h1)(t.cx,a,a/2),v=(0,c.h1)(t.cy,u,u/2),b=m(a,u,r),g=(0,c.h1)(t.innerRadius,b,0),x=(0,c.h1)(t.outerRadius,b,.8*b);return Object.keys(e).reduce(function(t,r){var a,u=e[r],c=u.domain,m=u.reversed;if(o()(u.range))"angleAxis"===n?a=[s,f]:"radiusAxis"===n&&(a=[g,x]),m&&(a=[a[1],a[0]]);else{var b,w=function(t){if(Array.isArray(t))return t}(b=a=u.range)||function(t,e){var r=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=r){var n,o,i,a,u=[],c=!0,l=!1;try{for(i=(r=r.call(t)).next;!(c=(n=i.call(r)).done)&&(u.push(n.value),2!==u.length);c=!0);}catch(t){l=!0,o=t}finally{try{if(!c&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(l)throw o}}return u}}(b,2)||function(t,e){if(t){if("string"==typeof t)return d(t,2);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return d(t,2)}}(b,2)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}();s=w[0],f=w[1]}var O=(0,l.Hq)(u,i),j=O.realScaleType,S=O.scale;S.domain(c).range(a),(0,l.zF)(S);var P=(0,l.g$)(S,p(p({},u),{},{realScaleType:j})),E=p(p(p({},u),P),{},{range:a,radius:x,realScaleType:j,scale:S,cx:y,cy:v,innerRadius:g,outerRadius:x,startAngle:s,endAngle:f});return p(p({},t),{},h({},r,E))},{})},g=function(t,e){var r=t.x,n=t.y;return Math.sqrt(Math.pow(r-e.x,2)+Math.pow(n-e.y,2))},x=function(t,e){var r=t.x,n=t.y,o=e.cx,i=e.cy,a=g({x:r,y:n},{x:o,y:i});if(a<=0)return{radius:a};var u=Math.acos((r-o)/a);return n>i&&(u=2*Math.PI-u),{radius:a,angle:180*u/Math.PI,angleInRadian:u}},w=function(t){var e=t.startAngle,r=t.endAngle,n=Math.min(Math.floor(e/360),Math.floor(r/360));return{startAngle:e-360*n,endAngle:r-360*n}},O=function(t,e){var r,n=x({x:t.x,y:t.y},e),o=n.radius,i=n.angle,a=e.innerRadius,u=e.outerRadius;if(ou)return!1;if(0===o)return!0;var c=w(e),l=c.startAngle,s=c.endAngle,f=i;if(l<=s){for(;f>s;)f-=360;for(;f=l&&f<=s}else{for(;f>l;)f-=360;for(;f=s&&f<=l}return r?p(p({},e),{},{radius:o,angle:f+360*Math.min(Math.floor(e.startAngle/360),Math.floor(e.endAngle/360))}):null},j=function(t){return(0,i.isValidElement)(t)||u()(t)||"boolean"==typeof t?"":t.className}},82944:function(t,e,r){"use strict";r.d(e,{$R:function(){return R},Bh:function(){return B},Gf:function(){return j},L6:function(){return N},NN:function(){return k},TT:function(){return M},eu:function(){return L},jf:function(){return T},rL:function(){return D},sP:function(){return A}});var n=r(13735),o=r.n(n),i=r(77571),a=r.n(i),u=r(42715),c=r.n(u),l=r(86757),s=r.n(l),f=r(28302),p=r.n(f),h=r(2265),d=r(14326),y=r(16630),v=r(46485),m=r(41637),b=["children"],g=["children"];function x(t,e){if(null==t)return{};var r,n,o=function(t,e){if(null==t)return{};var r={};for(var n in t)if(Object.prototype.hasOwnProperty.call(t,n)){if(e.indexOf(n)>=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}function w(t){return(w="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var O={click:"onClick",mousedown:"onMouseDown",mouseup:"onMouseUp",mouseover:"onMouseOver",mousemove:"onMouseMove",mouseout:"onMouseOut",mouseenter:"onMouseEnter",mouseleave:"onMouseLeave",touchcancel:"onTouchCancel",touchend:"onTouchEnd",touchmove:"onTouchMove",touchstart:"onTouchStart",contextmenu:"onContextMenu",dblclick:"onDoubleClick"},j=function(t){return"string"==typeof t?t:t?t.displayName||t.name||"Component":""},S=null,P=null,E=function t(e){if(e===S&&Array.isArray(P))return P;var r=[];return h.Children.forEach(e,function(e){a()(e)||((0,d.isFragment)(e)?r=r.concat(t(e.props.children)):r.push(e))}),P=r,S=e,r};function k(t,e){var r=[],n=[];return n=Array.isArray(e)?e.map(function(t){return j(t)}):[j(e)],E(t).forEach(function(t){var e=o()(t,"type.displayName")||o()(t,"type.name");-1!==n.indexOf(e)&&r.push(t)}),r}function A(t,e){var r=k(t,e);return r&&r[0]}var M=function(t){if(!t||!t.props)return!1;var e=t.props,r=e.width,n=e.height;return!!(0,y.hj)(r)&&!(r<=0)&&!!(0,y.hj)(n)&&!(n<=0)},_=["a","altGlyph","altGlyphDef","altGlyphItem","animate","animateColor","animateMotion","animateTransform","circle","clipPath","color-profile","cursor","defs","desc","ellipse","feBlend","feColormatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","filter","font","font-face","font-face-format","font-face-name","font-face-url","foreignObject","g","glyph","glyphRef","hkern","image","line","lineGradient","marker","mask","metadata","missing-glyph","mpath","path","pattern","polygon","polyline","radialGradient","rect","script","set","stop","style","svg","switch","symbol","text","textPath","title","tref","tspan","use","view","vkern"],T=function(t){return t&&"object"===w(t)&&"clipDot"in t},C=function(t,e,r,n){var o,i=null!==(o=null===m.ry||void 0===m.ry?void 0:m.ry[n])&&void 0!==o?o:[];return e.startsWith("data-")||!s()(t)&&(n&&i.includes(e)||m.Yh.includes(e))||r&&m.nv.includes(e)},N=function(t,e,r){if(!t||"function"==typeof t||"boolean"==typeof t)return null;var n=t;if((0,h.isValidElement)(t)&&(n=t.props),!p()(n))return null;var o={};return Object.keys(n).forEach(function(t){var i;C(null===(i=n)||void 0===i?void 0:i[t],t,e,r)&&(o[t]=n[t])}),o},D=function t(e,r){if(e===r)return!0;var n=h.Children.count(e);if(n!==h.Children.count(r))return!1;if(0===n)return!0;if(1===n)return I(Array.isArray(e)?e[0]:e,Array.isArray(r)?r[0]:r);for(var o=0;o=0)r.push(t);else if(t){var i=j(t.type),a=e[i]||{},u=a.handler,l=a.once;if(u&&(!l||!n[i])){var s=u(t,i,o);r.push(s),n[i]=!0}}}),r},B=function(t){var e=t&&t.type;return e&&O[e]?O[e]:null},R=function(t,e){return E(e).indexOf(t)}},46485:function(t,e,r){"use strict";function n(t,e){for(var r in t)if(({}).hasOwnProperty.call(t,r)&&(!({}).hasOwnProperty.call(e,r)||t[r]!==e[r]))return!1;for(var n in e)if(({}).hasOwnProperty.call(e,n)&&!({}).hasOwnProperty.call(t,n))return!1;return!0}r.d(e,{w:function(){return n}})},38569:function(t,e,r){"use strict";r.d(e,{z:function(){return l}});var n=r(22190),o=r(85355),i=r(82944);function a(t){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function u(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,n)}return r}function c(t){for(var e=1;e=0))throw Error(`invalid digits: ${t}`);if(e>15)return a;let r=10**e;return function(t){this._+=t[0];for(let e=1,n=t.length;e1e-6){if(Math.abs(f*c-l*s)>1e-6&&i){let h=r-a,d=o-u,y=c*c+l*l,v=Math.sqrt(y),m=Math.sqrt(p),b=i*Math.tan((n-Math.acos((y+p-(h*h+d*d))/(2*v*m)))/2),g=b/m,x=b/v;Math.abs(g-1)>1e-6&&this._append`L${t+g*s},${e+g*f}`,this._append`A${i},${i},0,0,${+(f*h>s*d)},${this._x1=t+x*c},${this._y1=e+x*l}`}else this._append`L${this._x1=t},${this._y1=e}`}}arc(t,e,r,a,u,c){if(t=+t,e=+e,c=!!c,(r=+r)<0)throw Error(`negative radius: ${r}`);let l=r*Math.cos(a),s=r*Math.sin(a),f=t+l,p=e+s,h=1^c,d=c?a-u:u-a;null===this._x1?this._append`M${f},${p}`:(Math.abs(this._x1-f)>1e-6||Math.abs(this._y1-p)>1e-6)&&this._append`L${f},${p}`,r&&(d<0&&(d=d%o+o),d>i?this._append`A${r},${r},0,1,${h},${t-l},${e-s}A${r},${r},0,1,${h},${this._x1=f},${this._y1=p}`:d>1e-6&&this._append`A${r},${r},0,${+(d>=n)},${h},${this._x1=t+r*Math.cos(u)},${this._y1=e+r*Math.sin(u)}`)}rect(t,e,r,n){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+e}h${r=+r}v${+n}h${-r}Z`}toString(){return this._}}function c(t){let e=3;return t.digits=function(r){if(!arguments.length)return e;if(null==r)e=null;else{let t=Math.floor(r);if(!(t>=0))throw RangeError(`invalid digits: ${r}`);e=t}return t},()=>new u(e)}u.prototype},59121:function(t,e,r){"use strict";r.d(e,{E:function(){return i}});var n=r(99649),o=r(63497);function i(t,e){let r=(0,n.Q)(t);return isNaN(e)?(0,o.L)(t,NaN):(e&&r.setDate(r.getDate()+e),r)}},31091:function(t,e,r){"use strict";r.d(e,{z:function(){return i}});var n=r(99649),o=r(63497);function i(t,e){let r=(0,n.Q)(t);if(isNaN(e))return(0,o.L)(t,NaN);if(!e)return r;let i=r.getDate(),a=(0,o.L)(t,r.getTime());return(a.setMonth(r.getMonth()+e+1,0),i>=a.getDate())?a:(r.setFullYear(a.getFullYear(),a.getMonth(),i),r)}},63497:function(t,e,r){"use strict";function n(t,e){return t instanceof Date?new t.constructor(e):new Date(e)}r.d(e,{L:function(){return n}})},99649:function(t,e,r){"use strict";function n(t){let e=Object.prototype.toString.call(t);return t instanceof Date||"object"==typeof t&&"[object Date]"===e?new t.constructor(+t):new Date("number"==typeof t||"[object Number]"===e||"string"==typeof t||"[object String]"===e?t:NaN)}r.d(e,{Q:function(){return n}})},69398:function(t,e,r){"use strict";function n(t,e){if(!t)throw Error("Invariant failed")}r.d(e,{Z:function(){return n}})}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/1108-c2d0c742b6e72436.js b/litellm/proxy/_experimental/out/_next/static/chunks/1108-c2d0c742b6e72436.js new file mode 100644 index 00000000000..efdd028104e --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/1108-c2d0c742b6e72436.js @@ -0,0 +1 @@ +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1108],{40278:function(t,e,r){"use strict";r.d(e,{Z:function(){return S}});var n=r(5853),o=r(7084),i=r(26898),a=r(13241),u=r(1153),c=r(2265),l=r(47625),s=r(93765),f=r(31699),p=r(97059),h=r(62994),d=r(25311),y=(0,s.z)({chartName:"BarChart",GraphicalChild:f.$,defaultTooltipEventType:"axis",validateTooltipEventTypes:["axis","item"],axisComponents:[{axisType:"xAxis",AxisComp:p.K},{axisType:"yAxis",AxisComp:h.B}],formatAxisMap:d.t9}),v=r(56940),m=r(26680),b=r(8147),g=r(22190),x=r(65278),w=r(98593),O=r(92666),j=r(32644);let S=c.forwardRef((t,e)=>{let{data:r=[],categories:s=[],index:d,colors:S=i.s,valueFormatter:P=u.Cj,layout:E="horizontal",stack:k=!1,relative:A=!1,startEndOnly:M=!1,animationDuration:_=900,showAnimation:T=!1,showXAxis:C=!0,showYAxis:N=!0,yAxisWidth:D=56,intervalType:I="equidistantPreserveStart",showTooltip:L=!0,showLegend:B=!0,showGridLines:R=!0,autoMinValue:z=!1,minValue:U,maxValue:F,allowDecimals:$=!0,noDataText:q,onValueChange:Z,enableLegendSlider:W=!1,customTooltip:Y,rotateLabelX:H,barCategoryGap:X,tickGap:G=5,xAxisLabel:V,yAxisLabel:K,className:Q,padding:J=C||N?{left:20,right:20}:{left:0,right:0}}=t,tt=(0,n._T)(t,["data","categories","index","colors","valueFormatter","layout","stack","relative","startEndOnly","animationDuration","showAnimation","showXAxis","showYAxis","yAxisWidth","intervalType","showTooltip","showLegend","showGridLines","autoMinValue","minValue","maxValue","allowDecimals","noDataText","onValueChange","enableLegendSlider","customTooltip","rotateLabelX","barCategoryGap","tickGap","xAxisLabel","yAxisLabel","className","padding"]),[te,tr]=(0,c.useState)(60),tn=(0,j.me)(s,S),[to,ti]=c.useState(void 0),[ta,tu]=(0,c.useState)(void 0),tc=!!Z;function tl(t,e,r){var n,o,i,a;r.stopPropagation(),Z&&((0,j.vZ)(to,Object.assign(Object.assign({},t.payload),{value:t.value}))?(tu(void 0),ti(void 0),null==Z||Z(null)):(tu(null===(o=null===(n=t.tooltipPayload)||void 0===n?void 0:n[0])||void 0===o?void 0:o.dataKey),ti(Object.assign(Object.assign({},t.payload),{value:t.value})),null==Z||Z(Object.assign({eventType:"bar",categoryClicked:null===(a=null===(i=t.tooltipPayload)||void 0===i?void 0:i[0])||void 0===a?void 0:a.dataKey},t.payload))))}let ts=(0,j.i4)(z,U,F);return c.createElement("div",Object.assign({ref:e,className:(0,a.q)("w-full h-80",Q)},tt),c.createElement(l.h,{className:"h-full w-full"},(null==r?void 0:r.length)?c.createElement(y,{barCategoryGap:X,data:r,stackOffset:k?"sign":A?"expand":"none",layout:"vertical"===E?"vertical":"horizontal",onClick:tc&&(ta||to)?()=>{ti(void 0),tu(void 0),null==Z||Z(null)}:void 0,margin:{bottom:V?30:void 0,left:K?20:void 0,right:K?5:void 0,top:5}},R?c.createElement(v.q,{className:(0,a.q)("stroke-1","stroke-tremor-border","dark:stroke-dark-tremor-border"),horizontal:"vertical"!==E,vertical:"vertical"===E}):null,"vertical"!==E?c.createElement(p.K,{padding:J,hide:!C,dataKey:d,interval:M?"preserveStartEnd":I,tick:{transform:"translate(0, 6)"},ticks:M?[r[0][d],r[r.length-1][d]]:void 0,fill:"",stroke:"",className:(0,a.q)("mt-4 text-tremor-label","fill-tremor-content","dark:fill-dark-tremor-content"),tickLine:!1,axisLine:!1,angle:null==H?void 0:H.angle,dy:null==H?void 0:H.verticalShift,height:null==H?void 0:H.xAxisHeight,minTickGap:G},V&&c.createElement(m._,{position:"insideBottom",offset:-20,className:"fill-tremor-content-emphasis text-tremor-default font-medium dark:fill-dark-tremor-content-emphasis"},V)):c.createElement(p.K,{hide:!C,type:"number",tick:{transform:"translate(-3, 0)"},domain:ts,fill:"",stroke:"",className:(0,a.q)("text-tremor-label","fill-tremor-content","dark:fill-dark-tremor-content"),tickLine:!1,axisLine:!1,tickFormatter:P,minTickGap:G,allowDecimals:$,angle:null==H?void 0:H.angle,dy:null==H?void 0:H.verticalShift,height:null==H?void 0:H.xAxisHeight},V&&c.createElement(m._,{position:"insideBottom",offset:-20,className:"fill-tremor-content-emphasis text-tremor-default font-medium dark:fill-dark-tremor-content-emphasis"},V)),"vertical"!==E?c.createElement(h.B,{width:D,hide:!N,axisLine:!1,tickLine:!1,type:"number",domain:ts,tick:{transform:"translate(-3, 0)"},fill:"",stroke:"",className:(0,a.q)("text-tremor-label","fill-tremor-content","dark:fill-dark-tremor-content"),tickFormatter:A?t=>"".concat((100*t).toString()," %"):P,allowDecimals:$},K&&c.createElement(m._,{position:"insideLeft",style:{textAnchor:"middle"},angle:-90,offset:-15,className:"fill-tremor-content-emphasis text-tremor-default font-medium dark:fill-dark-tremor-content-emphasis"},K)):c.createElement(h.B,{width:D,hide:!N,dataKey:d,axisLine:!1,tickLine:!1,ticks:M?[r[0][d],r[r.length-1][d]]:void 0,type:"category",interval:"preserveStartEnd",tick:{transform:"translate(0, 6)"},fill:"",stroke:"",className:(0,a.q)("text-tremor-label","fill-tremor-content","dark:fill-dark-tremor-content")},K&&c.createElement(m._,{position:"insideLeft",style:{textAnchor:"middle"},angle:-90,offset:-15,className:"fill-tremor-content-emphasis text-tremor-default font-medium dark:fill-dark-tremor-content-emphasis"},K)),c.createElement(b.u,{wrapperStyle:{outline:"none"},isAnimationActive:!1,cursor:{fill:"#d1d5db",opacity:"0.15"},content:L?t=>{let{active:e,payload:r,label:n}=t;return Y?c.createElement(Y,{payload:null==r?void 0:r.map(t=>{var e;return Object.assign(Object.assign({},t),{color:null!==(e=tn.get(t.dataKey))&&void 0!==e?e:o.fr.Gray})}),active:e,label:n}):c.createElement(w.ZP,{active:e,payload:r,label:n,valueFormatter:P,categoryColors:tn})}:c.createElement(c.Fragment,null),position:{y:0}}),B?c.createElement(g.D,{verticalAlign:"top",height:te,content:t=>{let{payload:e}=t;return(0,x.Z)({payload:e},tn,tr,ta,tc?t=>{tc&&(t!==ta||to?(tu(t),null==Z||Z({eventType:"category",categoryClicked:t})):(tu(void 0),null==Z||Z(null)),ti(void 0))}:void 0,W)}}):null,s.map(t=>{var e;return c.createElement(f.$,{className:(0,a.q)((0,u.bM)(null!==(e=tn.get(t))&&void 0!==e?e:o.fr.Gray,i.K.background).fillColor,Z?"cursor-pointer":""),key:t,name:t,type:"linear",stackId:k||A?"a":void 0,dataKey:t,fill:"",isAnimationActive:T,animationDuration:_,shape:t=>((t,e,r,n)=>{let{fillOpacity:o,name:i,payload:a,value:u}=t,{x:l,width:s,y:f,height:p}=t;return"horizontal"===n&&p<0?(f+=p,p=Math.abs(p)):"vertical"===n&&s<0&&(l+=s,s=Math.abs(s)),c.createElement("rect",{x:l,y:f,width:s,height:p,opacity:e||r&&r!==i?(0,j.vZ)(e,Object.assign(Object.assign({},a),{value:u}))?o:.3:o})})(t,to,ta,E),onClick:tl})})):c.createElement(O.Z,{noDataText:q})))});S.displayName="BarChart"},65278:function(t,e,r){"use strict";r.d(e,{Z:function(){return y}});var n=r(2265);let o=t=>{n.useEffect(()=>{let e=()=>{t()};return e(),window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)},[t])};var i=r(5853),a=r(26898),u=r(13241),c=r(1153);let l=t=>{var e=(0,i._T)(t,[]);return n.createElement("svg",Object.assign({},e,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"}),n.createElement("path",{d:"M8 12L14 6V18L8 12Z"}))},s=t=>{var e=(0,i._T)(t,[]);return n.createElement("svg",Object.assign({},e,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"}),n.createElement("path",{d:"M16 12L10 18V6L16 12Z"}))},f=(0,c.fn)("Legend"),p=t=>{let{name:e,color:r,onClick:o,activeLegend:i}=t,l=!!o;return n.createElement("li",{className:(0,u.q)(f("legendItem"),"group inline-flex items-center px-2 py-0.5 rounded-tremor-small transition whitespace-nowrap",l?"cursor-pointer":"cursor-default","text-tremor-content",l?"hover:bg-tremor-background-subtle":"","dark:text-dark-tremor-content",l?"dark:hover:bg-dark-tremor-background-subtle":""),onClick:t=>{t.stopPropagation(),null==o||o(e,r)}},n.createElement("svg",{className:(0,u.q)("flex-none h-2 w-2 mr-1.5",(0,c.bM)(r,a.K.text).textColor,i&&i!==e?"opacity-40":"opacity-100"),fill:"currentColor",viewBox:"0 0 8 8"},n.createElement("circle",{cx:4,cy:4,r:4})),n.createElement("p",{className:(0,u.q)("whitespace-nowrap truncate text-tremor-default","text-tremor-content",l?"group-hover:text-tremor-content-emphasis":"","dark:text-dark-tremor-content",i&&i!==e?"opacity-40":"opacity-100",l?"dark:group-hover:text-dark-tremor-content-emphasis":"")},e))},h=t=>{let{icon:e,onClick:r,disabled:o}=t,[i,a]=n.useState(!1),c=n.useRef(null);return n.useEffect(()=>(i?c.current=setInterval(()=>{null==r||r()},300):clearInterval(c.current),()=>clearInterval(c.current)),[i,r]),(0,n.useEffect)(()=>{o&&(clearInterval(c.current),a(!1))},[o]),n.createElement("button",{type:"button",className:(0,u.q)(f("legendSliderButton"),"w-5 group inline-flex items-center truncate rounded-tremor-small transition",o?"cursor-not-allowed":"cursor-pointer",o?"text-tremor-content-subtle":"text-tremor-content hover:text-tremor-content-emphasis hover:bg-tremor-background-subtle",o?"dark:text-dark-tremor-subtle":"dark:text-dark-tremor dark:hover:text-tremor-content-emphasis dark:hover:bg-dark-tremor-background-subtle"),disabled:o,onClick:t=>{t.stopPropagation(),null==r||r()},onMouseDown:t=>{t.stopPropagation(),a(!0)},onMouseUp:t=>{t.stopPropagation(),a(!1)}},n.createElement(e,{className:"w-full"}))},d=n.forwardRef((t,e)=>{let{categories:r,colors:o=a.s,className:c,onClickLegendItem:d,activeLegend:y,enableLegendSlider:v=!1}=t,m=(0,i._T)(t,["categories","colors","className","onClickLegendItem","activeLegend","enableLegendSlider"]),b=n.useRef(null),g=n.useRef(null),[x,w]=n.useState(null),[O,j]=n.useState(null),S=n.useRef(null),P=(0,n.useCallback)(()=>{let t=null==b?void 0:b.current;t&&w({left:t.scrollLeft>0,right:t.scrollWidth-t.clientWidth>t.scrollLeft})},[w]),E=(0,n.useCallback)(t=>{var e,r;let n=null==b?void 0:b.current,o=null==g?void 0:g.current,i=null!==(e=null==n?void 0:n.clientWidth)&&void 0!==e?e:0,a=null!==(r=null==o?void 0:o.clientWidth)&&void 0!==r?r:0;n&&v&&(n.scrollTo({left:"left"===t?n.scrollLeft-i+a:n.scrollLeft+i-a,behavior:"smooth"}),setTimeout(()=>{P()},400))},[v,P]);n.useEffect(()=>{let t=t=>{"ArrowLeft"===t?E("left"):"ArrowRight"===t&&E("right")};return O?(t(O),S.current=setInterval(()=>{t(O)},300)):clearInterval(S.current),()=>clearInterval(S.current)},[O,E]);let k=t=>{t.stopPropagation(),"ArrowLeft"!==t.key&&"ArrowRight"!==t.key||(t.preventDefault(),j(t.key))},A=t=>{t.stopPropagation(),j(null)};return n.useEffect(()=>{let t=null==b?void 0:b.current;return v&&(P(),null==t||t.addEventListener("keydown",k),null==t||t.addEventListener("keyup",A)),()=>{null==t||t.removeEventListener("keydown",k),null==t||t.removeEventListener("keyup",A)}},[P,v]),n.createElement("ol",Object.assign({ref:e,className:(0,u.q)(f("root"),"relative overflow-hidden",c)},m),n.createElement("div",{ref:b,tabIndex:0,className:(0,u.q)("h-full flex",v?(null==x?void 0:x.right)||(null==x?void 0:x.left)?"pl-4 pr-12 items-center overflow-auto snap-mandatory [&::-webkit-scrollbar]:hidden [scrollbar-width:none]":"":"flex-wrap")},r.map((t,e)=>n.createElement(p,{key:"item-".concat(e),name:t,color:o[e%o.length],onClick:d,activeLegend:y}))),v&&((null==x?void 0:x.right)||(null==x?void 0:x.left))?n.createElement(n.Fragment,null,n.createElement("div",{className:(0,u.q)("bg-tremor-background","dark:bg-dark-tremor-background","absolute flex top-0 pr-1 bottom-0 right-0 items-center justify-center h-full"),ref:g},n.createElement(h,{icon:l,onClick:()=>{j(null),E("left")},disabled:!(null==x?void 0:x.left)}),n.createElement(h,{icon:s,onClick:()=>{j(null),E("right")},disabled:!(null==x?void 0:x.right)}))):null)});d.displayName="Legend";let y=(t,e,r,i,a,u)=>{let{payload:c}=t,l=(0,n.useRef)(null);o(()=>{var t,e;r((e=null===(t=l.current)||void 0===t?void 0:t.clientHeight)?Number(e)+20:60)});let s=c.filter(t=>"none"!==t.type);return n.createElement("div",{ref:l,className:"flex items-center justify-end"},n.createElement(d,{categories:s.map(t=>t.value),colors:s.map(t=>e.get(t.value)),onClickLegendItem:a,activeLegend:i,enableLegendSlider:u}))}},98593:function(t,e,r){"use strict";r.d(e,{$B:function(){return c},ZP:function(){return s},zX:function(){return l}});var n=r(2265),o=r(7084),i=r(26898),a=r(13241),u=r(1153);let c=t=>{let{children:e}=t;return n.createElement("div",{className:(0,a.q)("rounded-tremor-default text-tremor-default border","bg-tremor-background shadow-tremor-dropdown border-tremor-border","dark:bg-dark-tremor-background dark:shadow-dark-tremor-dropdown dark:border-dark-tremor-border")},e)},l=t=>{let{value:e,name:r,color:o}=t;return n.createElement("div",{className:"flex items-center justify-between space-x-8"},n.createElement("div",{className:"flex items-center space-x-2"},n.createElement("span",{className:(0,a.q)("shrink-0 rounded-tremor-full border-2 h-3 w-3","border-tremor-background shadow-tremor-card","dark:border-dark-tremor-background dark:shadow-dark-tremor-card",(0,u.bM)(o,i.K.background).bgColor)}),n.createElement("p",{className:(0,a.q)("text-right whitespace-nowrap","text-tremor-content","dark:text-dark-tremor-content")},r)),n.createElement("p",{className:(0,a.q)("font-medium tabular-nums text-right whitespace-nowrap","text-tremor-content-emphasis","dark:text-dark-tremor-content-emphasis")},e))},s=t=>{let{active:e,payload:r,label:i,categoryColors:u,valueFormatter:s}=t;if(e&&r){let t=r.filter(t=>"none"!==t.type);return n.createElement(c,null,n.createElement("div",{className:(0,a.q)("border-tremor-border border-b px-4 py-2","dark:border-dark-tremor-border")},n.createElement("p",{className:(0,a.q)("font-medium","text-tremor-content-emphasis","dark:text-dark-tremor-content-emphasis")},i)),n.createElement("div",{className:(0,a.q)("px-4 py-2 space-y-1")},t.map((t,e)=>{var r;let{value:i,name:a}=t;return n.createElement(l,{key:"id-".concat(e),value:s(i),name:a,color:null!==(r=u.get(a))&&void 0!==r?r:o.fr.Blue})})))}return null}},92666:function(t,e,r){"use strict";r.d(e,{Z:function(){return i}});var n=r(13241),o=r(2265);let i=t=>{let{className:e,noDataText:r="No data"}=t;return o.createElement("div",{className:(0,n.q)("flex items-center justify-center w-full h-full border border-dashed rounded-tremor-default","border-tremor-border","dark:border-dark-tremor-border",e)},o.createElement("p",{className:(0,n.q)("text-tremor-content text-tremor-default","dark:text-dark-tremor-content")},r))}},32644:function(t,e,r){"use strict";r.d(e,{FB:function(){return i},i4:function(){return o},me:function(){return n},vZ:function(){return function t(e,r){if(e===r)return!0;if("object"!=typeof e||"object"!=typeof r||null===e||null===r)return!1;let n=Object.keys(e),o=Object.keys(r);if(n.length!==o.length)return!1;for(let i of n)if(!o.includes(i)||!t(e[i],r[i]))return!1;return!0}}});let n=(t,e)=>{let r=new Map;return t.forEach((t,n)=>{r.set(t,e[n%e.length])}),r},o=(t,e,r)=>[t?"auto":null!=e?e:0,null!=r?r:"auto"];function i(t,e){let r=[];for(let n of t)if(Object.prototype.hasOwnProperty.call(n,e)&&(r.push(n[e]),r.length>1))return!1;return!0}},49804:function(t,e,r){"use strict";r.d(e,{Z:function(){return l}});var n=r(5853),o=r(13241),i=r(1153),a=r(2265),u=r(9496);let c=(0,i.fn)("Col"),l=a.forwardRef((t,e)=>{let{numColSpan:r=1,numColSpanSm:i,numColSpanMd:l,numColSpanLg:s,children:f,className:p}=t,h=(0,n._T)(t,["numColSpan","numColSpanSm","numColSpanMd","numColSpanLg","children","className"]),d=(t,e)=>t&&Object.keys(e).includes(String(t))?e[t]:"";return a.createElement("div",Object.assign({ref:e,className:(0,o.q)(c("root"),(()=>{let t=d(r,u.PT),e=d(i,u.SP),n=d(l,u.VS),a=d(s,u._w);return(0,o.q)(t,e,n,a)})(),p)},h),f)});l.displayName="Col"},97765:function(t,e,r){"use strict";r.d(e,{Z:function(){return c}});var n=r(5853),o=r(26898),i=r(13241),a=r(1153),u=r(2265);let c=u.forwardRef((t,e)=>{let{color:r,children:c,className:l}=t,s=(0,n._T)(t,["color","children","className"]);return u.createElement("p",Object.assign({ref:e,className:(0,i.q)(r?(0,a.bM)(r,o.K.lightText).textColor:"text-tremor-content-emphasis dark:text-dark-tremor-content-emphasis",l)},s),c)});c.displayName="Subtitle"},61134:function(t,e,r){var n;!function(o){"use strict";var i,a={precision:20,rounding:4,toExpNeg:-7,toExpPos:21,LN10:"2.302585092994045684017991454684364207601101488628772976033327900967572609677352480235997205089598298341967784042286"},u=!0,c="[DecimalError] ",l=c+"Invalid argument: ",s=c+"Exponent out of range: ",f=Math.floor,p=Math.pow,h=/^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,d=f(1286742750677284.5),y={};function v(t,e){var r,n,o,i,a,c,l,s,f=t.constructor,p=f.precision;if(!t.s||!e.s)return e.s||(e=new f(t)),u?E(e,p):e;if(l=t.d,s=e.d,a=t.e,o=e.e,l=l.slice(),i=a-o){for(i<0?(n=l,i=-i,c=s.length):(n=s,o=a,c=l.length),i>(c=(a=Math.ceil(p/7))>c?a+1:c+1)&&(i=c,n.length=1),n.reverse();i--;)n.push(0);n.reverse()}for((c=l.length)-(i=s.length)<0&&(i=c,n=s,s=l,l=n),r=0;i;)r=(l[--i]=l[i]+s[i]+r)/1e7|0,l[i]%=1e7;for(r&&(l.unshift(r),++o),c=l.length;0==l[--c];)l.pop();return e.d=l,e.e=o,u?E(e,p):e}function m(t,e,r){if(t!==~~t||tr)throw Error(l+t)}function b(t){var e,r,n,o=t.length-1,i="",a=t[0];if(o>0){for(i+=a,e=1;et.e^this.s<0?1:-1;for(e=0,r=(n=this.d.length)<(o=t.d.length)?n:o;et.d[e]^this.s<0?1:-1;return n===o?0:n>o^this.s<0?1:-1},y.decimalPlaces=y.dp=function(){var t=this.d.length-1,e=(t-this.e)*7;if(t=this.d[t])for(;t%10==0;t/=10)e--;return e<0?0:e},y.dividedBy=y.div=function(t){return g(this,new this.constructor(t))},y.dividedToIntegerBy=y.idiv=function(t){var e=this.constructor;return E(g(this,new e(t),0,1),e.precision)},y.equals=y.eq=function(t){return!this.cmp(t)},y.exponent=function(){return w(this)},y.greaterThan=y.gt=function(t){return this.cmp(t)>0},y.greaterThanOrEqualTo=y.gte=function(t){return this.cmp(t)>=0},y.isInteger=y.isint=function(){return this.e>this.d.length-2},y.isNegative=y.isneg=function(){return this.s<0},y.isPositive=y.ispos=function(){return this.s>0},y.isZero=function(){return 0===this.s},y.lessThan=y.lt=function(t){return 0>this.cmp(t)},y.lessThanOrEqualTo=y.lte=function(t){return 1>this.cmp(t)},y.logarithm=y.log=function(t){var e,r=this.constructor,n=r.precision,o=n+5;if(void 0===t)t=new r(10);else if((t=new r(t)).s<1||t.eq(i))throw Error(c+"NaN");if(this.s<1)throw Error(c+(this.s?"NaN":"-Infinity"));return this.eq(i)?new r(0):(u=!1,e=g(S(this,o),S(t,o),o),u=!0,E(e,n))},y.minus=y.sub=function(t){return t=new this.constructor(t),this.s==t.s?k(this,t):v(this,(t.s=-t.s,t))},y.modulo=y.mod=function(t){var e,r=this.constructor,n=r.precision;if(!(t=new r(t)).s)throw Error(c+"NaN");return this.s?(u=!1,e=g(this,t,0,1).times(t),u=!0,this.minus(e)):E(new r(this),n)},y.naturalExponential=y.exp=function(){return x(this)},y.naturalLogarithm=y.ln=function(){return S(this)},y.negated=y.neg=function(){var t=new this.constructor(this);return t.s=-t.s||0,t},y.plus=y.add=function(t){return t=new this.constructor(t),this.s==t.s?v(this,t):k(this,(t.s=-t.s,t))},y.precision=y.sd=function(t){var e,r,n;if(void 0!==t&&!!t!==t&&1!==t&&0!==t)throw Error(l+t);if(e=w(this)+1,r=7*(n=this.d.length-1)+1,n=this.d[n]){for(;n%10==0;n/=10)r--;for(n=this.d[0];n>=10;n/=10)r++}return t&&e>r?e:r},y.squareRoot=y.sqrt=function(){var t,e,r,n,o,i,a,l=this.constructor;if(this.s<1){if(!this.s)return new l(0);throw Error(c+"NaN")}for(t=w(this),u=!1,0==(o=Math.sqrt(+this))||o==1/0?(((e=b(this.d)).length+t)%2==0&&(e+="0"),o=Math.sqrt(e),t=f((t+1)/2)-(t<0||t%2),n=new l(e=o==1/0?"5e"+t:(e=o.toExponential()).slice(0,e.indexOf("e")+1)+t)):n=new l(o.toString()),o=a=(r=l.precision)+3;;)if(n=(i=n).plus(g(this,i,a+2)).times(.5),b(i.d).slice(0,a)===(e=b(n.d)).slice(0,a)){if(e=e.slice(a-3,a+1),o==a&&"4999"==e){if(E(i,r+1,0),i.times(i).eq(this)){n=i;break}}else if("9999"!=e)break;a+=4}return u=!0,E(n,r)},y.times=y.mul=function(t){var e,r,n,o,i,a,c,l,s,f=this.constructor,p=this.d,h=(t=new f(t)).d;if(!this.s||!t.s)return new f(0);for(t.s*=this.s,r=this.e+t.e,(l=p.length)<(s=h.length)&&(i=p,p=h,h=i,a=l,l=s,s=a),i=[],n=a=l+s;n--;)i.push(0);for(n=s;--n>=0;){for(e=0,o=l+n;o>n;)c=i[o]+h[n]*p[o-n-1]+e,i[o--]=c%1e7|0,e=c/1e7|0;i[o]=(i[o]+e)%1e7|0}for(;!i[--a];)i.pop();return e?++r:i.shift(),t.d=i,t.e=r,u?E(t,f.precision):t},y.toDecimalPlaces=y.todp=function(t,e){var r=this,n=r.constructor;return(r=new n(r),void 0===t)?r:(m(t,0,1e9),void 0===e?e=n.rounding:m(e,0,8),E(r,t+w(r)+1,e))},y.toExponential=function(t,e){var r,n=this,o=n.constructor;return void 0===t?r=A(n,!0):(m(t,0,1e9),void 0===e?e=o.rounding:m(e,0,8),r=A(n=E(new o(n),t+1,e),!0,t+1)),r},y.toFixed=function(t,e){var r,n,o=this.constructor;return void 0===t?A(this):(m(t,0,1e9),void 0===e?e=o.rounding:m(e,0,8),r=A((n=E(new o(this),t+w(this)+1,e)).abs(),!1,t+w(n)+1),this.isneg()&&!this.isZero()?"-"+r:r)},y.toInteger=y.toint=function(){var t=this.constructor;return E(new t(this),w(this)+1,t.rounding)},y.toNumber=function(){return+this},y.toPower=y.pow=function(t){var e,r,n,o,a,l,s=this,p=s.constructor,h=+(t=new p(t));if(!t.s)return new p(i);if(!(s=new p(s)).s){if(t.s<1)throw Error(c+"Infinity");return s}if(s.eq(i))return s;if(n=p.precision,t.eq(i))return E(s,n);if(l=(e=t.e)>=(r=t.d.length-1),a=s.s,l){if((r=h<0?-h:h)<=9007199254740991){for(o=new p(i),e=Math.ceil(n/7+4),u=!1;r%2&&M((o=o.times(s)).d,e),0!==(r=f(r/2));)M((s=s.times(s)).d,e);return u=!0,t.s<0?new p(i).div(o):E(o,n)}}else if(a<0)throw Error(c+"NaN");return a=a<0&&1&t.d[Math.max(e,r)]?-1:1,s.s=1,u=!1,o=t.times(S(s,n+12)),u=!0,(o=x(o)).s=a,o},y.toPrecision=function(t,e){var r,n,o=this,i=o.constructor;return void 0===t?(r=w(o),n=A(o,r<=i.toExpNeg||r>=i.toExpPos)):(m(t,1,1e9),void 0===e?e=i.rounding:m(e,0,8),r=w(o=E(new i(o),t,e)),n=A(o,t<=r||r<=i.toExpNeg,t)),n},y.toSignificantDigits=y.tosd=function(t,e){var r=this.constructor;return void 0===t?(t=r.precision,e=r.rounding):(m(t,1,1e9),void 0===e?e=r.rounding:m(e,0,8)),E(new r(this),t,e)},y.toString=y.valueOf=y.val=y.toJSON=function(){var t=w(this),e=this.constructor;return A(this,t<=e.toExpNeg||t>=e.toExpPos)};var g=function(){function t(t,e){var r,n=0,o=t.length;for(t=t.slice();o--;)r=t[o]*e+n,t[o]=r%1e7|0,n=r/1e7|0;return n&&t.unshift(n),t}function e(t,e,r,n){var o,i;if(r!=n)i=r>n?1:-1;else for(o=i=0;oe[o]?1:-1;break}return i}function r(t,e,r){for(var n=0;r--;)t[r]-=n,n=t[r]1;)t.shift()}return function(n,o,i,a){var u,l,s,f,p,h,d,y,v,m,b,g,x,O,j,S,P,k,A=n.constructor,M=n.s==o.s?1:-1,_=n.d,T=o.d;if(!n.s)return new A(n);if(!o.s)throw Error(c+"Division by zero");for(s=0,l=n.e-o.e,P=T.length,j=_.length,y=(d=new A(M)).d=[];T[s]==(_[s]||0);)++s;if(T[s]>(_[s]||0)&&--l,(g=null==i?i=A.precision:a?i+(w(n)-w(o))+1:i)<0)return new A(0);if(g=g/7+2|0,s=0,1==P)for(f=0,T=T[0],g++;(s1&&(T=t(T,f),_=t(_,f),P=T.length,j=_.length),O=P,m=(v=_.slice(0,P)).length;m=1e7/2&&++S;do f=0,(u=e(T,v,P,m))<0?(b=v[0],P!=m&&(b=1e7*b+(v[1]||0)),(f=b/S|0)>1?(f>=1e7&&(f=1e7-1),h=(p=t(T,f)).length,m=v.length,1==(u=e(p,v,h,m))&&(f--,r(p,P16)throw Error(s+w(t));if(!t.s)return new h(i);for(null==e?(u=!1,c=d):c=e,a=new h(.03125);t.abs().gte(.1);)t=t.times(a),f+=5;for(c+=Math.log(p(2,f))/Math.LN10*2+5|0,r=n=o=new h(i),h.precision=c;;){if(n=E(n.times(t),c),r=r.times(++l),b((a=o.plus(g(n,r,c))).d).slice(0,c)===b(o.d).slice(0,c)){for(;f--;)o=E(o.times(o),c);return h.precision=d,null==e?(u=!0,E(o,d)):o}o=a}}function w(t){for(var e=7*t.e,r=t.d[0];r>=10;r/=10)e++;return e}function O(t,e,r){if(e>t.LN10.sd())throw u=!0,r&&(t.precision=r),Error(c+"LN10 precision limit exceeded");return E(new t(t.LN10),e)}function j(t){for(var e="";t--;)e+="0";return e}function S(t,e){var r,n,o,a,l,s,f,p,h,d=1,y=t,v=y.d,m=y.constructor,x=m.precision;if(y.s<1)throw Error(c+(y.s?"NaN":"-Infinity"));if(y.eq(i))return new m(0);if(null==e?(u=!1,p=x):p=e,y.eq(10))return null==e&&(u=!0),O(m,p);if(p+=10,m.precision=p,n=(r=b(v)).charAt(0),!(15e14>Math.abs(a=w(y))))return f=O(m,p+2,x).times(a+""),y=S(new m(n+"."+r.slice(1)),p-10).plus(f),m.precision=x,null==e?(u=!0,E(y,x)):y;for(;n<7&&1!=n||1==n&&r.charAt(1)>3;)n=(r=b((y=y.times(t)).d)).charAt(0),d++;for(a=w(y),n>1?(y=new m("0."+r),a++):y=new m(n+"."+r.slice(1)),s=l=y=g(y.minus(i),y.plus(i),p),h=E(y.times(y),p),o=3;;){if(l=E(l.times(h),p),b((f=s.plus(g(l,new m(o),p))).d).slice(0,p)===b(s.d).slice(0,p))return s=s.times(2),0!==a&&(s=s.plus(O(m,p+2,x).times(a+""))),s=g(s,new m(d),p),m.precision=x,null==e?(u=!0,E(s,x)):s;s=f,o+=2}}function P(t,e){var r,n,o;for((r=e.indexOf("."))>-1&&(e=e.replace(".","")),(n=e.search(/e/i))>0?(r<0&&(r=n),r+=+e.slice(n+1),e=e.substring(0,n)):r<0&&(r=e.length),n=0;48===e.charCodeAt(n);)++n;for(o=e.length;48===e.charCodeAt(o-1);)--o;if(e=e.slice(n,o)){if(o-=n,r=r-n-1,t.e=f(r/7),t.d=[],n=(r+1)%7,r<0&&(n+=7),nd||t.e<-d))throw Error(s+r)}else t.s=0,t.e=0,t.d=[0];return t}function E(t,e,r){var n,o,i,a,c,l,h,y,v=t.d;for(a=1,i=v[0];i>=10;i/=10)a++;if((n=e-a)<0)n+=7,o=e,h=v[y=0];else{if((y=Math.ceil((n+1)/7))>=(i=v.length))return t;for(a=1,h=i=v[y];i>=10;i/=10)a++;n%=7,o=n-7+a}if(void 0!==r&&(c=h/(i=p(10,a-o-1))%10|0,l=e<0||void 0!==v[y+1]||h%i,l=r<4?(c||l)&&(0==r||r==(t.s<0?3:2)):c>5||5==c&&(4==r||l||6==r&&(n>0?o>0?h/p(10,a-o):0:v[y-1])%10&1||r==(t.s<0?8:7))),e<1||!v[0])return l?(i=w(t),v.length=1,e=e-i-1,v[0]=p(10,(7-e%7)%7),t.e=f(-e/7)||0):(v.length=1,v[0]=t.e=t.s=0),t;if(0==n?(v.length=y,i=1,y--):(v.length=y+1,i=p(10,7-n),v[y]=o>0?(h/p(10,a-o)%p(10,o)|0)*i:0),l)for(;;){if(0==y){1e7==(v[0]+=i)&&(v[0]=1,++t.e);break}if(v[y]+=i,1e7!=v[y])break;v[y--]=0,i=1}for(n=v.length;0===v[--n];)v.pop();if(u&&(t.e>d||t.e<-d))throw Error(s+w(t));return t}function k(t,e){var r,n,o,i,a,c,l,s,f,p,h=t.constructor,d=h.precision;if(!t.s||!e.s)return e.s?e.s=-e.s:e=new h(t),u?E(e,d):e;if(l=t.d,p=e.d,n=e.e,s=t.e,l=l.slice(),a=s-n){for((f=a<0)?(r=l,a=-a,c=p.length):(r=p,n=s,c=l.length),a>(o=Math.max(Math.ceil(d/7),c)+2)&&(a=o,r.length=1),r.reverse(),o=a;o--;)r.push(0);r.reverse()}else{for((f=(o=l.length)<(c=p.length))&&(c=o),o=0;o0;--o)l[c++]=0;for(o=p.length;o>a;){if(l[--o]0?i=i.charAt(0)+"."+i.slice(1)+j(n):a>1&&(i=i.charAt(0)+"."+i.slice(1)),i=i+(o<0?"e":"e+")+o):o<0?(i="0."+j(-o-1)+i,r&&(n=r-a)>0&&(i+=j(n))):o>=a?(i+=j(o+1-a),r&&(n=r-o-1)>0&&(i=i+"."+j(n))):((n=o+1)0&&(o+1===a&&(i+="."),i+=j(n))),t.s<0?"-"+i:i}function M(t,e){if(t.length>e)return t.length=e,!0}function _(t){if(!t||"object"!=typeof t)throw Error(c+"Object expected");var e,r,n,o=["precision",1,1e9,"rounding",0,8,"toExpNeg",-1/0,0,"toExpPos",0,1/0];for(e=0;e=o[e+1]&&n<=o[e+2])this[r]=n;else throw Error(l+r+": "+n)}if(void 0!==(n=t[r="LN10"])){if(n==Math.LN10)this[r]=new this(n);else throw Error(l+r+": "+n)}return this}(a=function t(e){var r,n,o;function i(t){if(!(this instanceof i))return new i(t);if(this.constructor=i,t instanceof i){this.s=t.s,this.e=t.e,this.d=(t=t.d)?t.slice():t;return}if("number"==typeof t){if(0*t!=0)throw Error(l+t);if(t>0)this.s=1;else if(t<0)t=-t,this.s=-1;else{this.s=0,this.e=0,this.d=[0];return}if(t===~~t&&t<1e7){this.e=0,this.d=[t];return}return P(this,t.toString())}if("string"!=typeof t)throw Error(l+t);if(45===t.charCodeAt(0)?(t=t.slice(1),this.s=-1):this.s=1,h.test(t))P(this,t);else throw Error(l+t)}if(i.prototype=y,i.ROUND_UP=0,i.ROUND_DOWN=1,i.ROUND_CEIL=2,i.ROUND_FLOOR=3,i.ROUND_HALF_UP=4,i.ROUND_HALF_DOWN=5,i.ROUND_HALF_EVEN=6,i.ROUND_HALF_CEIL=7,i.ROUND_HALF_FLOOR=8,i.clone=t,i.config=i.set=_,void 0===e&&(e={}),e)for(r=0,o=["precision","rounding","toExpNeg","toExpPos","LN10"];r-1}},56883:function(t){t.exports=function(t,e,r){for(var n=-1,o=null==t?0:t.length;++n0&&i(s)?r>1?t(s,r-1,i,a,u):n(u,s):a||(u[u.length]=s)}return u}},63321:function(t,e,r){var n=r(33023)();t.exports=n},98060:function(t,e,r){var n=r(63321),o=r(43228);t.exports=function(t,e){return t&&n(t,e,o)}},92167:function(t,e,r){var n=r(67906),o=r(70235);t.exports=function(t,e){e=n(e,t);for(var r=0,i=e.length;null!=t&&re}},93012:function(t){t.exports=function(t,e){return null!=t&&e in Object(t)}},47909:function(t,e,r){var n=r(8235),o=r(31953),i=r(35281);t.exports=function(t,e,r){return e==e?i(t,e,r):n(t,o,r)}},90370:function(t,e,r){var n=r(54506),o=r(10303);t.exports=function(t){return o(t)&&"[object Arguments]"==n(t)}},56318:function(t,e,r){var n=r(6791),o=r(10303);t.exports=function t(e,r,i,a,u){return e===r||(null!=e&&null!=r&&(o(e)||o(r))?n(e,r,i,a,t,u):e!=e&&r!=r)}},6791:function(t,e,r){var n=r(85885),o=r(97638),i=r(88030),a=r(64974),u=r(81690),c=r(25614),l=r(98051),s=r(9792),f="[object Arguments]",p="[object Array]",h="[object Object]",d=Object.prototype.hasOwnProperty;t.exports=function(t,e,r,y,v,m){var b=c(t),g=c(e),x=b?p:u(t),w=g?p:u(e);x=x==f?h:x,w=w==f?h:w;var O=x==h,j=w==h,S=x==w;if(S&&l(t)){if(!l(e))return!1;b=!0,O=!1}if(S&&!O)return m||(m=new n),b||s(t)?o(t,e,r,y,v,m):i(t,e,x,r,y,v,m);if(!(1&r)){var P=O&&d.call(t,"__wrapped__"),E=j&&d.call(e,"__wrapped__");if(P||E){var k=P?t.value():t,A=E?e.value():e;return m||(m=new n),v(k,A,r,y,m)}}return!!S&&(m||(m=new n),a(t,e,r,y,v,m))}},62538:function(t,e,r){var n=r(85885),o=r(56318);t.exports=function(t,e,r,i){var a=r.length,u=a,c=!i;if(null==t)return!u;for(t=Object(t);a--;){var l=r[a];if(c&&l[2]?l[1]!==t[l[0]]:!(l[0]in t))return!1}for(;++ao?0:o+e),(r=r>o?o:r)<0&&(r+=o),o=e>r?0:r-e>>>0,e>>>=0;for(var i=Array(o);++n=200){var y=e?null:u(t);if(y)return c(y);p=!1,s=a,d=new n}else d=e?[]:h;t:for(;++l=o?t:n(t,e,r)}},1536:function(t,e,r){var n=r(78371);t.exports=function(t,e){if(t!==e){var r=void 0!==t,o=null===t,i=t==t,a=n(t),u=void 0!==e,c=null===e,l=e==e,s=n(e);if(!c&&!s&&!a&&t>e||a&&u&&l&&!c&&!s||o&&u&&l||!r&&l||!i)return 1;if(!o&&!a&&!s&&t=c)return l;return l*("desc"==r[o]?-1:1)}}return t.index-e.index}},92077:function(t,e,r){var n=r(74288)["__core-js_shared__"];t.exports=n},97930:function(t,e,r){var n=r(5629);t.exports=function(t,e){return function(r,o){if(null==r)return r;if(!n(r))return t(r,o);for(var i=r.length,a=e?i:-1,u=Object(r);(e?a--:++a-1?u[c?e[l]:l]:void 0}}},35464:function(t,e,r){var n=r(19608),o=r(49639),i=r(175);t.exports=function(t){return function(e,r,a){return a&&"number"!=typeof a&&o(e,r,a)&&(r=a=void 0),e=i(e),void 0===r?(r=e,e=0):r=i(r),a=void 0===a?es))return!1;var p=c.get(t),h=c.get(e);if(p&&h)return p==e&&h==t;var d=-1,y=!0,v=2&r?new n:void 0;for(c.set(t,e),c.set(e,t);++d-1&&t%1==0&&t-1}},13368:function(t,e,r){var n=r(24457);t.exports=function(t,e){var r=this.__data__,o=n(r,t);return o<0?(++this.size,r.push([t,e])):r[o][1]=e,this}},38764:function(t,e,r){var n=r(9855),o=r(99078),i=r(88675);t.exports=function(){this.size=0,this.__data__={hash:new n,map:new(i||o),string:new n}}},78615:function(t,e,r){var n=r(1507);t.exports=function(t){var e=n(this,t).delete(t);return this.size-=e?1:0,e}},83391:function(t,e,r){var n=r(1507);t.exports=function(t){return n(this,t).get(t)}},53483:function(t,e,r){var n=r(1507);t.exports=function(t){return n(this,t).has(t)}},74724:function(t,e,r){var n=r(1507);t.exports=function(t,e){var r=n(this,t),o=r.size;return r.set(t,e),this.size+=r.size==o?0:1,this}},22523:function(t){t.exports=function(t){var e=-1,r=Array(t.size);return t.forEach(function(t,n){r[++e]=[n,t]}),r}},47073:function(t){t.exports=function(t,e){return function(r){return null!=r&&r[t]===e&&(void 0!==e||t in Object(r))}}},23787:function(t,e,r){var n=r(50967);t.exports=function(t){var e=n(t,function(t){return 500===r.size&&r.clear(),t}),r=e.cache;return e}},20453:function(t,e,r){var n=r(39866)(Object,"create");t.exports=n},77184:function(t,e,r){var n=r(45070)(Object.keys,Object);t.exports=n},39931:function(t,e,r){t=r.nmd(t);var n=r(17071),o=e&&!e.nodeType&&e,i=o&&t&&!t.nodeType&&t,a=i&&i.exports===o&&n.process,u=function(){try{var t=i&&i.require&&i.require("util").types;if(t)return t;return a&&a.binding&&a.binding("util")}catch(t){}}();t.exports=u},45070:function(t){t.exports=function(t,e){return function(r){return t(e(r))}}},49478:function(t,e,r){var n=r(60493),o=Math.max;t.exports=function(t,e,r){return e=o(void 0===e?t.length-1:e,0),function(){for(var i=arguments,a=-1,u=o(i.length-e,0),c=Array(u);++a0){if(++r>=800)return arguments[0]}else r=0;return t.apply(void 0,arguments)}}},84092:function(t,e,r){var n=r(99078);t.exports=function(){this.__data__=new n,this.size=0}},31663:function(t){t.exports=function(t){var e=this.__data__,r=e.delete(t);return this.size=e.size,r}},69135:function(t){t.exports=function(t){return this.__data__.get(t)}},39552:function(t){t.exports=function(t){return this.__data__.has(t)}},8381:function(t,e,r){var n=r(99078),o=r(88675),i=r(76219);t.exports=function(t,e){var r=this.__data__;if(r instanceof n){var a=r.__data__;if(!o||a.length<199)return a.push([t,e]),this.size=++r.size,this;r=this.__data__=new i(a)}return r.set(t,e),this.size=r.size,this}},35281:function(t){t.exports=function(t,e,r){for(var n=r-1,o=t.length;++n-1&&t%1==0&&t<=9007199254740991}},82559:function(t,e,r){var n=r(22345);t.exports=function(t){return n(t)&&t!=+t}},77571:function(t){t.exports=function(t){return null==t}},22345:function(t,e,r){var n=r(54506),o=r(10303);t.exports=function(t){return"number"==typeof t||o(t)&&"[object Number]"==n(t)}},90231:function(t,e,r){var n=r(54506),o=r(62602),i=r(10303),a=Object.prototype,u=Function.prototype.toString,c=a.hasOwnProperty,l=u.call(Object);t.exports=function(t){if(!i(t)||"[object Object]"!=n(t))return!1;var e=o(t);if(null===e)return!0;var r=c.call(e,"constructor")&&e.constructor;return"function"==typeof r&&r instanceof r&&u.call(r)==l}},42715:function(t,e,r){var n=r(54506),o=r(25614),i=r(10303);t.exports=function(t){return"string"==typeof t||!o(t)&&i(t)&&"[object String]"==n(t)}},9792:function(t,e,r){var n=r(59332),o=r(23305),i=r(39931),a=i&&i.isTypedArray,u=a?o(a):n;t.exports=u},43228:function(t,e,r){var n=r(28579),o=r(4578),i=r(5629);t.exports=function(t){return i(t)?n(t):o(t)}},86185:function(t){t.exports=function(t){var e=null==t?0:t.length;return e?t[e-1]:void 0}},89238:function(t,e,r){var n=r(73819),o=r(88157),i=r(24240),a=r(25614);t.exports=function(t,e){return(a(t)?n:i)(t,o(e,3))}},41443:function(t,e,r){var n=r(83023),o=r(98060),i=r(88157);t.exports=function(t,e){var r={};return e=i(e,3),o(t,function(t,o,i){n(r,o,e(t,o,i))}),r}},95645:function(t,e,r){var n=r(67646),o=r(58905),i=r(79586);t.exports=function(t){return t&&t.length?n(t,i,o):void 0}},50967:function(t,e,r){var n=r(76219);function o(t,e){if("function"!=typeof t||null!=e&&"function"!=typeof e)throw TypeError("Expected a function");var r=function(){var n=arguments,o=e?e.apply(this,n):n[0],i=r.cache;if(i.has(o))return i.get(o);var a=t.apply(this,n);return r.cache=i.set(o,a)||i,a};return r.cache=new(o.Cache||n),r}o.Cache=n,t.exports=o},99008:function(t,e,r){var n=r(67646),o=r(20121),i=r(79586);t.exports=function(t){return t&&t.length?n(t,i,o):void 0}},93810:function(t){t.exports=function(){}},22350:function(t,e,r){var n=r(18155),o=r(73584),i=r(67352),a=r(70235);t.exports=function(t){return i(t)?n(a(t)):o(t)}},99676:function(t,e,r){var n=r(35464)();t.exports=n},33645:function(t,e,r){var n=r(25253),o=r(88157),i=r(12327),a=r(25614),u=r(49639);t.exports=function(t,e,r){var c=a(t)?n:i;return r&&u(t,e,r)&&(e=void 0),c(t,o(e,3))}},34935:function(t,e,r){var n=r(72569),o=r(84046),i=r(44843),a=r(49639),u=i(function(t,e){if(null==t)return[];var r=e.length;return r>1&&a(t,e[0],e[1])?e=[]:r>2&&a(e[0],e[1],e[2])&&(e=[e[0]]),o(t,n(e,1),[])});t.exports=u},55716:function(t){t.exports=function(){return[]}},7406:function(t){t.exports=function(){return!1}},37065:function(t,e,r){var n=r(7310),o=r(28302);t.exports=function(t,e,r){var i=!0,a=!0;if("function"!=typeof t)throw TypeError("Expected a function");return o(r)&&(i="leading"in r?!!r.leading:i,a="trailing"in r?!!r.trailing:a),n(t,e,{leading:i,maxWait:e,trailing:a})}},175:function(t,e,r){var n=r(6660),o=1/0;t.exports=function(t){return t?(t=n(t))===o||t===-o?(t<0?-1:1)*17976931348623157e292:t==t?t:0:0===t?t:0}},85759:function(t,e,r){var n=r(175);t.exports=function(t){var e=n(t),r=e%1;return e==e?r?e-r:e:0}},3641:function(t,e,r){var n=r(65020);t.exports=function(t){return null==t?"":n(t)}},47230:function(t,e,r){var n=r(88157),o=r(13826);t.exports=function(t,e){return t&&t.length?o(t,n(e,2)):[]}},75551:function(t,e,r){var n=r(80675)("toUpperCase");t.exports=n},48049:function(t,e,r){"use strict";var n=r(14397);function o(){}function i(){}i.resetWarningCache=o,t.exports=function(){function t(t,e,r,o,i,a){if(a!==n){var u=Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw u.name="Invariant Violation",u}}function e(){return t}t.isRequired=t;var r={array:t,bigint:t,bool:t,func:t,number:t,object:t,string:t,symbol:t,any:t,arrayOf:e,element:t,elementType:t,instanceOf:e,node:t,objectOf:e,oneOf:e,oneOfType:e,shape:e,exact:e,checkPropTypes:i,resetWarningCache:o};return r.PropTypes=r,r}},40718:function(t,e,r){t.exports=r(48049)()},14397:function(t){"use strict";t.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},84735:function(t,e,r){"use strict";r.d(e,{ZP:function(){return tS}});var n=r(2265),o=r(40718),i=r.n(o),a=Object.getOwnPropertyNames,u=Object.getOwnPropertySymbols,c=Object.prototype.hasOwnProperty;function l(t,e){return function(r,n,o){return t(r,n,o)&&e(r,n,o)}}function s(t){return function(e,r,n){if(!e||!r||"object"!=typeof e||"object"!=typeof r)return t(e,r,n);var o=n.cache,i=o.get(e),a=o.get(r);if(i&&a)return i===r&&a===e;o.set(e,r),o.set(r,e);var u=t(e,r,n);return o.delete(e),o.delete(r),u}}function f(t){return a(t).concat(u(t))}var p=Object.hasOwn||function(t,e){return c.call(t,e)};function h(t,e){return t===e||!t&&!e&&t!=t&&e!=e}var d=Object.getOwnPropertyDescriptor,y=Object.keys;function v(t,e,r){var n=t.length;if(e.length!==n)return!1;for(;n-- >0;)if(!r.equals(t[n],e[n],n,n,t,e,r))return!1;return!0}function m(t,e){return h(t.getTime(),e.getTime())}function b(t,e){return t.name===e.name&&t.message===e.message&&t.cause===e.cause&&t.stack===e.stack}function g(t,e){return t===e}function x(t,e,r){var n,o,i=t.size;if(i!==e.size)return!1;if(!i)return!0;for(var a=Array(i),u=t.entries(),c=0;(n=u.next())&&!n.done;){for(var l=e.entries(),s=!1,f=0;(o=l.next())&&!o.done;){if(a[f]){f++;continue}var p=n.value,h=o.value;if(r.equals(p[0],h[0],c,f,t,e,r)&&r.equals(p[1],h[1],p[0],h[0],t,e,r)){s=a[f]=!0;break}f++}if(!s)return!1;c++}return!0}function w(t,e,r){var n=y(t),o=n.length;if(y(e).length!==o)return!1;for(;o-- >0;)if(!A(t,e,r,n[o]))return!1;return!0}function O(t,e,r){var n,o,i,a=f(t),u=a.length;if(f(e).length!==u)return!1;for(;u-- >0;)if(!A(t,e,r,n=a[u])||(o=d(t,n),i=d(e,n),(o||i)&&(!o||!i||o.configurable!==i.configurable||o.enumerable!==i.enumerable||o.writable!==i.writable)))return!1;return!0}function j(t,e){return h(t.valueOf(),e.valueOf())}function S(t,e){return t.source===e.source&&t.flags===e.flags}function P(t,e,r){var n,o,i=t.size;if(i!==e.size)return!1;if(!i)return!0;for(var a=Array(i),u=t.values();(n=u.next())&&!n.done;){for(var c=e.values(),l=!1,s=0;(o=c.next())&&!o.done;){if(!a[s]&&r.equals(n.value,o.value,n.value,o.value,t,e,r)){l=a[s]=!0;break}s++}if(!l)return!1}return!0}function E(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}function k(t,e){return t.hostname===e.hostname&&t.pathname===e.pathname&&t.protocol===e.protocol&&t.port===e.port&&t.hash===e.hash&&t.username===e.username&&t.password===e.password}function A(t,e,r,n){return("_owner"===n||"__o"===n||"__v"===n)&&(!!t.$$typeof||!!e.$$typeof)||p(e,n)&&r.equals(t[n],e[n],n,n,t,e,r)}var M=Array.isArray,_="undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView:null,T=Object.assign,C=Object.prototype.toString.call.bind(Object.prototype.toString),N=D();function D(t){void 0===t&&(t={});var e,r,n,o,i,a,u,c,f,p,d,y,A,N,D=t.circular,I=t.createInternalComparator,L=t.createState,B=t.strict,R=(r=(e=function(t){var e=t.circular,r=t.createCustomConfig,n=t.strict,o={areArraysEqual:n?O:v,areDatesEqual:m,areErrorsEqual:b,areFunctionsEqual:g,areMapsEqual:n?l(x,O):x,areNumbersEqual:h,areObjectsEqual:n?O:w,arePrimitiveWrappersEqual:j,areRegExpsEqual:S,areSetsEqual:n?l(P,O):P,areTypedArraysEqual:n?O:E,areUrlsEqual:k,unknownTagComparators:void 0};if(r&&(o=T({},o,r(o))),e){var i=s(o.areArraysEqual),a=s(o.areMapsEqual),u=s(o.areObjectsEqual),c=s(o.areSetsEqual);o=T({},o,{areArraysEqual:i,areMapsEqual:a,areObjectsEqual:u,areSetsEqual:c})}return o}(t)).areArraysEqual,n=e.areDatesEqual,o=e.areErrorsEqual,i=e.areFunctionsEqual,a=e.areMapsEqual,u=e.areNumbersEqual,c=e.areObjectsEqual,f=e.arePrimitiveWrappersEqual,p=e.areRegExpsEqual,d=e.areSetsEqual,y=e.areTypedArraysEqual,A=e.areUrlsEqual,N=e.unknownTagComparators,function(t,e,l){if(t===e)return!0;if(null==t||null==e)return!1;var s=typeof t;if(s!==typeof e)return!1;if("object"!==s)return"number"===s?u(t,e,l):"function"===s&&i(t,e,l);var h=t.constructor;if(h!==e.constructor)return!1;if(h===Object)return c(t,e,l);if(M(t))return r(t,e,l);if(null!=_&&_(t))return y(t,e,l);if(h===Date)return n(t,e,l);if(h===RegExp)return p(t,e,l);if(h===Map)return a(t,e,l);if(h===Set)return d(t,e,l);var v=C(t);if("[object Date]"===v)return n(t,e,l);if("[object RegExp]"===v)return p(t,e,l);if("[object Map]"===v)return a(t,e,l);if("[object Set]"===v)return d(t,e,l);if("[object Object]"===v)return"function"!=typeof t.then&&"function"!=typeof e.then&&c(t,e,l);if("[object URL]"===v)return A(t,e,l);if("[object Error]"===v)return o(t,e,l);if("[object Arguments]"===v)return c(t,e,l);if("[object Boolean]"===v||"[object Number]"===v||"[object String]"===v)return f(t,e,l);if(N){var m=N[v];if(!m){var b=null!=t?t[Symbol.toStringTag]:void 0;b&&(m=N[b])}if(m)return m(t,e,l)}return!1}),z=I?I(R):function(t,e,r,n,o,i,a){return R(t,e,a)};return function(t){var e=t.circular,r=t.comparator,n=t.createState,o=t.equals,i=t.strict;if(n)return function(t,a){var u=n(),c=u.cache;return r(t,a,{cache:void 0===c?e?new WeakMap:void 0:c,equals:o,meta:u.meta,strict:i})};if(e)return function(t,e){return r(t,e,{cache:new WeakMap,equals:o,meta:void 0,strict:i})};var a={cache:void 0,equals:o,meta:void 0,strict:i};return function(t,e){return r(t,e,a)}}({circular:void 0!==D&&D,comparator:R,createState:L,equals:z,strict:void 0!==B&&B})}function I(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r=-1;requestAnimationFrame(function n(o){if(r<0&&(r=o),o-r>e)t(o),r=-1;else{var i;i=n,"undefined"!=typeof requestAnimationFrame&&requestAnimationFrame(i)}})}function L(t){return(L="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function B(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);rt.length)&&(e=t.length);for(var r=0,n=Array(e);r=0&&t<=1}),"[configBezier]: arguments should be x1, y1, x2, y2 of [0, 1] instead received %s",n);var p=V(i,u),h=V(a,c),d=(t=i,e=u,function(r){var n;return G([].concat(function(t){if(Array.isArray(t))return H(t)}(n=X(t,e).map(function(t,e){return t*e}).slice(1))||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(n)||Y(n)||function(){throw TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(),[0]),r)}),y=function(t){for(var e=t>1?1:t,r=e,n=0;n<8;++n){var o,i=p(r)-e,a=d(r);if(1e-4>Math.abs(i-e)||a<1e-4)break;r=(o=r-i/a)>1?1:o<0?0:o}return h(r)};return y.isStepper=!1,y},Q=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.stiff,r=void 0===e?100:e,n=t.damping,o=void 0===n?8:n,i=t.dt,a=void 0===i?17:i,u=function(t,e,n){var i=n+(-(t-e)*r-n*o)*a/1e3,u=n*a/1e3+t;return 1e-4>Math.abs(u-e)&&1e-4>Math.abs(i)?[e,0]:[u,i]};return u.isStepper=!0,u.dt=a,u},J=function(){for(var t=arguments.length,e=Array(t),r=0;rt.length)&&(e=t.length);for(var r=0,n=Array(e);rt.length)&&(e=t.length);for(var r=0,n=Array(e);r0?r[o-1]:n,p=l||Object.keys(c);if("function"==typeof u||"spring"===u)return[].concat(th(t),[e.runJSAnimation.bind(e,{from:f.style,to:c,duration:i,easing:u}),i]);var h=Z(p,i,u),d=tv(tv(tv({},f.style),c),{},{transition:h});return[].concat(th(t),[d,i,s]).filter($)},[a,Math.max(void 0===u?0:u,n)])),[t.onAnimationEnd]))}},{key:"runAnimation",value:function(t){if(!this.manager){var e,r,n;this.manager=(e=function(){return null},r=!1,n=function t(n){if(!r){if(Array.isArray(n)){if(!n.length)return;var o=function(t){if(Array.isArray(t))return t}(n)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(n)||function(t,e){if(t){if("string"==typeof t)return B(t,void 0);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return B(t,void 0)}}(n)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(),i=o[0],a=o.slice(1);if("number"==typeof i){I(t.bind(null,a),i);return}t(i),I(t.bind(null,a));return}"object"===L(n)&&e(n),"function"==typeof n&&n()}},{stop:function(){r=!0},start:function(t){r=!1,n(t)},subscribe:function(t){return e=t,function(){e=function(){return null}}}})}var o=t.begin,i=t.duration,a=t.attributeName,u=t.to,c=t.easing,l=t.onAnimationStart,s=t.onAnimationEnd,f=t.steps,p=t.children,h=this.manager;if(this.unSubscribe=h.subscribe(this.handleStyleChange),"function"==typeof c||"function"==typeof p||"spring"===c){this.runJSAnimation(t);return}if(f.length>1){this.runStepAnimation(t);return}var d=a?tm({},a,u):u,y=Z(Object.keys(d),i,c);h.start([l,o,tv(tv({},d),{},{transition:y}),i,s])}},{key:"render",value:function(){var t=this.props,e=t.children,r=(t.begin,t.duration),o=(t.attributeName,t.easing,t.isActive),i=(t.steps,t.from,t.to,t.canBegin,t.onAnimationEnd,t.shouldReAnimate,t.onAnimationReStart,function(t,e){if(null==t)return{};var r,n,o=function(t,e){if(null==t)return{};var r,n,o={},i=Object.keys(t);for(n=0;n=0||(o[r]=t[r]);return o}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(t,tp)),a=n.Children.count(e),u=this.state.style;if("function"==typeof e)return e(u);if(!o||0===a||r<=0)return e;var c=function(t){var e=t.props,r=e.style,o=e.className;return(0,n.cloneElement)(t,tv(tv({},i),{},{style:tv(tv({},void 0===r?{}:r),u),className:o}))};return 1===a?c(n.Children.only(e)):n.createElement("div",null,n.Children.map(e,function(t){return c(t)}))}}],function(t,e){for(var r=0;r=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(t,w),i=parseInt("".concat(r),10),a=parseInt("".concat(n),10),u=parseInt("".concat(e.height||o.height),10),c=parseInt("".concat(e.width||o.width),10);return P(P(P(P(P({},e),o),i?{x:i}:{}),a?{y:a}:{}),{},{height:u,width:c,name:e.name,radius:e.radius})}function k(t){return n.createElement(x.bn,j({shapeType:"rectangle",propTransformer:E,activeClassName:"recharts-active-bar"},t))}var A=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return function(r,n){if("number"==typeof t)return t;var o=(0,d.hj)(r)||(0,d.Rw)(r);return o?t(r,n):(o||(0,g.Z)(!1),e)}},M=["value","background"];function _(t){return(_="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function T(){return(T=Object.assign?Object.assign.bind():function(t){for(var e=1;e=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(e,M);if(!u)return null;var l=N(N(N(N(N({},c),{},{fill:"#eee"},u),a),(0,b.bw)(t.props,e,r)),{},{onAnimationStart:t.handleAnimationStart,onAnimationEnd:t.handleAnimationEnd,dataKey:o,index:r,className:"recharts-bar-background-rectangle"});return n.createElement(k,T({key:"background-bar-".concat(r),option:t.props.background,isActive:r===i},l))})}},{key:"renderErrorBar",value:function(t,e){if(this.props.isAnimationActive&&!this.state.isAnimationFinished)return null;var r=this.props,o=r.data,i=r.xAxis,a=r.yAxis,u=r.layout,c=r.children,l=(0,y.NN)(c,f.W);if(!l)return null;var p="vertical"===u?o[0].height/2:o[0].width/2,h=function(t,e){var r=Array.isArray(t.value)?t.value[1]:t.value;return{x:t.x,y:t.y,value:r,errorVal:(0,m.F$)(t,e)}};return n.createElement(s.m,{clipPath:t?"url(#clipPath-".concat(e,")"):null},l.map(function(t){return n.cloneElement(t,{key:"error-bar-".concat(e,"-").concat(t.props.dataKey),data:o,xAxis:i,yAxis:a,layout:u,offset:p,dataPointFormatter:h})}))}},{key:"render",value:function(){var t=this.props,e=t.hide,r=t.data,i=t.className,a=t.xAxis,u=t.yAxis,c=t.left,f=t.top,p=t.width,d=t.height,y=t.isAnimationActive,v=t.background,m=t.id;if(e||!r||!r.length)return null;var b=this.state.isAnimationFinished,g=(0,o.Z)("recharts-bar",i),x=a&&a.allowDataOverflow,w=u&&u.allowDataOverflow,O=x||w,j=l()(m)?this.id:m;return n.createElement(s.m,{className:g},x||w?n.createElement("defs",null,n.createElement("clipPath",{id:"clipPath-".concat(j)},n.createElement("rect",{x:x?c:c-p/2,y:w?f:f-d/2,width:x?p:2*p,height:w?d:2*d}))):null,n.createElement(s.m,{className:"recharts-bar-rectangles",clipPath:O?"url(#clipPath-".concat(j,")"):null},v?this.renderBackground():null,this.renderRectangles()),this.renderErrorBar(O,j),(!y||b)&&h.e.renderCallByParent(this.props,r))}}],r=[{key:"getDerivedStateFromProps",value:function(t,e){return t.animationId!==e.prevAnimationId?{prevAnimationId:t.animationId,curData:t.data,prevData:e.curData}:t.data!==e.curData?{curData:t.data}:null}}],e&&D(a.prototype,e),r&&D(a,r),Object.defineProperty(a,"prototype",{writable:!1}),a}(n.PureComponent);R(U,"displayName","Bar"),R(U,"defaultProps",{xAxisId:0,yAxisId:0,legendType:"rect",minPointSize:0,hide:!1,data:[],layout:"vertical",activeBar:!1,isAnimationActive:!v.x.isSsr,animationBegin:0,animationDuration:400,animationEasing:"ease"}),R(U,"getComposedData",function(t){var e=t.props,r=t.item,n=t.barPosition,o=t.bandSize,i=t.xAxis,a=t.yAxis,u=t.xAxisTicks,c=t.yAxisTicks,l=t.stackedData,s=t.dataStartIndex,f=t.displayedData,h=t.offset,v=(0,m.Bu)(n,r);if(!v)return null;var b=e.layout,g=r.type.defaultProps,x=void 0!==g?N(N({},g),r.props):r.props,w=x.dataKey,O=x.children,j=x.minPointSize,S="horizontal"===b?a:i,P=l?S.scale.domain():null,E=(0,m.Yj)({numericAxis:S}),k=(0,y.NN)(O,p.b),M=f.map(function(t,e){l?f=(0,m.Vv)(l[s+e],P):Array.isArray(f=(0,m.F$)(t,w))||(f=[E,f]);var n=A(j,U.defaultProps.minPointSize)(f[1],e);if("horizontal"===b){var f,p,h,y,g,x,O,S=[a.scale(f[0]),a.scale(f[1])],M=S[0],_=S[1];p=(0,m.Fy)({axis:i,ticks:u,bandSize:o,offset:v.offset,entry:t,index:e}),h=null!==(O=null!=_?_:M)&&void 0!==O?O:void 0,y=v.size;var T=M-_;if(g=Number.isNaN(T)?0:T,x={x:p,y:a.y,width:y,height:a.height},Math.abs(n)>0&&Math.abs(g)0&&Math.abs(y)=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}function P(t,e){for(var r=0;r0?this.props:d)),o<=0||a<=0||!y||!y.length)?null:n.createElement(s.m,{className:(0,c.Z)("recharts-cartesian-axis",l),ref:function(e){t.layerReference=e}},r&&this.renderAxisLine(),this.renderTicks(y,this.state.fontSize,this.state.letterSpacing),p._.renderCallByParent(this.props))}}],r=[{key:"renderTickItem",value:function(t,e,r){var o=(0,c.Z)(e.className,"recharts-cartesian-axis-tick-value");return n.isValidElement(t)?n.cloneElement(t,j(j({},e),{},{className:o})):i()(t)?t(j(j({},e),{},{className:o})):n.createElement(f.x,w({},e,{className:"recharts-cartesian-axis-tick-value"}),r)}}],e&&P(o.prototype,e),r&&P(o,r),Object.defineProperty(o,"prototype",{writable:!1}),o}(n.Component);M(T,"displayName","CartesianAxis"),M(T,"defaultProps",{x:0,y:0,width:0,height:0,viewBox:{x:0,y:0,width:0,height:0},orientation:"bottom",ticks:[],stroke:"#666",tickLine:!0,axisLine:!0,tick:!0,mirror:!1,minTickGap:5,tickSize:6,tickMargin:2,interval:"preserveEnd"})},56940:function(t,e,r){"use strict";r.d(e,{q:function(){return M}});var n=r(2265),o=r(86757),i=r.n(o),a=r(1175),u=r(16630),c=r(82944),l=r(85355),s=r(78242),f=r(80285),p=r(25739),h=["x1","y1","x2","y2","key"],d=["offset"];function y(t){return(y="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function v(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,n)}return r}function m(t){for(var e=1;e=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}var x=function(t){var e=t.fill;if(!e||"none"===e)return null;var r=t.fillOpacity,o=t.x,i=t.y,a=t.width,u=t.height,c=t.ry;return n.createElement("rect",{x:o,y:i,ry:c,width:a,height:u,stroke:"none",fill:e,fillOpacity:r,className:"recharts-cartesian-grid-bg"})};function w(t,e){var r;if(n.isValidElement(t))r=n.cloneElement(t,e);else if(i()(t))r=t(e);else{var o=e.x1,a=e.y1,u=e.x2,l=e.y2,s=e.key,f=g(e,h),p=(0,c.L6)(f,!1),y=(p.offset,g(p,d));r=n.createElement("line",b({},y,{x1:o,y1:a,x2:u,y2:l,fill:"none",key:s}))}return r}function O(t){var e=t.x,r=t.width,o=t.horizontal,i=void 0===o||o,a=t.horizontalPoints;if(!i||!a||!a.length)return null;var u=a.map(function(n,o){return w(i,m(m({},t),{},{x1:e,y1:n,x2:e+r,y2:n,key:"line-".concat(o),index:o}))});return n.createElement("g",{className:"recharts-cartesian-grid-horizontal"},u)}function j(t){var e=t.y,r=t.height,o=t.vertical,i=void 0===o||o,a=t.verticalPoints;if(!i||!a||!a.length)return null;var u=a.map(function(n,o){return w(i,m(m({},t),{},{x1:n,y1:e,x2:n,y2:e+r,key:"line-".concat(o),index:o}))});return n.createElement("g",{className:"recharts-cartesian-grid-vertical"},u)}function S(t){var e=t.horizontalFill,r=t.fillOpacity,o=t.x,i=t.y,a=t.width,u=t.height,c=t.horizontalPoints,l=t.horizontal;if(!(void 0===l||l)||!e||!e.length)return null;var s=c.map(function(t){return Math.round(t+i-i)}).sort(function(t,e){return t-e});i!==s[0]&&s.unshift(0);var f=s.map(function(t,c){var l=s[c+1]?s[c+1]-t:i+u-t;if(l<=0)return null;var f=c%e.length;return n.createElement("rect",{key:"react-".concat(c),y:t,x:o,height:l,width:a,stroke:"none",fill:e[f],fillOpacity:r,className:"recharts-cartesian-grid-bg"})});return n.createElement("g",{className:"recharts-cartesian-gridstripes-horizontal"},f)}function P(t){var e=t.vertical,r=t.verticalFill,o=t.fillOpacity,i=t.x,a=t.y,u=t.width,c=t.height,l=t.verticalPoints;if(!(void 0===e||e)||!r||!r.length)return null;var s=l.map(function(t){return Math.round(t+i-i)}).sort(function(t,e){return t-e});i!==s[0]&&s.unshift(0);var f=s.map(function(t,e){var l=s[e+1]?s[e+1]-t:i+u-t;if(l<=0)return null;var f=e%r.length;return n.createElement("rect",{key:"react-".concat(e),x:t,y:a,width:l,height:c,stroke:"none",fill:r[f],fillOpacity:o,className:"recharts-cartesian-grid-bg"})});return n.createElement("g",{className:"recharts-cartesian-gridstripes-vertical"},f)}var E=function(t,e){var r=t.xAxis,n=t.width,o=t.height,i=t.offset;return(0,l.Rf)((0,s.f)(m(m(m({},f.O.defaultProps),r),{},{ticks:(0,l.uY)(r,!0),viewBox:{x:0,y:0,width:n,height:o}})),i.left,i.left+i.width,e)},k=function(t,e){var r=t.yAxis,n=t.width,o=t.height,i=t.offset;return(0,l.Rf)((0,s.f)(m(m(m({},f.O.defaultProps),r),{},{ticks:(0,l.uY)(r,!0),viewBox:{x:0,y:0,width:n,height:o}})),i.top,i.top+i.height,e)},A={horizontal:!0,vertical:!0,stroke:"#ccc",fill:"none",verticalFill:[],horizontalFill:[]};function M(t){var e,r,o,c,l,s,f=(0,p.zn)(),h=(0,p.Mw)(),d=(0,p.qD)(),v=m(m({},t),{},{stroke:null!==(e=t.stroke)&&void 0!==e?e:A.stroke,fill:null!==(r=t.fill)&&void 0!==r?r:A.fill,horizontal:null!==(o=t.horizontal)&&void 0!==o?o:A.horizontal,horizontalFill:null!==(c=t.horizontalFill)&&void 0!==c?c:A.horizontalFill,vertical:null!==(l=t.vertical)&&void 0!==l?l:A.vertical,verticalFill:null!==(s=t.verticalFill)&&void 0!==s?s:A.verticalFill,x:(0,u.hj)(t.x)?t.x:d.left,y:(0,u.hj)(t.y)?t.y:d.top,width:(0,u.hj)(t.width)?t.width:d.width,height:(0,u.hj)(t.height)?t.height:d.height}),g=v.x,w=v.y,M=v.width,_=v.height,T=v.syncWithTicks,C=v.horizontalValues,N=v.verticalValues,D=(0,p.CW)(),I=(0,p.Nf)();if(!(0,u.hj)(M)||M<=0||!(0,u.hj)(_)||_<=0||!(0,u.hj)(g)||g!==+g||!(0,u.hj)(w)||w!==+w)return null;var L=v.verticalCoordinatesGenerator||E,B=v.horizontalCoordinatesGenerator||k,R=v.horizontalPoints,z=v.verticalPoints;if((!R||!R.length)&&i()(B)){var U=C&&C.length,F=B({yAxis:I?m(m({},I),{},{ticks:U?C:I.ticks}):void 0,width:f,height:h,offset:d},!!U||T);(0,a.Z)(Array.isArray(F),"horizontalCoordinatesGenerator should return Array but instead it returned [".concat(y(F),"]")),Array.isArray(F)&&(R=F)}if((!z||!z.length)&&i()(L)){var $=N&&N.length,q=L({xAxis:D?m(m({},D),{},{ticks:$?N:D.ticks}):void 0,width:f,height:h,offset:d},!!$||T);(0,a.Z)(Array.isArray(q),"verticalCoordinatesGenerator should return Array but instead it returned [".concat(y(q),"]")),Array.isArray(q)&&(z=q)}return n.createElement("g",{className:"recharts-cartesian-grid"},n.createElement(x,{fill:v.fill,fillOpacity:v.fillOpacity,x:v.x,y:v.y,width:v.width,height:v.height,ry:v.ry}),n.createElement(O,b({},v,{offset:d,horizontalPoints:R,xAxis:D,yAxis:I})),n.createElement(j,b({},v,{offset:d,verticalPoints:z,xAxis:D,yAxis:I})),n.createElement(S,b({},v,{horizontalPoints:R})),n.createElement(P,b({},v,{verticalPoints:z})))}M.displayName="CartesianGrid"},13137:function(t,e,r){"use strict";r.d(e,{W:function(){return v}});var n=r(2265),o=r(69398),i=r(9841),a=r(82944),u=["offset","layout","width","dataKey","data","dataPointFormatter","xAxis","yAxis"];function c(t){return(c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function l(){return(l=Object.assign?Object.assign.bind():function(t){for(var e=1;et.length)&&(e=t.length);for(var r=0,n=Array(e);r=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(t,u),m=(0,a.L6)(v,!1);"x"===this.props.direction&&"number"!==d.type&&(0,o.Z)(!1);var b=p.map(function(t){var o,a,u=h(t,f),p=u.x,v=u.y,b=u.value,g=u.errorVal;if(!g)return null;var x=[];if(Array.isArray(g)){var w=function(t){if(Array.isArray(t))return t}(g)||function(t,e){var r=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=r){var n,o,i,a,u=[],c=!0,l=!1;try{for(i=(r=r.call(t)).next;!(c=(n=i.call(r)).done)&&(u.push(n.value),2!==u.length);c=!0);}catch(t){l=!0,o=t}finally{try{if(!c&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(l)throw o}}return u}}(g,2)||function(t,e){if(t){if("string"==typeof t)return s(t,2);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return s(t,2)}}(g,2)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}();o=w[0],a=w[1]}else o=a=g;if("vertical"===r){var O=d.scale,j=v+e,S=j+c,P=j-c,E=O(b-o),k=O(b+a);x.push({x1:k,y1:S,x2:k,y2:P}),x.push({x1:E,y1:j,x2:k,y2:j}),x.push({x1:E,y1:S,x2:E,y2:P})}else if("horizontal"===r){var A=y.scale,M=p+e,_=M-c,T=M+c,C=A(b-o),N=A(b+a);x.push({x1:_,y1:N,x2:T,y2:N}),x.push({x1:M,y1:C,x2:M,y2:N}),x.push({x1:_,y1:C,x2:T,y2:C})}return n.createElement(i.m,l({className:"recharts-errorBar",key:"bar-".concat(x.map(function(t){return"".concat(t.x1,"-").concat(t.x2,"-").concat(t.y1,"-").concat(t.y2)}))},m),x.map(function(t){return n.createElement("line",l({},t,{key:"line-".concat(t.x1,"-").concat(t.x2,"-").concat(t.y1,"-").concat(t.y2)}))}))});return n.createElement(i.m,{className:"recharts-errorBars"},b)}}],function(t,e){for(var r=0;rt*o)return!1;var i=r();return t*(e-t*i/2-n)>=0&&t*(e+t*i/2-o)<=0}function f(t){return(f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function p(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,n)}return r}function h(t){for(var e=1;e=2?(0,i.uY)(m[1].coordinate-m[0].coordinate):1,M=(n="width"===P,f=b.x,p=b.y,d=b.width,y=b.height,1===A?{start:n?f:p,end:n?f+d:p+y}:{start:n?f+d:p+y,end:n?f:p});return"equidistantPreserveStart"===w?function(t,e,r,n,o){for(var i,a=(n||[]).slice(),u=e.start,c=e.end,f=0,p=1,h=u;p<=a.length;)if(i=function(){var e,i=null==n?void 0:n[f];if(void 0===i)return{v:l(n,p)};var a=f,d=function(){return void 0===e&&(e=r(i,a)),e},y=i.coordinate,v=0===f||s(t,y,d,h,c);v||(f=0,h=u,p+=1),v&&(h=y+t*(d()/2+o),f+=p)}())return i.v;return[]}(A,M,k,m,g):("preserveStart"===w||"preserveStartEnd"===w?function(t,e,r,n,o,i){var a=(n||[]).slice(),u=a.length,c=e.start,l=e.end;if(i){var f=n[u-1],p=r(f,u-1),d=t*(f.coordinate+t*p/2-l);a[u-1]=f=h(h({},f),{},{tickCoord:d>0?f.coordinate-d*t:f.coordinate}),s(t,f.tickCoord,function(){return p},c,l)&&(l=f.tickCoord-t*(p/2+o),a[u-1]=h(h({},f),{},{isShow:!0}))}for(var y=i?u-1:u,v=function(e){var n,i=a[e],u=function(){return void 0===n&&(n=r(i,e)),n};if(0===e){var f=t*(i.coordinate-t*u()/2-c);a[e]=i=h(h({},i),{},{tickCoord:f<0?i.coordinate-f*t:i.coordinate})}else a[e]=i=h(h({},i),{},{tickCoord:i.coordinate});s(t,i.tickCoord,u,c,l)&&(c=i.tickCoord+t*(u()/2+o),a[e]=h(h({},i),{},{isShow:!0}))},m=0;m0?l.coordinate-p*t:l.coordinate})}else i[e]=l=h(h({},l),{},{tickCoord:l.coordinate});s(t,l.tickCoord,f,u,c)&&(c=l.tickCoord-t*(f()/2+o),i[e]=h(h({},l),{},{isShow:!0}))},f=a-1;f>=0;f--)l(f);return i}(A,M,k,m,g)).filter(function(t){return t.isShow})}},93765:function(t,e,r){"use strict";r.d(e,{z:function(){return eD}});var n,o,i=r(2265),a=r(77571),u=r.n(a),c=r(86757),l=r.n(c),s=r(99676),f=r.n(s),p=r(13735),h=r.n(p),d=r(34935),y=r.n(d),v=r(37065),m=r.n(v),b=r(61994),g=r(69398),x=r(48777),w=r(9841),O=r(8147),j=r(22190),S=r(81889),P=r(73649),E=r(82944),k=r(55284),A=r(58811),M=r(85355),_=r(16630);function T(t){return(T="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function C(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,n)}return r}function N(t){for(var e=1;e0&&e.handleDrag(t.changedTouches[0])}),W(e,"handleDragEnd",function(){e.setState({isTravellerMoving:!1,isSlideMoving:!1},function(){var t=e.props,r=t.endIndex,n=t.onDragEnd,o=t.startIndex;null==n||n({endIndex:r,startIndex:o})}),e.detachDragEndListener()}),W(e,"handleLeaveWrapper",function(){(e.state.isTravellerMoving||e.state.isSlideMoving)&&(e.leaveTimer=window.setTimeout(e.handleDragEnd,e.props.leaveTimeOut))}),W(e,"handleEnterSlideOrTraveller",function(){e.setState({isTextActive:!0})}),W(e,"handleLeaveSlideOrTraveller",function(){e.setState({isTextActive:!1})}),W(e,"handleSlideDragStart",function(t){var r=X(t)?t.changedTouches[0]:t;e.setState({isTravellerMoving:!1,isSlideMoving:!0,slideMoveStartX:r.pageX}),e.attachDragEndListener()}),e.travellerDragStartHandlers={startX:e.handleTravellerDragStart.bind(e,"startX"),endX:e.handleTravellerDragStart.bind(e,"endX")},e.state={},e}return!function(t,e){if("function"!=typeof e&&null!==e)throw TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&Z(t,e)}(n,t),e=[{key:"componentWillUnmount",value:function(){this.leaveTimer&&(clearTimeout(this.leaveTimer),this.leaveTimer=null),this.detachDragEndListener()}},{key:"getIndex",value:function(t){var e=t.startX,r=t.endX,o=this.state.scaleValues,i=this.props,a=i.gap,u=i.data.length-1,c=n.getIndexInRange(o,Math.min(e,r)),l=n.getIndexInRange(o,Math.max(e,r));return{startIndex:c-c%a,endIndex:l===u?u:l-l%a}}},{key:"getTextOfTick",value:function(t){var e=this.props,r=e.data,n=e.tickFormatter,o=e.dataKey,i=(0,M.F$)(r[t],o,t);return l()(n)?n(i,t):i}},{key:"attachDragEndListener",value:function(){window.addEventListener("mouseup",this.handleDragEnd,!0),window.addEventListener("touchend",this.handleDragEnd,!0),window.addEventListener("mousemove",this.handleDrag,!0)}},{key:"detachDragEndListener",value:function(){window.removeEventListener("mouseup",this.handleDragEnd,!0),window.removeEventListener("touchend",this.handleDragEnd,!0),window.removeEventListener("mousemove",this.handleDrag,!0)}},{key:"handleSlideDrag",value:function(t){var e=this.state,r=e.slideMoveStartX,n=e.startX,o=e.endX,i=this.props,a=i.x,u=i.width,c=i.travellerWidth,l=i.startIndex,s=i.endIndex,f=i.onChange,p=t.pageX-r;p>0?p=Math.min(p,a+u-c-o,a+u-c-n):p<0&&(p=Math.max(p,a-n,a-o));var h=this.getIndex({startX:n+p,endX:o+p});(h.startIndex!==l||h.endIndex!==s)&&f&&f(h),this.setState({startX:n+p,endX:o+p,slideMoveStartX:t.pageX})}},{key:"handleTravellerDragStart",value:function(t,e){var r=X(e)?e.changedTouches[0]:e;this.setState({isSlideMoving:!1,isTravellerMoving:!0,movingTravellerId:t,brushMoveStartX:r.pageX}),this.attachDragEndListener()}},{key:"handleTravellerMove",value:function(t){var e=this.state,r=e.brushMoveStartX,n=e.movingTravellerId,o=e.endX,i=e.startX,a=this.state[n],u=this.props,c=u.x,l=u.width,s=u.travellerWidth,f=u.onChange,p=u.gap,h=u.data,d={startX:this.state.startX,endX:this.state.endX},y=t.pageX-r;y>0?y=Math.min(y,c+l-s-a):y<0&&(y=Math.max(y,c-a)),d[n]=a+y;var v=this.getIndex(d),m=v.startIndex,b=v.endIndex,g=function(){var t=h.length-1;return"startX"===n&&(o>i?m%p==0:b%p==0)||oi?b%p==0:m%p==0)||o>i&&b===t};this.setState(W(W({},n,a+y),"brushMoveStartX",t.pageX),function(){f&&g()&&f(v)})}},{key:"handleTravellerMoveKeyboard",value:function(t,e){var r=this,n=this.state,o=n.scaleValues,i=n.startX,a=n.endX,u=this.state[e],c=o.indexOf(u);if(-1!==c){var l=c+t;if(-1!==l&&!(l>=o.length)){var s=o[l];"startX"===e&&s>=a||"endX"===e&&s<=i||this.setState(W({},e,s),function(){r.props.onChange(r.getIndex({startX:r.state.startX,endX:r.state.endX}))})}}}},{key:"renderBackground",value:function(){var t=this.props,e=t.x,r=t.y,n=t.width,o=t.height,a=t.fill,u=t.stroke;return i.createElement("rect",{stroke:u,fill:a,x:e,y:r,width:n,height:o})}},{key:"renderPanorama",value:function(){var t=this.props,e=t.x,r=t.y,n=t.width,o=t.height,a=t.data,u=t.children,c=t.padding,l=i.Children.only(u);return l?i.cloneElement(l,{x:e,y:r,width:n,height:o,margin:c,compact:!0,data:a}):null}},{key:"renderTravellerLayer",value:function(t,e){var r,o,a=this,u=this.props,c=u.y,l=u.travellerWidth,s=u.height,f=u.traveller,p=u.ariaLabel,h=u.data,d=u.startIndex,y=u.endIndex,v=Math.max(t,this.props.x),m=U(U({},(0,E.L6)(this.props,!1)),{},{x:v,y:c,width:l,height:s}),b=p||"Min value: ".concat(null===(r=h[d])||void 0===r?void 0:r.name,", Max value: ").concat(null===(o=h[y])||void 0===o?void 0:o.name);return i.createElement(w.m,{tabIndex:0,role:"slider","aria-label":b,"aria-valuenow":t,className:"recharts-brush-traveller",onMouseEnter:this.handleEnterSlideOrTraveller,onMouseLeave:this.handleLeaveSlideOrTraveller,onMouseDown:this.travellerDragStartHandlers[e],onTouchStart:this.travellerDragStartHandlers[e],onKeyDown:function(t){["ArrowLeft","ArrowRight"].includes(t.key)&&(t.preventDefault(),t.stopPropagation(),a.handleTravellerMoveKeyboard("ArrowRight"===t.key?1:-1,e))},onFocus:function(){a.setState({isTravellerFocused:!0})},onBlur:function(){a.setState({isTravellerFocused:!1})},style:{cursor:"col-resize"}},n.renderTraveller(f,m))}},{key:"renderSlide",value:function(t,e){var r=this.props,n=r.y,o=r.height,a=r.stroke,u=r.travellerWidth;return i.createElement("rect",{className:"recharts-brush-slide",onMouseEnter:this.handleEnterSlideOrTraveller,onMouseLeave:this.handleLeaveSlideOrTraveller,onMouseDown:this.handleSlideDragStart,onTouchStart:this.handleSlideDragStart,style:{cursor:"move"},stroke:"none",fill:a,fillOpacity:.2,x:Math.min(t,e)+u,y:n,width:Math.max(Math.abs(e-t)-u,0),height:o})}},{key:"renderText",value:function(){var t=this.props,e=t.startIndex,r=t.endIndex,n=t.y,o=t.height,a=t.travellerWidth,u=t.stroke,c=this.state,l=c.startX,s=c.endX,f={pointerEvents:"none",fill:u};return i.createElement(w.m,{className:"recharts-brush-texts"},i.createElement(A.x,R({textAnchor:"end",verticalAnchor:"middle",x:Math.min(l,s)-5,y:n+o/2},f),this.getTextOfTick(e)),i.createElement(A.x,R({textAnchor:"start",verticalAnchor:"middle",x:Math.max(l,s)+a+5,y:n+o/2},f),this.getTextOfTick(r)))}},{key:"render",value:function(){var t=this.props,e=t.data,r=t.className,n=t.children,o=t.x,a=t.y,u=t.width,c=t.height,l=t.alwaysShowText,s=this.state,f=s.startX,p=s.endX,h=s.isTextActive,d=s.isSlideMoving,y=s.isTravellerMoving,v=s.isTravellerFocused;if(!e||!e.length||!(0,_.hj)(o)||!(0,_.hj)(a)||!(0,_.hj)(u)||!(0,_.hj)(c)||u<=0||c<=0)return null;var m=(0,b.Z)("recharts-brush",r),g=1===i.Children.count(n),x=L("userSelect","none");return i.createElement(w.m,{className:m,onMouseLeave:this.handleLeaveWrapper,onTouchMove:this.handleTouchMove,style:x},this.renderBackground(),g&&this.renderPanorama(),this.renderSlide(f,p),this.renderTravellerLayer(f,"startX"),this.renderTravellerLayer(p,"endX"),(h||d||y||v||l)&&this.renderText())}}],r=[{key:"renderDefaultTraveller",value:function(t){var e=t.x,r=t.y,n=t.width,o=t.height,a=t.stroke,u=Math.floor(r+o/2)-1;return i.createElement(i.Fragment,null,i.createElement("rect",{x:e,y:r,width:n,height:o,fill:a,stroke:"none"}),i.createElement("line",{x1:e+1,y1:u,x2:e+n-1,y2:u,fill:"none",stroke:"#fff"}),i.createElement("line",{x1:e+1,y1:u+2,x2:e+n-1,y2:u+2,fill:"none",stroke:"#fff"}))}},{key:"renderTraveller",value:function(t,e){return i.isValidElement(t)?i.cloneElement(t,e):l()(t)?t(e):n.renderDefaultTraveller(e)}},{key:"getDerivedStateFromProps",value:function(t,e){var r=t.data,n=t.width,o=t.x,i=t.travellerWidth,a=t.updateId,u=t.startIndex,c=t.endIndex;if(r!==e.prevData||a!==e.prevUpdateId)return U({prevData:r,prevTravellerWidth:i,prevUpdateId:a,prevX:o,prevWidth:n},r&&r.length?H({data:r,width:n,x:o,travellerWidth:i,startIndex:u,endIndex:c}):{scale:null,scaleValues:null});if(e.scale&&(n!==e.prevWidth||o!==e.prevX||i!==e.prevTravellerWidth)){e.scale.range([o,o+n-i]);var l=e.scale.domain().map(function(t){return e.scale(t)});return{prevData:r,prevTravellerWidth:i,prevUpdateId:a,prevX:o,prevWidth:n,startX:e.scale(t.startIndex),endX:e.scale(t.endIndex),scaleValues:l}}return null}},{key:"getIndexInRange",value:function(t,e){for(var r=t.length,n=0,o=r-1;o-n>1;){var i=Math.floor((n+o)/2);t[i]>e?o=i:n=i}return e>=t[o]?o:n}}],e&&F(n.prototype,e),r&&F(n,r),Object.defineProperty(n,"prototype",{writable:!1}),n}(i.PureComponent);W(G,"displayName","Brush"),W(G,"defaultProps",{height:40,travellerWidth:5,gap:1,fill:"#fff",stroke:"#666",padding:{top:1,right:1,bottom:1,left:1},leaveTimeOut:1e3,alwaysShowText:!1});var V=r(4094),K=r(38569),Q=r(26680),J=function(t,e){var r=t.alwaysShow,n=t.ifOverflow;return r&&(n="extendDomain"),n===e},tt=r(25311),te=r(1175);function tr(){return(tr=Object.assign?Object.assign.bind():function(t){for(var e=1;et.length)&&(e=t.length);for(var r=0,n=Array(e);rt.length)&&(e=t.length);for(var r=0,n=Array(e);r=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(t,t2));return(0,_.hj)(r)&&(0,_.hj)(o)&&(0,_.hj)(f)&&(0,_.hj)(h)&&(0,_.hj)(u)&&(0,_.hj)(l)?i.createElement("path",t5({},(0,E.L6)(y,!0),{className:(0,b.Z)("recharts-cross",d),d:"M".concat(r,",").concat(u,"v").concat(h,"M").concat(l,",").concat(o,"h").concat(f)})):null};function t7(t){var e=t.cx,r=t.cy,n=t.radius,o=t.startAngle,i=t.endAngle;return{points:[(0,tq.op)(e,r,n,o),(0,tq.op)(e,r,n,i)],cx:e,cy:r,radius:n,startAngle:o,endAngle:i}}var t4=r(60474);function t8(t){return(t8="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function t9(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,n)}return r}function et(t){for(var e=1;e=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}function ec(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(t){}return(ec=function(){return!!t})()}function el(t){return(el=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function es(t,e){return(es=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t})(t,e)}function ef(t){return function(t){if(Array.isArray(t))return eh(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||ep(t)||function(){throw TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function ep(t,e){if(t){if("string"==typeof t)return eh(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return eh(t,e)}}function eh(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);r0?i:t&&t.length&&(0,_.hj)(n)&&(0,_.hj)(o)?t.slice(n,o+1):[]};function eS(t){return"number"===t?[0,"auto"]:void 0}var eP=function(t,e,r,n){var o=t.graphicalItems,i=t.tooltipAxis,a=ej(e,t);return r<0||!o||!o.length||r>=a.length?null:o.reduce(function(o,u){var c,l,s=null!==(c=u.props.data)&&void 0!==c?c:e;if(s&&t.dataStartIndex+t.dataEndIndex!==0&&t.dataEndIndex-t.dataStartIndex>=r&&(s=s.slice(t.dataStartIndex,t.dataEndIndex+1)),i.dataKey&&!i.allowDuplicatedCategory){var f=void 0===s?a:s;l=(0,_.Ap)(f,i.dataKey,n)}else l=s&&s[r]||a[r];return l?[].concat(ef(o),[(0,M.Qo)(u,l)]):o},[])},eE=function(t,e,r,n){var o=n||{x:t.chartX,y:t.chartY},i="horizontal"===r?o.x:"vertical"===r?o.y:"centric"===r?o.angle:o.radius,a=t.orderedTooltipTicks,u=t.tooltipAxis,c=t.tooltipTicks,l=(0,M.VO)(i,a,c,u);if(l>=0&&c){var s=c[l]&&c[l].value,f=eP(t,e,l,s),p=eO(r,a,l,o);return{activeTooltipIndex:l,activeLabel:s,activePayload:f,activeCoordinate:p}}return null},ek=function(t,e){var r=e.axes,n=e.graphicalItems,o=e.axisType,i=e.axisIdKey,a=e.stackGroups,c=e.dataStartIndex,l=e.dataEndIndex,s=t.layout,p=t.children,h=t.stackOffset,d=(0,M.NA)(s,o);return r.reduce(function(e,r){var y=void 0!==r.type.defaultProps?ey(ey({},r.type.defaultProps),r.props):r.props,v=y.type,m=y.dataKey,b=y.allowDataOverflow,g=y.allowDuplicatedCategory,x=y.scale,w=y.ticks,O=y.includeHidden,j=y[i];if(e[j])return e;var S=ej(t.data,{graphicalItems:n.filter(function(t){var e;return(i in t.props?t.props[i]:null===(e=t.type.defaultProps)||void 0===e?void 0:e[i])===j}),dataStartIndex:c,dataEndIndex:l}),P=S.length;(function(t,e,r){if("number"===r&&!0===e&&Array.isArray(t)){var n=null==t?void 0:t[0],o=null==t?void 0:t[1];if(n&&o&&(0,_.hj)(n)&&(0,_.hj)(o))return!0}return!1})(y.domain,b,v)&&(A=(0,M.LG)(y.domain,null,b),d&&("number"===v||"auto"!==x)&&(C=(0,M.gF)(S,m,"category")));var E=eS(v);if(!A||0===A.length){var k,A,T,C,N,D=null!==(N=y.domain)&&void 0!==N?N:E;if(m){if(A=(0,M.gF)(S,m,v),"category"===v&&d){var I=(0,_.bv)(A);g&&I?(T=A,A=f()(0,P)):g||(A=(0,M.ko)(D,A,r).reduce(function(t,e){return t.indexOf(e)>=0?t:[].concat(ef(t),[e])},[]))}else if("category"===v)A=g?A.filter(function(t){return""!==t&&!u()(t)}):(0,M.ko)(D,A,r).reduce(function(t,e){return t.indexOf(e)>=0||""===e||u()(e)?t:[].concat(ef(t),[e])},[]);else if("number"===v){var L=(0,M.ZI)(S,n.filter(function(t){var e,r,n=i in t.props?t.props[i]:null===(e=t.type.defaultProps)||void 0===e?void 0:e[i],o="hide"in t.props?t.props.hide:null===(r=t.type.defaultProps)||void 0===r?void 0:r.hide;return n===j&&(O||!o)}),m,o,s);L&&(A=L)}d&&("number"===v||"auto"!==x)&&(C=(0,M.gF)(S,m,"category"))}else A=d?f()(0,P):a&&a[j]&&a[j].hasStack&&"number"===v?"expand"===h?[0,1]:(0,M.EB)(a[j].stackGroups,c,l):(0,M.s6)(S,n.filter(function(t){var e=i in t.props?t.props[i]:t.type.defaultProps[i],r="hide"in t.props?t.props.hide:t.type.defaultProps.hide;return e===j&&(O||!r)}),v,s,!0);"number"===v?(A=t$(p,A,j,o,w),D&&(A=(0,M.LG)(D,A,b))):"category"===v&&D&&A.every(function(t){return D.indexOf(t)>=0})&&(A=D)}return ey(ey({},e),{},ev({},j,ey(ey({},y),{},{axisType:o,domain:A,categoricalDomain:C,duplicateDomain:T,originalDomain:null!==(k=y.domain)&&void 0!==k?k:E,isCategorical:d,layout:s})))},{})},eA=function(t,e){var r=e.graphicalItems,n=e.Axis,o=e.axisType,i=e.axisIdKey,a=e.stackGroups,u=e.dataStartIndex,c=e.dataEndIndex,l=t.layout,s=t.children,p=ej(t.data,{graphicalItems:r,dataStartIndex:u,dataEndIndex:c}),d=p.length,y=(0,M.NA)(l,o),v=-1;return r.reduce(function(t,e){var m,b=(void 0!==e.type.defaultProps?ey(ey({},e.type.defaultProps),e.props):e.props)[i],g=eS("number");return t[b]?t:(v++,m=y?f()(0,d):a&&a[b]&&a[b].hasStack?t$(s,m=(0,M.EB)(a[b].stackGroups,u,c),b,o):t$(s,m=(0,M.LG)(g,(0,M.s6)(p,r.filter(function(t){var e,r,n=i in t.props?t.props[i]:null===(e=t.type.defaultProps)||void 0===e?void 0:e[i],o="hide"in t.props?t.props.hide:null===(r=t.type.defaultProps)||void 0===r?void 0:r.hide;return n===b&&!o}),"number",l),n.defaultProps.allowDataOverflow),b,o),ey(ey({},t),{},ev({},b,ey(ey({axisType:o},n.defaultProps),{},{hide:!0,orientation:h()(eb,"".concat(o,".").concat(v%2),null),domain:m,originalDomain:g,isCategorical:y,layout:l}))))},{})},eM=function(t,e){var r=e.axisType,n=void 0===r?"xAxis":r,o=e.AxisComp,i=e.graphicalItems,a=e.stackGroups,u=e.dataStartIndex,c=e.dataEndIndex,l=t.children,s="".concat(n,"Id"),f=(0,E.NN)(l,o),p={};return f&&f.length?p=ek(t,{axes:f,graphicalItems:i,axisType:n,axisIdKey:s,stackGroups:a,dataStartIndex:u,dataEndIndex:c}):i&&i.length&&(p=eA(t,{Axis:o,graphicalItems:i,axisType:n,axisIdKey:s,stackGroups:a,dataStartIndex:u,dataEndIndex:c})),p},e_=function(t){var e=(0,_.Kt)(t),r=(0,M.uY)(e,!1,!0);return{tooltipTicks:r,orderedTooltipTicks:y()(r,function(t){return t.coordinate}),tooltipAxis:e,tooltipAxisBandSize:(0,M.zT)(e,r)}},eT=function(t){var e=t.children,r=t.defaultShowTooltip,n=(0,E.sP)(e,G),o=0,i=0;return t.data&&0!==t.data.length&&(i=t.data.length-1),n&&n.props&&(n.props.startIndex>=0&&(o=n.props.startIndex),n.props.endIndex>=0&&(i=n.props.endIndex)),{chartX:0,chartY:0,dataStartIndex:o,dataEndIndex:i,activeTooltipIndex:-1,isTooltipActive:!!r}},eC=function(t){return"horizontal"===t?{numericAxisName:"yAxis",cateAxisName:"xAxis"}:"vertical"===t?{numericAxisName:"xAxis",cateAxisName:"yAxis"}:"centric"===t?{numericAxisName:"radiusAxis",cateAxisName:"angleAxis"}:{numericAxisName:"angleAxis",cateAxisName:"radiusAxis"}},eN=function(t,e){var r=t.props,n=t.graphicalItems,o=t.xAxisMap,i=void 0===o?{}:o,a=t.yAxisMap,u=void 0===a?{}:a,c=r.width,l=r.height,s=r.children,f=r.margin||{},p=(0,E.sP)(s,G),d=(0,E.sP)(s,j.D),y=Object.keys(u).reduce(function(t,e){var r=u[e],n=r.orientation;return r.mirror||r.hide?t:ey(ey({},t),{},ev({},n,t[n]+r.width))},{left:f.left||0,right:f.right||0}),v=Object.keys(i).reduce(function(t,e){var r=i[e],n=r.orientation;return r.mirror||r.hide?t:ey(ey({},t),{},ev({},n,h()(t,"".concat(n))+r.height))},{top:f.top||0,bottom:f.bottom||0}),m=ey(ey({},v),y),b=m.bottom;p&&(m.bottom+=p.props.height||G.defaultProps.height),d&&e&&(m=(0,M.By)(m,n,r,e));var g=c-m.left-m.right,x=l-m.top-m.bottom;return ey(ey({brushBottom:b},m),{},{width:Math.max(g,0),height:Math.max(x,0)})},eD=function(t){var e=t.chartName,r=t.GraphicalChild,n=t.defaultTooltipEventType,o=void 0===n?"axis":n,a=t.validateTooltipEventTypes,c=void 0===a?["axis"]:a,s=t.axisComponents,f=t.legendContent,p=t.formatAxisMap,d=t.defaultProps,y=function(t,e){var r=e.graphicalItems,n=e.stackGroups,o=e.offset,i=e.updateId,a=e.dataStartIndex,c=e.dataEndIndex,l=t.barSize,f=t.layout,p=t.barGap,h=t.barCategoryGap,d=t.maxBarSize,y=eC(f),v=y.numericAxisName,m=y.cateAxisName,b=!!r&&!!r.length&&r.some(function(t){var e=(0,E.Gf)(t&&t.type);return e&&e.indexOf("Bar")>=0}),x=[];return r.forEach(function(r,y){var w=ej(t.data,{graphicalItems:[r],dataStartIndex:a,dataEndIndex:c}),O=void 0!==r.type.defaultProps?ey(ey({},r.type.defaultProps),r.props):r.props,j=O.dataKey,S=O.maxBarSize,P=O["".concat(v,"Id")],k=O["".concat(m,"Id")],A=s.reduce(function(t,r){var n=e["".concat(r.axisType,"Map")],o=O["".concat(r.axisType,"Id")];n&&n[o]||"zAxis"===r.axisType||(0,g.Z)(!1);var i=n[o];return ey(ey({},t),{},ev(ev({},r.axisType,i),"".concat(r.axisType,"Ticks"),(0,M.uY)(i)))},{}),_=A[m],T=A["".concat(m,"Ticks")],C=n&&n[P]&&n[P].hasStack&&(0,M.O3)(r,n[P].stackGroups),N=(0,E.Gf)(r.type).indexOf("Bar")>=0,D=(0,M.zT)(_,T),I=[],L=b&&(0,M.pt)({barSize:l,stackGroups:n,totalSize:"xAxis"===m?A[m].width:"yAxis"===m?A[m].height:void 0});if(N){var B,R,z=u()(S)?d:S,U=null!==(B=null!==(R=(0,M.zT)(_,T,!0))&&void 0!==R?R:z)&&void 0!==B?B:0;I=(0,M.qz)({barGap:p,barCategoryGap:h,bandSize:U!==D?U:D,sizeList:L[k],maxBarSize:z}),U!==D&&(I=I.map(function(t){return ey(ey({},t),{},{position:ey(ey({},t.position),{},{offset:t.position.offset-U/2})})}))}var F=r&&r.type&&r.type.getComposedData;F&&x.push({props:ey(ey({},F(ey(ey({},A),{},{displayedData:w,props:t,dataKey:j,item:r,bandSize:D,barPosition:I,offset:o,stackedData:C,layout:f,dataStartIndex:a,dataEndIndex:c}))),{},ev(ev(ev({key:r.key||"item-".concat(y)},v,A[v]),m,A[m]),"animationId",i)),childIndex:(0,E.$R)(r,t.children),item:r})}),x},v=function(t,n){var o=t.props,i=t.dataStartIndex,a=t.dataEndIndex,u=t.updateId;if(!(0,E.TT)({props:o}))return null;var c=o.children,l=o.layout,f=o.stackOffset,h=o.data,d=o.reverseStackOrder,v=eC(l),m=v.numericAxisName,b=v.cateAxisName,g=(0,E.NN)(c,r),x=(0,M.wh)(h,g,"".concat(m,"Id"),"".concat(b,"Id"),f,d),w=s.reduce(function(t,e){var r="".concat(e.axisType,"Map");return ey(ey({},t),{},ev({},r,eM(o,ey(ey({},e),{},{graphicalItems:g,stackGroups:e.axisType===m&&x,dataStartIndex:i,dataEndIndex:a}))))},{}),O=eN(ey(ey({},w),{},{props:o,graphicalItems:g}),null==n?void 0:n.legendBBox);Object.keys(w).forEach(function(t){w[t]=p(o,w[t],O,t.replace("Map",""),e)});var j=e_(w["".concat(b,"Map")]),S=y(o,ey(ey({},w),{},{dataStartIndex:i,dataEndIndex:a,updateId:u,graphicalItems:g,stackGroups:x,offset:O}));return ey(ey({formattedGraphicalItems:S,graphicalItems:g,offset:O,stackGroups:x},j),w)},j=function(t){var r;function n(t){var r,o,a,c,s;return!function(t,e){if(!(t instanceof e))throw TypeError("Cannot call a class as a function")}(this,n),c=n,s=[t],c=el(c),ev(a=function(t,e){if(e&&("object"===eo(e)||"function"==typeof e))return e;if(void 0!==e)throw TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}(this,ec()?Reflect.construct(c,s||[],el(this).constructor):c.apply(this,s)),"eventEmitterSymbol",Symbol("rechartsEventEmitter")),ev(a,"accessibilityManager",new tQ),ev(a,"handleLegendBBoxUpdate",function(t){if(t){var e=a.state,r=e.dataStartIndex,n=e.dataEndIndex,o=e.updateId;a.setState(ey({legendBBox:t},v({props:a.props,dataStartIndex:r,dataEndIndex:n,updateId:o},ey(ey({},a.state),{},{legendBBox:t}))))}}),ev(a,"handleReceiveSyncEvent",function(t,e,r){a.props.syncId===t&&(r!==a.eventEmitterSymbol||"function"==typeof a.props.syncMethod)&&a.applySyncEvent(e)}),ev(a,"handleBrushChange",function(t){var e=t.startIndex,r=t.endIndex;if(e!==a.state.dataStartIndex||r!==a.state.dataEndIndex){var n=a.state.updateId;a.setState(function(){return ey({dataStartIndex:e,dataEndIndex:r},v({props:a.props,dataStartIndex:e,dataEndIndex:r,updateId:n},a.state))}),a.triggerSyncEvent({dataStartIndex:e,dataEndIndex:r})}}),ev(a,"handleMouseEnter",function(t){var e=a.getMouseInfo(t);if(e){var r=ey(ey({},e),{},{isTooltipActive:!0});a.setState(r),a.triggerSyncEvent(r);var n=a.props.onMouseEnter;l()(n)&&n(r,t)}}),ev(a,"triggeredAfterMouseMove",function(t){var e=a.getMouseInfo(t),r=e?ey(ey({},e),{},{isTooltipActive:!0}):{isTooltipActive:!1};a.setState(r),a.triggerSyncEvent(r);var n=a.props.onMouseMove;l()(n)&&n(r,t)}),ev(a,"handleItemMouseEnter",function(t){a.setState(function(){return{isTooltipActive:!0,activeItem:t,activePayload:t.tooltipPayload,activeCoordinate:t.tooltipPosition||{x:t.cx,y:t.cy}}})}),ev(a,"handleItemMouseLeave",function(){a.setState(function(){return{isTooltipActive:!1}})}),ev(a,"handleMouseMove",function(t){t.persist(),a.throttleTriggeredAfterMouseMove(t)}),ev(a,"handleMouseLeave",function(t){a.throttleTriggeredAfterMouseMove.cancel();var e={isTooltipActive:!1};a.setState(e),a.triggerSyncEvent(e);var r=a.props.onMouseLeave;l()(r)&&r(e,t)}),ev(a,"handleOuterEvent",function(t){var e,r=(0,E.Bh)(t),n=h()(a.props,"".concat(r));r&&l()(n)&&n(null!==(e=/.*touch.*/i.test(r)?a.getMouseInfo(t.changedTouches[0]):a.getMouseInfo(t))&&void 0!==e?e:{},t)}),ev(a,"handleClick",function(t){var e=a.getMouseInfo(t);if(e){var r=ey(ey({},e),{},{isTooltipActive:!0});a.setState(r),a.triggerSyncEvent(r);var n=a.props.onClick;l()(n)&&n(r,t)}}),ev(a,"handleMouseDown",function(t){var e=a.props.onMouseDown;l()(e)&&e(a.getMouseInfo(t),t)}),ev(a,"handleMouseUp",function(t){var e=a.props.onMouseUp;l()(e)&&e(a.getMouseInfo(t),t)}),ev(a,"handleTouchMove",function(t){null!=t.changedTouches&&t.changedTouches.length>0&&a.throttleTriggeredAfterMouseMove(t.changedTouches[0])}),ev(a,"handleTouchStart",function(t){null!=t.changedTouches&&t.changedTouches.length>0&&a.handleMouseDown(t.changedTouches[0])}),ev(a,"handleTouchEnd",function(t){null!=t.changedTouches&&t.changedTouches.length>0&&a.handleMouseUp(t.changedTouches[0])}),ev(a,"handleDoubleClick",function(t){var e=a.props.onDoubleClick;l()(e)&&e(a.getMouseInfo(t),t)}),ev(a,"handleContextMenu",function(t){var e=a.props.onContextMenu;l()(e)&&e(a.getMouseInfo(t),t)}),ev(a,"triggerSyncEvent",function(t){void 0!==a.props.syncId&&tY.emit(tH,a.props.syncId,t,a.eventEmitterSymbol)}),ev(a,"applySyncEvent",function(t){var e=a.props,r=e.layout,n=e.syncMethod,o=a.state.updateId,i=t.dataStartIndex,u=t.dataEndIndex;if(void 0!==t.dataStartIndex||void 0!==t.dataEndIndex)a.setState(ey({dataStartIndex:i,dataEndIndex:u},v({props:a.props,dataStartIndex:i,dataEndIndex:u,updateId:o},a.state)));else if(void 0!==t.activeTooltipIndex){var c=t.chartX,l=t.chartY,s=t.activeTooltipIndex,f=a.state,p=f.offset,h=f.tooltipTicks;if(!p)return;if("function"==typeof n)s=n(h,t);else if("value"===n){s=-1;for(var d=0;d=0){if(s.dataKey&&!s.allowDuplicatedCategory){var A="function"==typeof s.dataKey?function(t){return"function"==typeof s.dataKey?s.dataKey(t.payload):null}:"payload.".concat(s.dataKey.toString());C=(0,_.Ap)(v,A,p),N=m&&b&&(0,_.Ap)(b,A,p)}else C=null==v?void 0:v[f],N=m&&b&&b[f];if(S||j){var T=void 0!==t.props.activeIndex?t.props.activeIndex:f;return[(0,i.cloneElement)(t,ey(ey(ey({},n.props),P),{},{activeIndex:T})),null,null]}if(!u()(C))return[k].concat(ef(a.renderActivePoints({item:n,activePoint:C,basePoint:N,childIndex:f,isRange:m})))}else{var C,N,D,I=(null!==(D=a.getItemByXY(a.state.activeCoordinate))&&void 0!==D?D:{graphicalItem:k}).graphicalItem,L=I.item,B=void 0===L?t:L,R=I.childIndex,z=ey(ey(ey({},n.props),P),{},{activeIndex:R});return[(0,i.cloneElement)(B,z),null,null]}}return m?[k,null,null]:[k,null]}),ev(a,"renderCustomized",function(t,e,r){return(0,i.cloneElement)(t,ey(ey({key:"recharts-customized-".concat(r)},a.props),a.state))}),ev(a,"renderMap",{CartesianGrid:{handler:ew,once:!0},ReferenceArea:{handler:a.renderReferenceElement},ReferenceLine:{handler:ew},ReferenceDot:{handler:a.renderReferenceElement},XAxis:{handler:ew},YAxis:{handler:ew},Brush:{handler:a.renderBrush,once:!0},Bar:{handler:a.renderGraphicChild},Line:{handler:a.renderGraphicChild},Area:{handler:a.renderGraphicChild},Radar:{handler:a.renderGraphicChild},RadialBar:{handler:a.renderGraphicChild},Scatter:{handler:a.renderGraphicChild},Pie:{handler:a.renderGraphicChild},Funnel:{handler:a.renderGraphicChild},Tooltip:{handler:a.renderCursor,once:!0},PolarGrid:{handler:a.renderPolarGrid,once:!0},PolarAngleAxis:{handler:a.renderPolarAxis},PolarRadiusAxis:{handler:a.renderPolarAxis},Customized:{handler:a.renderCustomized}}),a.clipPathId="".concat(null!==(r=t.id)&&void 0!==r?r:(0,_.EL)("recharts"),"-clip"),a.throttleTriggeredAfterMouseMove=m()(a.triggeredAfterMouseMove,null!==(o=t.throttleDelay)&&void 0!==o?o:1e3/60),a.state={},a}return!function(t,e){if("function"!=typeof e&&null!==e)throw TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&es(t,e)}(n,t),r=[{key:"componentDidMount",value:function(){var t,e;this.addListener(),this.accessibilityManager.setDetails({container:this.container,offset:{left:null!==(t=this.props.margin.left)&&void 0!==t?t:0,top:null!==(e=this.props.margin.top)&&void 0!==e?e:0},coordinateList:this.state.tooltipTicks,mouseHandlerCallback:this.triggeredAfterMouseMove,layout:this.props.layout}),this.displayDefaultTooltip()}},{key:"displayDefaultTooltip",value:function(){var t=this.props,e=t.children,r=t.data,n=t.height,o=t.layout,i=(0,E.sP)(e,O.u);if(i){var a=i.props.defaultIndex;if("number"==typeof a&&!(a<0)&&!(a>this.state.tooltipTicks.length-1)){var u=this.state.tooltipTicks[a]&&this.state.tooltipTicks[a].value,c=eP(this.state,r,a,u),l=this.state.tooltipTicks[a].coordinate,s=(this.state.offset.top+n)/2,f="horizontal"===o?{x:l,y:s}:{y:l,x:s},p=this.state.formattedGraphicalItems.find(function(t){return"Scatter"===t.item.type.name});p&&(f=ey(ey({},f),p.props.points[a].tooltipPosition),c=p.props.points[a].tooltipPayload);var h={activeTooltipIndex:a,isTooltipActive:!0,activeLabel:u,activePayload:c,activeCoordinate:f};this.setState(h),this.renderCursor(i),this.accessibilityManager.setIndex(a)}}}},{key:"getSnapshotBeforeUpdate",value:function(t,e){if(!this.props.accessibilityLayer)return null;if(this.state.tooltipTicks!==e.tooltipTicks&&this.accessibilityManager.setDetails({coordinateList:this.state.tooltipTicks}),this.props.layout!==t.layout&&this.accessibilityManager.setDetails({layout:this.props.layout}),this.props.margin!==t.margin){var r,n;this.accessibilityManager.setDetails({offset:{left:null!==(r=this.props.margin.left)&&void 0!==r?r:0,top:null!==(n=this.props.margin.top)&&void 0!==n?n:0}})}return null}},{key:"componentDidUpdate",value:function(t){(0,E.rL)([(0,E.sP)(t.children,O.u)],[(0,E.sP)(this.props.children,O.u)])||this.displayDefaultTooltip()}},{key:"componentWillUnmount",value:function(){this.removeListener(),this.throttleTriggeredAfterMouseMove.cancel()}},{key:"getTooltipEventType",value:function(){var t=(0,E.sP)(this.props.children,O.u);if(t&&"boolean"==typeof t.props.shared){var e=t.props.shared?"axis":"item";return c.indexOf(e)>=0?e:o}return o}},{key:"getMouseInfo",value:function(t){if(!this.container)return null;var e=this.container,r=e.getBoundingClientRect(),n=(0,V.os)(r),o={chartX:Math.round(t.pageX-n.left),chartY:Math.round(t.pageY-n.top)},i=r.width/e.offsetWidth||1,a=this.inRange(o.chartX,o.chartY,i);if(!a)return null;var u=this.state,c=u.xAxisMap,l=u.yAxisMap,s=this.getTooltipEventType(),f=eE(this.state,this.props.data,this.props.layout,a);if("axis"!==s&&c&&l){var p=(0,_.Kt)(c).scale,h=(0,_.Kt)(l).scale,d=p&&p.invert?p.invert(o.chartX):null,y=h&&h.invert?h.invert(o.chartY):null;return ey(ey({},o),{},{xValue:d,yValue:y},f)}return f?ey(ey({},o),f):null}},{key:"inRange",value:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1,n=this.props.layout,o=t/r,i=e/r;if("horizontal"===n||"vertical"===n){var a=this.state.offset;return o>=a.left&&o<=a.left+a.width&&i>=a.top&&i<=a.top+a.height?{x:o,y:i}:null}var u=this.state,c=u.angleAxisMap,l=u.radiusAxisMap;if(c&&l){var s=(0,_.Kt)(c);return(0,tq.z3)({x:o,y:i},s)}return null}},{key:"parseEventsOfWrapper",value:function(){var t=this.props.children,e=this.getTooltipEventType(),r=(0,E.sP)(t,O.u),n={};return r&&"axis"===e&&(n="click"===r.props.trigger?{onClick:this.handleClick}:{onMouseEnter:this.handleMouseEnter,onDoubleClick:this.handleDoubleClick,onMouseMove:this.handleMouseMove,onMouseLeave:this.handleMouseLeave,onTouchMove:this.handleTouchMove,onTouchStart:this.handleTouchStart,onTouchEnd:this.handleTouchEnd,onContextMenu:this.handleContextMenu}),ey(ey({},(0,tX.Ym)(this.props,this.handleOuterEvent)),n)}},{key:"addListener",value:function(){tY.on(tH,this.handleReceiveSyncEvent)}},{key:"removeListener",value:function(){tY.removeListener(tH,this.handleReceiveSyncEvent)}},{key:"filterFormatItem",value:function(t,e,r){for(var n=this.state.formattedGraphicalItems,o=0,i=n.length;ot.length)&&(e=t.length);for(var r=0,n=Array(e);r=0?1:-1;"insideStart"===u?(o=b+S*l,a=w):"insideEnd"===u?(o=g-S*l,a=!w):"end"===u&&(o=g+S*l,a=w),a=j<=0?a:!a;var P=(0,d.op)(p,y,O,o),E=(0,d.op)(p,y,O,o+(a?1:-1)*359),k="M".concat(P.x,",").concat(P.y,"\n A").concat(O,",").concat(O,",0,1,").concat(a?0:1,",\n ").concat(E.x,",").concat(E.y),A=i()(t.id)?(0,h.EL)("recharts-radial-line-"):t.id;return n.createElement("text",x({},r,{dominantBaseline:"central",className:(0,s.Z)("recharts-radial-bar-label",f)}),n.createElement("defs",null,n.createElement("path",{id:A,d:k})),n.createElement("textPath",{xlinkHref:"#".concat(A)},e))},j=function(t){var e=t.viewBox,r=t.offset,n=t.position,o=e.cx,i=e.cy,a=e.innerRadius,u=e.outerRadius,c=(e.startAngle+e.endAngle)/2;if("outside"===n){var l=(0,d.op)(o,i,u+r,c),s=l.x;return{x:s,y:l.y,textAnchor:s>=o?"start":"end",verticalAnchor:"middle"}}if("center"===n)return{x:o,y:i,textAnchor:"middle",verticalAnchor:"middle"};if("centerTop"===n)return{x:o,y:i,textAnchor:"middle",verticalAnchor:"start"};if("centerBottom"===n)return{x:o,y:i,textAnchor:"middle",verticalAnchor:"end"};var f=(0,d.op)(o,i,(a+u)/2,c);return{x:f.x,y:f.y,textAnchor:"middle",verticalAnchor:"middle"}},S=function(t){var e=t.viewBox,r=t.parentViewBox,n=t.offset,o=t.position,i=e.x,a=e.y,u=e.width,c=e.height,s=c>=0?1:-1,f=s*n,p=s>0?"end":"start",d=s>0?"start":"end",y=u>=0?1:-1,v=y*n,m=y>0?"end":"start",b=y>0?"start":"end";if("top"===o)return g(g({},{x:i+u/2,y:a-s*n,textAnchor:"middle",verticalAnchor:p}),r?{height:Math.max(a-r.y,0),width:u}:{});if("bottom"===o)return g(g({},{x:i+u/2,y:a+c+f,textAnchor:"middle",verticalAnchor:d}),r?{height:Math.max(r.y+r.height-(a+c),0),width:u}:{});if("left"===o){var x={x:i-v,y:a+c/2,textAnchor:m,verticalAnchor:"middle"};return g(g({},x),r?{width:Math.max(x.x-r.x,0),height:c}:{})}if("right"===o){var w={x:i+u+v,y:a+c/2,textAnchor:b,verticalAnchor:"middle"};return g(g({},w),r?{width:Math.max(r.x+r.width-w.x,0),height:c}:{})}var O=r?{width:u,height:c}:{};return"insideLeft"===o?g({x:i+v,y:a+c/2,textAnchor:b,verticalAnchor:"middle"},O):"insideRight"===o?g({x:i+u-v,y:a+c/2,textAnchor:m,verticalAnchor:"middle"},O):"insideTop"===o?g({x:i+u/2,y:a+f,textAnchor:"middle",verticalAnchor:d},O):"insideBottom"===o?g({x:i+u/2,y:a+c-f,textAnchor:"middle",verticalAnchor:p},O):"insideTopLeft"===o?g({x:i+v,y:a+f,textAnchor:b,verticalAnchor:d},O):"insideTopRight"===o?g({x:i+u-v,y:a+f,textAnchor:m,verticalAnchor:d},O):"insideBottomLeft"===o?g({x:i+v,y:a+c-f,textAnchor:b,verticalAnchor:p},O):"insideBottomRight"===o?g({x:i+u-v,y:a+c-f,textAnchor:m,verticalAnchor:p},O):l()(o)&&((0,h.hj)(o.x)||(0,h.hU)(o.x))&&((0,h.hj)(o.y)||(0,h.hU)(o.y))?g({x:i+(0,h.h1)(o.x,u),y:a+(0,h.h1)(o.y,c),textAnchor:"end",verticalAnchor:"end"},O):g({x:i+u/2,y:a+c/2,textAnchor:"middle",verticalAnchor:"middle"},O)};function P(t){var e,r=t.offset,o=g({offset:void 0===r?5:r},function(t,e){if(null==t)return{};var r,n,o=function(t,e){if(null==t)return{};var r={};for(var n in t)if(Object.prototype.hasOwnProperty.call(t,n)){if(e.indexOf(n)>=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(t,v)),a=o.viewBox,c=o.position,l=o.value,d=o.children,y=o.content,m=o.className,b=o.textBreakAll;if(!a||i()(l)&&i()(d)&&!(0,n.isValidElement)(y)&&!u()(y))return null;if((0,n.isValidElement)(y))return(0,n.cloneElement)(y,o);if(u()(y)){if(e=(0,n.createElement)(y,o),(0,n.isValidElement)(e))return e}else e=w(o);var P="cx"in a&&(0,h.hj)(a.cx),E=(0,p.L6)(o,!0);if(P&&("insideStart"===c||"insideEnd"===c||"end"===c))return O(o,e,E);var k=P?j(o):S(o);return n.createElement(f.x,x({className:(0,s.Z)("recharts-label",void 0===m?"":m)},E,k,{breakAll:b}),e)}P.displayName="Label";var E=function(t){var e=t.cx,r=t.cy,n=t.angle,o=t.startAngle,i=t.endAngle,a=t.r,u=t.radius,c=t.innerRadius,l=t.outerRadius,s=t.x,f=t.y,p=t.top,d=t.left,y=t.width,v=t.height,m=t.clockWise,b=t.labelViewBox;if(b)return b;if((0,h.hj)(y)&&(0,h.hj)(v)){if((0,h.hj)(s)&&(0,h.hj)(f))return{x:s,y:f,width:y,height:v};if((0,h.hj)(p)&&(0,h.hj)(d))return{x:p,y:d,width:y,height:v}}return(0,h.hj)(s)&&(0,h.hj)(f)?{x:s,y:f,width:0,height:0}:(0,h.hj)(e)&&(0,h.hj)(r)?{cx:e,cy:r,startAngle:o||n||0,endAngle:i||n||0,innerRadius:c||0,outerRadius:l||u||a||0,clockWise:m}:t.viewBox?t.viewBox:{}};P.parseViewBox=E,P.renderCallByParent=function(t,e){var r,o,i=!(arguments.length>2)||void 0===arguments[2]||arguments[2];if(!t||!t.children&&i&&!t.label)return null;var a=t.children,c=E(t),s=(0,p.NN)(a,P).map(function(t,r){return(0,n.cloneElement)(t,{viewBox:e||c,key:"label-".concat(r)})});return i?[(r=t.label,o=e||c,r?!0===r?n.createElement(P,{key:"label-implicit",viewBox:o}):(0,h.P2)(r)?n.createElement(P,{key:"label-implicit",viewBox:o,value:r}):(0,n.isValidElement)(r)?r.type===P?(0,n.cloneElement)(r,{key:"label-implicit",viewBox:o}):n.createElement(P,{key:"label-implicit",content:r,viewBox:o}):u()(r)?n.createElement(P,{key:"label-implicit",content:r,viewBox:o}):l()(r)?n.createElement(P,x({viewBox:o},r,{key:"label-implicit"})):null:null)].concat(function(t){if(Array.isArray(t))return m(t)}(s)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(s)||function(t,e){if(t){if("string"==typeof t)return m(t,void 0);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return m(t,void 0)}}(s)||function(){throw TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()):s}},58772:function(t,e,r){"use strict";r.d(e,{e:function(){return P}});var n=r(2265),o=r(77571),i=r.n(o),a=r(28302),u=r.n(a),c=r(86757),l=r.n(c),s=r(86185),f=r.n(s),p=r(26680),h=r(9841),d=r(82944),y=r(85355);function v(t){return(v="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var m=["valueAccessor"],b=["data","dataKey","clockWise","id","textBreakAll"];function g(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);r=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}var S=function(t){return Array.isArray(t.value)?f()(t.value):t.value};function P(t){var e=t.valueAccessor,r=void 0===e?S:e,o=j(t,m),a=o.data,u=o.dataKey,c=o.clockWise,l=o.id,s=o.textBreakAll,f=j(o,b);return a&&a.length?n.createElement(h.m,{className:"recharts-label-list"},a.map(function(t,e){var o=i()(u)?r(t,e):(0,y.F$)(t&&t.payload,u),a=i()(l)?{}:{id:"".concat(l,"-").concat(e)};return n.createElement(p._,x({},(0,d.L6)(t,!0),f,a,{parentViewBox:t.parentViewBox,value:o,textBreakAll:s,viewBox:p._.parseViewBox(i()(c)?t:O(O({},t),{},{clockWise:c})),key:"label-".concat(e),index:e}))})):null}P.displayName="LabelList",P.renderCallByParent=function(t,e){var r,o=!(arguments.length>2)||void 0===arguments[2]||arguments[2];if(!t||!t.children&&o&&!t.label)return null;var i=t.children,a=(0,d.NN)(i,P).map(function(t,r){return(0,n.cloneElement)(t,{data:e,key:"labelList-".concat(r)})});return o?[(r=t.label)?!0===r?n.createElement(P,{key:"labelList-implicit",data:e}):n.isValidElement(r)||l()(r)?n.createElement(P,{key:"labelList-implicit",data:e,content:r}):u()(r)?n.createElement(P,x({data:e},r,{key:"labelList-implicit"})):null:null].concat(function(t){if(Array.isArray(t))return g(t)}(a)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(a)||function(t,e){if(t){if("string"==typeof t)return g(t,void 0);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return g(t,void 0)}}(a)||function(){throw TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()):a}},22190:function(t,e,r){"use strict";r.d(e,{D:function(){return N}});var n=r(2265),o=r(86757),i=r.n(o),a=r(61994),u=r(1175),c=r(48777),l=r(14870),s=r(41637);function f(t){return(f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function p(){return(p=Object.assign?Object.assign.bind():function(t){for(var e=1;e');var x=e.inactive?h:e.color;return n.createElement("li",p({className:b,style:y,key:"legend-item-".concat(r)},(0,s.bw)(t.props,e,r)),n.createElement(c.T,{width:o,height:o,viewBox:d,style:v},t.renderIcon(e)),n.createElement("span",{className:"recharts-legend-item-text",style:{color:x}},l?l(g,e,r):g))})}},{key:"render",value:function(){var t=this.props,e=t.payload,r=t.layout,o=t.align;return e&&e.length?n.createElement("ul",{className:"recharts-default-legend",style:{padding:0,margin:0,textAlign:"horizontal"===r?o:"left"}},this.renderItems()):null}}],function(t,e){for(var r=0;r1||Math.abs(e.height-this.lastBoundingBox.height)>1)&&(this.lastBoundingBox.width=e.width,this.lastBoundingBox.height=e.height,t&&t(e)):(-1!==this.lastBoundingBox.width||-1!==this.lastBoundingBox.height)&&(this.lastBoundingBox.width=-1,this.lastBoundingBox.height=-1,t&&t(null))}},{key:"getBBoxSnapshot",value:function(){return this.lastBoundingBox.width>=0&&this.lastBoundingBox.height>=0?P({},this.lastBoundingBox):{width:0,height:0}}},{key:"getDefaultPosition",value:function(t){var e,r,n=this.props,o=n.layout,i=n.align,a=n.verticalAlign,u=n.margin,c=n.chartWidth,l=n.chartHeight;return t&&(void 0!==t.left&&null!==t.left||void 0!==t.right&&null!==t.right)||(e="center"===i&&"vertical"===o?{left:((c||0)-this.getBBoxSnapshot().width)/2}:"right"===i?{right:u&&u.right||0}:{left:u&&u.left||0}),t&&(void 0!==t.top&&null!==t.top||void 0!==t.bottom&&null!==t.bottom)||(r="middle"===a?{top:((l||0)-this.getBBoxSnapshot().height)/2}:"bottom"===a?{bottom:u&&u.bottom||0}:{top:u&&u.top||0}),P(P({},e),r)}},{key:"render",value:function(){var t=this,e=this.props,r=e.content,o=e.width,i=e.height,a=e.wrapperStyle,u=e.payloadUniqBy,c=e.payload,l=P(P({position:"absolute",width:o||"auto",height:i||"auto"},this.getDefaultPosition(a)),a);return n.createElement("div",{className:"recharts-legend-wrapper",style:l,ref:function(e){t.wrapperNode=e}},function(t,e){if(n.isValidElement(t))return n.cloneElement(t,e);if("function"==typeof t)return n.createElement(t,e);e.ref;var r=function(t,e){if(null==t)return{};var r,n,o=function(t,e){if(null==t)return{};var r={};for(var n in t)if(Object.prototype.hasOwnProperty.call(t,n)){if(e.indexOf(n)>=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(e,j);return n.createElement(g,r)}(r,P(P({},this.props),{},{payload:(0,w.z)(c,u,C)})))}}],r=[{key:"getWithHeight",value:function(t,e){var r=P(P({},this.defaultProps),t.props).layout;return"vertical"===r&&(0,x.hj)(t.props.height)?{height:t.props.height}:"horizontal"===r?{width:t.props.width||e}:null}}],e&&E(o.prototype,e),r&&E(o,r),Object.defineProperty(o,"prototype",{writable:!1}),o}(n.PureComponent);_(N,"displayName","Legend"),_(N,"defaultProps",{iconSize:14,layout:"horizontal",align:"center",verticalAlign:"bottom"})},47625:function(t,e,r){"use strict";r.d(e,{h:function(){return d}});var n=r(61994),o=r(2265),i=r(37065),a=r.n(i),u=r(16630),c=r(1175),l=r(82944);function s(t){return(s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function f(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,n)}return r}function p(t){for(var e=1;et.length)&&(e=t.length);for(var r=0,n=Array(e);r0&&(t=a()(t,S,{trailing:!0,leading:!1}));var e=new ResizeObserver(t),r=M.current.getBoundingClientRect();return D(r.width,r.height),e.observe(M.current),function(){e.disconnect()}},[D,S]);var I=(0,o.useMemo)(function(){var t=C.containerWidth,e=C.containerHeight;if(t<0||e<0)return null;(0,c.Z)((0,u.hU)(y)||(0,u.hU)(m),"The width(%s) and height(%s) are both fixed numbers,\n maybe you don't need to use a ResponsiveContainer.",y,m),(0,c.Z)(!i||i>0,"The aspect(%s) must be greater than zero.",i);var r=(0,u.hU)(y)?t:y,n=(0,u.hU)(m)?e:m;i&&i>0&&(r?n=r/i:n&&(r=n*i),w&&n>w&&(n=w)),(0,c.Z)(r>0||n>0,"The width(%s) and height(%s) of chart should be greater than 0,\n please check the style of container, or the props width(%s) and height(%s),\n or add a minWidth(%s) or minHeight(%s) or use aspect(%s) to control the\n height and width.",r,n,y,m,g,x,i);var a=!Array.isArray(O)&&(0,l.Gf)(O.type).endsWith("Chart");return o.Children.map(O,function(t){return o.isValidElement(t)?(0,o.cloneElement)(t,p({width:r,height:n},a?{style:p({height:"100%",width:"100%",maxHeight:n,maxWidth:r},t.props.style)}:{})):t})},[i,O,m,w,x,g,C,y]);return o.createElement("div",{id:P?"".concat(P):void 0,className:(0,n.Z)("recharts-responsive-container",E),style:p(p({},void 0===A?{}:A),{},{width:y,height:m,minWidth:g,minHeight:x,maxHeight:w}),ref:M},I)})},58811:function(t,e,r){"use strict";r.d(e,{x:function(){return B}});var n=r(2265),o=r(77571),i=r.n(o),a=r(61994),u=r(16630),c=r(34067),l=r(82944),s=r(4094);function f(t){return(f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function p(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var r=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=r){var n,o,i,a,u=[],c=!0,l=!1;try{if(i=(r=r.call(t)).next,0===e){if(Object(r)!==r)return;c=!1}else for(;!(c=(n=i.call(r)).done)&&(u.push(n.value),u.length!==e);c=!0);}catch(t){l=!0,o=t}finally{try{if(!c&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(l)throw o}}return u}}(t,e)||function(t,e){if(t){if("string"==typeof t)return h(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return h(t,e)}}(t,e)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function h(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);r=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}function M(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var r=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=r){var n,o,i,a,u=[],c=!0,l=!1;try{if(i=(r=r.call(t)).next,0===e){if(Object(r)!==r)return;c=!1}else for(;!(c=(n=i.call(r)).done)&&(u.push(n.value),u.length!==e);c=!0);}catch(t){l=!0,o=t}finally{try{if(!c&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(l)throw o}}return u}}(t,e)||function(t,e){if(t){if("string"==typeof t)return _(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return _(t,e)}}(t,e)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function _(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);r0&&void 0!==arguments[0]?arguments[0]:[];return t.reduce(function(t,e){var i=e.word,a=e.width,u=t[t.length-1];return u&&(null==n||o||u.width+a+ra||e.reduce(function(t,e){return t.width>e.width?t:e}).width>Number(n),e]},y=0,v=c.length-1,m=0;y<=v&&m<=c.length-1;){var b=Math.floor((y+v)/2),g=M(d(b-1),2),x=g[0],w=g[1],O=M(d(b),1)[0];if(x||O||(y=b+1),x&&O&&(v=b-1),!x&&O){i=w;break}m++}return i||h},D=function(t){return[{words:i()(t)?[]:t.toString().split(T)}]},I=function(t){var e=t.width,r=t.scaleToFit,n=t.children,o=t.style,i=t.breakAll,a=t.maxLines;if((e||r)&&!c.x.isSsr){var u=C({breakAll:i,children:n,style:o});return u?N({breakAll:i,children:n,maxLines:a,style:o},u.wordsWithComputedWidth,u.spaceWidth,e,r):D(n)}return D(n)},L="#808080",B=function(t){var e,r=t.x,o=void 0===r?0:r,i=t.y,c=void 0===i?0:i,s=t.lineHeight,f=void 0===s?"1em":s,p=t.capHeight,h=void 0===p?"0.71em":p,d=t.scaleToFit,y=void 0!==d&&d,v=t.textAnchor,m=t.verticalAnchor,b=t.fill,g=void 0===b?L:b,x=A(t,P),w=(0,n.useMemo)(function(){return I({breakAll:x.breakAll,children:x.children,maxLines:x.maxLines,scaleToFit:y,style:x.style,width:x.width})},[x.breakAll,x.children,x.maxLines,y,x.style,x.width]),O=x.dx,j=x.dy,M=x.angle,_=x.className,T=x.breakAll,C=A(x,E);if(!(0,u.P2)(o)||!(0,u.P2)(c))return null;var N=o+((0,u.hj)(O)?O:0),D=c+((0,u.hj)(j)?j:0);switch(void 0===m?"end":m){case"start":e=S("calc(".concat(h,")"));break;case"middle":e=S("calc(".concat((w.length-1)/2," * -").concat(f," + (").concat(h," / 2))"));break;default:e=S("calc(".concat(w.length-1," * -").concat(f,")"))}var B=[];if(y){var R=w[0].width,z=x.width;B.push("scale(".concat(((0,u.hj)(z)?z/R:1)/R,")"))}return M&&B.push("rotate(".concat(M,", ").concat(N,", ").concat(D,")")),B.length&&(C.transform=B.join(" ")),n.createElement("text",k({},(0,l.L6)(C,!0),{x:N,y:D,className:(0,a.Z)("recharts-text",_),textAnchor:void 0===v?"start":v,fill:g.includes("url")?L:g}),w.map(function(t,r){var o=t.words.join(T?"":" ");return n.createElement("tspan",{x:N,dy:0===r?e:f,key:"".concat(o,"-").concat(r)},o)}))}},8147:function(t,e,r){"use strict";r.d(e,{u:function(){return $}});var n=r(2265),o=r(34935),i=r.n(o),a=r(77571),u=r.n(a),c=r(61994),l=r(16630);function s(t){return(s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function f(){return(f=Object.assign?Object.assign.bind():function(t){for(var e=1;et.length)&&(e=t.length);for(var r=0,n=Array(e);rc[n]+s?Math.max(f,c[n]):Math.max(p,c[n])}function O(t){return(O="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function j(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,n)}return r}function S(t){for(var e=1;e1||Math.abs(t.height-this.state.lastBoundingBox.height)>1)&&this.setState({lastBoundingBox:{width:t.width,height:t.height}})}else(-1!==this.state.lastBoundingBox.width||-1!==this.state.lastBoundingBox.height)&&this.setState({lastBoundingBox:{width:-1,height:-1}})}},{key:"componentDidMount",value:function(){document.addEventListener("keydown",this.handleKeyDown),this.updateBBox()}},{key:"componentWillUnmount",value:function(){document.removeEventListener("keydown",this.handleKeyDown)}},{key:"componentDidUpdate",value:function(){var t,e;this.props.active&&this.updateBBox(),this.state.dismissed&&((null===(t=this.props.coordinate)||void 0===t?void 0:t.x)!==this.state.dismissedAtCoordinate.x||(null===(e=this.props.coordinate)||void 0===e?void 0:e.y)!==this.state.dismissedAtCoordinate.y)&&(this.state.dismissed=!1)}},{key:"render",value:function(){var t,e,r,o,i,a,u,s,f,p,h,d,y,v,m,O,j,P,E,k=this,A=this.props,M=A.active,_=A.allowEscapeViewBox,T=A.animationDuration,C=A.animationEasing,N=A.children,D=A.coordinate,I=A.hasPayload,L=A.isAnimationActive,B=A.offset,R=A.position,z=A.reverseDirection,U=A.useTranslate3d,F=A.viewBox,$=A.wrapperStyle,q=(d=(t={allowEscapeViewBox:_,coordinate:D,offsetTopLeft:B,position:R,reverseDirection:z,tooltipBox:this.state.lastBoundingBox,useTranslate3d:U,viewBox:F}).allowEscapeViewBox,y=t.coordinate,v=t.offsetTopLeft,m=t.position,O=t.reverseDirection,j=t.tooltipBox,P=t.useTranslate3d,E=t.viewBox,j.height>0&&j.width>0&&y?(r=(e={translateX:p=w({allowEscapeViewBox:d,coordinate:y,key:"x",offsetTopLeft:v,position:m,reverseDirection:O,tooltipDimension:j.width,viewBox:E,viewBoxDimension:E.width}),translateY:h=w({allowEscapeViewBox:d,coordinate:y,key:"y",offsetTopLeft:v,position:m,reverseDirection:O,tooltipDimension:j.height,viewBox:E,viewBoxDimension:E.height}),useTranslate3d:P}).translateX,o=e.translateY,f={transform:e.useTranslate3d?"translate3d(".concat(r,"px, ").concat(o,"px, 0)"):"translate(".concat(r,"px, ").concat(o,"px)")}):f=x,{cssProperties:f,cssClasses:(a=(i={translateX:p,translateY:h,coordinate:y}).coordinate,u=i.translateX,s=i.translateY,(0,c.Z)(g,b(b(b(b({},"".concat(g,"-right"),(0,l.hj)(u)&&a&&(0,l.hj)(a.x)&&u>=a.x),"".concat(g,"-left"),(0,l.hj)(u)&&a&&(0,l.hj)(a.x)&&u=a.y),"".concat(g,"-top"),(0,l.hj)(s)&&a&&(0,l.hj)(a.y)&&s0;return n.createElement(_,{allowEscapeViewBox:i,animationDuration:a,animationEasing:u,isAnimationActive:f,active:o,coordinate:l,hasPayload:O,offset:p,position:y,reverseDirection:m,useTranslate3d:b,viewBox:g,wrapperStyle:x},(t=I(I({},this.props),{},{payload:w}),n.isValidElement(c)?n.cloneElement(c,t):"function"==typeof c?n.createElement(c,t):n.createElement(v,t)))}}],function(t,e){for(var r=0;r=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(t,a),s=(0,o.Z)("recharts-layer",c);return n.createElement("g",u({className:s},(0,i.L6)(l,!0),{ref:e}),r)})},48777:function(t,e,r){"use strict";r.d(e,{T:function(){return c}});var n=r(2265),o=r(61994),i=r(82944),a=["children","width","height","viewBox","className","style","title","desc"];function u(){return(u=Object.assign?Object.assign.bind():function(t){for(var e=1;e=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(t,a),y=l||{width:r,height:c,x:0,y:0},v=(0,o.Z)("recharts-surface",s);return n.createElement("svg",u({},(0,i.L6)(d,!0,"svg"),{className:v,width:r,height:c,style:f,viewBox:"".concat(y.x," ").concat(y.y," ").concat(y.width," ").concat(y.height)}),n.createElement("title",null,p),n.createElement("desc",null,h),e)}},25739:function(t,e,r){"use strict";r.d(e,{br:function(){return g},CW:function(){return O},Mw:function(){return A},zn:function(){return k},sp:function(){return x},qD:function(){return E},d2:function(){return P},bH:function(){return w},Ud:function(){return S},Nf:function(){return j}});var n=r(2265),o=r(69398),i=r(84173),a=r.n(i),u=r(32242),c=r.n(u),l=r(50967),s=r.n(l)()(function(t){return{x:t.left,y:t.top,width:t.width,height:t.height}},function(t){return["l",t.left,"t",t.top,"w",t.width,"h",t.height].join("")}),f=r(16630),p=(0,n.createContext)(void 0),h=(0,n.createContext)(void 0),d=(0,n.createContext)(void 0),y=(0,n.createContext)({}),v=(0,n.createContext)(void 0),m=(0,n.createContext)(0),b=(0,n.createContext)(0),g=function(t){var e=t.state,r=e.xAxisMap,o=e.yAxisMap,i=e.offset,a=t.clipPathId,u=t.children,c=t.width,l=t.height,f=s(i);return n.createElement(p.Provider,{value:r},n.createElement(h.Provider,{value:o},n.createElement(y.Provider,{value:i},n.createElement(d.Provider,{value:f},n.createElement(v.Provider,{value:a},n.createElement(m.Provider,{value:l},n.createElement(b.Provider,{value:c},u)))))))},x=function(){return(0,n.useContext)(v)},w=function(t){var e=(0,n.useContext)(p);null!=e||(0,o.Z)(!1);var r=e[t];return null!=r||(0,o.Z)(!1),r},O=function(){var t=(0,n.useContext)(p);return(0,f.Kt)(t)},j=function(){var t=(0,n.useContext)(h);return a()(t,function(t){return c()(t.domain,Number.isFinite)})||(0,f.Kt)(t)},S=function(t){var e=(0,n.useContext)(h);null!=e||(0,o.Z)(!1);var r=e[t];return null!=r||(0,o.Z)(!1),r},P=function(){return(0,n.useContext)(d)},E=function(){return(0,n.useContext)(y)},k=function(){return(0,n.useContext)(b)},A=function(){return(0,n.useContext)(m)}},57165:function(t,e,r){"use strict";r.d(e,{H:function(){return H}});var n=r(2265);function o(){}function i(t,e,r){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+r)/6)}function a(t){this._context=t}function u(t){this._context=t}function c(t){this._context=t}a.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:i(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:i(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},u.prototype={areaStart:o,areaEnd:o,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:i(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},c.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var r=(this._x0+4*this._x1+t)/6,n=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(r,n):this._context.moveTo(r,n);break;case 3:this._point=4;default:i(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};class l{constructor(t,e){this._context=t,this._x=e}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line}point(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._x?this._context.bezierCurveTo(this._x0=(this._x0+t)/2,this._y0,this._x0,e,t,e):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+e)/2,t,this._y0,t,e)}this._x0=t,this._y0=e}}function s(t){this._context=t}function f(t){this._context=t}function p(t){return new f(t)}function h(t,e,r){var n=t._x1-t._x0,o=e-t._x1,i=(t._y1-t._y0)/(n||o<0&&-0),a=(r-t._y1)/(o||n<0&&-0);return((i<0?-1:1)+(a<0?-1:1))*Math.min(Math.abs(i),Math.abs(a),.5*Math.abs((i*o+a*n)/(n+o)))||0}function d(t,e){var r=t._x1-t._x0;return r?(3*(t._y1-t._y0)/r-e)/2:e}function y(t,e,r){var n=t._x0,o=t._y0,i=t._x1,a=t._y1,u=(i-n)/3;t._context.bezierCurveTo(n+u,o+u*e,i-u,a-u*r,i,a)}function v(t){this._context=t}function m(t){this._context=new b(t)}function b(t){this._context=t}function g(t){this._context=t}function x(t){var e,r,n=t.length-1,o=Array(n),i=Array(n),a=Array(n);for(o[0]=0,i[0]=2,a[0]=t[0]+2*t[1],e=1;e=0;--e)o[e]=(a[e]-o[e+1])/i[e];for(e=0,i[n-1]=(t[n]+o[n-1])/2;e=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var r=this._x*(1-this._t)+t*this._t;this._context.lineTo(r,this._y),this._context.lineTo(r,e)}}this._x=t,this._y=e}};var O=r(22516),j=r(76115),S=r(67790);function P(t){return t[0]}function E(t){return t[1]}function k(t,e){var r=(0,j.Z)(!0),n=null,o=p,i=null,a=(0,S.d)(u);function u(u){var c,l,s,f=(u=(0,O.Z)(u)).length,p=!1;for(null==n&&(i=o(s=a())),c=0;c<=f;++c)!(c=f;--p)u.point(m[p],b[p]);u.lineEnd(),u.areaEnd()}}v&&(m[s]=+t(h,s,l),b[s]=+e(h,s,l),u.point(n?+n(h,s,l):m[s],r?+r(h,s,l):b[s]))}if(d)return u=null,d+""||null}function s(){return k().defined(o).curve(a).context(i)}return t="function"==typeof t?t:void 0===t?P:(0,j.Z)(+t),e="function"==typeof e?e:void 0===e?(0,j.Z)(0):(0,j.Z)(+e),r="function"==typeof r?r:void 0===r?E:(0,j.Z)(+r),l.x=function(e){return arguments.length?(t="function"==typeof e?e:(0,j.Z)(+e),n=null,l):t},l.x0=function(e){return arguments.length?(t="function"==typeof e?e:(0,j.Z)(+e),l):t},l.x1=function(t){return arguments.length?(n=null==t?null:"function"==typeof t?t:(0,j.Z)(+t),l):n},l.y=function(t){return arguments.length?(e="function"==typeof t?t:(0,j.Z)(+t),r=null,l):e},l.y0=function(t){return arguments.length?(e="function"==typeof t?t:(0,j.Z)(+t),l):e},l.y1=function(t){return arguments.length?(r=null==t?null:"function"==typeof t?t:(0,j.Z)(+t),l):r},l.lineX0=l.lineY0=function(){return s().x(t).y(e)},l.lineY1=function(){return s().x(t).y(r)},l.lineX1=function(){return s().x(n).y(e)},l.defined=function(t){return arguments.length?(o="function"==typeof t?t:(0,j.Z)(!!t),l):o},l.curve=function(t){return arguments.length?(a=t,null!=i&&(u=a(i)),l):a},l.context=function(t){return arguments.length?(null==t?i=u=null:u=a(i=t),l):i},l}var M=r(75551),_=r.n(M),T=r(86757),C=r.n(T),N=r(61994),D=r(41637),I=r(82944),L=r(16630);function B(t){return(B="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function R(){return(R=Object.assign?Object.assign.bind():function(t){for(var e=1;et.length)&&(e=t.length);for(var r=0,n=Array(e);r=0?1:-1,c=r>=0?1:-1,l=n>=0&&r>=0||n<0&&r<0?1:0;if(a>0&&o instanceof Array){for(var s=[0,0,0,0],f=0;f<4;f++)s[f]=o[f]>a?a:o[f];i="M".concat(t,",").concat(e+u*s[0]),s[0]>0&&(i+="A ".concat(s[0],",").concat(s[0],",0,0,").concat(l,",").concat(t+c*s[0],",").concat(e)),i+="L ".concat(t+r-c*s[1],",").concat(e),s[1]>0&&(i+="A ".concat(s[1],",").concat(s[1],",0,0,").concat(l,",\n ").concat(t+r,",").concat(e+u*s[1])),i+="L ".concat(t+r,",").concat(e+n-u*s[2]),s[2]>0&&(i+="A ".concat(s[2],",").concat(s[2],",0,0,").concat(l,",\n ").concat(t+r-c*s[2],",").concat(e+n)),i+="L ".concat(t+c*s[3],",").concat(e+n),s[3]>0&&(i+="A ".concat(s[3],",").concat(s[3],",0,0,").concat(l,",\n ").concat(t,",").concat(e+n-u*s[3])),i+="Z"}else if(a>0&&o===+o&&o>0){var p=Math.min(a,o);i="M ".concat(t,",").concat(e+u*p,"\n A ").concat(p,",").concat(p,",0,0,").concat(l,",").concat(t+c*p,",").concat(e,"\n L ").concat(t+r-c*p,",").concat(e,"\n A ").concat(p,",").concat(p,",0,0,").concat(l,",").concat(t+r,",").concat(e+u*p,"\n L ").concat(t+r,",").concat(e+n-u*p,"\n A ").concat(p,",").concat(p,",0,0,").concat(l,",").concat(t+r-c*p,",").concat(e+n,"\n L ").concat(t+c*p,",").concat(e+n,"\n A ").concat(p,",").concat(p,",0,0,").concat(l,",").concat(t,",").concat(e+n-u*p," Z")}else i="M ".concat(t,",").concat(e," h ").concat(r," v ").concat(n," h ").concat(-r," Z");return i},h=function(t,e){if(!t||!e)return!1;var r=t.x,n=t.y,o=e.x,i=e.y,a=e.width,u=e.height;return!!(Math.abs(a)>0&&Math.abs(u)>0)&&r>=Math.min(o,o+a)&&r<=Math.max(o,o+a)&&n>=Math.min(i,i+u)&&n<=Math.max(i,i+u)},d={x:0,y:0,width:0,height:0,radius:0,isAnimationActive:!1,isUpdateAnimationActive:!1,animationBegin:0,animationDuration:1500,animationEasing:"ease"},y=function(t){var e,r=f(f({},d),t),u=(0,n.useRef)(),s=function(t){if(Array.isArray(t))return t}(e=(0,n.useState)(-1))||function(t,e){var r=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=r){var n,o,i,a,u=[],c=!0,l=!1;try{for(i=(r=r.call(t)).next;!(c=(n=i.call(r)).done)&&(u.push(n.value),2!==u.length);c=!0);}catch(t){l=!0,o=t}finally{try{if(!c&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(l)throw o}}return u}}(e,2)||function(t,e){if(t){if("string"==typeof t)return l(t,2);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return l(t,2)}}(e,2)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(),h=s[0],y=s[1];(0,n.useEffect)(function(){if(u.current&&u.current.getTotalLength)try{var t=u.current.getTotalLength();t&&y(t)}catch(t){}},[]);var v=r.x,m=r.y,b=r.width,g=r.height,x=r.radius,w=r.className,O=r.animationEasing,j=r.animationDuration,S=r.animationBegin,P=r.isAnimationActive,E=r.isUpdateAnimationActive;if(v!==+v||m!==+m||b!==+b||g!==+g||0===b||0===g)return null;var k=(0,o.Z)("recharts-rectangle",w);return E?n.createElement(i.ZP,{canBegin:h>0,from:{width:b,height:g,x:v,y:m},to:{width:b,height:g,x:v,y:m},duration:j,animationEasing:O,isActive:E},function(t){var e=t.width,o=t.height,l=t.x,s=t.y;return n.createElement(i.ZP,{canBegin:h>0,from:"0px ".concat(-1===h?1:h,"px"),to:"".concat(h,"px 0px"),attributeName:"strokeDasharray",begin:S,duration:j,isActive:P,easing:O},n.createElement("path",c({},(0,a.L6)(r,!0),{className:k,d:p(l,s,e,o,x),ref:u})))}):n.createElement("path",c({},(0,a.L6)(r,!0),{className:k,d:p(v,m,b,g,x)}))}},60474:function(t,e,r){"use strict";r.d(e,{L:function(){return v}});var n=r(2265),o=r(61994),i=r(82944),a=r(39206),u=r(16630);function c(t){return(c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function l(){return(l=Object.assign?Object.assign.bind():function(t){for(var e=1;e180),",").concat(+(c>s),",\n ").concat(p.x,",").concat(p.y,"\n ");if(o>0){var d=(0,a.op)(r,n,o,c),y=(0,a.op)(r,n,o,s);h+="L ".concat(y.x,",").concat(y.y,"\n A ").concat(o,",").concat(o,",0,\n ").concat(+(Math.abs(l)>180),",").concat(+(c<=s),",\n ").concat(d.x,",").concat(d.y," Z")}else h+="L ".concat(r,",").concat(n," Z");return h},d=function(t){var e=t.cx,r=t.cy,n=t.innerRadius,o=t.outerRadius,i=t.cornerRadius,a=t.forceCornerRadius,c=t.cornerIsExternal,l=t.startAngle,s=t.endAngle,f=(0,u.uY)(s-l),d=p({cx:e,cy:r,radius:o,angle:l,sign:f,cornerRadius:i,cornerIsExternal:c}),y=d.circleTangency,v=d.lineTangency,m=d.theta,b=p({cx:e,cy:r,radius:o,angle:s,sign:-f,cornerRadius:i,cornerIsExternal:c}),g=b.circleTangency,x=b.lineTangency,w=b.theta,O=c?Math.abs(l-s):Math.abs(l-s)-m-w;if(O<0)return a?"M ".concat(v.x,",").concat(v.y,"\n a").concat(i,",").concat(i,",0,0,1,").concat(2*i,",0\n a").concat(i,",").concat(i,",0,0,1,").concat(-(2*i),",0\n "):h({cx:e,cy:r,innerRadius:n,outerRadius:o,startAngle:l,endAngle:s});var j="M ".concat(v.x,",").concat(v.y,"\n A").concat(i,",").concat(i,",0,0,").concat(+(f<0),",").concat(y.x,",").concat(y.y,"\n A").concat(o,",").concat(o,",0,").concat(+(O>180),",").concat(+(f<0),",").concat(g.x,",").concat(g.y,"\n A").concat(i,",").concat(i,",0,0,").concat(+(f<0),",").concat(x.x,",").concat(x.y,"\n ");if(n>0){var S=p({cx:e,cy:r,radius:n,angle:l,sign:f,isExternal:!0,cornerRadius:i,cornerIsExternal:c}),P=S.circleTangency,E=S.lineTangency,k=S.theta,A=p({cx:e,cy:r,radius:n,angle:s,sign:-f,isExternal:!0,cornerRadius:i,cornerIsExternal:c}),M=A.circleTangency,_=A.lineTangency,T=A.theta,C=c?Math.abs(l-s):Math.abs(l-s)-k-T;if(C<0&&0===i)return"".concat(j,"L").concat(e,",").concat(r,"Z");j+="L".concat(_.x,",").concat(_.y,"\n A").concat(i,",").concat(i,",0,0,").concat(+(f<0),",").concat(M.x,",").concat(M.y,"\n A").concat(n,",").concat(n,",0,").concat(+(C>180),",").concat(+(f>0),",").concat(P.x,",").concat(P.y,"\n A").concat(i,",").concat(i,",0,0,").concat(+(f<0),",").concat(E.x,",").concat(E.y,"Z")}else j+="L".concat(e,",").concat(r,"Z");return j},y={cx:0,cy:0,innerRadius:0,outerRadius:0,startAngle:0,endAngle:0,cornerRadius:0,forceCornerRadius:!1,cornerIsExternal:!1},v=function(t){var e,r=f(f({},y),t),a=r.cx,c=r.cy,s=r.innerRadius,p=r.outerRadius,v=r.cornerRadius,m=r.forceCornerRadius,b=r.cornerIsExternal,g=r.startAngle,x=r.endAngle,w=r.className;if(p0&&360>Math.abs(g-x)?d({cx:a,cy:c,innerRadius:s,outerRadius:p,cornerRadius:Math.min(S,j/2),forceCornerRadius:m,cornerIsExternal:b,startAngle:g,endAngle:x}):h({cx:a,cy:c,innerRadius:s,outerRadius:p,startAngle:g,endAngle:x}),n.createElement("path",l({},(0,i.L6)(r,!0),{className:O,d:e,role:"img"}))}},14870:function(t,e,r){"use strict";r.d(e,{v:function(){return N}});var n=r(2265),o=r(75551),i=r.n(o);let a=Math.cos,u=Math.sin,c=Math.sqrt,l=Math.PI,s=2*l;var f={draw(t,e){let r=c(e/l);t.moveTo(r,0),t.arc(0,0,r,0,s)}};let p=c(1/3),h=2*p,d=u(l/10)/u(7*l/10),y=u(s/10)*d,v=-a(s/10)*d,m=c(3),b=c(3)/2,g=1/c(12),x=(g/2+1)*3;var w=r(76115),O=r(67790);c(3),c(3);var j=r(61994),S=r(82944);function P(t){return(P="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var E=["type","size","sizeType"];function k(){return(k=Object.assign?Object.assign.bind():function(t){for(var e=1;e=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(t,E)),{},{type:o,size:u,sizeType:l}),p=s.className,h=s.cx,d=s.cy,y=(0,S.L6)(s,!0);return h===+h&&d===+d&&u===+u?n.createElement("path",k({},y,{className:(0,j.Z)("recharts-symbols",p),transform:"translate(".concat(h,", ").concat(d,")"),d:(e=_["symbol".concat(i()(o))]||f,(function(t,e){let r=null,n=(0,O.d)(o);function o(){let o;if(r||(r=o=n()),t.apply(this,arguments).draw(r,+e.apply(this,arguments)),o)return r=null,o+""||null}return t="function"==typeof t?t:(0,w.Z)(t||f),e="function"==typeof e?e:(0,w.Z)(void 0===e?64:+e),o.type=function(e){return arguments.length?(t="function"==typeof e?e:(0,w.Z)(e),o):t},o.size=function(t){return arguments.length?(e="function"==typeof t?t:(0,w.Z)(+t),o):e},o.context=function(t){return arguments.length?(r=null==t?null:t,o):r},o})().type(e).size(C(u,l,o))())})):null};N.registerSymbol=function(t,e){_["symbol".concat(i()(t))]=e}},11638:function(t,e,r){"use strict";r.d(e,{bn:function(){return C},a3:function(){return z},lT:function(){return N},V$:function(){return D},w7:function(){return I}});var n=r(2265),o=r(86757),i=r.n(o),a=r(90231),u=r.n(a),c=r(24342),l=r.n(c),s=r(21652),f=r.n(s),p=r(73649),h=r(61994),d=r(84735),y=r(82944);function v(t){return(v="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function m(){return(m=Object.assign?Object.assign.bind():function(t){for(var e=1;et.length)&&(e=t.length);for(var r=0,n=Array(e);r0,from:{upperWidth:0,lowerWidth:0,height:p,x:c,y:l},to:{upperWidth:s,lowerWidth:f,height:p,x:c,y:l},duration:j,animationEasing:g,isActive:P},function(t){var e=t.upperWidth,i=t.lowerWidth,u=t.height,c=t.x,l=t.y;return n.createElement(d.ZP,{canBegin:a>0,from:"0px ".concat(-1===a?1:a,"px"),to:"".concat(a,"px 0px"),attributeName:"strokeDasharray",begin:S,duration:j,easing:g},n.createElement("path",m({},(0,y.L6)(r,!0),{className:E,d:w(c,l,e,i,u),ref:o})))}):n.createElement("g",null,n.createElement("path",m({},(0,y.L6)(r,!0),{className:E,d:w(c,l,s,f,p)})))},S=r(60474),P=r(9841),E=r(14870),k=["option","shapeType","propTransformer","activeClassName","isActive"];function A(t){return(A="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function M(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,n)}return r}function _(t){for(var e=1;e=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}(t,k);if((0,n.isValidElement)(r))e=(0,n.cloneElement)(r,_(_({},f),(0,n.isValidElement)(r)?r.props:r));else if(i()(r))e=r(f);else if(u()(r)&&!l()(r)){var p=(void 0===a?function(t,e){return _(_({},e),t)}:a)(r,f);e=n.createElement(T,{shapeType:o,elementProps:p})}else e=n.createElement(T,{shapeType:o,elementProps:f});return s?n.createElement(P.m,{className:void 0===c?"recharts-active-shape":c},e):e}function N(t,e){return null!=e&&"trapezoids"in t.props}function D(t,e){return null!=e&&"sectors"in t.props}function I(t,e){return null!=e&&"points"in t.props}function L(t,e){var r,n,o=t.x===(null==e||null===(r=e.labelViewBox)||void 0===r?void 0:r.x)||t.x===e.x,i=t.y===(null==e||null===(n=e.labelViewBox)||void 0===n?void 0:n.y)||t.y===e.y;return o&&i}function B(t,e){var r=t.endAngle===e.endAngle,n=t.startAngle===e.startAngle;return r&&n}function R(t,e){var r=t.x===e.x,n=t.y===e.y,o=t.z===e.z;return r&&n&&o}function z(t){var e,r,n,o=t.activeTooltipItem,i=t.graphicalItem,a=t.itemData,u=(N(i,o)?e="trapezoids":D(i,o)?e="sectors":I(i,o)&&(e="points"),e),c=N(i,o)?null===(r=o.tooltipPayload)||void 0===r||null===(r=r[0])||void 0===r||null===(r=r.payload)||void 0===r?void 0:r.payload:D(i,o)?null===(n=o.tooltipPayload)||void 0===n||null===(n=n[0])||void 0===n||null===(n=n.payload)||void 0===n?void 0:n.payload:I(i,o)?o.payload:{},l=a.filter(function(t,e){var r=f()(c,t),n=i.props[u].filter(function(t){var e;return(N(i,o)?e=L:D(i,o)?e=B:I(i,o)&&(e=R),e)(t,o)}),a=i.props[u].indexOf(n[n.length-1]);return r&&e===a});return a.indexOf(l[l.length-1])}},25311:function(t,e,r){"use strict";r.d(e,{Ky:function(){return w},O1:function(){return b},_b:function(){return g},t9:function(){return m},xE:function(){return O}});var n=r(41443),o=r.n(n),i=r(32242),a=r.n(i),u=r(85355),c=r(82944),l=r(16630),s=r(31699);function f(t){return(f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function p(t,e){for(var r=0;r0&&(A=Math.min((t||0)-(M[e-1]||0),A))}),Number.isFinite(A)){var _=A/k,T="vertical"===g.layout?r.height:r.width;if("gap"===g.padding&&(c=_*T/2),"no-gap"===g.padding){var C=(0,l.h1)(t.barCategoryGap,_*T),N=_*T/2;c=N-C-(N-C)/T*C}}}s="xAxis"===n?[r.left+(j.left||0)+(c||0),r.left+r.width-(j.right||0)-(c||0)]:"yAxis"===n?"horizontal"===f?[r.top+r.height-(j.bottom||0),r.top+(j.top||0)]:[r.top+(j.top||0)+(c||0),r.top+r.height-(j.bottom||0)-(c||0)]:g.range,P&&(s=[s[1],s[0]]);var D=(0,u.Hq)(g,o,m),I=D.scale,L=D.realScaleType;I.domain(w).range(s),(0,u.zF)(I);var B=(0,u.g$)(I,d(d({},g),{},{realScaleType:L}));"xAxis"===n?(b="top"===x&&!S||"bottom"===x&&S,p=r.left,h=v[E]-b*g.height):"yAxis"===n&&(b="left"===x&&!S||"right"===x&&S,p=v[E]-b*g.width,h=r.top);var R=d(d(d({},g),B),{},{realScaleType:L,x:p,y:h,scale:I,width:"xAxis"===n?r.width:g.width,height:"yAxis"===n?r.height:g.height});return R.bandSize=(0,u.zT)(R,B),g.hide||"xAxis"!==n?g.hide||(v[E]+=(b?-1:1)*R.width):v[E]+=(b?-1:1)*R.height,d(d({},i),{},y({},a,R))},{})},b=function(t,e){var r=t.x,n=t.y,o=e.x,i=e.y;return{x:Math.min(r,o),y:Math.min(n,i),width:Math.abs(o-r),height:Math.abs(i-n)}},g=function(t){return b({x:t.x1,y:t.y1},{x:t.x2,y:t.y2})},x=function(){var t,e;function r(t){!function(t,e){if(!(t instanceof e))throw TypeError("Cannot call a class as a function")}(this,r),this.scale=t}return t=[{key:"domain",get:function(){return this.scale.domain}},{key:"range",get:function(){return this.scale.range}},{key:"rangeMin",get:function(){return this.range()[0]}},{key:"rangeMax",get:function(){return this.range()[1]}},{key:"bandwidth",get:function(){return this.scale.bandwidth}},{key:"apply",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=e.bandAware,n=e.position;if(void 0!==t){if(n)switch(n){case"start":default:return this.scale(t);case"middle":var o=this.bandwidth?this.bandwidth()/2:0;return this.scale(t)+o;case"end":var i=this.bandwidth?this.bandwidth():0;return this.scale(t)+i}if(r){var a=this.bandwidth?this.bandwidth()/2:0;return this.scale(t)+a}return this.scale(t)}}},{key:"isInRange",value:function(t){var e=this.range(),r=e[0],n=e[e.length-1];return r<=n?t>=r&&t<=n:t>=n&&t<=r}}],e=[{key:"create",value:function(t){return new r(t)}}],t&&p(r.prototype,t),e&&p(r,e),Object.defineProperty(r,"prototype",{writable:!1}),r}();y(x,"EPS",1e-4);var w=function(t){var e=Object.keys(t).reduce(function(e,r){return d(d({},e),{},y({},r,x.create(t[r])))},{});return d(d({},e),{},{apply:function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=r.bandAware,i=r.position;return o()(t,function(t,r){return e[r].apply(t,{bandAware:n,position:i})})},isInRange:function(t){return a()(t,function(t,r){return e[r].isInRange(t)})}})},O=function(t){var e=t.width,r=t.height,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,o=(n%180+180)%180*Math.PI/180,i=Math.atan(r/e);return Math.abs(o>i&&otx(e,t()).base(e.base()),tj.o.apply(e,arguments),e}},scaleOrdinal:function(){return tX.Z},scalePoint:function(){return f.x},scalePow:function(){return tJ},scaleQuantile:function(){return function t(){var e,r=[],n=[],o=[];function i(){var t=0,e=Math.max(1,n.length);for(o=Array(e-1);++t=1)return+r(t[n-1],n-1,t);var n,o=(n-1)*e,i=Math.floor(o),a=+r(t[i],i,t);return a+(+r(t[i+1],i+1,t)-a)*(o-i)}}(r,t/e);return a}function a(t){return null==t||isNaN(t=+t)?e:n[P(o,t)]}return a.invertExtent=function(t){var e=n.indexOf(t);return e<0?[NaN,NaN]:[e>0?o[e-1]:r[0],e=o?[i[o-1],n]:[i[e-1],i[e]]},u.unknown=function(t){return arguments.length&&(e=t),u},u.thresholds=function(){return i.slice()},u.copy=function(){return t().domain([r,n]).range(a).unknown(e)},tj.o.apply(tI(u),arguments)}},scaleRadial:function(){return function t(){var e,r=tO(),n=[0,1],o=!1;function i(t){var n,i=Math.sign(n=r(t))*Math.sqrt(Math.abs(n));return isNaN(i)?e:o?Math.round(i):i}return i.invert=function(t){return r.invert(t1(t))},i.domain=function(t){return arguments.length?(r.domain(t),i):r.domain()},i.range=function(t){return arguments.length?(r.range((n=Array.from(t,td)).map(t1)),i):n.slice()},i.rangeRound=function(t){return i.range(t).round(!0)},i.round=function(t){return arguments.length?(o=!!t,i):o},i.clamp=function(t){return arguments.length?(r.clamp(t),i):r.clamp()},i.unknown=function(t){return arguments.length?(e=t,i):e},i.copy=function(){return t(r.domain(),n).round(o).clamp(r.clamp()).unknown(e)},tj.o.apply(i,arguments),tI(i)}},scaleSequential:function(){return function t(){var e=tI(rX()(tv));return e.copy=function(){return rG(e,t())},tj.O.apply(e,arguments)}},scaleSequentialLog:function(){return function t(){var e=tZ(rX()).domain([1,10]);return e.copy=function(){return rG(e,t()).base(e.base())},tj.O.apply(e,arguments)}},scaleSequentialPow:function(){return rV},scaleSequentialQuantile:function(){return function t(){var e=[],r=tv;function n(t){if(null!=t&&!isNaN(t=+t))return r((P(e,t,1)-1)/(e.length-1))}return n.domain=function(t){if(!arguments.length)return e.slice();for(let r of(e=[],t))null==r||isNaN(r=+r)||e.push(r);return e.sort(g),n},n.interpolator=function(t){return arguments.length?(r=t,n):r},n.range=function(){return e.map((t,n)=>r(n/(e.length-1)))},n.quantiles=function(t){return Array.from({length:t+1},(r,n)=>(function(t,e,r){if(!(!(n=(t=Float64Array.from(function*(t,e){if(void 0===e)for(let e of t)null!=e&&(e=+e)>=e&&(yield e);else{let r=-1;for(let n of t)null!=(n=e(n,++r,t))&&(n=+n)>=n&&(yield n)}}(t,void 0))).length)||isNaN(e=+e))){if(e<=0||n<2)return t5(t);if(e>=1)return t2(t);var n,o=(n-1)*e,i=Math.floor(o),a=t2((function t(e,r,n=0,o=1/0,i){if(r=Math.floor(r),n=Math.floor(Math.max(0,n)),o=Math.floor(Math.min(e.length-1,o)),!(n<=r&&r<=o))return e;for(i=void 0===i?t6:function(t=g){if(t===g)return t6;if("function"!=typeof t)throw TypeError("compare is not a function");return(e,r)=>{let n=t(e,r);return n||0===n?n:(0===t(r,r))-(0===t(e,e))}}(i);o>n;){if(o-n>600){let a=o-n+1,u=r-n+1,c=Math.log(a),l=.5*Math.exp(2*c/3),s=.5*Math.sqrt(c*l*(a-l)/a)*(u-a/2<0?-1:1),f=Math.max(n,Math.floor(r-u*l/a+s)),p=Math.min(o,Math.floor(r+(a-u)*l/a+s));t(e,r,f,p,i)}let a=e[r],u=n,c=o;for(t3(e,n,r),i(e[o],a)>0&&t3(e,n,o);ui(e[u],a);)++u;for(;i(e[c],a)>0;)--c}0===i(e[n],a)?t3(e,n,c):t3(e,++c,o),c<=r&&(n=c+1),r<=c&&(o=c-1)}return e})(t,i).subarray(0,i+1));return a+(t5(t.subarray(i+1))-a)*(o-i)}})(e,n/t))},n.copy=function(){return t(r).domain(e)},tj.O.apply(n,arguments)}},scaleSequentialSqrt:function(){return rK},scaleSequentialSymlog:function(){return function t(){var e=tH(rX());return e.copy=function(){return rG(e,t()).constant(e.constant())},tj.O.apply(e,arguments)}},scaleSqrt:function(){return t0},scaleSymlog:function(){return function t(){var e=tH(tw());return e.copy=function(){return tx(e,t()).constant(e.constant())},tj.o.apply(e,arguments)}},scaleThreshold:function(){return function t(){var e,r=[.5],n=[0,1],o=1;function i(t){return null!=t&&t<=t?n[P(r,t,0,o)]:e}return i.domain=function(t){return arguments.length?(o=Math.min((r=Array.from(t)).length,n.length-1),i):r.slice()},i.range=function(t){return arguments.length?(n=Array.from(t),o=Math.min(r.length,n.length-1),i):n.slice()},i.invertExtent=function(t){var e=n.indexOf(t);return[r[e-1],r[e]]},i.unknown=function(t){return arguments.length?(e=t,i):e},i.copy=function(){return t().domain(r).range(n).unknown(e)},tj.o.apply(i,arguments)}},scaleTime:function(){return rY},scaleUtc:function(){return rH},tickFormat:function(){return tD}});var f=r(55284);let p=Math.sqrt(50),h=Math.sqrt(10),d=Math.sqrt(2);function y(t,e,r){let n,o,i;let a=(e-t)/Math.max(0,r),u=Math.floor(Math.log10(a)),c=a/Math.pow(10,u),l=c>=p?10:c>=h?5:c>=d?2:1;return(u<0?(n=Math.round(t*(i=Math.pow(10,-u)/l)),o=Math.round(e*i),n/ie&&--o,i=-i):(n=Math.round(t/(i=Math.pow(10,u)*l)),o=Math.round(e/i),n*ie&&--o),o0))return[];if(t===e)return[t];let n=e=o))return[];let u=i-o+1,c=Array(u);if(n){if(a<0)for(let t=0;te?1:t>=e?0:NaN}function x(t,e){return null==t||null==e?NaN:et?1:e>=t?0:NaN}function w(t){let e,r,n;function o(t,n,o=0,i=t.length){if(o>>1;0>r(t[e],n)?o=e+1:i=e}while(og(t(e),r),n=(e,r)=>t(e)-r):(e=t===g||t===x?t:O,r=t,n=t),{left:o,center:function(t,e,r=0,i=t.length){let a=o(t,e,r,i-1);return a>r&&n(t[a-1],e)>-n(t[a],e)?a-1:a},right:function(t,n,o=0,i=t.length){if(o>>1;0>=r(t[e],n)?o=e+1:i=e}while(o>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):8===r?Z(e>>24&255,e>>16&255,e>>8&255,(255&e)/255):4===r?Z(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|240&e,((15&e)<<4|15&e)/255):null):(e=N.exec(t))?new Y(e[1],e[2],e[3],1):(e=D.exec(t))?new Y(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=I.exec(t))?Z(e[1],e[2],e[3],e[4]):(e=L.exec(t))?Z(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=B.exec(t))?Q(e[1],e[2]/100,e[3]/100,1):(e=R.exec(t))?Q(e[1],e[2]/100,e[3]/100,e[4]):z.hasOwnProperty(t)?q(z[t]):"transparent"===t?new Y(NaN,NaN,NaN,0):null}function q(t){return new Y(t>>16&255,t>>8&255,255&t,1)}function Z(t,e,r,n){return n<=0&&(t=e=r=NaN),new Y(t,e,r,n)}function W(t,e,r,n){var o;return 1==arguments.length?((o=t)instanceof A||(o=$(o)),o)?new Y((o=o.rgb()).r,o.g,o.b,o.opacity):new Y:new Y(t,e,r,null==n?1:n)}function Y(t,e,r,n){this.r=+t,this.g=+e,this.b=+r,this.opacity=+n}function H(){return`#${K(this.r)}${K(this.g)}${K(this.b)}`}function X(){let t=G(this.opacity);return`${1===t?"rgb(":"rgba("}${V(this.r)}, ${V(this.g)}, ${V(this.b)}${1===t?")":`, ${t})`}`}function G(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function V(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function K(t){return((t=V(t))<16?"0":"")+t.toString(16)}function Q(t,e,r,n){return n<=0?t=e=r=NaN:r<=0||r>=1?t=e=NaN:e<=0&&(t=NaN),new tt(t,e,r,n)}function J(t){if(t instanceof tt)return new tt(t.h,t.s,t.l,t.opacity);if(t instanceof A||(t=$(t)),!t)return new tt;if(t instanceof tt)return t;var e=(t=t.rgb()).r/255,r=t.g/255,n=t.b/255,o=Math.min(e,r,n),i=Math.max(e,r,n),a=NaN,u=i-o,c=(i+o)/2;return u?(a=e===i?(r-n)/u+(r0&&c<1?0:a,new tt(a,u,c,t.opacity)}function tt(t,e,r,n){this.h=+t,this.s=+e,this.l=+r,this.opacity=+n}function te(t){return(t=(t||0)%360)<0?t+360:t}function tr(t){return Math.max(0,Math.min(1,t||0))}function tn(t,e,r){return(t<60?e+(r-e)*t/60:t<180?r:t<240?e+(r-e)*(240-t)/60:e)*255}function to(t,e,r,n,o){var i=t*t,a=i*t;return((1-3*t+3*i-a)*e+(4-6*i+3*a)*r+(1+3*t+3*i-3*a)*n+a*o)/6}E(A,$,{copy(t){return Object.assign(new this.constructor,this,t)},displayable(){return this.rgb().displayable()},hex:U,formatHex:U,formatHex8:function(){return this.rgb().formatHex8()},formatHsl:function(){return J(this).formatHsl()},formatRgb:F,toString:F}),E(Y,W,k(A,{brighter(t){return t=null==t?1.4285714285714286:Math.pow(1.4285714285714286,t),new Y(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=null==t?.7:Math.pow(.7,t),new Y(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new Y(V(this.r),V(this.g),V(this.b),G(this.opacity))},displayable(){return -.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:H,formatHex:H,formatHex8:function(){return`#${K(this.r)}${K(this.g)}${K(this.b)}${K((isNaN(this.opacity)?1:this.opacity)*255)}`},formatRgb:X,toString:X})),E(tt,function(t,e,r,n){return 1==arguments.length?J(t):new tt(t,e,r,null==n?1:n)},k(A,{brighter(t){return t=null==t?1.4285714285714286:Math.pow(1.4285714285714286,t),new tt(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=null==t?.7:Math.pow(.7,t),new tt(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+(this.h<0)*360,e=isNaN(t)||isNaN(this.s)?0:this.s,r=this.l,n=r+(r<.5?r:1-r)*e,o=2*r-n;return new Y(tn(t>=240?t-240:t+120,o,n),tn(t,o,n),tn(t<120?t+240:t-120,o,n),this.opacity)},clamp(){return new tt(te(this.h),tr(this.s),tr(this.l),G(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){let t=G(this.opacity);return`${1===t?"hsl(":"hsla("}${te(this.h)}, ${100*tr(this.s)}%, ${100*tr(this.l)}%${1===t?")":`, ${t})`}`}}));var ti=t=>()=>t;function ta(t,e){var r=e-t;return r?function(e){return t+e*r}:ti(isNaN(t)?e:t)}var tu=function t(e){var r,n=1==(r=+(r=e))?ta:function(t,e){var n,o,i;return e-t?(n=t,o=e,n=Math.pow(n,i=r),o=Math.pow(o,i)-n,i=1/i,function(t){return Math.pow(n+t*o,i)}):ti(isNaN(t)?e:t)};function o(t,e){var r=n((t=W(t)).r,(e=W(e)).r),o=n(t.g,e.g),i=n(t.b,e.b),a=ta(t.opacity,e.opacity);return function(e){return t.r=r(e),t.g=o(e),t.b=i(e),t.opacity=a(e),t+""}}return o.gamma=t,o}(1);function tc(t){return function(e){var r,n,o=e.length,i=Array(o),a=Array(o),u=Array(o);for(r=0;r=1?(r=1,e-1):Math.floor(r*e),o=t[n],i=t[n+1],a=n>0?t[n-1]:2*o-i,u=nu&&(a=e.slice(u,a),l[c]?l[c]+=a:l[++c]=a),(o=o[0])===(i=i[0])?l[c]?l[c]+=i:l[++c]=i:(l[++c]=null,s.push({i:c,x:tl(o,i)})),u=tf.lastIndex;return ue&&(r=t,t=e,e=r),l=function(r){return Math.max(t,Math.min(e,r))}),n=c>2?tg:tb,o=i=null,f}function f(e){return null==e||isNaN(e=+e)?r:(o||(o=n(a.map(t),u,c)))(t(l(e)))}return f.invert=function(r){return l(e((i||(i=n(u,a.map(t),tl)))(r)))},f.domain=function(t){return arguments.length?(a=Array.from(t,td),s()):a.slice()},f.range=function(t){return arguments.length?(u=Array.from(t),s()):u.slice()},f.rangeRound=function(t){return u=Array.from(t),c=th,s()},f.clamp=function(t){return arguments.length?(l=!!t||tv,s()):l!==tv},f.interpolate=function(t){return arguments.length?(c=t,s()):c},f.unknown=function(t){return arguments.length?(r=t,f):r},function(r,n){return t=r,e=n,s()}}function tO(){return tw()(tv,tv)}var tj=r(89999),tS=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function tP(t){var e;if(!(e=tS.exec(t)))throw Error("invalid format: "+t);return new tE({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}function tE(t){this.fill=void 0===t.fill?" ":t.fill+"",this.align=void 0===t.align?">":t.align+"",this.sign=void 0===t.sign?"-":t.sign+"",this.symbol=void 0===t.symbol?"":t.symbol+"",this.zero=!!t.zero,this.width=void 0===t.width?void 0:+t.width,this.comma=!!t.comma,this.precision=void 0===t.precision?void 0:+t.precision,this.trim=!!t.trim,this.type=void 0===t.type?"":t.type+""}function tk(t,e){if((r=(t=e?t.toExponential(e-1):t.toExponential()).indexOf("e"))<0)return null;var r,n=t.slice(0,r);return[n.length>1?n[0]+n.slice(2):n,+t.slice(r+1)]}function tA(t){return(t=tk(Math.abs(t)))?t[1]:NaN}function tM(t,e){var r=tk(t,e);if(!r)return t+"";var n=r[0],o=r[1];return o<0?"0."+Array(-o).join("0")+n:n.length>o+1?n.slice(0,o+1)+"."+n.slice(o+1):n+Array(o-n.length+2).join("0")}tP.prototype=tE.prototype,tE.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};var t_={"%":(t,e)=>(100*t).toFixed(e),b:t=>Math.round(t).toString(2),c:t=>t+"",d:function(t){return Math.abs(t=Math.round(t))>=1e21?t.toLocaleString("en").replace(/,/g,""):t.toString(10)},e:(t,e)=>t.toExponential(e),f:(t,e)=>t.toFixed(e),g:(t,e)=>t.toPrecision(e),o:t=>Math.round(t).toString(8),p:(t,e)=>tM(100*t,e),r:tM,s:function(t,e){var r=tk(t,e);if(!r)return t+"";var o=r[0],i=r[1],a=i-(n=3*Math.max(-8,Math.min(8,Math.floor(i/3))))+1,u=o.length;return a===u?o:a>u?o+Array(a-u+1).join("0"):a>0?o.slice(0,a)+"."+o.slice(a):"0."+Array(1-a).join("0")+tk(t,Math.max(0,e+a-1))[0]},X:t=>Math.round(t).toString(16).toUpperCase(),x:t=>Math.round(t).toString(16)};function tT(t){return t}var tC=Array.prototype.map,tN=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"];function tD(t,e,r,n){var o,u,c=b(t,e,r);switch((n=tP(null==n?",f":n)).type){case"s":var l=Math.max(Math.abs(t),Math.abs(e));return null!=n.precision||isNaN(u=Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(tA(l)/3)))-tA(Math.abs(c))))||(n.precision=u),a(n,l);case"":case"e":case"g":case"p":case"r":null!=n.precision||isNaN(u=Math.max(0,tA(Math.abs(Math.max(Math.abs(t),Math.abs(e)))-(o=Math.abs(o=c)))-tA(o))+1)||(n.precision=u-("e"===n.type));break;case"f":case"%":null!=n.precision||isNaN(u=Math.max(0,-tA(Math.abs(c))))||(n.precision=u-("%"===n.type)*2)}return i(n)}function tI(t){var e=t.domain;return t.ticks=function(t){var r=e();return v(r[0],r[r.length-1],null==t?10:t)},t.tickFormat=function(t,r){var n=e();return tD(n[0],n[n.length-1],null==t?10:t,r)},t.nice=function(r){null==r&&(r=10);var n,o,i=e(),a=0,u=i.length-1,c=i[a],l=i[u],s=10;for(l0;){if((o=m(c,l,r))===n)return i[a]=c,i[u]=l,e(i);if(o>0)c=Math.floor(c/o)*o,l=Math.ceil(l/o)*o;else if(o<0)c=Math.ceil(c*o)/o,l=Math.floor(l*o)/o;else break;n=o}return t},t}function tL(){var t=tO();return t.copy=function(){return tx(t,tL())},tj.o.apply(t,arguments),tI(t)}function tB(t,e){t=t.slice();var r,n=0,o=t.length-1,i=t[n],a=t[o];return a-t(-e,r)}function tZ(t){let e,r;let n=t(tR,tz),o=n.domain,a=10;function u(){var i,u;return e=(i=a)===Math.E?Math.log:10===i&&Math.log10||2===i&&Math.log2||(i=Math.log(i),t=>Math.log(t)/i),r=10===(u=a)?t$:u===Math.E?Math.exp:t=>Math.pow(u,t),o()[0]<0?(e=tq(e),r=tq(r),t(tU,tF)):t(tR,tz),n}return n.base=function(t){return arguments.length?(a=+t,u()):a},n.domain=function(t){return arguments.length?(o(t),u()):o()},n.ticks=t=>{let n,i;let u=o(),c=u[0],l=u[u.length-1],s=l0){for(;f<=p;++f)for(n=1;nl)break;d.push(i)}}else for(;f<=p;++f)for(n=a-1;n>=1;--n)if(!((i=f>0?n/r(-f):n*r(f))l)break;d.push(i)}2*d.length{if(null==t&&(t=10),null==o&&(o=10===a?"s":","),"function"!=typeof o&&(a%1||null!=(o=tP(o)).precision||(o.trim=!0),o=i(o)),t===1/0)return o;let u=Math.max(1,a*t/n.ticks().length);return t=>{let n=t/r(Math.round(e(t)));return n*ao(tB(o(),{floor:t=>r(Math.floor(e(t))),ceil:t=>r(Math.ceil(e(t)))})),n}function tW(t){return function(e){return Math.sign(e)*Math.log1p(Math.abs(e/t))}}function tY(t){return function(e){return Math.sign(e)*Math.expm1(Math.abs(e))*t}}function tH(t){var e=1,r=t(tW(1),tY(e));return r.constant=function(r){return arguments.length?t(tW(e=+r),tY(e)):e},tI(r)}i=(o=function(t){var e,r,o,i=void 0===t.grouping||void 0===t.thousands?tT:(e=tC.call(t.grouping,Number),r=t.thousands+"",function(t,n){for(var o=t.length,i=[],a=0,u=e[0],c=0;o>0&&u>0&&(c+u+1>n&&(u=Math.max(1,n-c)),i.push(t.substring(o-=u,o+u)),!((c+=u+1)>n));)u=e[a=(a+1)%e.length];return i.reverse().join(r)}),a=void 0===t.currency?"":t.currency[0]+"",u=void 0===t.currency?"":t.currency[1]+"",c=void 0===t.decimal?".":t.decimal+"",l=void 0===t.numerals?tT:(o=tC.call(t.numerals,String),function(t){return t.replace(/[0-9]/g,function(t){return o[+t]})}),s=void 0===t.percent?"%":t.percent+"",f=void 0===t.minus?"−":t.minus+"",p=void 0===t.nan?"NaN":t.nan+"";function h(t){var e=(t=tP(t)).fill,r=t.align,o=t.sign,h=t.symbol,d=t.zero,y=t.width,v=t.comma,m=t.precision,b=t.trim,g=t.type;"n"===g?(v=!0,g="g"):t_[g]||(void 0===m&&(m=12),b=!0,g="g"),(d||"0"===e&&"="===r)&&(d=!0,e="0",r="=");var x="$"===h?a:"#"===h&&/[boxX]/.test(g)?"0"+g.toLowerCase():"",w="$"===h?u:/[%p]/.test(g)?s:"",O=t_[g],j=/[defgprs%]/.test(g);function S(t){var a,u,s,h=x,S=w;if("c"===g)S=O(t)+S,t="";else{var P=(t=+t)<0||1/t<0;if(t=isNaN(t)?p:O(Math.abs(t),m),b&&(t=function(t){e:for(var e,r=t.length,n=1,o=-1;n0&&(o=0)}return o>0?t.slice(0,o)+t.slice(e+1):t}(t)),P&&0==+t&&"+"!==o&&(P=!1),h=(P?"("===o?o:f:"-"===o||"("===o?"":o)+h,S=("s"===g?tN[8+n/3]:"")+S+(P&&"("===o?")":""),j){for(a=-1,u=t.length;++a(s=t.charCodeAt(a))||s>57){S=(46===s?c+t.slice(a+1):t.slice(a))+S,t=t.slice(0,a);break}}}v&&!d&&(t=i(t,1/0));var E=h.length+t.length+S.length,k=E>1)+h+t+S+k.slice(E);break;default:t=k+h+t+S}return l(t)}return m=void 0===m?6:/[gprs]/.test(g)?Math.max(1,Math.min(21,m)):Math.max(0,Math.min(20,m)),S.toString=function(){return t+""},S}return{format:h,formatPrefix:function(t,e){var r=h(((t=tP(t)).type="f",t)),n=3*Math.max(-8,Math.min(8,Math.floor(tA(e)/3))),o=Math.pow(10,-n),i=tN[8+n/3];return function(t){return r(o*t)+i}}}}({thousands:",",grouping:[3],currency:["$",""]})).format,a=o.formatPrefix;var tX=r(36967);function tG(t){return function(e){return e<0?-Math.pow(-e,t):Math.pow(e,t)}}function tV(t){return t<0?-Math.sqrt(-t):Math.sqrt(t)}function tK(t){return t<0?-t*t:t*t}function tQ(t){var e=t(tv,tv),r=1;return e.exponent=function(e){return arguments.length?1==(r=+e)?t(tv,tv):.5===r?t(tV,tK):t(tG(r),tG(1/r)):r},tI(e)}function tJ(){var t=tQ(tw());return t.copy=function(){return tx(t,tJ()).exponent(t.exponent())},tj.o.apply(t,arguments),t}function t0(){return tJ.apply(null,arguments).exponent(.5)}function t1(t){return Math.sign(t)*t*t}function t2(t,e){let r;if(void 0===e)for(let e of t)null!=e&&(r=e)&&(r=e);else{let n=-1;for(let o of t)null!=(o=e(o,++n,t))&&(r=o)&&(r=o)}return r}function t5(t,e){let r;if(void 0===e)for(let e of t)null!=e&&(r>e||void 0===r&&e>=e)&&(r=e);else{let n=-1;for(let o of t)null!=(o=e(o,++n,t))&&(r>o||void 0===r&&o>=o)&&(r=o)}return r}function t6(t,e){return(null==t||!(t>=t))-(null==e||!(e>=e))||(te?1:0)}function t3(t,e,r){let n=t[e];t[e]=t[r],t[r]=n}let t7=new Date,t4=new Date;function t8(t,e,r,n){function o(e){return t(e=0==arguments.length?new Date:new Date(+e)),e}return o.floor=e=>(t(e=new Date(+e)),e),o.ceil=r=>(t(r=new Date(r-1)),e(r,1),t(r),r),o.round=t=>{let e=o(t),r=o.ceil(t);return t-e(e(t=new Date(+t),null==r?1:Math.floor(r)),t),o.range=(r,n,i)=>{let a;let u=[];if(r=o.ceil(r),i=null==i?1:Math.floor(i),!(r0))return u;do u.push(a=new Date(+r)),e(r,i),t(r);while(at8(e=>{if(e>=e)for(;t(e),!r(e);)e.setTime(e-1)},(t,n)=>{if(t>=t){if(n<0)for(;++n<=0;)for(;e(t,-1),!r(t););else for(;--n>=0;)for(;e(t,1),!r(t););}}),r&&(o.count=(e,n)=>(t7.setTime(+e),t4.setTime(+n),t(t7),t(t4),Math.floor(r(t7,t4))),o.every=t=>isFinite(t=Math.floor(t))&&t>0?t>1?o.filter(n?e=>n(e)%t==0:e=>o.count(0,e)%t==0):o:null),o}let t9=t8(()=>{},(t,e)=>{t.setTime(+t+e)},(t,e)=>e-t);t9.every=t=>isFinite(t=Math.floor(t))&&t>0?t>1?t8(e=>{e.setTime(Math.floor(e/t)*t)},(e,r)=>{e.setTime(+e+r*t)},(e,r)=>(r-e)/t):t9:null,t9.range;let et=t8(t=>{t.setTime(t-t.getMilliseconds())},(t,e)=>{t.setTime(+t+1e3*e)},(t,e)=>(e-t)/1e3,t=>t.getUTCSeconds());et.range;let ee=t8(t=>{t.setTime(t-t.getMilliseconds()-1e3*t.getSeconds())},(t,e)=>{t.setTime(+t+6e4*e)},(t,e)=>(e-t)/6e4,t=>t.getMinutes());ee.range;let er=t8(t=>{t.setUTCSeconds(0,0)},(t,e)=>{t.setTime(+t+6e4*e)},(t,e)=>(e-t)/6e4,t=>t.getUTCMinutes());er.range;let en=t8(t=>{t.setTime(t-t.getMilliseconds()-1e3*t.getSeconds()-6e4*t.getMinutes())},(t,e)=>{t.setTime(+t+36e5*e)},(t,e)=>(e-t)/36e5,t=>t.getHours());en.range;let eo=t8(t=>{t.setUTCMinutes(0,0,0)},(t,e)=>{t.setTime(+t+36e5*e)},(t,e)=>(e-t)/36e5,t=>t.getUTCHours());eo.range;let ei=t8(t=>t.setHours(0,0,0,0),(t,e)=>t.setDate(t.getDate()+e),(t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*6e4)/864e5,t=>t.getDate()-1);ei.range;let ea=t8(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/864e5,t=>t.getUTCDate()-1);ea.range;let eu=t8(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/864e5,t=>Math.floor(t/864e5));function ec(t){return t8(e=>{e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)},(t,e)=>{t.setDate(t.getDate()+7*e)},(t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*6e4)/6048e5)}eu.range;let el=ec(0),es=ec(1),ef=ec(2),ep=ec(3),eh=ec(4),ed=ec(5),ey=ec(6);function ev(t){return t8(e=>{e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+7*e)},(t,e)=>(e-t)/6048e5)}el.range,es.range,ef.range,ep.range,eh.range,ed.range,ey.range;let em=ev(0),eb=ev(1),eg=ev(2),ex=ev(3),ew=ev(4),eO=ev(5),ej=ev(6);em.range,eb.range,eg.range,ex.range,ew.range,eO.range,ej.range;let eS=t8(t=>{t.setDate(1),t.setHours(0,0,0,0)},(t,e)=>{t.setMonth(t.getMonth()+e)},(t,e)=>e.getMonth()-t.getMonth()+(e.getFullYear()-t.getFullYear())*12,t=>t.getMonth());eS.range;let eP=t8(t=>{t.setUTCDate(1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCMonth(t.getUTCMonth()+e)},(t,e)=>e.getUTCMonth()-t.getUTCMonth()+(e.getUTCFullYear()-t.getUTCFullYear())*12,t=>t.getUTCMonth());eP.range;let eE=t8(t=>{t.setMonth(0,1),t.setHours(0,0,0,0)},(t,e)=>{t.setFullYear(t.getFullYear()+e)},(t,e)=>e.getFullYear()-t.getFullYear(),t=>t.getFullYear());eE.every=t=>isFinite(t=Math.floor(t))&&t>0?t8(e=>{e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)},(e,r)=>{e.setFullYear(e.getFullYear()+r*t)}):null,eE.range;let ek=t8(t=>{t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCFullYear(t.getUTCFullYear()+e)},(t,e)=>e.getUTCFullYear()-t.getUTCFullYear(),t=>t.getUTCFullYear());function eA(t,e,r,n,o,i){let a=[[et,1,1e3],[et,5,5e3],[et,15,15e3],[et,30,3e4],[i,1,6e4],[i,5,3e5],[i,15,9e5],[i,30,18e5],[o,1,36e5],[o,3,108e5],[o,6,216e5],[o,12,432e5],[n,1,864e5],[n,2,1728e5],[r,1,6048e5],[e,1,2592e6],[e,3,7776e6],[t,1,31536e6]];function u(e,r,n){let o=Math.abs(r-e)/n,i=w(([,,t])=>t).right(a,o);if(i===a.length)return t.every(b(e/31536e6,r/31536e6,n));if(0===i)return t9.every(Math.max(b(e,r,n),1));let[u,c]=a[o/a[i-1][2]isFinite(t=Math.floor(t))&&t>0?t8(e=>{e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)},(e,r)=>{e.setUTCFullYear(e.getUTCFullYear()+r*t)}):null,ek.range;let[eM,e_]=eA(ek,eP,em,eu,eo,er),[eT,eC]=eA(eE,eS,el,ei,en,ee);function eN(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function eD(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function eI(t,e,r){return{y:t,m:e,d:r,H:0,M:0,S:0,L:0}}var eL={"-":"",_:" ",0:"0"},eB=/^\s*\d+/,eR=/^%/,ez=/[\\^$*+?|[\]().{}]/g;function eU(t,e,r){var n=t<0?"-":"",o=(n?-t:t)+"",i=o.length;return n+(i[t.toLowerCase(),e]))}function eZ(t,e,r){var n=eB.exec(e.slice(r,r+1));return n?(t.w=+n[0],r+n[0].length):-1}function eW(t,e,r){var n=eB.exec(e.slice(r,r+1));return n?(t.u=+n[0],r+n[0].length):-1}function eY(t,e,r){var n=eB.exec(e.slice(r,r+2));return n?(t.U=+n[0],r+n[0].length):-1}function eH(t,e,r){var n=eB.exec(e.slice(r,r+2));return n?(t.V=+n[0],r+n[0].length):-1}function eX(t,e,r){var n=eB.exec(e.slice(r,r+2));return n?(t.W=+n[0],r+n[0].length):-1}function eG(t,e,r){var n=eB.exec(e.slice(r,r+4));return n?(t.y=+n[0],r+n[0].length):-1}function eV(t,e,r){var n=eB.exec(e.slice(r,r+2));return n?(t.y=+n[0]+(+n[0]>68?1900:2e3),r+n[0].length):-1}function eK(t,e,r){var n=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(r,r+6));return n?(t.Z=n[1]?0:-(n[2]+(n[3]||"00")),r+n[0].length):-1}function eQ(t,e,r){var n=eB.exec(e.slice(r,r+1));return n?(t.q=3*n[0]-3,r+n[0].length):-1}function eJ(t,e,r){var n=eB.exec(e.slice(r,r+2));return n?(t.m=n[0]-1,r+n[0].length):-1}function e0(t,e,r){var n=eB.exec(e.slice(r,r+2));return n?(t.d=+n[0],r+n[0].length):-1}function e1(t,e,r){var n=eB.exec(e.slice(r,r+3));return n?(t.m=0,t.d=+n[0],r+n[0].length):-1}function e2(t,e,r){var n=eB.exec(e.slice(r,r+2));return n?(t.H=+n[0],r+n[0].length):-1}function e5(t,e,r){var n=eB.exec(e.slice(r,r+2));return n?(t.M=+n[0],r+n[0].length):-1}function e6(t,e,r){var n=eB.exec(e.slice(r,r+2));return n?(t.S=+n[0],r+n[0].length):-1}function e3(t,e,r){var n=eB.exec(e.slice(r,r+3));return n?(t.L=+n[0],r+n[0].length):-1}function e7(t,e,r){var n=eB.exec(e.slice(r,r+6));return n?(t.L=Math.floor(n[0]/1e3),r+n[0].length):-1}function e4(t,e,r){var n=eR.exec(e.slice(r,r+1));return n?r+n[0].length:-1}function e8(t,e,r){var n=eB.exec(e.slice(r));return n?(t.Q=+n[0],r+n[0].length):-1}function e9(t,e,r){var n=eB.exec(e.slice(r));return n?(t.s=+n[0],r+n[0].length):-1}function rt(t,e){return eU(t.getDate(),e,2)}function re(t,e){return eU(t.getHours(),e,2)}function rr(t,e){return eU(t.getHours()%12||12,e,2)}function rn(t,e){return eU(1+ei.count(eE(t),t),e,3)}function ro(t,e){return eU(t.getMilliseconds(),e,3)}function ri(t,e){return ro(t,e)+"000"}function ra(t,e){return eU(t.getMonth()+1,e,2)}function ru(t,e){return eU(t.getMinutes(),e,2)}function rc(t,e){return eU(t.getSeconds(),e,2)}function rl(t){var e=t.getDay();return 0===e?7:e}function rs(t,e){return eU(el.count(eE(t)-1,t),e,2)}function rf(t){var e=t.getDay();return e>=4||0===e?eh(t):eh.ceil(t)}function rp(t,e){return t=rf(t),eU(eh.count(eE(t),t)+(4===eE(t).getDay()),e,2)}function rh(t){return t.getDay()}function rd(t,e){return eU(es.count(eE(t)-1,t),e,2)}function ry(t,e){return eU(t.getFullYear()%100,e,2)}function rv(t,e){return eU((t=rf(t)).getFullYear()%100,e,2)}function rm(t,e){return eU(t.getFullYear()%1e4,e,4)}function rb(t,e){var r=t.getDay();return eU((t=r>=4||0===r?eh(t):eh.ceil(t)).getFullYear()%1e4,e,4)}function rg(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+eU(e/60|0,"0",2)+eU(e%60,"0",2)}function rx(t,e){return eU(t.getUTCDate(),e,2)}function rw(t,e){return eU(t.getUTCHours(),e,2)}function rO(t,e){return eU(t.getUTCHours()%12||12,e,2)}function rj(t,e){return eU(1+ea.count(ek(t),t),e,3)}function rS(t,e){return eU(t.getUTCMilliseconds(),e,3)}function rP(t,e){return rS(t,e)+"000"}function rE(t,e){return eU(t.getUTCMonth()+1,e,2)}function rk(t,e){return eU(t.getUTCMinutes(),e,2)}function rA(t,e){return eU(t.getUTCSeconds(),e,2)}function rM(t){var e=t.getUTCDay();return 0===e?7:e}function r_(t,e){return eU(em.count(ek(t)-1,t),e,2)}function rT(t){var e=t.getUTCDay();return e>=4||0===e?ew(t):ew.ceil(t)}function rC(t,e){return t=rT(t),eU(ew.count(ek(t),t)+(4===ek(t).getUTCDay()),e,2)}function rN(t){return t.getUTCDay()}function rD(t,e){return eU(eb.count(ek(t)-1,t),e,2)}function rI(t,e){return eU(t.getUTCFullYear()%100,e,2)}function rL(t,e){return eU((t=rT(t)).getUTCFullYear()%100,e,2)}function rB(t,e){return eU(t.getUTCFullYear()%1e4,e,4)}function rR(t,e){var r=t.getUTCDay();return eU((t=r>=4||0===r?ew(t):ew.ceil(t)).getUTCFullYear()%1e4,e,4)}function rz(){return"+0000"}function rU(){return"%"}function rF(t){return+t}function r$(t){return Math.floor(+t/1e3)}function rq(t){return new Date(t)}function rZ(t){return t instanceof Date?+t:+new Date(+t)}function rW(t,e,r,n,o,i,a,u,c,l){var s=tO(),f=s.invert,p=s.domain,h=l(".%L"),d=l(":%S"),y=l("%I:%M"),v=l("%I %p"),m=l("%a %d"),b=l("%b %d"),g=l("%B"),x=l("%Y");function w(t){return(c(t)1)for(var r,n,o,i=1,a=t[e[0]],u=a.length;i=12)]},q:function(t){return 1+~~(t.getMonth()/3)},Q:rF,s:r$,S:rc,u:rl,U:rs,V:rp,w:rh,W:rd,x:null,X:null,y:ry,Y:rm,Z:rg,"%":rU},x={a:function(t){return a[t.getUTCDay()]},A:function(t){return i[t.getUTCDay()]},b:function(t){return c[t.getUTCMonth()]},B:function(t){return u[t.getUTCMonth()]},c:null,d:rx,e:rx,f:rP,g:rL,G:rR,H:rw,I:rO,j:rj,L:rS,m:rE,M:rk,p:function(t){return o[+(t.getUTCHours()>=12)]},q:function(t){return 1+~~(t.getUTCMonth()/3)},Q:rF,s:r$,S:rA,u:rM,U:r_,V:rC,w:rN,W:rD,x:null,X:null,y:rI,Y:rB,Z:rz,"%":rU},w={a:function(t,e,r){var n=h.exec(e.slice(r));return n?(t.w=d.get(n[0].toLowerCase()),r+n[0].length):-1},A:function(t,e,r){var n=f.exec(e.slice(r));return n?(t.w=p.get(n[0].toLowerCase()),r+n[0].length):-1},b:function(t,e,r){var n=m.exec(e.slice(r));return n?(t.m=b.get(n[0].toLowerCase()),r+n[0].length):-1},B:function(t,e,r){var n=y.exec(e.slice(r));return n?(t.m=v.get(n[0].toLowerCase()),r+n[0].length):-1},c:function(t,r,n){return S(t,e,r,n)},d:e0,e:e0,f:e7,g:eV,G:eG,H:e2,I:e2,j:e1,L:e3,m:eJ,M:e5,p:function(t,e,r){var n=l.exec(e.slice(r));return n?(t.p=s.get(n[0].toLowerCase()),r+n[0].length):-1},q:eQ,Q:e8,s:e9,S:e6,u:eW,U:eY,V:eH,w:eZ,W:eX,x:function(t,e,n){return S(t,r,e,n)},X:function(t,e,r){return S(t,n,e,r)},y:eV,Y:eG,Z:eK,"%":e4};function O(t,e){return function(r){var n,o,i,a=[],u=-1,c=0,l=t.length;for(r instanceof Date||(r=new Date(+r));++u53)return null;"w"in i||(i.w=1),"Z"in i?(n=(o=(n=eD(eI(i.y,0,1))).getUTCDay())>4||0===o?eb.ceil(n):eb(n),n=ea.offset(n,(i.V-1)*7),i.y=n.getUTCFullYear(),i.m=n.getUTCMonth(),i.d=n.getUTCDate()+(i.w+6)%7):(n=(o=(n=eN(eI(i.y,0,1))).getDay())>4||0===o?es.ceil(n):es(n),n=ei.offset(n,(i.V-1)*7),i.y=n.getFullYear(),i.m=n.getMonth(),i.d=n.getDate()+(i.w+6)%7)}else("W"in i||"U"in i)&&("w"in i||(i.w="u"in i?i.u%7:"W"in i?1:0),o="Z"in i?eD(eI(i.y,0,1)).getUTCDay():eN(eI(i.y,0,1)).getDay(),i.m=0,i.d="W"in i?(i.w+6)%7+7*i.W-(o+5)%7:i.w+7*i.U-(o+6)%7);return"Z"in i?(i.H+=i.Z/100|0,i.M+=i.Z%100,eD(i)):eN(i)}}function S(t,e,r,n){for(var o,i,a=0,u=e.length,c=r.length;a=c)return -1;if(37===(o=e.charCodeAt(a++))){if(!(i=w[(o=e.charAt(a++))in eL?e.charAt(a++):o])||(n=i(t,r,n))<0)return -1}else if(o!=r.charCodeAt(n++))return -1}return n}return g.x=O(r,g),g.X=O(n,g),g.c=O(e,g),x.x=O(r,x),x.X=O(n,x),x.c=O(e,x),{format:function(t){var e=O(t+="",g);return e.toString=function(){return t},e},parse:function(t){var e=j(t+="",!1);return e.toString=function(){return t},e},utcFormat:function(t){var e=O(t+="",x);return e.toString=function(){return t},e},utcParse:function(t){var e=j(t+="",!0);return e.toString=function(){return t},e}}}({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]})).format,u.parse,l=u.utcFormat,u.utcParse;var r2=r(22516),r5=r(76115);function r6(t){for(var e=t.length,r=Array(e);--e>=0;)r[e]=e;return r}function r3(t,e){return t[e]}function r7(t){let e=[];return e.key=t,e}var r4=r(95645),r8=r.n(r4),r9=r(99008),nt=r.n(r9),ne=r(77571),nr=r.n(ne),nn=r(86757),no=r.n(nn),ni=r(42715),na=r.n(ni),nu=r(13735),nc=r.n(nu),nl=r(11314),ns=r.n(nl),nf=r(82559),np=r.n(nf),nh=r(75551),nd=r.n(nh),ny=r(21652),nv=r.n(ny),nm=r(34935),nb=r.n(nm),ng=r(61134),nx=r.n(ng);function nw(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);r=e?r.apply(void 0,o):t(e-a,nP(function(){for(var t=arguments.length,e=Array(t),n=0;nt.length)&&(e=t.length);for(var r=0,n=Array(e);rn&&(o=n,i=r),[o,i]}function nR(t,e,r){if(t.lte(0))return new(nx())(0);var n=nC.getDigitCount(t.toNumber()),o=new(nx())(10).pow(n),i=t.div(o),a=1!==n?.05:.1,u=new(nx())(Math.ceil(i.div(a).toNumber())).add(r).mul(a).mul(o);return e?u:new(nx())(Math.ceil(u))}function nz(t,e,r){var n=1,o=new(nx())(t);if(!o.isint()&&r){var i=Math.abs(t);i<1?(n=new(nx())(10).pow(nC.getDigitCount(t)-1),o=new(nx())(Math.floor(o.div(n).toNumber())).mul(n)):i>1&&(o=new(nx())(Math.floor(t)))}else 0===t?o=new(nx())(Math.floor((e-1)/2)):r||(o=new(nx())(Math.floor(t)));var a=Math.floor((e-1)/2);return nM(nA(function(t){return o.add(new(nx())(t-a).mul(n)).toNumber()}),nk)(0,e)}var nU=nT(function(t){var e=nD(t,2),r=e[0],n=e[1],o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:6,i=!(arguments.length>2)||void 0===arguments[2]||arguments[2],a=Math.max(o,2),u=nD(nB([r,n]),2),c=u[0],l=u[1];if(c===-1/0||l===1/0){var s=l===1/0?[c].concat(nN(nk(0,o-1).map(function(){return 1/0}))):[].concat(nN(nk(0,o-1).map(function(){return-1/0})),[l]);return r>n?n_(s):s}if(c===l)return nz(c,o,i);var f=function t(e,r,n,o){var i,a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0;if(!Number.isFinite((r-e)/(n-1)))return{step:new(nx())(0),tickMin:new(nx())(0),tickMax:new(nx())(0)};var u=nR(new(nx())(r).sub(e).div(n-1),o,a),c=Math.ceil((i=e<=0&&r>=0?new(nx())(0):(i=new(nx())(e).add(r).div(2)).sub(new(nx())(i).mod(u))).sub(e).div(u).toNumber()),l=Math.ceil(new(nx())(r).sub(i).div(u).toNumber()),s=c+l+1;return s>n?t(e,r,n,o,a+1):(s0?l+(n-s):l,c=r>0?c:c+(n-s)),{step:u,tickMin:i.sub(new(nx())(c).mul(u)),tickMax:i.add(new(nx())(l).mul(u))})}(c,l,a,i),p=f.step,h=f.tickMin,d=f.tickMax,y=nC.rangeStep(h,d.add(new(nx())(.1).mul(p)),p);return r>n?n_(y):y});nT(function(t){var e=nD(t,2),r=e[0],n=e[1],o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:6,i=!(arguments.length>2)||void 0===arguments[2]||arguments[2],a=Math.max(o,2),u=nD(nB([r,n]),2),c=u[0],l=u[1];if(c===-1/0||l===1/0)return[r,n];if(c===l)return nz(c,o,i);var s=nR(new(nx())(l).sub(c).div(a-1),i,0),f=nM(nA(function(t){return new(nx())(c).add(new(nx())(t).mul(s)).toNumber()}),nk)(0,a).filter(function(t){return t>=c&&t<=l});return r>n?n_(f):f});var nF=nT(function(t,e){var r=nD(t,2),n=r[0],o=r[1],i=!(arguments.length>2)||void 0===arguments[2]||arguments[2],a=nD(nB([n,o]),2),u=a[0],c=a[1];if(u===-1/0||c===1/0)return[n,o];if(u===c)return[u];var l=nR(new(nx())(c).sub(u).div(Math.max(e,2)-1),i,0),s=[].concat(nN(nC.rangeStep(new(nx())(u),new(nx())(c).sub(new(nx())(.99).mul(l)),l)),[c]);return n>o?n_(s):s}),n$=r(13137),nq=r(16630),nZ=r(82944),nW=r(38569);function nY(t){return(nY="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function nH(t){return function(t){if(Array.isArray(t))return nX(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(t){if("string"==typeof t)return nX(t,void 0);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return nX(t,void 0)}}(t)||function(){throw TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function nX(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);r1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2?arguments[2]:void 0,o=arguments.length>3?arguments[3]:void 0,i=-1,a=null!==(e=null==r?void 0:r.length)&&void 0!==e?e:0;if(a<=1)return 0;if(o&&"angleAxis"===o.axisType&&1e-6>=Math.abs(Math.abs(o.range[1]-o.range[0])-360))for(var u=o.range,c=0;c0?n[c-1].coordinate:n[a-1].coordinate,s=n[c].coordinate,f=c>=a-1?n[0].coordinate:n[c+1].coordinate,p=void 0;if((0,nq.uY)(s-l)!==(0,nq.uY)(f-s)){var h=[];if((0,nq.uY)(f-s)===(0,nq.uY)(u[1]-u[0])){p=f;var d=s+u[1]-u[0];h[0]=Math.min(d,(d+l)/2),h[1]=Math.max(d,(d+l)/2)}else{p=l;var y=f+u[1]-u[0];h[0]=Math.min(s,(y+s)/2),h[1]=Math.max(s,(y+s)/2)}var v=[Math.min(s,(p+s)/2),Math.max(s,(p+s)/2)];if(t>v[0]&&t<=v[1]||t>=h[0]&&t<=h[1]){i=n[c].index;break}}else{var m=Math.min(l,f),b=Math.max(l,f);if(t>(m+s)/2&&t<=(b+s)/2){i=n[c].index;break}}}else for(var g=0;g0&&g(r[g].coordinate+r[g-1].coordinate)/2&&t<=(r[g].coordinate+r[g+1].coordinate)/2||g===a-1&&t>(r[g].coordinate+r[g-1].coordinate)/2){i=r[g].index;break}return i},n1=function(t){var e,r,n=t.type.displayName,o=null!==(e=t.type)&&void 0!==e&&e.defaultProps?nV(nV({},t.type.defaultProps),t.props):t.props,i=o.stroke,a=o.fill;switch(n){case"Line":r=i;break;case"Area":case"Radar":r=i&&"none"!==i?i:a;break;default:r=a}return r},n2=function(t){var e=t.barSize,r=t.totalSize,n=t.stackGroups,o=void 0===n?{}:n;if(!o)return{};for(var i={},a=Object.keys(o),u=0,c=a.length;u=0});if(v&&v.length){var m=v[0].type.defaultProps,b=void 0!==m?nV(nV({},m),v[0].props):v[0].props,g=b.barSize,x=b[y];i[x]||(i[x]=[]);var w=nr()(g)?e:g;i[x].push({item:v[0],stackList:v.slice(1),barSize:nr()(w)?void 0:(0,nq.h1)(w,r,0)})}}return i},n5=function(t){var e,r=t.barGap,n=t.barCategoryGap,o=t.bandSize,i=t.sizeList,a=void 0===i?[]:i,u=t.maxBarSize,c=a.length;if(c<1)return null;var l=(0,nq.h1)(r,o,0,!0),s=[];if(a[0].barSize===+a[0].barSize){var f=!1,p=o/c,h=a.reduce(function(t,e){return t+e.barSize||0},0);(h+=(c-1)*l)>=o&&(h-=(c-1)*l,l=0),h>=o&&p>0&&(f=!0,p*=.9,h=c*p);var d={offset:((o-h)/2>>0)-l,size:0};e=a.reduce(function(t,e){var r={item:e.item,position:{offset:d.offset+d.size+l,size:f?p:e.barSize}},n=[].concat(nH(t),[r]);return d=n[n.length-1].position,e.stackList&&e.stackList.length&&e.stackList.forEach(function(t){n.push({item:t,position:d})}),n},s)}else{var y=(0,nq.h1)(n,o,0,!0);o-2*y-(c-1)*l<=0&&(l=0);var v=(o-2*y-(c-1)*l)/c;v>1&&(v>>=0);var m=u===+u?Math.min(v,u):v;e=a.reduce(function(t,e,r){var n=[].concat(nH(t),[{item:e.item,position:{offset:y+(v+l)*r+(v-m)/2,size:m}}]);return e.stackList&&e.stackList.length&&e.stackList.forEach(function(t){n.push({item:t,position:n[n.length-1].position})}),n},s)}return e},n6=function(t,e,r,n){var o=r.children,i=r.width,a=r.margin,u=i-(a.left||0)-(a.right||0),c=(0,nW.z)({children:o,legendWidth:u});if(c){var l=n||{},s=l.width,f=l.height,p=c.align,h=c.verticalAlign,d=c.layout;if(("vertical"===d||"horizontal"===d&&"middle"===h)&&"center"!==p&&(0,nq.hj)(t[p]))return nV(nV({},t),{},nK({},p,t[p]+(s||0)));if(("horizontal"===d||"vertical"===d&&"center"===p)&&"middle"!==h&&(0,nq.hj)(t[h]))return nV(nV({},t),{},nK({},h,t[h]+(f||0)))}return t},n3=function(t,e,r,n,o){var i=e.props.children,a=(0,nZ.NN)(i,n$.W).filter(function(t){var e;return e=t.props.direction,!!nr()(o)||("horizontal"===n?"yAxis"===o:"vertical"===n||"x"===e?"xAxis"===o:"y"!==e||"yAxis"===o)});if(a&&a.length){var u=a.map(function(t){return t.props.dataKey});return t.reduce(function(t,e){var n=nQ(e,r);if(nr()(n))return t;var o=Array.isArray(n)?[nt()(n),r8()(n)]:[n,n],i=u.reduce(function(t,r){var n=nQ(e,r,0),i=o[0]-Math.abs(Array.isArray(n)?n[0]:n),a=o[1]+Math.abs(Array.isArray(n)?n[1]:n);return[Math.min(i,t[0]),Math.max(a,t[1])]},[1/0,-1/0]);return[Math.min(i[0],t[0]),Math.max(i[1],t[1])]},[1/0,-1/0])}return null},n7=function(t,e,r,n,o){var i=e.map(function(e){return n3(t,e,r,o,n)}).filter(function(t){return!nr()(t)});return i&&i.length?i.reduce(function(t,e){return[Math.min(t[0],e[0]),Math.max(t[1],e[1])]},[1/0,-1/0]):null},n4=function(t,e,r,n,o){var i=e.map(function(e){var i=e.props.dataKey;return"number"===r&&i&&n3(t,e,i,n)||nJ(t,i,r,o)});if("number"===r)return i.reduce(function(t,e){return[Math.min(t[0],e[0]),Math.max(t[1],e[1])]},[1/0,-1/0]);var a={};return i.reduce(function(t,e){for(var r=0,n=e.length;r=2?2*(0,nq.uY)(a[0]-a[1])*c:c,e&&(t.ticks||t.niceTicks))?(t.ticks||t.niceTicks).map(function(t){return{coordinate:n(o?o.indexOf(t):t)+c,value:t,offset:c}}).filter(function(t){return!np()(t.coordinate)}):t.isCategorical&&t.categoricalDomain?t.categoricalDomain.map(function(t,e){return{coordinate:n(t)+c,value:t,index:e,offset:c}}):n.ticks&&!r?n.ticks(t.tickCount).map(function(t){return{coordinate:n(t)+c,value:t,offset:c}}):n.domain().map(function(t,e){return{coordinate:n(t)+c,value:o?o[t]:t,index:e,offset:c}})},oe=new WeakMap,or=function(t,e){if("function"!=typeof e)return t;oe.has(t)||oe.set(t,new WeakMap);var r=oe.get(t);if(r.has(e))return r.get(e);var n=function(){t.apply(void 0,arguments),e.apply(void 0,arguments)};return r.set(e,n),n},on=function(t,e,r){var n=t.scale,o=t.type,i=t.layout,a=t.axisType;if("auto"===n)return"radial"===i&&"radiusAxis"===a?{scale:f.Z(),realScaleType:"band"}:"radial"===i&&"angleAxis"===a?{scale:tL(),realScaleType:"linear"}:"category"===o&&e&&(e.indexOf("LineChart")>=0||e.indexOf("AreaChart")>=0||e.indexOf("ComposedChart")>=0&&!r)?{scale:f.x(),realScaleType:"point"}:"category"===o?{scale:f.Z(),realScaleType:"band"}:{scale:tL(),realScaleType:"linear"};if(na()(n)){var u="scale".concat(nd()(n));return{scale:(s[u]||f.x)(),realScaleType:s[u]?u:"point"}}return no()(n)?{scale:n}:{scale:f.x(),realScaleType:"point"}},oo=function(t){var e=t.domain();if(e&&!(e.length<=2)){var r=e.length,n=t.range(),o=Math.min(n[0],n[1])-1e-4,i=Math.max(n[0],n[1])+1e-4,a=t(e[0]),u=t(e[r-1]);(ai||ui)&&t.domain([e[0],e[r-1]])}},oi=function(t,e){if(!t)return null;for(var r=0,n=t.length;rn)&&(o[1]=n),o[0]>n&&(o[0]=n),o[1]=0?(t[a][r][0]=o,t[a][r][1]=o+u,o=t[a][r][1]):(t[a][r][0]=i,t[a][r][1]=i+u,i=t[a][r][1])}},expand:function(t,e){if((n=t.length)>0){for(var r,n,o,i=0,a=t[0].length;i0){for(var r,n=0,o=t[e[0]],i=o.length;n0&&(n=(r=t[e[0]]).length)>0){for(var r,n,o,i=0,a=1;a=0?(t[i][r][0]=o,t[i][r][1]=o+a,o=t[i][r][1]):(t[i][r][0]=0,t[i][r][1]=0)}}},oc=function(t,e,r){var n=e.map(function(t){return t.props.dataKey}),o=ou[r];return(function(){var t=(0,r5.Z)([]),e=r6,r=r1,n=r3;function o(o){var i,a,u=Array.from(t.apply(this,arguments),r7),c=u.length,l=-1;for(let t of o)for(i=0,++l;i=0?0:o<0?o:n}return r[0]},od=function(t,e){var r,n=(null!==(r=t.type)&&void 0!==r&&r.defaultProps?nV(nV({},t.type.defaultProps),t.props):t.props).stackId;if((0,nq.P2)(n)){var o=e[n];if(o){var i=o.items.indexOf(t);return i>=0?o.stackedData[i]:null}}return null},oy=function(t,e,r){return Object.keys(t).reduce(function(n,o){var i=t[o].stackedData.reduce(function(t,n){var o=n.slice(e,r+1).reduce(function(t,e){return[nt()(e.concat([t[0]]).filter(nq.hj)),r8()(e.concat([t[1]]).filter(nq.hj))]},[1/0,-1/0]);return[Math.min(t[0],o[0]),Math.max(t[1],o[1])]},[1/0,-1/0]);return[Math.min(i[0],n[0]),Math.max(i[1],n[1])]},[1/0,-1/0]).map(function(t){return t===1/0||t===-1/0?0:t})},ov=/^dataMin[\s]*-[\s]*([0-9]+([.]{1}[0-9]+){0,1})$/,om=/^dataMax[\s]*\+[\s]*([0-9]+([.]{1}[0-9]+){0,1})$/,ob=function(t,e,r){if(no()(t))return t(e,r);if(!Array.isArray(t))return e;var n=[];if((0,nq.hj)(t[0]))n[0]=r?t[0]:Math.min(t[0],e[0]);else if(ov.test(t[0])){var o=+ov.exec(t[0])[1];n[0]=e[0]-o}else no()(t[0])?n[0]=t[0](e[0]):n[0]=e[0];if((0,nq.hj)(t[1]))n[1]=r?t[1]:Math.max(t[1],e[1]);else if(om.test(t[1])){var i=+om.exec(t[1])[1];n[1]=e[1]+i}else no()(t[1])?n[1]=t[1](e[1]):n[1]=e[1];return n},og=function(t,e,r){if(t&&t.scale&&t.scale.bandwidth){var n=t.scale.bandwidth();if(!r||n>0)return n}if(t&&e&&e.length>=2){for(var o=nb()(e,function(t){return t.coordinate}),i=1/0,a=1,u=o.length;a1&&void 0!==arguments[1]?arguments[1]:{};if(null==t||n.x.isSsr)return{width:0,height:0};var o=(Object.keys(e=a({},r)).forEach(function(t){e[t]||delete e[t]}),e),i=JSON.stringify({text:t,copyStyle:o});if(u.widthCache[i])return u.widthCache[i];try{var s=document.getElementById(l);s||((s=document.createElement("span")).setAttribute("id",l),s.setAttribute("aria-hidden","true"),document.body.appendChild(s));var f=a(a({},c),o);Object.assign(s.style,f),s.textContent="".concat(t);var p=s.getBoundingClientRect(),h={width:p.width,height:p.height};return u.widthCache[i]=h,++u.cacheCount>2e3&&(u.cacheCount=0,u.widthCache={}),h}catch(t){return{width:0,height:0}}},f=function(t){return{top:t.top+window.scrollY-document.documentElement.clientTop,left:t.left+window.scrollX-document.documentElement.clientLeft}}},16630:function(t,e,r){"use strict";r.d(e,{Ap:function(){return S},EL:function(){return g},Kt:function(){return w},P2:function(){return m},Rw:function(){return v},bv:function(){return O},fC:function(){return P},h1:function(){return x},hU:function(){return d},hj:function(){return y},k4:function(){return j},uY:function(){return h}});var n=r(42715),o=r.n(n),i=r(82559),a=r.n(i),u=r(13735),c=r.n(u),l=r(22345),s=r.n(l),f=r(77571),p=r.n(f),h=function(t){return 0===t?0:t>0?1:-1},d=function(t){return o()(t)&&t.indexOf("%")===t.length-1},y=function(t){return s()(t)&&!a()(t)},v=function(t){return p()(t)},m=function(t){return y(t)||o()(t)},b=0,g=function(t){var e=++b;return"".concat(t||"").concat(e)},x=function(t,e){var r,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,i=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(!y(t)&&!o()(t))return n;if(d(t)){var u=t.indexOf("%");r=e*parseFloat(t.slice(0,u))/100}else r=+t;return a()(r)&&(r=n),i&&r>e&&(r=e),r},w=function(t){if(!t)return null;var e=Object.keys(t);return e&&e.length?t[e[0]]:null},O=function(t){if(!Array.isArray(t))return!1;for(var e=t.length,r={},n=0;n2?r-2:0),o=2;ot.length)&&(e=t.length);for(var r=0,n=Array(e);r2&&void 0!==arguments[2]?arguments[2]:{top:0,right:0,bottom:0,left:0};return Math.min(Math.abs(t-(r.left||0)-(r.right||0)),Math.abs(e-(r.top||0)-(r.bottom||0)))/2},b=function(t,e,r,n,i){var a=t.width,u=t.height,s=t.startAngle,f=t.endAngle,y=(0,c.h1)(t.cx,a,a/2),v=(0,c.h1)(t.cy,u,u/2),b=m(a,u,r),g=(0,c.h1)(t.innerRadius,b,0),x=(0,c.h1)(t.outerRadius,b,.8*b);return Object.keys(e).reduce(function(t,r){var a,u=e[r],c=u.domain,m=u.reversed;if(o()(u.range))"angleAxis"===n?a=[s,f]:"radiusAxis"===n&&(a=[g,x]),m&&(a=[a[1],a[0]]);else{var b,w=function(t){if(Array.isArray(t))return t}(b=a=u.range)||function(t,e){var r=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=r){var n,o,i,a,u=[],c=!0,l=!1;try{for(i=(r=r.call(t)).next;!(c=(n=i.call(r)).done)&&(u.push(n.value),2!==u.length);c=!0);}catch(t){l=!0,o=t}finally{try{if(!c&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(l)throw o}}return u}}(b,2)||function(t,e){if(t){if("string"==typeof t)return d(t,2);var r=Object.prototype.toString.call(t).slice(8,-1);if("Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return d(t,2)}}(b,2)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}();s=w[0],f=w[1]}var O=(0,l.Hq)(u,i),j=O.realScaleType,S=O.scale;S.domain(c).range(a),(0,l.zF)(S);var P=(0,l.g$)(S,p(p({},u),{},{realScaleType:j})),E=p(p(p({},u),P),{},{range:a,radius:x,realScaleType:j,scale:S,cx:y,cy:v,innerRadius:g,outerRadius:x,startAngle:s,endAngle:f});return p(p({},t),{},h({},r,E))},{})},g=function(t,e){var r=t.x,n=t.y;return Math.sqrt(Math.pow(r-e.x,2)+Math.pow(n-e.y,2))},x=function(t,e){var r=t.x,n=t.y,o=e.cx,i=e.cy,a=g({x:r,y:n},{x:o,y:i});if(a<=0)return{radius:a};var u=Math.acos((r-o)/a);return n>i&&(u=2*Math.PI-u),{radius:a,angle:180*u/Math.PI,angleInRadian:u}},w=function(t){var e=t.startAngle,r=t.endAngle,n=Math.min(Math.floor(e/360),Math.floor(r/360));return{startAngle:e-360*n,endAngle:r-360*n}},O=function(t,e){var r,n=x({x:t.x,y:t.y},e),o=n.radius,i=n.angle,a=e.innerRadius,u=e.outerRadius;if(ou)return!1;if(0===o)return!0;var c=w(e),l=c.startAngle,s=c.endAngle,f=i;if(l<=s){for(;f>s;)f-=360;for(;f=l&&f<=s}else{for(;f>l;)f-=360;for(;f=s&&f<=l}return r?p(p({},e),{},{radius:o,angle:f+360*Math.min(Math.floor(e.startAngle/360),Math.floor(e.endAngle/360))}):null},j=function(t){return(0,i.isValidElement)(t)||u()(t)||"boolean"==typeof t?"":t.className}},82944:function(t,e,r){"use strict";r.d(e,{$R:function(){return R},Bh:function(){return B},Gf:function(){return j},L6:function(){return N},NN:function(){return k},TT:function(){return M},eu:function(){return L},jf:function(){return T},rL:function(){return D},sP:function(){return A}});var n=r(13735),o=r.n(n),i=r(77571),a=r.n(i),u=r(42715),c=r.n(u),l=r(86757),s=r.n(l),f=r(28302),p=r.n(f),h=r(2265),d=r(14326),y=r(16630),v=r(46485),m=r(41637),b=["children"],g=["children"];function x(t,e){if(null==t)return{};var r,n,o=function(t,e){if(null==t)return{};var r={};for(var n in t)if(Object.prototype.hasOwnProperty.call(t,n)){if(e.indexOf(n)>=0)continue;r[n]=t[n]}return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}function w(t){return(w="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var O={click:"onClick",mousedown:"onMouseDown",mouseup:"onMouseUp",mouseover:"onMouseOver",mousemove:"onMouseMove",mouseout:"onMouseOut",mouseenter:"onMouseEnter",mouseleave:"onMouseLeave",touchcancel:"onTouchCancel",touchend:"onTouchEnd",touchmove:"onTouchMove",touchstart:"onTouchStart",contextmenu:"onContextMenu",dblclick:"onDoubleClick"},j=function(t){return"string"==typeof t?t:t?t.displayName||t.name||"Component":""},S=null,P=null,E=function t(e){if(e===S&&Array.isArray(P))return P;var r=[];return h.Children.forEach(e,function(e){a()(e)||((0,d.isFragment)(e)?r=r.concat(t(e.props.children)):r.push(e))}),P=r,S=e,r};function k(t,e){var r=[],n=[];return n=Array.isArray(e)?e.map(function(t){return j(t)}):[j(e)],E(t).forEach(function(t){var e=o()(t,"type.displayName")||o()(t,"type.name");-1!==n.indexOf(e)&&r.push(t)}),r}function A(t,e){var r=k(t,e);return r&&r[0]}var M=function(t){if(!t||!t.props)return!1;var e=t.props,r=e.width,n=e.height;return!!(0,y.hj)(r)&&!(r<=0)&&!!(0,y.hj)(n)&&!(n<=0)},_=["a","altGlyph","altGlyphDef","altGlyphItem","animate","animateColor","animateMotion","animateTransform","circle","clipPath","color-profile","cursor","defs","desc","ellipse","feBlend","feColormatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","filter","font","font-face","font-face-format","font-face-name","font-face-url","foreignObject","g","glyph","glyphRef","hkern","image","line","lineGradient","marker","mask","metadata","missing-glyph","mpath","path","pattern","polygon","polyline","radialGradient","rect","script","set","stop","style","svg","switch","symbol","text","textPath","title","tref","tspan","use","view","vkern"],T=function(t){return t&&"object"===w(t)&&"clipDot"in t},C=function(t,e,r,n){var o,i=null!==(o=null===m.ry||void 0===m.ry?void 0:m.ry[n])&&void 0!==o?o:[];return e.startsWith("data-")||!s()(t)&&(n&&i.includes(e)||m.Yh.includes(e))||r&&m.nv.includes(e)},N=function(t,e,r){if(!t||"function"==typeof t||"boolean"==typeof t)return null;var n=t;if((0,h.isValidElement)(t)&&(n=t.props),!p()(n))return null;var o={};return Object.keys(n).forEach(function(t){var i;C(null===(i=n)||void 0===i?void 0:i[t],t,e,r)&&(o[t]=n[t])}),o},D=function t(e,r){if(e===r)return!0;var n=h.Children.count(e);if(n!==h.Children.count(r))return!1;if(0===n)return!0;if(1===n)return I(Array.isArray(e)?e[0]:e,Array.isArray(r)?r[0]:r);for(var o=0;o=0)r.push(t);else if(t){var i=j(t.type),a=e[i]||{},u=a.handler,l=a.once;if(u&&(!l||!n[i])){var s=u(t,i,o);r.push(s),n[i]=!0}}}),r},B=function(t){var e=t&&t.type;return e&&O[e]?O[e]:null},R=function(t,e){return E(e).indexOf(t)}},46485:function(t,e,r){"use strict";function n(t,e){for(var r in t)if(({}).hasOwnProperty.call(t,r)&&(!({}).hasOwnProperty.call(e,r)||t[r]!==e[r]))return!1;for(var n in e)if(({}).hasOwnProperty.call(e,n)&&!({}).hasOwnProperty.call(t,n))return!1;return!0}r.d(e,{w:function(){return n}})},38569:function(t,e,r){"use strict";r.d(e,{z:function(){return l}});var n=r(22190),o=r(85355),i=r(82944);function a(t){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function u(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,n)}return r}function c(t){for(var e=1;e=0))throw Error(`invalid digits: ${t}`);if(e>15)return a;let r=10**e;return function(t){this._+=t[0];for(let e=1,n=t.length;e1e-6){if(Math.abs(f*c-l*s)>1e-6&&i){let h=r-a,d=o-u,y=c*c+l*l,v=Math.sqrt(y),m=Math.sqrt(p),b=i*Math.tan((n-Math.acos((y+p-(h*h+d*d))/(2*v*m)))/2),g=b/m,x=b/v;Math.abs(g-1)>1e-6&&this._append`L${t+g*s},${e+g*f}`,this._append`A${i},${i},0,0,${+(f*h>s*d)},${this._x1=t+x*c},${this._y1=e+x*l}`}else this._append`L${this._x1=t},${this._y1=e}`}}arc(t,e,r,a,u,c){if(t=+t,e=+e,c=!!c,(r=+r)<0)throw Error(`negative radius: ${r}`);let l=r*Math.cos(a),s=r*Math.sin(a),f=t+l,p=e+s,h=1^c,d=c?a-u:u-a;null===this._x1?this._append`M${f},${p}`:(Math.abs(this._x1-f)>1e-6||Math.abs(this._y1-p)>1e-6)&&this._append`L${f},${p}`,r&&(d<0&&(d=d%o+o),d>i?this._append`A${r},${r},0,1,${h},${t-l},${e-s}A${r},${r},0,1,${h},${this._x1=f},${this._y1=p}`:d>1e-6&&this._append`A${r},${r},0,${+(d>=n)},${h},${this._x1=t+r*Math.cos(u)},${this._y1=e+r*Math.sin(u)}`)}rect(t,e,r,n){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+e}h${r=+r}v${+n}h${-r}Z`}toString(){return this._}}function c(t){let e=3;return t.digits=function(r){if(!arguments.length)return e;if(null==r)e=null;else{let t=Math.floor(r);if(!(t>=0))throw RangeError(`invalid digits: ${r}`);e=t}return t},()=>new u(e)}u.prototype},59121:function(t,e,r){"use strict";r.d(e,{E:function(){return i}});var n=r(99649),o=r(63497);function i(t,e){let r=(0,n.Q)(t);return isNaN(e)?(0,o.L)(t,NaN):(e&&r.setDate(r.getDate()+e),r)}},31091:function(t,e,r){"use strict";r.d(e,{z:function(){return i}});var n=r(99649),o=r(63497);function i(t,e){let r=(0,n.Q)(t);if(isNaN(e))return(0,o.L)(t,NaN);if(!e)return r;let i=r.getDate(),a=(0,o.L)(t,r.getTime());return(a.setMonth(r.getMonth()+e+1,0),i>=a.getDate())?a:(r.setFullYear(a.getFullYear(),a.getMonth(),i),r)}},63497:function(t,e,r){"use strict";function n(t,e){return t instanceof Date?new t.constructor(e):new Date(e)}r.d(e,{L:function(){return n}})},99649:function(t,e,r){"use strict";function n(t){let e=Object.prototype.toString.call(t);return t instanceof Date||"object"==typeof t&&"[object Date]"===e?new t.constructor(+t):new Date("number"==typeof t||"[object Number]"===e||"string"==typeof t||"[object String]"===e?t:NaN)}r.d(e,{Q:function(){return n}})},69398:function(t,e,r){"use strict";function n(t,e){if(!t)throw Error("Invariant failed")}r.d(e,{Z:function(){return n}})}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/1112-0b9bd4ebde18e77b.js b/litellm/proxy/_experimental/out/_next/static/chunks/1112-0b9bd4ebde18e77b.js deleted file mode 100644 index ea4e968a055..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/1112-0b9bd4ebde18e77b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1112],{41112:function(e,l,s){s.d(l,{Z:function(){return B}});var a=s(57437),t=s(2265),r=s(16312),i=s(22116),n=s(19250),o=s(4260),c=s(37592),d=s(10032),m=s(42264),x=s(43769);let{TextArea:u}=o.default,{Option:h}=c.default,g=["Development","Productivity","Learning","Security","Data & Analytics","Integration","Testing","Documentation"];var p=e=>{let{visible:l,onClose:s,accessToken:p,onSuccess:j}=e,[y]=d.Z.useForm(),[b,N]=(0,t.useState)(!1),[Z,f]=(0,t.useState)("github"),v=async e=>{if(!p){m.ZP.error("No access token available");return}if(!(0,x.$L)(e.name)){m.ZP.error("Plugin name must be kebab-case (lowercase letters, numbers, and hyphens only)");return}if(e.version&&!(0,x.Nq)(e.version)){m.ZP.error("Version must be in semantic versioning format (e.g., 1.0.0)");return}if(e.authorEmail&&!(0,x.vV)(e.authorEmail)){m.ZP.error("Invalid email format");return}if(e.homepage&&!(0,x.jv)(e.homepage)){m.ZP.error("Invalid homepage URL format");return}N(!0);try{let l={name:e.name.trim(),source:"github"===Z?{source:"github",repo:e.repo.trim()}:{source:"url",url:e.url.trim()}};e.version&&(l.version=e.version.trim()),e.description&&(l.description=e.description.trim()),(e.authorName||e.authorEmail)&&(l.author={},e.authorName&&(l.author.name=e.authorName.trim()),e.authorEmail&&(l.author.email=e.authorEmail.trim())),e.homepage&&(l.homepage=e.homepage.trim()),e.category&&(l.category=e.category),e.keywords&&(l.keywords=(0,x.jE)(e.keywords)),await (0,n.registerClaudeCodePlugin)(p,l),m.ZP.success("Plugin registered successfully"),y.resetFields(),f("github"),j(),s()}catch(e){console.error("Error registering plugin:",e),m.ZP.error("Failed to register plugin")}finally{N(!1)}},C=()=>{y.resetFields(),f("github"),s()};return(0,a.jsx)(i.Z,{title:"Add New Claude Code Plugin",open:l,onCancel:C,footer:null,width:700,className:"top-8",children:(0,a.jsxs)(d.Z,{form:y,layout:"vertical",onFinish:v,className:"mt-4",children:[(0,a.jsx)(d.Z.Item,{label:"Plugin Name",name:"name",rules:[{required:!0,message:"Please enter plugin name"},{pattern:/^[a-z0-9-]+$/,message:"Name must be kebab-case (lowercase, numbers, hyphens only)"}],tooltip:"Unique identifier in kebab-case format (e.g., my-awesome-plugin)",children:(0,a.jsx)(o.default,{placeholder:"my-awesome-plugin",className:"rounded-lg"})}),(0,a.jsx)(d.Z.Item,{label:"Source Type",name:"sourceType",initialValue:"github",rules:[{required:!0,message:"Please select source type"}],children:(0,a.jsxs)(c.default,{onChange:e=>{f(e),y.setFieldsValue({repo:void 0,url:void 0})},className:"rounded-lg",children:[(0,a.jsx)(h,{value:"github",children:"GitHub"}),(0,a.jsx)(h,{value:"url",children:"URL"})]})}),"github"===Z&&(0,a.jsx)(d.Z.Item,{label:"GitHub Repository",name:"repo",rules:[{required:!0,message:"Please enter repository"},{pattern:/^[a-zA-Z0-9_-]+\/[a-zA-Z0-9_-]+$/,message:"Repository must be in format: org/repo"}],tooltip:"Format: organization/repository (e.g., anthropics/claude-code)",children:(0,a.jsx)(o.default,{placeholder:"anthropics/claude-code",className:"rounded-lg"})}),"url"===Z&&(0,a.jsx)(d.Z.Item,{label:"Git URL",name:"url",rules:[{required:!0,message:"Please enter git URL"}],tooltip:"Full git URL to the repository",children:(0,a.jsx)(o.default,{type:"url",placeholder:"https://github.com/org/repo.git",className:"rounded-lg"})}),(0,a.jsx)(d.Z.Item,{label:"Version (Optional)",name:"version",tooltip:"Semantic version (e.g., 1.0.0)",children:(0,a.jsx)(o.default,{placeholder:"1.0.0",className:"rounded-lg"})}),(0,a.jsx)(d.Z.Item,{label:"Description (Optional)",name:"description",tooltip:"Brief description of what the plugin does",children:(0,a.jsx)(u,{rows:3,placeholder:"A plugin that helps with...",maxLength:500,className:"rounded-lg"})}),(0,a.jsx)(d.Z.Item,{label:"Category (Optional)",name:"category",tooltip:"Select a category or enter a custom one",children:(0,a.jsx)(c.default,{placeholder:"Select or type a category",allowClear:!0,showSearch:!0,optionFilterProp:"children",className:"rounded-lg",children:g.map(e=>(0,a.jsx)(h,{value:e,children:e},e))})}),(0,a.jsx)(d.Z.Item,{label:"Keywords (Optional)",name:"keywords",tooltip:"Comma-separated list of keywords for search",children:(0,a.jsx)(o.default,{placeholder:"search, web, api",className:"rounded-lg"})}),(0,a.jsx)(d.Z.Item,{label:"Author Name (Optional)",name:"authorName",tooltip:"Name of the plugin author or organization",children:(0,a.jsx)(o.default,{placeholder:"Your Name or Organization",className:"rounded-lg"})}),(0,a.jsx)(d.Z.Item,{label:"Author Email (Optional)",name:"authorEmail",rules:[{type:"email",message:"Please enter a valid email"}],tooltip:"Contact email for the plugin author",children:(0,a.jsx)(o.default,{type:"email",placeholder:"author@example.com",className:"rounded-lg"})}),(0,a.jsx)(d.Z.Item,{label:"Homepage (Optional)",name:"homepage",rules:[{type:"url",message:"Please enter a valid URL"}],tooltip:"URL to the plugin's homepage or documentation",children:(0,a.jsx)(o.default,{type:"url",placeholder:"https://example.com",className:"rounded-lg"})}),(0,a.jsx)(d.Z.Item,{className:"mb-0 mt-6",children:(0,a.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,a.jsx)(r.z,{variant:"secondary",onClick:C,disabled:b,children:"Cancel"}),(0,a.jsx)(r.z,{type:"submit",loading:b,children:b?"Registering...":"Register Plugin"})]})})]})})},j=s(23639),y=s(74998),b=s(44633),N=s(86462),Z=s(49084),f=s(71594),v=s(24525),C=s(41649),w=s(78489),P=s(21626),k=s(97214),S=s(28241),_=s(58834),z=s(69552),I=s(71876),E=s(99981),A=s(63709),D=s(9114),L=e=>{let{pluginsList:l,isLoading:s,onDeleteClick:r,accessToken:i,onPluginUpdated:o,isAdmin:c,onPluginClick:d}=e,[m,u]=(0,t.useState)([{id:"created_at",desc:!0}]),[h,g]=(0,t.useState)(null),p=e=>e?new Date(e).toLocaleString():"-",L=e=>{navigator.clipboard.writeText(e),D.Z.success("Copied to clipboard!")},R=async e=>{if(i){g(e.id);try{e.enabled?(await (0,n.disableClaudeCodePlugin)(i,e.name),D.Z.success('Plugin "'.concat(e.name,'" disabled'))):(await (0,n.enableClaudeCodePlugin)(i,e.name),D.Z.success('Plugin "'.concat(e.name,'" enabled'))),o()}catch(e){D.Z.error("Failed to toggle plugin status")}finally{g(null)}}},F=[{header:"Plugin Name",accessorKey:"name",cell:e=>{let{row:l}=e,s=l.original,t=s.name||"";return(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)(E.Z,{title:t,children:(0,a.jsx)(w.Z,{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 min-w-[150px] justify-start",onClick:()=>d(s.id),children:t})}),(0,a.jsx)(E.Z,{title:"Copy Plugin ID",children:(0,a.jsx)(j.Z,{onClick:e=>{e.stopPropagation(),L(s.id)},className:"cursor-pointer text-gray-500 hover:text-blue-500 text-xs"})})]})}},{header:"Version",accessorKey:"version",cell:e=>{let{row:l}=e,s=l.original.version||"N/A";return(0,a.jsx)("span",{className:"text-xs text-gray-600",children:s})}},{header:"Description",accessorKey:"description",cell:e=>{let{row:l}=e,s=l.original.description||"No description";return(0,a.jsx)(E.Z,{title:s,children:(0,a.jsx)("span",{className:"text-xs text-gray-600 block max-w-[300px] truncate",children:s})})}},{header:"Category",accessorKey:"category",cell:e=>{let{row:l}=e,s=l.original.category;if(!s)return(0,a.jsx)(C.Z,{color:"gray",className:"text-xs font-normal",size:"xs",children:"Uncategorized"});let t=(0,x.LH)(s);return(0,a.jsx)(C.Z,{color:t,className:"text-xs font-normal",size:"xs",children:s})}},{header:"Enabled",accessorKey:"enabled",cell:e=>{let{row:l}=e,s=l.original;return(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)(C.Z,{color:s.enabled?"green":"gray",className:"text-xs font-normal",size:"xs",children:s.enabled?"Yes":"No"}),c&&(0,a.jsx)(E.Z,{title:s.enabled?"Disable plugin":"Enable plugin",children:(0,a.jsx)(A.Z,{size:"small",checked:s.enabled,loading:h===s.id,onChange:()=>R(s)})})]})}},{header:"Created At",accessorKey:"created_at",cell:e=>{let{row:l}=e,s=l.original;return(0,a.jsx)(E.Z,{title:s.created_at,children:(0,a.jsx)("span",{className:"text-xs",children:p(s.created_at)})})}},...c?[{header:"Actions",id:"actions",enableSorting:!1,cell:e=>{let{row:l}=e,s=l.original;return(0,a.jsx)("div",{className:"flex items-center gap-1",children:(0,a.jsx)(E.Z,{title:"Delete plugin",children:(0,a.jsx)(w.Z,{size:"xs",variant:"light",color:"red",onClick:e=>{e.stopPropagation(),r(s.name,s.name)},icon:y.Z,className:"text-red-500 hover:text-red-700 hover:bg-red-50"})})})}}]:[]],U=(0,f.b7)({data:l,columns:F,state:{sorting:m},onSortingChange:u,getCoreRowModel:(0,v.sC)(),getSortedRowModel:(0,v.tj)(),enableSorting:!0});return(0,a.jsx)("div",{className:"rounded-lg custom-border relative",children:(0,a.jsx)("div",{className:"overflow-x-auto",children:(0,a.jsxs)(P.Z,{className:"[&_td]:py-0.5 [&_th]:py-1",children:[(0,a.jsx)(_.Z,{children:U.getHeaderGroups().map(e=>(0,a.jsx)(I.Z,{children:e.headers.map(e=>(0,a.jsx)(z.Z,{className:"py-1 h-8 ".concat("actions"===e.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)]":""),onClick:e.column.getCanSort()?e.column.getToggleSortingHandler():void 0,children:(0,a.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,a.jsx)("div",{className:"flex items-center",children:e.isPlaceholder?null:(0,f.ie)(e.column.columnDef.header,e.getContext())}),e.column.getCanSort()&&(0,a.jsx)("div",{className:"w-4",children:e.column.getIsSorted()?({asc:(0,a.jsx)(b.Z,{className:"h-4 w-4 text-blue-500"}),desc:(0,a.jsx)(N.Z,{className:"h-4 w-4 text-blue-500"})})[e.column.getIsSorted()]:(0,a.jsx)(Z.Z,{className:"h-4 w-4 text-gray-400"})})]})},e.id))},e.id))}),(0,a.jsx)(k.Z,{children:s?(0,a.jsx)(I.Z,{children:(0,a.jsx)(S.Z,{colSpan:F.length,className:"h-8 text-center",children:(0,a.jsx)("div",{className:"text-center text-gray-500",children:(0,a.jsx)("p",{children:"Loading..."})})})}):l&&l.length>0?U.getRowModel().rows.map(e=>(0,a.jsx)(I.Z,{className:"h-8",children:e.getVisibleCells().map(e=>(0,a.jsx)(S.Z,{className:"py-0.5 max-h-8 overflow-hidden text-ellipsis whitespace-nowrap ".concat("actions"===e.column.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)]":""),children:(0,f.ie)(e.column.columnDef.cell,e.getContext())},e.id))},e.id)):(0,a.jsx)(I.Z,{children:(0,a.jsx)(S.Z,{colSpan:F.length,className:"h-8 text-center",children:(0,a.jsx)("div",{className:"text-center text-gray-500",children:(0,a.jsx)("p",{children:"No plugins found. Add one to get started."})})})})})]})})})},R=s(20347),F=s(10900),U=s(3477),O=s(12514),T=s(67101),H=s(84264),K=s(96761),V=s(10353),q=e=>{let{pluginId:l,onClose:s,accessToken:r,isAdmin:i,onPluginUpdated:o}=e,[c,d]=(0,t.useState)(null),[m,u]=(0,t.useState)(!0),[h,g]=(0,t.useState)(!1);(0,t.useEffect)(()=>{p()},[l,r]);let p=async()=>{if(r){u(!0);try{let e=await (0,n.getClaudeCodePluginDetails)(r,l);d(e.plugin)}catch(e){console.error("Error fetching plugin info:",e),D.Z.error("Failed to load plugin information")}finally{u(!1)}}},y=async()=>{if(r&&c){g(!0);try{c.enabled?(await (0,n.disableClaudeCodePlugin)(r,c.name),D.Z.success('Plugin "'.concat(c.name,'" disabled'))):(await (0,n.enableClaudeCodePlugin)(r,c.name),D.Z.success('Plugin "'.concat(c.name,'" enabled'))),o(),p()}catch(e){D.Z.error("Failed to toggle plugin status")}finally{g(!1)}}},b=e=>{navigator.clipboard.writeText(e),D.Z.success("Copied to clipboard!")};if(m)return(0,a.jsx)("div",{className:"flex items-center justify-center p-8",children:(0,a.jsx)(V.Z,{size:"large"})});if(!c)return(0,a.jsxs)("div",{className:"p-8 text-center text-gray-500",children:[(0,a.jsx)("p",{children:"Plugin not found"}),(0,a.jsx)(w.Z,{className:"mt-4",onClick:s,children:"Go Back"})]});let N=(0,x.aB)(c),Z=(0,x.OB)(c.source),f=(0,x.LH)(c.category);return(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-6",children:[(0,a.jsx)(F.Z,{className:"h-5 w-5 cursor-pointer text-gray-500 hover:text-gray-700",onClick:s}),(0,a.jsx)("h2",{className:"text-2xl font-bold",children:c.name}),c.version&&(0,a.jsxs)(C.Z,{color:"blue",size:"xs",children:["v",c.version]}),c.category&&(0,a.jsx)(C.Z,{color:f,size:"xs",children:c.category}),(0,a.jsx)(C.Z,{color:c.enabled?"green":"gray",size:"xs",children:c.enabled?"Enabled":"Disabled"})]}),(0,a.jsx)(O.Z,{children:(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsxs)("div",{className:"flex-1",children:[(0,a.jsx)(H.Z,{className:"text-gray-600 text-xs mb-2",children:"Install Command"}),(0,a.jsx)("div",{className:"font-mono bg-gray-100 px-3 py-2 rounded text-sm",children:N})]}),(0,a.jsx)(E.Z,{title:"Copy install command",children:(0,a.jsx)(w.Z,{size:"xs",variant:"secondary",icon:j.Z,onClick:()=>b(N),className:"ml-4",children:"Copy"})})]})}),(0,a.jsxs)(O.Z,{children:[(0,a.jsx)(K.Z,{children:"Plugin Details"}),(0,a.jsxs)(T.Z,{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 mt-4",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)(H.Z,{className:"text-gray-600 text-xs",children:"Plugin ID"}),(0,a.jsxs)("div",{className:"flex items-center gap-2 mt-1",children:[(0,a.jsx)(H.Z,{className:"font-mono text-xs",children:c.id}),(0,a.jsx)(j.Z,{className:"cursor-pointer text-gray-500 hover:text-blue-500 text-xs",onClick:()=>b(c.id)})]})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)(H.Z,{className:"text-gray-600 text-xs",children:"Name"}),(0,a.jsx)(H.Z,{className:"font-semibold mt-1",children:c.name})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)(H.Z,{className:"text-gray-600 text-xs",children:"Version"}),(0,a.jsx)(H.Z,{className:"font-semibold mt-1",children:c.version||"N/A"})]}),(0,a.jsxs)("div",{className:"col-span-2",children:[(0,a.jsx)(H.Z,{className:"text-gray-600 text-xs",children:"Source"}),(0,a.jsxs)("div",{className:"flex items-center gap-2 mt-1",children:[(0,a.jsx)(H.Z,{className:"font-semibold",children:(0,x.i5)(c.source)}),Z&&(0,a.jsx)("a",{href:Z,target:"_blank",rel:"noopener noreferrer",className:"text-blue-500 hover:text-blue-700",children:(0,a.jsx)(U.Z,{className:"h-4 w-4"})})]})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)(H.Z,{className:"text-gray-600 text-xs",children:"Category"}),(0,a.jsx)("div",{className:"mt-1",children:c.category?(0,a.jsx)(C.Z,{color:f,size:"xs",children:c.category}):(0,a.jsx)(H.Z,{className:"text-gray-400",children:"Uncategorized"})})]}),i&&(0,a.jsxs)("div",{className:"col-span-3",children:[(0,a.jsx)(H.Z,{className:"text-gray-600 text-xs",children:"Status"}),(0,a.jsxs)("div",{className:"flex items-center gap-3 mt-2",children:[(0,a.jsx)(A.Z,{checked:c.enabled,loading:h,onChange:y}),(0,a.jsx)(H.Z,{className:"text-sm",children:c.enabled?"Plugin is enabled and visible in marketplace":"Plugin is disabled and hidden from marketplace"})]})]})]})]}),c.description&&(0,a.jsxs)(O.Z,{children:[(0,a.jsx)(K.Z,{children:"Description"}),(0,a.jsx)(H.Z,{className:"mt-2",children:c.description})]}),c.keywords&&c.keywords.length>0&&(0,a.jsxs)(O.Z,{children:[(0,a.jsx)(K.Z,{children:"Keywords"}),(0,a.jsx)("div",{className:"flex flex-wrap gap-2 mt-2",children:c.keywords.map((e,l)=>(0,a.jsx)(C.Z,{color:"gray",size:"xs",children:e},l))})]}),c.author&&(0,a.jsxs)(O.Z,{children:[(0,a.jsx)(K.Z,{children:"Author Information"}),(0,a.jsxs)(T.Z,{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 mt-4",children:[c.author.name&&(0,a.jsxs)("div",{children:[(0,a.jsx)(H.Z,{className:"text-gray-600 text-xs",children:"Name"}),(0,a.jsx)(H.Z,{className:"font-semibold mt-1",children:c.author.name})]}),c.author.email&&(0,a.jsxs)("div",{children:[(0,a.jsx)(H.Z,{className:"text-gray-600 text-xs",children:"Email"}),(0,a.jsx)(H.Z,{className:"font-semibold mt-1",children:(0,a.jsx)("a",{href:"mailto:".concat(c.author.email),className:"text-blue-500 hover:text-blue-700",children:c.author.email})})]})]})]}),c.homepage&&(0,a.jsxs)(O.Z,{children:[(0,a.jsx)(K.Z,{children:"Homepage"}),(0,a.jsxs)("a",{href:c.homepage,target:"_blank",rel:"noopener noreferrer",className:"text-blue-500 hover:text-blue-700 flex items-center gap-2 mt-2",children:[c.homepage,(0,a.jsx)(U.Z,{className:"h-4 w-4"})]})]}),(0,a.jsxs)(O.Z,{children:[(0,a.jsx)(K.Z,{children:"Metadata"}),(0,a.jsxs)(T.Z,{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 mt-4",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)(H.Z,{className:"text-gray-600 text-xs",children:"Created At"}),(0,a.jsx)(H.Z,{className:"font-semibold mt-1",children:(0,x.ie)(c.created_at)})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)(H.Z,{className:"text-gray-600 text-xs",children:"Updated At"}),(0,a.jsx)(H.Z,{className:"font-semibold mt-1",children:(0,x.ie)(c.updated_at)})]}),c.created_by&&(0,a.jsxs)("div",{className:"col-span-2",children:[(0,a.jsx)(H.Z,{className:"text-gray-600 text-xs",children:"Created By"}),(0,a.jsx)(H.Z,{className:"font-semibold mt-1",children:c.created_by})]})]})]})]})},B=e=>{let{accessToken:l,userRole:s}=e,[o,c]=(0,t.useState)([]),[d,m]=(0,t.useState)(!1),[x,u]=(0,t.useState)(!1),[h,g]=(0,t.useState)(!1),[j,y]=(0,t.useState)(null),[b,N]=(0,t.useState)(null),Z=!!s&&(0,R.tY)(s),f=async()=>{if(l){u(!0);try{let e=await (0,n.getClaudeCodePluginsList)(l,!1);console.log("Claude Code plugins: ".concat(JSON.stringify(e))),c(e.plugins)}catch(e){console.error("Error fetching Claude Code plugins:",e)}finally{u(!1)}}};(0,t.useEffect)(()=>{f()},[l]);let v=async()=>{if(j&&l){g(!0);try{await (0,n.deleteClaudeCodePlugin)(l,j.name),D.Z.success('Plugin "'.concat(j.displayName,'" deleted successfully')),f()}catch(e){console.error("Error deleting plugin:",e),D.Z.error("Failed to delete plugin")}finally{g(!1),y(null)}}};return(0,a.jsxs)("div",{className:"w-full mx-auto flex-auto overflow-y-auto m-8 p-2",children:[(0,a.jsxs)("div",{className:"flex flex-col gap-2 mb-4",children:[(0,a.jsx)("h1",{className:"text-2xl font-bold",children:"Claude Code Plugins"}),(0,a.jsxs)("p",{className:"text-sm text-gray-600",children:["Manage Claude Code marketplace plugins. Add, enable, disable, or delete plugins that will be available in your marketplace catalog. Enabled plugins will appear in the public marketplace at"," ",(0,a.jsx)("code",{className:"bg-gray-100 px-1 rounded",children:"/claude-code/marketplace.json"}),"."]}),(0,a.jsx)("div",{className:"mt-2",children:(0,a.jsx)(r.z,{onClick:()=>{b&&N(null),m(!0)},disabled:!l||!Z,children:"+ Add New Plugin"})})]}),b?(0,a.jsx)(q,{pluginId:b,onClose:()=>N(null),accessToken:l,isAdmin:Z,onPluginUpdated:f}):(0,a.jsx)(L,{pluginsList:o,isLoading:x,onDeleteClick:(e,l)=>{y({name:e,displayName:l})},accessToken:l,onPluginUpdated:f,isAdmin:Z,onPluginClick:e=>N(e)}),(0,a.jsx)(p,{visible:d,onClose:()=>{m(!1)},accessToken:l,onSuccess:()=>{f()}}),j&&(0,a.jsxs)(i.Z,{title:"Delete Plugin",open:null!==j,onOk:v,onCancel:()=>{y(null)},confirmLoading:h,okText:"Delete",okButtonProps:{danger:!0},children:[(0,a.jsxs)("p",{children:["Are you sure you want to delete plugin:"," ",(0,a.jsx)("strong",{children:j.displayName}),"?"]}),(0,a.jsx)("p",{children:"This action cannot be undone."})]})]})}}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/1128-64fa4a41ccaf67ea.js b/litellm/proxy/_experimental/out/_next/static/chunks/1128-64fa4a41ccaf67ea.js new file mode 100644 index 00000000000..b9f027c5bee --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/1128-64fa4a41ccaf67ea.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1128],{29271:function(e,t,r){r.d(t,{Z:function(){return l}});var n=r(1119),o=r(2265),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:"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"},i=r(55015),l=o.forwardRef(function(e,t){return o.createElement(i.Z,(0,n.Z)({},e,{ref:t,icon:a}))})},92403:function(e,t,r){r.d(t,{Z:function(){return l}});var n=r(1119),o=r(2265),a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M608 112c-167.9 0-304 136.1-304 304 0 70.3 23.9 135 63.9 186.5l-41.1 41.1-62.3-62.3a8.15 8.15 0 00-11.4 0l-39.8 39.8a8.15 8.15 0 000 11.4l62.3 62.3-44.9 44.9-62.3-62.3a8.15 8.15 0 00-11.4 0l-39.8 39.8a8.15 8.15 0 000 11.4l62.3 62.3-65.3 65.3a8.03 8.03 0 000 11.3l42.3 42.3c3.1 3.1 8.2 3.1 11.3 0l253.6-253.6A304.06 304.06 0 00608 720c167.9 0 304-136.1 304-304S775.9 112 608 112zm161.2 465.2C726.2 620.3 668.9 644 608 644c-60.9 0-118.2-23.7-161.2-66.8-43.1-43-66.8-100.3-66.8-161.2 0-60.9 23.7-118.2 66.8-161.2 43-43.1 100.3-66.8 161.2-66.8 60.9 0 118.2 23.7 161.2 66.8 43.1 43 66.8 100.3 66.8 161.2 0 60.9-23.7 118.2-66.8 161.2z"}}]},name:"key",theme:"outlined"},i=r(55015),l=o.forwardRef(function(e,t){return o.createElement(i.Z,(0,n.Z)({},e,{ref:t,icon:a}))})},62272:function(e,t,r){r.d(t,{Z:function(){return l}});var n=r(1119),o=r(2265),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"},i=r(55015),l=o.forwardRef(function(e,t){return o.createElement(i.Z,(0,n.Z)({},e,{ref:t,icon:a}))})},34419:function(e,t,r){r.d(t,{Z:function(){return l}});var n=r(1119),o=r(2265),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"},i=r(55015),l=o.forwardRef(function(e,t){return o.createElement(i.Z,(0,n.Z)({},e,{ref:t,icon:a}))})},58747:function(e,t,r){r.d(t,{Z:function(){return a}});var n=r(5853),o=r(2265);let a=e=>{var t=(0,n._T)(e,[]);return o.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"},t),o.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"}))}},4537:function(e,t,r){r.d(t,{Z:function(){return a}});var n=r(5853),o=r(2265);let a=e=>{var t=(0,n._T)(e,[]);return o.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"},t),o.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"}))}},27281:function(e,t,r){r.d(t,{Z:function(){return p}});var n=r(5853),o=r(58747),a=r(2265),i=r(4537),l=r(13241),s=r(1153),c=r(96398),u=r(51975),d=r(85238),h=r(44140);let f=(0,s.fn)("Select"),p=a.forwardRef((e,t)=>{let{defaultValue:r="",value:s,onValueChange:p,placeholder:m="Select...",disabled:b=!1,icon:v,enableClear:y=!1,required:g,children:C,name:k,error:w=!1,errorMessage:x,className:O,id:E}=e,M=(0,n._T)(e,["defaultValue","value","onValueChange","placeholder","disabled","icon","enableClear","required","children","name","error","errorMessage","className","id"]),S=(0,a.useRef)(null),N=a.Children.toArray(C),[P,j]=(0,h.Z)(r,s),R=(0,a.useMemo)(()=>{let e=a.Children.toArray(C).filter(a.isValidElement);return(0,c.sl)(e)},[C]);return a.createElement("div",{className:(0,l.q)("w-full min-w-[10rem] text-tremor-default",O)},a.createElement("div",{className:"relative"},a.createElement("select",{title:"select-hidden",required:g,className:(0,l.q)("h-full w-full absolute left-0 top-0 -z-10 opacity-0"),value:P,onChange:e=>{e.preventDefault()},name:k,disabled:b,id:E,onFocus:()=>{let e=S.current;e&&e.focus()}},a.createElement("option",{className:"hidden",value:"",disabled:!0,hidden:!0},m),N.map(e=>{let t=e.props.value,r=e.props.children;return a.createElement("option",{className:"hidden",key:t,value:t},r)})),a.createElement(u.Ri,Object.assign({as:"div",ref:t,defaultValue:P,value:P,onChange:e=>{null==p||p(e),j(e)},disabled:b,id:E},M),e=>{var t;let{value:r}=e;return a.createElement(a.Fragment,null,a.createElement(u.Y4,{ref:S,className:(0,l.q)("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",v?"pl-10":"pl-3",(0,c.um)((0,c.Uh)(r),b,w))},v&&a.createElement("span",{className:(0,l.q)("absolute inset-y-0 left-0 flex items-center ml-px pl-2.5")},a.createElement(v,{className:(0,l.q)(f("Icon"),"flex-none h-5 w-5","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle")})),a.createElement("span",{className:"w-[90%] block truncate"},r&&null!==(t=R.get(r))&&void 0!==t?t:m),a.createElement("span",{className:(0,l.q)("absolute inset-y-0 right-0 flex items-center mr-3")},a.createElement(o.Z,{className:(0,l.q)(f("arrowDownIcon"),"flex-none h-5 w-5","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle")}))),y&&P?a.createElement("button",{type:"button",className:(0,l.q)("absolute inset-y-0 right-0 flex items-center mr-8"),onClick:e=>{e.preventDefault(),j(""),null==p||p("")}},a.createElement(i.Z,{className:(0,l.q)(f("clearIcon"),"flex-none h-4 w-4","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle")})):null,a.createElement(d.u,{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.createElement(u.O_,{anchor:"bottom start",className:(0,l.q)("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")},C)))})),w&&x?a.createElement("p",{className:(0,l.q)("errorMessage","text-sm text-rose-500 mt-1")},x):null)});p.displayName="Select"},67982:function(e,t,r){r.d(t,{Z:function(){return s}});var n=r(5853),o=r(13241),a=r(1153),i=r(2265);let l=(0,a.fn)("Divider"),s=i.forwardRef((e,t)=>{let{className:r,children:a}=e,s=(0,n._T)(e,["className","children"]);return i.createElement("div",Object.assign({ref:t,className:(0,o.q)(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",r)},s),a?i.createElement(i.Fragment,null,i.createElement("div",{className:(0,o.q)("w-full h-[1px] bg-tremor-border dark:bg-dark-tremor-border")}),i.createElement("div",{className:(0,o.q)("text-inherit whitespace-nowrap")},a),i.createElement("div",{className:(0,o.q)("w-full h-[1px] bg-tremor-border dark:bg-dark-tremor-border")})):i.createElement("div",{className:(0,o.q)("w-full h-[1px] bg-tremor-border dark:bg-dark-tremor-border")}))});s.displayName="Divider"},94789:function(e,t,r){r.d(t,{Z:function(){return c}});var n=r(5853),o=r(2265),a=r(26898),i=r(13241),l=r(1153);let s=(0,l.fn)("Callout"),c=o.forwardRef((e,t)=>{let{title:r,icon:c,color:u,className:d,children:h}=e,f=(0,n._T)(e,["title","icon","color","className","children"]);return o.createElement("div",Object.assign({ref:t,className:(0,i.q)(s("root"),"flex flex-col overflow-hidden rounded-tremor-default text-tremor-default border-l-4 py-3 pr-3 pl-4",u?(0,i.q)((0,l.bM)(u,a.K.background).bgColor,(0,l.bM)(u,a.K.darkBorder).borderColor,(0,l.bM)(u,a.K.darkText).textColor,"dark:bg-opacity-10 bg-opacity-10"):(0,i.q)("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"),d)},f),o.createElement("div",{className:(0,i.q)(s("header"),"flex items-start")},c?o.createElement(c,{className:(0,i.q)(s("icon"),"flex-none h-5 w-5 mr-1.5")}):null,o.createElement("h4",{className:(0,i.q)(s("title"),"font-semibold")},r)),o.createElement("p",{className:(0,i.q)(s("body"),"overflow-y-auto",h?"mt-2":"")},h))});c.displayName="Callout"},96761:function(e,t,r){r.d(t,{Z:function(){return s}});var n=r(5853),o=r(26898),a=r(13241),i=r(1153),l=r(2265);let s=l.forwardRef((e,t)=>{let{color:r,children:s,className:c}=e,u=(0,n._T)(e,["color","children","className"]);return l.createElement("p",Object.assign({ref:t,className:(0,a.q)("font-medium text-tremor-title",r?(0,i.bM)(r,o.K.darkText).textColor:"text-tremor-content-strong dark:text-dark-tremor-content-strong",c)},u),s)});s.displayName="Title"},44140:function(e,t,r){r.d(t,{Z:function(){return o}});var n=r(2265);let o=(e,t)=>{let r=void 0!==t,[o,a]=(0,n.useState)(e);return[r?t:o,e=>{r||a(e)}]}},3810:function(e,t,r){r.d(t,{Z:function(){return j}});var n=r(2265),o=r(36760),a=r.n(o),i=r(18694),l=r(93350),s=r(53445),c=r(19722),u=r(6694),d=r(71744),h=r(93463),f=r(54558),p=r(12918),m=r(71140),b=r(99320);let v=e=>{let{paddingXXS:t,lineWidth:r,tagPaddingHorizontal:n,componentCls:o,calc:a}=e,i=a(n).sub(r).equal(),l=a(t).sub(r).equal();return{[o]:Object.assign(Object.assign({},(0,p.Wf)(e)),{display:"inline-block",height:"auto",marginInlineEnd:e.marginXS,paddingInline:i,fontSize:e.tagFontSize,lineHeight:e.tagLineHeight,whiteSpace:"nowrap",background:e.defaultBg,border:"".concat((0,h.bf)(e.lineWidth)," ").concat(e.lineType," ").concat(e.colorBorder),borderRadius:e.borderRadiusSM,opacity:1,transition:"all ".concat(e.motionDurationMid),textAlign:"start",position:"relative",["&".concat(o,"-rtl")]:{direction:"rtl"},"&, a, a:hover":{color:e.defaultColor},["".concat(o,"-close-icon")]:{marginInlineStart:l,fontSize:e.tagIconSize,color:e.colorIcon,cursor:"pointer",transition:"all ".concat(e.motionDurationMid),"&:hover":{color:e.colorTextHeading}},["&".concat(o,"-has-color")]:{borderColor:"transparent",["&, a, a:hover, ".concat(e.iconCls,"-close, ").concat(e.iconCls,"-close:hover")]:{color:e.colorTextLightSolid}},"&-checkable":{backgroundColor:"transparent",borderColor:"transparent",cursor:"pointer",["&:not(".concat(o,"-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"},["> ".concat(e.iconCls," + span, > span + ").concat(e.iconCls)]:{marginInlineStart:i}}),["".concat(o,"-borderless")]:{borderColor:"transparent",background:e.tagBorderlessBg}}},y=e=>{let{lineWidth:t,fontSizeIcon:r,calc:n}=e,o=e.fontSizeSM;return(0,m.IX)(e,{tagFontSize:o,tagLineHeight:(0,h.bf)(n(e.lineHeightSM).mul(o).equal()),tagIconSize:n(r).sub(n(t).mul(2)).equal(),tagPaddingHorizontal:8,tagBorderlessBg:e.defaultBg})},g=e=>({defaultBg:new f.t(e.colorFillQuaternary).onBackground(e.colorBgContainer).toHexString(),defaultColor:e.colorText});var C=(0,b.I$)("Tag",e=>v(y(e)),g),k=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 w=n.forwardRef((e,t)=>{let{prefixCls:r,style:o,className:i,checked:l,children:s,icon:c,onChange:u,onClick:h}=e,f=k(e,["prefixCls","style","className","checked","children","icon","onChange","onClick"]),{getPrefixCls:p,tag:m}=n.useContext(d.E_),b=p("tag",r),[v,y,g]=C(b),w=a()(b,"".concat(b,"-checkable"),{["".concat(b,"-checkable-checked")]:l},null==m?void 0:m.className,i,y,g);return v(n.createElement("span",Object.assign({},f,{ref:t,style:Object.assign(Object.assign({},o),null==m?void 0:m.style),className:w,onClick:e=>{null==u||u(!l),null==h||h(e)}}),c,n.createElement("span",null,s)))});var x=r(18536);let O=e=>(0,x.Z)(e,(t,r)=>{let{textColor:n,lightBorderColor:o,lightColor:a,darkColor:i}=r;return{["".concat(e.componentCls).concat(e.componentCls,"-").concat(t)]:{color:n,background:a,borderColor:o,"&-inverse":{color:e.colorTextLightSolid,background:i,borderColor:i},["&".concat(e.componentCls,"-borderless")]:{borderColor:"transparent"}}}});var E=(0,b.bk)(["Tag","preset"],e=>O(y(e)),g);let M=(e,t,r)=>{let n="string"!=typeof r?r:r.charAt(0).toUpperCase()+r.slice(1);return{["".concat(e.componentCls).concat(e.componentCls,"-").concat(t)]:{color:e["color".concat(r)],background:e["color".concat(n,"Bg")],borderColor:e["color".concat(n,"Border")],["&".concat(e.componentCls,"-borderless")]:{borderColor:"transparent"}}}};var S=(0,b.bk)(["Tag","status"],e=>{let t=y(e);return[M(t,"success","Success"),M(t,"processing","Info"),M(t,"error","Error"),M(t,"warning","Warning")]},g),N=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 P=n.forwardRef((e,t)=>{let{prefixCls:r,className:o,rootClassName:h,style:f,children:p,icon:m,color:b,onClose:v,bordered:y=!0,visible:g}=e,k=N(e,["prefixCls","className","rootClassName","style","children","icon","color","onClose","bordered","visible"]),{getPrefixCls:w,direction:x,tag:O}=n.useContext(d.E_),[M,P]=n.useState(!0),j=(0,i.Z)(k,["closeIcon","closable"]);n.useEffect(()=>{void 0!==g&&P(g)},[g]);let R=(0,l.o2)(b),T=(0,l.yT)(b),Z=R||T,L=Object.assign(Object.assign({backgroundColor:b&&!Z?b:void 0},null==O?void 0:O.style),f),q=w("tag",r),[z,_,F]=C(q),B=a()(q,null==O?void 0:O.className,{["".concat(q,"-").concat(b)]:Z,["".concat(q,"-has-color")]:b&&!Z,["".concat(q,"-hidden")]:!M,["".concat(q,"-rtl")]:"rtl"===x,["".concat(q,"-borderless")]:!y},o,h,_,F),I=e=>{e.stopPropagation(),null==v||v(e),e.defaultPrevented||P(!1)},[,V]=(0,s.b)((0,s.w)(e),(0,s.w)(O),{closable:!1,closeIconRender:e=>{let t=n.createElement("span",{className:"".concat(q,"-close-icon"),onClick:I},e);return(0,c.wm)(e,t,e=>({onClick:t=>{var r;null===(r=null==e?void 0:e.onClick)||void 0===r||r.call(e,t),I(t)},className:a()(null==e?void 0:e.className,"".concat(q,"-close-icon"))}))}}),H="function"==typeof k.onClick||p&&"a"===p.type,D=m||null,A=D?n.createElement(n.Fragment,null,D,p&&n.createElement("span",null,p)):p,K=n.createElement("span",Object.assign({},j,{ref:t,className:B,style:L}),A,V,R&&n.createElement(E,{key:"preset",prefixCls:q}),T&&n.createElement(S,{key:"status",prefixCls:q}));return z(H?n.createElement(u.Z,{component:"Tag"},K):K)});P.CheckableTag=w;var j=P},87769:function(e,t,r){r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("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"}]])},42208:function(e,t,r){r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("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"}]])},88906:function(e,t,r){r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("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"}]])},15868:function(e,t,r){r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("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"}]])},18930:function(e,t,r){r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("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"}]])},95805:function(e,t,r){r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("users",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["path",{d:"M16 3.128a4 4 0 0 1 0 7.744",key:"16gr8j"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87",key:"kshegd"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}]])},6337:function(e,t,r){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)}Object.defineProperty(t,"__esModule",{value:!0}),t.CopyToClipboard=void 0;var o=l(r(2265)),a=l(r(49211)),i=["text","onCopy","options","children"];function l(e){return e&&e.__esModule?e:{default:e}}function s(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=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0)&&Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}(e,i),n=o.default.Children.only(t);return o.default.cloneElement(n,c(c({},r),{},{onClick:this.onClick}))}}],function(e,t){for(var r=0;rt!==e),this.scheduleGc(),this.#r.notify({type:"observerRemoved",mutation:this,observer:e})}optionalRemove(){this.#t.length||("pending"===this.state.status?this.scheduleGc():this.#r.remove(this))}continue(){return this.#n?.continue()??this.execute(this.state.variables)}async execute(e){let t=()=>{this.#o({type:"continue"})},r={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};this.#n=(0,a.Mz)({fn:()=>this.options.mutationFn?this.options.mutationFn(e,r):Promise.reject(Error("No mutationFn found")),onFail:(e,t)=>{this.#o({type:"failed",failureCount:e,error:t})},onPause:()=>{this.#o({type:"pause"})},onContinue:t,retry:this.options.retry??0,retryDelay:this.options.retryDelay,networkMode:this.options.networkMode,canRun:()=>this.#r.canRun(this)});let n="pending"===this.state.status,o=!this.#n.canStart();try{if(n)t();else{this.#o({type:"pending",variables:e,isPaused:o}),await this.#r.config.onMutate?.(e,this,r);let t=await this.options.onMutate?.(e,r);t!==this.state.context&&this.#o({type:"pending",context:t,variables:e,isPaused:o})}let a=await this.#n.start();return await this.#r.config.onSuccess?.(a,e,this.state.context,this,r),await this.options.onSuccess?.(a,e,this.state.context,r),await this.#r.config.onSettled?.(a,null,this.state.variables,this.state.context,this,r),await this.options.onSettled?.(a,null,e,this.state.context,r),this.#o({type:"success",data:a}),a}catch(t){try{throw await this.#r.config.onError?.(t,e,this.state.context,this,r),await this.options.onError?.(t,e,this.state.context,r),await this.#r.config.onSettled?.(void 0,t,this.state.variables,this.state.context,this,r),await this.options.onSettled?.(void 0,t,e,this.state.context,r),t}finally{this.#o({type:"error",error:t})}}finally{this.#r.runNext(this)}}#o(e){this.state=(t=>{switch(e.type){case"failed":return{...t,failureCount:e.failureCount,failureReason:e.error};case"pause":return{...t,isPaused:!0};case"continue":return{...t,isPaused:!1};case"pending":return{...t,context:e.context,data:void 0,failureCount:0,failureReason:null,error:null,isPaused:e.isPaused,status:"pending",variables:e.variables,submittedAt:Date.now()};case"success":return{...t,data:e.data,failureCount:0,failureReason:null,error:null,status:"success",isPaused:!1};case"error":return{...t,data:void 0,error:e.error,failureCount:t.failureCount+1,failureReason:e.error,isPaused:!1,status:"error"}}})(this.state),n.Vr.batch(()=>{this.#t.forEach(t=>{t.onMutationUpdate(e)}),this.#r.notify({mutation:this,type:"updated",action:e})})}};function l(){return{context:void 0,data:void 0,error:null,failureCount:0,failureReason:null,isPaused:!1,status:"idle",variables:void 0,submittedAt:0}}},21770:function(e,t,r){r.d(t,{D:function(){return u}});var n=r(2265),o=r(2894),a=r(18238),i=r(24112),l=r(45345),s=class extends i.l{#e;#a=void 0;#i;#l;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,l.VS)(this.options,t)||this.#e.getMutationCache().notify({type:"observerOptionsUpdated",mutation:this.#i,observer:this}),t?.mutationKey&&this.options.mutationKey&&(0,l.Ym)(t.mutationKey)!==(0,l.Ym)(this.options.mutationKey)?this.reset():this.#i?.state.status==="pending"&&this.#i.setOptions(this.options)}onUnsubscribe(){this.hasListeners()||this.#i?.removeObserver(this)}onMutationUpdate(e){this.#s(),this.#c(e)}getCurrentResult(){return this.#a}reset(){this.#i?.removeObserver(this),this.#i=void 0,this.#s(),this.#c()}mutate(e,t){return this.#l=t,this.#i?.removeObserver(this),this.#i=this.#e.getMutationCache().build(this.#e,this.options),this.#i.addObserver(this),this.#i.execute(e)}#s(){let e=this.#i?.state??(0,o.R)();this.#a={...e,isPending:"pending"===e.status,isSuccess:"success"===e.status,isError:"error"===e.status,isIdle:"idle"===e.status,mutate:this.mutate,reset:this.reset}}#c(e){a.Vr.batch(()=>{if(this.#l&&this.hasListeners()){let t=this.#a.variables,r=this.#a.context,n={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};e?.type==="success"?(this.#l.onSuccess?.(e.data,t,r,n),this.#l.onSettled?.(e.data,null,t,r,n)):e?.type==="error"&&(this.#l.onError?.(e.error,t,r,n),this.#l.onSettled?.(void 0,e.error,t,r,n))}this.listeners.forEach(e=>{e(this.#a)})})}},c=r(29827);function u(e,t){let r=(0,c.NL)(t),[o]=n.useState(()=>new s(r,e));n.useEffect(()=>{o.setOptions(e)},[o,e]);let i=n.useSyncExternalStore(n.useCallback(e=>o.subscribe(a.Vr.batchCalls(e)),[o]),()=>o.getCurrentResult(),()=>o.getCurrentResult()),u=n.useCallback((e,t)=>{o.mutate(e,t).catch(l.ZT)},[o]);if(i.error&&(0,l.L3)(o.options.throwOnError,[i.error]))throw i.error;return{...i,mutate:u,mutateAsync:i.mutate}}},85238:function(e,t,r){let n;r.d(t,{u:function(){return N}});var o=r(2265),a=r(59456),i=r(93980),l=r(25289),s=r(73389),c=r(43507),u=r(180),d=r(67561),h=r(98218),f=r(28294),p=r(95504),m=r(72468),b=r(38929);function v(e){var t;return!!(e.enter||e.enterFrom||e.enterTo||e.leave||e.leaveFrom||e.leaveTo)||(null!=(t=e.as)?t:x)!==o.Fragment||1===o.Children.count(e.children)}let y=(0,o.createContext)(null);y.displayName="TransitionContext";var g=((n=g||{}).Visible="visible",n.Hidden="hidden",n);let C=(0,o.createContext)(null);function k(e){return"children"in e?k(e.children):e.current.filter(e=>{let{el:t}=e;return null!==t.current}).filter(e=>{let{state:t}=e;return"visible"===t}).length>0}function w(e,t){let r=(0,c.E)(e),n=(0,o.useRef)([]),s=(0,l.t)(),u=(0,a.G)(),d=(0,i.z)(function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:b.l4.Hidden,o=n.current.findIndex(t=>{let{el:r}=t;return r===e});-1!==o&&((0,m.E)(t,{[b.l4.Unmount](){n.current.splice(o,1)},[b.l4.Hidden](){n.current[o].state="hidden"}}),u.microTask(()=>{var e;!k(n)&&s.current&&(null==(e=r.current)||e.call(r))}))}),h=(0,i.z)(e=>{let t=n.current.find(t=>{let{el:r}=t;return r===e});return t?"visible"!==t.state&&(t.state="visible"):n.current.push({el:e,state:"visible"}),()=>d(e,b.l4.Unmount)}),f=(0,o.useRef)([]),p=(0,o.useRef)(Promise.resolve()),v=(0,o.useRef)({enter:[],leave:[]}),y=(0,i.z)((e,r,n)=>{f.current.splice(0),t&&(t.chains.current[r]=t.chains.current[r].filter(t=>{let[r]=t;return r!==e})),null==t||t.chains.current[r].push([e,new Promise(e=>{f.current.push(e)})]),null==t||t.chains.current[r].push([e,new Promise(e=>{Promise.all(v.current[r].map(e=>{let[t,r]=e;return r})).then(()=>e())})]),"enter"===r?p.current=p.current.then(()=>null==t?void 0:t.wait.current).then(()=>n(r)):n(r)}),g=(0,i.z)((e,t,r)=>{Promise.all(v.current[t].splice(0).map(e=>{let[t,r]=e;return r})).then(()=>{var e;null==(e=f.current.shift())||e()}).then(()=>r(t))});return(0,o.useMemo)(()=>({children:n,register:h,unregister:d,onStart:y,onStop:g,wait:p,chains:v}),[h,d,n,y,g,v,p])}C.displayName="NestingContext";let x=o.Fragment,O=b.VN.RenderStrategy,E=(0,b.yV)(function(e,t){let{show:r,appear:n=!1,unmount:a=!0,...l}=e,c=(0,o.useRef)(null),h=v(e),p=(0,d.T)(...h?[c,t]:null===t?[]:[t]);(0,u.H)();let m=(0,f.oJ)();if(void 0===r&&null!==m&&(r=(m&f.ZM.Open)===f.ZM.Open),void 0===r)throw Error("A is used but it is missing a `show={true | false}` prop.");let[g,x]=(0,o.useState)(r?"visible":"hidden"),E=w(()=>{r||x("hidden")}),[S,N]=(0,o.useState)(!0),P=(0,o.useRef)([r]);(0,s.e)(()=>{!1!==S&&P.current[P.current.length-1]!==r&&(P.current.push(r),N(!1))},[P,r]);let j=(0,o.useMemo)(()=>({show:r,appear:n,initial:S}),[r,n,S]);(0,s.e)(()=>{r?x("visible"):k(E)||null===c.current||x("hidden")},[r,E]);let R={unmount:a},T=(0,i.z)(()=>{var t;S&&N(!1),null==(t=e.beforeEnter)||t.call(e)}),Z=(0,i.z)(()=>{var t;S&&N(!1),null==(t=e.beforeLeave)||t.call(e)}),L=(0,b.L6)();return o.createElement(C.Provider,{value:E},o.createElement(y.Provider,{value:j},L({ourProps:{...R,as:o.Fragment,children:o.createElement(M,{ref:p,...R,...l,beforeEnter:T,beforeLeave:Z})},theirProps:{},defaultTag:o.Fragment,features:O,visible:"visible"===g,name:"Transition"})))}),M=(0,b.yV)(function(e,t){var r,n;let{transition:a=!0,beforeEnter:l,afterEnter:c,beforeLeave:g,afterLeave:E,enter:M,enterFrom:S,enterTo:N,entered:P,leave:j,leaveFrom:R,leaveTo:T,...Z}=e,[L,q]=(0,o.useState)(null),z=(0,o.useRef)(null),_=v(e),F=(0,d.T)(..._?[z,t,q]:null===t?[]:[t]),B=null==(r=Z.unmount)||r?b.l4.Unmount:b.l4.Hidden,{show:I,appear:V,initial:H}=function(){let e=(0,o.useContext)(y);if(null===e)throw Error("A is used but it is missing a parent or .");return e}(),[D,A]=(0,o.useState)(I?"visible":"hidden"),K=function(){let e=(0,o.useContext)(C);if(null===e)throw Error("A is used but it is missing a parent or .");return e}(),{register:U,unregister:G}=K;(0,s.e)(()=>U(z),[U,z]),(0,s.e)(()=>{if(B===b.l4.Hidden&&z.current){if(I&&"visible"!==D){A("visible");return}return(0,m.E)(D,{hidden:()=>G(z),visible:()=>U(z)})}},[D,z,U,G,I,B]);let Y=(0,u.H)();(0,s.e)(()=>{if(_&&Y&&"visible"===D&&null===z.current)throw Error("Did you forget to passthrough the `ref` to the actual DOM node?")},[z,D,Y,_]);let W=H&&!V,X=V&&I&&H,J=(0,o.useRef)(!1),Q=w(()=>{J.current||(A("hidden"),G(z))},K),$=(0,i.z)(e=>{J.current=!0,Q.onStart(z,e?"enter":"leave",e=>{"enter"===e?null==l||l():"leave"===e&&(null==g||g())})}),ee=(0,i.z)(e=>{let t=e?"enter":"leave";J.current=!1,Q.onStop(z,t,e=>{"enter"===e?null==c||c():"leave"===e&&(null==E||E())}),"leave"!==t||k(Q)||(A("hidden"),G(z))});(0,o.useEffect)(()=>{_&&a||($(I),ee(I))},[I,_,a]);let et=!(!a||!_||!Y||W),[,er]=(0,h.Y)(et,L,I,{start:$,end:ee}),en=(0,b.oA)({ref:F,className:(null==(n=(0,p.A)(Z.className,X&&M,X&&S,er.enter&&M,er.enter&&er.closed&&S,er.enter&&!er.closed&&N,er.leave&&j,er.leave&&!er.closed&&R,er.leave&&er.closed&&T,!er.transition&&I&&P))?void 0:n.trim())||void 0,...(0,h.X)(er)}),eo=0;"visible"===D&&(eo|=f.ZM.Open),"hidden"===D&&(eo|=f.ZM.Closed),er.enter&&(eo|=f.ZM.Opening),er.leave&&(eo|=f.ZM.Closing);let ea=(0,b.L6)();return o.createElement(C.Provider,{value:Q},o.createElement(f.up,{value:eo},ea({ourProps:en,theirProps:Z,defaultTag:x,features:O,visible:"visible"===D,name:"Transition.Child"})))}),S=(0,b.yV)(function(e,t){let r=null!==(0,o.useContext)(y),n=null!==(0,f.oJ)();return o.createElement(o.Fragment,null,!r&&n?o.createElement(E,{ref:t,...e}):o.createElement(M,{ref:t,...e}))}),N=Object.assign(E,{Child:S,Root:E})}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/1132-d0fa0c9565944e8f.js b/litellm/proxy/_experimental/out/_next/static/chunks/1132-d0fa0c9565944e8f.js deleted file mode 100644 index 76fa42eb99f..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/1132-d0fa0c9565944e8f.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1132],{12660:function(e,t,r){"use strict";r.d(t,{Z:function(){return i}});var n=r(1119),o=r(2265),a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M917.7 148.8l-42.4-42.4c-1.6-1.6-3.6-2.3-5.7-2.3s-4.1.8-5.7 2.3l-76.1 76.1a199.27 199.27 0 00-112.1-34.3c-51.2 0-102.4 19.5-141.5 58.6L432.3 308.7a8.03 8.03 0 000 11.3L704 591.7c1.6 1.6 3.6 2.3 5.7 2.3 2 0 4.1-.8 5.7-2.3l101.9-101.9c68.9-69 77-175.7 24.3-253.5l76.1-76.1c3.1-3.2 3.1-8.3 0-11.4zM769.1 441.7l-59.4 59.4-186.8-186.8 59.4-59.4c24.9-24.9 58.1-38.7 93.4-38.7 35.3 0 68.4 13.7 93.4 38.7 24.9 24.9 38.7 58.1 38.7 93.4 0 35.3-13.8 68.4-38.7 93.4zm-190.2 105a8.03 8.03 0 00-11.3 0L501 613.3 410.7 523l66.7-66.7c3.1-3.1 3.1-8.2 0-11.3L441 408.6a8.03 8.03 0 00-11.3 0L363 475.3l-43-43a7.85 7.85 0 00-5.7-2.3c-2 0-4.1.8-5.7 2.3L206.8 534.2c-68.9 69-77 175.7-24.3 253.5l-76.1 76.1a8.03 8.03 0 000 11.3l42.4 42.4c1.6 1.6 3.6 2.3 5.7 2.3s4.1-.8 5.7-2.3l76.1-76.1c33.7 22.9 72.9 34.3 112.1 34.3 51.2 0 102.4-19.5 141.5-58.6l101.9-101.9c3.1-3.1 3.1-8.2 0-11.3l-43-43 66.7-66.7c3.1-3.1 3.1-8.2 0-11.3l-36.6-36.2zM441.7 769.1a131.32 131.32 0 01-93.4 38.7c-35.3 0-68.4-13.7-93.4-38.7a131.32 131.32 0 01-38.7-93.4c0-35.3 13.7-68.4 38.7-93.4l59.4-59.4 186.8 186.8-59.4 59.4z"}}]},name:"api",theme:"outlined"},l=r(55015),i=o.forwardRef(function(e,t){return o.createElement(l.Z,(0,n.Z)({},e,{ref:t,icon:a}))})},5540:function(e,t,r){"use strict";r.d(t,{Z:function(){return i}});var n=r(1119),o=r(2265),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"},l=r(55015),i=o.forwardRef(function(e,t){return o.createElement(l.Z,(0,n.Z)({},e,{ref:t,icon:a}))})},3632:function(e,t,r){"use strict";r.d(t,{Z:function(){return i}});var n=r(1119),o=r(2265),a={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"},l=r(55015),i=o.forwardRef(function(e,t){return o.createElement(l.Z,(0,n.Z)({},e,{ref:t,icon:a}))})},35291:function(e,t,r){"use strict";r.d(t,{Z:function(){return i}});var n=r(1119),o=r(2265),a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M464 720a48 48 0 1096 0 48 48 0 10-96 0zm16-304v184c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V416c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8zm475.7 440l-416-720c-6.2-10.7-16.9-16-27.7-16s-21.6 5.3-27.7 16l-416 720C56 877.4 71.4 904 96 904h832c24.6 0 40-26.6 27.7-48zm-783.5-27.9L512 239.9l339.8 588.2H172.2z"}}]},name:"warning",theme:"outlined"},l=r(55015),i=o.forwardRef(function(e,t){return o.createElement(l.Z,(0,n.Z)({},e,{ref:t,icon:a}))})},58747:function(e,t,r){"use strict";r.d(t,{Z:function(){return a}});var n=r(5853),o=r(2265);let a=e=>{var t=(0,n._T)(e,[]);return o.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"},t),o.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"}))}},4537:function(e,t,r){"use strict";r.d(t,{Z:function(){return a}});var n=r(5853),o=r(2265);let a=e=>{var t=(0,n._T)(e,[]);return o.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"},t),o.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"}))}},47323:function(e,t,r){"use strict";r.d(t,{Z:function(){return h}});var n=r(5853),o=r(2265),a=r(47187),l=r(7084),i=r(13241),s=r(1153),c=r(26898);let u={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"}},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:""}},f=(e,t)=>{switch(e){case"simple":return{textColor:t?(0,s.bM)(t,c.K.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:"",borderColor:"",ringColor:""};case"light":return{textColor:t?(0,s.bM)(t,c.K.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,i.q)((0,s.bM)(t,c.K.background).bgColor,"bg-opacity-20"):"bg-tremor-brand-muted dark:bg-dark-tremor-brand-muted",borderColor:"",ringColor:""};case"shadow":return{textColor:t?(0,s.bM)(t,c.K.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,i.q)((0,s.bM)(t,c.K.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.bM)(t,c.K.text).textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",bgColor:t?(0,i.q)((0,s.bM)(t,c.K.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.bM)(t,c.K.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,i.q)((0,s.bM)(t,c.K.background).bgColor,"bg-opacity-20"):"bg-tremor-background dark:bg-dark-tremor-background",borderColor:t?(0,s.bM)(t,c.K.ring).borderColor:"border-tremor-brand-subtle dark:border-dark-tremor-brand-subtle",ringColor:t?(0,i.q)((0,s.bM)(t,c.K.ring).ringColor,"ring-opacity-40"):"ring-tremor-brand-muted dark:ring-dark-tremor-brand-muted"}}},p=(0,s.fn)("Icon"),h=o.forwardRef((e,t)=>{let{icon:r,variant:c="simple",tooltip:h,size:b=l.u8.SM,color:g,className:v}=e,y=(0,n._T)(e,["icon","variant","tooltip","size","color","className"]),w=f(c,g),{tooltipProps:k,getReferenceProps:x}=(0,a.l)();return o.createElement("span",Object.assign({ref:(0,s.lq)([t,k.refs.setReference]),className:(0,i.q)(p("root"),"inline-flex shrink-0 items-center justify-center",w.bgColor,w.textColor,w.borderColor,w.ringColor,m[c].rounded,m[c].border,m[c].shadow,m[c].ring,u[b].paddingX,u[b].paddingY,v)},x,y),o.createElement(a.Z,Object.assign({text:h},k)),o.createElement(r,{className:(0,i.q)(p("icon"),"shrink-0",d[b].height,d[b].width)}))});h.displayName="Icon"},30150:function(e,t,r){"use strict";r.d(t,{Z:function(){return m}});var n=r(5853),o=r(2265);let a=e=>{var t=(0,n._T)(e,[]);return o.createElement("svg",Object.assign({},t,{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:"2.5"}),o.createElement("path",{d:"M12 4v16m8-8H4"}))},l=e=>{var t=(0,n._T)(e,[]);return o.createElement("svg",Object.assign({},t,{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:"2.5"}),o.createElement("path",{d:"M20 12H4"}))};var i=r(13241),s=r(1153),c=r(69262);let u="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",m=o.forwardRef((e,t)=>{let{onSubmit:r,enableStepper:m=!0,disabled:f,onValueChange:p,onChange:h}=e,b=(0,n._T)(e,["onSubmit","enableStepper","disabled","onValueChange","onChange"]),g=(0,o.useRef)(null),[v,y]=o.useState(!1),w=o.useCallback(()=>{y(!0)},[]),k=o.useCallback(()=>{y(!1)},[]),[x,C]=o.useState(!1),E=o.useCallback(()=>{C(!0)},[]),S=o.useCallback(()=>{C(!1)},[]);return o.createElement(c.Z,Object.assign({type:"number",ref:(0,s.lq)([g,t]),disabled:f,makeInputClassName:(0,s.fn)("NumberInput"),onKeyDown:e=>{var t;if("Enter"===e.key&&!e.ctrlKey&&!e.altKey&&!e.shiftKey){let e=null===(t=g.current)||void 0===t?void 0:t.value;null==r||r(parseFloat(null!=e?e:""))}"ArrowDown"===e.key&&w(),"ArrowUp"===e.key&&E()},onKeyUp:e=>{"ArrowDown"===e.key&&k(),"ArrowUp"===e.key&&S()},onChange:e=>{f||(null==p||p(parseFloat(e.target.value)),null==h||h(e))},stepper:m?o.createElement("div",{className:(0,i.q)("flex justify-center align-middle")},o.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=g.current)||void 0===e||e.stepDown(),null===(t=g.current)||void 0===t||t.dispatchEvent(new Event("input",{bubbles:!0})))},className:(0,i.q)(!f&&d,u,"group py-[10px] px-2.5 border-l border-tremor-border dark:border-dark-tremor-border")},o.createElement(l,{"data-testid":"step-down",className:(v?"scale-95":"")+" h-4 w-4 duration-75 transition group-active:scale-95"})),o.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=g.current)||void 0===e||e.stepUp(),null===(t=g.current)||void 0===t||t.dispatchEvent(new Event("input",{bubbles:!0})))},className:(0,i.q)(!f&&d,u,"group py-[10px] px-2.5 border-l border-tremor-border dark:border-dark-tremor-border")},o.createElement(a,{"data-testid":"step-up",className:(x?"scale-95":"")+" h-4 w-4 duration-75 transition group-active:scale-95"}))):null},b))});m.displayName="NumberInput"},27281:function(e,t,r){"use strict";r.d(t,{Z:function(){return p}});var n=r(5853),o=r(58747),a=r(2265),l=r(4537),i=r(13241),s=r(1153),c=r(96398),u=r(51975),d=r(85238),m=r(44140);let f=(0,s.fn)("Select"),p=a.forwardRef((e,t)=>{let{defaultValue:r="",value:s,onValueChange:p,placeholder:h="Select...",disabled:b=!1,icon:g,enableClear:v=!1,required:y,children:w,name:k,error:x=!1,errorMessage:C,className:E,id:S}=e,O=(0,n._T)(e,["defaultValue","value","onValueChange","placeholder","disabled","icon","enableClear","required","children","name","error","errorMessage","className","id"]),j=(0,a.useRef)(null),N=a.Children.toArray(w),[_,R]=(0,m.Z)(r,s),T=(0,a.useMemo)(()=>{let e=a.Children.toArray(w).filter(a.isValidElement);return(0,c.sl)(e)},[w]);return a.createElement("div",{className:(0,i.q)("w-full min-w-[10rem] text-tremor-default",E)},a.createElement("div",{className:"relative"},a.createElement("select",{title:"select-hidden",required:y,className:(0,i.q)("h-full w-full absolute left-0 top-0 -z-10 opacity-0"),value:_,onChange:e=>{e.preventDefault()},name:k,disabled:b,id:S,onFocus:()=>{let e=j.current;e&&e.focus()}},a.createElement("option",{className:"hidden",value:"",disabled:!0,hidden:!0},h),N.map(e=>{let t=e.props.value,r=e.props.children;return a.createElement("option",{className:"hidden",key:t,value:t},r)})),a.createElement(u.Ri,Object.assign({as:"div",ref:t,defaultValue:_,value:_,onChange:e=>{null==p||p(e),R(e)},disabled:b,id:S},O),e=>{var t;let{value:r}=e;return a.createElement(a.Fragment,null,a.createElement(u.Y4,{ref:j,className:(0,i.q)("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",g?"pl-10":"pl-3",(0,c.um)((0,c.Uh)(r),b,x))},g&&a.createElement("span",{className:(0,i.q)("absolute inset-y-0 left-0 flex items-center ml-px pl-2.5")},a.createElement(g,{className:(0,i.q)(f("Icon"),"flex-none h-5 w-5","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle")})),a.createElement("span",{className:"w-[90%] block truncate"},r&&null!==(t=T.get(r))&&void 0!==t?t:h),a.createElement("span",{className:(0,i.q)("absolute inset-y-0 right-0 flex items-center mr-3")},a.createElement(o.Z,{className:(0,i.q)(f("arrowDownIcon"),"flex-none h-5 w-5","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle")}))),v&&_?a.createElement("button",{type:"button",className:(0,i.q)("absolute inset-y-0 right-0 flex items-center mr-8"),onClick:e=>{e.preventDefault(),R(""),null==p||p("")}},a.createElement(l.Z,{className:(0,i.q)(f("clearIcon"),"flex-none h-4 w-4","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle")})):null,a.createElement(d.u,{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.createElement(u.O_,{anchor:"bottom start",className:(0,i.q)("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")},w)))})),x&&C?a.createElement("p",{className:(0,i.q)("errorMessage","text-sm text-rose-500 mt-1")},C):null)});p.displayName="Select"},59341:function(e,t,r){"use strict";r.d(t,{Z:function(){return M}});var n=r(5853),o=r(71049),a=r(11323),l=r(2265),i=r(66797),s=r(40099),c=r(74275),u=r(59456),d=r(93980),m=r(65573),f=r(67561),p=r(87550),h=r(628),b=r(80281),g=r(31370),v=r(20131),y=r(38929),w=r(52307),k=r(52724),x=r(7935);let C=(0,l.createContext)(null);C.displayName="GroupContext";let E=l.Fragment,S=Object.assign((0,y.yV)(function(e,t){var r;let n=(0,l.useId)(),E=(0,b.Q)(),S=(0,p.B)(),{id:O=E||"headlessui-switch-".concat(n),disabled:j=S||!1,checked:N,defaultChecked:_,onChange:R,name:T,value:M,form:P,autoFocus:z=!1,...L}=e,I=(0,l.useContext)(C),[Z,F]=(0,l.useState)(null),B=(0,l.useRef)(null),D=(0,f.T)(B,t,null===I?null:I.setSwitch,F),q=(0,c.L)(_),[A,W]=(0,s.q)(N,R,null!=q&&q),H=(0,u.G)(),[V,K]=(0,l.useState)(!1),U=(0,d.z)(()=>{K(!0),null==W||W(!A),H.nextFrame(()=>{K(!1)})}),X=(0,d.z)(e=>{if((0,g.P)(e.currentTarget))return e.preventDefault();e.preventDefault(),U()}),Y=(0,d.z)(e=>{e.key===k.R.Space?(e.preventDefault(),U()):e.key===k.R.Enter&&(0,v.g)(e.currentTarget)}),G=(0,d.z)(e=>e.preventDefault()),$=(0,x.wp)(),J=(0,w.zH)(),{isFocusVisible:Q,focusProps:ee}=(0,o.F)({autoFocus:z}),{isHovered:et,hoverProps:er}=(0,a.X)({isDisabled:j}),{pressed:en,pressProps:eo}=(0,i.x)({disabled:j}),ea=(0,l.useMemo)(()=>({checked:A,disabled:j,hover:et,focus:Q,active:en,autofocus:z,changing:V}),[A,et,Q,en,j,V,z]),el=(0,y.dG)({id:O,ref:D,role:"switch",type:(0,m.f)(e,Z),tabIndex:-1===e.tabIndex?0:null!=(r=e.tabIndex)?r:0,"aria-checked":A,"aria-labelledby":$,"aria-describedby":J,disabled:j||void 0,autoFocus:z,onClick:X,onKeyUp:Y,onKeyPress:G},ee,er,eo),ei=(0,l.useCallback)(()=>{if(void 0!==q)return null==W?void 0:W(q)},[W,q]),es=(0,y.L6)();return l.createElement(l.Fragment,null,null!=T&&l.createElement(h.Mt,{disabled:j,data:{[T]:M||"on"},overrides:{type:"checkbox",checked:A},form:P,onReset:ei}),es({ourProps:el,theirProps:L,slot:ea,defaultTag:"button",name:"Switch"}))}),{Group:function(e){var t;let[r,n]=(0,l.useState)(null),[o,a]=(0,x.bE)(),[i,s]=(0,w.fw)(),c=(0,l.useMemo)(()=>({switch:r,setSwitch:n}),[r,n]),u=(0,y.L6)();return l.createElement(s,{name:"Switch.Description",value:i},l.createElement(a,{name:"Switch.Label",value:o,props:{htmlFor:null==(t=c.switch)?void 0:t.id,onClick(e){r&&(e.currentTarget instanceof HTMLLabelElement&&e.preventDefault(),r.click(),r.focus({preventScroll:!0}))}}},l.createElement(C.Provider,{value:c},u({ourProps:{},theirProps:e,slot:{},defaultTag:E,name:"Switch.Group"}))))},Label:x.__,Description:w.dk});var O=r(44140),j=r(26898),N=r(13241),_=r(1153),R=r(47187);let T=(0,_.fn)("Switch"),M=l.forwardRef((e,t)=>{let{checked:r,defaultChecked:o=!1,onChange:a,color:i,name:s,error:c,errorMessage:u,disabled:d,required:m,tooltip:f,id:p}=e,h=(0,n._T)(e,["checked","defaultChecked","onChange","color","name","error","errorMessage","disabled","required","tooltip","id"]),b={bgColor:i?(0,_.bM)(i,j.K.background).bgColor:"bg-tremor-brand dark:bg-dark-tremor-brand",ringColor:i?(0,_.bM)(i,j.K.ring).ringColor:"ring-tremor-brand-muted dark:ring-dark-tremor-brand-muted"},[g,v]=(0,O.Z)(o,r),[y,w]=(0,l.useState)(!1),{tooltipProps:k,getReferenceProps:x}=(0,R.l)(300);return l.createElement("div",{className:"flex flex-row items-center justify-start"},l.createElement(R.Z,Object.assign({text:f},k)),l.createElement("div",Object.assign({ref:(0,_.lq)([t,k.refs.setReference]),className:(0,N.q)(T("root"),"flex flex-row relative h-5")},h,x),l.createElement("input",{type:"checkbox",className:(0,N.q)(T("input"),"absolute w-5 h-5 cursor-pointer left-0 top-0 opacity-0"),name:s,required:m,checked:g,onChange:e=>{e.preventDefault()}}),l.createElement(S,{checked:g,onChange:e=>{v(e),null==a||a(e)},disabled:d,className:(0,N.q)(T("switch"),"w-10 h-5 group relative inline-flex shrink-0 cursor-pointer items-center justify-center rounded-tremor-full","focus:outline-none",d?"cursor-not-allowed":""),onFocus:()=>w(!0),onBlur:()=>w(!1),id:p},l.createElement("span",{className:(0,N.q)(T("sr-only"),"sr-only")},"Switch ",g?"on":"off"),l.createElement("span",{"aria-hidden":"true",className:(0,N.q)(T("background"),g?b.bgColor:"bg-tremor-border dark:bg-dark-tremor-border","pointer-events-none absolute mx-auto h-3 w-9 rounded-tremor-full transition-colors duration-100 ease-in-out")}),l.createElement("span",{"aria-hidden":"true",className:(0,N.q)(T("round"),g?(0,N.q)(b.bgColor,"translate-x-5 border-tremor-background dark:border-dark-tremor-background"):"translate-x-0 bg-tremor-border dark:bg-dark-tremor-border border-tremor-background dark:border-dark-tremor-background","pointer-events-none absolute left-0 inline-block h-5 w-5 transform rounded-tremor-full border-2 shadow-tremor-input duration-100 ease-in-out transition",y?(0,N.q)("ring-2",b.ringColor):"")}))),c&&u?l.createElement("p",{className:(0,N.q)(T("errorMessage"),"text-sm text-red-500 mt-1 ")},u):null)});M.displayName="Switch"},87452:function(e,t,r){"use strict";r.d(t,{Z:function(){return d},r:function(){return u}});var n=r(5853),o=r(91054);r(42698),r(64016);var a=r(8710);r(33232);var l=r(13241),i=r(1153),s=r(2265);let c=(0,i.fn)("Accordion"),u=(0,s.createContext)({isOpen:!1}),d=s.forwardRef((e,t)=>{var r;let{defaultOpen:i=!1,children:d,className:m}=e,f=(0,n._T)(e,["defaultOpen","children","className"]),p=null!==(r=(0,s.useContext)(a.Z))&&void 0!==r?r:(0,l.q)("rounded-tremor-default border");return s.createElement(o.pJ,Object.assign({as:"div",ref:t,className:(0,l.q)(c("root"),"overflow-hidden","bg-tremor-background border-tremor-border","dark:bg-dark-tremor-background dark:border-dark-tremor-border",p,m),defaultOpen:i},f),e=>{let{open:t}=e;return s.createElement(u.Provider,{value:{isOpen:t}},d)})});d.displayName="Accordion"},88829:function(e,t,r){"use strict";r.d(t,{Z:function(){return s}});var n=r(5853),o=r(2265),a=r(91054),l=r(13241);let i=(0,r(1153).fn)("AccordionBody"),s=o.forwardRef((e,t)=>{let{children:r,className:s}=e,c=(0,n._T)(e,["children","className"]);return o.createElement(a.pJ.Panel,Object.assign({ref:t,className:(0,l.q)(i("root"),"w-full text-tremor-default px-4 pb-3","text-tremor-content","dark:text-dark-tremor-content",s)},c),r)});s.displayName="AccordionBody"},72208:function(e,t,r){"use strict";r.d(t,{Z:function(){return u}});var n=r(5853),o=r(2265),a=r(91054);let l=e=>{var t=(0,n._T)(e,[]);return o.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"},t),o.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 i=r(87452),s=r(13241);let c=(0,r(1153).fn)("AccordionHeader"),u=o.forwardRef((e,t)=>{let{children:r,className:u}=e,d=(0,n._T)(e,["children","className"]),{isOpen:m}=(0,o.useContext)(i.r);return o.createElement(a.pJ.Button,Object.assign({ref:t,className:(0,s.q)(c("root"),"w-full flex items-center justify-between px-4 py-3","text-tremor-content-emphasis","dark:text-dark-tremor-content-emphasis",u)},d),o.createElement("div",{className:(0,s.q)(c("children"),"flex flex-1 text-inherit mr-4")},r),o.createElement("div",null,o.createElement(l,{className:(0,s.q)(c("arrowIcon"),"h-5 w-5 -mr-1","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle",m?"transition-all":"transition-all -rotate-180")})))});u.displayName="AccordionHeader"},49804:function(e,t,r){"use strict";r.d(t,{Z:function(){return c}});var n=r(5853),o=r(13241),a=r(1153),l=r(2265),i=r(9496);let s=(0,a.fn)("Col"),c=l.forwardRef((e,t)=>{let{numColSpan:r=1,numColSpanSm:a,numColSpanMd:c,numColSpanLg:u,children:d,className:m}=e,f=(0,n._T)(e,["numColSpan","numColSpanSm","numColSpanMd","numColSpanLg","children","className"]),p=(e,t)=>e&&Object.keys(t).includes(String(e))?t[e]:"";return l.createElement("div",Object.assign({ref:t,className:(0,o.q)(s("root"),(()=>{let e=p(r,i.PT),t=p(a,i.SP),n=p(c,i.VS),l=p(u,i._w);return(0,o.q)(e,t,n,l)})(),m)},f),d)});c.displayName="Col"},97765:function(e,t,r){"use strict";r.d(t,{Z:function(){return s}});var n=r(5853),o=r(26898),a=r(13241),l=r(1153),i=r(2265);let s=i.forwardRef((e,t)=>{let{color:r,children:s,className:c}=e,u=(0,n._T)(e,["color","children","className"]);return i.createElement("p",Object.assign({ref:t,className:(0,a.q)(r?(0,l.bM)(r,o.K.lightText).textColor:"text-tremor-content-emphasis dark:text-dark-tremor-content-emphasis",c)},u),s)});s.displayName="Subtitle"},92570:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=e=>e?"function"==typeof e?e():e:null},33866:function(e,t,r){"use strict";r.d(t,{Z:function(){return P}});var n=r(2265),o=r(36760),a=r.n(o),l=r(66632),i=r(93350),s=r(19722),c=r(71744),u=r(93463),d=r(12918),m=r(18536),f=r(71140),p=r(99320);let h=new u.E4("antStatusProcessing",{"0%":{transform:"scale(0.8)",opacity:.5},"100%":{transform:"scale(2.4)",opacity:0}}),b=new u.E4("antZoomBadgeIn",{"0%":{transform:"scale(0) translate(50%, -50%)",opacity:0},"100%":{transform:"scale(1) translate(50%, -50%)"}}),g=new u.E4("antZoomBadgeOut",{"0%":{transform:"scale(1) translate(50%, -50%)"},"100%":{transform:"scale(0) translate(50%, -50%)",opacity:0}}),v=new u.E4("antNoWrapperZoomBadgeIn",{"0%":{transform:"scale(0)",opacity:0},"100%":{transform:"scale(1)"}}),y=new u.E4("antNoWrapperZoomBadgeOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0)",opacity:0}}),w=new u.E4("antBadgeLoadingCircle",{"0%":{transformOrigin:"50%"},"100%":{transform:"translate(50%, -50%) rotate(360deg)",transformOrigin:"50%"}}),k=e=>{let{componentCls:t,iconCls:r,antCls:n,badgeShadowSize:o,textFontSize:a,textFontSizeSM:l,statusSize:i,dotSize:s,textFontWeight:c,indicatorHeight:f,indicatorHeightSM:p,marginXS:k,calc:x}=e,C="".concat(n,"-scroll-number"),E=(0,m.Z)(e,(e,r)=>{let{darkColor:n}=r;return{["&".concat(t," ").concat(t,"-color-").concat(e)]:{background:n,["&:not(".concat(t,"-count)")]:{color:n},"a:hover &":{background:n}}}});return{[t]:Object.assign(Object.assign(Object.assign(Object.assign({},(0,d.Wf)(e)),{position:"relative",display:"inline-block",width:"fit-content",lineHeight:1,["".concat(t,"-count")]:{display:"inline-flex",justifyContent:"center",zIndex:e.indicatorZIndex,minWidth:f,height:f,color:e.badgeTextColor,fontWeight:c,fontSize:a,lineHeight:(0,u.bf)(f),whiteSpace:"nowrap",textAlign:"center",background:e.badgeColor,borderRadius:x(f).div(2).equal(),boxShadow:"0 0 0 ".concat((0,u.bf)(o)," ").concat(e.badgeShadowColor),transition:"background ".concat(e.motionDurationMid),a:{color:e.badgeTextColor},"a:hover":{color:e.badgeTextColor},"a:hover &":{background:e.badgeColorHover}},["".concat(t,"-count-sm")]:{minWidth:p,height:p,fontSize:l,lineHeight:(0,u.bf)(p),borderRadius:x(p).div(2).equal()},["".concat(t,"-multiple-words")]:{padding:"0 ".concat((0,u.bf)(e.paddingXS)),bdi:{unicodeBidi:"plaintext"}},["".concat(t,"-dot")]:{zIndex:e.indicatorZIndex,width:s,minWidth:s,height:s,background:e.badgeColor,borderRadius:"100%",boxShadow:"0 0 0 ".concat((0,u.bf)(o)," ").concat(e.badgeShadowColor)},["".concat(t,"-count, ").concat(t,"-dot, ").concat(C,"-custom-component")]:{position:"absolute",top:0,insetInlineEnd:0,transform:"translate(50%, -50%)",transformOrigin:"100% 0%",["&".concat(r,"-spin")]:{animationName:w,animationDuration:"1s",animationIterationCount:"infinite",animationTimingFunction:"linear"}},["&".concat(t,"-status")]:{lineHeight:"inherit",verticalAlign:"baseline",["".concat(t,"-status-dot")]:{position:"relative",top:-1,display:"inline-block",width:i,height:i,verticalAlign:"middle",borderRadius:"50%"},["".concat(t,"-status-success")]:{backgroundColor:e.colorSuccess},["".concat(t,"-status-processing")]:{overflow:"visible",color:e.colorInfo,backgroundColor:e.colorInfo,borderColor:"currentcolor","&::after":{position:"absolute",top:0,insetInlineStart:0,width:"100%",height:"100%",borderWidth:o,borderStyle:"solid",borderColor:"inherit",borderRadius:"50%",animationName:h,animationDuration:e.badgeProcessingDuration,animationIterationCount:"infinite",animationTimingFunction:"ease-in-out",content:'""'}},["".concat(t,"-status-default")]:{backgroundColor:e.colorTextPlaceholder},["".concat(t,"-status-error")]:{backgroundColor:e.colorError},["".concat(t,"-status-warning")]:{backgroundColor:e.colorWarning},["".concat(t,"-status-text")]:{marginInlineStart:k,color:e.colorText,fontSize:e.fontSize}}}),E),{["".concat(t,"-zoom-appear, ").concat(t,"-zoom-enter")]:{animationName:b,animationDuration:e.motionDurationSlow,animationTimingFunction:e.motionEaseOutBack,animationFillMode:"both"},["".concat(t,"-zoom-leave")]:{animationName:g,animationDuration:e.motionDurationSlow,animationTimingFunction:e.motionEaseOutBack,animationFillMode:"both"},["&".concat(t,"-not-a-wrapper")]:{["".concat(t,"-zoom-appear, ").concat(t,"-zoom-enter")]:{animationName:v,animationDuration:e.motionDurationSlow,animationTimingFunction:e.motionEaseOutBack},["".concat(t,"-zoom-leave")]:{animationName:y,animationDuration:e.motionDurationSlow,animationTimingFunction:e.motionEaseOutBack},["&:not(".concat(t,"-status)")]:{verticalAlign:"middle"},["".concat(C,"-custom-component, ").concat(t,"-count")]:{transform:"none"},["".concat(C,"-custom-component, ").concat(C)]:{position:"relative",top:"auto",display:"block",transformOrigin:"50% 50%"}},[C]:{overflow:"hidden",transition:"all ".concat(e.motionDurationMid," ").concat(e.motionEaseOutBack),["".concat(C,"-only")]:{position:"relative",display:"inline-block",height:f,transition:"all ".concat(e.motionDurationSlow," ").concat(e.motionEaseOutBack),WebkitTransformStyle:"preserve-3d",WebkitBackfaceVisibility:"hidden",["> p".concat(C,"-only-unit")]:{height:f,margin:0,WebkitTransformStyle:"preserve-3d",WebkitBackfaceVisibility:"hidden"}},["".concat(C,"-symbol")]:{verticalAlign:"top"}},"&-rtl":{direction:"rtl",["".concat(t,"-count, ").concat(t,"-dot, ").concat(C,"-custom-component")]:{transform:"translate(-50%, -50%)"}}})}},x=e=>{let{fontHeight:t,lineWidth:r,marginXS:n,colorBorderBg:o}=e,a=e.colorTextLightSolid,l=e.colorError,i=e.colorErrorHover;return(0,f.IX)(e,{badgeFontHeight:t,badgeShadowSize:r,badgeTextColor:a,badgeColor:l,badgeColorHover:i,badgeShadowColor:o,badgeProcessingDuration:"1.2s",badgeRibbonOffset:n,badgeRibbonCornerTransform:"scaleY(0.75)",badgeRibbonCornerFilter:"brightness(75%)"})},C=e=>{let{fontSize:t,lineHeight:r,fontSizeSM:n,lineWidth:o}=e;return{indicatorZIndex:"auto",indicatorHeight:Math.round(t*r)-2*o,indicatorHeightSM:t,dotSize:n/2,textFontSize:n,textFontSizeSM:n,textFontWeight:"normal",statusSize:n/2}};var E=(0,p.I$)("Badge",e=>k(x(e)),C);let S=e=>{let{antCls:t,badgeFontHeight:r,marginXS:n,badgeRibbonOffset:o,calc:a}=e,l="".concat(t,"-ribbon"),i=(0,m.Z)(e,(e,t)=>{let{darkColor:r}=t;return{["&".concat(l,"-color-").concat(e)]:{background:r,color:r}}});return{["".concat(t,"-ribbon-wrapper")]:{position:"relative"},[l]:Object.assign(Object.assign(Object.assign(Object.assign({},(0,d.Wf)(e)),{position:"absolute",top:n,padding:"0 ".concat((0,u.bf)(e.paddingXS)),color:e.colorPrimary,lineHeight:(0,u.bf)(r),whiteSpace:"nowrap",backgroundColor:e.colorPrimary,borderRadius:e.borderRadiusSM,["".concat(l,"-text")]:{color:e.badgeTextColor},["".concat(l,"-corner")]:{position:"absolute",top:"100%",width:o,height:o,color:"currentcolor",border:"".concat((0,u.bf)(a(o).div(2).equal())," solid"),transform:e.badgeRibbonCornerTransform,transformOrigin:"top",filter:e.badgeRibbonCornerFilter}}),i),{["&".concat(l,"-placement-end")]:{insetInlineEnd:a(o).mul(-1).equal(),borderEndEndRadius:0,["".concat(l,"-corner")]:{insetInlineEnd:0,borderInlineEndColor:"transparent",borderBlockEndColor:"transparent"}},["&".concat(l,"-placement-start")]:{insetInlineStart:a(o).mul(-1).equal(),borderEndStartRadius:0,["".concat(l,"-corner")]:{insetInlineStart:0,borderBlockEndColor:"transparent",borderInlineStartColor:"transparent"}},"&-rtl":{direction:"rtl"}})}};var O=(0,p.I$)(["Badge","Ribbon"],e=>S(x(e)),C);let j=e=>{let t;let{prefixCls:r,value:o,current:l,offset:i=0}=e;return i&&(t={position:"absolute",top:"".concat(i,"00%"),left:0}),n.createElement("span",{style:t,className:a()("".concat(r,"-only-unit"),{current:l})},o)};var N=e=>{let t,r;let{prefixCls:o,count:a,value:l}=e,i=Number(l),s=Math.abs(a),[c,u]=n.useState(i),[d,m]=n.useState(s),f=()=>{u(i),m(s)};if(n.useEffect(()=>{let e=setTimeout(f,1e3);return()=>clearTimeout(e)},[i]),c===i||Number.isNaN(i)||Number.isNaN(c))t=[n.createElement(j,Object.assign({},e,{key:i,current:!0}))],r={transition:"none"};else{t=[];let o=i+10,a=[];for(let e=i;e<=o;e+=1)a.push(e);let l=de%10===c);t=(l<0?a.slice(0,u+1):a.slice(u)).map((t,r)=>n.createElement(j,Object.assign({},e,{key:t,value:t%10,offset:l<0?r-u:r,current:r===u}))),r={transform:"translateY(".concat(-function(e,t,r){let n=e,o=0;for(;(n+10)%10!==t;)n+=r,o+=r;return o}(c,i,l),"00%)")}}return n.createElement("span",{className:"".concat(o,"-only"),style:r,onTransitionEnd:f},t)},_=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 R=n.forwardRef((e,t)=>{let{prefixCls:r,count:o,className:l,motionClassName:i,style:u,title:d,show:m,component:f="sup",children:p}=e,h=_(e,["prefixCls","count","className","motionClassName","style","title","show","component","children"]),{getPrefixCls:b}=n.useContext(c.E_),g=b("scroll-number",r),v=Object.assign(Object.assign({},h),{"data-show":m,style:u,className:a()(g,l,i),title:d}),y=o;if(o&&Number(o)%1==0){let e=String(o).split("");y=n.createElement("bdi",null,e.map((t,r)=>n.createElement(N,{prefixCls:g,count:Number(o),value:t,key:e.length-r})))}return((null==u?void 0:u.borderColor)&&(v.style=Object.assign(Object.assign({},u),{boxShadow:"0 0 0 1px ".concat(u.borderColor," inset")})),p)?(0,s.Tm)(p,e=>({className:a()("".concat(g,"-custom-component"),null==e?void 0:e.className,i)})):n.createElement(f,Object.assign({},v,{ref:t}),y)});var T=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 M=n.forwardRef((e,t)=>{var r,o,u,d,m;let{prefixCls:f,scrollNumberPrefixCls:p,children:h,status:b,text:g,color:v,count:y=null,overflowCount:w=99,dot:k=!1,size:x="default",title:C,offset:S,style:O,className:j,rootClassName:N,classNames:_,styles:M,showZero:P=!1}=e,z=T(e,["prefixCls","scrollNumberPrefixCls","children","status","text","color","count","overflowCount","dot","size","title","offset","style","className","rootClassName","classNames","styles","showZero"]),{getPrefixCls:L,direction:I,badge:Z}=n.useContext(c.E_),F=L("badge",f),[B,D,q]=E(F),A=y>w?"".concat(w,"+"):y,W="0"===A||0===A||"0"===g||0===g,H=null===y||W&&!P,V=(null!=b||null!=v)&&H,K=null!=b||!W,U=k&&!W,X=U?"":A,Y=(0,n.useMemo)(()=>((null==X||""===X)&&(null==g||""===g)||W&&!P)&&!U,[X,W,P,U,g]),G=(0,n.useRef)(y);Y||(G.current=y);let $=G.current,J=(0,n.useRef)(X);Y||(J.current=X);let Q=J.current,ee=(0,n.useRef)(U);Y||(ee.current=U);let et=(0,n.useMemo)(()=>{if(!S)return Object.assign(Object.assign({},null==Z?void 0:Z.style),O);let e={marginTop:S[1]};return"rtl"===I?e.left=Number.parseInt(S[0],10):e.right=-Number.parseInt(S[0],10),Object.assign(Object.assign(Object.assign({},e),null==Z?void 0:Z.style),O)},[I,S,O,null==Z?void 0:Z.style]),er=null!=C?C:"string"==typeof $||"number"==typeof $?$:void 0,en=!Y&&(0===g?P:!!g&&!0!==g),eo=en?n.createElement("span",{className:"".concat(F,"-status-text")},g):null,ea=$&&"object"==typeof $?(0,s.Tm)($,e=>({style:Object.assign(Object.assign({},et),e.style)})):void 0,el=(0,i.o2)(v,!1),ei=a()(null==_?void 0:_.indicator,null===(r=null==Z?void 0:Z.classNames)||void 0===r?void 0:r.indicator,{["".concat(F,"-status-dot")]:V,["".concat(F,"-status-").concat(b)]:!!b,["".concat(F,"-color-").concat(v)]:el}),es={};v&&!el&&(es.color=v,es.background=v);let ec=a()(F,{["".concat(F,"-status")]:V,["".concat(F,"-not-a-wrapper")]:!h,["".concat(F,"-rtl")]:"rtl"===I},j,N,null==Z?void 0:Z.className,null===(o=null==Z?void 0:Z.classNames)||void 0===o?void 0:o.root,null==_?void 0:_.root,D,q);if(!h&&V&&(g||K||!H)){let e=et.color;return B(n.createElement("span",Object.assign({},z,{className:ec,style:Object.assign(Object.assign(Object.assign({},null==M?void 0:M.root),null===(u=null==Z?void 0:Z.styles)||void 0===u?void 0:u.root),et)}),n.createElement("span",{className:ei,style:Object.assign(Object.assign(Object.assign({},null==M?void 0:M.indicator),null===(d=null==Z?void 0:Z.styles)||void 0===d?void 0:d.indicator),es)}),en&&n.createElement("span",{style:{color:e},className:"".concat(F,"-status-text")},g)))}return B(n.createElement("span",Object.assign({ref:t},z,{className:ec,style:Object.assign(Object.assign({},null===(m=null==Z?void 0:Z.styles)||void 0===m?void 0:m.root),null==M?void 0:M.root)}),h,n.createElement(l.ZP,{visible:!Y,motionName:"".concat(F,"-zoom"),motionAppear:!1,motionDeadline:1e3},e=>{var t,r;let{className:o}=e,l=L("scroll-number",p),i=ee.current,s=a()(null==_?void 0:_.indicator,null===(t=null==Z?void 0:Z.classNames)||void 0===t?void 0:t.indicator,{["".concat(F,"-dot")]:i,["".concat(F,"-count")]:!i,["".concat(F,"-count-sm")]:"small"===x,["".concat(F,"-multiple-words")]:!i&&Q&&Q.toString().length>1,["".concat(F,"-status-").concat(b)]:!!b,["".concat(F,"-color-").concat(v)]:el}),c=Object.assign(Object.assign(Object.assign({},null==M?void 0:M.indicator),null===(r=null==Z?void 0:Z.styles)||void 0===r?void 0:r.indicator),et);return v&&!el&&((c=c||{}).background=v),n.createElement(R,{prefixCls:l,show:!Y,motionClassName:o,className:s,count:Q,title:er,style:c,key:"scrollNumber"},ea)}),eo))});M.Ribbon=e=>{let{className:t,prefixCls:r,style:o,color:l,children:s,text:u,placement:d="end",rootClassName:m}=e,{getPrefixCls:f,direction:p}=n.useContext(c.E_),h=f("ribbon",r),b="".concat(h,"-wrapper"),[g,v,y]=O(h,b),w=(0,i.o2)(l,!1),k=a()(h,"".concat(h,"-placement-").concat(d),{["".concat(h,"-rtl")]:"rtl"===p,["".concat(h,"-color-").concat(l)]:w},t),x={},C={};return l&&!w&&(x.background=l,C.color=l),g(n.createElement("div",{className:a()(b,m,v,y)},s,n.createElement("div",{className:a()(k,v),style:Object.assign(Object.assign({},x),o)},n.createElement("span",{className:"".concat(h,"-text")},u),n.createElement("div",{className:"".concat(h,"-corner"),style:C}))))};var P=M},20435:function(e,t,r){"use strict";r.d(t,{aV:function(){return d}});var n=r(2265),o=r(36760),a=r.n(o),l=r(5769),i=r(92570),s=r(71744),c=r(72262),u=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 d=e=>{let{title:t,content:r,prefixCls:o}=e;return t||r?n.createElement(n.Fragment,null,t&&n.createElement("div",{className:"".concat(o,"-title")},t),r&&n.createElement("div",{className:"".concat(o,"-inner-content")},r)):null},m=e=>{let{hashId:t,prefixCls:r,className:o,style:s,placement:c="top",title:u,content:m,children:f}=e,p=(0,i.Z)(u),h=(0,i.Z)(m),b=a()(t,r,"".concat(r,"-pure"),"".concat(r,"-placement-").concat(c),o);return n.createElement("div",{className:b,style:s},n.createElement("div",{className:"".concat(r,"-arrow")}),n.createElement(l.G,Object.assign({},e,{className:t,prefixCls:r}),f||n.createElement(d,{prefixCls:r,title:p,content:h})))};t.ZP=e=>{let{prefixCls:t,className:r}=e,o=u(e,["prefixCls","className"]),{getPrefixCls:l}=n.useContext(s.E_),i=l("popover",t),[d,f,p]=(0,c.Z)(i);return d(n.createElement(m,Object.assign({},o,{prefixCls:i,hashId:f,className:a()(r,p)})))}},79326:function(e,t,r){"use strict";var n=r(2265),o=r(36760),a=r.n(o),l=r(50506),i=r(95814),s=r(92570),c=r(68710),u=r(19722),d=r(71744),m=r(99981),f=r(20435),p=r(72262),h=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 b=n.forwardRef((e,t)=>{var r,o;let{prefixCls:b,title:g,content:v,overlayClassName:y,placement:w="top",trigger:k="hover",children:x,mouseEnterDelay:C=.1,mouseLeaveDelay:E=.1,onOpenChange:S,overlayStyle:O={},styles:j,classNames:N}=e,_=h(e,["prefixCls","title","content","overlayClassName","placement","trigger","children","mouseEnterDelay","mouseLeaveDelay","onOpenChange","overlayStyle","styles","classNames"]),{getPrefixCls:R,className:T,style:M,classNames:P,styles:z}=(0,d.dj)("popover"),L=R("popover",b),[I,Z,F]=(0,p.Z)(L),B=R(),D=a()(y,Z,F,T,P.root,null==N?void 0:N.root),q=a()(P.body,null==N?void 0:N.body),[A,W]=(0,l.Z)(!1,{value:null!==(r=e.open)&&void 0!==r?r:e.visible,defaultValue:null!==(o=e.defaultOpen)&&void 0!==o?o:e.defaultVisible}),H=(e,t)=>{W(e,!0),null==S||S(e,t)},V=e=>{e.keyCode===i.Z.ESC&&H(!1,e)},K=(0,s.Z)(g),U=(0,s.Z)(v);return I(n.createElement(m.Z,Object.assign({placement:w,trigger:k,mouseEnterDelay:C,mouseLeaveDelay:E},_,{prefixCls:L,classNames:{root:D,body:q},styles:{root:Object.assign(Object.assign(Object.assign(Object.assign({},z.root),M),O),null==j?void 0:j.root),body:Object.assign(Object.assign({},z.body),null==j?void 0:j.body)},ref:t,open:A,onOpenChange:e=>{H(e)},overlay:K||U?n.createElement(f.aV,{prefixCls:L,title:K,content:U}):null,transitionName:(0,c.m)(B,"zoom-big",_.transitionName),"data-popover-inject":!0}),(0,u.Tm)(x,{onKeyDown:e=>{var t,r;(0,n.isValidElement)(x)&&(null===(r=null==x?void 0:(t=x.props).onKeyDown)||void 0===r||r.call(t,e)),V(e)}})))});b._InternalPanelDoNotUseOrYouWillBeFired=f.ZP,t.Z=b},72262:function(e,t,r){"use strict";var n=r(12918),o=r(691),a=r(88260),l=r(34442),i=r(53454),s=r(99320),c=r(71140);let u=e=>{let{componentCls:t,popoverColor:r,titleMinWidth:o,fontWeightStrong:l,innerPadding:i,boxShadowSecondary:s,colorTextHeading:c,borderRadiusLG:u,zIndexPopup:d,titleMarginBottom:m,colorBgElevated:f,popoverBg:p,titleBorderBottom:h,innerContentPadding:b,titlePadding:g}=e;return[{[t]:Object.assign(Object.assign({},(0,n.Wf)(e)),{position:"absolute",top:0,left:{_skip_check_:!0,value:0},zIndex:d,fontWeight:"normal",whiteSpace:"normal",textAlign:"start",cursor:"auto",userSelect:"text","--valid-offset-x":"var(--arrow-offset-horizontal, var(--arrow-x))",transformOrigin:"var(--valid-offset-x, 50%) var(--arrow-y, 50%)","--antd-arrow-background-color":f,width:"max-content",maxWidth:"100vw","&-rtl":{direction:"rtl"},"&-hidden":{display:"none"},["".concat(t,"-content")]:{position:"relative"},["".concat(t,"-inner")]:{backgroundColor:p,backgroundClip:"padding-box",borderRadius:u,boxShadow:s,padding:i},["".concat(t,"-title")]:{minWidth:o,marginBottom:m,color:c,fontWeight:l,borderBottom:h,padding:g},["".concat(t,"-inner-content")]:{color:r,padding:b}})},(0,a.ZP)(e,"var(--antd-arrow-background-color)"),{["".concat(t,"-pure")]:{position:"relative",maxWidth:"none",margin:e.sizePopupArrow,display:"inline-block",["".concat(t,"-content")]:{display:"inline-block"}}}]},d=e=>{let{componentCls:t}=e;return{[t]:i.i.map(r=>{let n=e["".concat(r,"6")];return{["&".concat(t,"-").concat(r)]:{"--antd-arrow-background-color":n,["".concat(t,"-inner")]:{backgroundColor:n},["".concat(t,"-arrow")]:{background:"transparent"}}}})}};t.Z=(0,s.I$)("Popover",e=>{let{colorBgElevated:t,colorText:r}=e,n=(0,c.IX)(e,{popoverBg:t,popoverColor:r});return[u(n),d(n),(0,o._y)(n,"zoom-big")]},e=>{let{lineWidth:t,controlHeight:r,fontHeight:n,padding:o,wireframe:i,zIndexPopupBase:s,borderRadiusLG:c,marginXS:u,lineType:d,colorSplit:m,paddingSM:f}=e,p=r-n;return Object.assign(Object.assign(Object.assign({titleMinWidth:177,zIndexPopup:s+30},(0,l.w)(e)),(0,a.wZ)({contentRadius:c,limitVerticalRadius:!0})),{innerPadding:i?0:12,titleMarginBottom:i?0:u,titlePadding:i?"".concat(p/2,"px ").concat(o,"px ").concat(p/2-t,"px"):0,titleBorderBottom:i?"".concat(t,"px ").concat(d," ").concat(m):"none",innerContentPadding:i?"".concat(f,"px ").concat(o,"px"):0})},{resetStyle:!1,deprecatedTokens:[["width","titleMinWidth"],["minWidth","titleMinWidth"]]})},3810:function(e,t,r){"use strict";r.d(t,{Z:function(){return R}});var n=r(2265),o=r(36760),a=r.n(o),l=r(18694),i=r(93350),s=r(53445),c=r(19722),u=r(6694),d=r(71744),m=r(93463),f=r(54558),p=r(12918),h=r(71140),b=r(99320);let g=e=>{let{paddingXXS:t,lineWidth:r,tagPaddingHorizontal:n,componentCls:o,calc:a}=e,l=a(n).sub(r).equal(),i=a(t).sub(r).equal();return{[o]:Object.assign(Object.assign({},(0,p.Wf)(e)),{display:"inline-block",height:"auto",marginInlineEnd:e.marginXS,paddingInline:l,fontSize:e.tagFontSize,lineHeight:e.tagLineHeight,whiteSpace:"nowrap",background:e.defaultBg,border:"".concat((0,m.bf)(e.lineWidth)," ").concat(e.lineType," ").concat(e.colorBorder),borderRadius:e.borderRadiusSM,opacity:1,transition:"all ".concat(e.motionDurationMid),textAlign:"start",position:"relative",["&".concat(o,"-rtl")]:{direction:"rtl"},"&, a, a:hover":{color:e.defaultColor},["".concat(o,"-close-icon")]:{marginInlineStart:i,fontSize:e.tagIconSize,color:e.colorIcon,cursor:"pointer",transition:"all ".concat(e.motionDurationMid),"&:hover":{color:e.colorTextHeading}},["&".concat(o,"-has-color")]:{borderColor:"transparent",["&, a, a:hover, ".concat(e.iconCls,"-close, ").concat(e.iconCls,"-close:hover")]:{color:e.colorTextLightSolid}},"&-checkable":{backgroundColor:"transparent",borderColor:"transparent",cursor:"pointer",["&:not(".concat(o,"-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"},["> ".concat(e.iconCls," + span, > span + ").concat(e.iconCls)]:{marginInlineStart:l}}),["".concat(o,"-borderless")]:{borderColor:"transparent",background:e.tagBorderlessBg}}},v=e=>{let{lineWidth:t,fontSizeIcon:r,calc:n}=e,o=e.fontSizeSM;return(0,h.IX)(e,{tagFontSize:o,tagLineHeight:(0,m.bf)(n(e.lineHeightSM).mul(o).equal()),tagIconSize:n(r).sub(n(t).mul(2)).equal(),tagPaddingHorizontal:8,tagBorderlessBg:e.defaultBg})},y=e=>({defaultBg:new f.t(e.colorFillQuaternary).onBackground(e.colorBgContainer).toHexString(),defaultColor:e.colorText});var w=(0,b.I$)("Tag",e=>g(v(e)),y),k=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 x=n.forwardRef((e,t)=>{let{prefixCls:r,style:o,className:l,checked:i,children:s,icon:c,onChange:u,onClick:m}=e,f=k(e,["prefixCls","style","className","checked","children","icon","onChange","onClick"]),{getPrefixCls:p,tag:h}=n.useContext(d.E_),b=p("tag",r),[g,v,y]=w(b),x=a()(b,"".concat(b,"-checkable"),{["".concat(b,"-checkable-checked")]:i},null==h?void 0:h.className,l,v,y);return g(n.createElement("span",Object.assign({},f,{ref:t,style:Object.assign(Object.assign({},o),null==h?void 0:h.style),className:x,onClick:e=>{null==u||u(!i),null==m||m(e)}}),c,n.createElement("span",null,s)))});var C=r(18536);let E=e=>(0,C.Z)(e,(t,r)=>{let{textColor:n,lightBorderColor:o,lightColor:a,darkColor:l}=r;return{["".concat(e.componentCls).concat(e.componentCls,"-").concat(t)]:{color:n,background:a,borderColor:o,"&-inverse":{color:e.colorTextLightSolid,background:l,borderColor:l},["&".concat(e.componentCls,"-borderless")]:{borderColor:"transparent"}}}});var S=(0,b.bk)(["Tag","preset"],e=>E(v(e)),y);let O=(e,t,r)=>{let n="string"!=typeof r?r:r.charAt(0).toUpperCase()+r.slice(1);return{["".concat(e.componentCls).concat(e.componentCls,"-").concat(t)]:{color:e["color".concat(r)],background:e["color".concat(n,"Bg")],borderColor:e["color".concat(n,"Border")],["&".concat(e.componentCls,"-borderless")]:{borderColor:"transparent"}}}};var j=(0,b.bk)(["Tag","status"],e=>{let t=v(e);return[O(t,"success","Success"),O(t,"processing","Info"),O(t,"error","Error"),O(t,"warning","Warning")]},y),N=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 _=n.forwardRef((e,t)=>{let{prefixCls:r,className:o,rootClassName:m,style:f,children:p,icon:h,color:b,onClose:g,bordered:v=!0,visible:y}=e,k=N(e,["prefixCls","className","rootClassName","style","children","icon","color","onClose","bordered","visible"]),{getPrefixCls:x,direction:C,tag:E}=n.useContext(d.E_),[O,_]=n.useState(!0),R=(0,l.Z)(k,["closeIcon","closable"]);n.useEffect(()=>{void 0!==y&&_(y)},[y]);let T=(0,i.o2)(b),M=(0,i.yT)(b),P=T||M,z=Object.assign(Object.assign({backgroundColor:b&&!P?b:void 0},null==E?void 0:E.style),f),L=x("tag",r),[I,Z,F]=w(L),B=a()(L,null==E?void 0:E.className,{["".concat(L,"-").concat(b)]:P,["".concat(L,"-has-color")]:b&&!P,["".concat(L,"-hidden")]:!O,["".concat(L,"-rtl")]:"rtl"===C,["".concat(L,"-borderless")]:!v},o,m,Z,F),D=e=>{e.stopPropagation(),null==g||g(e),e.defaultPrevented||_(!1)},[,q]=(0,s.b)((0,s.w)(e),(0,s.w)(E),{closable:!1,closeIconRender:e=>{let t=n.createElement("span",{className:"".concat(L,"-close-icon"),onClick:D},e);return(0,c.wm)(e,t,e=>({onClick:t=>{var r;null===(r=null==e?void 0:e.onClick)||void 0===r||r.call(e,t),D(t)},className:a()(null==e?void 0:e.className,"".concat(L,"-close-icon"))}))}}),A="function"==typeof k.onClick||p&&"a"===p.type,W=h||null,H=W?n.createElement(n.Fragment,null,W,p&&n.createElement("span",null,p)):p,V=n.createElement("span",Object.assign({},R,{ref:t,className:B,style:z}),H,q,T&&n.createElement(S,{key:"preset",prefixCls:L}),M&&n.createElement(j,{key:"status",prefixCls:L}));return I(A?n.createElement(u.Z,{component:"Tag"},V):V)});_.CheckableTag=x;var R=_},23910:function(e,t,r){var n=r(74288).Symbol;e.exports=n},54506:function(e,t,r){var n=r(23910),o=r(4479),a=r(80910),l=n?n.toStringTag:void 0;e.exports=function(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":l&&l in Object(e)?o(e):a(e)}},55041:function(e,t,r){var n=r(5035),o=/^\s+/;e.exports=function(e){return e?e.slice(0,n(e)+1).replace(o,""):e}},17071:function(e,t,r){var n="object"==typeof r.g&&r.g&&r.g.Object===Object&&r.g;e.exports=n},4479:function(e,t,r){var n=r(23910),o=Object.prototype,a=o.hasOwnProperty,l=o.toString,i=n?n.toStringTag:void 0;e.exports=function(e){var t=a.call(e,i),r=e[i];try{e[i]=void 0;var n=!0}catch(e){}var o=l.call(e);return n&&(t?e[i]=r:delete e[i]),o}},80910:function(e){var t=Object.prototype.toString;e.exports=function(e){return t.call(e)}},74288:function(e,t,r){var n=r(17071),o="object"==typeof self&&self&&self.Object===Object&&self,a=n||o||Function("return this")();e.exports=a},5035:function(e){var t=/\s/;e.exports=function(e){for(var r=e.length;r--&&t.test(e.charAt(r)););return r}},7310:function(e,t,r){var n=r(28302),o=r(11121),a=r(6660),l=Math.max,i=Math.min;e.exports=function(e,t,r){var s,c,u,d,m,f,p=0,h=!1,b=!1,g=!0;if("function"!=typeof e)throw TypeError("Expected a function");function v(t){var r=s,n=c;return s=c=void 0,p=t,d=e.apply(n,r)}function y(e){var r=e-f,n=e-p;return void 0===f||r>=t||r<0||b&&n>=u}function w(){var e,r,n,a=o();if(y(a))return k(a);m=setTimeout(w,(e=a-f,r=a-p,n=t-e,b?i(n,u-r):n))}function k(e){return(m=void 0,g&&s)?v(e):(s=c=void 0,d)}function x(){var e,r=o(),n=y(r);if(s=arguments,c=this,f=r,n){if(void 0===m)return p=e=f,m=setTimeout(w,t),h?v(e):d;if(b)return clearTimeout(m),m=setTimeout(w,t),v(f)}return void 0===m&&(m=setTimeout(w,t)),d}return t=a(t)||0,n(r)&&(h=!!r.leading,u=(b="maxWait"in r)?l(a(r.maxWait)||0,t):u,g="trailing"in r?!!r.trailing:g),x.cancel=function(){void 0!==m&&clearTimeout(m),p=0,s=f=c=m=void 0},x.flush=function(){return void 0===m?d:k(o())},x}},28302:function(e){e.exports=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}},10303:function(e){e.exports=function(e){return null!=e&&"object"==typeof e}},78371:function(e,t,r){var n=r(54506),o=r(10303);e.exports=function(e){return"symbol"==typeof e||o(e)&&"[object Symbol]"==n(e)}},11121:function(e,t,r){var n=r(74288);e.exports=function(){return n.Date.now()}},6660:function(e,t,r){var n=r(55041),o=r(28302),a=r(78371),l=0/0,i=/^[-+]0x[0-9a-f]+$/i,s=/^0b[01]+$/i,c=/^0o[0-7]+$/i,u=parseInt;e.exports=function(e){if("number"==typeof e)return e;if(a(e))return l;if(o(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=o(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=n(e);var r=s.test(e);return r||c.test(e)?u(e.slice(2),r?2:8):i.test(e)?l:+e}},79205:function(e,t,r){"use strict";r.d(t,{Z:function(){return d}});var n=r(2265);let o=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),a=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(e,t,r)=>r?r.toUpperCase():t.toLowerCase()),l=e=>{let t=a(e);return t.charAt(0).toUpperCase()+t.slice(1)},i=function(){for(var e=arguments.length,t=Array(e),r=0;r!!e&&""!==e.trim()&&r.indexOf(e)===t).join(" ").trim()},s=e=>{for(let t in e)if(t.startsWith("aria-")||"role"===t||"title"===t)return!0};var c={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 u=(0,n.forwardRef)((e,t)=>{let{color:r="currentColor",size:o=24,strokeWidth:a=2,absoluteStrokeWidth:l,className:u="",children:d,iconNode:m,...f}=e;return(0,n.createElement)("svg",{ref:t,...c,width:o,height:o,stroke:r,strokeWidth:l?24*Number(a)/Number(o):a,className:i("lucide",u),...!d&&!s(f)&&{"aria-hidden":"true"},...f},[...m.map(e=>{let[t,r]=e;return(0,n.createElement)(t,r)}),...Array.isArray(d)?d:[d]])}),d=(e,t)=>{let r=(0,n.forwardRef)((r,a)=>{let{className:s,...c}=r;return(0,n.createElement)(u,{ref:a,iconNode:t,className:i("lucide-".concat(o(l(e))),"lucide-".concat(e),s),...c})});return r.displayName=l(e),r}},30401:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("check",[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]])},78867:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("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"}]])},32489:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("x",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]])},24601:function(){},18975:function(e,t,r){"use strict";var n=r(40257);r(24601);var o=r(2265),a=o&&"object"==typeof o&&"default"in o?o:{default:o},l=void 0!==n&&n.env&&!0,i=function(e){return"[object String]"===Object.prototype.toString.call(e)},s=function(){function e(e){var t=void 0===e?{}:e,r=t.name,n=void 0===r?"stylesheet":r,o=t.optimizeForSpeed,a=void 0===o?l:o;c(i(n),"`name` must be a string"),this._name=n,this._deletedRulePlaceholder="#"+n+"-deleted-rule____{}",c("boolean"==typeof a,"`optimizeForSpeed` must be a boolean"),this._optimizeForSpeed=a,this._serverSheet=void 0,this._tags=[],this._injected=!1,this._rulesCount=0;var s="undefined"!=typeof window&&document.querySelector('meta[property="csp-nonce"]');this._nonce=s?s.getAttribute("content"):null}var t=e.prototype;return t.setOptimizeForSpeed=function(e){c("boolean"==typeof e,"`setOptimizeForSpeed` accepts a boolean"),c(0===this._rulesCount,"optimizeForSpeed cannot be when rules have already been inserted"),this.flush(),this._optimizeForSpeed=e,this.inject()},t.isOptimizeForSpeed=function(){return this._optimizeForSpeed},t.inject=function(){var e=this;if(c(!this._injected,"sheet already injected"),this._injected=!0,"undefined"!=typeof window&&this._optimizeForSpeed){this._tags[0]=this.makeStyleTag(this._name),this._optimizeForSpeed="insertRule"in this.getSheet(),this._optimizeForSpeed||(l||console.warn("StyleSheet: optimizeForSpeed mode not supported falling back to standard mode."),this.flush(),this._injected=!0);return}this._serverSheet={cssRules:[],insertRule:function(t,r){return"number"==typeof r?e._serverSheet.cssRules[r]={cssText:t}:e._serverSheet.cssRules.push({cssText:t}),r},deleteRule:function(t){e._serverSheet.cssRules[t]=null}}},t.getSheetForTag=function(e){if(e.sheet)return e.sheet;for(var t=0;t>>0},d={};function m(e,t){if(!t)return"jsx-"+e;var r=String(t),n=e+r;return d[n]||(d[n]="jsx-"+u(e+"-"+r)),d[n]}function f(e,t){"undefined"==typeof window&&(t=t.replace(/\/style/gi,"\\/style"));var r=e+t;return d[r]||(d[r]=t.replace(/__jsx-style-dynamic-selector/g,e)),d[r]}var p=function(){function e(e){var t=void 0===e?{}:e,r=t.styleSheet,n=void 0===r?null:r,o=t.optimizeForSpeed,a=void 0!==o&&o;this._sheet=n||new s({name:"styled-jsx",optimizeForSpeed:a}),this._sheet.inject(),n&&"boolean"==typeof a&&(this._sheet.setOptimizeForSpeed(a),this._optimizeForSpeed=this._sheet.isOptimizeForSpeed()),this._fromServer=void 0,this._indices={},this._instancesCounts={}}var t=e.prototype;return t.add=function(e){var t=this;void 0===this._optimizeForSpeed&&(this._optimizeForSpeed=Array.isArray(e.children),this._sheet.setOptimizeForSpeed(this._optimizeForSpeed),this._optimizeForSpeed=this._sheet.isOptimizeForSpeed()),"undefined"==typeof window||this._fromServer||(this._fromServer=this.selectFromServer(),this._instancesCounts=Object.keys(this._fromServer).reduce(function(e,t){return e[t]=0,e},{}));var r=this.getIdAndRules(e),n=r.styleId,o=r.rules;if(n in this._instancesCounts){this._instancesCounts[n]+=1;return}var a=o.map(function(e){return t._sheet.insertRule(e)}).filter(function(e){return -1!==e});this._indices[n]=a,this._instancesCounts[n]=1},t.remove=function(e){var t=this,r=this.getIdAndRules(e).styleId;if(function(e,t){if(!e)throw Error("StyleSheetRegistry: "+t+".")}(r in this._instancesCounts,"styleId: `"+r+"` not found"),this._instancesCounts[r]-=1,this._instancesCounts[r]<1){var n=this._fromServer&&this._fromServer[r];n?(n.parentNode.removeChild(n),delete this._fromServer[r]):(this._indices[r].forEach(function(e){return t._sheet.deleteRule(e)}),delete this._indices[r]),delete this._instancesCounts[r]}},t.update=function(e,t){this.add(t),this.remove(e)},t.flush=function(){this._sheet.flush(),this._sheet.inject(),this._fromServer=void 0,this._indices={},this._instancesCounts={}},t.cssRules=function(){var e=this,t=this._fromServer?Object.keys(this._fromServer).map(function(t){return[t,e._fromServer[t]]}):[],r=this._sheet.cssRules();return t.concat(Object.keys(this._indices).map(function(t){return[t,e._indices[t].map(function(e){return r[e].cssText}).join(e._optimizeForSpeed?"":"\n")]}).filter(function(e){return!!e[1]}))},t.styles=function(e){var t,r;return t=this.cssRules(),void 0===(r=e)&&(r={}),t.map(function(e){var t=e[0],n=e[1];return a.default.createElement("style",{id:"__"+t,key:"__"+t,nonce:r.nonce?r.nonce:void 0,dangerouslySetInnerHTML:{__html:n}})})},t.getIdAndRules=function(e){var t=e.children,r=e.dynamic,n=e.id;if(r){var o=m(n,r);return{styleId:o,rules:Array.isArray(t)?t.map(function(e){return f(o,e)}):[f(o,t)]}}return{styleId:m(n),rules:Array.isArray(t)?t:[t]}},t.selectFromServer=function(){return Array.prototype.slice.call(document.querySelectorAll('[id^="__jsx-"]')).reduce(function(e,t){return e[t.id.slice(2)]=t,e},{})},e}(),h=o.createContext(null);h.displayName="StyleSheetContext";var b=a.default.useInsertionEffect||a.default.useLayoutEffect,g="undefined"!=typeof window?new p:void 0;function v(e){var t=g||o.useContext(h);return t&&("undefined"==typeof window?t.add(e):b(function(){return t.add(e),function(){t.remove(e)}},[e.id,String(e.dynamic)])),null}v.dynamic=function(e){return e.map(function(e){return m(e[0],e[1])}).join(" ")},t.style=v},29:function(e,t,r){"use strict";e.exports=r(18975).style},10900:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10 19l-7-7m0 0l7-7m-7 7h18"}))});t.Z=o},91777:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.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"}))});t.Z=o},86462:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"}))});t.Z=o},47686:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9 5l7 7-7 7"}))});t.Z=o},44633:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 15l7-7 7 7"}))});t.Z=o},82182:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.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"}),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"}))});t.Z=o},79814:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.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"}))});t.Z=o},93416:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.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"}))});t.Z=o},77355:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 9v3m0 0v3m0-3h3m-3 0H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z"}))});t.Z=o},22452:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 4v16m8-8H4"}))});t.Z=o},23628:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.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"}))});t.Z=o},25327:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.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"}))});t.Z=o},49084:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4"}))});t.Z=o},74998:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.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"}))});t.Z=o},3497:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.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"}))});t.Z=o},91054:function(e,t,r){"use strict";let n,o;r.d(t,{pJ:function(){return M}});var a,l=r(71049),i=r(11323),s=r(2265),c=r(66797),u=r(93980),d=r(65573),m=r(67561),f=r(98218),p=r(33443),h=r(28294),b=r(31370),g=r(72468),v=r(5664),y=r(38929);let w=null!=(a=s.startTransition)?a:function(e){e()};var k=r(52724),x=((n=x||{})[n.Open=0]="Open",n[n.Closed=1]="Closed",n),C=((o=C||{})[o.ToggleDisclosure=0]="ToggleDisclosure",o[o.CloseDisclosure=1]="CloseDisclosure",o[o.SetButtonId=2]="SetButtonId",o[o.SetPanelId=3]="SetPanelId",o[o.SetButtonElement=4]="SetButtonElement",o[o.SetPanelElement=5]="SetPanelElement",o);let E={0:e=>({...e,disclosureState:(0,g.E)(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}},S=(0,s.createContext)(null);function O(e){let t=(0,s.useContext)(S);if(null===t){let t=Error("<".concat(e," /> is missing a parent component."));throw Error.captureStackTrace&&Error.captureStackTrace(t,O),t}return t}S.displayName="DisclosureContext";let j=(0,s.createContext)(null);j.displayName="DisclosureAPIContext";let N=(0,s.createContext)(null);function _(e,t){return(0,g.E)(t.type,E,e,t)}N.displayName="DisclosurePanelContext";let R=s.Fragment,T=y.VN.RenderStrategy|y.VN.Static,M=Object.assign((0,y.yV)(function(e,t){let{defaultOpen:r=!1,...n}=e,o=(0,s.useRef)(null),a=(0,m.T)(t,(0,m.h)(e=>{o.current=e},void 0===e.as||e.as===s.Fragment)),l=(0,s.useReducer)(_,{disclosureState:r?0:1,buttonElement:null,panelElement:null,buttonId:null,panelId:null}),[{disclosureState:i,buttonId:c},d]=l,f=(0,u.z)(e=>{d({type:1});let t=(0,v.r)(o);if(!t||!c)return;let r=e?e instanceof HTMLElement?e:e.current instanceof HTMLElement?e.current:t.getElementById(c):t.getElementById(c);null==r||r.focus()}),b=(0,s.useMemo)(()=>({close:f}),[f]),w=(0,s.useMemo)(()=>({open:0===i,close:f}),[i,f]),k=(0,y.L6)();return s.createElement(S.Provider,{value:l},s.createElement(j.Provider,{value:b},s.createElement(p.Z,{value:f},s.createElement(h.up,{value:(0,g.E)(i,{0:h.ZM.Open,1:h.ZM.Closed})},k({ourProps:{ref:a},theirProps:n,slot:w,defaultTag:R,name:"Disclosure"})))))}),{Button:(0,y.yV)(function(e,t){let r=(0,s.useId)(),{id:n="headlessui-disclosure-button-".concat(r),disabled:o=!1,autoFocus:a=!1,...f}=e,[p,h]=O("Disclosure.Button"),g=(0,s.useContext)(N),v=null!==g&&g===p.panelId,w=(0,s.useRef)(null),x=(0,m.T)(w,t,(0,u.z)(e=>{if(!v)return h({type:4,element:e})}));(0,s.useEffect)(()=>{if(!v)return h({type:2,buttonId:n}),()=>{h({type:2,buttonId:null})}},[n,h,v]);let C=(0,u.z)(e=>{var t;if(v){if(1===p.disclosureState)return;switch(e.key){case k.R.Space:case k.R.Enter:e.preventDefault(),e.stopPropagation(),h({type:0}),null==(t=p.buttonElement)||t.focus()}}else switch(e.key){case k.R.Space:case k.R.Enter:e.preventDefault(),e.stopPropagation(),h({type:0})}}),E=(0,u.z)(e=>{e.key===k.R.Space&&e.preventDefault()}),S=(0,u.z)(e=>{var t;(0,b.P)(e.currentTarget)||o||(v?(h({type:0}),null==(t=p.buttonElement)||t.focus()):h({type:0}))}),{isFocusVisible:j,focusProps:_}=(0,l.F)({autoFocus:a}),{isHovered:R,hoverProps:T}=(0,i.X)({isDisabled:o}),{pressed:M,pressProps:P}=(0,c.x)({disabled:o}),z=(0,s.useMemo)(()=>({open:0===p.disclosureState,hover:R,active:M,disabled:o,focus:j,autofocus:a}),[p,R,M,j,o,a]),L=(0,d.f)(e,p.buttonElement),I=v?(0,y.dG)({ref:x,type:L,disabled:o||void 0,autoFocus:a,onKeyDown:C,onClick:S},_,T,P):(0,y.dG)({ref:x,id:n,type:L,"aria-expanded":0===p.disclosureState,"aria-controls":p.panelElement?p.panelId:void 0,disabled:o||void 0,autoFocus:a,onKeyDown:C,onKeyUp:E,onClick:S},_,T,P);return(0,y.L6)()({ourProps:I,theirProps:f,slot:z,defaultTag:"button",name:"Disclosure.Button"})}),Panel:(0,y.yV)(function(e,t){let r=(0,s.useId)(),{id:n="headlessui-disclosure-panel-".concat(r),transition:o=!1,...a}=e,[l,i]=O("Disclosure.Panel"),{close:c}=function e(t){let r=(0,s.useContext)(j);if(null===r){let r=Error("<".concat(t," /> is missing a parent component."));throw Error.captureStackTrace&&Error.captureStackTrace(r,e),r}return r}("Disclosure.Panel"),[d,p]=(0,s.useState)(null),b=(0,m.T)(t,(0,u.z)(e=>{w(()=>i({type:5,element:e}))}),p);(0,s.useEffect)(()=>(i({type:3,panelId:n}),()=>{i({type:3,panelId:null})}),[n,i]);let g=(0,h.oJ)(),[v,k]=(0,f.Y)(o,d,null!==g?(g&h.ZM.Open)===h.ZM.Open:0===l.disclosureState),x=(0,s.useMemo)(()=>({open:0===l.disclosureState,close:c}),[l.disclosureState,c]),C={ref:b,id:n,...(0,f.X)(k)},E=(0,y.L6)();return s.createElement(h.uu,null,s.createElement(N.Provider,{value:l.panelId},E({ourProps:C,theirProps:a,slot:x,defaultTag:"div",features:T,visible:v,name:"Disclosure.Panel"})))})})},85238:function(e,t,r){"use strict";let n;r.d(t,{u:function(){return N}});var o=r(2265),a=r(59456),l=r(93980),i=r(25289),s=r(73389),c=r(43507),u=r(180),d=r(67561),m=r(98218),f=r(28294),p=r(95504),h=r(72468),b=r(38929);function g(e){var t;return!!(e.enter||e.enterFrom||e.enterTo||e.leave||e.leaveFrom||e.leaveTo)||(null!=(t=e.as)?t:C)!==o.Fragment||1===o.Children.count(e.children)}let v=(0,o.createContext)(null);v.displayName="TransitionContext";var y=((n=y||{}).Visible="visible",n.Hidden="hidden",n);let w=(0,o.createContext)(null);function k(e){return"children"in e?k(e.children):e.current.filter(e=>{let{el:t}=e;return null!==t.current}).filter(e=>{let{state:t}=e;return"visible"===t}).length>0}function x(e,t){let r=(0,c.E)(e),n=(0,o.useRef)([]),s=(0,i.t)(),u=(0,a.G)(),d=(0,l.z)(function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:b.l4.Hidden,o=n.current.findIndex(t=>{let{el:r}=t;return r===e});-1!==o&&((0,h.E)(t,{[b.l4.Unmount](){n.current.splice(o,1)},[b.l4.Hidden](){n.current[o].state="hidden"}}),u.microTask(()=>{var e;!k(n)&&s.current&&(null==(e=r.current)||e.call(r))}))}),m=(0,l.z)(e=>{let t=n.current.find(t=>{let{el:r}=t;return r===e});return t?"visible"!==t.state&&(t.state="visible"):n.current.push({el:e,state:"visible"}),()=>d(e,b.l4.Unmount)}),f=(0,o.useRef)([]),p=(0,o.useRef)(Promise.resolve()),g=(0,o.useRef)({enter:[],leave:[]}),v=(0,l.z)((e,r,n)=>{f.current.splice(0),t&&(t.chains.current[r]=t.chains.current[r].filter(t=>{let[r]=t;return r!==e})),null==t||t.chains.current[r].push([e,new Promise(e=>{f.current.push(e)})]),null==t||t.chains.current[r].push([e,new Promise(e=>{Promise.all(g.current[r].map(e=>{let[t,r]=e;return r})).then(()=>e())})]),"enter"===r?p.current=p.current.then(()=>null==t?void 0:t.wait.current).then(()=>n(r)):n(r)}),y=(0,l.z)((e,t,r)=>{Promise.all(g.current[t].splice(0).map(e=>{let[t,r]=e;return r})).then(()=>{var e;null==(e=f.current.shift())||e()}).then(()=>r(t))});return(0,o.useMemo)(()=>({children:n,register:m,unregister:d,onStart:v,onStop:y,wait:p,chains:g}),[m,d,n,v,y,g,p])}w.displayName="NestingContext";let C=o.Fragment,E=b.VN.RenderStrategy,S=(0,b.yV)(function(e,t){let{show:r,appear:n=!1,unmount:a=!0,...i}=e,c=(0,o.useRef)(null),m=g(e),p=(0,d.T)(...m?[c,t]:null===t?[]:[t]);(0,u.H)();let h=(0,f.oJ)();if(void 0===r&&null!==h&&(r=(h&f.ZM.Open)===f.ZM.Open),void 0===r)throw Error("A is used but it is missing a `show={true | false}` prop.");let[y,C]=(0,o.useState)(r?"visible":"hidden"),S=x(()=>{r||C("hidden")}),[j,N]=(0,o.useState)(!0),_=(0,o.useRef)([r]);(0,s.e)(()=>{!1!==j&&_.current[_.current.length-1]!==r&&(_.current.push(r),N(!1))},[_,r]);let R=(0,o.useMemo)(()=>({show:r,appear:n,initial:j}),[r,n,j]);(0,s.e)(()=>{r?C("visible"):k(S)||null===c.current||C("hidden")},[r,S]);let T={unmount:a},M=(0,l.z)(()=>{var t;j&&N(!1),null==(t=e.beforeEnter)||t.call(e)}),P=(0,l.z)(()=>{var t;j&&N(!1),null==(t=e.beforeLeave)||t.call(e)}),z=(0,b.L6)();return o.createElement(w.Provider,{value:S},o.createElement(v.Provider,{value:R},z({ourProps:{...T,as:o.Fragment,children:o.createElement(O,{ref:p,...T,...i,beforeEnter:M,beforeLeave:P})},theirProps:{},defaultTag:o.Fragment,features:E,visible:"visible"===y,name:"Transition"})))}),O=(0,b.yV)(function(e,t){var r,n;let{transition:a=!0,beforeEnter:i,afterEnter:c,beforeLeave:y,afterLeave:S,enter:O,enterFrom:j,enterTo:N,entered:_,leave:R,leaveFrom:T,leaveTo:M,...P}=e,[z,L]=(0,o.useState)(null),I=(0,o.useRef)(null),Z=g(e),F=(0,d.T)(...Z?[I,t,L]:null===t?[]:[t]),B=null==(r=P.unmount)||r?b.l4.Unmount:b.l4.Hidden,{show:D,appear:q,initial:A}=function(){let e=(0,o.useContext)(v);if(null===e)throw Error("A is used but it is missing a parent or .");return e}(),[W,H]=(0,o.useState)(D?"visible":"hidden"),V=function(){let e=(0,o.useContext)(w);if(null===e)throw Error("A is used but it is missing a parent or .");return e}(),{register:K,unregister:U}=V;(0,s.e)(()=>K(I),[K,I]),(0,s.e)(()=>{if(B===b.l4.Hidden&&I.current){if(D&&"visible"!==W){H("visible");return}return(0,h.E)(W,{hidden:()=>U(I),visible:()=>K(I)})}},[W,I,K,U,D,B]);let X=(0,u.H)();(0,s.e)(()=>{if(Z&&X&&"visible"===W&&null===I.current)throw Error("Did you forget to passthrough the `ref` to the actual DOM node?")},[I,W,X,Z]);let Y=A&&!q,G=q&&D&&A,$=(0,o.useRef)(!1),J=x(()=>{$.current||(H("hidden"),U(I))},V),Q=(0,l.z)(e=>{$.current=!0,J.onStart(I,e?"enter":"leave",e=>{"enter"===e?null==i||i():"leave"===e&&(null==y||y())})}),ee=(0,l.z)(e=>{let t=e?"enter":"leave";$.current=!1,J.onStop(I,t,e=>{"enter"===e?null==c||c():"leave"===e&&(null==S||S())}),"leave"!==t||k(J)||(H("hidden"),U(I))});(0,o.useEffect)(()=>{Z&&a||(Q(D),ee(D))},[D,Z,a]);let et=!(!a||!Z||!X||Y),[,er]=(0,m.Y)(et,z,D,{start:Q,end:ee}),en=(0,b.oA)({ref:F,className:(null==(n=(0,p.A)(P.className,G&&O,G&&j,er.enter&&O,er.enter&&er.closed&&j,er.enter&&!er.closed&&N,er.leave&&R,er.leave&&!er.closed&&T,er.leave&&er.closed&&M,!er.transition&&D&&_))?void 0:n.trim())||void 0,...(0,m.X)(er)}),eo=0;"visible"===W&&(eo|=f.ZM.Open),"hidden"===W&&(eo|=f.ZM.Closed),er.enter&&(eo|=f.ZM.Opening),er.leave&&(eo|=f.ZM.Closing);let ea=(0,b.L6)();return o.createElement(w.Provider,{value:J},o.createElement(f.up,{value:eo},ea({ourProps:en,theirProps:P,defaultTag:C,features:E,visible:"visible"===W,name:"Transition.Child"})))}),j=(0,b.yV)(function(e,t){let r=null!==(0,o.useContext)(v),n=null!==(0,f.oJ)();return o.createElement(o.Fragment,null,!r&&n?o.createElement(S,{ref:t,...e}):o.createElement(O,{ref:t,...e}))}),N=Object.assign(S,{Child:j,Root:S})},33443:function(e,t,r){"use strict";r.d(t,{Z:function(){return a}});var n=r(2265);let o=(0,n.createContext)(()=>{});function a(e){let{value:t,children:r}=e;return n.createElement(o.Provider,{value:t},r)}}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/1176-9175d7684b344026.js b/litellm/proxy/_experimental/out/_next/static/chunks/1176-9175d7684b344026.js deleted file mode 100644 index 753a61d0bbb..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/1176-9175d7684b344026.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1176,1623],{5540:function(e,t,n){"use strict";n.d(t,{Z:function(){return s}});var r=n(1119),a=n(2265),o={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"},i=n(55015),s=a.forwardRef(function(e,t){return a.createElement(i.Z,(0,r.Z)({},e,{ref:t,icon:o}))})},69993:function(e,t,n){"use strict";n.d(t,{Z:function(){return s}});var r=n(1119),a=n(2265),o={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M300 328a60 60 0 10120 0 60 60 0 10-120 0zM852 64H172c-17.7 0-32 14.3-32 32v660c0 17.7 14.3 32 32 32h680c17.7 0 32-14.3 32-32V96c0-17.7-14.3-32-32-32zm-32 660H204V128h616v596zM604 328a60 60 0 10120 0 60 60 0 10-120 0zm250.2 556H169.8c-16.5 0-29.8 14.3-29.8 32v36c0 4.4 3.3 8 7.4 8h729.1c4.1 0 7.4-3.6 7.4-8v-36c.1-17.7-13.2-32-29.7-32zM664 508H360c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h304c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"}}]},name:"robot",theme:"outlined"},i=n(55015),s=a.forwardRef(function(e,t){return a.createElement(i.Z,(0,r.Z)({},e,{ref:t,icon:o}))})},55322:function(e,t,n){"use strict";n.d(t,{Z:function(){return s}});var r=n(1119),a=n(2265),o={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 009.3-35.2l-.9-2.6a443.74 443.74 0 00-79.7-137.9l-1.8-2.1a32.12 32.12 0 00-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 00-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 00-25.8 25.7l-15.8 85.4a351.86 351.86 0 00-99 57.4l-81.9-29.1a32 32 0 00-35.1 9.5l-1.8 2.1a446.02 446.02 0 00-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 00-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0035.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0025.8 25.7l2.7.5a449.4 449.4 0 00159 0l2.7-.5a32.05 32.05 0 0025.8-25.7l15.7-85a350 350 0 0099.7-57.6l81.3 28.9a32 32 0 0035.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 01-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97a377.5 377.5 0 01-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 01512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 01400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 01624 502c0 29.9-11.7 58-32.8 79.2z"}}]},name:"setting",theme:"outlined"},i=n(55015),s=a.forwardRef(function(e,t){return a.createElement(i.Z,(0,r.Z)({},e,{ref:t,icon:o}))})},59341:function(e,t,n){"use strict";n.d(t,{Z:function(){return P}});var r=n(5853),a=n(71049),o=n(11323),i=n(2265),s=n(66797),l=n(40099),c=n(74275),u=n(59456),d=n(93980),h=n(65573),m=n(67561),f=n(87550),p=n(628),b=n(80281),g=n(31370),v=n(20131),y=n(38929),w=n(52307),k=n(52724),C=n(7935);let E=(0,i.createContext)(null);E.displayName="GroupContext";let O=i.Fragment,x=Object.assign((0,y.yV)(function(e,t){var n;let r=(0,i.useId)(),O=(0,b.Q)(),x=(0,f.B)(),{id:N=O||"headlessui-switch-".concat(r),disabled:S=x||!1,checked:M,defaultChecked:j,onChange:R,name:q,value:P,form:D,autoFocus:L=!1,...F}=e,T=(0,i.useContext)(E),[I,Z]=(0,i.useState)(null),z=(0,i.useRef)(null),V=(0,m.T)(z,t,null===T?null:T.setSwitch,Z),A=(0,c.L)(j),[B,Q]=(0,l.q)(M,R,null!=A&&A),_=(0,u.G)(),[H,K]=(0,i.useState)(!1),W=(0,d.z)(()=>{K(!0),null==Q||Q(!B),_.nextFrame(()=>{K(!1)})}),G=(0,d.z)(e=>{if((0,g.P)(e.currentTarget))return e.preventDefault();e.preventDefault(),W()}),J=(0,d.z)(e=>{e.key===k.R.Space?(e.preventDefault(),W()):e.key===k.R.Enter&&(0,v.g)(e.currentTarget)}),Y=(0,d.z)(e=>e.preventDefault()),X=(0,C.wp)(),U=(0,w.zH)(),{isFocusVisible:$,focusProps:ee}=(0,a.F)({autoFocus:L}),{isHovered:et,hoverProps:en}=(0,o.X)({isDisabled:S}),{pressed:er,pressProps:ea}=(0,s.x)({disabled:S}),eo=(0,i.useMemo)(()=>({checked:B,disabled:S,hover:et,focus:$,active:er,autofocus:L,changing:H}),[B,et,$,er,S,H,L]),ei=(0,y.dG)({id:N,ref:V,role:"switch",type:(0,h.f)(e,I),tabIndex:-1===e.tabIndex?0:null!=(n=e.tabIndex)?n:0,"aria-checked":B,"aria-labelledby":X,"aria-describedby":U,disabled:S||void 0,autoFocus:L,onClick:G,onKeyUp:J,onKeyPress:Y},ee,en,ea),es=(0,i.useCallback)(()=>{if(void 0!==A)return null==Q?void 0:Q(A)},[Q,A]),el=(0,y.L6)();return i.createElement(i.Fragment,null,null!=q&&i.createElement(p.Mt,{disabled:S,data:{[q]:P||"on"},overrides:{type:"checkbox",checked:B},form:D,onReset:es}),el({ourProps:ei,theirProps:F,slot:eo,defaultTag:"button",name:"Switch"}))}),{Group:function(e){var t;let[n,r]=(0,i.useState)(null),[a,o]=(0,C.bE)(),[s,l]=(0,w.fw)(),c=(0,i.useMemo)(()=>({switch:n,setSwitch:r}),[n,r]),u=(0,y.L6)();return i.createElement(l,{name:"Switch.Description",value:s},i.createElement(o,{name:"Switch.Label",value:a,props:{htmlFor:null==(t=c.switch)?void 0:t.id,onClick(e){n&&(e.currentTarget instanceof HTMLLabelElement&&e.preventDefault(),n.click(),n.focus({preventScroll:!0}))}}},i.createElement(E.Provider,{value:c},u({ourProps:{},theirProps:e,slot:{},defaultTag:O,name:"Switch.Group"}))))},Label:C.__,Description:w.dk});var N=n(44140),S=n(26898),M=n(13241),j=n(1153),R=n(47187);let q=(0,j.fn)("Switch"),P=i.forwardRef((e,t)=>{let{checked:n,defaultChecked:a=!1,onChange:o,color:s,name:l,error:c,errorMessage:u,disabled:d,required:h,tooltip:m,id:f}=e,p=(0,r._T)(e,["checked","defaultChecked","onChange","color","name","error","errorMessage","disabled","required","tooltip","id"]),b={bgColor:s?(0,j.bM)(s,S.K.background).bgColor:"bg-tremor-brand dark:bg-dark-tremor-brand",ringColor:s?(0,j.bM)(s,S.K.ring).ringColor:"ring-tremor-brand-muted dark:ring-dark-tremor-brand-muted"},[g,v]=(0,N.Z)(a,n),[y,w]=(0,i.useState)(!1),{tooltipProps:k,getReferenceProps:C}=(0,R.l)(300);return i.createElement("div",{className:"flex flex-row items-center justify-start"},i.createElement(R.Z,Object.assign({text:m},k)),i.createElement("div",Object.assign({ref:(0,j.lq)([t,k.refs.setReference]),className:(0,M.q)(q("root"),"flex flex-row relative h-5")},p,C),i.createElement("input",{type:"checkbox",className:(0,M.q)(q("input"),"absolute w-5 h-5 cursor-pointer left-0 top-0 opacity-0"),name:l,required:h,checked:g,onChange:e=>{e.preventDefault()}}),i.createElement(x,{checked:g,onChange:e=>{v(e),null==o||o(e)},disabled:d,className:(0,M.q)(q("switch"),"w-10 h-5 group relative inline-flex shrink-0 cursor-pointer items-center justify-center rounded-tremor-full","focus:outline-none",d?"cursor-not-allowed":""),onFocus:()=>w(!0),onBlur:()=>w(!1),id:f},i.createElement("span",{className:(0,M.q)(q("sr-only"),"sr-only")},"Switch ",g?"on":"off"),i.createElement("span",{"aria-hidden":"true",className:(0,M.q)(q("background"),g?b.bgColor:"bg-tremor-border dark:bg-dark-tremor-border","pointer-events-none absolute mx-auto h-3 w-9 rounded-tremor-full transition-colors duration-100 ease-in-out")}),i.createElement("span",{"aria-hidden":"true",className:(0,M.q)(q("round"),g?(0,M.q)(b.bgColor,"translate-x-5 border-tremor-background dark:border-dark-tremor-background"):"translate-x-0 bg-tremor-border dark:bg-dark-tremor-border border-tremor-background dark:border-dark-tremor-background","pointer-events-none absolute left-0 inline-block h-5 w-5 transform rounded-tremor-full border-2 shadow-tremor-input duration-100 ease-in-out transition",y?(0,M.q)("ring-2",b.ringColor):"")}))),c&&u?i.createElement("p",{className:(0,M.q)(q("errorMessage"),"text-sm text-red-500 mt-1 ")},u):null)});P.displayName="Switch"},49804:function(e,t,n){"use strict";n.d(t,{Z:function(){return c}});var r=n(5853),a=n(13241),o=n(1153),i=n(2265),s=n(9496);let l=(0,o.fn)("Col"),c=i.forwardRef((e,t)=>{let{numColSpan:n=1,numColSpanSm:o,numColSpanMd:c,numColSpanLg:u,children:d,className:h}=e,m=(0,r._T)(e,["numColSpan","numColSpanSm","numColSpanMd","numColSpanLg","children","className"]),f=(e,t)=>e&&Object.keys(t).includes(String(e))?t[e]:"";return i.createElement("div",Object.assign({ref:t,className:(0,a.q)(l("root"),(()=>{let e=f(n,s.PT),t=f(o,s.SP),r=f(c,s.VS),i=f(u,s._w);return(0,a.q)(e,t,r,i)})(),h)},m),d)});c.displayName="Col"},35829:function(e,t,n){"use strict";n.d(t,{Z:function(){return l}});var r=n(5853),a=n(26898),o=n(13241),i=n(1153),s=n(2265);let l=s.forwardRef((e,t)=>{let{color:n,children:l,className:c}=e,u=(0,r._T)(e,["color","children","className"]);return s.createElement("p",Object.assign({ref:t,className:(0,o.q)("font-semibold text-tremor-metric",n?(0,i.bM)(n,a.K.darkText).textColor:"text-tremor-content-strong dark:text-dark-tremor-content-strong",c)},u),l)});l.displayName="Metric"},33866:function(e,t,n){"use strict";n.d(t,{Z:function(){return D}});var r=n(2265),a=n(36760),o=n.n(a),i=n(66632),s=n(93350),l=n(19722),c=n(71744),u=n(93463),d=n(12918),h=n(18536),m=n(71140),f=n(99320);let p=new u.E4("antStatusProcessing",{"0%":{transform:"scale(0.8)",opacity:.5},"100%":{transform:"scale(2.4)",opacity:0}}),b=new u.E4("antZoomBadgeIn",{"0%":{transform:"scale(0) translate(50%, -50%)",opacity:0},"100%":{transform:"scale(1) translate(50%, -50%)"}}),g=new u.E4("antZoomBadgeOut",{"0%":{transform:"scale(1) translate(50%, -50%)"},"100%":{transform:"scale(0) translate(50%, -50%)",opacity:0}}),v=new u.E4("antNoWrapperZoomBadgeIn",{"0%":{transform:"scale(0)",opacity:0},"100%":{transform:"scale(1)"}}),y=new u.E4("antNoWrapperZoomBadgeOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0)",opacity:0}}),w=new u.E4("antBadgeLoadingCircle",{"0%":{transformOrigin:"50%"},"100%":{transform:"translate(50%, -50%) rotate(360deg)",transformOrigin:"50%"}}),k=e=>{let{componentCls:t,iconCls:n,antCls:r,badgeShadowSize:a,textFontSize:o,textFontSizeSM:i,statusSize:s,dotSize:l,textFontWeight:c,indicatorHeight:m,indicatorHeightSM:f,marginXS:k,calc:C}=e,E="".concat(r,"-scroll-number"),O=(0,h.Z)(e,(e,n)=>{let{darkColor:r}=n;return{["&".concat(t," ").concat(t,"-color-").concat(e)]:{background:r,["&:not(".concat(t,"-count)")]:{color:r},"a:hover &":{background:r}}}});return{[t]:Object.assign(Object.assign(Object.assign(Object.assign({},(0,d.Wf)(e)),{position:"relative",display:"inline-block",width:"fit-content",lineHeight:1,["".concat(t,"-count")]:{display:"inline-flex",justifyContent:"center",zIndex:e.indicatorZIndex,minWidth:m,height:m,color:e.badgeTextColor,fontWeight:c,fontSize:o,lineHeight:(0,u.bf)(m),whiteSpace:"nowrap",textAlign:"center",background:e.badgeColor,borderRadius:C(m).div(2).equal(),boxShadow:"0 0 0 ".concat((0,u.bf)(a)," ").concat(e.badgeShadowColor),transition:"background ".concat(e.motionDurationMid),a:{color:e.badgeTextColor},"a:hover":{color:e.badgeTextColor},"a:hover &":{background:e.badgeColorHover}},["".concat(t,"-count-sm")]:{minWidth:f,height:f,fontSize:i,lineHeight:(0,u.bf)(f),borderRadius:C(f).div(2).equal()},["".concat(t,"-multiple-words")]:{padding:"0 ".concat((0,u.bf)(e.paddingXS)),bdi:{unicodeBidi:"plaintext"}},["".concat(t,"-dot")]:{zIndex:e.indicatorZIndex,width:l,minWidth:l,height:l,background:e.badgeColor,borderRadius:"100%",boxShadow:"0 0 0 ".concat((0,u.bf)(a)," ").concat(e.badgeShadowColor)},["".concat(t,"-count, ").concat(t,"-dot, ").concat(E,"-custom-component")]:{position:"absolute",top:0,insetInlineEnd:0,transform:"translate(50%, -50%)",transformOrigin:"100% 0%",["&".concat(n,"-spin")]:{animationName:w,animationDuration:"1s",animationIterationCount:"infinite",animationTimingFunction:"linear"}},["&".concat(t,"-status")]:{lineHeight:"inherit",verticalAlign:"baseline",["".concat(t,"-status-dot")]:{position:"relative",top:-1,display:"inline-block",width:s,height:s,verticalAlign:"middle",borderRadius:"50%"},["".concat(t,"-status-success")]:{backgroundColor:e.colorSuccess},["".concat(t,"-status-processing")]:{overflow:"visible",color:e.colorInfo,backgroundColor:e.colorInfo,borderColor:"currentcolor","&::after":{position:"absolute",top:0,insetInlineStart:0,width:"100%",height:"100%",borderWidth:a,borderStyle:"solid",borderColor:"inherit",borderRadius:"50%",animationName:p,animationDuration:e.badgeProcessingDuration,animationIterationCount:"infinite",animationTimingFunction:"ease-in-out",content:'""'}},["".concat(t,"-status-default")]:{backgroundColor:e.colorTextPlaceholder},["".concat(t,"-status-error")]:{backgroundColor:e.colorError},["".concat(t,"-status-warning")]:{backgroundColor:e.colorWarning},["".concat(t,"-status-text")]:{marginInlineStart:k,color:e.colorText,fontSize:e.fontSize}}}),O),{["".concat(t,"-zoom-appear, ").concat(t,"-zoom-enter")]:{animationName:b,animationDuration:e.motionDurationSlow,animationTimingFunction:e.motionEaseOutBack,animationFillMode:"both"},["".concat(t,"-zoom-leave")]:{animationName:g,animationDuration:e.motionDurationSlow,animationTimingFunction:e.motionEaseOutBack,animationFillMode:"both"},["&".concat(t,"-not-a-wrapper")]:{["".concat(t,"-zoom-appear, ").concat(t,"-zoom-enter")]:{animationName:v,animationDuration:e.motionDurationSlow,animationTimingFunction:e.motionEaseOutBack},["".concat(t,"-zoom-leave")]:{animationName:y,animationDuration:e.motionDurationSlow,animationTimingFunction:e.motionEaseOutBack},["&:not(".concat(t,"-status)")]:{verticalAlign:"middle"},["".concat(E,"-custom-component, ").concat(t,"-count")]:{transform:"none"},["".concat(E,"-custom-component, ").concat(E)]:{position:"relative",top:"auto",display:"block",transformOrigin:"50% 50%"}},[E]:{overflow:"hidden",transition:"all ".concat(e.motionDurationMid," ").concat(e.motionEaseOutBack),["".concat(E,"-only")]:{position:"relative",display:"inline-block",height:m,transition:"all ".concat(e.motionDurationSlow," ").concat(e.motionEaseOutBack),WebkitTransformStyle:"preserve-3d",WebkitBackfaceVisibility:"hidden",["> p".concat(E,"-only-unit")]:{height:m,margin:0,WebkitTransformStyle:"preserve-3d",WebkitBackfaceVisibility:"hidden"}},["".concat(E,"-symbol")]:{verticalAlign:"top"}},"&-rtl":{direction:"rtl",["".concat(t,"-count, ").concat(t,"-dot, ").concat(E,"-custom-component")]:{transform:"translate(-50%, -50%)"}}})}},C=e=>{let{fontHeight:t,lineWidth:n,marginXS:r,colorBorderBg:a}=e,o=e.colorTextLightSolid,i=e.colorError,s=e.colorErrorHover;return(0,m.IX)(e,{badgeFontHeight:t,badgeShadowSize:n,badgeTextColor:o,badgeColor:i,badgeColorHover:s,badgeShadowColor:a,badgeProcessingDuration:"1.2s",badgeRibbonOffset:r,badgeRibbonCornerTransform:"scaleY(0.75)",badgeRibbonCornerFilter:"brightness(75%)"})},E=e=>{let{fontSize:t,lineHeight:n,fontSizeSM:r,lineWidth:a}=e;return{indicatorZIndex:"auto",indicatorHeight:Math.round(t*n)-2*a,indicatorHeightSM:t,dotSize:r/2,textFontSize:r,textFontSizeSM:r,textFontWeight:"normal",statusSize:r/2}};var O=(0,f.I$)("Badge",e=>k(C(e)),E);let x=e=>{let{antCls:t,badgeFontHeight:n,marginXS:r,badgeRibbonOffset:a,calc:o}=e,i="".concat(t,"-ribbon"),s=(0,h.Z)(e,(e,t)=>{let{darkColor:n}=t;return{["&".concat(i,"-color-").concat(e)]:{background:n,color:n}}});return{["".concat(t,"-ribbon-wrapper")]:{position:"relative"},[i]:Object.assign(Object.assign(Object.assign(Object.assign({},(0,d.Wf)(e)),{position:"absolute",top:r,padding:"0 ".concat((0,u.bf)(e.paddingXS)),color:e.colorPrimary,lineHeight:(0,u.bf)(n),whiteSpace:"nowrap",backgroundColor:e.colorPrimary,borderRadius:e.borderRadiusSM,["".concat(i,"-text")]:{color:e.badgeTextColor},["".concat(i,"-corner")]:{position:"absolute",top:"100%",width:a,height:a,color:"currentcolor",border:"".concat((0,u.bf)(o(a).div(2).equal())," solid"),transform:e.badgeRibbonCornerTransform,transformOrigin:"top",filter:e.badgeRibbonCornerFilter}}),s),{["&".concat(i,"-placement-end")]:{insetInlineEnd:o(a).mul(-1).equal(),borderEndEndRadius:0,["".concat(i,"-corner")]:{insetInlineEnd:0,borderInlineEndColor:"transparent",borderBlockEndColor:"transparent"}},["&".concat(i,"-placement-start")]:{insetInlineStart:o(a).mul(-1).equal(),borderEndStartRadius:0,["".concat(i,"-corner")]:{insetInlineStart:0,borderBlockEndColor:"transparent",borderInlineStartColor:"transparent"}},"&-rtl":{direction:"rtl"}})}};var N=(0,f.I$)(["Badge","Ribbon"],e=>x(C(e)),E);let S=e=>{let t;let{prefixCls:n,value:a,current:i,offset:s=0}=e;return s&&(t={position:"absolute",top:"".concat(s,"00%"),left:0}),r.createElement("span",{style:t,className:o()("".concat(n,"-only-unit"),{current:i})},a)};var M=e=>{let t,n;let{prefixCls:a,count:o,value:i}=e,s=Number(i),l=Math.abs(o),[c,u]=r.useState(s),[d,h]=r.useState(l),m=()=>{u(s),h(l)};if(r.useEffect(()=>{let e=setTimeout(m,1e3);return()=>clearTimeout(e)},[s]),c===s||Number.isNaN(s)||Number.isNaN(c))t=[r.createElement(S,Object.assign({},e,{key:s,current:!0}))],n={transition:"none"};else{t=[];let a=s+10,o=[];for(let e=s;e<=a;e+=1)o.push(e);let i=de%10===c);t=(i<0?o.slice(0,u+1):o.slice(u)).map((t,n)=>r.createElement(S,Object.assign({},e,{key:t,value:t%10,offset:i<0?n-u:n,current:n===u}))),n={transform:"translateY(".concat(-function(e,t,n){let r=e,a=0;for(;(r+10)%10!==t;)r+=n,a+=n;return a}(c,s,i),"00%)")}}return r.createElement("span",{className:"".concat(a,"-only"),style:n,onTransitionEnd:m},t)},j=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&0>t.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,r=Object.getOwnPropertySymbols(e);at.indexOf(r[a])&&Object.prototype.propertyIsEnumerable.call(e,r[a])&&(n[r[a]]=e[r[a]]);return n};let R=r.forwardRef((e,t)=>{let{prefixCls:n,count:a,className:i,motionClassName:s,style:u,title:d,show:h,component:m="sup",children:f}=e,p=j(e,["prefixCls","count","className","motionClassName","style","title","show","component","children"]),{getPrefixCls:b}=r.useContext(c.E_),g=b("scroll-number",n),v=Object.assign(Object.assign({},p),{"data-show":h,style:u,className:o()(g,i,s),title:d}),y=a;if(a&&Number(a)%1==0){let e=String(a).split("");y=r.createElement("bdi",null,e.map((t,n)=>r.createElement(M,{prefixCls:g,count:Number(a),value:t,key:e.length-n})))}return((null==u?void 0:u.borderColor)&&(v.style=Object.assign(Object.assign({},u),{boxShadow:"0 0 0 1px ".concat(u.borderColor," inset")})),f)?(0,l.Tm)(f,e=>({className:o()("".concat(g,"-custom-component"),null==e?void 0:e.className,s)})):r.createElement(m,Object.assign({},v,{ref:t}),y)});var q=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&0>t.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,r=Object.getOwnPropertySymbols(e);at.indexOf(r[a])&&Object.prototype.propertyIsEnumerable.call(e,r[a])&&(n[r[a]]=e[r[a]]);return n};let P=r.forwardRef((e,t)=>{var n,a,u,d,h;let{prefixCls:m,scrollNumberPrefixCls:f,children:p,status:b,text:g,color:v,count:y=null,overflowCount:w=99,dot:k=!1,size:C="default",title:E,offset:x,style:N,className:S,rootClassName:M,classNames:j,styles:P,showZero:D=!1}=e,L=q(e,["prefixCls","scrollNumberPrefixCls","children","status","text","color","count","overflowCount","dot","size","title","offset","style","className","rootClassName","classNames","styles","showZero"]),{getPrefixCls:F,direction:T,badge:I}=r.useContext(c.E_),Z=F("badge",m),[z,V,A]=O(Z),B=y>w?"".concat(w,"+"):y,Q="0"===B||0===B||"0"===g||0===g,_=null===y||Q&&!D,H=(null!=b||null!=v)&&_,K=null!=b||!Q,W=k&&!Q,G=W?"":B,J=(0,r.useMemo)(()=>((null==G||""===G)&&(null==g||""===g)||Q&&!D)&&!W,[G,Q,D,W,g]),Y=(0,r.useRef)(y);J||(Y.current=y);let X=Y.current,U=(0,r.useRef)(G);J||(U.current=G);let $=U.current,ee=(0,r.useRef)(W);J||(ee.current=W);let et=(0,r.useMemo)(()=>{if(!x)return Object.assign(Object.assign({},null==I?void 0:I.style),N);let e={marginTop:x[1]};return"rtl"===T?e.left=Number.parseInt(x[0],10):e.right=-Number.parseInt(x[0],10),Object.assign(Object.assign(Object.assign({},e),null==I?void 0:I.style),N)},[T,x,N,null==I?void 0:I.style]),en=null!=E?E:"string"==typeof X||"number"==typeof X?X:void 0,er=!J&&(0===g?D:!!g&&!0!==g),ea=er?r.createElement("span",{className:"".concat(Z,"-status-text")},g):null,eo=X&&"object"==typeof X?(0,l.Tm)(X,e=>({style:Object.assign(Object.assign({},et),e.style)})):void 0,ei=(0,s.o2)(v,!1),es=o()(null==j?void 0:j.indicator,null===(n=null==I?void 0:I.classNames)||void 0===n?void 0:n.indicator,{["".concat(Z,"-status-dot")]:H,["".concat(Z,"-status-").concat(b)]:!!b,["".concat(Z,"-color-").concat(v)]:ei}),el={};v&&!ei&&(el.color=v,el.background=v);let ec=o()(Z,{["".concat(Z,"-status")]:H,["".concat(Z,"-not-a-wrapper")]:!p,["".concat(Z,"-rtl")]:"rtl"===T},S,M,null==I?void 0:I.className,null===(a=null==I?void 0:I.classNames)||void 0===a?void 0:a.root,null==j?void 0:j.root,V,A);if(!p&&H&&(g||K||!_)){let e=et.color;return z(r.createElement("span",Object.assign({},L,{className:ec,style:Object.assign(Object.assign(Object.assign({},null==P?void 0:P.root),null===(u=null==I?void 0:I.styles)||void 0===u?void 0:u.root),et)}),r.createElement("span",{className:es,style:Object.assign(Object.assign(Object.assign({},null==P?void 0:P.indicator),null===(d=null==I?void 0:I.styles)||void 0===d?void 0:d.indicator),el)}),er&&r.createElement("span",{style:{color:e},className:"".concat(Z,"-status-text")},g)))}return z(r.createElement("span",Object.assign({ref:t},L,{className:ec,style:Object.assign(Object.assign({},null===(h=null==I?void 0:I.styles)||void 0===h?void 0:h.root),null==P?void 0:P.root)}),p,r.createElement(i.ZP,{visible:!J,motionName:"".concat(Z,"-zoom"),motionAppear:!1,motionDeadline:1e3},e=>{var t,n;let{className:a}=e,i=F("scroll-number",f),s=ee.current,l=o()(null==j?void 0:j.indicator,null===(t=null==I?void 0:I.classNames)||void 0===t?void 0:t.indicator,{["".concat(Z,"-dot")]:s,["".concat(Z,"-count")]:!s,["".concat(Z,"-count-sm")]:"small"===C,["".concat(Z,"-multiple-words")]:!s&&$&&$.toString().length>1,["".concat(Z,"-status-").concat(b)]:!!b,["".concat(Z,"-color-").concat(v)]:ei}),c=Object.assign(Object.assign(Object.assign({},null==P?void 0:P.indicator),null===(n=null==I?void 0:I.styles)||void 0===n?void 0:n.indicator),et);return v&&!ei&&((c=c||{}).background=v),r.createElement(R,{prefixCls:i,show:!J,motionClassName:a,className:l,count:$,title:en,style:c,key:"scrollNumber"},eo)}),ea))});P.Ribbon=e=>{let{className:t,prefixCls:n,style:a,color:i,children:l,text:u,placement:d="end",rootClassName:h}=e,{getPrefixCls:m,direction:f}=r.useContext(c.E_),p=m("ribbon",n),b="".concat(p,"-wrapper"),[g,v,y]=N(p,b),w=(0,s.o2)(i,!1),k=o()(p,"".concat(p,"-placement-").concat(d),{["".concat(p,"-rtl")]:"rtl"===f,["".concat(p,"-color-").concat(i)]:w},t),C={},E={};return i&&!w&&(C.background=i,E.color=i),g(r.createElement("div",{className:o()(b,h,v,y)},l,r.createElement("div",{className:o()(k,v),style:Object.assign(Object.assign({},C),a)},r.createElement("span",{className:"".concat(p,"-text")},u),r.createElement("div",{className:"".concat(p,"-corner"),style:E}))))};var D=P},15051:function(e,t,n){"use strict";n.d(t,{Z:function(){return r}});let r=(0,n(79205).Z)("arrow-down",[["path",{d:"M12 5v14",key:"s699le"}],["path",{d:"m19 12-7 7-7-7",key:"1idqje"}]])},49322:function(e,t,n){"use strict";n.d(t,{Z:function(){return r}});let r=(0,n(79205).Z)("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"}]])},99397:function(e,t,n){"use strict";n.d(t,{Z:function(){return r}});let r=(0,n(79205).Z)("plus",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]])},32489:function(e,t,n){"use strict";n.d(t,{Z:function(){return r}});let r=(0,n(79205).Z)("x",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]])},86669:function(e,t,n){"use strict";n.d(t,{gc:function(){return w},jF:function(){return v}});var r=n(2265);let a=e=>"boolean"==typeof e||e instanceof Boolean,o=e=>"number"==typeof e||e instanceof Number,i=e=>"bigint"==typeof e||e instanceof BigInt,s=e=>!!e&&e instanceof Date,l=e=>"string"==typeof e||e instanceof String,c=e=>Array.isArray(e),u=e=>"object"==typeof e&&null!==e,d=e=>!!e&&e instanceof Object&&"function"==typeof e;function h(e,t){return void 0===t&&(t=!1),!e||t?`"${e}"`:e}function m(e){let{field:t,value:n,data:a,lastElement:o,openBracket:i,closeBracket:s,level:l,style:c,shouldExpandNode:u,clickToExpandNode:d,outerRef:m,beforeExpandChange:f}=e,p=(0,r.useRef)(!1),[b,v]=(0,r.useState)(()=>u(l,n,t)),y=(0,r.useRef)(null);(0,r.useEffect)(()=>{p.current?v(u(l,n,t)):p.current=!0},[u]);let w=(0,r.useId)();if(0===a.length)return function(e){let{field:t,openBracket:n,closeBracket:a,lastElement:o,style:i}=e;return(0,r.createElement)("div",{className:i.basicChildStyle,role:"treeitem","aria-selected":void 0},(t||""===t)&&(0,r.createElement)("span",{className:i.label},h(t,i.quotesForFieldNames),":"),(0,r.createElement)("span",{className:i.punctuation},n),(0,r.createElement)("span",{className:i.punctuation},a),!o&&(0,r.createElement)("span",{className:i.punctuation},","))}({field:t,openBracket:i,closeBracket:s,lastElement:o,style:c});let k=b?c.collapseIcon:c.expandIcon,C=b?c.ariaLables.collapseJson:c.ariaLables.expandJson,E=l+1,O=a.length-1,x=e=>{b!==e&&(!f||f({level:l,value:n,field:t,newExpandValue:e}))&&v(e)},N=e=>{if("ArrowRight"===e.key||"ArrowLeft"===e.key)e.preventDefault(),x("ArrowRight"===e.key);else if("ArrowUp"===e.key||"ArrowDown"===e.key){e.preventDefault();let t="ArrowUp"===e.key?-1:1;if(!m.current)return;let n=m.current.querySelectorAll("[role=button]"),r=-1;for(let e=0;e{var e;x(!b);let t=y.current;if(!t)return;let n=null===(e=m.current)||void 0===e?void 0:e.querySelector('[role=button][tabindex="0"]');n&&(n.tabIndex=-1),t.tabIndex=0,t.focus()};return(0,r.createElement)("div",{className:c.basicChildStyle,role:"treeitem","aria-expanded":b,"aria-selected":void 0},(0,r.createElement)("span",{className:k,onClick:S,onKeyDown:N,role:"button","aria-label":C,"aria-expanded":b,"aria-controls":b?w:void 0,ref:y,tabIndex:0===l?0:-1}),(t||""===t)&&(d?(0,r.createElement)("span",{className:c.clickableLabel,onClick:S,onKeyDown:N},h(t,c.quotesForFieldNames),":"):(0,r.createElement)("span",{className:c.label},h(t,c.quotesForFieldNames),":")),(0,r.createElement)("span",{className:c.punctuation},i),b?(0,r.createElement)("ul",{id:w,role:"group",className:c.childFieldsContainer},a.map((e,t)=>(0,r.createElement)(g,{key:e[0]||t,field:e[0],value:e[1],style:c,lastElement:t===O,level:E,shouldExpandNode:u,clickToExpandNode:d,beforeExpandChange:f,outerRef:m}))):(0,r.createElement)("span",{className:c.collapsedContent,onClick:S,onKeyDown:N}),(0,r.createElement)("span",{className:c.punctuation},s),!o&&(0,r.createElement)("span",{className:c.punctuation},","))}function f(e){let{field:t,value:n,style:r,lastElement:a,shouldExpandNode:o,clickToExpandNode:i,level:s,outerRef:l,beforeExpandChange:c}=e;return m({field:t,value:n,lastElement:a||!1,level:s,openBracket:"{",closeBracket:"}",style:r,shouldExpandNode:o,clickToExpandNode:i,data:Object.keys(n).map(e=>[e,n[e]]),outerRef:l,beforeExpandChange:c})}function p(e){let{field:t,value:n,style:r,lastElement:a,level:o,shouldExpandNode:i,clickToExpandNode:s,outerRef:l,beforeExpandChange:c}=e;return m({field:t,value:n,lastElement:a||!1,level:o,openBracket:"[",closeBracket:"]",style:r,shouldExpandNode:i,clickToExpandNode:s,data:n.map(e=>[void 0,e]),outerRef:l,beforeExpandChange:c})}function b(e){let t,{field:n,value:c,style:u,lastElement:m}=e,f=u.otherValue;if(null===c)t="null",f=u.nullValue;else if(void 0===c)t="undefined",f=u.undefinedValue;else if(l(c)){var p;p=!u.noQuotesForStringValues,t=u.stringifyStringValues?JSON.stringify(c):p?`"${c}"`:c,f=u.stringValue}else a(c)?(t=c?"true":"false",f=u.booleanValue):o(c)?(t=c.toString(),f=u.numberValue):i(c)?(t=`${c.toString()}n`,f=u.numberValue):t=s(c)?c.toISOString():d(c)?"function() { }":c.toString();return(0,r.createElement)("div",{className:u.basicChildStyle,role:"treeitem","aria-selected":void 0},(n||""===n)&&(0,r.createElement)("span",{className:u.label},h(n,u.quotesForFieldNames),":"),(0,r.createElement)("span",{className:f},t),!m&&(0,r.createElement)("span",{className:u.punctuation},","))}function g(e){let t=e.value;return c(t)?(0,r.createElement)(p,Object.assign({},e)):!u(t)||s(t)||d(t)?(0,r.createElement)(b,Object.assign({},e)):(0,r.createElement)(f,Object.assign({},e))}let v={container:"_2IvMF _GzYRV",basicChildStyle:"_2bkNM",childFieldsContainer:"_1BXBN",label:"_1MGIk",clickableLabel:"_2YKJg _1MGIk _1MFti",nullValue:"_2T6PJ",undefinedValue:"_1Gho6",stringValue:"_vGjyY",booleanValue:"_3zQKs",numberValue:"_1bQdo",otherValue:"_1xvuR",punctuation:"_3uHL6 _3eOF8",collapseIcon:"_oLqym _f10Tu _1MFti _1LId0",expandIcon:"_2AXVT _f10Tu _1MFti _1UmXx",collapsedContent:"_2KJWg _1pNG9 _1MFti",noQuotesForStringValues:!1,quotesForFieldNames:!1,ariaLables:{collapseJson:"collapse JSON",expandJson:"expand JSON"},stringifyStringValues:!1},y=()=>!0,w=e=>{let{data:t,style:n=v,shouldExpandNode:a=y,clickToExpandNode:o=!1,beforeExpandChange:i,compactTopLevel:s,...l}=e,c=(0,r.useRef)(null);return(0,r.createElement)("div",Object.assign({"aria-label":"JSON view"},l,{className:n.container,ref:c,role:"tree"}),s&&u(t)?Object.entries(t).map(e=>{let[t,s]=e;return(0,r.createElement)(g,{key:t,field:t,value:s,style:{...v,...n},lastElement:!0,level:1,shouldExpandNode:a,clickToExpandNode:o,beforeExpandChange:i,outerRef:c})}):(0,r.createElement)(g,{value:t,style:{...v,...n},lastElement:!0,level:0,shouldExpandNode:a,clickToExpandNode:o,outerRef:c,beforeExpandChange:i}))}},52621:function(){},10900:function(e,t,n){"use strict";var r=n(2265);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:"M10 19l-7-7m0 0l7-7m-7 7h18"}))});t.Z=a},91777:function(e,t,n){"use strict";var r=n(2265);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:"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"}))});t.Z=a},47686:function(e,t,n){"use strict";var r=n(2265);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:"M9 5l7 7-7 7"}))});t.Z=a},58710:function(e,t,n){"use strict";var r=n(2265);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:"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"}))});t.Z=a},82182:function(e,t,n){"use strict";var r=n(2265);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:"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"}),r.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"}))});t.Z=a},79814:function(e,t,n){"use strict";var r=n(2265);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:"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"}))});t.Z=a},2356:function(e,t,n){"use strict";var r=n(2265);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"}))});t.Z=a},93416:function(e,t,n){"use strict";var r=n(2265);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:"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"}))});t.Z=a},77355:function(e,t,n){"use strict";var r=n(2265);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:"M12 9v3m0 0v3m0-3h3m-3 0H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z"}))});t.Z=a},22452:function(e,t,n){"use strict";var r=n(2265);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:"M12 4v16m8-8H4"}))});t.Z=a},25327:function(e,t,n){"use strict";var r=n(2265);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:"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"}))});t.Z=a},49084:function(e,t,n){"use strict";var r=n(2265);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:"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4"}))});t.Z=a},3497:function(e,t,n){"use strict";var r=n(2265);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:"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"}))});t.Z=a},2894:function(e,t,n){"use strict";n.d(t,{R:function(){return s},m:function(){return i}});var r=n(18238),a=n(7989),o=n(11255),i=class extends a.F{#e;#t;#n;#r;constructor(e){super(),this.#e=e.client,this.mutationId=e.mutationId,this.#n=e.mutationCache,this.#t=[],this.state=e.state||s(),this.setOptions(e.options),this.scheduleGc()}setOptions(e){this.options=e,this.updateGcTime(this.options.gcTime)}get meta(){return this.options.meta}addObserver(e){this.#t.includes(e)||(this.#t.push(e),this.clearGcTimeout(),this.#n.notify({type:"observerAdded",mutation:this,observer:e}))}removeObserver(e){this.#t=this.#t.filter(t=>t!==e),this.scheduleGc(),this.#n.notify({type:"observerRemoved",mutation:this,observer:e})}optionalRemove(){this.#t.length||("pending"===this.state.status?this.scheduleGc():this.#n.remove(this))}continue(){return this.#r?.continue()??this.execute(this.state.variables)}async execute(e){let t=()=>{this.#a({type:"continue"})},n={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};this.#r=(0,o.Mz)({fn:()=>this.options.mutationFn?this.options.mutationFn(e,n):Promise.reject(Error("No mutationFn found")),onFail:(e,t)=>{this.#a({type:"failed",failureCount:e,error:t})},onPause:()=>{this.#a({type:"pause"})},onContinue:t,retry:this.options.retry??0,retryDelay:this.options.retryDelay,networkMode:this.options.networkMode,canRun:()=>this.#n.canRun(this)});let r="pending"===this.state.status,a=!this.#r.canStart();try{if(r)t();else{this.#a({type:"pending",variables:e,isPaused:a}),await this.#n.config.onMutate?.(e,this,n);let t=await this.options.onMutate?.(e,n);t!==this.state.context&&this.#a({type:"pending",context:t,variables:e,isPaused:a})}let o=await this.#r.start();return await this.#n.config.onSuccess?.(o,e,this.state.context,this,n),await this.options.onSuccess?.(o,e,this.state.context,n),await this.#n.config.onSettled?.(o,null,this.state.variables,this.state.context,this,n),await this.options.onSettled?.(o,null,e,this.state.context,n),this.#a({type:"success",data:o}),o}catch(t){try{throw await this.#n.config.onError?.(t,e,this.state.context,this,n),await this.options.onError?.(t,e,this.state.context,n),await this.#n.config.onSettled?.(void 0,t,this.state.variables,this.state.context,this,n),await this.options.onSettled?.(void 0,t,e,this.state.context,n),t}finally{this.#a({type:"error",error:t})}}finally{this.#n.runNext(this)}}#a(e){this.state=(t=>{switch(e.type){case"failed":return{...t,failureCount:e.failureCount,failureReason:e.error};case"pause":return{...t,isPaused:!0};case"continue":return{...t,isPaused:!1};case"pending":return{...t,context:e.context,data:void 0,failureCount:0,failureReason:null,error:null,isPaused:e.isPaused,status:"pending",variables:e.variables,submittedAt:Date.now()};case"success":return{...t,data:e.data,failureCount:0,failureReason:null,error:null,status:"success",isPaused:!1};case"error":return{...t,data:void 0,error:e.error,failureCount:t.failureCount+1,failureReason:e.error,isPaused:!1,status:"error"}}})(this.state),r.Vr.batch(()=>{this.#t.forEach(t=>{t.onMutationUpdate(e)}),this.#n.notify({mutation:this,type:"updated",action:e})})}};function s(){return{context:void 0,data:void 0,error:null,failureCount:0,failureReason:null,isPaused:!1,status:"idle",variables:void 0,submittedAt:0}}},21623:function(e,t,n){"use strict";n.d(t,{S:function(){return p}});var r=n(45345),a=n(21733),o=n(18238),i=n(24112),s=class extends i.l{constructor(e={}){super(),this.config=e,this.#o=new Map}#o;build(e,t,n){let o=t.queryKey,i=t.queryHash??(0,r.Rm)(o,t),s=this.get(i);return s||(s=new a.A({client:e,queryKey:o,queryHash:i,options:e.defaultQueryOptions(t),state:n,defaultOptions:e.getQueryDefaults(o)}),this.add(s)),s}add(e){this.#o.has(e.queryHash)||(this.#o.set(e.queryHash,e),this.notify({type:"added",query:e}))}remove(e){let t=this.#o.get(e.queryHash);t&&(e.destroy(),t===e&&this.#o.delete(e.queryHash),this.notify({type:"removed",query:e}))}clear(){o.Vr.batch(()=>{this.getAll().forEach(e=>{this.remove(e)})})}get(e){return this.#o.get(e)}getAll(){return[...this.#o.values()]}find(e){let t={exact:!0,...e};return this.getAll().find(e=>(0,r._x)(t,e))}findAll(e={}){let t=this.getAll();return Object.keys(e).length>0?t.filter(t=>(0,r._x)(e,t)):t}notify(e){o.Vr.batch(()=>{this.listeners.forEach(t=>{t(e)})})}onFocus(){o.Vr.batch(()=>{this.getAll().forEach(e=>{e.onFocus()})})}onOnline(){o.Vr.batch(()=>{this.getAll().forEach(e=>{e.onOnline()})})}},l=n(2894),c=class extends i.l{constructor(e={}){super(),this.config=e,this.#i=new Set,this.#s=new Map,this.#l=0}#i;#s;#l;build(e,t,n){let r=new l.m({client:e,mutationCache:this,mutationId:++this.#l,options:e.defaultMutationOptions(t),state:n});return this.add(r),r}add(e){this.#i.add(e);let t=u(e);if("string"==typeof t){let n=this.#s.get(t);n?n.push(e):this.#s.set(t,[e])}this.notify({type:"added",mutation:e})}remove(e){if(this.#i.delete(e)){let t=u(e);if("string"==typeof t){let n=this.#s.get(t);if(n){if(n.length>1){let t=n.indexOf(e);-1!==t&&n.splice(t,1)}else n[0]===e&&this.#s.delete(t)}}}this.notify({type:"removed",mutation:e})}canRun(e){let t=u(e);if("string"!=typeof t)return!0;{let n=this.#s.get(t),r=n?.find(e=>"pending"===e.state.status);return!r||r===e}}runNext(e){let t=u(e);if("string"!=typeof t)return Promise.resolve();{let n=this.#s.get(t)?.find(t=>t!==e&&t.state.isPaused);return n?.continue()??Promise.resolve()}}clear(){o.Vr.batch(()=>{this.#i.forEach(e=>{this.notify({type:"removed",mutation:e})}),this.#i.clear(),this.#s.clear()})}getAll(){return Array.from(this.#i)}find(e){let t={exact:!0,...e};return this.getAll().find(e=>(0,r.X7)(t,e))}findAll(e={}){return this.getAll().filter(t=>(0,r.X7)(e,t))}notify(e){o.Vr.batch(()=>{this.listeners.forEach(t=>{t(e)})})}resumePausedMutations(){let e=this.getAll().filter(e=>e.state.isPaused);return o.Vr.batch(()=>Promise.all(e.map(e=>e.continue().catch(r.ZT))))}};function u(e){return e.options.scope?.id}var d=n(87045),h=n(57853);function m(e){return{onFetch:(t,n)=>{let a=t.options,o=t.fetchOptions?.meta?.fetchMore?.direction,i=t.state.data?.pages||[],s=t.state.data?.pageParams||[],l={pages:[],pageParams:[]},c=0,u=async()=>{let n=!1,u=e=>{Object.defineProperty(e,"signal",{enumerable:!0,get:()=>(t.signal.aborted?n=!0:t.signal.addEventListener("abort",()=>{n=!0}),t.signal)})},d=(0,r.cG)(t.options,t.fetchOptions),h=async(e,a,o)=>{if(n)return Promise.reject();if(null==a&&e.pages.length)return Promise.resolve(e);let i=(()=>{let e={client:t.client,queryKey:t.queryKey,pageParam:a,direction:o?"backward":"forward",meta:t.options.meta};return u(e),e})(),s=await d(i),{maxPages:l}=t.options,c=o?r.Ht:r.VX;return{pages:c(e.pages,s,l),pageParams:c(e.pageParams,a,l)}};if(o&&i.length){let e="backward"===o,t={pages:i,pageParams:s},n=(e?function(e,{pages:t,pageParams:n}){return t.length>0?e.getPreviousPageParam?.(t[0],t,n[0],n):void 0}:f)(a,t);l=await h(t,n,e)}else{let t=e??i.length;do{let e=0===c?s[0]??a.initialPageParam:f(a,l);if(c>0&&null==e)break;l=await h(l,e),c++}while(ct.options.persister?.(u,{client:t.client,queryKey:t.queryKey,meta:t.options.meta,signal:t.signal},n):t.fetchFn=u}}}function f(e,{pages:t,pageParams:n}){let r=t.length-1;return t.length>0?e.getNextPageParam(t[r],t,n[r],n):void 0}var p=class{#c;#n;#u;#d;#h;#m;#f;#p;constructor(e={}){this.#c=e.queryCache||new s,this.#n=e.mutationCache||new c,this.#u=e.defaultOptions||{},this.#d=new Map,this.#h=new Map,this.#m=0}mount(){this.#m++,1===this.#m&&(this.#f=d.j.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#c.onFocus())}),this.#p=h.N.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#c.onOnline())}))}unmount(){this.#m--,0===this.#m&&(this.#f?.(),this.#f=void 0,this.#p?.(),this.#p=void 0)}isFetching(e){return this.#c.findAll({...e,fetchStatus:"fetching"}).length}isMutating(e){return this.#n.findAll({...e,status:"pending"}).length}getQueryData(e){let t=this.defaultQueryOptions({queryKey:e});return this.#c.get(t.queryHash)?.state.data}ensureQueryData(e){let t=this.defaultQueryOptions(e),n=this.#c.build(this,t),a=n.state.data;return void 0===a?this.fetchQuery(e):(e.revalidateIfStale&&n.isStaleByTime((0,r.KC)(t.staleTime,n))&&this.prefetchQuery(t),Promise.resolve(a))}getQueriesData(e){return this.#c.findAll(e).map(({queryKey:e,state:t})=>[e,t.data])}setQueryData(e,t,n){let a=this.defaultQueryOptions({queryKey:e}),o=this.#c.get(a.queryHash),i=o?.state.data,s=(0,r.SE)(t,i);if(void 0!==s)return this.#c.build(this,a).setData(s,{...n,manual:!0})}setQueriesData(e,t,n){return o.Vr.batch(()=>this.#c.findAll(e).map(({queryKey:e})=>[e,this.setQueryData(e,t,n)]))}getQueryState(e){let t=this.defaultQueryOptions({queryKey:e});return this.#c.get(t.queryHash)?.state}removeQueries(e){let t=this.#c;o.Vr.batch(()=>{t.findAll(e).forEach(e=>{t.remove(e)})})}resetQueries(e,t){let n=this.#c;return o.Vr.batch(()=>(n.findAll(e).forEach(e=>{e.reset()}),this.refetchQueries({type:"active",...e},t)))}cancelQueries(e,t={}){let n={revert:!0,...t};return Promise.all(o.Vr.batch(()=>this.#c.findAll(e).map(e=>e.cancel(n)))).then(r.ZT).catch(r.ZT)}invalidateQueries(e,t={}){return o.Vr.batch(()=>(this.#c.findAll(e).forEach(e=>{e.invalidate()}),e?.refetchType==="none")?Promise.resolve():this.refetchQueries({...e,type:e?.refetchType??e?.type??"active"},t))}refetchQueries(e,t={}){let n={...t,cancelRefetch:t.cancelRefetch??!0};return Promise.all(o.Vr.batch(()=>this.#c.findAll(e).filter(e=>!e.isDisabled()&&!e.isStatic()).map(e=>{let t=e.fetch(void 0,n);return n.throwOnError||(t=t.catch(r.ZT)),"paused"===e.state.fetchStatus?Promise.resolve():t}))).then(r.ZT)}fetchQuery(e){let t=this.defaultQueryOptions(e);void 0===t.retry&&(t.retry=!1);let n=this.#c.build(this,t);return n.isStaleByTime((0,r.KC)(t.staleTime,n))?n.fetch(t):Promise.resolve(n.state.data)}prefetchQuery(e){return this.fetchQuery(e).then(r.ZT).catch(r.ZT)}fetchInfiniteQuery(e){return e.behavior=m(e.pages),this.fetchQuery(e)}prefetchInfiniteQuery(e){return this.fetchInfiniteQuery(e).then(r.ZT).catch(r.ZT)}ensureInfiniteQueryData(e){return e.behavior=m(e.pages),this.ensureQueryData(e)}resumePausedMutations(){return h.N.isOnline()?this.#n.resumePausedMutations():Promise.resolve()}getQueryCache(){return this.#c}getMutationCache(){return this.#n}getDefaultOptions(){return this.#u}setDefaultOptions(e){this.#u=e}setQueryDefaults(e,t){this.#d.set((0,r.Ym)(e),{queryKey:e,defaultOptions:t})}getQueryDefaults(e){let t=[...this.#d.values()],n={};return t.forEach(t=>{(0,r.to)(e,t.queryKey)&&Object.assign(n,t.defaultOptions)}),n}setMutationDefaults(e,t){this.#h.set((0,r.Ym)(e),{mutationKey:e,defaultOptions:t})}getMutationDefaults(e){let t=[...this.#h.values()],n={};return t.forEach(t=>{(0,r.to)(e,t.mutationKey)&&Object.assign(n,t.defaultOptions)}),n}defaultQueryOptions(e){if(e._defaulted)return e;let t={...this.#u.queries,...this.getQueryDefaults(e.queryKey),...e,_defaulted:!0};return t.queryHash||(t.queryHash=(0,r.Rm)(t.queryKey,t)),void 0===t.refetchOnReconnect&&(t.refetchOnReconnect="always"!==t.networkMode),void 0===t.throwOnError&&(t.throwOnError=!!t.suspense),!t.networkMode&&t.persister&&(t.networkMode="offlineFirst"),t.queryFn===r.CN&&(t.enabled=!1),t}defaultMutationOptions(e){return e?._defaulted?e:{...this.#u.mutations,...e?.mutationKey&&this.getMutationDefaults(e.mutationKey),...e,_defaulted:!0}}clear(){this.#c.clear(),this.#n.clear()}}},21770:function(e,t,n){"use strict";n.d(t,{D:function(){return u}});var r=n(2265),a=n(2894),o=n(18238),i=n(24112),s=n(45345),l=class extends i.l{#e;#b=void 0;#g;#v;constructor(e,t){super(),this.#e=e,this.setOptions(t),this.bindMethods(),this.#y()}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.VS)(this.options,t)||this.#e.getMutationCache().notify({type:"observerOptionsUpdated",mutation:this.#g,observer:this}),t?.mutationKey&&this.options.mutationKey&&(0,s.Ym)(t.mutationKey)!==(0,s.Ym)(this.options.mutationKey)?this.reset():this.#g?.state.status==="pending"&&this.#g.setOptions(this.options)}onUnsubscribe(){this.hasListeners()||this.#g?.removeObserver(this)}onMutationUpdate(e){this.#y(),this.#w(e)}getCurrentResult(){return this.#b}reset(){this.#g?.removeObserver(this),this.#g=void 0,this.#y(),this.#w()}mutate(e,t){return this.#v=t,this.#g?.removeObserver(this),this.#g=this.#e.getMutationCache().build(this.#e,this.options),this.#g.addObserver(this),this.#g.execute(e)}#y(){let e=this.#g?.state??(0,a.R)();this.#b={...e,isPending:"pending"===e.status,isSuccess:"success"===e.status,isError:"error"===e.status,isIdle:"idle"===e.status,mutate:this.mutate,reset:this.reset}}#w(e){o.Vr.batch(()=>{if(this.#v&&this.hasListeners()){let t=this.#b.variables,n=this.#b.context,r={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};e?.type==="success"?(this.#v.onSuccess?.(e.data,t,n,r),this.#v.onSettled?.(e.data,null,t,n,r)):e?.type==="error"&&(this.#v.onError?.(e.error,t,n,r),this.#v.onSettled?.(void 0,e.error,t,n,r))}this.listeners.forEach(e=>{e(this.#b)})})}},c=n(29827);function u(e,t){let n=(0,c.NL)(t),[a]=r.useState(()=>new l(n,e));r.useEffect(()=>{a.setOptions(e)},[a,e]);let i=r.useSyncExternalStore(r.useCallback(e=>a.subscribe(o.Vr.batchCalls(e)),[a]),()=>a.getCurrentResult(),()=>a.getCurrentResult()),u=r.useCallback((e,t)=>{a.mutate(e,t).catch(s.ZT)},[a]);if(i.error&&(0,s.L3)(a.options.throwOnError,[i.error]))throw i.error;return{...i,mutate:u,mutateAsync:i.mutate}}},92668:function(e,t,n){"use strict";n.d(t,{I:function(){return s}});var r=n(59121),a=n(31091),o=n(63497),i=n(99649);function s(e,t){let{years:n=0,months:s=0,weeks:l=0,days:c=0,hours:u=0,minutes:d=0,seconds:h=0}=t,m=(0,i.Q)(e),f=s||n?(0,a.z)(m,s+12*n):m,p=c||l?(0,r.E)(f,c+7*l):f;return(0,o.L)(e,p.getTime()+1e3*(h+60*(d+60*u)))}},59121:function(e,t,n){"use strict";n.d(t,{E:function(){return o}});var r=n(99649),a=n(63497);function o(e,t){let n=(0,r.Q)(e);return isNaN(t)?(0,a.L)(e,NaN):(t&&n.setDate(n.getDate()+t),n)}},31091:function(e,t,n){"use strict";n.d(t,{z:function(){return o}});var r=n(99649),a=n(63497);function o(e,t){let n=(0,r.Q)(e);if(isNaN(t))return(0,a.L)(e,NaN);if(!t)return n;let o=n.getDate(),i=(0,a.L)(e,n.getTime());return(i.setMonth(n.getMonth()+t+1,0),o>=i.getDate())?i:(n.setFullYear(i.getFullYear(),i.getMonth(),o),n)}},63497:function(e,t,n){"use strict";function r(e,t){return e instanceof Date?new e.constructor(t):new Date(t)}n.d(t,{L:function(){return r}})},99649:function(e,t,n){"use strict";function r(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)}n.d(t,{Q:function(){return r}})}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/137-c6f74fedf576a11b.js b/litellm/proxy/_experimental/out/_next/static/chunks/137-c6f74fedf576a11b.js new file mode 100644 index 00000000000..fe98281d76f --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/137-c6f74fedf576a11b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[137],{1309:function(e,l,a){a.d(l,{C:function(){return t.Z}});var t=a(41649)},10137:function(e,l,a){a.d(l,{Z:function(){return lF}});var t,i,r,s,n=a(57437),o=a(2265),d=a(78489),c=a(12485),u=a(18135),m=a(35242),x=a(29706),p=a(77991),h=a(19250),g=a(57840),f=a(37592),j=a(15690),v=a(10032),y=a(3810),_=a(22116),b=a(64504);(t=r||(r={})).PresidioPII="Presidio PII",t.Bedrock="Bedrock Guardrail",t.Lakera="Lakera";let N={},w=e=>{let l={};return l.PresidioPII="Presidio PII",l.Bedrock="Bedrock Guardrail",l.Lakera="Lakera",Object.entries(e).forEach(e=>{let[a,t]=e;t&&"object"==typeof t&&"ui_friendly_name"in t&&(l[a.split("_").map((e,l)=>e.charAt(0).toUpperCase()+e.slice(1)).join("")]=t.ui_friendly_name)}),N=l,l},k=()=>Object.keys(N).length>0?N:r,C={PresidioPII:"presidio",Bedrock:"bedrock",Lakera:"lakera_v2",LitellmContentFilter:"litellm_content_filter",ToolPermission:"tool_permission"},S=e=>{Object.entries(e).forEach(e=>{let[l,a]=e;a&&"object"==typeof a&&"ui_friendly_name"in a&&(C[l.split("_").map((e,l)=>e.charAt(0).toUpperCase()+e.slice(1)).join("")]=l)})},Z=e=>!!e&&"Presidio PII"===k()[e],P=e=>!!e&&"LiteLLM Content Filter"===k()[e],A="../ui/assets/logos/",O={"Presidio PII":"".concat(A,"presidio.png"),"Bedrock Guardrail":"".concat(A,"bedrock.svg"),Lakera:"".concat(A,"lakeraai.jpeg"),"Azure Content Safety Prompt Shield":"".concat(A,"presidio.png"),"Azure Content Safety Text Moderation":"".concat(A,"presidio.png"),"Aporia AI":"".concat(A,"aporia.png"),"PANW Prisma AIRS":"".concat(A,"palo_alto_networks.jpeg"),"Noma Security":"".concat(A,"noma_security.png"),"Javelin Guardrails":"".concat(A,"javelin.png"),"Pillar Guardrail":"".concat(A,"pillar.jpeg"),"Google Cloud Model Armor":"".concat(A,"google.svg"),"Guardrails AI":"".concat(A,"guardrails_ai.jpeg"),"Lasso Guardrail":"".concat(A,"lasso.png"),"Pangea Guardrail":"".concat(A,"pangea.png"),"AIM Guardrail":"".concat(A,"aim_security.jpeg"),"OpenAI Moderation":"".concat(A,"openai_small.svg"),EnkryptAI:"".concat(A,"enkrypt_ai.avif"),"Prompt Security":"".concat(A,"prompt_security.png"),"LiteLLM Content Filter":"".concat(A,"litellm_logo.jpg")},I=e=>{if(!e)return{logo:"",displayName:"-"};let l=Object.keys(C).find(l=>C[l].toLowerCase()===e.toLowerCase());if(!l)return{logo:"",displayName:e};let a=k()[l];return{logo:O[a]||"",displayName:a||e}};var L=a(99981),T=a(5545),z=a(4156),E=a(97416),B=a(8881),M=a(10798),F=a(49638);let{Text:G}=g.default,{Option:K}=f.default,D=e=>e.replace(/_/g," "),R=e=>{switch(e){case"MASK":return(0,n.jsx)(E.Z,{style:{marginRight:4}});case"BLOCK":return(0,n.jsx)(B.Z,{style:{marginRight:4}});default:return null}},J=e=>{let{categories:l,selectedCategories:a,onChange:t}=e;return(0,n.jsxs)("div",{children:[(0,n.jsxs)("div",{className:"flex items-center mb-2",children:[(0,n.jsx)(M.Z,{className:"text-gray-500 mr-1"}),(0,n.jsx)(G,{className:"text-gray-500 font-medium",children:"Filter by category"})]}),(0,n.jsx)(f.default,{mode:"multiple",placeholder:"Select categories to filter by",style:{width:"100%"},onChange:t,value:a,allowClear:!0,showSearch:!0,optionFilterProp:"children",className:"mb-4",tagRender:e=>(0,n.jsx)(y.Z,{color:"blue",closable:e.closable,onClose:e.onClose,className:"mr-2 mb-2",children:e.label}),children:l.map(e=>(0,n.jsx)(K,{value:e.category,children:e.category},e.category))})]})},V=e=>{let{onSelectAll:l,onUnselectAll:a,hasSelectedEntities:t}=e;return(0,n.jsxs)("div",{className:"bg-gray-50 p-5 rounded-lg mb-6 border border-gray-200 shadow-sm",children:[(0,n.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[(0,n.jsxs)("div",{className:"flex items-center",children:[(0,n.jsx)(G,{strong:!0,className:"text-gray-700 text-base",children:"Quick Actions"}),(0,n.jsx)(L.Z,{title:"Apply action to all PII types at once",children:(0,n.jsx)("div",{className:"ml-2 text-gray-400 cursor-help text-xs",children:"ⓘ"})})]}),(0,n.jsx)(T.ZP,{color:"danger",variant:"outlined",onClick:a,disabled:!t,icon:(0,n.jsx)(F.Z,{}),children:"Unselect All"})]}),(0,n.jsxs)("div",{className:"grid grid-cols-2 gap-4",children:[(0,n.jsx)(T.ZP,{color:"primary",variant:"outlined",onClick:()=>l("MASK"),className:"h-10",block:!0,icon:(0,n.jsx)(E.Z,{}),children:"Select All & Mask"}),(0,n.jsx)(T.ZP,{color:"danger",variant:"outlined",onClick:()=>l("BLOCK"),className:"h-10 hover:bg-red-100",block:!0,icon:(0,n.jsx)(B.Z,{}),children:"Select All & Block"})]})]})},U=e=>{let{entities:l,selectedEntities:a,selectedActions:t,actions:i,onEntitySelect:r,onActionSelect:s,entityToCategoryMap:o}=e;return(0,n.jsxs)("div",{className:"border rounded-lg overflow-hidden shadow-sm",children:[(0,n.jsxs)("div",{className:"bg-gray-50 px-5 py-3 border-b flex",children:[(0,n.jsx)(G,{strong:!0,className:"flex-1 text-gray-700",children:"PII Type"}),(0,n.jsx)(G,{strong:!0,className:"w-32 text-right text-gray-700",children:"Action"})]}),(0,n.jsx)("div",{className:"max-h-[400px] overflow-y-auto",children:0===l.length?(0,n.jsx)("div",{className:"py-10 text-center text-gray-500",children:"No PII types match your filter criteria"}):l.map(e=>(0,n.jsxs)("div",{className:"px-5 py-3 flex items-center justify-between hover:bg-gray-50 border-b ".concat(a.includes(e)?"bg-blue-50":""),children:[(0,n.jsxs)("div",{className:"flex items-center flex-1",children:[(0,n.jsx)(z.Z,{checked:a.includes(e),onChange:()=>r(e),className:"mr-3"}),(0,n.jsx)(G,{className:a.includes(e)?"font-medium text-gray-900":"text-gray-700",children:D(e)}),o.get(e)&&(0,n.jsx)(y.Z,{className:"ml-2 text-xs",color:"blue",children:o.get(e)})]}),(0,n.jsx)("div",{className:"w-32",children:(0,n.jsx)(f.default,{value:a.includes(e)&&t[e]||"MASK",onChange:l=>s(e,l),style:{width:120},disabled:!a.includes(e),className:"".concat(a.includes(e)?"":"opacity-50"),dropdownMatchSelectWidth:!1,children:i.map(e=>(0,n.jsx)(K,{value:e,children:(0,n.jsxs)("div",{className:"flex items-center",children:[R(e),e]})},e))})})]},e))})]})},{Title:W,Text:Y}=g.default;var q=e=>{let{entities:l,actions:a,selectedEntities:t,selectedActions:i,onEntitySelect:r,onActionSelect:s,entityCategories:d=[]}=e,[c,u]=(0,o.useState)([]),m=new Map;d.forEach(e=>{e.entities.forEach(l=>{m.set(l,e.category)})});let x=l.filter(e=>0===c.length||c.includes(m.get(e)||""));return(0,n.jsxs)("div",{className:"pii-configuration",children:[(0,n.jsxs)("div",{className:"flex justify-between items-center mb-5",children:[(0,n.jsx)("div",{className:"flex items-center",children:(0,n.jsx)(W,{level:4,className:"!m-0 font-semibold text-gray-800",children:"Configure PII Protection"})}),(0,n.jsxs)(Y,{className:"text-gray-500",children:[t.length," items selected"]})]}),(0,n.jsxs)("div",{className:"mb-6",children:[(0,n.jsx)(J,{categories:d,selectedCategories:c,onChange:u}),(0,n.jsx)(V,{onSelectAll:e=>{l.forEach(l=>{t.includes(l)||r(l),s(l,e)})},onUnselectAll:()=>{t.forEach(e=>{r(e)})},hasSelectedEntities:t.length>0})]}),(0,n.jsx)(U,{entities:x,selectedEntities:t,selectedActions:i,actions:a,onEntitySelect:r,onActionSelect:s,entityToCategoryMap:m})]})},H=a(10353),$=a(31283),Q=a(24199),X=e=>{var l;let{selectedProvider:a,accessToken:t,providerParams:i=null,value:r=null}=e,[s,d]=(0,o.useState)(!1),[c,u]=(0,o.useState)(i),[m,x]=(0,o.useState)(null);if((0,o.useEffect)(()=>{if(i){u(i);return}let e=async()=>{if(t){d(!0),x(null);try{let e=await (0,h.getGuardrailProviderSpecificParams)(t);console.log("Provider params API response:",e),u(e),w(e),S(e)}catch(e){console.error("Error fetching provider params:",e),x("Failed to load provider parameters")}finally{d(!1)}}};i||e()},[t,i]),!a)return null;if(s)return(0,n.jsx)(H.Z,{tip:"Loading provider parameters..."});if(m)return(0,n.jsx)("div",{className:"text-red-500",children:m});let p=null===(l=C[a])||void 0===l?void 0:l.toLowerCase(),g=c&&c[p];if(console.log("Provider key:",p),console.log("Provider fields:",g),!g||0===Object.keys(g).length)return(0,n.jsx)("div",{children:"No configuration fields available for this provider."});console.log("Value:",r);let j=new Set(["patterns","blocked_words","blocked_words_file","categories","severity_threshold","pattern_redaction_format","keyword_redaction_tag"]),y=P(a),_=function(e){let l=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",a=arguments.length>2?arguments[2]:void 0;return Object.entries(e).map(e=>{let[t,i]=e,s=l?"".concat(l,".").concat(t):t,o=a?a[t]:null==r?void 0:r[t];return(console.log("Field value:",o),"ui_friendly_name"===t||"optional_params"===t&&"nested"===i.type&&i.fields||y&&j.has(t))?null:"nested"===i.type&&i.fields?(0,n.jsxs)("div",{children:[(0,n.jsx)("div",{className:"mb-2 font-medium",children:t}),(0,n.jsx)("div",{className:"ml-4 border-l-2 border-gray-200 pl-4",children:_(i.fields,s,o)})]},s):(0,n.jsx)(v.Z.Item,{name:s,label:t,tooltip:i.description,rules:i.required?[{required:!0,message:"".concat(t," is required")}]:void 0,children:"select"===i.type&&i.options?(0,n.jsx)(f.default,{placeholder:i.description,defaultValue:o||i.default_value,children:i.options.map(e=>(0,n.jsx)(f.default.Option,{value:e,children:e},e))}):"multiselect"===i.type&&i.options?(0,n.jsx)(f.default,{mode:"multiple",placeholder:i.description,defaultValue:o||i.default_value,children:i.options.map(e=>(0,n.jsx)(f.default.Option,{value:e,children:e},e))}):"bool"===i.type||"boolean"===i.type?(0,n.jsxs)(f.default,{placeholder:i.description,defaultValue:void 0!==o?String(o):i.default_value,children:[(0,n.jsx)(f.default.Option,{value:"true",children:"True"}),(0,n.jsx)(f.default.Option,{value:"false",children:"False"})]}):"number"===i.type?(0,n.jsx)(Q.Z,{step:1,width:400,placeholder:i.description,defaultValue:void 0!==o?Number(o):void 0}):t.includes("password")||t.includes("secret")||t.includes("key")?(0,n.jsx)($.o,{placeholder:i.description,type:"password",defaultValue:o||""}):(0,n.jsx)($.o,{placeholder:i.description,type:"text",defaultValue:o||""})},s)})};return(0,n.jsx)(n.Fragment,{children:_(g)})};let{Title:ee}=g.default,el=e=>{let{field:l,fieldKey:a,fullFieldKey:t,value:i}=e,[r,s]=o.useState([]),[d,c]=o.useState(l.dict_key_options||[]);o.useEffect(()=>{if(i&&"object"==typeof i){let e=Object.keys(i);s(e.map(e=>({key:e,id:"".concat(e,"_").concat(Date.now(),"_").concat(Math.random())}))),c((l.dict_key_options||[]).filter(l=>!e.includes(l)))}},[i,l.dict_key_options]);let u=e=>{e&&(s([...r,{key:e,id:"".concat(e,"_").concat(Date.now())}]),c(d.filter(l=>l!==e)))},m=(e,l)=>{s(r.filter(l=>l.id!==e)),c([...d,l].sort())};return(0,n.jsxs)("div",{className:"space-y-3",children:[r.map(e=>(0,n.jsxs)("div",{className:"flex items-center space-x-3 p-3 border rounded-lg",children:[(0,n.jsx)("div",{className:"w-24 font-medium text-sm",children:e.key}),(0,n.jsx)("div",{className:"flex-1",children:(0,n.jsx)(v.Z.Item,{name:Array.isArray(t)?[...t,e.key]:[t,e.key],style:{marginBottom:0},initialValue:i&&"object"==typeof i?i[e.key]:void 0,normalize:"number"===l.dict_value_type?e=>{if(null==e||""===e)return;let l=Number(e);return isNaN(l)?e:l}:void 0,children:"number"===l.dict_value_type?(0,n.jsx)(Q.Z,{step:1,width:200,placeholder:"Enter ".concat(e.key," value")}):"boolean"===l.dict_value_type?(0,n.jsxs)(f.default,{placeholder:"Select ".concat(e.key," value"),children:[(0,n.jsx)(f.default.Option,{value:!0,children:"True"}),(0,n.jsx)(f.default.Option,{value:!1,children:"False"})]}):(0,n.jsx)($.o,{placeholder:"Enter ".concat(e.key," value"),type:"text"})})}),(0,n.jsx)("button",{type:"button",className:"text-red-500 hover:text-red-700 text-sm",onClick:()=>m(e.id,e.key),children:"Remove"})]},e.id)),d.length>0&&(0,n.jsxs)("div",{className:"flex items-center space-x-3 mt-2",children:[(0,n.jsx)(f.default,{placeholder:"Select category to configure",style:{width:200},onSelect:e=>e&&u(e),value:void 0,children:d.map(e=>(0,n.jsx)(f.default.Option,{value:e,children:e},e))}),(0,n.jsx)("span",{className:"text-sm text-gray-500",children:"Select a category to add threshold configuration"})]})]})};var ea=e=>{let{optionalParams:l,parentFieldKey:a,values:t}=e,i=(e,l)=>{let i="".concat(a,".").concat(e),r=null==t?void 0:t[e];return(console.log("value",r),"dict"===l.type&&l.dict_key_options)?(0,n.jsxs)("div",{className:"mb-8 p-6 bg-gray-50 rounded-lg border border-gray-200",children:[(0,n.jsx)("div",{className:"mb-4 font-medium text-gray-900 text-base",children:e}),(0,n.jsx)("p",{className:"text-sm text-gray-600 mb-4",children:l.description}),(0,n.jsx)(el,{field:l,fieldKey:e,fullFieldKey:[a,e],value:r})]},i):(0,n.jsx)("div",{className:"mb-8 p-6 bg-white rounded-lg border border-gray-200 shadow-sm",children:(0,n.jsx)(v.Z.Item,{name:[a,e],label:(0,n.jsxs)("div",{className:"mb-2",children:[(0,n.jsx)("div",{className:"font-medium text-gray-900 text-base",children:e}),(0,n.jsx)("p",{className:"text-sm text-gray-600 mt-1",children:l.description})]}),rules:l.required?[{required:!0,message:"".concat(e," is required")}]:void 0,className:"mb-0",initialValue:void 0!==r?r:l.default_value,normalize:"number"===l.type?e=>{if(null==e||""===e)return;let l=Number(e);return isNaN(l)?e:l}:void 0,children:"select"===l.type&&l.options?(0,n.jsx)(f.default,{placeholder:l.description,children:l.options.map(e=>(0,n.jsx)(f.default.Option,{value:e,children:e},e))}):"multiselect"===l.type&&l.options?(0,n.jsx)(f.default,{mode:"multiple",placeholder:l.description,children:l.options.map(e=>(0,n.jsx)(f.default.Option,{value:e,children:e},e))}):"bool"===l.type||"boolean"===l.type?(0,n.jsxs)(f.default,{placeholder:l.description,children:[(0,n.jsx)(f.default.Option,{value:"true",children:"True"}),(0,n.jsx)(f.default.Option,{value:"false",children:"False"})]}):"number"===l.type?(0,n.jsx)(Q.Z,{step:1,width:400,placeholder:l.description}):e.includes("password")||e.includes("secret")||e.includes("key")?(0,n.jsx)($.o,{placeholder:l.description,type:"password"}):(0,n.jsx)($.o,{placeholder:l.description,type:"text"})})},i)};return l.fields&&0!==Object.keys(l.fields).length?(0,n.jsxs)("div",{className:"guardrail-optional-params",children:[(0,n.jsxs)("div",{className:"mb-8 pb-4 border-b border-gray-100",children:[(0,n.jsx)(ee,{level:3,className:"mb-2 font-semibold text-gray-900",children:"Optional Parameters"}),(0,n.jsx)("p",{className:"text-gray-600 text-sm",children:l.description||"Configure additional settings for this guardrail provider"})]}),(0,n.jsx)("div",{className:"space-y-8",children:Object.entries(l.fields).map(e=>{let[l,a]=e;return i(l,a)})})]}):null},et=a(9114),ei=a(5945),er=a(58760),es=a(65319),en=a(96473),eo=a(3632),ed=a(16312);let{Text:ec}=g.default,{Option:eu}=f.default;var em=e=>{let{visible:l,prebuiltPatterns:a,categories:t,selectedPatternName:i,patternAction:r,onPatternNameChange:s,onActionChange:o,onAdd:d,onCancel:c}=e;return(0,n.jsxs)(_.Z,{title:"Add prebuilt pattern",open:l,onCancel:c,footer:null,width:800,children:[(0,n.jsxs)(er.Z,{direction:"vertical",style:{width:"100%"},size:"large",children:[(0,n.jsxs)("div",{children:[(0,n.jsx)(ec,{strong:!0,children:"Pattern type"}),(0,n.jsx)(f.default,{placeholder:"Choose pattern type",value:i,onChange:s,style:{width:"100%",marginTop:8},showSearch:!0,filterOption:(e,l)=>{let t=a.find(e=>e.name===(null==l?void 0:l.value));return!!t&&(t.display_name.toLowerCase().includes(e.toLowerCase())||t.name.toLowerCase().includes(e.toLowerCase()))},children:t.map(e=>{let l=a.filter(l=>l.category===e);return 0===l.length?null:(0,n.jsx)(f.default.OptGroup,{label:e,children:l.map(e=>(0,n.jsx)(eu,{value:e.name,children:e.display_name},e.name))},e)})})]}),(0,n.jsxs)("div",{children:[(0,n.jsx)(ec,{strong:!0,children:"Action"}),(0,n.jsx)(ec,{type:"secondary",style:{display:"block",marginTop:4,marginBottom:8},children:"Choose what action the guardrail should take when this pattern is detected"}),(0,n.jsxs)(f.default,{value:r,onChange:o,style:{width:"100%"},children:[(0,n.jsx)(eu,{value:"BLOCK",children:"Block"}),(0,n.jsx)(eu,{value:"MASK",children:"Mask"})]})]})]}),(0,n.jsxs)("div",{style:{display:"flex",justifyContent:"flex-end",gap:"8px",marginTop:"24px"},children:[(0,n.jsx)(ed.z,{variant:"secondary",onClick:c,children:"Cancel"}),(0,n.jsx)(ed.z,{onClick:d,children:"Add"})]})]})};let{Text:ex}=g.default,{Option:ep}=f.default;var eh=e=>{let{visible:l,patternName:a,patternRegex:t,patternAction:i,onNameChange:r,onRegexChange:s,onActionChange:o,onAdd:d,onCancel:c}=e;return(0,n.jsxs)(_.Z,{title:"Add custom regex pattern",open:l,onCancel:c,footer:null,width:800,children:[(0,n.jsxs)(er.Z,{direction:"vertical",style:{width:"100%"},size:"large",children:[(0,n.jsxs)("div",{children:[(0,n.jsx)(ex,{strong:!0,children:"Pattern name"}),(0,n.jsx)(b.o,{placeholder:"e.g., internal_id, employee_code",value:a,onValueChange:r,style:{marginTop:8}})]}),(0,n.jsxs)("div",{children:[(0,n.jsx)(ex,{strong:!0,children:"Regex pattern"}),(0,n.jsx)(b.o,{placeholder:"e.g., ID-[0-9]{6}",value:t,onValueChange:s,style:{marginTop:8}}),(0,n.jsx)(ex,{type:"secondary",style:{fontSize:12},children:"Enter a valid regular expression to match sensitive data"})]}),(0,n.jsxs)("div",{children:[(0,n.jsx)(ex,{strong:!0,children:"Action"}),(0,n.jsx)(ex,{type:"secondary",style:{display:"block",marginTop:4,marginBottom:8},children:"Choose what action the guardrail should take when this pattern is detected"}),(0,n.jsxs)(f.default,{value:i,onChange:o,style:{width:"100%"},children:[(0,n.jsx)(ep,{value:"BLOCK",children:"Block"}),(0,n.jsx)(ep,{value:"MASK",children:"Mask"})]})]})]}),(0,n.jsxs)("div",{style:{display:"flex",justifyContent:"flex-end",gap:"8px",marginTop:"24px"},children:[(0,n.jsx)(b.z,{variant:"secondary",onClick:c,children:"Cancel"}),(0,n.jsx)(b.z,{onClick:d,children:"Add"})]})]})},eg=a(49566),ef=a(16853);let{Text:ej}=g.default,{Option:ev}=f.default;var ey=e=>{let{visible:l,keyword:a,action:t,description:i,onKeywordChange:r,onActionChange:s,onDescriptionChange:o,onAdd:c,onCancel:u}=e;return(0,n.jsxs)(_.Z,{title:"Add blocked keyword",open:l,onCancel:u,footer:null,width:800,children:[(0,n.jsxs)(er.Z,{direction:"vertical",style:{width:"100%"},size:"large",children:[(0,n.jsxs)("div",{children:[(0,n.jsx)(ej,{strong:!0,children:"Keyword"}),(0,n.jsx)(eg.Z,{placeholder:"Enter sensitive keyword or phrase",value:a,onValueChange:r,style:{marginTop:8}})]}),(0,n.jsxs)("div",{children:[(0,n.jsx)(ej,{strong:!0,children:"Action"}),(0,n.jsx)(ej,{type:"secondary",style:{display:"block",marginTop:4,marginBottom:8},children:"Choose what action the guardrail should take when this keyword is detected"}),(0,n.jsxs)(f.default,{value:t,onChange:s,style:{width:"100%"},children:[(0,n.jsx)(ev,{value:"BLOCK",children:"Block"}),(0,n.jsx)(ev,{value:"MASK",children:"Mask"})]})]}),(0,n.jsxs)("div",{children:[(0,n.jsx)(ej,{strong:!0,children:"Description (optional)"}),(0,n.jsx)(ef.Z,{placeholder:"Explain why this keyword is sensitive",value:i,onValueChange:o,rows:3,style:{marginTop:8}})]})]}),(0,n.jsxs)("div",{style:{display:"flex",justifyContent:"flex-end",gap:"8px",marginTop:"24px"},children:[(0,n.jsx)(d.Z,{variant:"secondary",onClick:u,children:"Cancel"}),(0,n.jsx)(d.Z,{onClick:c,children:"Add"})]})]})},e_=a(56609),eb=a(26349);let{Text:eN}=g.default,{Option:ew}=f.default;var ek=e=>{let{patterns:l,onActionChange:a,onRemove:t}=e,i=[{title:"Type",dataIndex:"type",key:"type",width:100,render:e=>(0,n.jsx)(y.Z,{color:"prebuilt"===e?"blue":"green",children:"prebuilt"===e?"Prebuilt":"Custom"})},{title:"Pattern name",dataIndex:"name",key:"name",render:(e,l)=>l.display_name||l.name},{title:"Regex pattern",dataIndex:"pattern",key:"pattern",render:e=>e?(0,n.jsxs)(eN,{code:!0,style:{fontSize:12},children:[e.substring(0,40),"..."]}):"-"},{title:"Action",dataIndex:"action",key:"action",width:150,render:(e,l)=>(0,n.jsxs)(f.default,{value:e,onChange:e=>a(l.id,e),style:{width:120},size:"small",children:[(0,n.jsx)(ew,{value:"BLOCK",children:"Block"}),(0,n.jsx)(ew,{value:"MASK",children:"Mask"})]})},{title:"",key:"actions",width:100,render:(e,l)=>(0,n.jsx)(ed.z,{type:"button",variant:"light",color:"red",size:"xs",icon:eb.Z,onClick:()=>t(l.id),children:"Delete"})}];return 0===l.length?(0,n.jsx)("div",{style:{textAlign:"center",padding:"40px 0",color:"#999"},children:"No patterns added."}):(0,n.jsx)(e_.Z,{dataSource:l,columns:i,rowKey:"id",pagination:!1,size:"small"})};let{Text:eC}=g.default,{Option:eS}=f.default;var eZ=e=>{let{keywords:l,onActionChange:a,onRemove:t}=e,i=[{title:"Keyword",dataIndex:"keyword",key:"keyword"},{title:"Action",dataIndex:"action",key:"action",width:150,render:(e,l)=>(0,n.jsxs)(f.default,{value:e,onChange:e=>a(l.id,"action",e),style:{width:120},size:"small",children:[(0,n.jsx)(eS,{value:"BLOCK",children:"Block"}),(0,n.jsx)(eS,{value:"MASK",children:"Mask"})]})},{title:"Description",dataIndex:"description",key:"description",render:e=>e||"-"},{title:"",key:"actions",width:100,render:(e,l)=>(0,n.jsx)(ed.z,{type:"button",variant:"light",color:"red",size:"xs",icon:eb.Z,onClick:()=>t(l.id),children:"Delete"})}];return 0===l.length?(0,n.jsx)("div",{style:{textAlign:"center",padding:"40px 0",color:"#999"},children:"No keywords added."}):(0,n.jsx)(e_.Z,{dataSource:l,columns:i,rowKey:"id",pagination:!1,size:"small"})},eP=a(44851),eA=a(38434);let{Title:eO,Text:eI}=g.default,{Option:eL}=f.default,{Panel:eT}=eP.default;var ez=e=>{var l;let{availableCategories:a,selectedCategories:t,onCategoryAdd:i,onCategoryRemove:r,onCategoryUpdate:s,accessToken:d}=e,[c,u]=o.useState(""),[m,x]=o.useState({}),[p,g]=o.useState({}),[j,v]=o.useState([]),[_,b]=o.useState(""),[N,w]=o.useState(!1),k=async e=>{if(d&&!m[e]){g(l=>({...l,[e]:!0}));try{let l=await (0,h.getCategoryYaml)(d,e);x(a=>({...a,[e]:l.yaml_content}))}catch(l){console.error("Failed to fetch YAML for category ".concat(e,":"),l)}finally{g(l=>({...l,[e]:!1}))}}};o.useEffect(()=>{if(c&&d){let e=m[c];if(e){b(e);return}w(!0),console.log("Fetching YAML for category: ".concat(c),{accessToken:d?"present":"missing"}),(0,h.getCategoryYaml)(d,c).then(e=>{console.log("Successfully fetched YAML for ".concat(c,":"),e),b(e.yaml_content),x(l=>({...l,[c]:e.yaml_content}))}).catch(e=>{console.error("Failed to fetch preview YAML for category ".concat(c,":"),e),b("")}).finally(()=>{w(!1)})}else b(""),w(!1)},[c,d]);let C=[{title:"Category",dataIndex:"display_name",key:"display_name",render:(e,l)=>{let t=a.find(e=>e.name===l.category);return(0,n.jsxs)("div",{children:[(0,n.jsx)("div",{style:{fontWeight:500},children:e}),(null==t?void 0:t.description)&&(0,n.jsx)("div",{style:{fontSize:"12px",color:"#888",marginTop:"4px"},children:t.description})]})}},{title:"Action",dataIndex:"action",key:"action",width:150,render:(e,l)=>(0,n.jsxs)(f.default,{value:e,onChange:e=>s(l.id,"action",e),style:{width:"100%"},children:[(0,n.jsx)(eL,{value:"BLOCK",children:(0,n.jsx)(y.Z,{color:"red",children:"BLOCK"})}),(0,n.jsx)(eL,{value:"MASK",children:(0,n.jsx)(y.Z,{color:"orange",children:"MASK"})})]})},{title:"Severity Threshold",dataIndex:"severity_threshold",key:"severity_threshold",width:180,render:(e,l)=>(0,n.jsxs)(f.default,{value:e,onChange:e=>s(l.id,"severity_threshold",e),style:{width:"100%"},children:[(0,n.jsx)(eL,{value:"low",children:"Low"}),(0,n.jsx)(eL,{value:"medium",children:"Medium"}),(0,n.jsx)(eL,{value:"high",children:"High"})]})},{title:"",key:"actions",width:80,render:(e,l)=>(0,n.jsx)(ed.z,{icon:eb.Z,onClick:()=>r(l.id),variant:"secondary",size:"xs",children:"Remove"})}],S=a.filter(e=>!t.some(l=>l.category===e.name));return(0,n.jsxs)(ei.Z,{title:(0,n.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[(0,n.jsx)(eO,{level:5,style:{margin:0},children:"Content Categories"}),(0,n.jsx)(eI,{type:"secondary",style:{fontSize:14,fontWeight:400},children:"Detect harmful content, bias, and inappropriate advice using semantic analysis"})]}),size:"small",children:[(0,n.jsxs)("div",{style:{marginBottom:16,display:"flex",gap:8},children:[(0,n.jsx)(f.default,{placeholder:"Select a content category",value:c||void 0,onChange:u,style:{flex:1},showSearch:!0,optionLabelProp:"label",filterOption:(e,l)=>{var a,t;return(null!==(t=null==l?void 0:null===(a=l.label)||void 0===a?void 0:a.toString().toLowerCase())&&void 0!==t?t:"").includes(e.toLowerCase())},children:S.map(e=>(0,n.jsx)(eL,{value:e.name,label:e.display_name,children:(0,n.jsxs)("div",{children:[(0,n.jsx)("div",{style:{fontWeight:500},children:e.display_name}),(0,n.jsx)("div",{style:{fontSize:"12px",color:"#666",marginTop:"2px"},children:e.description})]})},e.name))}),(0,n.jsx)(ed.z,{onClick:()=>{if(!c)return;let e=a.find(e=>e.name===c);!e||t.some(e=>e.category===c)||(i({id:"category-".concat(Date.now()),category:e.name,display_name:e.display_name,action:e.default_action,severity_threshold:"medium"}),u(""),b(""))},disabled:!c,icon:en.Z,children:"Add"})]}),c&&(0,n.jsxs)("div",{style:{marginBottom:16,padding:"12px",background:"#f9f9f9",border:"1px solid #e0e0e0",borderRadius:"4px"},children:[(0,n.jsxs)("div",{style:{marginBottom:8,fontWeight:500,fontSize:"14px"},children:["Preview: ",null===(l=a.find(e=>e.name===c))||void 0===l?void 0:l.display_name]}),N?(0,n.jsx)("div",{style:{padding:"16px",textAlign:"center",color:"#888"},children:"Loading YAML..."}):_?(0,n.jsx)("pre",{style:{background:"#fff",padding:"12px",borderRadius:"4px",overflow:"auto",maxHeight:"300px",fontSize:"12px",lineHeight:"1.5",margin:0,border:"1px solid #e0e0e0"},children:(0,n.jsx)("code",{children:_})}):(0,n.jsx)("div",{style:{padding:"8px",textAlign:"center",color:"#888",fontSize:"12px"},children:"Unable to load YAML content"})]}),t.length>0?(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e_.Z,{dataSource:t,columns:C,pagination:!1,size:"small",rowKey:"id"}),(0,n.jsx)("div",{style:{marginTop:16},children:(0,n.jsx)(eP.default,{activeKey:j,onChange:e=>{let l=Array.isArray(e)?e:e?[e]:[],a=new Set(j);l.forEach(e=>{a.has(e)||m[e]||k(e)}),v(l)},ghost:!0,children:t.map(e=>(0,n.jsx)(eT,{header:(0,n.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:8},children:[(0,n.jsx)(eA.Z,{}),(0,n.jsxs)("span",{children:["View YAML for ",e.display_name]})]}),children:p[e.category]?(0,n.jsx)("div",{style:{padding:"16px",textAlign:"center",color:"#888"},children:"Loading YAML..."}):m[e.category]?(0,n.jsx)("pre",{style:{background:"#f5f5f5",padding:"16px",borderRadius:"4px",overflow:"auto",maxHeight:"400px",fontSize:"12px",lineHeight:"1.5",margin:0},children:(0,n.jsx)("code",{children:m[e.category]})}):(0,n.jsx)("div",{style:{padding:"16px",textAlign:"center",color:"#888"},children:"YAML will load when expanded"})},e.category))})})]}):(0,n.jsx)("div",{style:{textAlign:"center",padding:"24px",color:"#888",border:"1px dashed #d9d9d9",borderRadius:"4px"},children:"No content categories selected. Add categories to detect harmful content, bias, or inappropriate advice."})]})};let{Title:eE,Text:eB}=g.default;var eM=e=>{let{prebuiltPatterns:l,categories:a,selectedPatterns:t,blockedWords:i,onPatternAdd:r,onPatternRemove:s,onPatternActionChange:d,onBlockedWordAdd:c,onBlockedWordRemove:u,onBlockedWordUpdate:m,onFileUpload:x,accessToken:p,showStep:g,contentCategories:f=[],selectedContentCategories:j=[],onContentCategoryAdd:v,onContentCategoryRemove:y,onContentCategoryUpdate:_}=e,[b,N]=(0,o.useState)(!1),[w,k]=(0,o.useState)(!1),[C,S]=(0,o.useState)(!1),[Z,P]=(0,o.useState)(""),[A,O]=(0,o.useState)("BLOCK"),[I,L]=(0,o.useState)(""),[T,z]=(0,o.useState)(""),[E,B]=(0,o.useState)("BLOCK"),[M,F]=(0,o.useState)(""),[G,K]=(0,o.useState)("BLOCK"),[D,R]=(0,o.useState)(""),[J,V]=(0,o.useState)(!1),U=async e=>{V(!0);try{let l=await e.text();if(p){let e=await (0,h.validateBlockedWordsFile)(p,l);if(e.valid)x&&x(l),et.Z.success(e.message||"File uploaded successfully");else{let l=e.error||e.errors&&e.errors.join(", ")||"Invalid file";et.Z.error("Validation failed: ".concat(l))}}}catch(e){et.Z.error("Failed to upload file: ".concat(e))}finally{V(!1)}return!1};return(0,n.jsxs)("div",{className:"space-y-6",children:[!g&&(0,n.jsx)("div",{children:(0,n.jsx)(eB,{type:"secondary",children:"Configure patterns, keywords, and content categories to detect and filter sensitive information in requests and responses."})}),(!g||"patterns"===g)&&(0,n.jsxs)(ei.Z,{title:(0,n.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[(0,n.jsx)(eE,{level:5,style:{margin:0},children:"Pattern Detection"}),(0,n.jsx)(eB,{type:"secondary",style:{fontSize:14,fontWeight:400},children:"Detect sensitive information using regex patterns (SSN, credit cards, API keys, etc.)"})]}),size:"small",children:[(0,n.jsx)("div",{style:{marginBottom:16},children:(0,n.jsxs)(er.Z,{children:[(0,n.jsx)(ed.z,{type:"button",onClick:()=>N(!0),icon:en.Z,children:"Add prebuilt pattern"}),(0,n.jsx)(ed.z,{type:"button",onClick:()=>S(!0),variant:"secondary",icon:en.Z,children:"Add custom regex"})]})}),(0,n.jsx)(ek,{patterns:t,onActionChange:d,onRemove:s})]}),(!g||"keywords"===g)&&(0,n.jsxs)(ei.Z,{title:(0,n.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[(0,n.jsx)(eE,{level:5,style:{margin:0},children:"Blocked Keywords"}),(0,n.jsx)(eB,{type:"secondary",style:{fontSize:14,fontWeight:400},children:"Block or mask specific sensitive terms and phrases"})]}),size:"small",children:[(0,n.jsx)("div",{style:{marginBottom:16},children:(0,n.jsxs)(er.Z,{children:[(0,n.jsx)(ed.z,{type:"button",onClick:()=>k(!0),icon:en.Z,children:"Add keyword"}),(0,n.jsx)(es.default,{beforeUpload:U,accept:".yaml,.yml",showUploadList:!1,children:(0,n.jsx)(ed.z,{type:"button",variant:"secondary",icon:eo.Z,loading:J,children:"Upload YAML file"})})]})}),(0,n.jsx)(eZ,{keywords:i,onActionChange:m,onRemove:u})]}),(!g||"categories"===g)&&f.length>0&&v&&y&&_&&(0,n.jsx)(ez,{availableCategories:f,selectedCategories:j,onCategoryAdd:v,onCategoryRemove:y,onCategoryUpdate:_,accessToken:p}),(0,n.jsx)(em,{visible:b,prebuiltPatterns:l,categories:a,selectedPatternName:Z,patternAction:A,onPatternNameChange:P,onActionChange:e=>O(e),onAdd:()=>{if(!Z){et.Z.error("Please select a pattern");return}let e=l.find(e=>e.name===Z);r({id:"pattern-".concat(Date.now()),type:"prebuilt",name:Z,display_name:null==e?void 0:e.display_name,action:A}),N(!1),P(""),O("BLOCK")},onCancel:()=>{N(!1),P(""),O("BLOCK")}}),(0,n.jsx)(eh,{visible:C,patternName:I,patternRegex:T,patternAction:E,onNameChange:L,onRegexChange:z,onActionChange:e=>B(e),onAdd:()=>{if(!I||!T){et.Z.error("Please provide pattern name and regex");return}r({id:"custom-".concat(Date.now()),type:"custom",name:I,pattern:T,action:E}),S(!1),L(""),z(""),B("BLOCK")},onCancel:()=>{S(!1),L(""),z(""),B("BLOCK")}}),(0,n.jsx)(ey,{visible:w,keyword:M,action:G,description:D,onKeywordChange:F,onActionChange:e=>K(e),onDescriptionChange:R,onAdd:()=>{if(!M){et.Z.error("Please enter a keyword");return}c({id:"word-".concat(Date.now()),keyword:M,action:G,description:D||void 0}),k(!1),F(""),R(""),K("BLOCK")},onCancel:()=>{k(!1),F(""),R(""),K("BLOCK")}})]})},eF=a(78801),eG=a(4260),eK=a(23496),eD=a(85180),eR=a(15424);let eJ={rules:[],default_action:"deny",on_disallowed_action:"block",violation_message_template:""},eV=e=>({...eJ,...e||{},rules:(null==e?void 0:e.rules)?[...e.rules]:[]});var eU=e=>{let{value:l,onChange:a,disabled:t=!1}=e,i=eV(l),r=e=>{let l={...i,...e};null==a||a(l)},s=(e,l)=>{r({rules:i.rules.map((a,t)=>t===e?{...a,...l}:a)})},o=e=>{r({rules:i.rules.filter((l,a)=>a!==e)})},d=(e,l)=>{let a=i.rules[e];if(!a)return;let t=Object.entries(a.allowed_param_patterns||{});l(t);let r={};t.forEach(e=>{let[l,a]=e;r[l]=a}),s(e,{allowed_param_patterns:Object.keys(r).length>0?r:void 0})},c=(e,l,a)=>{d(e,e=>{if(!e[l])return;let[,t]=e[l];e[l]=[a,t]})},u=(e,l,a)=>{d(e,e=>{if(!e[l])return;let[t]=e[l];e[l]=[t,a]})},m=(e,l)=>{let a=Object.entries(e.allowed_param_patterns||{});return 0===a.length?(0,n.jsx)(T.ZP,{disabled:t,size:"small",onClick:()=>s(l,{allowed_param_patterns:{"":""}}),children:"+ Restrict tool arguments (optional)"}):(0,n.jsxs)("div",{className:"space-y-2",children:[(0,n.jsx)(eF.x,{className:"text-sm text-gray-600",children:"Argument constraints (dot or array paths)"}),a.map((a,i)=>{let[r,s]=a;return(0,n.jsxs)(er.Z,{align:"start",children:[(0,n.jsx)(eG.default,{disabled:t,placeholder:"messages[0].content",value:r,onChange:e=>c(l,i,e.target.value)}),(0,n.jsx)(eG.default,{disabled:t,placeholder:"^email@.*$",value:s,onChange:e=>u(l,i,e.target.value)}),(0,n.jsx)(T.ZP,{disabled:t,icon:(0,n.jsx)(eb.Z,{}),danger:!0,onClick:()=>d(l,e=>{e.splice(i,1)})})]},"".concat(e.id||l,"-").concat(i))}),(0,n.jsx)(T.ZP,{disabled:t,size:"small",onClick:()=>s(l,{allowed_param_patterns:{...e.allowed_param_patterns||{},"":""}}),children:"+ Add another constraint"})]})};return(0,n.jsxs)(eF.Z,{children:[(0,n.jsxs)("div",{className:"flex items-center justify-between",children:[(0,n.jsxs)("div",{children:[(0,n.jsx)(eF.x,{className:"text-lg font-semibold",children:"LiteLLM Tool Permission Guardrail"}),(0,n.jsx)(eF.x,{className:"text-sm text-gray-500",children:"Provide regex patterns (e.g., ^mcp__github_.*$) for tool names or types and optionally constrain payload fields."})]}),!t&&(0,n.jsx)(T.ZP,{icon:(0,n.jsx)(en.Z,{}),type:"primary",onClick:()=>{r({rules:[...i.rules,{id:"rule_".concat(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,n.jsx)(eK.Z,{}),0===i.rules.length?(0,n.jsx)(eD.Z,{description:"No tool rules added yet"}):(0,n.jsx)("div",{className:"space-y-4",children:i.rules.map((e,l)=>{var a,i;return(0,n.jsxs)(eF.Z,{className:"bg-gray-50",children:[(0,n.jsxs)("div",{className:"flex items-center justify-between mb-3",children:[(0,n.jsxs)(eF.x,{className:"font-semibold",children:["Rule ",l+1]}),(0,n.jsx)(T.ZP,{icon:(0,n.jsx)(eb.Z,{}),danger:!0,type:"text",disabled:t,onClick:()=>o(l),children:"Remove"})]}),(0,n.jsxs)("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-2",children:[(0,n.jsxs)("div",{children:[(0,n.jsx)(eF.x,{className:"text-sm font-medium",children:"Rule ID"}),(0,n.jsx)(eG.default,{disabled:t,placeholder:"unique_rule_id",value:e.id,onChange:e=>s(l,{id:e.target.value})})]}),(0,n.jsxs)("div",{children:[(0,n.jsx)(eF.x,{className:"text-sm font-medium",children:"Tool Name (optional)"}),(0,n.jsx)(eG.default,{disabled:t,placeholder:"^mcp__github_.*$",value:null!==(a=e.tool_name)&&void 0!==a?a:"",onChange:e=>s(l,{tool_name:""===e.target.value.trim()?void 0:e.target.value})})]})]}),(0,n.jsx)("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-2 mt-4",children:(0,n.jsxs)("div",{children:[(0,n.jsx)(eF.x,{className:"text-sm font-medium",children:"Tool Type (optional)"}),(0,n.jsx)(eG.default,{disabled:t,placeholder:"^function$",value:null!==(i=e.tool_type)&&void 0!==i?i:"",onChange:e=>s(l,{tool_type:""===e.target.value.trim()?void 0:e.target.value})})]})}),(0,n.jsxs)("div",{className:"mt-4 flex flex-col gap-2",children:[(0,n.jsx)(eF.x,{className:"text-sm font-medium",children:"Decision"}),(0,n.jsxs)(f.default,{disabled:t,value:e.decision,style:{width:200},onChange:e=>s(l,{decision:e}),children:[(0,n.jsx)(f.default.Option,{value:"allow",children:"Allow"}),(0,n.jsx)(f.default.Option,{value:"deny",children:"Deny"})]})]}),(0,n.jsx)("div",{className:"mt-4",children:m(e,l)})]},e.id||l)})}),(0,n.jsx)(eK.Z,{}),(0,n.jsxs)("div",{className:"grid gap-4 md:grid-cols-2",children:[(0,n.jsxs)("div",{children:[(0,n.jsx)(eF.x,{className:"text-sm font-medium",children:"Default action"}),(0,n.jsxs)(f.default,{disabled:t,value:i.default_action,onChange:e=>r({default_action:e}),children:[(0,n.jsx)(f.default.Option,{value:"allow",children:"Allow"}),(0,n.jsx)(f.default.Option,{value:"deny",children:"Deny"})]})]}),(0,n.jsxs)("div",{children:[(0,n.jsxs)(eF.x,{className:"text-sm font-medium flex items-center gap-1",children:["On disallowed action",(0,n.jsx)(L.Z,{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,n.jsx)(eR.Z,{})})]}),(0,n.jsxs)(f.default,{disabled:t,value:i.on_disallowed_action,onChange:e=>r({on_disallowed_action:e}),children:[(0,n.jsx)(f.default.Option,{value:"block",children:"Block"}),(0,n.jsx)(f.default.Option,{value:"rewrite",children:"Rewrite"})]})]})]}),(0,n.jsxs)("div",{className:"mt-4",children:[(0,n.jsx)(eF.x,{className:"text-sm font-medium",children:"Violation message (optional)"}),(0,n.jsx)(eG.default.TextArea,{disabled:t,rows:3,placeholder:"This violates our org policy...",value:i.violation_message_template,onChange:e=>r({violation_message_template:e.target.value})})]})]})};let{Title:eW,Text:eY,Link:eq}=g.default,{Option:eH}=f.default,{Step:e$}=j.default,eQ={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"};var eX=e=>{let{visible:l,onClose:a,accessToken:t,onSuccess:i}=e,[r]=v.Z.useForm(),[s,d]=(0,o.useState)(!1),[c,u]=(0,o.useState)(null),[m,x]=(0,o.useState)(null),[p,g]=(0,o.useState)([]),[N,A]=(0,o.useState)({}),[I,L]=(0,o.useState)(0),[T,z]=(0,o.useState)(null),[E,B]=(0,o.useState)([]),[M,F]=(0,o.useState)(2),[G,K]=(0,o.useState)({}),[D,R]=(0,o.useState)([]),[J,V]=(0,o.useState)([]),[U,W]=(0,o.useState)([]),[Y,H]=(0,o.useState)({rules:[],default_action:"deny",on_disallowed_action:"block",violation_message_template:""}),$=(0,o.useMemo)(()=>!!c&&"tool_permission"===(C[c]||"").toLowerCase(),[c]);(0,o.useEffect)(()=>{t&&(async()=>{try{let[e,l]=await Promise.all([(0,h.getGuardrailUISettings)(t),(0,h.getGuardrailProviderSpecificParams)(t)]);x(e),z(l),w(l),S(l)}catch(e){console.error("Error fetching guardrail data:",e),et.Z.fromBackend("Failed to load guardrail configuration")}})()},[t]);let Q=e=>{u(e),r.setFieldsValue({config:void 0,presidio_analyzer_api_base:void 0,presidio_anonymizer_api_base:void 0}),g([]),A({}),B([]),F(2),K({}),H({rules:[],default_action:"deny",on_disallowed_action:"block",violation_message_template:""})},ee=e=>{g(l=>l.includes(e)?l.filter(l=>l!==e):[...l,e])},el=(e,l)=>{A(a=>({...a,[e]:l}))},ei=async()=>{try{if(0===I&&(await r.validateFields(["guardrail_name","provider","mode","default_on"]),c)){let e=["guardrail_name","provider","mode","default_on"];"PresidioPII"===c&&e.push("presidio_analyzer_api_base","presidio_anonymizer_api_base"),await r.validateFields(e)}if(1===I&&Z(c)&&0===p.length){et.Z.fromBackend("Please select at least one PII entity to continue");return}L(I+1)}catch(e){console.error("Form validation failed:",e)}},er=()=>{L(I-1)},es=()=>{r.resetFields(),u(null),g([]),A({}),B([]),F(2),K({}),R([]),V([]),W([]),H({rules:[],default_action:"deny",on_disallowed_action:"block",violation_message_template:""}),L(0)},en=()=>{es(),a()},eo=async()=>{try{d(!0),await r.validateFields();let l=r.getFieldsValue(!0),s=C[l.provider],n={guardrail_name:l.guardrail_name,litellm_params:{guardrail:s,mode:l.mode,default_on:l.default_on},guardrail_info:{}};if("PresidioPII"===l.provider&&p.length>0){let e={};p.forEach(l=>{e[l]=N[l]||"MASK"}),n.litellm_params.pii_entities_config=e,l.presidio_analyzer_api_base&&(n.litellm_params.presidio_analyzer_api_base=l.presidio_analyzer_api_base),l.presidio_anonymizer_api_base&&(n.litellm_params.presidio_anonymizer_api_base=l.presidio_anonymizer_api_base)}if(P(l.provider))D.length>0&&(n.litellm_params.patterns=D.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}))),J.length>0&&(n.litellm_params.blocked_words=J.map(e=>({keyword:e.keyword,action:e.action,description:e.description}))),U.length>0&&(n.litellm_params.categories=U.map(e=>({category:e.category,enabled:!0,action:e.action,severity_threshold:e.severity_threshold||"medium"})));else if(l.config)try{let e=JSON.parse(l.config);n.guardrail_info=e}catch(e){et.Z.fromBackend("Invalid JSON in configuration"),d(!1);return}if("tool_permission"===s){if(0===Y.rules.length){et.Z.fromBackend("Add at least one tool permission rule"),d(!1);return}n.litellm_params.rules=Y.rules,n.litellm_params.default_action=Y.default_action,n.litellm_params.on_disallowed_action=Y.on_disallowed_action,Y.violation_message_template&&(n.litellm_params.violation_message_template=Y.violation_message_template)}if(console.log("values: ",JSON.stringify(l)),T&&c){var e;let a=null===(e=C[c])||void 0===e?void 0:e.toLowerCase();console.log("providerKey: ",a);let t=T[a]||{},i=new Set;console.log("providerSpecificParams: ",JSON.stringify(t)),Object.keys(t).forEach(e=>{"optional_params"!==e&&i.add(e)}),t.optional_params&&t.optional_params.fields&&Object.keys(t.optional_params.fields).forEach(e=>{i.add(e)}),console.log("allowedParams: ",i),i.forEach(e=>{let a=l[e];if(null==a||""===a){var t;a=null===(t=l.optional_params)||void 0===t?void 0:t[e]}null!=a&&""!==a&&(n.litellm_params[e]=a)})}if(!t)throw Error("No access token available");console.log("Sending guardrail data:",JSON.stringify(n)),await (0,h.createGuardrailCall)(t,n),et.Z.success("Guardrail created successfully"),es(),i(),a()}catch(e){console.error("Failed to create guardrail:",e),et.Z.fromBackend("Failed to create guardrail: "+(e instanceof Error?e.message:String(e)))}finally{d(!1)}},ed=()=>{var e;return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(v.Z.Item,{name:"guardrail_name",label:"Guardrail Name",rules:[{required:!0,message:"Please enter a guardrail name"}],children:(0,n.jsx)(b.o,{placeholder:"Enter a name for this guardrail"})}),(0,n.jsx)(v.Z.Item,{name:"provider",label:"Guardrail Provider",rules:[{required:!0,message:"Please select a provider"}],children:(0,n.jsx)(f.default,{placeholder:"Select a guardrail provider",onChange:Q,labelInValue:!1,optionLabelProp:"label",dropdownRender:e=>e,showSearch:!0,children:Object.entries(k()).map(e=>{let[l,a]=e;return(0,n.jsx)(eH,{value:l,label:(0,n.jsxs)("div",{style:{display:"flex",alignItems:"center"},children:[O[a]&&(0,n.jsx)("img",{src:O[a],alt:"",style:{height:"20px",width:"20px",marginRight:"8px",objectFit:"contain"},onError:e=>{e.currentTarget.style.display="none"}}),(0,n.jsx)("span",{children:a})]}),children:(0,n.jsxs)("div",{style:{display:"flex",alignItems:"center"},children:[O[a]&&(0,n.jsx)("img",{src:O[a],alt:"",style:{height:"20px",width:"20px",marginRight:"8px",objectFit:"contain"},onError:e=>{e.currentTarget.style.display="none"}}),(0,n.jsx)("span",{children:a})]})},l)})})}),(0,n.jsx)(v.Z.Item,{name:"mode",label:"Mode",tooltip:"How the guardrail should be applied",rules:[{required:!0,message:"Please select a mode"}],children:(0,n.jsx)(f.default,{optionLabelProp:"label",mode:"multiple",children:(null==m?void 0:null===(e=m.supported_modes)||void 0===e?void 0:e.map(e=>(0,n.jsx)(eH,{value:e,label:e,children:(0,n.jsxs)("div",{children:[(0,n.jsxs)("div",{children:[(0,n.jsx)("strong",{children:e}),"pre_call"===e&&(0,n.jsx)(y.Z,{color:"green",style:{marginLeft:"8px"},children:"Recommended"})]}),(0,n.jsx)("div",{style:{fontSize:"12px",color:"#888"},children:eQ[e]})]})},e)))||(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(eH,{value:"pre_call",label:"pre_call",children:(0,n.jsxs)("div",{children:[(0,n.jsxs)("div",{children:[(0,n.jsx)("strong",{children:"pre_call"})," ",(0,n.jsx)(y.Z,{color:"green",children:"Recommended"})]}),(0,n.jsx)("div",{style:{fontSize:"12px",color:"#888"},children:eQ.pre_call})]})}),(0,n.jsx)(eH,{value:"during_call",label:"during_call",children:(0,n.jsxs)("div",{children:[(0,n.jsx)("div",{children:(0,n.jsx)("strong",{children:"during_call"})}),(0,n.jsx)("div",{style:{fontSize:"12px",color:"#888"},children:eQ.during_call})]})}),(0,n.jsx)(eH,{value:"post_call",label:"post_call",children:(0,n.jsxs)("div",{children:[(0,n.jsx)("div",{children:(0,n.jsx)("strong",{children:"post_call"})}),(0,n.jsx)("div",{style:{fontSize:"12px",color:"#888"},children:eQ.post_call})]})}),(0,n.jsx)(eH,{value:"logging_only",label:"logging_only",children:(0,n.jsxs)("div",{children:[(0,n.jsx)("div",{children:(0,n.jsx)("strong",{children:"logging_only"})}),(0,n.jsx)("div",{style:{fontSize:"12px",color:"#888"},children:eQ.logging_only})]})})]})})}),(0,n.jsx)(v.Z.Item,{name:"default_on",label:"Always On",tooltip:"If enabled, this guardrail will be applied to all requests by default.",children:(0,n.jsxs)(f.default,{children:[(0,n.jsx)(f.default.Option,{value:!0,children:"Yes"}),(0,n.jsx)(f.default.Option,{value:!1,children:"No"})]})}),!$&&!P(c)&&(0,n.jsx)(X,{selectedProvider:c,accessToken:t,providerParams:T})]})},ec=()=>m&&"PresidioPII"===c?(0,n.jsx)(q,{entities:m.supported_entities,actions:m.supported_actions,selectedEntities:p,selectedActions:N,onEntitySelect:ee,onActionSelect:el,entityCategories:m.pii_entity_categories}):null,eu=e=>{if(!m||!P(c))return null;let l=m.content_filter_settings;return l?(0,n.jsx)(eM,{prebuiltPatterns:l.prebuilt_patterns||[],categories:l.pattern_categories||[],selectedPatterns:D,blockedWords:J,onPatternAdd:e=>R([...D,e]),onPatternRemove:e=>R(D.filter(l=>l.id!==e)),onPatternActionChange:(e,l)=>{R(D.map(a=>a.id===e?{...a,action:l}:a))},onBlockedWordAdd:e=>V([...J,e]),onBlockedWordRemove:e=>V(J.filter(l=>l.id!==e)),onBlockedWordUpdate:(e,l,a)=>{V(J.map(t=>t.id===e?{...t,[l]:a}:t))},contentCategories:l.content_categories||[],selectedContentCategories:U,onContentCategoryAdd:e=>W([...U,e]),onContentCategoryRemove:e=>W(U.filter(l=>l.id!==e)),onContentCategoryUpdate:(e,l,a)=>{W(U.map(t=>t.id===e?{...t,[l]:a}:t))},accessToken:t,showStep:e}):null},em=()=>{var e;if(!c)return null;if($)return(0,n.jsx)(eU,{value:Y,onChange:H});if(!T)return null;console.log("guardrail_provider_map: ",C),console.log("selectedProvider: ",c);let l=null===(e=C[c])||void 0===e?void 0:e.toLowerCase(),a=T&&T[l];return a&&a.optional_params?(0,n.jsx)(ea,{optionalParams:a.optional_params,parentFieldKey:"optional_params"}):null};return(0,n.jsx)(_.Z,{title:"Add Guardrail",open:l,onCancel:en,footer:null,width:800,children:(0,n.jsxs)(v.Z,{form:r,layout:"vertical",initialValues:{mode:"pre_call",default_on:!1},children:[(0,n.jsxs)(j.default,{current:I,className:"mb-6",style:{overflow:"visible"},children:[(0,n.jsx)(e$,{title:"Basic Info"}),(0,n.jsx)(e$,{title:Z(c)?"PII Configuration":P(c)?"Default Categories":"Provider Configuration"}),P(c)&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e$,{title:"Patterns"}),(0,n.jsx)(e$,{title:"Keywords"})]})]}),(()=>{switch(I){case 0:return ed();case 1:if(Z(c))return ec();if(P(c))return eu("categories");return em();case 2:if(P(c))return eu("patterns");return null;case 3:if(P(c))return eu("keywords");return null;default:return null}})(),(()=>{let e=I===(P(c)?4:2)-1;return(0,n.jsxs)("div",{className:"flex justify-end space-x-2 mt-4",children:[I>0&&(0,n.jsx)(b.z,{variant:"secondary",onClick:er,children:"Previous"}),!e&&(0,n.jsx)(b.z,{onClick:ei,children:"Next"}),e&&(0,n.jsx)(b.z,{onClick:eo,loading:s,children:"Create Guardrail"}),(0,n.jsx)(b.z,{variant:"secondary",onClick:en,children:"Cancel"})]})})()]})})},e0=a(47323),e1=a(21626),e4=a(97214),e2=a(28241),e8=a(58834),e5=a(69552),e6=a(71876),e3=a(74998),e9=a(44633),e7=a(86462),le=a(49084),ll=a(1309),la=a(71594),lt=a(24525),li=a(63709);let{Title:lr,Text:ls}=g.default,{Option:ln}=f.default;var lo=e=>{var l;let{visible:a,onClose:t,accessToken:i,onSuccess:r,guardrailId:s,initialValues:d}=e,[c]=v.Z.useForm(),[u,m]=(0,o.useState)(!1),[x,p]=(0,o.useState)((null==d?void 0:d.provider)||null),[g,j]=(0,o.useState)(null),[y,N]=(0,o.useState)([]),[w,S]=(0,o.useState)({});(0,o.useEffect)(()=>{(async()=>{try{if(!i)return;let e=await (0,h.getGuardrailUISettings)(i);j(e)}catch(e){console.error("Error fetching guardrail settings:",e),et.Z.fromBackend("Failed to load guardrail settings")}})()},[i]),(0,o.useEffect)(()=>{(null==d?void 0:d.pii_entities_config)&&Object.keys(d.pii_entities_config).length>0&&(N(Object.keys(d.pii_entities_config)),S(d.pii_entities_config))},[d]);let Z=e=>{N(l=>l.includes(e)?l.filter(l=>l!==e):[...l,e])},P=(e,l)=>{S(a=>({...a,[e]:l}))},A=async()=>{try{m(!0);let e=await c.validateFields(),l=C[e.provider],a={guardrail_id:s,guardrail:{guardrail_name:e.guardrail_name,litellm_params:{guardrail:l,mode:e.mode,default_on:e.default_on},guardrail_info:{}}};if("PresidioPII"===e.provider&&y.length>0){let e={};y.forEach(l=>{e[l]=w[l]||"MASK"}),a.guardrail.litellm_params.pii_entities_config=e}else if(e.config)try{let l=JSON.parse(e.config);"Bedrock"===e.provider&&l?(l.guardrail_id&&(a.guardrail.litellm_params.guardrailIdentifier=l.guardrail_id),l.guardrail_version&&(a.guardrail.litellm_params.guardrailVersion=l.guardrail_version)):a.guardrail.guardrail_info=l}catch(e){et.Z.fromBackend("Invalid JSON in configuration"),m(!1);return}if(!i)throw Error("No access token available");console.log("Sending guardrail update data:",JSON.stringify(a));let n=await fetch("/guardrails/".concat(s),{method:"PUT",headers:{Authorization:"Bearer ".concat(i),"Content-Type":"application/json"},body:JSON.stringify(a)});if(!n.ok){let e=await n.text();throw Error(e||"Failed to update guardrail")}et.Z.success("Guardrail updated successfully"),r(),t()}catch(e){console.error("Failed to update guardrail:",e),et.Z.fromBackend("Failed to update guardrail: "+(e instanceof Error?e.message:String(e)))}finally{m(!1)}},I=()=>g&&x&&"PresidioPII"===x?(0,n.jsx)(q,{entities:g.supported_entities,actions:g.supported_actions,selectedEntities:y,selectedActions:w,onEntitySelect:Z,onActionSelect:P,entityCategories:g.pii_entity_categories}):null;return(0,n.jsx)(_.Z,{title:"Edit Guardrail",open:a,onCancel:t,footer:null,width:700,children:(0,n.jsxs)(v.Z,{form:c,layout:"vertical",initialValues:d,children:[(0,n.jsx)(v.Z.Item,{name:"guardrail_name",label:"Guardrail Name",rules:[{required:!0,message:"Please enter a guardrail name"}],children:(0,n.jsx)(b.o,{placeholder:"Enter a name for this guardrail"})}),(0,n.jsx)(v.Z.Item,{name:"provider",label:"Guardrail Provider",rules:[{required:!0,message:"Please select a provider"}],children:(0,n.jsx)(f.default,{placeholder:"Select a guardrail provider",onChange:e=>{p(e),c.setFieldsValue({config:void 0}),N([]),S({})},disabled:!0,optionLabelProp:"label",children:Object.entries(k()).map(e=>{let[l,a]=e;return(0,n.jsx)(ln,{value:l,label:a,children:(0,n.jsxs)("div",{style:{display:"flex",alignItems:"center"},children:[O[a]&&(0,n.jsx)("img",{src:O[a],alt:"",style:{height:"20px",width:"20px",marginRight:"8px",objectFit:"contain"},onError:e=>{e.currentTarget.style.display="none"}}),(0,n.jsx)("span",{children:a})]})},l)})})}),(0,n.jsx)(v.Z.Item,{name:"mode",label:"Mode",tooltip:"How the guardrail should be applied",rules:[{required:!0,message:"Please select a mode"}],children:(0,n.jsx)(f.default,{children:(null==g?void 0:null===(l=g.supported_modes)||void 0===l?void 0:l.map(e=>(0,n.jsx)(ln,{value:e,children:e},e)))||(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(ln,{value:"pre_call",children:"pre_call"}),(0,n.jsx)(ln,{value:"post_call",children:"post_call"})]})})}),(0,n.jsx)(v.Z.Item,{name:"default_on",label:"Always On",tooltip:"If enabled, this guardrail will be applied to all requests by default",valuePropName:"checked",children:(0,n.jsx)(li.Z,{})}),(()=>{if(!x)return null;if("PresidioPII"===x)return I();switch(x){case"Aporia":return(0,n.jsx)(v.Z.Item,{label:"Aporia Configuration",name:"config",tooltip:"JSON configuration for Aporia",children:(0,n.jsx)(eG.default.TextArea,{rows:4,placeholder:'{\n "api_key": "your_aporia_api_key",\n "project_name": "your_project_name"\n}'})});case"AimSecurity":return(0,n.jsx)(v.Z.Item,{label:"Aim Security Configuration",name:"config",tooltip:"JSON configuration for Aim Security",children:(0,n.jsx)(eG.default.TextArea,{rows:4,placeholder:'{\n "api_key": "your_aim_api_key"\n}'})});case"Bedrock":return(0,n.jsx)(v.Z.Item,{label:"Amazon Bedrock Configuration",name:"config",tooltip:"JSON configuration for Amazon Bedrock guardrails",children:(0,n.jsx)(eG.default.TextArea,{rows:4,placeholder:'{\n "guardrail_id": "your_guardrail_id",\n "guardrail_version": "your_guardrail_version"\n}'})});case"GuardrailsAI":return(0,n.jsx)(v.Z.Item,{label:"Guardrails.ai Configuration",name:"config",tooltip:"JSON configuration for Guardrails.ai",children:(0,n.jsx)(eG.default.TextArea,{rows:4,placeholder:'{\n "api_key": "your_guardrails_api_key",\n "guardrail_id": "your_guardrail_id"\n}'})});case"LakeraAI":return(0,n.jsx)(v.Z.Item,{label:"Lakera AI Configuration",name:"config",tooltip:"JSON configuration for Lakera AI",children:(0,n.jsx)(eG.default.TextArea,{rows:4,placeholder:'{\n "api_key": "your_lakera_api_key"\n}'})});case"PromptInjection":return(0,n.jsx)(v.Z.Item,{label:"Prompt Injection Configuration",name:"config",tooltip:"JSON configuration for prompt injection detection",children:(0,n.jsx)(eG.default.TextArea,{rows:4,placeholder:'{\n "threshold": 0.8\n}'})});default:return(0,n.jsx)(v.Z.Item,{label:"Custom Configuration",name:"config",tooltip:"JSON configuration for your custom guardrail",children:(0,n.jsx)(eG.default.TextArea,{rows:4,placeholder:'{\n "key1": "value1",\n "key2": "value2"\n}'})})}})(),(0,n.jsxs)("div",{className:"flex justify-end space-x-2 mt-4",children:[(0,n.jsx)(b.z,{variant:"secondary",onClick:t,children:"Cancel"}),(0,n.jsx)(b.z,{onClick:A,loading:u,children:"Update Guardrail"})]})]})})};(i=s||(s={})).DB="db",i.CONFIG="config";var ld=e=>{let{guardrailsList:l,isLoading:a,onDeleteClick:t,accessToken:i,onGuardrailUpdated:r,isAdmin:c=!1,onGuardrailClick:u}=e,[m,x]=(0,o.useState)([{id:"created_at",desc:!0}]),[p,h]=(0,o.useState)(!1),[g,f]=(0,o.useState)(null),j=e=>e?new Date(e).toLocaleString():"-",v=[{header:"Guardrail ID",accessorKey:"guardrail_id",cell:e=>(0,n.jsx)(L.Z,{title:String(e.getValue()||""),children:(0,n.jsx)(d.Z,{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()&&u(e.getValue()),children:e.getValue()?"".concat(String(e.getValue()).slice(0,7),"..."):""})})},{header:"Name",accessorKey:"guardrail_name",cell:e=>{let{row:l}=e,a=l.original;return(0,n.jsx)(L.Z,{title:a.guardrail_name,children:(0,n.jsx)("span",{className:"text-xs font-medium",children:a.guardrail_name||"-"})})}},{header:"Provider",accessorKey:"litellm_params.guardrail",cell:e=>{let{row:l}=e,{logo:a,displayName:t}=I(l.original.litellm_params.guardrail);return(0,n.jsxs)("div",{className:"flex items-center space-x-2",children:[a&&(0,n.jsx)("img",{src:a,alt:"".concat(t," logo"),className:"w-4 h-4",onError:e=>{e.target.style.display="none"}}),(0,n.jsx)("span",{className:"text-xs",children:t})]})}},{header:"Mode",accessorKey:"litellm_params.mode",cell:e=>{let{row:l}=e,a=l.original;return(0,n.jsx)("span",{className:"text-xs",children:a.litellm_params.mode})}},{header:"Default On",accessorKey:"litellm_params.default_on",cell:e=>{var l,a;let{row:t}=e,i=t.original;return(0,n.jsx)(ll.C,{color:(null===(l=i.litellm_params)||void 0===l?void 0:l.default_on)?"green":"gray",className:"text-xs font-normal",size:"xs",children:(null===(a=i.litellm_params)||void 0===a?void 0:a.default_on)?"Default On":"Default Off"})}},{header:"Created At",accessorKey:"created_at",cell:e=>{let{row:l}=e,a=l.original;return(0,n.jsx)(L.Z,{title:a.created_at,children:(0,n.jsx)("span",{className:"text-xs",children:j(a.created_at)})})}},{header:"Updated At",accessorKey:"updated_at",cell:e=>{let{row:l}=e,a=l.original;return(0,n.jsx)(L.Z,{title:a.updated_at,children:(0,n.jsx)("span",{className:"text-xs",children:j(a.updated_at)})})}},{id:"actions",header:"Actions",cell:e=>{let{row:l}=e,a=l.original,i=a.guardrail_definition_location===s.CONFIG;return(0,n.jsx)("div",{className:"flex space-x-2",children:i?(0,n.jsx)(L.Z,{title:"Config guardrail cannot be deleted on the dashboard. Please delete it from the config file.",children:(0,n.jsx)(e0.Z,{"data-testid":"config-delete-icon",icon:e3.Z,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,n.jsx)(L.Z,{title:"Delete guardrail",children:(0,n.jsx)(e0.Z,{icon:e3.Z,size:"sm",onClick:()=>a.guardrail_id&&t(a.guardrail_id,a.guardrail_name||"Unnamed Guardrail"),className:"cursor-pointer hover:text-red-500"})})})}}],y=(0,la.b7)({data:l,columns:v,state:{sorting:m},onSortingChange:x,getCoreRowModel:(0,lt.sC)(),getSortedRowModel:(0,lt.tj)(),enableSorting:!0});return(0,n.jsxs)("div",{className:"rounded-lg custom-border relative",children:[(0,n.jsx)("div",{className:"overflow-x-auto",children:(0,n.jsxs)(e1.Z,{className:"[&_td]:py-0.5 [&_th]:py-1",children:[(0,n.jsx)(e8.Z,{children:y.getHeaderGroups().map(e=>(0,n.jsx)(e6.Z,{children:e.headers.map(e=>(0,n.jsx)(e5.Z,{className:"py-1 h-8 ".concat("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,n.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,n.jsx)("div",{className:"flex items-center",children:e.isPlaceholder?null:(0,la.ie)(e.column.columnDef.header,e.getContext())}),"actions"!==e.id&&(0,n.jsx)("div",{className:"w-4",children:e.column.getIsSorted()?({asc:(0,n.jsx)(e9.Z,{className:"h-4 w-4 text-blue-500"}),desc:(0,n.jsx)(e7.Z,{className:"h-4 w-4 text-blue-500"})})[e.column.getIsSorted()]:(0,n.jsx)(le.Z,{className:"h-4 w-4 text-gray-400"})})]})},e.id))},e.id))}),(0,n.jsx)(e4.Z,{children:a?(0,n.jsx)(e6.Z,{children:(0,n.jsx)(e2.Z,{colSpan:v.length,className:"h-8 text-center",children:(0,n.jsx)("div",{className:"text-center text-gray-500",children:(0,n.jsx)("p",{children:"Loading..."})})})}):l.length>0?y.getRowModel().rows.map(e=>(0,n.jsx)(e6.Z,{className:"h-8",children:e.getVisibleCells().map(e=>(0,n.jsx)(e2.Z,{className:"py-0.5 max-h-8 overflow-hidden text-ellipsis whitespace-nowrap ".concat("actions"===e.column.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)]":""),children:(0,la.ie)(e.column.columnDef.cell,e.getContext())},e.id))},e.id)):(0,n.jsx)(e6.Z,{children:(0,n.jsx)(e2.Z,{colSpan:v.length,className:"h-8 text-center",children:(0,n.jsx)("div",{className:"text-center text-gray-500",children:(0,n.jsx)("p",{children:"No guardrails found"})})})})})]})}),g&&(0,n.jsx)(lo,{visible:p,onClose:()=>h(!1),accessToken:i,onSuccess:()=>{h(!1),f(null),r()},guardrailId:g.guardrail_id||"",initialValues:{guardrail_name:g.guardrail_name||"",provider:Object.keys(C).find(e=>C[e]===(null==g?void 0:g.litellm_params.guardrail))||"",mode:g.litellm_params.mode,default_on:g.litellm_params.default_on,pii_entities_config:g.litellm_params.pii_entities_config,...g.guardrail_info}})]})},lc=a(20347),lu=a(30078),lm=a(41649),lx=a(12514),lp=a(84264),lh=e=>{let{patterns:l,blockedWords:a,readOnly:t=!0,onPatternActionChange:i,onPatternRemove:r,onBlockedWordUpdate:s,onBlockedWordRemove:o}=e;if(0===l.length&&0===a.length)return null;let d=()=>{};return(0,n.jsxs)(n.Fragment,{children:[l.length>0&&(0,n.jsxs)(lx.Z,{className:"mt-6",children:[(0,n.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,n.jsx)(lp.Z,{className:"text-lg font-semibold",children:"Pattern Detection"}),(0,n.jsxs)(lm.Z,{color:"blue",children:[l.length," patterns configured"]})]}),(0,n.jsx)(ek,{patterns:l,onActionChange:t?d:i||d,onRemove:t?d:r||d})]}),a.length>0&&(0,n.jsxs)(lx.Z,{className:"mt-6",children:[(0,n.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,n.jsx)(lp.Z,{className:"text-lg font-semibold",children:"Blocked Keywords"}),(0,n.jsxs)(lm.Z,{color:"blue",children:[a.length," keywords configured"]})]}),(0,n.jsx)(eZ,{keywords:a,onActionChange:t?d:s||d,onRemove:t?d:o||d})]})]})},lg=e=>{var l;let{guardrailData:a,guardrailSettings:t,isEditing:i,accessToken:r,onDataChange:s,onUnsavedChanges:d}=e,[c,u]=(0,o.useState)([]),[m,x]=(0,o.useState)([]),[p,h]=(0,o.useState)([]),[g,f]=(0,o.useState)([]);(0,o.useEffect)(()=>{var e,l;if(null==a?void 0:null===(e=a.litellm_params)||void 0===e?void 0:e.patterns){let e=a.litellm_params.patterns.map((e,l)=>({id:"pattern-".concat(l),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"}));u(e),h(e)}else u([]),h([]);if(null==a?void 0:null===(l=a.litellm_params)||void 0===l?void 0:l.blocked_words){let e=a.litellm_params.blocked_words.map((e,l)=>({id:"word-".concat(l),keyword:e.keyword,action:e.action||"BLOCK",description:e.description}));x(e),f(e)}else x([]),f([])},[a]),(0,o.useEffect)(()=>{s&&s(c,m)},[c,m,s]);let j=o.useMemo(()=>{let e=JSON.stringify(c)!==JSON.stringify(p),l=JSON.stringify(m)!==JSON.stringify(g);return e||l},[c,m,p,g]);return((0,o.useEffect)(()=>{i&&d&&d(j)},[j,i,d]),(null==a?void 0:null===(l=a.litellm_params)||void 0===l?void 0:l.guardrail)!=="litellm_content_filter")?null:i?(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(eK.Z,{orientation:"left",children:"Content Filter Configuration"}),j&&(0,n.jsx)("div",{className:"mb-4 px-4 py-3 bg-yellow-50 border border-yellow-200 rounded-md",children:(0,n.jsx)("p",{className:"text-sm text-yellow-800 font-medium",children:'⚠️ You have unsaved changes to patterns or keywords. Remember to click "Save Changes" at the bottom.'})}),(0,n.jsx)("div",{className:"mb-6",children:t&&t.content_filter_settings&&(0,n.jsx)(eM,{prebuiltPatterns:t.content_filter_settings.prebuilt_patterns||[],categories:t.content_filter_settings.pattern_categories||[],selectedPatterns:c,blockedWords:m,onPatternAdd:e=>u([...c,e]),onPatternRemove:e=>u(c.filter(l=>l.id!==e)),onPatternActionChange:(e,l)=>u(c.map(a=>a.id===e?{...a,action:l}:a)),onBlockedWordAdd:e=>x([...m,e]),onBlockedWordRemove:e=>x(m.filter(l=>l.id!==e)),onBlockedWordUpdate:(e,l,a)=>x(m.map(t=>t.id===e?{...t,[l]:a}:t)),onFileUpload:e=>{console.log("File uploaded:",e)},accessToken:r})})]}):(0,n.jsx)(lh,{patterns:c,blockedWords:m,readOnly:!0})};let lf=(e,l)=>({patterns:e.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:l.map(e=>({keyword:e.keyword,action:e.action,description:e.description}))});var lj=a(10900),lv=a(59872),ly=a(30401),l_=a(78867),lb=e=>{var l,a,t,i,r,s,d,c,u,m,x,p,g,j,y,_;let{guardrailId:b,onClose:N,accessToken:w,isAdmin:k}=e,[S,Z]=(0,o.useState)(null),[P,A]=(0,o.useState)(null),[O,z]=(0,o.useState)(!0),[M,F]=(0,o.useState)(!1),[G]=v.Z.useForm(),[K,D]=(0,o.useState)([]),[R,J]=(0,o.useState)({}),[V,U]=(0,o.useState)(null),[W,Y]=(0,o.useState)({}),[H,$]=(0,o.useState)(!1),Q={rules:[],default_action:"deny",on_disallowed_action:"block",violation_message_template:""},[ee,el]=(0,o.useState)(Q),[ei,er]=(0,o.useState)(!1),es=o.useRef({patterns:[],blockedWords:[]}),en=(0,o.useCallback)((e,l)=>{es.current={patterns:e,blockedWords:l}},[]),eo=async()=>{try{var e;if(z(!0),!w)return;let l=await (0,h.getGuardrailInfo)(w,b);if(Z(l),null===(e=l.litellm_params)||void 0===e?void 0:e.pii_entities_config){let e=l.litellm_params.pii_entities_config;if(D([]),J({}),Object.keys(e).length>0){let l=[],a={};Object.entries(e).forEach(e=>{let[t,i]=e;l.push(t),a[t]="string"==typeof i?i:"MASK"}),D(l),J(a)}}else D([]),J({})}catch(e){et.Z.fromBackend("Failed to load guardrail information"),console.error("Error fetching guardrail info:",e)}finally{z(!1)}},ed=async()=>{try{if(!w)return;let e=await (0,h.getGuardrailProviderSpecificParams)(w);A(e)}catch(e){console.error("Error fetching guardrail provider specific params:",e)}},ec=async()=>{try{if(!w)return;let e=await (0,h.getGuardrailUISettings)(w);U(e)}catch(e){console.error("Error fetching guardrail UI settings:",e)}};(0,o.useEffect)(()=>{ed()},[w]),(0,o.useEffect)(()=>{eo(),ec()},[b,w]),(0,o.useEffect)(()=>{if(S&&G){var e;G.setFieldsValue({guardrail_name:S.guardrail_name,...S.litellm_params,guardrail_info:S.guardrail_info?JSON.stringify(S.guardrail_info,null,2):"",...(null===(e=S.litellm_params)||void 0===e?void 0:e.optional_params)&&{optional_params:S.litellm_params.optional_params}})}},[S,P,G]);let eu=(0,o.useCallback)(()=>{var e,l,a,t,i;(null==S?void 0:null===(e=S.litellm_params)||void 0===e?void 0:e.guardrail)==="tool_permission"?el({rules:(null===(l=S.litellm_params)||void 0===l?void 0:l.rules)||[],default_action:((null===(a=S.litellm_params)||void 0===a?void 0:a.default_action)||"deny").toLowerCase(),on_disallowed_action:((null===(t=S.litellm_params)||void 0===t?void 0:t.on_disallowed_action)||"block").toLowerCase(),violation_message_template:(null===(i=S.litellm_params)||void 0===i?void 0:i.violation_message_template)||""}):el(Q),er(!1)},[S]);(0,o.useEffect)(()=>{eu()},[eu]);let em=async e=>{try{var l,a,t,i,r,s,n,o,d,c,u,m;if(!w)return;let x={litellm_params:{}};e.guardrail_name!==S.guardrail_name&&(x.guardrail_name=e.guardrail_name),e.default_on!==(null===(l=S.litellm_params)||void 0===l?void 0:l.default_on)&&(x.litellm_params.default_on=e.default_on);let p=S.guardrail_info,g=e.guardrail_info?JSON.parse(e.guardrail_info):void 0;JSON.stringify(p)!==JSON.stringify(g)&&(x.guardrail_info=g);let f=(null===(a=S.litellm_params)||void 0===a?void 0:a.pii_entities_config)||{},j={};if(K.forEach(e=>{j[e]=R[e]||"MASK"}),JSON.stringify(f)!==JSON.stringify(j)&&(x.litellm_params.pii_entities_config=j),(null===(t=S.litellm_params)||void 0===t?void 0:t.guardrail)==="litellm_content_filter"){let e=(null===(s=S.litellm_params)||void 0===s?void 0:s.patterns)||[],l=(null===(n=S.litellm_params)||void 0===n?void 0:n.blocked_words)||[],a=lf(es.current.patterns,es.current.blockedWords);JSON.stringify(e)!==JSON.stringify(a.patterns)&&(x.litellm_params.patterns=a.patterns),JSON.stringify(l)!==JSON.stringify(a.blocked_words)&&(x.litellm_params.blocked_words=a.blocked_words)}if((null===(i=S.litellm_params)||void 0===i?void 0:i.guardrail)==="tool_permission"){let e=(null===(o=S.litellm_params)||void 0===o?void 0:o.rules)||[],l=ee.rules||[],a=JSON.stringify(e)!==JSON.stringify(l),t=((null===(d=S.litellm_params)||void 0===d?void 0:d.default_action)||"deny").toLowerCase(),i=(ee.default_action||"deny").toLowerCase(),r=t!==i,s=((null===(c=S.litellm_params)||void 0===c?void 0:c.on_disallowed_action)||"block").toLowerCase(),n=(ee.on_disallowed_action||"block").toLowerCase(),m=s!==n,p=(null===(u=S.litellm_params)||void 0===u?void 0:u.violation_message_template)||"",h=ee.violation_message_template||"",g=p!==h;(ei||a||r||m||g)&&(x.litellm_params.rules=l,x.litellm_params.default_action=i,x.litellm_params.on_disallowed_action=n,x.litellm_params.violation_message_template=h||null)}let v=Object.keys(C).find(e=>{var l;return C[e]===(null===(l=S.litellm_params)||void 0===l?void 0:l.guardrail)});console.log("values: ",JSON.stringify(e)),console.log("currentProvider: ",v);let y=(null===(r=S.litellm_params)||void 0===r?void 0:r.guardrail)==="tool_permission";if(P&&v&&!y){let l=P[null===(m=C[v])||void 0===m?void 0:m.toLowerCase()]||{},a=new Set;console.log("providerSpecificParams: ",JSON.stringify(l)),Object.keys(l).forEach(e=>{"optional_params"!==e&&a.add(e)}),l.optional_params&&l.optional_params.fields&&Object.keys(l.optional_params.fields).forEach(e=>{a.add(e)}),console.log("allowedParams: ",a),a.forEach(l=>{var a,t;let i=e[l];(null==i||""===i)&&(i=null===(t=e.optional_params)||void 0===t?void 0:t[l]);let r=null===(a=S.litellm_params)||void 0===a?void 0:a[l];JSON.stringify(i)!==JSON.stringify(r)&&(null!=i&&""!==i?x.litellm_params[l]=i:null!=r&&""!==r&&(x.litellm_params[l]=null))})}if(0===Object.keys(x.litellm_params).length&&delete x.litellm_params,0===Object.keys(x).length){et.Z.info("No changes detected"),F(!1);return}await (0,h.updateGuardrailCall)(w,b,x),et.Z.success("Guardrail updated successfully"),$(!1),eo(),F(!1)}catch(e){console.error("Error updating guardrail:",e),et.Z.fromBackend("Failed to update guardrail")}};if(O)return(0,n.jsx)("div",{className:"p-4",children:"Loading..."});if(!S)return(0,n.jsx)("div",{className:"p-4",children:"Guardrail not found"});let ex=e=>e?new Date(e).toLocaleString():"-",{logo:ep,displayName:eh}=I((null===(l=S.litellm_params)||void 0===l?void 0:l.guardrail)||""),eg=async(e,l)=>{await (0,lv.vQ)(e)&&(Y(e=>({...e,[l]:!0})),setTimeout(()=>{Y(e=>({...e,[l]:!1}))},2e3))},ef="config"===S.guardrail_definition_location;return(0,n.jsxs)("div",{className:"p-4",children:[(0,n.jsxs)("div",{children:[(0,n.jsx)(lu.zx,{icon:lj.Z,variant:"light",onClick:N,className:"mb-4",children:"Back to Guardrails"}),(0,n.jsx)(lu.Dx,{children:S.guardrail_name||"Unnamed Guardrail"}),(0,n.jsxs)("div",{className:"flex items-center cursor-pointer",children:[(0,n.jsx)(lu.xv,{className:"text-gray-500 font-mono",children:S.guardrail_id}),(0,n.jsx)(T.ZP,{type:"text",size:"small",icon:W["guardrail-id"]?(0,n.jsx)(ly.Z,{size:12}):(0,n.jsx)(l_.Z,{size:12}),onClick:()=>eg(S.guardrail_id,"guardrail-id"),className:"left-2 z-10 transition-all duration-200 ".concat(W["guardrail-id"]?"text-green-600 bg-green-50 border-green-200":"text-gray-500 hover:text-gray-700 hover:bg-gray-100")})]})]}),(0,n.jsxs)(lu.v0,{children:[(0,n.jsxs)(lu.td,{className:"mb-4",children:[(0,n.jsx)(lu.OK,{children:"Overview"},"overview"),k?(0,n.jsx)(lu.OK,{children:"Settings"},"settings"):(0,n.jsx)(n.Fragment,{})]}),(0,n.jsxs)(lu.nP,{children:[(0,n.jsxs)(lu.x4,{children:[(0,n.jsxs)(lu.rj,{numItems:1,numItemsSm:2,numItemsLg:3,className:"gap-6",children:[(0,n.jsxs)(lu.Zb,{children:[(0,n.jsx)(lu.xv,{children:"Provider"}),(0,n.jsxs)("div",{className:"mt-2 flex items-center space-x-2",children:[ep&&(0,n.jsx)("img",{src:ep,alt:"".concat(eh," logo"),className:"w-6 h-6",onError:e=>{e.target.style.display="none"}}),(0,n.jsx)(lu.Dx,{children:eh})]})]}),(0,n.jsxs)(lu.Zb,{children:[(0,n.jsx)(lu.xv,{children:"Mode"}),(0,n.jsxs)("div",{className:"mt-2",children:[(0,n.jsx)(lu.Dx,{children:(null===(a=S.litellm_params)||void 0===a?void 0:a.mode)||"-"}),(0,n.jsx)(lu.Ct,{color:(null===(t=S.litellm_params)||void 0===t?void 0:t.default_on)?"green":"gray",children:(null===(i=S.litellm_params)||void 0===i?void 0:i.default_on)?"Default On":"Default Off"})]})]}),(0,n.jsxs)(lu.Zb,{children:[(0,n.jsx)(lu.xv,{children:"Created At"}),(0,n.jsxs)("div",{className:"mt-2",children:[(0,n.jsx)(lu.Dx,{children:ex(S.created_at)}),(0,n.jsxs)(lu.xv,{children:["Last Updated: ",ex(S.updated_at)]})]})]})]}),(null===(r=S.litellm_params)||void 0===r?void 0:r.pii_entities_config)&&Object.keys(S.litellm_params.pii_entities_config).length>0&&(0,n.jsx)(lu.Zb,{className:"mt-6",children:(0,n.jsxs)("div",{className:"flex justify-between items-center",children:[(0,n.jsx)(lu.xv,{className:"font-medium",children:"PII Protection"}),(0,n.jsxs)(lu.Ct,{color:"blue",children:[Object.keys(S.litellm_params.pii_entities_config).length," PII entities configured"]})]})}),(null===(s=S.litellm_params)||void 0===s?void 0:s.pii_entities_config)&&Object.keys(S.litellm_params.pii_entities_config).length>0&&(0,n.jsxs)(lu.Zb,{className:"mt-6",children:[(0,n.jsx)(lu.xv,{className:"mb-4 text-lg font-semibold",children:"PII Entity Configuration"}),(0,n.jsxs)("div",{className:"border rounded-lg overflow-hidden shadow-sm",children:[(0,n.jsxs)("div",{className:"bg-gray-50 px-5 py-3 border-b flex",children:[(0,n.jsx)(lu.xv,{className:"flex-1 font-semibold text-gray-700",children:"Entity Type"}),(0,n.jsx)(lu.xv,{className:"flex-1 font-semibold text-gray-700",children:"Configuration"})]}),(0,n.jsx)("div",{className:"max-h-[400px] overflow-y-auto",children:Object.entries(null===(d=S.litellm_params)||void 0===d?void 0:d.pii_entities_config).map(e=>{let[l,a]=e;return(0,n.jsxs)("div",{className:"px-5 py-3 flex border-b hover:bg-gray-50 transition-colors",children:[(0,n.jsx)(lu.xv,{className:"flex-1 font-medium text-gray-900",children:l}),(0,n.jsx)(lu.xv,{className:"flex-1",children:(0,n.jsxs)("span",{className:"inline-flex items-center gap-1.5 ".concat("MASK"===a?"text-blue-600":"text-red-600"),children:["MASK"===a?(0,n.jsx)(E.Z,{}):(0,n.jsx)(B.Z,{}),String(a)]})})]},l)})})]})]}),(null===(c=S.litellm_params)||void 0===c?void 0:c.guardrail)==="tool_permission"&&(0,n.jsx)(lu.Zb,{className:"mt-6",children:(0,n.jsx)(eU,{value:ee,disabled:!0})}),(0,n.jsx)(lg,{guardrailData:S,guardrailSettings:V,isEditing:!1,accessToken:w})]}),k&&(0,n.jsx)(lu.x4,{children:(0,n.jsxs)(lu.Zb,{children:[(0,n.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,n.jsx)(lu.Dx,{children:"Guardrail Settings"}),ef&&(0,n.jsx)(L.Z,{title:"Guardrail is defined in the config file and cannot be edited.",children:(0,n.jsx)(eR.Z,{})}),!M&&!ef&&(0,n.jsx)(lu.zx,{onClick:()=>F(!0),children:"Edit Settings"})]}),M?(0,n.jsxs)(v.Z,{form:G,onFinish:em,initialValues:{guardrail_name:S.guardrail_name,...S.litellm_params,guardrail_info:S.guardrail_info?JSON.stringify(S.guardrail_info,null,2):"",...(null===(u=S.litellm_params)||void 0===u?void 0:u.optional_params)&&{optional_params:S.litellm_params.optional_params}},layout:"vertical",children:[(0,n.jsx)(v.Z.Item,{label:"Guardrail Name",name:"guardrail_name",rules:[{required:!0,message:"Please input a guardrail name"}],children:(0,n.jsx)(lu.oi,{})}),(0,n.jsx)(v.Z.Item,{label:"Default On",name:"default_on",children:(0,n.jsxs)(f.default,{children:[(0,n.jsx)(f.default.Option,{value:!0,children:"Yes"}),(0,n.jsx)(f.default.Option,{value:!1,children:"No"})]})}),(null===(m=S.litellm_params)||void 0===m?void 0:m.guardrail)==="presidio"&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(eK.Z,{orientation:"left",children:"PII Protection"}),(0,n.jsx)("div",{className:"mb-6",children:V&&(0,n.jsx)(q,{entities:V.supported_entities,actions:V.supported_actions,selectedEntities:K,selectedActions:R,onEntitySelect:e=>{D(l=>l.includes(e)?l.filter(l=>l!==e):[...l,e])},onActionSelect:(e,l)=>{J(a=>({...a,[e]:l}))},entityCategories:V.pii_entity_categories})})]}),(0,n.jsx)(lg,{guardrailData:S,guardrailSettings:V,isEditing:!0,accessToken:w,onDataChange:en,onUnsavedChanges:$}),(0,n.jsx)(eK.Z,{orientation:"left",children:"Provider Settings"}),(null===(x=S.litellm_params)||void 0===x?void 0:x.guardrail)==="tool_permission"?(0,n.jsx)(eU,{value:ee,onChange:el}):(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(X,{selectedProvider:Object.keys(C).find(e=>{var l;return C[e]===(null===(l=S.litellm_params)||void 0===l?void 0:l.guardrail)})||null,accessToken:w,providerParams:P,value:S.litellm_params}),P&&(()=>{var e;let l=Object.keys(C).find(e=>{var l;return C[e]===(null===(l=S.litellm_params)||void 0===l?void 0:l.guardrail)});if(!l)return null;let a=P[null===(e=C[l])||void 0===e?void 0:e.toLowerCase()];return a&&a.optional_params?(0,n.jsx)(ea,{optionalParams:a.optional_params,parentFieldKey:"optional_params",values:S.litellm_params}):null})()]}),(0,n.jsx)(eK.Z,{orientation:"left",children:"Advanced Settings"}),(0,n.jsx)(v.Z.Item,{label:"Guardrail Information",name:"guardrail_info",children:(0,n.jsx)(eG.default.TextArea,{rows:5})}),(0,n.jsxs)("div",{className:"flex justify-end gap-2 mt-6",children:[(0,n.jsx)(T.ZP,{onClick:()=>{F(!1),$(!1),eu()},children:"Cancel"}),(0,n.jsx)(lu.zx,{children:"Save Changes"})]})]}):(0,n.jsxs)("div",{className:"space-y-4",children:[(0,n.jsxs)("div",{children:[(0,n.jsx)(lu.xv,{className:"font-medium",children:"Guardrail ID"}),(0,n.jsx)("div",{className:"font-mono",children:S.guardrail_id})]}),(0,n.jsxs)("div",{children:[(0,n.jsx)(lu.xv,{className:"font-medium",children:"Guardrail Name"}),(0,n.jsx)("div",{children:S.guardrail_name||"Unnamed Guardrail"})]}),(0,n.jsxs)("div",{children:[(0,n.jsx)(lu.xv,{className:"font-medium",children:"Provider"}),(0,n.jsx)("div",{children:eh})]}),(0,n.jsxs)("div",{children:[(0,n.jsx)(lu.xv,{className:"font-medium",children:"Mode"}),(0,n.jsx)("div",{children:(null===(p=S.litellm_params)||void 0===p?void 0:p.mode)||"-"})]}),(0,n.jsxs)("div",{children:[(0,n.jsx)(lu.xv,{className:"font-medium",children:"Default On"}),(0,n.jsx)(lu.Ct,{color:(null===(g=S.litellm_params)||void 0===g?void 0:g.default_on)?"green":"gray",children:(null===(j=S.litellm_params)||void 0===j?void 0:j.default_on)?"Yes":"No"})]}),(null===(y=S.litellm_params)||void 0===y?void 0:y.pii_entities_config)&&Object.keys(S.litellm_params.pii_entities_config).length>0&&(0,n.jsxs)("div",{children:[(0,n.jsx)(lu.xv,{className:"font-medium",children:"PII Protection"}),(0,n.jsx)("div",{className:"mt-2",children:(0,n.jsxs)(lu.Ct,{color:"blue",children:[Object.keys(S.litellm_params.pii_entities_config).length," PII entities configured"]})})]}),(0,n.jsxs)("div",{children:[(0,n.jsx)(lu.xv,{className:"font-medium",children:"Created At"}),(0,n.jsx)("div",{children:ex(S.created_at)})]}),(0,n.jsxs)("div",{children:[(0,n.jsx)(lu.xv,{className:"font-medium",children:"Last Updated"}),(0,n.jsx)("div",{children:ex(S.updated_at)})]}),(null===(_=S.litellm_params)||void 0===_?void 0:_.guardrail)==="tool_permission"&&(0,n.jsx)(eU,{value:ee,disabled:!0})]})]})})]})]})]})},lN=a(96761),lw=a(35631),lk=a(29436),lC=a(41169),lS=a(23639),lZ=a(77565),lP=a(70464),lA=a(83669),lO=a(5540);let{Text:lI}=g.default;var lL=function(e){let{results:l,errors:a}=e,[t,i]=(0,o.useState)(new Set),r=e=>{let l=new Set(t);l.has(e)?l.delete(e):l.add(e),i(l)},s=async e=>{try{if(navigator.clipboard&&window.isSecureContext)return await navigator.clipboard.writeText(e),!0;{let l=document.createElement("textarea");l.value=e,l.style.position="fixed",l.style.opacity="0",document.body.appendChild(l),l.focus(),l.select();let a=document.execCommand("copy");if(document.body.removeChild(l),!a)throw Error("execCommand failed");return!0}}catch(e){return console.error("Copy failed:",e),!1}};return l||a?(0,n.jsxs)("div",{className:"space-y-3 pt-4 border-t border-gray-200",children:[(0,n.jsx)("h3",{className:"text-sm font-semibold text-gray-900",children:"Results"}),l&&l.map(e=>{let l=t.has(e.guardrailName);return(0,n.jsx)(lx.Z,{className:"bg-green-50 border-green-200",children:(0,n.jsxs)("div",{className:"space-y-3",children:[(0,n.jsxs)("div",{className:"flex items-center justify-between",children:[(0,n.jsxs)("div",{className:"flex items-center space-x-2 cursor-pointer flex-1",onClick:()=>r(e.guardrailName),children:[l?(0,n.jsx)(lZ.Z,{className:"text-gray-500 text-xs"}):(0,n.jsx)(lP.Z,{className:"text-gray-500 text-xs"}),(0,n.jsx)(lA.Z,{className:"text-green-600 text-lg"}),(0,n.jsx)("span",{className:"text-sm font-medium text-green-800",children:e.guardrailName})]}),(0,n.jsxs)("div",{className:"flex items-center gap-3",children:[(0,n.jsxs)("div",{className:"flex items-center space-x-1 text-xs text-gray-600",children:[(0,n.jsx)(lO.Z,{}),(0,n.jsxs)("span",{className:"font-medium",children:[e.latency,"ms"]})]}),!l&&(0,n.jsx)(d.Z,{size:"xs",variant:"secondary",icon:lS.Z,onClick:async()=>{await s(e.response_text)?et.Z.success("Result copied to clipboard"):et.Z.fromBackend("Failed to copy result")},children:"Copy"})]})]}),!l&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)("div",{className:"bg-white border border-green-200 rounded p-3",children:[(0,n.jsx)("label",{className:"text-xs font-medium text-gray-600 mb-2 block",children:"Output Text"}),(0,n.jsx)("div",{className:"font-mono text-sm text-gray-900 whitespace-pre-wrap break-words",children:e.response_text})]}),(0,n.jsxs)("div",{className:"text-xs text-gray-600",children:[(0,n.jsx)("span",{className:"font-medium",children:"Characters:"})," ",e.response_text.length]})]})]})},e.guardrailName)}),a&&a.map(e=>{let l=t.has(e.guardrailName);return(0,n.jsx)(lx.Z,{className:"bg-red-50 border-red-200",children:(0,n.jsxs)("div",{className:"flex items-start space-x-2",children:[(0,n.jsx)("div",{className:"cursor-pointer mt-0.5",onClick:()=>r(e.guardrailName),children:l?(0,n.jsx)(lZ.Z,{className:"text-gray-500 text-xs"}):(0,n.jsx)(lP.Z,{className:"text-gray-500 text-xs"})}),(0,n.jsx)("div",{className:"text-red-600 mt-0.5",children:(0,n.jsx)("svg",{className:"w-5 h-5",fill:"currentColor",viewBox:"0 0 20 20",children:(0,n.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,n.jsxs)("div",{className:"flex-1",children:[(0,n.jsxs)("div",{className:"flex items-center justify-between mb-1",children:[(0,n.jsxs)("p",{className:"text-sm font-medium text-red-800 cursor-pointer",onClick:()=>r(e.guardrailName),children:[e.guardrailName," - Error"]}),(0,n.jsxs)("div",{className:"flex items-center space-x-1 text-xs text-gray-600",children:[(0,n.jsx)(lO.Z,{}),(0,n.jsxs)("span",{className:"font-medium",children:[e.latency,"ms"]})]})]}),!l&&(0,n.jsx)("p",{className:"text-sm text-red-700 mt-1",children:e.error.message})]})]})},e.guardrailName)})]}):null};let{TextArea:lT}=eG.default,{Text:lz}=g.default;var lE=function(e){let{guardrailNames:l,onSubmit:a,isLoading:t,results:i,errors:r,onClose:s}=e,[d,c]=(0,o.useState)(""),u=()=>{if(!d.trim()){et.Z.fromBackend("Please enter text to test");return}a(d)},m=async e=>{try{if(navigator.clipboard&&window.isSecureContext)return await navigator.clipboard.writeText(e),!0;{let l=document.createElement("textarea");l.value=e,l.style.position="fixed",l.style.opacity="0",document.body.appendChild(l),l.focus(),l.select();let a=document.execCommand("copy");if(document.body.removeChild(l),!a)throw Error("execCommand failed");return!0}}catch(e){return console.error("Copy failed:",e),!1}},x=async()=>{await m(d)?et.Z.success("Input copied to clipboard"):et.Z.fromBackend("Failed to copy input")};return(0,n.jsxs)("div",{className:"space-y-4 h-full flex flex-col",children:[(0,n.jsx)("div",{className:"flex items-center justify-between pb-3 border-b border-gray-200",children:(0,n.jsx)("div",{className:"flex items-center space-x-3",children:(0,n.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,n.jsxs)("div",{className:"flex items-center space-x-2 mb-1",children:[(0,n.jsx)("h2",{className:"text-lg font-semibold text-gray-900",children:"Test Guardrails:"}),(0,n.jsx)("div",{className:"flex flex-wrap gap-2",children:l.map(e=>(0,n.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,n.jsx)("span",{className:"font-mono text-blue-700 font-medium text-sm",children:e})},e))})]}),(0,n.jsxs)("p",{className:"text-sm text-gray-500",children:["Test ",l.length>1?"guardrails":"guardrail"," and compare results"]})]})})}),(0,n.jsxs)("div",{className:"flex-1 overflow-auto space-y-4",children:[(0,n.jsxs)("div",{className:"space-y-3",children:[(0,n.jsxs)("div",{children:[(0,n.jsxs)("div",{className:"flex justify-between items-center mb-2",children:[(0,n.jsxs)("div",{className:"flex items-center gap-2",children:[(0,n.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Input Text"}),(0,n.jsx)(L.Z,{title:"Press Enter to submit. Use Shift+Enter for new line.",children:(0,n.jsx)(eR.Z,{className:"text-gray-400 cursor-help"})})]}),d&&(0,n.jsx)(ed.z,{size:"xs",variant:"secondary",icon:lS.Z,onClick:x,children:"Copy Input"})]}),(0,n.jsx)(lT,{value:d,onChange:e=>c(e.target.value),onKeyDown:e=>{"Enter"!==e.key||e.shiftKey||e.ctrlKey||e.metaKey||(e.preventDefault(),u())},placeholder:"Enter text to test with guardrails...",rows:8,className:"font-mono text-sm"}),(0,n.jsxs)("div",{className:"flex justify-between items-center mt-1",children:[(0,n.jsxs)(lz,{className:"text-xs text-gray-500",children:["Press ",(0,n.jsx)("kbd",{className:"px-1 py-0.5 bg-gray-100 border border-gray-300 rounded text-xs",children:"Enter"})," to submit • ",(0,n.jsx)("kbd",{className:"px-1 py-0.5 bg-gray-100 border border-gray-300 rounded text-xs",children:"Shift+Enter"})," for new line"]}),(0,n.jsxs)(lz,{className:"text-xs text-gray-500",children:["Characters: ",d.length]})]})]}),(0,n.jsx)("div",{className:"pt-2",children:(0,n.jsx)(ed.z,{onClick:u,loading:t,disabled:!d.trim(),className:"w-full",children:t?"Testing ".concat(l.length," guardrail").concat(l.length>1?"s":"","..."):"Test ".concat(l.length," guardrail").concat(l.length>1?"s":"")})})]}),(0,n.jsx)(lL,{results:i,errors:r})]})]})},lB=e=>{let{guardrailsList:l,isLoading:a,accessToken:t,onClose:i}=e,[r,s]=(0,o.useState)(new Set),[d,c]=(0,o.useState)(""),[u,m]=(0,o.useState)([]),[x,p]=(0,o.useState)([]),[g,f]=(0,o.useState)(!1),j=l.filter(e=>{var l;return null===(l=e.guardrail_name)||void 0===l?void 0:l.toLowerCase().includes(d.toLowerCase())}),v=e=>{let l=new Set(r);l.has(e)?l.delete(e):l.add(e),s(l)},y=async e=>{if(0===r.size||!t)return;f(!0),m([]),p([]);let l=[],a=[];await Promise.all(Array.from(r).map(async i=>{let r=Date.now();try{let a=await (0,h.applyGuardrail)(t,i,e,null,null),s=Date.now()-r;l.push({guardrailName:i,response_text:a.response_text,latency:s})}catch(l){let e=Date.now()-r;console.error("Error testing guardrail ".concat(i,":"),l),a.push({guardrailName:i,error:l,latency:e})}})),m(l),p(a),f(!1),l.length>0&&et.Z.success("".concat(l.length," guardrail").concat(l.length>1?"s":""," applied successfully")),a.length>0&&et.Z.fromBackend("".concat(a.length," guardrail").concat(a.length>1?"s":""," failed"))};return(0,n.jsx)("div",{className:"w-full h-[calc(100vh-200px)]",children:(0,n.jsx)(lx.Z,{className:"h-full",children:(0,n.jsxs)("div",{className:"flex h-full",children:[(0,n.jsxs)("div",{className:"w-1/4 border-r border-gray-200 flex flex-col overflow-hidden",children:[(0,n.jsx)("div",{className:"p-4 border-b border-gray-200",children:(0,n.jsxs)("div",{className:"mb-3",children:[(0,n.jsx)(lN.Z,{className:"text-lg font-semibold mb-3",children:"Guardrails"}),(0,n.jsx)(eg.Z,{icon:lk.Z,placeholder:"Search guardrails...",value:d,onValueChange:c})]})}),(0,n.jsx)("div",{className:"flex-1 overflow-auto",children:a?(0,n.jsx)("div",{className:"flex items-center justify-center h-32",children:(0,n.jsx)(H.Z,{})}):0===j.length?(0,n.jsx)("div",{className:"p-4",children:(0,n.jsx)(eD.Z,{description:d?"No guardrails match your search":"No guardrails available"})}):(0,n.jsx)(lw.Z,{dataSource:j,renderItem:e=>(0,n.jsx)(lw.Z.Item,{onClick:()=>{e.guardrail_name&&v(e.guardrail_name)},className:"cursor-pointer hover:bg-gray-50 transition-colors px-4 ".concat(r.has(e.guardrail_name||"")?"bg-blue-50 border-l-4 border-l-blue-500":"border-l-4 border-l-transparent"),children:(0,n.jsx)(lw.Z.Item.Meta,{avatar:(0,n.jsx)(z.Z,{checked:r.has(e.guardrail_name||""),onClick:l=>{l.stopPropagation(),e.guardrail_name&&v(e.guardrail_name)}}),title:(0,n.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,n.jsx)(lC.Z,{className:"text-gray-400"}),(0,n.jsx)("span",{className:"font-medium text-gray-900",children:e.guardrail_name})]}),description:(0,n.jsxs)("div",{className:"text-xs space-y-1 mt-1",children:[(0,n.jsxs)("div",{children:[(0,n.jsx)("span",{className:"font-medium",children:"Type: "}),(0,n.jsx)("span",{className:"text-gray-600",children:e.litellm_params.guardrail})]}),(0,n.jsxs)("div",{children:[(0,n.jsx)("span",{className:"font-medium",children:"Mode: "}),(0,n.jsx)("span",{className:"text-gray-600",children:e.litellm_params.mode})]})]})})})})}),(0,n.jsx)("div",{className:"p-3 border-t border-gray-200 bg-gray-50",children:(0,n.jsxs)(lp.Z,{className:"text-xs text-gray-600",children:[r.size," of ",j.length," selected"]})})]}),(0,n.jsxs)("div",{className:"w-3/4 flex flex-col bg-white",children:[(0,n.jsx)("div",{className:"p-4 border-b border-gray-200 flex justify-between items-center",children:(0,n.jsx)(lN.Z,{className:"text-xl font-semibold mb-0",children:"Guardrail Testing Playground"})}),(0,n.jsx)("div",{className:"flex-1 overflow-auto p-4",children:0===r.size?(0,n.jsxs)("div",{className:"h-full flex flex-col items-center justify-center text-gray-400",children:[(0,n.jsx)(lC.Z,{style:{fontSize:"48px",marginBottom:"16px"}}),(0,n.jsx)(lp.Z,{className:"text-lg font-medium text-gray-600 mb-2",children:"Select Guardrails to Test"}),(0,n.jsx)(lp.Z,{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,n.jsx)("div",{className:"h-full",children:(0,n.jsx)(lE,{guardrailNames:Array.from(r),onSubmit:y,results:u.length>0?u:null,errors:x.length>0?x:null,isLoading:g,onClose:()=>s(new Set)})})})]})]})})})},lM=a(21609),lF=e=>{let{accessToken:l,userRole:a}=e,[t,i]=(0,o.useState)([]),[r,s]=(0,o.useState)(!1),[g,f]=(0,o.useState)(!1),[j,v]=(0,o.useState)(!1),[y,_]=(0,o.useState)(null),[b,N]=(0,o.useState)(!1),[w,k]=(0,o.useState)(null),[C,S]=(0,o.useState)(0),Z=!!a&&(0,lc.tY)(a),P=async()=>{if(l){f(!0);try{let e=await (0,h.getGuardrailsList)(l);console.log("guardrails: ".concat(JSON.stringify(e))),i(e.guardrails)}catch(e){console.error("Error fetching guardrails:",e)}finally{f(!1)}}};(0,o.useEffect)(()=>{P()},[l]);let A=async()=>{if(y&&l){v(!0);try{await (0,h.deleteGuardrailCall)(l,y.guardrail_id),et.Z.success('Guardrail "'.concat(y.guardrail_name,'" deleted successfully')),await P()}catch(e){console.error("Error deleting guardrail:",e),et.Z.fromBackend("Failed to delete guardrail")}finally{v(!1),N(!1),_(null)}}},O=y&&y.litellm_params?I(y.litellm_params.guardrail).displayName:void 0;return(0,n.jsx)("div",{className:"w-full mx-auto flex-auto overflow-y-auto m-8 p-2",children:(0,n.jsxs)(u.Z,{index:C,onIndexChange:S,children:[(0,n.jsxs)(m.Z,{className:"mb-4",children:[(0,n.jsx)(c.Z,{children:"Guardrails"}),(0,n.jsx)(c.Z,{disabled:!l||0===t.length,children:"Test Playground"})]}),(0,n.jsxs)(p.Z,{children:[(0,n.jsxs)(x.Z,{children:[(0,n.jsx)("div",{className:"flex justify-between items-center mb-4",children:(0,n.jsx)(d.Z,{onClick:()=>{w&&k(null),s(!0)},disabled:!l,children:"+ Add New Guardrail"})}),w?(0,n.jsx)(lb,{guardrailId:w,onClose:()=>k(null),accessToken:l,isAdmin:Z}):(0,n.jsx)(ld,{guardrailsList:t,isLoading:g,onDeleteClick:(e,l)=>{_(t.find(l=>l.guardrail_id===e)||null),N(!0)},accessToken:l,onGuardrailUpdated:P,isAdmin:Z,onGuardrailClick:e=>k(e)}),(0,n.jsx)(eX,{visible:r,onClose:()=>{s(!1)},accessToken:l,onSuccess:()=>{P()}}),(0,n.jsx)(lM.Z,{isOpen:b,title:"Delete Guardrail",message:"Are you sure you want to delete guardrail: ".concat(null==y?void 0:y.guardrail_name,"? This action cannot be undone."),resourceInformationTitle:"Guardrail Information",resourceInformation:[{label:"Name",value:null==y?void 0:y.guardrail_name},{label:"ID",value:null==y?void 0:y.guardrail_id,code:!0},{label:"Provider",value:O},{label:"Mode",value:null==y?void 0:y.litellm_params.mode},{label:"Default On",value:(null==y?void 0:y.litellm_params.default_on)?"Yes":"No"}],onCancel:()=>{N(!1),_(null)},onOk:A,confirmLoading:j})]}),(0,n.jsx)(x.Z,{children:(0,n.jsx)(lB,{guardrailsList:t,isLoading:g,accessToken:l,onClose:()=>S(0)})})]})]})})}}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/1414-2770d1155b664522.js b/litellm/proxy/_experimental/out/_next/static/chunks/1414-2770d1155b664522.js new file mode 100644 index 00000000000..937cb546ae2 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/1414-2770d1155b664522.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1414],{41649:function(e,t,r){r.d(t,{Z:function(){return h}});var o=r(5853),n=r(2265),a=r(47187),i=r(7084),s=r(26898),l=r(13241),c=r(1153);let d={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"}},u={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"}},p=(0,c.fn)("Badge"),h=n.forwardRef((e,t)=>{let{color:r,icon:h,size:m=i.u8.SM,tooltip:g,className:b,children:f}=e,v=(0,o._T)(e,["color","icon","size","tooltip","className","children"]),y=h||null,{tooltipProps:k,getReferenceProps:x}=(0,a.l)();return n.createElement("span",Object.assign({ref:(0,c.lq)([t,k.refs.setReference]),className:(0,l.q)(p("root"),"w-max shrink-0 inline-flex justify-center items-center cursor-default rounded-tremor-small ring-1 ring-inset",r?(0,l.q)((0,c.bM)(r,s.K.background).bgColor,(0,c.bM)(r,s.K.iconText).textColor,(0,c.bM)(r,s.K.iconRing).ringColor,"bg-opacity-10 ring-opacity-20","dark:bg-opacity-5 dark:ring-opacity-60"):(0,l.q)("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"),d[m].paddingX,d[m].paddingY,d[m].fontSize,b)},x,v),n.createElement(a.Z,Object.assign({text:g},k)),y?n.createElement(y,{className:(0,l.q)(p("icon"),"shrink-0 -ml-1 mr-1.5",u[m].height,u[m].width)}):null,n.createElement("span",{className:(0,l.q)(p("text"),"whitespace-nowrap")},f))});h.displayName="Badge"},47323:function(e,t,r){r.d(t,{Z:function(){return g}});var o=r(5853),n=r(2265),a=r(47187),i=r(7084),s=r(13241),l=r(1153),c=r(26898);let d={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"}},u={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"}},p={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:""}},h=(e,t)=>{switch(e){case"simple":return{textColor:t?(0,l.bM)(t,c.K.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:"",borderColor:"",ringColor:""};case"light":return{textColor:t?(0,l.bM)(t,c.K.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,s.q)((0,l.bM)(t,c.K.background).bgColor,"bg-opacity-20"):"bg-tremor-brand-muted dark:bg-dark-tremor-brand-muted",borderColor:"",ringColor:""};case"shadow":return{textColor:t?(0,l.bM)(t,c.K.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,s.q)((0,l.bM)(t,c.K.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.bM)(t,c.K.text).textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",bgColor:t?(0,s.q)((0,l.bM)(t,c.K.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.bM)(t,c.K.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,s.q)((0,l.bM)(t,c.K.background).bgColor,"bg-opacity-20"):"bg-tremor-background dark:bg-dark-tremor-background",borderColor:t?(0,l.bM)(t,c.K.ring).borderColor:"border-tremor-brand-subtle dark:border-dark-tremor-brand-subtle",ringColor:t?(0,s.q)((0,l.bM)(t,c.K.ring).ringColor,"ring-opacity-40"):"ring-tremor-brand-muted dark:ring-dark-tremor-brand-muted"}}},m=(0,l.fn)("Icon"),g=n.forwardRef((e,t)=>{let{icon:r,variant:c="simple",tooltip:g,size:b=i.u8.SM,color:f,className:v}=e,y=(0,o._T)(e,["icon","variant","tooltip","size","color","className"]),k=h(c,f),{tooltipProps:x,getReferenceProps:w}=(0,a.l)();return n.createElement("span",Object.assign({ref:(0,l.lq)([t,x.refs.setReference]),className:(0,s.q)(m("root"),"inline-flex shrink-0 items-center justify-center",k.bgColor,k.textColor,k.borderColor,k.ringColor,p[c].rounded,p[c].border,p[c].shadow,p[c].ring,d[b].paddingX,d[b].paddingY,v)},w,y),n.createElement(a.Z,Object.assign({text:g},x)),n.createElement(r,{className:(0,s.q)(m("icon"),"shrink-0",u[b].height,u[b].width)}))});g.displayName="Icon"},59341:function(e,t,r){r.d(t,{Z:function(){return R}});var o=r(5853),n=r(71049),a=r(11323),i=r(2265),s=r(66797),l=r(40099),c=r(74275),d=r(59456),u=r(93980),p=r(65573),h=r(67561),m=r(87550),g=r(628),b=r(80281),f=r(31370),v=r(20131),y=r(38929),k=r(52307),x=r(52724),w=r(7935);let C=(0,i.createContext)(null);C.displayName="GroupContext";let O=i.Fragment,E=Object.assign((0,y.yV)(function(e,t){var r;let o=(0,i.useId)(),O=(0,b.Q)(),E=(0,m.B)(),{id:j=O||"headlessui-switch-".concat(o),disabled:S=E||!1,checked:M,defaultChecked:N,onChange:P,name:Z,value:R,form:L,autoFocus:z=!1,...I}=e,q=(0,i.useContext)(C),[T,B]=(0,i.useState)(null),K=(0,i.useRef)(null),W=(0,h.T)(K,t,null===q?null:q.setSwitch,B),D=(0,c.L)(N),[F,H]=(0,l.q)(M,P,null!=D&&D),_=(0,d.G)(),[V,X]=(0,i.useState)(!1),Y=(0,u.z)(()=>{X(!0),null==H||H(!F),_.nextFrame(()=>{X(!1)})}),A=(0,u.z)(e=>{if((0,f.P)(e.currentTarget))return e.preventDefault();e.preventDefault(),Y()}),G=(0,u.z)(e=>{e.key===x.R.Space?(e.preventDefault(),Y()):e.key===x.R.Enter&&(0,v.g)(e.currentTarget)}),U=(0,u.z)(e=>e.preventDefault()),$=(0,w.wp)(),Q=(0,k.zH)(),{isFocusVisible:J,focusProps:ee}=(0,n.F)({autoFocus:z}),{isHovered:et,hoverProps:er}=(0,a.X)({isDisabled:S}),{pressed:eo,pressProps:en}=(0,s.x)({disabled:S}),ea=(0,i.useMemo)(()=>({checked:F,disabled:S,hover:et,focus:J,active:eo,autofocus:z,changing:V}),[F,et,J,eo,S,V,z]),ei=(0,y.dG)({id:j,ref:W,role:"switch",type:(0,p.f)(e,T),tabIndex:-1===e.tabIndex?0:null!=(r=e.tabIndex)?r:0,"aria-checked":F,"aria-labelledby":$,"aria-describedby":Q,disabled:S||void 0,autoFocus:z,onClick:A,onKeyUp:G,onKeyPress:U},ee,er,en),es=(0,i.useCallback)(()=>{if(void 0!==D)return null==H?void 0:H(D)},[H,D]),el=(0,y.L6)();return i.createElement(i.Fragment,null,null!=Z&&i.createElement(g.Mt,{disabled:S,data:{[Z]:R||"on"},overrides:{type:"checkbox",checked:F},form:L,onReset:es}),el({ourProps:ei,theirProps:I,slot:ea,defaultTag:"button",name:"Switch"}))}),{Group:function(e){var t;let[r,o]=(0,i.useState)(null),[n,a]=(0,w.bE)(),[s,l]=(0,k.fw)(),c=(0,i.useMemo)(()=>({switch:r,setSwitch:o}),[r,o]),d=(0,y.L6)();return i.createElement(l,{name:"Switch.Description",value:s},i.createElement(a,{name:"Switch.Label",value:n,props:{htmlFor:null==(t=c.switch)?void 0:t.id,onClick(e){r&&(e.currentTarget instanceof HTMLLabelElement&&e.preventDefault(),r.click(),r.focus({preventScroll:!0}))}}},i.createElement(C.Provider,{value:c},d({ourProps:{},theirProps:e,slot:{},defaultTag:O,name:"Switch.Group"}))))},Label:w.__,Description:k.dk});var j=r(44140),S=r(26898),M=r(13241),N=r(1153),P=r(47187);let Z=(0,N.fn)("Switch"),R=i.forwardRef((e,t)=>{let{checked:r,defaultChecked:n=!1,onChange:a,color:s,name:l,error:c,errorMessage:d,disabled:u,required:p,tooltip:h,id:m}=e,g=(0,o._T)(e,["checked","defaultChecked","onChange","color","name","error","errorMessage","disabled","required","tooltip","id"]),b={bgColor:s?(0,N.bM)(s,S.K.background).bgColor:"bg-tremor-brand dark:bg-dark-tremor-brand",ringColor:s?(0,N.bM)(s,S.K.ring).ringColor:"ring-tremor-brand-muted dark:ring-dark-tremor-brand-muted"},[f,v]=(0,j.Z)(n,r),[y,k]=(0,i.useState)(!1),{tooltipProps:x,getReferenceProps:w}=(0,P.l)(300);return i.createElement("div",{className:"flex flex-row items-center justify-start"},i.createElement(P.Z,Object.assign({text:h},x)),i.createElement("div",Object.assign({ref:(0,N.lq)([t,x.refs.setReference]),className:(0,M.q)(Z("root"),"flex flex-row relative h-5")},g,w),i.createElement("input",{type:"checkbox",className:(0,M.q)(Z("input"),"absolute w-5 h-5 cursor-pointer left-0 top-0 opacity-0"),name:l,required:p,checked:f,onChange:e=>{e.preventDefault()}}),i.createElement(E,{checked:f,onChange:e=>{v(e),null==a||a(e)},disabled:u,className:(0,M.q)(Z("switch"),"w-10 h-5 group relative inline-flex shrink-0 cursor-pointer items-center justify-center rounded-tremor-full","focus:outline-none",u?"cursor-not-allowed":""),onFocus:()=>k(!0),onBlur:()=>k(!1),id:m},i.createElement("span",{className:(0,M.q)(Z("sr-only"),"sr-only")},"Switch ",f?"on":"off"),i.createElement("span",{"aria-hidden":"true",className:(0,M.q)(Z("background"),f?b.bgColor:"bg-tremor-border dark:bg-dark-tremor-border","pointer-events-none absolute mx-auto h-3 w-9 rounded-tremor-full transition-colors duration-100 ease-in-out")}),i.createElement("span",{"aria-hidden":"true",className:(0,M.q)(Z("round"),f?(0,M.q)(b.bgColor,"translate-x-5 border-tremor-background dark:border-dark-tremor-background"):"translate-x-0 bg-tremor-border dark:bg-dark-tremor-border border-tremor-background dark:border-dark-tremor-background","pointer-events-none absolute left-0 inline-block h-5 w-5 transform rounded-tremor-full border-2 shadow-tremor-input duration-100 ease-in-out transition",y?(0,M.q)("ring-2",b.ringColor):"")}))),c&&d?i.createElement("p",{className:(0,M.q)(Z("errorMessage"),"text-sm text-red-500 mt-1 ")},d):null)});R.displayName="Switch"},44140:function(e,t,r){r.d(t,{Z:function(){return n}});var o=r(2265);let n=(e,t)=>{let r=void 0!==t,[n,a]=(0,o.useState)(e);return[r?t:n,e=>{r||a(e)}]}},92570:function(e,t,r){r.d(t,{Z:function(){return o}});let o=e=>e?"function"==typeof e?e():e:null},867:function(e,t,r){r.d(t,{Z:function(){return E}});var o=r(2265),n=r(54537),a=r(36760),i=r.n(a),s=r(50506),l=r(18694),c=r(71744),d=r(79326),u=r(59367),p=r(92570),h=r(5545),m=r(51248),g=r(55274),b=r(37381),f=r(20435),v=r(99320);let y=e=>{let{componentCls:t,iconCls:r,antCls:o,zIndexPopup:n,colorText:a,colorWarning:i,marginXXS:s,marginXS:l,fontSize:c,fontWeightStrong:d,colorTextHeading:u}=e;return{[t]:{zIndex:n,["&".concat(o,"-popover")]:{fontSize:c},["".concat(t,"-message")]:{marginBottom:l,display:"flex",flexWrap:"nowrap",alignItems:"start",["> ".concat(t,"-message-icon ").concat(r)]:{color:i,fontSize:c,lineHeight:1,marginInlineEnd:l},["".concat(t,"-title")]:{fontWeight:d,color:u,"&:only-child":{fontWeight:"normal"}},["".concat(t,"-description")]:{marginTop:s,color:a}},["".concat(t,"-buttons")]:{textAlign:"end",whiteSpace:"nowrap",button:{marginInlineStart:l}}}}};var k=(0,v.I$)("Popconfirm",e=>y(e),e=>{let{zIndexPopupBase:t}=e;return{zIndexPopup:t+60}},{resetStyle:!1}),x=function(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&0>t.indexOf(o)&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var n=0,o=Object.getOwnPropertySymbols(e);nt.indexOf(o[n])&&Object.prototype.propertyIsEnumerable.call(e,o[n])&&(r[o[n]]=e[o[n]]);return r};let w=e=>{let{prefixCls:t,okButtonProps:r,cancelButtonProps:a,title:i,description:s,cancelText:l,okText:d,okType:f="primary",icon:v=o.createElement(n.Z,null),showCancel:y=!0,close:k,onConfirm:x,onCancel:w,onPopupClick:C}=e,{getPrefixCls:O}=o.useContext(c.E_),[E]=(0,g.Z)("Popconfirm",b.Z.Popconfirm),j=(0,p.Z)(i),S=(0,p.Z)(s);return o.createElement("div",{className:"".concat(t,"-inner-content"),onClick:C},o.createElement("div",{className:"".concat(t,"-message")},v&&o.createElement("span",{className:"".concat(t,"-message-icon")},v),o.createElement("div",{className:"".concat(t,"-message-text")},j&&o.createElement("div",{className:"".concat(t,"-title")},j),S&&o.createElement("div",{className:"".concat(t,"-description")},S))),o.createElement("div",{className:"".concat(t,"-buttons")},y&&o.createElement(h.ZP,Object.assign({onClick:w,size:"small"},a),l||(null==E?void 0:E.cancelText)),o.createElement(u.Z,{buttonProps:Object.assign(Object.assign({size:"small"},(0,m.nx)(f)),r),actionFn:x,close:k,prefixCls:O("btn"),quitOnNullishReturnValue:!0,emitEvent:!0},d||(null==E?void 0:E.okText))))};var C=function(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&0>t.indexOf(o)&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var n=0,o=Object.getOwnPropertySymbols(e);nt.indexOf(o[n])&&Object.prototype.propertyIsEnumerable.call(e,o[n])&&(r[o[n]]=e[o[n]]);return r};let O=o.forwardRef((e,t)=>{var r,a;let{prefixCls:u,placement:p="top",trigger:h="click",okType:m="primary",icon:g=o.createElement(n.Z,null),children:b,overlayClassName:f,onOpenChange:v,onVisibleChange:y,overlayStyle:x,styles:O,classNames:E}=e,j=C(e,["prefixCls","placement","trigger","okType","icon","children","overlayClassName","onOpenChange","onVisibleChange","overlayStyle","styles","classNames"]),{getPrefixCls:S,className:M,style:N,classNames:P,styles:Z}=(0,c.dj)("popconfirm"),[R,L]=(0,s.Z)(!1,{value:null!==(r=e.open)&&void 0!==r?r:e.visible,defaultValue:null!==(a=e.defaultOpen)&&void 0!==a?a:e.defaultVisible}),z=(e,t)=>{L(e,!0),null==y||y(e),null==v||v(e,t)},I=S("popconfirm",u),q=i()(I,M,f,P.root,null==E?void 0:E.root),T=i()(P.body,null==E?void 0:E.body),[B]=k(I);return B(o.createElement(d.Z,Object.assign({},(0,l.Z)(j,["title"]),{trigger:h,placement:p,onOpenChange:(t,r)=>{let{disabled:o=!1}=e;o||z(t,r)},open:R,ref:t,classNames:{root:q,body:T},styles:{root:Object.assign(Object.assign(Object.assign(Object.assign({},Z.root),N),x),null==O?void 0:O.root),body:Object.assign(Object.assign({},Z.body),null==O?void 0:O.body)},content:o.createElement(w,Object.assign({okType:m,icon:g},e,{prefixCls:I,close:e=>{z(!1,e)},onConfirm:t=>{var r;return null===(r=e.onConfirm)||void 0===r?void 0:r.call(void 0,t)},onCancel:t=>{var r;z(!1,t),null===(r=e.onCancel)||void 0===r||r.call(void 0,t)}})),"data-popover-inject":!0}),b))});O._InternalPanelDoNotUseOrYouWillBeFired=e=>{let{prefixCls:t,placement:r,className:n,style:a}=e,s=x(e,["prefixCls","placement","className","style"]),{getPrefixCls:l}=o.useContext(c.E_),d=l("popconfirm",t),[u]=k(d);return u(o.createElement(f.ZP,{placement:r,className:i()(d,n),style:a,content:o.createElement(w,Object.assign({prefixCls:d},s))}))};var E=O},20435:function(e,t,r){r.d(t,{aV:function(){return u}});var o=r(2265),n=r(36760),a=r.n(n),i=r(5769),s=r(92570),l=r(71744),c=r(72262),d=function(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&0>t.indexOf(o)&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var n=0,o=Object.getOwnPropertySymbols(e);nt.indexOf(o[n])&&Object.prototype.propertyIsEnumerable.call(e,o[n])&&(r[o[n]]=e[o[n]]);return r};let u=e=>{let{title:t,content:r,prefixCls:n}=e;return t||r?o.createElement(o.Fragment,null,t&&o.createElement("div",{className:"".concat(n,"-title")},t),r&&o.createElement("div",{className:"".concat(n,"-inner-content")},r)):null},p=e=>{let{hashId:t,prefixCls:r,className:n,style:l,placement:c="top",title:d,content:p,children:h}=e,m=(0,s.Z)(d),g=(0,s.Z)(p),b=a()(t,r,"".concat(r,"-pure"),"".concat(r,"-placement-").concat(c),n);return o.createElement("div",{className:b,style:l},o.createElement("div",{className:"".concat(r,"-arrow")}),o.createElement(i.G,Object.assign({},e,{className:t,prefixCls:r}),h||o.createElement(u,{prefixCls:r,title:m,content:g})))};t.ZP=e=>{let{prefixCls:t,className:r}=e,n=d(e,["prefixCls","className"]),{getPrefixCls:i}=o.useContext(l.E_),s=i("popover",t),[u,h,m]=(0,c.Z)(s);return u(o.createElement(p,Object.assign({},n,{prefixCls:s,hashId:h,className:a()(r,m)})))}},79326:function(e,t,r){var o=r(2265),n=r(36760),a=r.n(n),i=r(50506),s=r(95814),l=r(92570),c=r(68710),d=r(19722),u=r(71744),p=r(99981),h=r(20435),m=r(72262),g=function(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&0>t.indexOf(o)&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var n=0,o=Object.getOwnPropertySymbols(e);nt.indexOf(o[n])&&Object.prototype.propertyIsEnumerable.call(e,o[n])&&(r[o[n]]=e[o[n]]);return r};let b=o.forwardRef((e,t)=>{var r,n;let{prefixCls:b,title:f,content:v,overlayClassName:y,placement:k="top",trigger:x="hover",children:w,mouseEnterDelay:C=.1,mouseLeaveDelay:O=.1,onOpenChange:E,overlayStyle:j={},styles:S,classNames:M}=e,N=g(e,["prefixCls","title","content","overlayClassName","placement","trigger","children","mouseEnterDelay","mouseLeaveDelay","onOpenChange","overlayStyle","styles","classNames"]),{getPrefixCls:P,className:Z,style:R,classNames:L,styles:z}=(0,u.dj)("popover"),I=P("popover",b),[q,T,B]=(0,m.Z)(I),K=P(),W=a()(y,T,B,Z,L.root,null==M?void 0:M.root),D=a()(L.body,null==M?void 0:M.body),[F,H]=(0,i.Z)(!1,{value:null!==(r=e.open)&&void 0!==r?r:e.visible,defaultValue:null!==(n=e.defaultOpen)&&void 0!==n?n:e.defaultVisible}),_=(e,t)=>{H(e,!0),null==E||E(e,t)},V=e=>{e.keyCode===s.Z.ESC&&_(!1,e)},X=(0,l.Z)(f),Y=(0,l.Z)(v);return q(o.createElement(p.Z,Object.assign({placement:k,trigger:x,mouseEnterDelay:C,mouseLeaveDelay:O},N,{prefixCls:I,classNames:{root:W,body:D},styles:{root:Object.assign(Object.assign(Object.assign(Object.assign({},z.root),R),j),null==S?void 0:S.root),body:Object.assign(Object.assign({},z.body),null==S?void 0:S.body)},ref:t,open:F,onOpenChange:e=>{_(e)},overlay:X||Y?o.createElement(h.aV,{prefixCls:I,title:X,content:Y}):null,transitionName:(0,c.m)(K,"zoom-big",N.transitionName),"data-popover-inject":!0}),(0,d.Tm)(w,{onKeyDown:e=>{var t,r;(0,o.isValidElement)(w)&&(null===(r=null==w?void 0:(t=w.props).onKeyDown)||void 0===r||r.call(t,e)),V(e)}})))});b._InternalPanelDoNotUseOrYouWillBeFired=h.ZP,t.Z=b},72262:function(e,t,r){var o=r(12918),n=r(691),a=r(88260),i=r(34442),s=r(53454),l=r(99320),c=r(71140);let d=e=>{let{componentCls:t,popoverColor:r,titleMinWidth:n,fontWeightStrong:i,innerPadding:s,boxShadowSecondary:l,colorTextHeading:c,borderRadiusLG:d,zIndexPopup:u,titleMarginBottom:p,colorBgElevated:h,popoverBg:m,titleBorderBottom:g,innerContentPadding:b,titlePadding:f}=e;return[{[t]:Object.assign(Object.assign({},(0,o.Wf)(e)),{position:"absolute",top:0,left:{_skip_check_:!0,value:0},zIndex:u,fontWeight:"normal",whiteSpace:"normal",textAlign:"start",cursor:"auto",userSelect:"text","--valid-offset-x":"var(--arrow-offset-horizontal, var(--arrow-x))",transformOrigin:"var(--valid-offset-x, 50%) var(--arrow-y, 50%)","--antd-arrow-background-color":h,width:"max-content",maxWidth:"100vw","&-rtl":{direction:"rtl"},"&-hidden":{display:"none"},["".concat(t,"-content")]:{position:"relative"},["".concat(t,"-inner")]:{backgroundColor:m,backgroundClip:"padding-box",borderRadius:d,boxShadow:l,padding:s},["".concat(t,"-title")]:{minWidth:n,marginBottom:p,color:c,fontWeight:i,borderBottom:g,padding:f},["".concat(t,"-inner-content")]:{color:r,padding:b}})},(0,a.ZP)(e,"var(--antd-arrow-background-color)"),{["".concat(t,"-pure")]:{position:"relative",maxWidth:"none",margin:e.sizePopupArrow,display:"inline-block",["".concat(t,"-content")]:{display:"inline-block"}}}]},u=e=>{let{componentCls:t}=e;return{[t]:s.i.map(r=>{let o=e["".concat(r,"6")];return{["&".concat(t,"-").concat(r)]:{"--antd-arrow-background-color":o,["".concat(t,"-inner")]:{backgroundColor:o},["".concat(t,"-arrow")]:{background:"transparent"}}}})}};t.Z=(0,l.I$)("Popover",e=>{let{colorBgElevated:t,colorText:r}=e,o=(0,c.IX)(e,{popoverBg:t,popoverColor:r});return[d(o),u(o),(0,n._y)(o,"zoom-big")]},e=>{let{lineWidth:t,controlHeight:r,fontHeight:o,padding:n,wireframe:s,zIndexPopupBase:l,borderRadiusLG:c,marginXS:d,lineType:u,colorSplit:p,paddingSM:h}=e,m=r-o;return Object.assign(Object.assign(Object.assign({titleMinWidth:177,zIndexPopup:l+30},(0,i.w)(e)),(0,a.wZ)({contentRadius:c,limitVerticalRadius:!0})),{innerPadding:s?0:12,titleMarginBottom:s?0:d,titlePadding:s?"".concat(m/2,"px ").concat(n,"px ").concat(m/2-t,"px"):0,titleBorderBottom:s?"".concat(t,"px ").concat(u," ").concat(p):"none",innerContentPadding:s?"".concat(h,"px ").concat(n,"px"):0})},{resetStyle:!1,deprecatedTokens:[["width","titleMinWidth"],["minWidth","titleMinWidth"]]})},3810:function(e,t,r){r.d(t,{Z:function(){return P}});var o=r(2265),n=r(36760),a=r.n(n),i=r(18694),s=r(93350),l=r(53445),c=r(19722),d=r(6694),u=r(71744),p=r(93463),h=r(54558),m=r(12918),g=r(71140),b=r(99320);let f=e=>{let{paddingXXS:t,lineWidth:r,tagPaddingHorizontal:o,componentCls:n,calc:a}=e,i=a(o).sub(r).equal(),s=a(t).sub(r).equal();return{[n]:Object.assign(Object.assign({},(0,m.Wf)(e)),{display:"inline-block",height:"auto",marginInlineEnd:e.marginXS,paddingInline:i,fontSize:e.tagFontSize,lineHeight:e.tagLineHeight,whiteSpace:"nowrap",background:e.defaultBg,border:"".concat((0,p.bf)(e.lineWidth)," ").concat(e.lineType," ").concat(e.colorBorder),borderRadius:e.borderRadiusSM,opacity:1,transition:"all ".concat(e.motionDurationMid),textAlign:"start",position:"relative",["&".concat(n,"-rtl")]:{direction:"rtl"},"&, a, a:hover":{color:e.defaultColor},["".concat(n,"-close-icon")]:{marginInlineStart:s,fontSize:e.tagIconSize,color:e.colorIcon,cursor:"pointer",transition:"all ".concat(e.motionDurationMid),"&:hover":{color:e.colorTextHeading}},["&".concat(n,"-has-color")]:{borderColor:"transparent",["&, a, a:hover, ".concat(e.iconCls,"-close, ").concat(e.iconCls,"-close:hover")]:{color:e.colorTextLightSolid}},"&-checkable":{backgroundColor:"transparent",borderColor:"transparent",cursor:"pointer",["&:not(".concat(n,"-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"},["> ".concat(e.iconCls," + span, > span + ").concat(e.iconCls)]:{marginInlineStart:i}}),["".concat(n,"-borderless")]:{borderColor:"transparent",background:e.tagBorderlessBg}}},v=e=>{let{lineWidth:t,fontSizeIcon:r,calc:o}=e,n=e.fontSizeSM;return(0,g.IX)(e,{tagFontSize:n,tagLineHeight:(0,p.bf)(o(e.lineHeightSM).mul(n).equal()),tagIconSize:o(r).sub(o(t).mul(2)).equal(),tagPaddingHorizontal:8,tagBorderlessBg:e.defaultBg})},y=e=>({defaultBg:new h.t(e.colorFillQuaternary).onBackground(e.colorBgContainer).toHexString(),defaultColor:e.colorText});var k=(0,b.I$)("Tag",e=>f(v(e)),y),x=function(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&0>t.indexOf(o)&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var n=0,o=Object.getOwnPropertySymbols(e);nt.indexOf(o[n])&&Object.prototype.propertyIsEnumerable.call(e,o[n])&&(r[o[n]]=e[o[n]]);return r};let w=o.forwardRef((e,t)=>{let{prefixCls:r,style:n,className:i,checked:s,children:l,icon:c,onChange:d,onClick:p}=e,h=x(e,["prefixCls","style","className","checked","children","icon","onChange","onClick"]),{getPrefixCls:m,tag:g}=o.useContext(u.E_),b=m("tag",r),[f,v,y]=k(b),w=a()(b,"".concat(b,"-checkable"),{["".concat(b,"-checkable-checked")]:s},null==g?void 0:g.className,i,v,y);return f(o.createElement("span",Object.assign({},h,{ref:t,style:Object.assign(Object.assign({},n),null==g?void 0:g.style),className:w,onClick:e=>{null==d||d(!s),null==p||p(e)}}),c,o.createElement("span",null,l)))});var C=r(18536);let O=e=>(0,C.Z)(e,(t,r)=>{let{textColor:o,lightBorderColor:n,lightColor:a,darkColor:i}=r;return{["".concat(e.componentCls).concat(e.componentCls,"-").concat(t)]:{color:o,background:a,borderColor:n,"&-inverse":{color:e.colorTextLightSolid,background:i,borderColor:i},["&".concat(e.componentCls,"-borderless")]:{borderColor:"transparent"}}}});var E=(0,b.bk)(["Tag","preset"],e=>O(v(e)),y);let j=(e,t,r)=>{let o="string"!=typeof r?r:r.charAt(0).toUpperCase()+r.slice(1);return{["".concat(e.componentCls).concat(e.componentCls,"-").concat(t)]:{color:e["color".concat(r)],background:e["color".concat(o,"Bg")],borderColor:e["color".concat(o,"Border")],["&".concat(e.componentCls,"-borderless")]:{borderColor:"transparent"}}}};var S=(0,b.bk)(["Tag","status"],e=>{let t=v(e);return[j(t,"success","Success"),j(t,"processing","Info"),j(t,"error","Error"),j(t,"warning","Warning")]},y),M=function(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&0>t.indexOf(o)&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var n=0,o=Object.getOwnPropertySymbols(e);nt.indexOf(o[n])&&Object.prototype.propertyIsEnumerable.call(e,o[n])&&(r[o[n]]=e[o[n]]);return r};let N=o.forwardRef((e,t)=>{let{prefixCls:r,className:n,rootClassName:p,style:h,children:m,icon:g,color:b,onClose:f,bordered:v=!0,visible:y}=e,x=M(e,["prefixCls","className","rootClassName","style","children","icon","color","onClose","bordered","visible"]),{getPrefixCls:w,direction:C,tag:O}=o.useContext(u.E_),[j,N]=o.useState(!0),P=(0,i.Z)(x,["closeIcon","closable"]);o.useEffect(()=>{void 0!==y&&N(y)},[y]);let Z=(0,s.o2)(b),R=(0,s.yT)(b),L=Z||R,z=Object.assign(Object.assign({backgroundColor:b&&!L?b:void 0},null==O?void 0:O.style),h),I=w("tag",r),[q,T,B]=k(I),K=a()(I,null==O?void 0:O.className,{["".concat(I,"-").concat(b)]:L,["".concat(I,"-has-color")]:b&&!L,["".concat(I,"-hidden")]:!j,["".concat(I,"-rtl")]:"rtl"===C,["".concat(I,"-borderless")]:!v},n,p,T,B),W=e=>{e.stopPropagation(),null==f||f(e),e.defaultPrevented||N(!1)},[,D]=(0,l.b)((0,l.w)(e),(0,l.w)(O),{closable:!1,closeIconRender:e=>{let t=o.createElement("span",{className:"".concat(I,"-close-icon"),onClick:W},e);return(0,c.wm)(e,t,e=>({onClick:t=>{var r;null===(r=null==e?void 0:e.onClick)||void 0===r||r.call(e,t),W(t)},className:a()(null==e?void 0:e.className,"".concat(I,"-close-icon"))}))}}),F="function"==typeof x.onClick||m&&"a"===m.type,H=g||null,_=H?o.createElement(o.Fragment,null,H,m&&o.createElement("span",null,m)):m,V=o.createElement("span",Object.assign({},P,{ref:t,className:K,style:z}),_,D,Z&&o.createElement(E,{key:"preset",prefixCls:I}),R&&o.createElement(S,{key:"status",prefixCls:I}));return q(F?o.createElement(d.Z,{component:"Tag"},V):V)});N.CheckableTag=w;var P=N},41671:function(e,t,r){r.d(t,{Z:function(){return o}});let o=(0,r(79205).Z)("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"}]])},33276:function(e,t,r){r.d(t,{Z:function(){return o}});let o=(0,r(79205).Z)("play",[["polygon",{points:"6 3 20 12 6 21 6 3",key:"1oa8hb"}]])},15868:function(e,t,r){r.d(t,{Z:function(){return o}});let o=(0,r(79205).Z)("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"}]])},18930:function(e,t,r){r.d(t,{Z:function(){return o}});let o=(0,r(79205).Z)("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"}]])},17689:function(e,t,r){r.d(t,{Z:function(){return o}});let o=(0,r(79205).Z)("upload",[["path",{d:"M12 3v12",key:"1x0j5s"}],["path",{d:"m17 8-5-5-5 5",key:"7q97r8"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}]])},44643:function(e,t,r){var o=r(2265);let n=o.forwardRef(function(e,t){return o.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),o.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"}))});t.Z=n},86462:function(e,t,r){var o=r(2265);let n=o.forwardRef(function(e,t){return o.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),o.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"}))});t.Z=n},44633:function(e,t,r){var o=r(2265);let n=o.forwardRef(function(e,t){return o.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),o.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 15l7-7 7 7"}))});t.Z=n},3477:function(e,t,r){var o=r(2265);let n=o.forwardRef(function(e,t){return o.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),o.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"}))});t.Z=n},53410:function(e,t,r){var o=r(2265);let n=o.forwardRef(function(e,t){return o.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),o.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"}))});t.Z=n},91126:function(e,t,r){var o=r(2265);let n=o.forwardRef(function(e,t){return o.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),o.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"}),o.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M21 12a9 9 0 11-18 0 9 9 0 0118 0z"}))});t.Z=n},23628:function(e,t,r){var o=r(2265);let n=o.forwardRef(function(e,t){return o.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),o.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"}))});t.Z=n},74998:function(e,t,r){var o=r(2265);let n=o.forwardRef(function(e,t){return o.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),o.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"}))});t.Z=n},2894:function(e,t,r){r.d(t,{R:function(){return s},m:function(){return i}});var o=r(18238),n=r(7989),a=r(11255),i=class extends n.F{#e;#t;#r;#o;constructor(e){super(),this.#e=e.client,this.mutationId=e.mutationId,this.#r=e.mutationCache,this.#t=[],this.state=e.state||s(),this.setOptions(e.options),this.scheduleGc()}setOptions(e){this.options=e,this.updateGcTime(this.options.gcTime)}get meta(){return this.options.meta}addObserver(e){this.#t.includes(e)||(this.#t.push(e),this.clearGcTimeout(),this.#r.notify({type:"observerAdded",mutation:this,observer:e}))}removeObserver(e){this.#t=this.#t.filter(t=>t!==e),this.scheduleGc(),this.#r.notify({type:"observerRemoved",mutation:this,observer:e})}optionalRemove(){this.#t.length||("pending"===this.state.status?this.scheduleGc():this.#r.remove(this))}continue(){return this.#o?.continue()??this.execute(this.state.variables)}async execute(e){let t=()=>{this.#n({type:"continue"})},r={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};this.#o=(0,a.Mz)({fn:()=>this.options.mutationFn?this.options.mutationFn(e,r):Promise.reject(Error("No mutationFn found")),onFail:(e,t)=>{this.#n({type:"failed",failureCount:e,error:t})},onPause:()=>{this.#n({type:"pause"})},onContinue:t,retry:this.options.retry??0,retryDelay:this.options.retryDelay,networkMode:this.options.networkMode,canRun:()=>this.#r.canRun(this)});let o="pending"===this.state.status,n=!this.#o.canStart();try{if(o)t();else{this.#n({type:"pending",variables:e,isPaused:n}),await this.#r.config.onMutate?.(e,this,r);let t=await this.options.onMutate?.(e,r);t!==this.state.context&&this.#n({type:"pending",context:t,variables:e,isPaused:n})}let a=await this.#o.start();return await this.#r.config.onSuccess?.(a,e,this.state.context,this,r),await this.options.onSuccess?.(a,e,this.state.context,r),await this.#r.config.onSettled?.(a,null,this.state.variables,this.state.context,this,r),await this.options.onSettled?.(a,null,e,this.state.context,r),this.#n({type:"success",data:a}),a}catch(t){try{throw await this.#r.config.onError?.(t,e,this.state.context,this,r),await this.options.onError?.(t,e,this.state.context,r),await this.#r.config.onSettled?.(void 0,t,this.state.variables,this.state.context,this,r),await this.options.onSettled?.(void 0,t,e,this.state.context,r),t}finally{this.#n({type:"error",error:t})}}finally{this.#r.runNext(this)}}#n(e){this.state=(t=>{switch(e.type){case"failed":return{...t,failureCount:e.failureCount,failureReason:e.error};case"pause":return{...t,isPaused:!0};case"continue":return{...t,isPaused:!1};case"pending":return{...t,context:e.context,data:void 0,failureCount:0,failureReason:null,error:null,isPaused:e.isPaused,status:"pending",variables:e.variables,submittedAt:Date.now()};case"success":return{...t,data:e.data,failureCount:0,failureReason:null,error:null,status:"success",isPaused:!1};case"error":return{...t,data:void 0,error:e.error,failureCount:t.failureCount+1,failureReason:e.error,isPaused:!1,status:"error"}}})(this.state),o.Vr.batch(()=>{this.#t.forEach(t=>{t.onMutationUpdate(e)}),this.#r.notify({mutation:this,type:"updated",action:e})})}};function s(){return{context:void 0,data:void 0,error:null,failureCount:0,failureReason:null,isPaused:!1,status:"idle",variables:void 0,submittedAt:0}}},21770:function(e,t,r){r.d(t,{D:function(){return d}});var o=r(2265),n=r(2894),a=r(18238),i=r(24112),s=r(45345),l=class extends i.l{#e;#a=void 0;#i;#s;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,s.VS)(this.options,t)||this.#e.getMutationCache().notify({type:"observerOptionsUpdated",mutation:this.#i,observer:this}),t?.mutationKey&&this.options.mutationKey&&(0,s.Ym)(t.mutationKey)!==(0,s.Ym)(this.options.mutationKey)?this.reset():this.#i?.state.status==="pending"&&this.#i.setOptions(this.options)}onUnsubscribe(){this.hasListeners()||this.#i?.removeObserver(this)}onMutationUpdate(e){this.#l(),this.#c(e)}getCurrentResult(){return this.#a}reset(){this.#i?.removeObserver(this),this.#i=void 0,this.#l(),this.#c()}mutate(e,t){return this.#s=t,this.#i?.removeObserver(this),this.#i=this.#e.getMutationCache().build(this.#e,this.options),this.#i.addObserver(this),this.#i.execute(e)}#l(){let e=this.#i?.state??(0,n.R)();this.#a={...e,isPending:"pending"===e.status,isSuccess:"success"===e.status,isError:"error"===e.status,isIdle:"idle"===e.status,mutate:this.mutate,reset:this.reset}}#c(e){a.Vr.batch(()=>{if(this.#s&&this.hasListeners()){let t=this.#a.variables,r=this.#a.context,o={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};e?.type==="success"?(this.#s.onSuccess?.(e.data,t,r,o),this.#s.onSettled?.(e.data,null,t,r,o)):e?.type==="error"&&(this.#s.onError?.(e.error,t,r,o),this.#s.onSettled?.(void 0,e.error,t,r,o))}this.listeners.forEach(e=>{e(this.#a)})})}},c=r(29827);function d(e,t){let r=(0,c.NL)(t),[n]=o.useState(()=>new l(r,e));o.useEffect(()=>{n.setOptions(e)},[n,e]);let i=o.useSyncExternalStore(o.useCallback(e=>n.subscribe(a.Vr.batchCalls(e)),[n]),()=>n.getCurrentResult(),()=>n.getCurrentResult()),d=o.useCallback((e,t)=>{n.mutate(e,t).catch(s.ZT)},[n]);if(i.error&&(0,s.L3)(n.options.throwOnError,[i.error]))throw i.error;return{...i,mutate:d,mutateAsync:i.mutate}}}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/1442-024f7e51804e0d7e.js b/litellm/proxy/_experimental/out/_next/static/chunks/1442-024f7e51804e0d7e.js new file mode 100644 index 00000000000..3c42e191d4b --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/1442-024f7e51804e0d7e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1442],{42698:function(e,t,n){n.d(t,{Z:function(){return i}});var r=n(2265),o=n(7084);n(13241);let i=(0,r.createContext)(o.fr.Blue)},64016:function(e,t,n){n.d(t,{Z:function(){return r}});let r=(0,n(2265).createContext)(0)},8710:function(e,t,n){n.d(t,{Z:function(){return r}});let r=(0,n(2265).createContext)(void 0)},33232:function(e,t,n){n.d(t,{Z:function(){return r}});let r=(0,n(2265).createContext)({selectedValue:void 0,handleValueChange:void 0})},71049:function(e,t,n){n.d(t,{F:function(){return D}});var r,o=n(2265);let i="undefined"!=typeof document?o.useLayoutEffect:()=>{},u=null!==(r=o.useInsertionEffect)&&void 0!==r?r:i;function a(e){return e.nativeEvent=e,e.isDefaultPrevented=()=>e.defaultPrevented,e.isPropagationStopped=()=>e.cancelBubble,e.persist=()=>{},e}function l(e){let t=(0,o.useRef)({isFocused:!1,observer:null});i(()=>{let e=t.current;return()=>{e.observer&&(e.observer.disconnect(),e.observer=null)}},[]);let n=function(e){let t=(0,o.useRef)(null);return u(()=>{t.current=e},[e]),(0,o.useCallback)((...e)=>{let n=t.current;return null==n?void 0:n(...e)},[])}(t=>{null==e||e(t)});return(0,o.useCallback)(e=>{if(e.target instanceof HTMLButtonElement||e.target instanceof HTMLInputElement||e.target instanceof HTMLTextAreaElement||e.target instanceof HTMLSelectElement){t.current.isFocused=!0;let r=e.target;r.addEventListener("focusout",e=>{t.current.isFocused=!1,r.disabled&&n(a(e)),t.current.observer&&(t.current.observer.disconnect(),t.current.observer=null)},{once:!0}),t.current.observer=new MutationObserver(()=>{if(t.current.isFocused&&r.disabled){var e;null===(e=t.current.observer)||void 0===e||e.disconnect();let n=r===document.activeElement?null:document.activeElement;r.dispatchEvent(new FocusEvent("blur",{relatedTarget:n})),r.dispatchEvent(new FocusEvent("focusout",{bubbles:!0,relatedTarget:n}))}}),t.current.observer.observe(r,{attributes:!0,attributeFilter:["disabled"]})}},[n])}function c(e){var t;if("undefined"==typeof window||null==window.navigator)return!1;let n=null===(t=window.navigator.userAgentData)||void 0===t?void 0:t.brands;return Array.isArray(n)&&n.some(t=>e.test(t.brand))||e.test(window.navigator.userAgent)}function s(e){var t;return"undefined"!=typeof window&&null!=window.navigator&&e.test((null===(t=window.navigator.userAgentData)||void 0===t?void 0:t.platform)||window.navigator.platform)}function d(e){let t=null;return()=>(null==t&&(t=e()),t)}let f=d(function(){return s(/^Mac/i)}),v=d(function(){return s(/^iPhone/i)}),p=d(function(){return s(/^iPad/i)||f()&&navigator.maxTouchPoints>1}),g=d(function(){return v()||p()});d(function(){return f()||g()}),d(function(){return c(/AppleWebKit/i)&&!m()});let m=d(function(){return c(/Chrome/i)}),h=d(function(){return c(/Android/i)});d(function(){return c(/Firefox/i)});var y=n(18064);let b=null,E=new Set,w=new Map,T=!1,A=!1,F={Tab:!0,Escape:!0};function L(e,t){for(let n of E)n(e,t)}function k(e){T=!0,e.metaKey||!f()&&e.altKey||e.ctrlKey||"Control"===e.key||"Shift"===e.key||"Meta"===e.key||(b="keyboard",L("keyboard",e))}function N(e){b="pointer",("mousedown"===e.type||"pointerdown"===e.type)&&(T=!0,L("pointer",e))}function P(e){(""===e.pointerType&&e.isTrusted||(h()&&e.pointerType?"click"===e.type&&1===e.buttons:0===e.detail&&!e.pointerType))&&(T=!0,b="virtual")}function O(e){e.target!==window&&e.target!==document&&e.isTrusted&&(T||A||(b="virtual",L("virtual",e)),T=!1,A=!1)}function S(){T=!1,A=!0}function M(e){if("undefined"==typeof window||"undefined"==typeof document||w.get((0,y.kR)(e)))return;let t=(0,y.kR)(e),n=(0,y.r3)(e),r=t.HTMLElement.prototype.focus;t.HTMLElement.prototype.focus=function(){T=!0,r.apply(this,arguments)},n.addEventListener("keydown",k,!0),n.addEventListener("keyup",k,!0),n.addEventListener("click",P,!0),t.addEventListener("focus",O,!0),t.addEventListener("blur",S,!1),"undefined"!=typeof PointerEvent&&(n.addEventListener("pointerdown",N,!0),n.addEventListener("pointermove",N,!0),n.addEventListener("pointerup",N,!0)),t.addEventListener("beforeunload",()=>{C(e)},{once:!0}),w.set(t,{focus:r})}let C=(e,t)=>{let n=(0,y.kR)(e),r=(0,y.r3)(e);t&&r.removeEventListener("DOMContentLoaded",t),w.has(n)&&(n.HTMLElement.prototype.focus=w.get(n).focus,r.removeEventListener("keydown",k,!0),r.removeEventListener("keyup",k,!0),r.removeEventListener("click",P,!0),n.removeEventListener("focus",O,!0),n.removeEventListener("blur",S,!1),"undefined"!=typeof PointerEvent&&(r.removeEventListener("pointerdown",N,!0),r.removeEventListener("pointermove",N,!0),r.removeEventListener("pointerup",N,!0)),w.delete(n))};function x(){return"pointer"!==b}"undefined"!=typeof document&&function(e){let t;let n=(0,y.r3)(void 0);"loading"!==n.readyState?M(void 0):(t=()=>{M(void 0)},n.addEventListener("DOMContentLoaded",t)),()=>C(e,t)}();let H=new Set(["checkbox","radio","range","color","file","image","button","submit","reset"]);var R=n(26428),j=n(66852);function D(e={}){var t,n,r;let{autoFocus:i=!1,isTextInput:u,within:c}=e,s=(0,o.useRef)({isFocused:!1,isFocusVisible:i||x()}),[d,f]=(0,o.useState)(!1),[v,p]=(0,o.useState)(()=>s.current.isFocused&&s.current.isFocusVisible),g=(0,o.useCallback)(()=>p(s.current.isFocused&&s.current.isFocusVisible),[]),m=(0,o.useCallback)(e=>{s.current.isFocused=e,f(e),g()},[g]);t=e=>{s.current.isFocusVisible=e,g()},n=[],r={isTextInput:u},M(),(0,o.useEffect)(()=>{let e=(e,n)=>{(function(e,t,n){let r=(0,y.r3)(null==n?void 0:n.target),o="undefined"!=typeof window?(0,y.kR)(null==n?void 0:n.target).HTMLInputElement:HTMLInputElement,i="undefined"!=typeof window?(0,y.kR)(null==n?void 0:n.target).HTMLTextAreaElement:HTMLTextAreaElement,u="undefined"!=typeof window?(0,y.kR)(null==n?void 0:n.target).HTMLElement:HTMLElement,a="undefined"!=typeof window?(0,y.kR)(null==n?void 0:n.target).KeyboardEvent:KeyboardEvent;return!((e=e||r.activeElement instanceof o&&!H.has(r.activeElement.type)||r.activeElement instanceof i||r.activeElement instanceof u&&r.activeElement.isContentEditable)&&"keyboard"===t&&n instanceof a&&!F[n.key])})(!!(null==r?void 0:r.isTextInput),e,n)&&t(x())};return E.add(e),()=>{E.delete(e)}},n);let{focusProps:h}=function(e){let{isDisabled:t,onFocus:n,onBlur:r,onFocusChange:i}=e,u=(0,o.useCallback)(e=>{if(e.target===e.currentTarget)return r&&r(e),i&&i(!1),!0},[r,i]),a=l(u),c=(0,o.useCallback)(e=>{let t=(0,y.r3)(e.target),r=t?(0,R.vY)(t):(0,R.vY)();e.target===e.currentTarget&&r===(0,R.NI)(e.nativeEvent)&&(n&&n(e),i&&i(!0),a(e))},[i,n,a]);return{focusProps:{onFocus:!t&&(n||i||r)?c:void 0,onBlur:!t&&(r||i)?u:void 0}}}({isDisabled:c,onFocusChange:m}),{focusWithinProps:b}=function(e){let{isDisabled:t,onBlurWithin:n,onFocusWithin:r,onFocusWithinChange:i}=e,u=(0,o.useRef)({isFocusWithin:!1}),{addGlobalListener:c,removeAllGlobalListeners:s}=(0,j.x)(),d=(0,o.useCallback)(e=>{e.currentTarget.contains(e.target)&&u.current.isFocusWithin&&!e.currentTarget.contains(e.relatedTarget)&&(u.current.isFocusWithin=!1,s(),n&&n(e),i&&i(!1))},[n,i,u,s]),f=l(d),v=(0,o.useCallback)(e=>{if(!e.currentTarget.contains(e.target))return;let t=(0,y.r3)(e.target),n=(0,R.vY)(t);if(!u.current.isFocusWithin&&n===(0,R.NI)(e.nativeEvent)){r&&r(e),i&&i(!0),u.current.isFocusWithin=!0,f(e);let n=e.currentTarget;c(t,"focus",e=>{if(u.current.isFocusWithin&&!(0,R.bE)(n,e.target)){let r=new t.defaultView.FocusEvent("blur",{relatedTarget:e.target});Object.defineProperty(r,"target",{value:n}),Object.defineProperty(r,"currentTarget",{value:n}),d(a(r))}},{capture:!0})}},[r,i,f,c,d]);return t?{focusWithinProps:{onFocus:void 0,onBlur:void 0}}:{focusWithinProps:{onFocus:v,onBlur:d}}}({isDisabled:!c,onFocusWithinChange:m});return{isFocused:d,isFocusVisible:v,focusProps:c?b:h}}},11323:function(e,t,n){n.d(t,{X:function(){return d}});var r=n(66852),o=n(18064),i=n(26428),u=n(2265);let a=!1,l=0;function c(e){"touch"===e.pointerType&&(a=!0,setTimeout(()=>{a=!1},50))}function s(){if("undefined"!=typeof document)return 0===l&&"undefined"!=typeof PointerEvent&&document.addEventListener("pointerup",c),l++,()=>{--l>0||"undefined"==typeof PointerEvent||document.removeEventListener("pointerup",c)}}function d(e){let{onHoverStart:t,onHoverChange:n,onHoverEnd:l,isDisabled:c}=e,[d,f]=(0,u.useState)(!1),v=(0,u.useRef)({isHovered:!1,ignoreEmulatedMouseEvents:!1,pointerType:"",target:null}).current;(0,u.useEffect)(s,[]);let{addGlobalListener:p,removeAllGlobalListeners:g}=(0,r.x)(),{hoverProps:m,triggerHoverEnd:h}=(0,u.useMemo)(()=>{let e=(e,u)=>{if(v.pointerType=u,c||"touch"===u||v.isHovered||!e.currentTarget.contains(e.target))return;v.isHovered=!0;let a=e.currentTarget;v.target=a,p((0,o.r3)(e.target),"pointerover",e=>{v.isHovered&&v.target&&!(0,i.bE)(v.target,e.target)&&r(e,e.pointerType)},{capture:!0}),t&&t({type:"hoverstart",target:a,pointerType:u}),n&&n(!0),f(!0)},r=(e,t)=>{let r=v.target;v.pointerType="",v.target=null,"touch"!==t&&v.isHovered&&r&&(v.isHovered=!1,g(),l&&l({type:"hoverend",target:r,pointerType:t}),n&&n(!1),f(!1))},u={};return"undefined"!=typeof PointerEvent&&(u.onPointerEnter=t=>{a&&"mouse"===t.pointerType||e(t,t.pointerType)},u.onPointerLeave=e=>{!c&&e.currentTarget.contains(e.target)&&r(e,e.pointerType)}),{hoverProps:u,triggerHoverEnd:r}},[t,n,l,c,v,p,g]);return(0,u.useEffect)(()=>{c&&h({currentTarget:v.target},v.pointerType)},[c]),{hoverProps:m,isHovered:d}}},26428:function(e,t,n){function r(e,t){return!!t&&!!e&&e.contains(t)}n.d(t,{vY:function(){return o},NI:function(){return i},bE:function(){return r}}),n(18064);let o=(e=document)=>e.activeElement;function i(e){return e.target}},18064:function(e,t,n){n.d(t,{Zq:function(){return i},kR:function(){return o},r3:function(){return r}});let r=e=>{var t;return null!==(t=null==e?void 0:e.ownerDocument)&&void 0!==t?t:document},o=e=>e&&"window"in e&&e.window===e?e:r(e).defaultView||window;function i(e){return null!==e&&"object"==typeof e&&"nodeType"in e&&"number"==typeof e.nodeType&&e.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&"host"in e}},66852:function(e,t,n){n.d(t,{x:function(){return o}});var r=n(2265);function o(){let e=(0,r.useRef)(new Map),t=(0,r.useCallback)((t,n,r,o)=>{let i=(null==o?void 0:o.once)?(...t)=>{e.current.delete(r),r(...t)}:r;e.current.set(r,{type:n,eventTarget:t,fn:i,options:o}),t.addEventListener(n,i,o)},[]),n=(0,r.useCallback)((t,n,r,o)=>{var i;let u=(null===(i=e.current.get(r))||void 0===i?void 0:i.fn)||r;t.removeEventListener(n,u,o),e.current.delete(r)},[]),o=(0,r.useCallback)(()=>{e.current.forEach((e,t)=>{n(e.eventTarget,e.type,t,e.options)})},[n]);return(0,r.useEffect)(()=>o,[o]),{addGlobalListener:t,removeGlobalListener:n,removeAllGlobalListeners:o}}},52724:function(e,t,n){let r;n.d(t,{R:function(){return o}});var o=((r=o||{}).Space=" ",r.Enter="Enter",r.Escape="Escape",r.Backspace="Backspace",r.Delete="Delete",r.ArrowLeft="ArrowLeft",r.ArrowUp="ArrowUp",r.ArrowRight="ArrowRight",r.ArrowDown="ArrowDown",r.Home="Home",r.End="End",r.PageUp="PageUp",r.PageDown="PageDown",r.Tab="Tab",r)},66797:function(e,t,n){n.d(t,{x:function(){return a}});var r=n(2265),o=n(5664),i=n(59456),u=n(93980);function a(){let{disabled:e=!1}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=(0,r.useRef)(null),[n,a]=(0,r.useState)(!1),l=(0,i.G)(),c=(0,u.z)(()=>{t.current=null,a(!1),l.dispose()}),s=(0,u.z)(e=>{if(l.dispose(),null===t.current){t.current=e.currentTarget,a(!0);{let n=(0,o.r)(e.currentTarget);l.addEventListener(n,"pointerup",c,!1),l.addEventListener(n,"pointermove",e=>{if(t.current){var n,r;let o,i;a((o=e.width/2,i=e.height/2,n={top:e.clientY-i,right:e.clientX+o,bottom:e.clientY+i,left:e.clientX-o},r=t.current.getBoundingClientRect(),!(!n||!r||n.rightr.right||n.bottomr.bottom)))}},!1),l.addEventListener(n,"pointercancel",c,!1)}}});return{pressed:n,pressProps:e?{}:{onPointerDown:s,onPointerUp:c,onClick:c}}}},59456:function(e,t,n){n.d(t,{G:function(){return i}});var r=n(2265),o=n(36933);function i(){let[e]=(0,r.useState)(o.k);return(0,r.useEffect)(()=>()=>e.dispose(),[e]),e}},93980:function(e,t,n){n.d(t,{z:function(){return i}});var r=n(2265),o=n(43507);let i=function(e){let t=(0,o.E)(e);return r.useCallback(function(){for(var e=arguments.length,n=Array(e),r=0;r{o.O.isServer?(0,r.useEffect)(e,t):(0,r.useLayoutEffect)(e,t)}},43507:function(e,t,n){n.d(t,{E:function(){return i}});var r=n(2265),o=n(73389);function i(e){let t=(0,r.useRef)(e);return(0,o.e)(()=>{t.current=e},[e]),t}},65573:function(e,t,n){n.d(t,{f:function(){return o}});var r=n(2265);function o(e,t){return(0,r.useMemo)(()=>{var n;if(e.type)return e.type;let r=null!=(n=e.as)?n:"button";if("string"==typeof r&&"button"===r.toLowerCase()||(null==t?void 0:t.tagName)==="BUTTON"&&!t.hasAttribute("type"))return"button"},[e.type,e.as,t])}},67561:function(e,t,n){n.d(t,{T:function(){return a},h:function(){return u}});var r=n(2265),o=n(93980);let i=Symbol();function u(e){let t=!(arguments.length>1)||void 0===arguments[1]||arguments[1];return Object.assign(e,{[i]:t})}function a(){for(var e=arguments.length,t=Array(e),n=0;n{u.current=t},[t]);let a=(0,o.z)(e=>{for(let t of u.current)null!=t&&("function"==typeof t?t(e):t.current=e)});return t.every(e=>null==e||(null==e?void 0:e[i]))?void 0:a}},65639:function(e,t,n){let r;n.d(t,{_:function(){return u},x:function(){return i}});var o=n(38929),i=((r=i||{})[r.None=1]="None",r[r.Focusable=2]="Focusable",r[r.Hidden=4]="Hidden",r);let u=(0,o.yV)(function(e,t){var n;let{features:r=1,...i}=e,u={ref:t,"aria-hidden":(2&r)==2||(null!=(n=i["aria-hidden"])?n:void 0),hidden:(4&r)==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&r)==4&&(2&r)!=2&&{display:"none"}}};return(0,o.L6)()({ourProps:u,theirProps:i,slot:{},defaultTag:"span",name:"Hidden"})})},95504:function(e,t,n){n.d(t,{A:function(){return r}});function r(){for(var e=arguments.length,t=Array(e),n=0;n"string"==typeof e?e.split(" "):[]))).filter(Boolean).join(" ")}},36933:function(e,t,n){n.d(t,{k:function(){return function e(){let t=[],n={addEventListener:(e,t,r,o)=>(e.addEventListener(t,r,o),n.add(()=>e.removeEventListener(t,r,o))),requestAnimationFrame(){for(var e=arguments.length,t=Array(e),r=0;rcancelAnimationFrame(o))},nextFrame(){for(var e=arguments.length,t=Array(e),r=0;rn.requestAnimationFrame(...t))},setTimeout(){for(var e=arguments.length,t=Array(e),r=0;rclearTimeout(o))},microTask(){for(var e=arguments.length,t=Array(e),o=0;o{i.current&&t[0]()}),n.add(()=>{i.current=!1})},style(e,t,n){let r=e.style.getPropertyValue(t);return Object.assign(e.style,{[t]:n}),this.add(()=>{Object.assign(e.style,{[t]:r})})},group(t){let n=e();return t(n),this.add(()=>n.dispose())},add:e=>(t.includes(e)||t.push(e),()=>{let n=t.indexOf(e);if(n>=0)for(let e of t.splice(n,1))e()}),dispose(){for(let e of t.splice(0))e()}};return n}}});var r=n(24310)},60415:function(e,t,n){n.d(t,{O:function(){return a}});var r=Object.defineProperty,o=(e,t,n)=>t in e?r(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,i=(e,t,n)=>(o(e,"symbol"!=typeof t?t+"":t,n),n);class u{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"undefined"==typeof window||"undefined"==typeof document?"server":"client"}handoff(){"pending"===this.handoffState&&(this.handoffState="complete")}get isHandoffComplete(){return"complete"===this.handoffState}constructor(){i(this,"current",this.detect()),i(this,"handoffState","pending"),i(this,"currentId",0)}}let a=new u},93698:function(e,t,n){let r,o,i,u,a;n.d(t,{EO:function(){return E},GO:function(){return g},TO:function(){return f},fE:function(){return v},jA:function(){return w},sP:function(){return h},tJ:function(){return m},z2:function(){return b}});var l=n(72468),c=n(5664);let s=["[contentEditable=true]","[tabindex]","a[href]","area[href]","button:not([disabled])","iframe","input:not([disabled])","select:not([disabled])","textarea:not([disabled])"].map(e=>"".concat(e,":not([tabindex='-1'])")).join(","),d=["[data-autofocus]"].map(e=>"".concat(e,":not([tabindex='-1'])")).join(",");var f=((r=f||{})[r.First=1]="First",r[r.Previous=2]="Previous",r[r.Next=4]="Next",r[r.Last=8]="Last",r[r.WrapAround=16]="WrapAround",r[r.NoScroll=32]="NoScroll",r[r.AutoFocus=64]="AutoFocus",r),v=((o=v||{})[o.Error=0]="Error",o[o.Overflow=1]="Overflow",o[o.Success=2]="Success",o[o.Underflow=3]="Underflow",o),p=((i=p||{})[i.Previous=-1]="Previous",i[i.Next=1]="Next",i);function g(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:document.body;return null==e?[]:Array.from(e.querySelectorAll(s)).sort((e,t)=>Math.sign((e.tabIndex||Number.MAX_SAFE_INTEGER)-(t.tabIndex||Number.MAX_SAFE_INTEGER)))}var m=((u=m||{})[u.Strict=0]="Strict",u[u.Loose=1]="Loose",u);function h(e){var t;let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return e!==(null==(t=(0,c.r)(e))?void 0:t.body)&&(0,l.E)(n,{0:()=>e.matches(s),1(){let t=e;for(;null!==t;){if(t.matches(s))return!0;t=t.parentElement}return!1}})}var y=((a=y||{})[a.Keyboard=0]="Keyboard",a[a.Mouse=1]="Mouse",a);function b(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:e=>e;return e.slice().sort((e,n)=>{let r=t(e),o=t(n);if(null===r||null===o)return 0;let i=r.compareDocumentPosition(o);return i&Node.DOCUMENT_POSITION_FOLLOWING?-1:i&Node.DOCUMENT_POSITION_PRECEDING?1:0})}function E(e,t){return w(g(),t,{relativeTo:e})}function w(e,t){var n,r,o;let{sorted:i=!0,relativeTo:u=null,skipElements:a=[]}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},l=Array.isArray(e)?e.length>0?e[0].ownerDocument:document:e.ownerDocument,c=Array.isArray(e)?i?b(e):e:64&t?function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:document.body;return null==e?[]:Array.from(e.querySelectorAll(d)).sort((e,t)=>Math.sign((e.tabIndex||Number.MAX_SAFE_INTEGER)-(t.tabIndex||Number.MAX_SAFE_INTEGER)))}(e):g(e);a.length>0&&c.length>1&&(c=c.filter(e=>!a.some(t=>null!=t&&"current"in t?(null==t?void 0:t.current)===e:t===e))),u=null!=u?u:l.activeElement;let s=(()=>{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(u))-1;if(4&t)return Math.max(0,c.indexOf(u))+1;if(8&t)return c.length-1;throw Error("Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last")})(),v=32&t?{preventScroll:!0}:{},p=0,m=c.length,h;do{if(p>=m||p+m<=0)return 0;let e=f+p;if(16&t)e=(e+m)%m;else{if(e<0)return 3;if(e>=m)return 1}null==(h=c[e])||h.focus(v),p+=s}while(h!==l.activeElement);return 6&t&&null!=(o=null==(r=null==(n=h)?void 0:n.matches)?void 0:r.call(n,"textarea,input"))&&o&&h.select(),2}"undefined"!=typeof window&&"undefined"!=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))},72468:function(e,t,n){n.d(t,{E:function(){return r}});function r(e,t){for(var n=arguments.length,o=Array(n>2?n-2:0),i=2;i'"'.concat(e,'"')).join(", "),"."));throw Error.captureStackTrace&&Error.captureStackTrace(u,r),u}},24310:function(e,t,n){n.d(t,{Y:function(){return r}});function r(e){"function"==typeof queueMicrotask?queueMicrotask(e):Promise.resolve().then(e).catch(e=>setTimeout(()=>{throw e}))}},5664:function(e,t,n){n.d(t,{r:function(){return o}});var r=n(60415);function o(e){return r.O.isServer?null:e instanceof Node?e.ownerDocument:null!=e&&e.hasOwnProperty("current")&&e.current instanceof Node?e.current.ownerDocument:document}},38929:function(e,t,n){let r,o;n.d(t,{L6:function(){return s},VN:function(){return l},dG:function(){return p},l4:function(){return c},oA:function(){return m},yV:function(){return g}});var i=n(2265),u=n(95504),a=n(72468),l=((r=l||{})[r.None=0]="None",r[r.RenderStrategy=1]="RenderStrategy",r[r.Static=2]="Static",r),c=((o=c||{})[o.Unmount=0]="Unmount",o[o.Hidden=1]="Hidden",o);function s(){let e,t;let n=(e=(0,i.useRef)([]),t=(0,i.useCallback)(t=>{for(let n of e.current)null!=n&&("function"==typeof n?n(t):n.current=t)},[]),function(){for(var n=arguments.length,r=Array(n),o=0;onull==e))return e.current=r,t});return(0,i.useCallback)(e=>(function(e){let{ourProps:t,theirProps:n,slot:r,defaultTag:o,features:i,visible:u=!0,name:l,mergeRefs:c}=e;c=null!=c?c:f;let s=v(n,t);if(u)return d(s,r,o,l,c);let p=null!=i?i:0;if(2&p){let{static:e=!1,...t}=s;if(e)return d(t,r,o,l,c)}if(1&p){let{unmount:e=!0,...t}=s;return(0,a.E)(e?0:1,{0:()=>null,1:()=>d({...t,hidden:!0,style:{display:"none"}},r,o,l,c)})}return d(s,r,o,l,c)})({mergeRefs:n,...e}),[n])}function d(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0,r=arguments.length>3?arguments[3]:void 0,o=arguments.length>4?arguments[4]:void 0,{as:a=n,children:l,refName:c="ref",...s}=h(e,["unmount","static"]),d=void 0!==e.ref?{[c]:e.ref}:{},f="function"==typeof l?l(t):l;"className"in s&&s.className&&"function"==typeof s.className&&(s.className=s.className(t)),s["aria-labelledby"]&&s["aria-labelledby"]===s.id&&(s["aria-labelledby"]=void 0);let p={};if(t){let e=!1,n=[];for(let[r,o]of Object.entries(t))"boolean"==typeof o&&(e=!0),!0===o&&n.push(r.replace(/([A-Z])/g,e=>"-".concat(e.toLowerCase())));if(e)for(let e of(p["data-headlessui-state"]=n.join(" "),n))p["data-".concat(e)]=""}if(a===i.Fragment&&(Object.keys(m(s)).length>0||Object.keys(m(p)).length>0)){if(!(0,i.isValidElement)(f)||Array.isArray(f)&&f.length>1){if(Object.keys(m(s)).length>0)throw Error(['Passing props on "Fragment"!',"","The current component <".concat(r,' /> is rendering a "Fragment".'),"However we need to passthrough the following props:",Object.keys(m(s)).concat(Object.keys(m(p))).map(e=>" - ".concat(e)).join("\n"),"","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=>" - ".concat(e)).join("\n")].join("\n"))}else{let e=f.props,t=null==e?void 0:e.className,n="function"==typeof t?function(){for(var e=arguments.length,n=Array(e),r=0;r="19"?f.props.ref:f.ref,d.ref)},n?{className:n}:{}))}}return(0,i.createElement)(a,Object.assign({},h(s,["ref"]),a!==i.Fragment&&d,a!==i.Fragment&&p),f)}function f(){for(var e=arguments.length,t=Array(e),n=0;nnull==e)?void 0:e=>{for(let n of t)null!=n&&("function"==typeof n?n(e):n.current=e)}}function v(){for(var e=arguments.length,t=Array(e),n=0;n{var t;return null==(t=null==e?void 0:e.preventDefault)?void 0:t.call(e)}]);for(let e in o)Object.assign(r,{[e](t){for(var n=arguments.length,r=Array(n>1?n-1:0),i=1;i1&&void 0!==arguments[1]?arguments[1]:[],n=Object.assign({},e);for(let e of t)e in n&&delete n[e];return n}}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/1658-2c9554a5b3840812.js b/litellm/proxy/_experimental/out/_next/static/chunks/1658-2c9554a5b3840812.js deleted file mode 100644 index 824c8bc9b96..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/1658-2c9554a5b3840812.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1658],{71658:function(e,l,t){t.d(l,{Z:function(){return l1}});var s=t(57437),a=t(19250),r=t(11713),i=t(90246),n=t(39760);let o=(0,i.n)("credentials"),d=()=>{let{accessToken:e}=(0,n.Z)();return(0,r.a)({queryKey:o.list({}),queryFn:async()=>await (0,a.credentialListCall)(e),enabled:!!e})},c=(0,i.n)("modelCostMap"),m=()=>(0,r.a)({queryKey:c.list({}),queryFn:async()=>await (0,a.modelCostMap)(),staleTime:6e4,gcTime:6e4});var u=t(52178),h=t(55584),x=t(47359),p=t(71594),g=t(24525),f=t(2265),j=t(19130),v=t(73705),_=t(5545),b=t(44633),y=t(86462),N=t(3837),w=t(49084);let Z=e=>{let{sortState:l,onSortChange:t}=e,a=[{key:"asc",label:"Ascending",icon:(0,s.jsx)(b.Z,{className:"h-4 w-4"})},{key:"desc",label:"Descending",icon:(0,s.jsx)(y.Z,{className:"h-4 w-4"})},{key:"reset",label:"Reset",icon:(0,s.jsx)(N.Z,{className:"h-4 w-4"})}];return(0,s.jsx)(v.Z,{menu:{items:a,onClick:e=>{let{key:l}=e;"asc"===l?t("asc"):"desc"===l?t("desc"):"reset"===l&&t(!1)},selectable:!0,selectedKeys:l?[l]:[]},trigger:["click"],autoAdjustOverflow:!0,children:(0,s.jsx)(_.ZP,{type:"text",onClick:e=>e.stopPropagation(),icon:"asc"===l?(0,s.jsx)(b.Z,{className:"h-4 w-4"}):"desc"===l?(0,s.jsx)(y.Z,{className:"h-4 w-4"}):(0,s.jsx)(w.Z,{className:"h-4 w-4"}),className:l?"text-blue-500 hover:text-blue-600":"text-gray-400 hover:text-blue-500"})})};function C(e){let{data:l=[],columns:t,isLoading:a=!1,sorting:r=[],onSortingChange:i,pagination:n,onPaginationChange:o,enablePagination:d=!1}=e,[c]=f.useState("onChange"),[m,u]=f.useState({}),[h,x]=f.useState({}),v=(0,p.b7)({data:l,columns:t,state:{sorting:r,columnSizing:m,columnVisibility:h,...d&&n?{pagination:n}:{}},columnResizeMode:c,onSortingChange:i,onColumnSizingChange:u,onColumnVisibilityChange:x,...d&&o?{onPaginationChange:o}:{},getCoreRowModel:(0,g.sC)(),...d?{getPaginationRowModel:(0,g.G_)()}:{},enableSorting:!0,enableColumnResizing:!0,manualSorting:!0,defaultColumn:{minSize:40,maxSize:500}});return(0,s.jsx)("div",{className:"rounded-lg custom-border relative",children:(0,s.jsx)("div",{className:"overflow-x-auto",children:(0,s.jsx)("div",{className:"relative min-w-full",children:(0,s.jsxs)(j.iA,{className:"[&_td]:py-2 [&_th]:py-2 w-full",children:[(0,s.jsx)(j.ss,{children:v.getHeaderGroups().map(e=>(0,s.jsx)(j.SC,{children:e.headers.map(e=>{var l;return(0,s.jsxs)(j.xs,{className:"py-1 h-8 relative ".concat("actions"===e.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)] w-[120px] ml-8":""," ").concat((null===(l=e.column.columnDef.meta)||void 0===l?void 0:l.className)||""),style:{width:"actions"===e.id?120:e.getSize(),position:"actions"===e.id?"sticky":"relative",right:"actions"===e.id?0:"auto"},children:[(0,s.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,s.jsx)("div",{className:"flex items-center",children:e.isPlaceholder?null:(0,p.ie)(e.column.columnDef.header,e.getContext())}),"actions"!==e.id&&e.column.getCanSort()&&i&&(0,s.jsx)(Z,{sortState:!1!==e.column.getIsSorted()&&e.column.getIsSorted(),onSortChange:l=>{!1===l?i([]):i([{id:e.column.id,desc:"desc"===l}])},columnId:e.column.id})]}),e.column.getCanResize()&&(0,s.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 ".concat(e.column.getIsResizing()?"bg-blue-500":"hover:bg-blue-200")})]},e.id)})},e.id))}),(0,s.jsx)(j.RM,{children:a?(0,s.jsx)(j.SC,{children:(0,s.jsx)(j.pj,{colSpan:t.length,className:"h-8 text-center",children:(0,s.jsx)("div",{className:"text-center text-gray-500",children:(0,s.jsx)("p",{children:"\uD83D\uDE85 Loading models..."})})})}):v.getRowModel().rows.length>0?v.getRowModel().rows.map(e=>(0,s.jsx)(j.SC,{children:e.getVisibleCells().map(e=>{var l;return(0,s.jsx)(j.pj,{className:"py-0.5 ".concat("actions"===e.column.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)] w-[120px] ml-8":""," ").concat((null===(l=e.column.columnDef.meta)||void 0===l?void 0:l.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,p.ie)(e.column.columnDef.cell,e.getContext())},e.id)})},e.id)):(0,s.jsx)(j.SC,{children:(0,s.jsx)(j.pj,{colSpan:t.length,className:"h-8 text-center",children:(0,s.jsx)("div",{className:"text-center text-gray-500",children:(0,s.jsx)("p",{children:"No models found"})})})})})]})})})})}var k=t(45589),S=t(74998),A=t(41649),E=t(78489),P=t(47323),M=t(99981),L=t(42673);let F=e=>{let{provider:l,className:t="w-4 h-4"}=e,[a,r]=(0,f.useState)(!1),{logo:i}=(0,L.dr)(l);return a||!i?(0,s.jsx)("div",{className:"".concat(t," rounded-full bg-gray-200 flex items-center justify-center text-xs"),children:(null==l?void 0:l.charAt(0))||"-"}):(0,s.jsx)("img",{src:i,alt:"".concat(l," logo"),className:t,onError:()=>r(!0)})},I=(e,l,t,a,r,i,n,o,d,c)=>[{header:()=>(0,s.jsx)("span",{className:"text-sm font-semibold",children:"Model ID"}),accessorKey:"model_info.id",enableSorting:!1,cell:e=>{let{row:l}=e,t=l.original;return(0,s.jsx)(M.Z,{title:t.model_info.id,children:(0,s.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:()=>a(t.model_info.id),children:t.model_info.id})})}},{header:()=>(0,s.jsx)("span",{className:"text-sm font-semibold",children:"Model Information"}),accessorKey:"model_name",size:250,cell:e=>{let{row:l}=e,t=l.original,a=i(l.original)||"-",r=(0,s.jsxs)("div",{children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("strong",{children:"Provider:"})," ",t.provider||"-"]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("strong",{children:"Public Model Name:"})," ",a]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("strong",{children:"LiteLLM Model Name:"})," ",t.litellm_model_name||"-"]})]});return(0,s.jsx)(M.Z,{title:r,children:(0,s.jsxs)("div",{className:"flex items-start space-x-2 min-w-0 w-full max-w-[250px]",children:[(0,s.jsx)("div",{className:"flex-shrink-0 mt-0.5",children:t.provider?(0,s.jsx)(F,{provider:t.provider}):(0,s.jsx)("div",{className:"w-4 h-4 rounded-full bg-gray-200 flex items-center justify-center text-xs",children:"-"})}),(0,s.jsxs)("div",{className:"flex flex-col min-w-0 flex-1",children:[(0,s.jsx)("div",{className:"text-xs font-medium text-gray-900 truncate max-w-[210px]",children:a}),(0,s.jsx)("div",{className:"text-xs text-gray-500 truncate mt-0.5 max-w-[210px]",children:t.litellm_model_name||"-"})]})]})})}},{header:()=>(0,s.jsx)("span",{className:"text-sm font-semibold",children:"Credentials"}),accessorKey:"litellm_credential_name",enableSorting:!1,size:180,cell:e=>{var l;let{row:t}=e,a=null===(l=t.original.litellm_params)||void 0===l?void 0:l.litellm_credential_name;return a?(0,s.jsx)(M.Z,{title:"Credential: ".concat(a),children:(0,s.jsxs)("div",{className:"flex items-center space-x-2 max-w-[180px]",children:[(0,s.jsx)(k.Z,{className:"w-4 h-4 text-blue-500 flex-shrink-0"}),(0,s.jsx)("span",{className:"text-xs truncate",title:a,children:a})]})}):(0,s.jsxs)("div",{className:"flex items-center space-x-2 max-w-[180px]",children:[(0,s.jsx)(k.Z,{className:"w-4 h-4 text-gray-300 flex-shrink-0"}),(0,s.jsx)("span",{className:"text-xs text-gray-400",children:"No credentials"})]})}},{header:()=>(0,s.jsx)("span",{className:"text-sm font-semibold",children:"Created By"}),accessorKey:"model_info.created_by",sortingFn:"datetime",size:160,cell:e=>{var l;let{row:t}=e,a=t.original,r=!(null===(l=a.model_info)||void 0===l?void 0:l.db_model),i=a.model_info.created_by,n=a.model_info.created_at?new Date(a.model_info.created_at).toLocaleDateString():null;return(0,s.jsxs)("div",{className:"flex flex-col min-w-0 max-w-[160px]",children:[(0,s.jsx)("div",{className:"text-xs font-medium text-gray-900 truncate",title:r?"Defined in config":i||"Unknown",children:r?"Defined in config":i||"Unknown"}),(0,s.jsx)("div",{className:"text-xs text-gray-500 truncate mt-0.5",title:r?"Config file":n||"Unknown date",children:r?"-":n||"Unknown date"})]})}},{header:()=>(0,s.jsx)("span",{className:"text-sm font-semibold",children:"Updated At"}),accessorKey:"model_info.updated_at",sortingFn:"datetime",cell:e=>{let{row:l}=e,t=l.original;return(0,s.jsx)("span",{className:"text-xs",children:t.model_info.updated_at?new Date(t.model_info.updated_at).toLocaleDateString():"-"})}},{header:()=>(0,s.jsx)("span",{className:"text-sm font-semibold",children:"Costs"}),accessorKey:"input_cost",size:120,cell:e=>{let{row:l}=e,t=l.original,a=t.input_cost,r=t.output_cost;return a||r?(0,s.jsx)(M.Z,{title:"Cost per 1M tokens",children:(0,s.jsxs)("div",{className:"flex flex-col min-w-0 max-w-[120px]",children:[a&&(0,s.jsxs)("div",{className:"text-xs font-medium text-gray-900 truncate",children:["In: $",a]}),r&&(0,s.jsxs)("div",{className:"text-xs text-gray-500 truncate mt-0.5",children:["Out: $",r]})]})}):(0,s.jsx)("div",{className:"max-w-[120px]",children:(0,s.jsx)("span",{className:"text-xs text-gray-400",children:"-"})})}},{header:()=>(0,s.jsx)("span",{className:"text-sm font-semibold",children:"Team ID"}),accessorKey:"model_info.team_id",enableSorting:!1,cell:e=>{let{row:l}=e,t=l.original;return t.model_info.team_id?(0,s.jsx)("div",{className:"overflow-hidden",children:(0,s.jsx)(M.Z,{title:t.model_info.team_id,children:(0,s.jsxs)(E.Z,{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:()=>r(t.model_info.team_id),children:[t.model_info.team_id.slice(0,7),"..."]})})}):"-"}},{header:()=>(0,s.jsx)("span",{className:"text-sm font-semibold",children:"Model Access Group"}),accessorKey:"model_info.model_access_group",enableSorting:!1,cell:e=>{let{row:l}=e,t=l.original,a=t.model_info.access_groups;if(!a||0===a.length)return"-";let r=t.model_info.id,i=d.has(r),n=a.length>1,o=()=>{let e=new Set(d);i?e.delete(r):e.add(r),c(e)};return(0,s.jsxs)("div",{className:"flex items-center gap-1 overflow-hidden",children:[(0,s.jsx)(A.Z,{size:"xs",color:"blue",className:"text-xs px-1.5 py-0.5 h-5 leading-tight flex-shrink-0",children:a[0]}),(i||!n&&2===a.length)&&a.slice(1).map((e,l)=>(0,s.jsx)(A.Z,{size:"xs",color:"blue",className:"text-xs px-1.5 py-0.5 h-5 leading-tight flex-shrink-0",children:e},l+1)),n&&(0,s.jsx)("button",{onClick:e=>{e.stopPropagation(),o()},className:"text-xs text-blue-600 hover:text-blue-800 px-1 py-0.5 rounded hover:bg-blue-50 h-5 leading-tight flex-shrink-0 whitespace-nowrap",children:i?"−":"+".concat(a.length-1)})]})}},{header:()=>(0,s.jsx)("span",{className:"text-sm font-semibold",children:"Status"}),accessorKey:"model_info.db_model",cell:e=>{let{row:l}=e,t=l.original;return(0,s.jsx)("div",{className:"\n inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium\n ".concat(t.model_info.db_model?"bg-blue-50 text-blue-600":"bg-gray-100 text-gray-600","\n "),children:t.model_info.db_model?"DB Model":"Config Model"})}},{id:"actions",header:()=>(0,s.jsx)("span",{className:"text-sm font-semibold",children:"Actions"}),cell:t=>{var r,i;let{row:n}=t,o=n.original,d="Admin"===e||(null===(r=o.model_info)||void 0===r?void 0:r.created_by)===l,c=!(null===(i=o.model_info)||void 0===i?void 0:i.db_model);return(0,s.jsx)("div",{className:"flex items-center justify-end gap-2 pr-4",children:c?(0,s.jsx)(M.Z,{title:"Config model cannot be deleted on the dashboard. Please delete it from the config file.",children:(0,s.jsx)(P.Z,{icon:S.Z,size:"sm",className:"opacity-50 cursor-not-allowed"})}):(0,s.jsx)(M.Z,{title:"Delete model",children:(0,s.jsx)(P.Z,{icon:S.Z,size:"sm",onClick:()=>{d&&a(o.model_info.id)},className:d?"cursor-pointer hover:text-red-600":"opacity-50 cursor-not-allowed"})})})}}],T=e=>{var l;return(null==e?void 0:null===(l=e.model_info)||void 0===l?void 0:l.team_public_model_name)?e.model_info.team_public_model_name:(null==e?void 0:e.model_name)||"-"};var R=t(15424),O=t(67101),V=t(27281),q=t(57365),z=t(29706),D=t(84264),B=t(50337),G=t(10353),U=t(7310),H=t.n(U);let K=(e,l)=>{if(!(null==e?void 0:e.data))return{data:[]};let t=JSON.parse(JSON.stringify(e.data));for(let e=0;e{let[l]=e;return"model"!==l&&"api_base"!==l}))),t[e].provider=c,t[e].input_cost=m,t[e].output_cost=u,t[e].litellm_model_name=n,t[e].input_cost&&(t[e].input_cost=(1e6*Number(t[e].input_cost)).toFixed(2)),t[e].output_cost&&(t[e].output_cost=(1e6*Number(t[e].output_cost)).toFixed(2)),t[e].max_tokens=h,t[e].max_input_tokens=x,t[e].api_base=null==i?void 0:null===(r=i.litellm_params)||void 0===r?void 0:r.api_base,t[e].cleanedLitellmParams=p}return{data:t}};var J=e=>{let{selectedModelGroup:l,setSelectedModelGroup:t,availableModelGroups:a,availableModelAccessGroups:r,setSelectedModelId:i,setSelectedTeamId:o}=e,{data:d,isLoading:c}=m(),{userId:h,userRole:p,premiumUser:g}=(0,n.Z)(),{data:j,isLoading:v}=(0,x.y2)(),[_,b]=(0,f.useState)(""),[y,N]=(0,f.useState)(""),[w,Z]=(0,f.useState)("current_team"),[k,S]=(0,f.useState)("personal"),[A,E]=(0,f.useState)(!1),[P,M]=(0,f.useState)(null),[L,F]=(0,f.useState)(new Set),[U,J]=(0,f.useState)(1),[W]=(0,f.useState)(50),[Y,$]=(0,f.useState)({pageIndex:0,pageSize:50}),[X,Q]=(0,f.useState)([]),ee=(0,f.useMemo)(()=>H()(e=>{N(e),J(1),$(e=>({...e,pageIndex:0}))},200),[]);(0,f.useEffect)(()=>(ee(_),()=>{ee.cancel()}),[_,ee]);let el="personal"===k?void 0:k.team_id,et=(0,f.useMemo)(()=>{if(0===X.length)return;let e=X[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},[X]),es=(0,f.useMemo)(()=>{if(0!==X.length)return X[0].desc?"desc":"asc"},[X]),{data:ea,isLoading:er}=(0,u.XP)(U,W,y||void 0,void 0,el,et,es),ei=er||c,en=e=>null!=d&&"object"==typeof d&&e in d?d[e].litellm_provider:"openai",eo=(0,f.useMemo)(()=>ea?K(ea,en):{data:[]},[ea,d]),ed=(0,f.useMemo)(()=>{var e,l,t,s;return ea?{total_count:null!==(e=ea.total_count)&&void 0!==e?e:0,current_page:null!==(l=ea.current_page)&&void 0!==l?l:1,total_pages:null!==(t=ea.total_pages)&&void 0!==t?t:1,size:null!==(s=ea.size)&&void 0!==s?s:W}:{total_count:0,current_page:1,total_pages:1,size:W}},[ea,W]),ec=(0,f.useMemo)(()=>eo&&eo.data&&0!==eo.data.length?eo.data.filter(e=>{var t,s;let a="all"===l||e.model_name===l||!l||"wildcard"===l&&(null===(t=e.model_name)||void 0===t?void 0:t.includes("*")),r="all"===P||(null===(s=e.model_info.access_groups)||void 0===s?void 0:s.includes(P))||!P;return a&&r}):[],[eo,l,P]);return(0,f.useEffect)(()=>{$(e=>({...e,pageIndex:0})),J(1)},[l,P]),(0,f.useEffect)(()=>{J(1),$(e=>({...e,pageIndex:0}))},[el]),(0,f.useEffect)(()=>{J(1),$(e=>({...e,pageIndex:0}))},[X]),(0,s.jsx)(z.Z,{children:(0,s.jsx)(O.Z,{children:(0,s.jsx)("div",{className:"flex flex-col space-y-4",children:(0,s.jsxs)("div",{className:"bg-white rounded-lg shadow",children:[(0,s.jsxs)("div",{className:"border-b px-6 py-4 bg-gray-50",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between",children:[(0,s.jsxs)("div",{className:"flex items-center gap-4",children:[(0,s.jsx)(D.Z,{className:"text-lg font-semibold text-gray-900",children:"Current Team:"}),ei?(0,s.jsx)(B.Z.Input,{active:!0,style:{width:320,height:36}}):(0,s.jsxs)(V.Z,{className:"w-80",defaultValue:"personal",value:"personal"===k?"personal":k.team_id,onValueChange:e=>{if("personal"===e)S("personal"),J(1),$(e=>({...e,pageIndex:0}));else{let l=null==j?void 0:j.find(l=>l.team_id===e);l&&(S(l),J(1),$(e=>({...e,pageIndex:0})))}},children:[(0,s.jsx)(q.Z,{value:"personal",children:(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("div",{className:"w-2 h-2 bg-blue-500 rounded-full"}),(0,s.jsx)("span",{className:"font-medium",children:"Personal"})]})}),v?(0,s.jsx)(q.Z,{value:"loading",children:(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)(G.Z,{size:"small"}),(0,s.jsx)("span",{className:"font-medium text-gray-500",children:"Loading teams..."})]})}):null==j?void 0:j.filter(e=>e.team_id).map(e=>(0,s.jsx)(q.Z,{value:e.team_id,children:(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("div",{className:"w-2 h-2 bg-green-500 rounded-full"}),(0,s.jsx)("span",{className:"font-medium",children:e.team_alias?"".concat(e.team_alias.slice(0,30),"..."):"Team ".concat(e.team_id.slice(0,30),"...")})]})},e.team_id))]})]}),(0,s.jsxs)("div",{className:"flex items-center gap-4",children:[(0,s.jsx)(D.Z,{className:"text-lg font-semibold text-gray-900",children:"View:"}),ei?(0,s.jsx)(B.Z.Input,{active:!0,style:{width:256,height:36}}):(0,s.jsxs)(V.Z,{className:"w-64",defaultValue:"current_team",value:w,onValueChange:e=>Z(e),children:[(0,s.jsx)(q.Z,{value:"current_team",children:(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("div",{className:"w-2 h-2 bg-purple-500 rounded-full"}),(0,s.jsx)("span",{className:"font-medium",children:"Current Team Models"})]})}),(0,s.jsx)(q.Z,{value:"all",children:(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("div",{className:"w-2 h-2 bg-gray-500 rounded-full"}),(0,s.jsx)("span",{className:"font-medium",children:"All Available Models"})]})})]})]})]}),"current_team"===w&&(0,s.jsxs)("div",{className:"flex items-start gap-2 mt-3",children:[(0,s.jsx)(R.Z,{className:"text-gray-400 mt-0.5 flex-shrink-0 text-xs"}),(0,s.jsx)("div",{className:"text-xs text-gray-500",children:"personal"===k?(0,s.jsxs)("span",{children:["To access these models: Create a Virtual Key without selecting a team on the"," ",(0,s.jsx)("a",{href:"/public?login=success&page=api-keys",className:"text-gray-600 hover:text-gray-800 underline",children:"Virtual Keys page"})]}):(0,s.jsxs)("span",{children:['To access these models: Create a Virtual Key and select Team as "',"string"!=typeof k?k.team_alias||k.team_id:"",'" on the'," ",(0,s.jsx)("a",{href:"/public?login=success&page=api-keys",className:"text-gray-600 hover:text-gray-800 underline",children:"Virtual Keys page"})]})})]})]}),(0,s.jsx)("div",{className:"border-b px-6 py-4",children:(0,s.jsxs)("div",{className:"flex flex-col space-y-4",children:[(0,s.jsxs)("div",{className:"flex flex-wrap items-center gap-3",children:[(0,s.jsxs)("div",{className:"relative w-64",children:[(0,s.jsx)("input",{type:"text",placeholder:"Search model names...",className:"w-full px-3 py-2 pl-8 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",value:_,onChange:e=>b(e.target.value)}),(0,s.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,s.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,s.jsxs)("button",{className:"px-3 py-2 text-sm border rounded-md hover:bg-gray-50 flex items-center gap-2 ".concat(A?"bg-gray-100":""),onClick:()=>E(!A),children:[(0,s.jsx)("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,s.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,s.jsxs)("button",{className:"px-3 py-2 text-sm border rounded-md hover:bg-gray-50 flex items-center gap-2",onClick:()=>{b(""),t("all"),M(null),S("personal"),Z("current_team"),J(1),$({pageIndex:0,pageSize:50}),Q([])},children:[(0,s.jsx)("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,s.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"]})]}),A&&(0,s.jsxs)("div",{className:"flex flex-wrap items-center gap-3 mt-3",children:[(0,s.jsx)("div",{className:"w-64",children:(0,s.jsxs)(V.Z,{value:null!=l?l:"all",onValueChange:e=>t("all"===e?"all":e),placeholder:"Filter by Public Model Name",children:[(0,s.jsx)(q.Z,{value:"all",children:"All Models"}),(0,s.jsx)(q.Z,{value:"wildcard",children:"Wildcard Models (*)"}),a.map((e,l)=>(0,s.jsx)(q.Z,{value:e,children:e},l))]})}),(0,s.jsx)("div",{className:"w-64",children:(0,s.jsxs)(V.Z,{value:null!=P?P:"all",onValueChange:e=>M("all"===e?null:e),placeholder:"Filter by Model Access Group",children:[(0,s.jsx)(q.Z,{value:"all",children:"All Model Access Groups"}),r.map((e,l)=>(0,s.jsx)(q.Z,{value:e,children:e},l))]})})]}),(0,s.jsxs)("div",{className:"flex justify-between items-center",children:[ei?(0,s.jsx)(B.Z.Input,{active:!0,style:{width:184,height:20}}):(0,s.jsx)("span",{className:"text-sm text-gray-700",children:ed.total_count>0?"Showing ".concat((U-1)*W+1," - ").concat(Math.min(U*W,ed.total_count)," of ").concat(ed.total_count," results"):"Showing 0 results"}),(0,s.jsxs)("div",{className:"flex items-center space-x-2",children:[ei?(0,s.jsx)(B.Z.Button,{active:!0,style:{width:84,height:30}}):(0,s.jsx)("button",{onClick:()=>{J(U-1),$(e=>({...e,pageIndex:0}))},disabled:1===U,className:"px-3 py-1 text-sm border rounded-md ".concat(1===U?"bg-gray-100 text-gray-400 cursor-not-allowed":"hover:bg-gray-50"),children:"Previous"}),ei?(0,s.jsx)(B.Z.Button,{active:!0,style:{width:56,height:30}}):(0,s.jsx)("button",{onClick:()=>{J(U+1),$(e=>({...e,pageIndex:0}))},disabled:U>=ed.total_pages,className:"px-3 py-1 text-sm border rounded-md ".concat(U>=ed.total_pages?"bg-gray-100 text-gray-400 cursor-not-allowed":"hover:bg-gray-50"),children:"Next"})]})]})]})}),(0,s.jsx)(C,{columns:I(p,h,g,i,o,T,()=>{},()=>{},L,F),data:ec,isLoading:er,sorting:X,onSortingChange:Q,pagination:Y,onPaginationChange:$,enablePagination:!0})]})})})})},W=t(96761),Y=t(19015);let $={"BadRequestError (400)":"BadRequestErrorRetries","AuthenticationError (401)":"AuthenticationErrorRetries","TimeoutError (408)":"TimeoutErrorRetries","RateLimitError (429)":"RateLimitErrorRetries","ContentPolicyViolationError (400)":"ContentPolicyViolationErrorRetries","InternalServerError (500)":"InternalServerErrorRetries"};var X=e=>{let{selectedModelGroup:l,setSelectedModelGroup:t,availableModelGroups:a,globalRetryPolicy:r,setGlobalRetryPolicy:i,defaultRetry:n,modelGroupRetryPolicy:o,setModelGroupRetryPolicy:d,handleSaveRetrySettings:c}=e;return(0,s.jsxs)(z.Z,{children:[(0,s.jsx)("div",{className:"flex items-center gap-4 mb-6",children:(0,s.jsxs)("div",{className:"flex items-center",children:[(0,s.jsx)(D.Z,{children:"Retry Policy Scope:"}),(0,s.jsxs)(V.Z,{className:"ml-2 w-48",defaultValue:"global",value:"global"===l?"global":l||a[0],onValueChange:e=>t(e),children:[(0,s.jsx)(q.Z,{value:"global",children:"Global Default"}),a.map((e,l)=>(0,s.jsx)(q.Z,{value:e,onClick:()=>t(e),children:e},l))]})]})}),"global"===l?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(W.Z,{children:"Global Retry Policy"}),(0,s.jsx)(D.Z,{className:"mb-6",children:"Default retry settings applied to all model groups unless overridden"})]}):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(W.Z,{children:["Retry Policy for ",l]}),(0,s.jsx)(D.Z,{className:"mb-6",children:"Model-specific retry settings. Falls back to global defaults if not set."})]}),$&&(0,s.jsx)("table",{children:(0,s.jsx)("tbody",{children:Object.entries($).map((e,t)=>{var a,c,m,u;let h,[x,p]=e;if("global"===l)h=null!==(a=null==r?void 0:r[p])&&void 0!==a?a:n;else{let e=null==o?void 0:null===(c=o[l])||void 0===c?void 0:c[p];h=null!=e?e:null!==(m=null==r?void 0:r[p])&&void 0!==m?m:n}return(0,s.jsxs)("tr",{className:"flex justify-between items-center mt-2",children:[(0,s.jsxs)("td",{children:[(0,s.jsx)(D.Z,{children:x}),"global"!==l&&(0,s.jsxs)(D.Z,{className:"text-xs text-gray-500 ml-2",children:["(Global: ",null!==(u=null==r?void 0:r[p])&&void 0!==u?u:n,")"]})]}),(0,s.jsx)("td",{children:(0,s.jsx)(Y.Z,{className:"ml-5",value:h,min:0,step:1,onChange:e=>{"global"===l?i(l=>null==e?l:{...null!=l?l:{},[p]:e}):d(t=>{var s;let a=null!==(s=null==t?void 0:t[l])&&void 0!==s?s:{};return{...null!=t?t:{},[l]:{...a,[p]:e}}})}})})]},t)})})}),(0,s.jsx)(E.Z,{className:"mt-6 mr-8",onClick:c,children:"Save"})]})},Q=t(57840),ee=t(58760),el=t(867),et=t(5945),es=t(3810),ea=t(22116),er=t(89245),ei=t(5540),en=t(8881),eo=t(9114);let{Text:ed}=Q.default;var ec=e=>{let{accessToken:l,onReloadSuccess:t,buttonText:r="Reload Price Data",showIcon:i=!0,size:n="middle",type:o="primary",className:d=""}=e,[c,m]=(0,f.useState)(!1),[u,h]=(0,f.useState)(!1),[x,p]=(0,f.useState)(!1),[g,j]=(0,f.useState)(!1),[v,b]=(0,f.useState)(6),[y,N]=(0,f.useState)(null),[w,Z]=(0,f.useState)(!1);(0,f.useEffect)(()=>{C();let e=setInterval(()=>{C()},3e4);return()=>clearInterval(e)},[l]);let C=async()=>{if(l){Z(!0);try{console.log("Fetching reload status...");let e=await (0,a.getModelCostMapReloadStatus)(l);console.log("Received status:",e),N(e)}catch(e){console.error("Failed to fetch reload status:",e),N({scheduled:!1,interval_hours:null,last_run:null,next_run:null})}finally{Z(!1)}}},k=async()=>{if(!l){eo.Z.fromBackend("No access token available");return}m(!0);try{let e=await (0,a.reloadModelCostMap)(l);"success"===e.status?(eo.Z.success("Price data reloaded successfully! ".concat(e.models_count||0," models updated.")),null==t||t(),await C()):eo.Z.fromBackend("Failed to reload price data")}catch(e){console.error("Error reloading price data:",e),eo.Z.fromBackend("Failed to reload price data. Please try again.")}finally{m(!1)}},S=async()=>{if(!l){eo.Z.fromBackend("No access token available");return}if(v<=0){eo.Z.fromBackend("Hours must be greater than 0");return}h(!0);try{let e=await (0,a.scheduleModelCostMapReload)(l,v);"success"===e.status?(eo.Z.success("Periodic reload scheduled for every ".concat(v," hours")),j(!1),await C()):eo.Z.fromBackend("Failed to schedule periodic reload")}catch(e){console.error("Error scheduling reload:",e),eo.Z.fromBackend("Failed to schedule periodic reload. Please try again.")}finally{h(!1)}},A=async()=>{if(!l){eo.Z.fromBackend("No access token available");return}p(!0);try{let e=await (0,a.cancelModelCostMapReload)(l);"success"===e.status?(eo.Z.success("Periodic reload cancelled successfully"),await C()):eo.Z.fromBackend("Failed to cancel periodic reload")}catch(e){console.error("Error cancelling reload:",e),eo.Z.fromBackend("Failed to cancel periodic reload. Please try again.")}finally{p(!1)}},E=e=>{if(!e)return"Never";try{return new Date(e).toLocaleString()}catch(l){return e}};return(0,s.jsxs)("div",{className:d,children:[(0,s.jsxs)(ee.Z,{direction:"horizontal",size:"middle",style:{marginBottom:16},children:[(0,s.jsx)(el.Z,{title:"Hard Refresh Price Data",description:"This will immediately fetch the latest pricing information from the remote source. Continue?",onConfirm:k,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,s.jsx)(_.ZP,{type:o,size:n,loading:c,icon:i?(0,s.jsx)(er.Z,{}):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:r})}),(null==y?void 0:y.scheduled)?(0,s.jsx)(_.ZP,{type:"default",size:n,danger:!0,icon:(0,s.jsx)(en.Z,{}),loading:x,onClick:A,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,s.jsx)(_.ZP,{type:"default",size:n,icon:(0,s.jsx)(ei.Z,{}),onClick:()=>j(!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"})]}),y&&(0,s.jsx)(et.Z,{size:"small",style:{backgroundColor:"#f8f9fa",border:"1px solid #e9ecef",borderRadius:8},children:(0,s.jsxs)(ee.Z,{direction:"vertical",size:"small",style:{width:"100%"},children:[y.scheduled?(0,s.jsx)("div",{children:(0,s.jsxs)(es.Z,{color:"green",icon:(0,s.jsx)(ei.Z,{}),children:["Scheduled every ",y.interval_hours," hours"]})}):(0,s.jsx)(ed,{type:"secondary",children:"No periodic reload scheduled"}),(0,s.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[(0,s.jsx)(ed,{type:"secondary",style:{fontSize:"12px"},children:"Last run:"}),(0,s.jsx)(ed,{style:{fontSize:"12px"},children:E(y.last_run)})]}),y.scheduled&&(0,s.jsxs)(s.Fragment,{children:[y.next_run&&(0,s.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[(0,s.jsx)(ed,{type:"secondary",style:{fontSize:"12px"},children:"Next run:"}),(0,s.jsx)(ed,{style:{fontSize:"12px"},children:E(y.next_run)})]}),(0,s.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[(0,s.jsx)(ed,{type:"secondary",style:{fontSize:"12px"},children:"Status:"}),(0,s.jsx)(es.Z,{color:(null==y?void 0:y.scheduled)?y.last_run?"success":"processing":"default",children:(null==y?void 0:y.scheduled)?y.last_run?"Active":"Ready":"Not scheduled"})]})]})]})}),(0,s.jsxs)(ea.Z,{title:"Set Up Periodic Reload",open:g,onOk:S,onCancel:()=>j(!1),confirmLoading:u,okText:"Schedule",cancelText:"Cancel",okButtonProps:{style:{backgroundColor:"#6366f1",borderColor:"#6366f1",color:"white"}},children:[(0,s.jsx)("div",{style:{marginBottom:16},children:(0,s.jsx)(ed,{children:"Set up automatic reload of price data every:"})}),(0,s.jsx)("div",{style:{marginBottom:16},children:(0,s.jsx)(Y.Z,{min:1,max:168,value:v,onChange:e=>b(e||6),addonAfter:"hours",style:{width:"100%"}})}),(0,s.jsx)("div",{children:(0,s.jsxs)(ed,{type:"secondary",children:["This will automatically fetch the latest pricing data from the remote source every ",v," hours."]})})]})]})},em=()=>{let{accessToken:e}=(0,n.Z)(),{refetch:l}=m();return(0,s.jsx)(z.Z,{children:(0,s.jsxs)("div",{className:"p-6",children:[(0,s.jsxs)("div",{className:"mb-6",children:[(0,s.jsx)(W.Z,{children:"Price Data Management"}),(0,s.jsx)(D.Z,{className:"text-tremor-content",children:"Manage model pricing data and configure automatic reload schedules"})]}),(0,s.jsx)(ec,{accessToken:e,onReloadSuccess:()=>{l()},buttonText:"Reload Price Data",size:"middle",type:"primary",className:"w-full"})]})})};let eu=async(e,l,t)=>{try{var s,a;console.log("handling submit for formValues:",e);let l=e.model_mappings||[];if("model_mappings"in e&&delete e.model_mappings,e.model&&e.model.includes("all-wildcard")){let t=e.custom_llm_provider,a=(null!==(s=L.fK[t])&&void 0!==s?s:t.toLowerCase())+"/*";e.model_name=a,l.push({public_name:a,litellm_model:a}),e.model=a}let t=[];for(let s of l){let l={},r={},i=s.public_name;for(let[t,i]of(l.model=s.litellm_model,e.input_cost_per_token&&(e.input_cost_per_token=Number(e.input_cost_per_token)/1e6),e.output_cost_per_token&&(e.output_cost_per_token=Number(e.output_cost_per_token)/1e6),l.model=s.litellm_model,console.log("formValues add deployment:",e),Object.entries(e)))if(""!==i&&"custom_pricing"!==t&&"pricing_model"!==t&&"cache_control"!==t){if("model_name"==t)l.model=i;else if("custom_llm_provider"==t){console.log("custom_llm_provider:",i);let e=null!==(a=L.fK[i])&&void 0!==a?a:i.toLowerCase();l.custom_llm_provider=e,console.log("custom_llm_provider mappingResult:",e)}else if("model"==t)continue;else if("base_model"===t)r[t]=i;else if("team_id"===t)r.team_id=i;else if("model_access_group"===t)r.access_groups=i;else if("mode"==t)console.log("placing mode in modelInfo"),r.mode=i,delete l.mode;else if("custom_model_name"===t)l.model=i;else if("litellm_extra_params"==t){console.log("litellm_extra_params:",i);let e={};if(i&&void 0!=i){try{e=JSON.parse(i)}catch(e){throw eo.Z.fromBackend("Failed to parse LiteLLM Extra Params: "+e),Error("Failed to parse litellm_extra_params: "+e)}for(let[t,s]of Object.entries(e))l[t]=s}}else if("model_info_params"==t){console.log("model_info_params:",i);let e={};if(i&&void 0!=i){try{e=JSON.parse(i)}catch(e){throw eo.Z.fromBackend("Failed to parse LiteLLM Extra Params: "+e),Error("Failed to parse litellm_extra_params: "+e)}for(let[l,t]of Object.entries(e))r[l]=t}}else if("input_cost_per_token"===t||"output_cost_per_token"===t||"input_cost_per_second"===t){i&&(l[t]=Number(i));continue}else l[t]=i}t.push({litellmParamsObj:l,modelInfoObj:r,modelName:i})}return t}catch(e){eo.Z.fromBackend("Failed to create model: "+e)}},eh=async(e,l,t,s)=>{try{let r=await eu(e,l,t);if(!r||0===r.length)return;for(let e of r){let{litellmParamsObj:t,modelInfoObj:s,modelName:r}=e,i={model_name:r,litellm_params:t,model_info:s},n=await (0,a.modelCreateCall)(l,i);console.log("response for model create call: ".concat(n.data))}s&&s(),t.resetFields()}catch(e){eo.Z.fromBackend("Failed to add model: "+e)}};var ex=t(53410),ep=t(62490),eg=t(10032),ef=t(21609),ej=t(31283),ev=t(37592);let e_=(0,i.n)("providerFields"),eb=()=>(0,r.a)({queryKey:e_.list({}),queryFn:async()=>await (0,a.getProviderCreateMetadata)(),staleTime:864e5,gcTime:864e5});var ey=t(3632),eN=t(56522),ew=t(47451),eZ=t(69410),eC=t(65319),ek=t(4260);let{Link:eS}=Q.default,eA=e=>{var l,t,s,a,r;let i="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:null!==(l=e.placeholder)&&void 0!==l?l:void 0,tooltip:null!==(t=e.tooltip)&&void 0!==t?t:void 0,required:null!==(s=e.required)&&void 0!==s&&s,type:i,options:null!==(a=e.options)&&void 0!==a?a:void 0,defaultValue:null!==(r=e.default_value)&&void 0!==r?r:void 0}},eE={};var eP=e=>{let{selectedProvider:l,uploadProps:t}=e,a=L.Cl[l],r=eg.Z.useFormInstance(),{data:i,isLoading:n,error:o}=eb(),d=f.useMemo(()=>{if(!i)return null;let e={};return i.forEach(l=>{let t=l.provider_display_name,s=l.credential_fields.map(eA);e[t]=s,l.provider&&(e[l.provider]=s),l.litellm_provider&&(e[l.litellm_provider]=s)}),e},[i]);f.useEffect(()=>{d&&Object.assign(eE,d)},[d]);let c=f.useMemo(()=>{var e;let t=null!==(e=eE[a])&&void 0!==e?e:eE[l];if(t)return t;if(!i)return[];let s=i.find(e=>e.provider_display_name===a||e.provider===l||e.litellm_provider===l);if(!s)return[];let r=s.credential_fields.map(eA);return eE[s.provider_display_name]=r,s.provider&&(eE[s.provider]=r),s.litellm_provider&&(eE[s.litellm_provider]=r),r},[a,l,i]),m={name:"file",accept:".json",beforeUpload:e=>{if("application/json"===e.type){let l=new FileReader;l.onload=e=>{if(e.target){let l=e.target.result;console.log("Setting field value from JSON, length: ".concat(l.length)),r.setFieldsValue({vertex_credentials:l}),console.log("Form values after setting:",r.getFieldsValue())}},l.readAsText(e)}return!1},onChange(e){console.log("Upload onChange triggered in ProviderSpecificFields"),console.log("Current form values:",r.getFieldsValue()),"uploading"!==e.file.status&&console.log(e.file,e.fileList)}};return(0,s.jsxs)(s.Fragment,{children:[n&&0===c.length&&(0,s.jsx)(ew.Z,{children:(0,s.jsx)(eZ.Z,{span:24,children:(0,s.jsx)(eN.x,{className:"mb-2",children:"Loading provider fields..."})})}),o&&0===c.length&&(0,s.jsx)(ew.Z,{children:(0,s.jsx)(eZ.Z,{span:24,children:(0,s.jsx)(eN.x,{className:"mb-2 text-red-500",children:o instanceof Error?o.message:"Failed to load provider credential fields"})})}),c.map(e=>{var l;return(0,s.jsxs)(f.Fragment,{children:[(0,s.jsx)(eg.Z.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,s.jsx)(ev.default,{placeholder:e.placeholder,defaultValue:e.defaultValue,children:null===(l=e.options)||void 0===l?void 0:l.map(e=>(0,s.jsx)(ev.default.Option,{value:e,children:e},e))}):"upload"===e.type?(0,s.jsx)(eC.default,{...m,onChange:l=>{(null==t?void 0:t.onChange)&&t.onChange(l),setTimeout(()=>{let l=r.getFieldValue(e.key);console.log("".concat(e.key," value after upload:"),JSON.stringify(l))},500)},children:(0,s.jsx)(_.ZP,{icon:(0,s.jsx)(ey.Z,{}),children:"Click to Upload"})}):"textarea"===e.type?(0,s.jsx)(ek.default.TextArea,{placeholder:e.placeholder,defaultValue:e.defaultValue,rows:6,style:{fontFamily:"monospace",fontSize:"12px"}}):(0,s.jsx)(eN.o,{placeholder:e.placeholder,type:"password"===e.type?"password":"text",defaultValue:e.defaultValue})}),"vertex_credentials"===e.key&&(0,s.jsx)(ew.Z,{children:(0,s.jsx)(eZ.Z,{children:(0,s.jsx)(eN.x,{className:"mb-3 mt-1",children:"Give a gcp service account(.json file)"})})}),"base_model"===e.key&&(0,s.jsxs)(ew.Z,{children:[(0,s.jsx)(eZ.Z,{span:10}),(0,s.jsx)(eZ.Z,{span:10,children:(0,s.jsxs)(eN.x,{className:"mb-2",children:["The actual model your azure deployment uses. Used for accurate cost tracking. Select name from"," ",(0,s.jsx)(eS,{href:"https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json",target:"_blank",children:"here"})]})})]})]},e.key)})]})};let{Link:eM}=Q.default;var eL=e=>{let{open:l,onCancel:t,onAddCredential:a,uploadProps:r}=e,[i]=eg.Z.useForm(),[n,o]=(0,f.useState)(L.Cl.OpenAI);return(0,s.jsx)(ea.Z,{title:"Add New Credential",open:l,onCancel:()=>{t(),i.resetFields()},footer:null,width:600,children:(0,s.jsxs)(eg.Z,{form:i,onFinish:e=>{a(Object.entries(e).reduce((e,l)=>{let[t,s]=l;return""!==s&&null!=s&&(e[t]=s),e},{})),i.resetFields()},layout:"vertical",children:[(0,s.jsx)(eg.Z.Item,{label:"Credential Name:",name:"credential_name",rules:[{required:!0,message:"Credential name is required"}],children:(0,s.jsx)(ej.o,{placeholder:"Enter a friendly name for these credentials"})}),(0,s.jsx)(eg.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"Helper to auto-populate provider specific fields",children:(0,s.jsx)(ev.default,{showSearch:!0,onChange:e=>{o(e),i.setFieldValue("custom_llm_provider",e)},children:Object.entries(L.Cl).map(e=>{let[l,t]=e;return(0,s.jsx)(ev.default.Option,{value:l,children:(0,s.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,s.jsx)("img",{src:L.cd[t],alt:"".concat(l," logo"),className:"w-5 h-5",onError:e=>{let l=e.target,s=l.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=t.charAt(0),s.replaceChild(e,l)}}}),(0,s.jsx)("span",{children:t})]})},l)})})}),(0,s.jsx)(eP,{selectedProvider:n,uploadProps:r}),(0,s.jsxs)("div",{className:"flex justify-between items-center",children:[(0,s.jsx)(M.Z,{title:"Get help on our github",children:(0,s.jsx)(eM,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})}),(0,s.jsxs)("div",{children:[(0,s.jsx)(_.ZP,{onClick:()=>{t(),i.resetFields()},style:{marginRight:10},children:"Cancel"}),(0,s.jsx)(_.ZP,{htmlType:"submit",children:"Add Credential"})]})]})]})})};let{Link:eF}=Q.default;function eI(e){let{open:l,onCancel:t,onUpdateCredential:a,uploadProps:r,existingCredential:i}=e,[n]=eg.Z.useForm(),[o,d]=(0,f.useState)(L.Cl.Anthropic);return(0,f.useEffect)(()=>{if(i){let e=Object.entries(i.credential_values||{}).reduce((e,l)=>{let[t,s]=l;return e[t]=null!=s?s:null,e},{});n.setFieldsValue({credential_name:i.credential_name,custom_llm_provider:i.credential_info.custom_llm_provider,...e}),d(i.credential_info.custom_llm_provider)}},[i]),(0,s.jsx)(ea.Z,{title:"Edit Credential",open:l,onCancel:()=>{t(),n.resetFields()},footer:null,width:600,destroyOnHidden:!0,children:(0,s.jsxs)(eg.Z,{form:n,onFinish:e=>{a(Object.entries(e).reduce((e,l)=>{let[t,s]=l;return""!==s&&null!=s&&(e[t]=s),e},{})),n.resetFields()},layout:"vertical",children:[(0,s.jsx)(eg.Z.Item,{label:"Credential Name:",name:"credential_name",rules:[{required:!0,message:"Credential name is required"}],initialValue:null==i?void 0:i.credential_name,children:(0,s.jsx)(ej.o,{placeholder:"Enter a friendly name for these credentials",disabled:null!=i&&!!i.credential_name})}),(0,s.jsx)(eg.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"Helper to auto-populate provider specific fields",children:(0,s.jsx)(ev.default,{showSearch:!0,onChange:e=>{d(e),n.setFieldValue("custom_llm_provider",e)},children:Object.entries(L.Cl).map(e=>{let[l,t]=e;return(0,s.jsx)(ev.default.Option,{value:l,children:(0,s.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,s.jsx)("img",{src:L.cd[t],alt:"".concat(l," logo"),className:"w-5 h-5",onError:e=>{let l=e.target,s=l.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=t.charAt(0),s.replaceChild(e,l)}}}),(0,s.jsx)("span",{children:t})]})},l)})})}),(0,s.jsx)(eP,{selectedProvider:o,uploadProps:r}),(0,s.jsxs)("div",{className:"flex justify-between items-center",children:[(0,s.jsx)(M.Z,{title:"Get help on our github",children:(0,s.jsx)(eF,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})}),(0,s.jsxs)("div",{children:[(0,s.jsx)(_.ZP,{onClick:()=>{t(),n.resetFields()},style:{marginRight:10},children:"Cancel"}),(0,s.jsx)(_.ZP,{htmlType:"submit",children:"Update Credential"})]})]})]})})}var eT=e=>{var l;let{uploadProps:t}=e,{accessToken:r}=(0,n.Z)(),{data:i,refetch:o}=d(),c=(null==i?void 0:i.credentials)||[],[m,u]=(0,f.useState)(!1),[h,x]=(0,f.useState)(!1),[p,g]=(0,f.useState)(null),[j,v]=(0,f.useState)(null),[_,b]=(0,f.useState)(!1),[y,N]=(0,f.useState)(!1),[w]=eg.Z.useForm(),Z=["credential_name","custom_llm_provider"],C=async e=>{if(!r)return;let l=Object.entries(e).filter(e=>{let[l]=e;return!Z.includes(l)}).reduce((e,l)=>{let[t,s]=l;return{...e,[t]:s}},{}),t={credential_name:e.credential_name,credential_values:l,credential_info:{custom_llm_provider:e.custom_llm_provider}};await (0,a.credentialUpdateCall)(r,e.credential_name,t),eo.Z.success("Credential updated successfully"),x(!1),await o()},k=async e=>{if(!r)return;let l=Object.entries(e).filter(e=>{let[l]=e;return!Z.includes(l)}).reduce((e,l)=>{let[t,s]=l;return{...e,[t]:s}},{}),t={credential_name:e.credential_name,credential_values:l,credential_info:{custom_llm_provider:e.custom_llm_provider}};await (0,a.credentialCreateCall)(r,t),eo.Z.success("Credential added successfully"),u(!1),await o()},A=e=>{let l={openai:"blue",azure:"indigo",anthropic:"purple",default:"gray"},t=l[e.toLowerCase()]||l.default;return(0,s.jsx)(ep.Ct,{color:t,size:"xs",children:e})},E=async()=>{if(r&&j){N(!0);try{await (0,a.credentialDeleteCall)(r,j.credential_name),eo.Z.success("Credential deleted successfully"),await o()}catch(e){eo.Z.error("Failed to delete credential")}finally{v(null),b(!1),N(!1)}}},P=e=>{v(e),b(!0)};return(0,s.jsxs)("div",{className:"w-full mx-auto flex-auto overflow-y-auto p-2",children:[(0,s.jsx)(ep.zx,{onClick:()=>u(!0),children:"Add Credential"}),(0,s.jsx)("div",{className:"flex justify-between items-center mt-4 mb-4",children:(0,s.jsx)(ep.xv,{children:"Configured credentials for different AI providers. Add and manage your API credentials."})}),(0,s.jsx)(ep.Zb,{children:(0,s.jsxs)(ep.iA,{children:[(0,s.jsx)(ep.ss,{children:(0,s.jsxs)(ep.SC,{children:[(0,s.jsx)(ep.xs,{children:"Credential Name"}),(0,s.jsx)(ep.xs,{children:"Provider"}),(0,s.jsx)(ep.xs,{children:"Actions"})]})}),(0,s.jsx)(ep.RM,{children:c&&0!==c.length?c.map((e,l)=>{var t;return(0,s.jsxs)(ep.SC,{children:[(0,s.jsx)(ep.pj,{children:e.credential_name}),(0,s.jsx)(ep.pj,{children:A((null===(t=e.credential_info)||void 0===t?void 0:t.custom_llm_provider)||"-")}),(0,s.jsxs)(ep.pj,{children:[(0,s.jsx)(ep.zx,{icon:ex.Z,variant:"light",size:"sm",onClick:()=>{g(e),x(!0)}}),(0,s.jsx)(ep.zx,{icon:S.Z,variant:"light",size:"sm",onClick:()=>P(e),className:"ml-2"})]})]},l)}):(0,s.jsx)(ep.SC,{children:(0,s.jsx)(ep.pj,{colSpan:4,className:"text-center py-4 text-gray-500",children:"No credentials configured"})})})]})}),m&&(0,s.jsx)(eL,{onAddCredential:k,open:m,onCancel:()=>u(!1),uploadProps:t}),h&&(0,s.jsx)(eI,{open:h,existingCredential:p,onUpdateCredential:C,uploadProps:t,onCancel:()=>x(!1)}),(0,s.jsx)(ef.Z,{isOpen:_,onCancel:()=>{v(null),b(!1)},onOk:E,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:null==j?void 0:j.credential_name},{label:"Provider",value:(null==j?void 0:null===(l=j.credential_info)||void 0===l?void 0:l.custom_llm_provider)||"-"}],confirmLoading:y,requiredConfirmation:null==j?void 0:j.credential_name})]})},eR=t(20347),eO=t(23628),eV=t(29827),eq=t(49804),ez=t(12485),eD=t(18135),eB=t(35242),eG=t(77991),eU=t(34419),eH=t(58643),eK=t(29),eJ=t.n(eK),eW=t(23496),eY=t(35291),e$=t(23639);let{Text:eX}=Q.default;var eQ=e=>{let{formValues:l,accessToken:t,testMode:r,modelName:i="this model",onClose:n,onTestComplete:o}=e,[d,c]=f.useState(null),[m,u]=f.useState(null),[h,x]=f.useState(null),[p,g]=f.useState(!0),[j,v]=f.useState(!1),[b,y]=f.useState(!1),N=async()=>{g(!0),y(!1),c(null),u(null),x(null),v(!1),await new Promise(e=>setTimeout(e,100));try{console.log("Testing connection with form values:",l);let r=await eu(l,t,null);if(!r){console.log("No result from prepareModelAddRequest"),c("Failed to prepare model data. Please check your form inputs."),v(!1),g(!1);return}console.log("Result from prepareModelAddRequest:",r);let{litellmParamsObj:i,modelInfoObj:n,modelName:o}=r[0],d=await (0,a.testConnectionRequest)(t,i,n,null==n?void 0:n.mode);if("success"===d.status)eo.Z.success("Connection test successful!"),c(null),v(!0);else{var e,s;let l=(null===(e=d.result)||void 0===e?void 0:e.error)||d.message||"Unknown error";c(l),u(i),x(null===(s=d.result)||void 0===s?void 0:s.raw_request_typed_dict),v(!1)}}catch(e){console.error("Test connection error:",e),c(e instanceof Error?e.message:String(e)),v(!1)}finally{g(!1),o&&o()}};f.useEffect(()=>{let e=setTimeout(()=>{N()},200);return()=>clearTimeout(e)},[]);let w=e=>e?e.split("stack trace:")[0].trim().replace(/^litellm\.(.*?)Error: /,""):"Unknown error",Z="string"==typeof d?w(d):(null==d?void 0:d.message)?w(d.message):"Unknown error",C=h?((e,l,t)=>{let s=JSON.stringify(l,null,2).split("\n").map(e=>" ".concat(e)).join("\n"),a=Object.entries(t).map(e=>{let[l,t]=e;return"-H '".concat(l,": ").concat(t,"'")}).join(" \\\n ");return"curl -X POST \\\n ".concat(e," \\\n ").concat(a?"".concat(a," \\\n "):"","-H 'Content-Type: application/json' \\\n -d '{\n").concat(s,"\n }'")})(h.raw_request_api_base,h.raw_request_body,h.raw_request_headers||{}):"";return(0,s.jsxs)("div",{style:{padding:"24px",borderRadius:"8px",backgroundColor:"#fff"},children:[p?(0,s.jsxs)("div",{style:{textAlign:"center",padding:"32px 20px"},className:"jsx-dc9a0e2d897fe63b",children:[(0,s.jsx)("div",{style:{marginBottom:"16px"},className:"jsx-dc9a0e2d897fe63b loading-spinner",children:(0,s.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,s.jsxs)(eX,{style:{fontSize:"16px"},children:["Testing connection to ",i,"..."]}),(0,s.jsx)(eJ(),{id:"dc9a0e2d897fe63b",children:"@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg);transform:rotate(0deg)}100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-o-transform:rotate(360deg);transform:rotate(360deg)}}"})]}):j?(0,s.jsxs)("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",padding:"32px 20px"},children:[(0,s.jsx)("div",{style:{color:"#52c41a",fontSize:"24px",display:"flex",alignItems:"center"},children:(0,s.jsx)("svg",{viewBox:"64 64 896 896",focusable:"false","data-icon":"check-circle",width:"1em",height:"1em",fill:"currentColor","aria-hidden":"true",children:(0,s.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,s.jsxs)(eX,{type:"success",style:{fontSize:"18px",fontWeight:500,marginLeft:"10px"},children:["Connection to ",i," successful!"]})]}):(0,s.jsx)(s.Fragment,{children:(0,s.jsxs)("div",{children:[(0,s.jsxs)("div",{style:{display:"flex",alignItems:"center",marginBottom:"20px"},children:[(0,s.jsx)(eY.Z,{style:{color:"#ff4d4f",fontSize:"24px",marginRight:"12px"}}),(0,s.jsxs)(eX,{type:"danger",style:{fontSize:"18px",fontWeight:500},children:["Connection to ",i," failed"]})]}),(0,s.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,s.jsxs)(eX,{strong:!0,style:{display:"block",marginBottom:"8px"},children:["Error:"," "]}),(0,s.jsx)(eX,{type:"danger",style:{fontSize:"14px",lineHeight:"1.5"},children:Z}),d&&(0,s.jsx)("div",{style:{marginTop:"12px"},children:(0,s.jsx)(_.ZP,{type:"link",onClick:()=>y(!b),style:{paddingLeft:0,height:"auto"},children:b?"Hide Details":"Show Details"})})]}),b&&(0,s.jsxs)("div",{style:{marginBottom:"20px"},children:[(0,s.jsx)(eX,{strong:!0,style:{display:"block",marginBottom:"8px",fontSize:"15px"},children:"Troubleshooting Details"}),(0,s.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 d?d:JSON.stringify(d,null,2)})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(eX,{strong:!0,style:{display:"block",marginBottom:"8px",fontSize:"15px"},children:"API Request"}),(0,s.jsx)("pre",{style:{backgroundColor:"#f5f5f5",padding:"16px",borderRadius:"8px",fontSize:"13px",maxHeight:"250px",overflow:"auto",border:"1px solid #e8e8e8",lineHeight:"1.5"},children:C||"No request data available"}),(0,s.jsx)(_.ZP,{style:{marginTop:"8px"},icon:(0,s.jsx)(e$.Z,{}),onClick:()=>{navigator.clipboard.writeText(C||""),eo.Z.success("Copied to clipboard")},children:"Copy to Clipboard"})]})]})}),(0,s.jsx)(eW.Z,{style:{margin:"24px 0 16px"}}),(0,s.jsx)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:(0,s.jsx)(_.ZP,{type:"link",href:"https://docs.litellm.ai/docs/providers",target:"_blank",icon:(0,s.jsx)(R.Z,{}),children:"View Documentation"})})]})};let e0=async(e,l,t,s)=>{try{console.log("=== AUTO ROUTER SUBMIT HANDLER CALLED ==="),console.log("handling auto router submit for formValues:",e),console.log("Access token:",l?"Present":"Missing"),console.log("Form:",t?"Present":"Missing"),console.log("Callback:",s?"Present":"Missing");let r={model_name:e.auto_router_name,litellm_params:{model:"auto_router/".concat(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),console.log("Auto router configuration to be created:",r),console.log("Auto router config (stringified):",r.litellm_params.auto_router_config),console.log("Calling modelCreateCall with:",{accessToken:l?"Present":"Missing",config:r});let i=await (0,a.modelCreateCall)(l,r);console.log("response for auto router create call:",i),t.resetFields()}catch(e){console.error("Failed to add auto router:",e),eo.Z.fromBackend("Failed to add auto router: "+e)}};var e1=t(10703),e2=t(44851),e4=t(96473),e5=t(70464),e6=t(26349),e3=t(92280);let{TextArea:e8}=ek.default,{Panel:e7}=e2.default;var e9=e=>{let{modelInfo:l,value:t,onChange:a}=e,[r,i]=(0,f.useState)([]),[n,o]=(0,f.useState)(!1),[d,c]=(0,f.useState)([]);(0,f.useEffect)(()=>{if(null==t?void 0:t.routes){let e=t.routes.map((e,l)=>({id:e.id||"route-".concat(l,"-").concat(Date.now()),model:e.name||e.model||"",utterances:e.utterances||[],description:e.description||"",score_threshold:e.score_threshold||.5}));i(e),c(e.map(e=>e.id))}else i([]),c([])},[t]);let m=e=>{let l=r.filter(l=>l.id!==e);i(l),h(l),c(l=>l.filter(l=>l!==e))},u=(e,l,t)=>{let s=r.map(s=>s.id===e?{...s,[l]:t}:s);i(s),h(s)},h=e=>{let l={routes:e.map(e=>({name:e.model,utterances:e.utterances,description:e.description,score_threshold:e.score_threshold}))};null==a||a(l)},x=l.map(e=>({value:e.model_group,label:e.model_group}));return(0,s.jsxs)("div",{className:"w-full max-w-none",children:[(0,s.jsxs)("div",{className:"flex justify-between items-center mb-6 w-full",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)(e3.x,{className:"text-lg font-semibold",children:"Routes Configuration"}),(0,s.jsx)(M.Z,{title:"Configure routing logic to automatically select the best model based on user input patterns",children:(0,s.jsx)(R.Z,{className:"text-gray-400"})})]}),(0,s.jsx)(_.ZP,{type:"primary",icon:(0,s.jsx)(e4.Z,{}),onClick:()=>{let e="route-".concat(Date.now()),l=[...r,{id:e,model:"",utterances:[],description:"",score_threshold:.5}];i(l),h(l),c(l=>[...l,e])},className:"bg-blue-600 hover:bg-blue-700",children:"Add Route"})]}),0===r.length?(0,s.jsx)("div",{className:"text-center py-12 text-gray-500 bg-gray-50 rounded-lg border-2 border-dashed border-gray-200 mb-6",children:(0,s.jsx)(e3.x,{children:"No routes configured. Click “Add Route” to get started."})}):(0,s.jsx)("div",{className:"space-y-3 mb-6 w-full",children:r.map((e,l)=>(0,s.jsx)(et.Z,{className:"border border-gray-200 shadow-sm w-full",bodyStyle:{padding:0},children:(0,s.jsx)(e2.default,{ghost:!0,expandIcon:e=>{let{isActive:l}=e;return(0,s.jsx)(e5.Z,{rotate:l?180:0})},activeKey:d,onChange:e=>c(Array.isArray(e)?e:[e].filter(Boolean)),items:[{key:e.id,label:(0,s.jsxs)("div",{className:"flex justify-between items-center py-2",children:[(0,s.jsxs)(e3.x,{className:"font-medium text-base",children:["Route ",l+1,": ",e.model||"Unnamed"]}),(0,s.jsx)(_.ZP,{type:"text",danger:!0,icon:(0,s.jsx)(e6.Z,{}),onClick:l=>{l.stopPropagation(),m(e.id)},className:"mr-2"})]}),children:(0,s.jsxs)("div",{className:"px-6 pb-6 w-full",children:[(0,s.jsxs)("div",{className:"mb-4 w-full",children:[(0,s.jsx)(e3.x,{className:"text-sm font-medium mb-2 block",children:"Model"}),(0,s.jsx)(ev.default,{value:e.model,onChange:l=>u(e.id,"model",l),placeholder:"Select model",showSearch:!0,style:{width:"100%"},options:x})]}),(0,s.jsxs)("div",{className:"mb-4 w-full",children:[(0,s.jsx)(e3.x,{className:"text-sm font-medium mb-2 block",children:"Description"}),(0,s.jsx)(e8,{value:e.description,onChange:l=>u(e.id,"description",l.target.value),placeholder:"Describe when this route should be used...",rows:2,style:{width:"100%"}})]}),(0,s.jsxs)("div",{className:"mb-4 w-full",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2 mb-2",children:[(0,s.jsx)(e3.x,{className:"text-sm font-medium",children:"Score Threshold"}),(0,s.jsx)(M.Z,{title:"Minimum similarity score to route to this model (0-1)",children:(0,s.jsx)(R.Z,{className:"text-gray-400"})})]}),(0,s.jsx)(Y.Z,{value:e.score_threshold,onChange:l=>u(e.id,"score_threshold",l||0),min:0,max:1,step:.1,style:{width:"100%"},placeholder:"0.5"})]}),(0,s.jsxs)("div",{className:"w-full",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2 mb-2",children:[(0,s.jsx)(e3.x,{className:"text-sm font-medium",children:"Example Utterances"}),(0,s.jsx)(M.Z,{title:"Training examples for this route. Type an utterance and press Enter to add it.",children:(0,s.jsx)(R.Z,{className:"text-gray-400"})})]}),(0,s.jsx)(e3.x,{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,s.jsx)(ev.default,{mode:"tags",value:e.utterances,onChange:l=>u(e.id,"utterances",l),placeholder:"Type an utterance and press Enter...",style:{width:"100%"},tokenSeparators:["\n"],maxTagCount:"responsive",allowClear:!0})]})]})}]})},e.id))}),(0,s.jsxs)("div",{className:"border-t pt-6 w-full",children:[(0,s.jsxs)("div",{className:"flex justify-between items-center mb-4 w-full",children:[(0,s.jsx)(e3.x,{className:"text-lg font-semibold",children:"JSON Preview"}),(0,s.jsx)(_.ZP,{type:"link",onClick:()=>o(!n),className:"text-blue-600 p-0",children:n?"Hide":"Show"})]}),n&&(0,s.jsx)(et.Z,{className:"bg-gray-50 w-full",children:(0,s.jsx)("pre",{className:"text-sm overflow-auto max-h-64 w-full",children:JSON.stringify({routes:r.map(e=>({name:e.model,utterances:e.utterances,description:e.description,score_threshold:e.score_threshold}))},null,2)})})]})]})};let{Title:le,Link:ll}=Q.default;var lt=e=>{let{form:l,handleOk:t,accessToken:r,userRole:i}=e,[n,o]=(0,f.useState)(!1),[d,c]=(0,f.useState)(!1),[m,u]=(0,f.useState)(""),[h,x]=(0,f.useState)([]),[p,g]=(0,f.useState)([]),[j,v]=(0,f.useState)(!1),[b,y]=(0,f.useState)(!1),[N,w]=(0,f.useState)(null);(0,f.useEffect)(()=>{(async()=>{x((await (0,a.modelAvailableCall)(r,"","",!1,null,!0,!0)).data.map(e=>e.id))})()},[r]),(0,f.useEffect)(()=>{(async()=>{try{let e=await (0,e1.p)(r);console.log("Fetched models for auto router:",e),g(e)}catch(e){console.error("Error fetching model info for auto router:",e)}})()},[r]);let Z=eR.ZL.includes(i),C=async()=>{c(!0),u("test-".concat(Date.now())),o(!0)},k=()=>{console.log("Auto router submit triggered!"),console.log("Router config:",N);let e=l.getFieldsValue();if(console.log("Form values:",e),!e.auto_router_name){eo.Z.fromBackend("Please enter an Auto Router Name");return}if(!e.auto_router_default_model){eo.Z.fromBackend("Please select a Default Model");return}if(l.setFieldsValue({custom_llm_provider:"auto_router",model:e.auto_router_name,api_key:"not_required_for_auto_router"}),!N||!N.routes||0===N.routes.length){eo.Z.fromBackend("Please configure at least one route for the auto router");return}if(N.routes.filter(e=>!e.name||!e.description||0===e.utterances.length).length>0){eo.Z.fromBackend("Please ensure all routes have a target model, description, and at least one utterance");return}l.validateFields().then(e=>{console.log("Form validation passed, submitting with values:",e);let s={...e,auto_router_config:N};console.log("Final submit values:",s),e0(s,r,l,t)}).catch(e=>{console.error("Validation failed:",e);let l=e.errorFields||[];if(l.length>0){let e=l.map(e=>{let l=e.name[0];return({auto_router_name:"Auto Router Name",auto_router_default_model:"Default Model",auto_router_embedding_model:"Embedding Model"})[l]||l});eo.Z.fromBackend("Please fill in the following required fields: ".concat(e.join(", ")))}else eo.Z.fromBackend("Please fill in all required fields")})};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(le,{level:2,children:"Add Auto Router"}),(0,s.jsx)(eN.x,{className:"text-gray-600 mb-6",children:"Create an auto router with intelligent routing logic that automatically selects the best model based on user input patterns and semantic matching."}),(0,s.jsx)(et.Z,{children:(0,s.jsxs)(eg.Z,{form:l,onFinish:k,labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:[(0,s.jsx)(eg.Z.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,s.jsx)(eN.o,{placeholder:"e.g., auto_router_1, smart_routing"})}),(0,s.jsx)("div",{className:"w-full mb-4",children:(0,s.jsx)(e9,{modelInfo:p,value:N,onChange:e=>{w(e),l.setFieldValue("auto_router_config",e)}})}),(0,s.jsx)(eg.Z.Item,{rules:[{required:!0,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,s.jsx)(ev.default,{placeholder:"Select a default model",onChange:e=>{v("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,s.jsx)(eg.Z.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,s.jsx)(ev.default,{value:l.getFieldValue("auto_router_embedding_model"),placeholder:"Select an embedding model (optional)",onChange:e=>{y("custom"===e),l.setFieldValue("auto_router_embedding_model",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,allowClear:!0})}),(0,s.jsxs)("div",{className:"flex items-center my-4",children:[(0,s.jsx)("div",{className:"flex-grow border-t border-gray-200"}),(0,s.jsx)("span",{className:"px-4 text-gray-500 text-sm",children:"Additional Settings"}),(0,s.jsx)("div",{className:"flex-grow border-t border-gray-200"})]}),Z&&(0,s.jsx)(eg.Z.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,s.jsx)(ev.default,{mode:"tags",showSearch:!0,placeholder:"Select existing groups or type to create new ones",optionFilterProp:"children",tokenSeparators:[","],options:h.map(e=>({value:e,label:e})),maxTagCount:"responsive",allowClear:!0})}),(0,s.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,s.jsx)(M.Z,{title:"Get help on our github",children:(0,s.jsx)(Q.default.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})}),(0,s.jsxs)("div",{className:"space-x-2",children:[(0,s.jsx)(_.ZP,{onClick:C,loading:d,children:"Test Connect"}),(0,s.jsx)(_.ZP,{onClick:()=>{console.log("Add Auto Router button clicked!"),console.log("Current router config:",N),console.log("Current form values:",l.getFieldsValue()),k()},children:"Add Auto Router"})]})]})]})}),(0,s.jsx)(ea.Z,{title:"Connection Test Results",open:n,onCancel:()=>{o(!1),c(!1)},footer:[(0,s.jsx)(_.ZP,{onClick:()=>{o(!1),c(!1)},children:"Close"},"close")],width:700,children:n&&(0,s.jsx)(eQ,{formValues:l.getFieldsValue(),accessToken:r,testMode:"chat",modelName:l.getFieldValue("auto_router_name"),onClose:()=>{o(!1),c(!1)},onTestComplete:()=>c(!1)},m)})]})};let ls=(0,i.n)("guardrails"),la=()=>{let{accessToken:e,userId:l,userRole:t}=(0,n.Z)();return(0,r.a)({queryKey:ls.list({}),queryFn:async()=>(await (0,a.getGuardrailsList)(e)).guardrails.map(e=>e.guardrail_name),enabled:!!(e&&l&&t)})},lr=(0,i.n)("tags"),li=()=>{let{accessToken:e,userId:l,userRole:t}=(0,n.Z)();return(0,r.a)({queryKey:lr.list({}),queryFn:async()=>await (0,a.tagListCall)(e),enabled:!!(e&&l&&t)})};var ln=t(59341),lo=t(51653),ld=t(84376),lc=t(63709),lm=t(26210),lu=t(34766),lh=t(45246),lx=t(24199);let{Text:lp}=Q.default;var lg=e=>{let{form:l,showCacheControl:t,onCacheControlChange:a}=e,r=e=>{let t=l.getFieldValue("litellm_extra_params");try{let s=t?JSON.parse(t):{};e.length>0?s.cache_control_injection_points=e:delete s.cache_control_injection_points,Object.keys(s).length>0?l.setFieldValue("litellm_extra_params",JSON.stringify(s,null,2)):l.setFieldValue("litellm_extra_params","")}catch(e){console.error("Error updating cache control points:",e)}};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(eg.Z.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,s.jsx)(lc.Z,{onChange:a,className:"bg-gray-600"})}),t&&(0,s.jsxs)("div",{className:"ml-6 pl-4 border-l-2 border-gray-200",children:[(0,s.jsx)(lp,{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,s.jsx)(eg.Z.List,{name:"cache_control_injection_points",initialValue:[{location:"message"}],children:(e,t)=>{let{add:a,remove:i}=t;return(0,s.jsxs)(s.Fragment,{children:[e.map((t,a)=>(0,s.jsxs)("div",{className:"flex items-center mb-4 gap-4",children:[(0,s.jsx)(eg.Z.Item,{...t,label:"Type",name:[t.name,"location"],initialValue:"message",className:"mb-0",style:{width:"180px"},children:(0,s.jsx)(ev.default,{disabled:!0,options:[{value:"message",label:"Message"}]})}),(0,s.jsx)(eg.Z.Item,{...t,label:"Role",name:[t.name,"role"],className:"mb-0",style:{width:"180px"},tooltip:"LiteLLM will mark all messages of this role as cacheable",children:(0,s.jsx)(ev.default,{placeholder:"Select a role",allowClear:!0,options:[{value:"user",label:"User"},{value:"system",label:"System"},{value:"assistant",label:"Assistant"}],onChange:()=>{r(l.getFieldValue("cache_control_points"))}})}),(0,s.jsx)(eg.Z.Item,{...t,label:"Index",name:[t.name,"index"],className:"mb-0",style:{width:"180px"},tooltip:"(Optional) If set litellm will mark the message at this index as cacheable",children:(0,s.jsx)(lx.Z,{type:"number",placeholder:"Optional",step:1,onChange:()=>{r(l.getFieldValue("cache_control_points"))}})}),e.length>1&&(0,s.jsx)(lh.Z,{className:"text-red-500 cursor-pointer text-lg ml-12",onClick:()=>{i(t.name),setTimeout(()=>{r(l.getFieldValue("cache_control_points"))},0)}})]},t.key)),(0,s.jsx)(eg.Z.Item,{children:(0,s.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",onClick:()=>a(),children:[(0,s.jsx)(e4.Z,{className:"mr-2"}),"Add Injection Point"]})})]})}})]})]})},lf=t(9309);let{Link:lj}=Q.default;var lv=e=>{let{showAdvancedSettings:l,setShowAdvancedSettings:t,teams:a,guardrailsList:r,tagsList:i}=e,[n]=eg.Z.useForm(),[o,d]=f.useState(!1),[c,m]=f.useState("per_token"),[u,h]=f.useState(!1),x=(e,l)=>l&&(isNaN(Number(l))||0>Number(l))?Promise.reject("Please enter a valid positive number"):Promise.resolve();return(0,s.jsx)(s.Fragment,{children:(0,s.jsxs)(lm.UQ,{className:"mt-2 mb-4",children:[(0,s.jsx)(lm._m,{children:(0,s.jsx)("b",{children:"Advanced Settings"})}),(0,s.jsx)(lm.X1,{children:(0,s.jsxs)("div",{className:"bg-white rounded-lg",children:[(0,s.jsx)(eg.Z.Item,{label:"Custom Pricing",name:"custom_pricing",valuePropName:"checked",className:"mb-4",children:(0,s.jsx)(lc.Z,{onChange:e=>{d(e),e||n.setFieldsValue({input_cost_per_token:void 0,output_cost_per_token:void 0,input_cost_per_second:void 0})},className:"bg-gray-600"})}),(0,s.jsx)(eg.Z.Item,{label:(0,s.jsxs)("span",{children:["Guardrails"," ",(0,s.jsx)(M.Z,{title:"Apply safety guardrails to this key to filter content or enforce policies",children:(0,s.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/quick_start",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,s.jsx)(R.Z,{style:{marginLeft:"4px"}})})})]}),name:"guardrails",className:"mt-4",help:"Select existing guardrails. Go to 'Guardrails' tab to create new guardrails.",children:(0,s.jsx)(ev.default,{mode:"tags",style:{width:"100%"},placeholder:"Select or enter guardrails",options:r.map(e=>({value:e,label:e}))})}),(0,s.jsx)(eg.Z.Item,{label:"Tags",name:"tags",className:"mb-4",children:(0,s.jsx)(ev.default,{mode:"tags",style:{width:"100%"},placeholder:"Select or enter tags",options:Object.values(i).map(e=>({value:e.name,label:e.name,title:e.description||e.name}))})}),o&&(0,s.jsxs)("div",{className:"ml-6 pl-4 border-l-2 border-gray-200",children:[(0,s.jsx)(eg.Z.Item,{label:"Pricing Model",name:"pricing_model",className:"mb-4",children:(0,s.jsx)(ev.default,{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,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(eg.Z.Item,{label:"Input Cost (per 1M tokens)",name:"input_cost_per_token",rules:[{validator:x}],className:"mb-4",children:(0,s.jsx)(lm.oi,{})}),(0,s.jsx)(eg.Z.Item,{label:"Output Cost (per 1M tokens)",name:"output_cost_per_token",rules:[{validator:x}],className:"mb-4",children:(0,s.jsx)(lm.oi,{})})]}):(0,s.jsx)(eg.Z.Item,{label:"Cost Per Second",name:"input_cost_per_second",rules:[{validator:x}],className:"mb-4",children:(0,s.jsx)(lm.oi,{})})]}),(0,s.jsx)(eg.Z.Item,{label:"Use in pass through routes",name:"use_in_pass_through",valuePropName:"checked",className:"mb-4 mt-4",tooltip:(0,s.jsxs)("span",{children:["Allow using these credentials in pass through routes."," ",(0,s.jsx)(lj,{href:"https://docs.litellm.ai/docs/pass_through/vertex_ai",target:"_blank",children:"Learn more"})]}),children:(0,s.jsx)(lc.Z,{onChange:e=>{let l=n.getFieldValue("litellm_extra_params");try{let t=l?JSON.parse(l):{};e?t.use_in_pass_through=!0:delete t.use_in_pass_through,Object.keys(t).length>0?n.setFieldValue("litellm_extra_params",JSON.stringify(t,null,2)):n.setFieldValue("litellm_extra_params","")}catch(l){e?n.setFieldValue("litellm_extra_params",JSON.stringify({use_in_pass_through:!0},null,2)):n.setFieldValue("litellm_extra_params","")}},className:"bg-gray-600"})}),(0,s.jsx)(lg,{form:n,showCacheControl:u,onCacheControlChange:e=>{if(h(e),!e){let e=n.getFieldValue("litellm_extra_params");try{let l=e?JSON.parse(e):{};delete l.cache_control_injection_points,Object.keys(l).length>0?n.setFieldValue("litellm_extra_params",JSON.stringify(l,null,2)):n.setFieldValue("litellm_extra_params","")}catch(e){n.setFieldValue("litellm_extra_params","")}}}}),(0,s.jsx)(eg.Z.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:lf.Ac}],children:(0,s.jsx)(lu.Z,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}),(0,s.jsxs)(ew.Z,{className:"mb-4",children:[(0,s.jsx)(eZ.Z,{span:10}),(0,s.jsx)(eZ.Z,{span:10,children:(0,s.jsxs)(lm.xv,{className:"text-gray-600 text-sm",children:["Pass JSON of litellm supported params"," ",(0,s.jsx)(lj,{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",children:"litellm.completion() call"})]})})]}),(0,s.jsx)(eg.Z.Item,{label:"Model Info",name:"model_info_params",tooltip:"Optional model info params. Returned when calling `/model/info` endpoint.",className:"mb-0",rules:[{validator:lf.Ac}],children:(0,s.jsx)(lu.Z,{rows:4,placeholder:'{ "mode": "chat" }'})})]})})]})})},l_=t(56609),lb=t(67187);let ly=e=>{let{content:l,children:t,width:a="auto",className:r=""}=e,[i,n]=(0,f.useState)(!1),[o,d]=(0,f.useState)("top"),c=(0,f.useRef)(null),m=()=>{if(c.current){let e=c.current.getBoundingClientRect(),l=e.top,t=window.innerHeight-e.bottom;l<300&&t>300?d("bottom"):d("top")}};return(0,s.jsxs)("div",{className:"relative inline-block",ref:c,children:[t||(0,s.jsx)(lb.Z,{className:"ml-1 text-gray-500 cursor-help",onMouseEnter:()=>{m(),n(!0)},onMouseLeave:()=>n(!1)}),i&&(0,s.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 ".concat(r),style:{["top"===o?"bottom":"top"]:"100%",width:a,marginBottom:"top"===o?"8px":"0",marginTop:"bottom"===o?"8px":"0"},children:[l,(0,s.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"}})]})]})};var lN=()=>{let e=eg.Z.useFormInstance(),[l,t]=(0,f.useState)(0),a=eg.Z.useWatch("model",e)||[],r=Array.isArray(a)?a:[a],i=eg.Z.useWatch("custom_model_name",e),n=!r.includes("all-wildcard"),o=eg.Z.useWatch("custom_llm_provider",e);if((0,f.useEffect)(()=>{if(i&&r.includes("custom")){let l=(e.getFieldValue("model_mappings")||[]).map(e=>"custom"===e.public_name||"custom"===e.litellm_model?o===L.Cl.Azure?{public_name:i,litellm_model:"azure/".concat(i)}:{public_name:i,litellm_model:i}:e);e.setFieldValue("model_mappings",l),t(e=>e+1)}},[i,r,o,e]),(0,f.useEffect)(()=>{if(r.length>0&&!r.includes("all-wildcard")){let l=e.getFieldValue("model_mappings")||[];if(l.length!==r.length||!r.every(e=>l.some(l=>"custom"===e?"custom"===l.litellm_model||l.litellm_model===i:o===L.Cl.Azure?l.litellm_model==="azure/".concat(e):l.litellm_model===e))){let l=r.map(e=>"custom"===e&&i?o===L.Cl.Azure?{public_name:i,litellm_model:"azure/".concat(i)}:{public_name:i,litellm_model:i}:o===L.Cl.Azure?{public_name:e,litellm_model:"azure/".concat(e)}:{public_name:e,litellm_model:e});e.setFieldValue("model_mappings",l),t(e=>e+1)}}},[r,i,o,e]),!n)return null;let d=(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("div",{className:"mb-2 font-normal",children:"The name you specify in your API calls to LiteLLM Proxy"}),(0,s.jsxs)("div",{className:"mb-2 font-normal",children:[(0,s.jsx)("strong",{children:"Example:"})," If you name your public model"," ",(0,s.jsx)("code",{className:"bg-gray-700 px-1 py-0.5 rounded text-xs",children:"example-name"}),", and choose"," ",(0,s.jsx)("code",{className:"bg-gray-700 px-1 py-0.5 rounded text-xs",children:"openai/qwen-plus-latest"})," as the LiteLLM model"]}),(0,s.jsxs)("div",{className:"mb-2 font-normal",children:[(0,s.jsx)("strong",{children:"Usage:"})," You make an API call to the LiteLLM proxy with"," ",(0,s.jsx)("code",{className:"bg-gray-700 px-1 py-0.5 rounded text-xs",children:'model = "example-name"'})]}),(0,s.jsxs)("div",{className:"font-normal",children:[(0,s.jsx)("strong",{children:"Result:"})," LiteLLM sends"," ",(0,s.jsx)("code",{className:"bg-gray-700 px-1 py-0.5 rounded text-xs",children:"qwen-plus-latest"})," to the provider"]})]}),c=(0,s.jsx)("div",{children:"The model name LiteLLM will send to the LLM API"}),m=[{title:(0,s.jsxs)("span",{className:"flex items-center",children:["Public Model Name",(0,s.jsx)(ly,{content:d,width:"500px"})]}),dataIndex:"public_name",key:"public_name",render:(l,t,a)=>(0,s.jsx)(ej.o,{value:l,onChange:l=>{let t=l.target.value,s=[...e.getFieldValue("model_mappings")],r=o===L.Cl.Anthropic,i=t.endsWith("-1m"),n=e.getFieldValue("litellm_extra_params"),d=!n||""===n.trim(),c=t;if(r&&i&&d){let l=JSON.stringify({extra_headers:{"anthropic-beta":"context-1m-2025-08-07"}},null,2);e.setFieldValue("litellm_extra_params",l),c=t.slice(0,-3)}s[a].public_name=c,e.setFieldValue("model_mappings",s)}})},{title:(0,s.jsxs)("span",{className:"flex items-center",children:["LiteLLM Model Name",(0,s.jsx)(ly,{content:c,width:"360px"})]}),dataIndex:"litellm_model",key:"litellm_model"}];return(0,s.jsx)(s.Fragment,{children:(0,s.jsx)(eg.Z.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,l)=>{if(!l||0===l.length)throw Error("At least one model mapping is required");if(l.filter(e=>!e.public_name||""===e.public_name.trim()).length>0)throw Error("All model mappings must have valid public names")}}],children:(0,s.jsx)(l_.Z,{dataSource:e.getFieldValue("model_mappings"),columns:m,pagination:!1,size:"small"},l)})})},lw=e=>{let{selectedProvider:l,providerModels:t,getPlaceholder:a}=e,r=eg.Z.useFormInstance(),i=e=>{let t=e.target.value,s=(r.getFieldValue("model_mappings")||[]).map(e=>"custom"===e.public_name||"custom"===e.litellm_model?l===L.Cl.Azure?{public_name:t,litellm_model:"azure/".concat(t)}:{public_name:t,litellm_model:t}:e);r.setFieldsValue({model_mappings:s})};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(eg.Z.Item,{label:"LiteLLM Model Name(s)",tooltip:"The model name LiteLLM will send to the LLM API",className:"mb-0",children:[(0,s.jsx)(eg.Z.Item,{name:"model",rules:[{required:!0,message:"Please enter ".concat(l===L.Cl.Azure?"a deployment name":"at least one model",".")}],noStyle:!0,children:l===L.Cl.Azure||l===L.Cl.OpenAI_Compatible||l===L.Cl.Ollama?(0,s.jsx)(s.Fragment,{children:(0,s.jsx)(eN.o,{placeholder:a(l),onChange:l===L.Cl.Azure?e=>{let l=e.target.value,t=l?[{public_name:l,litellm_model:"azure/".concat(l)}]:[];r.setFieldsValue({model:l,model_mappings:t})}:void 0})}):t.length>0?(0,s.jsx)(ev.default,{mode:"multiple",allowClear:!0,showSearch:!0,placeholder:"Select models",onChange:e=>{let t=Array.isArray(e)?e:[e];if(t.includes("all-wildcard"))r.setFieldsValue({model_name:void 0,model_mappings:[]});else if(JSON.stringify(r.getFieldValue("model"))!==JSON.stringify(t)){let e=t.map(e=>l===L.Cl.Azure?{public_name:e,litellm_model:"azure/".concat(e)}:{public_name:e,litellm_model:e});r.setFieldsValue({model:t,model_mappings:e})}},optionFilterProp:"children",filterOption:(e,l)=>{var t;return(null!==(t=null==l?void 0:l.label)&&void 0!==t?t:"").toLowerCase().includes(e.toLowerCase())},options:[{label:"Custom Model Name (Enter below)",value:"custom"},{label:"All ".concat(l," Models (Wildcard)"),value:"all-wildcard"},...t.map(e=>({label:e,value:e}))],style:{width:"100%"}}):(0,s.jsx)(eN.o,{placeholder:a(l)})}),(0,s.jsx)(eg.Z.Item,{noStyle:!0,shouldUpdate:(e,l)=>e.model!==l.model,children:e=>{let{getFieldValue:t}=e,a=t("model")||[];return(Array.isArray(a)?a:[a]).includes("custom")&&(0,s.jsx)(eg.Z.Item,{name:"custom_model_name",rules:[{required:!0,message:"Please enter a custom model name."}],className:"mt-2",children:(0,s.jsx)(eN.o,{placeholder:l===L.Cl.Azure?"Enter Azure deployment name":"Enter custom model name",onChange:i})})}})]}),(0,s.jsxs)(ew.Z,{children:[(0,s.jsx)(eZ.Z,{span:10}),(0,s.jsx)(eZ.Z,{span:14,children:(0,s.jsx)(eN.x,{className:"mb-3 mt-1",children:l===L.Cl.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"})})]})]})};let lZ=[{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:lC,Link:lk}=Q.default;var lS=e=>{let{form:l,handleOk:t,selectedProvider:r,setSelectedProvider:i,providerModels:o,setProviderModelsFn:d,getPlaceholder:c,uploadProps:m,showAdvancedSettings:u,setShowAdvancedSettings:h,teams:x,credentials:p}=e,[g,j]=(0,f.useState)("chat"),[v,b]=(0,f.useState)(!1),[y,N]=(0,f.useState)(!1),[w,Z]=(0,f.useState)(""),{accessToken:C,userRole:k,premiumUser:S,userId:A}=(0,n.Z)(),{data:E,isLoading:P,error:I}=eb(),{data:T,isLoading:R,error:O}=la(),{data:V,isLoading:q,error:z}=li(),B=async()=>{N(!0),Z("test-".concat(Date.now())),b(!0)},[G,U]=(0,f.useState)(!1),[H,K]=(0,f.useState)([]),[J,W]=(0,f.useState)(null);(0,f.useEffect)(()=>{(async()=>{K((await (0,a.modelAvailableCall)(C,"","",!1,null,!0,!0)).data.map(e=>e.id))})()},[C]);let Y=(0,f.useMemo)(()=>E?[...E].sort((e,l)=>e.provider_display_name.localeCompare(l.provider_display_name)):[],[E]),$=I?I instanceof Error?I.message:"Failed to load providers":null,X=eR.ZL.includes(k),ee=(0,eR.yV)(x,A);return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(lC,{level:2,children:"Add Model"}),(0,s.jsx)(et.Z,{children:(0,s.jsx)(eg.Z,{form:l,onFinish:async e=>{console.log("\uD83D\uDD25 Form onFinish triggered with values:",e),await t().then(()=>{W(null)})},onFinishFailed:e=>{console.log("\uD83D\uDCA5 Form onFinishFailed triggered:",e)},labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:(0,s.jsxs)(s.Fragment,{children:[ee&&!X&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(eg.Z.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,s.jsx)(ld.Z,{teams:x,onChange:e=>{W(e)}})}),!J&&(0,s.jsx)(lo.Z,{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"})]}),(X||ee&&J)&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(eg.Z.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,s.jsxs)(ev.default,{virtual:!1,showSearch:!0,loading:P,placeholder:P?"Loading providers...":"Select a provider",optionFilterProp:"data-label",onChange:e=>{i(e),d(e),l.setFieldsValue({custom_llm_provider:e}),l.setFieldsValue({model:[],model_name:void 0})},children:[$&&0===Y.length&&(0,s.jsx)(ev.default.Option,{value:"",children:$},"__error"),Y.map(e=>{let l=e.provider_display_name,t=e.provider;return L.cd[l],(0,s.jsx)(ev.default.Option,{value:t,"data-label":l,children:(0,s.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,s.jsx)(F,{provider:t,className:"w-5 h-5"}),(0,s.jsx)("span",{children:l})]})},t)})]})}),(0,s.jsx)(lw,{selectedProvider:r,providerModels:o,getPlaceholder:c}),(0,s.jsx)(lN,{}),(0,s.jsx)(eg.Z.Item,{label:"Mode",name:"mode",className:"mb-1",children:(0,s.jsx)(ev.default,{style:{width:"100%"},value:g,onChange:e=>j(e),options:lZ})}),(0,s.jsxs)(ew.Z,{children:[(0,s.jsx)(eZ.Z,{span:10}),(0,s.jsx)(eZ.Z,{span:10,children:(0,s.jsxs)(D.Z,{className:"mb-5 mt-1",children:[(0,s.jsx)("strong",{children:"Optional"})," - LiteLLM endpoint to use when health checking this model"," ",(0,s.jsx)(lk,{href:"https://docs.litellm.ai/docs/proxy/health#health",target:"_blank",children:"Learn more"})]})})]}),(0,s.jsx)("div",{className:"mb-4",children:(0,s.jsx)(Q.default.Text,{className:"text-sm text-gray-500 mb-2",children:"Either select existing credentials OR enter new provider credentials below"})}),(0,s.jsx)(eg.Z.Item,{label:"Existing Credentials",name:"litellm_credential_name",initialValue:null,children:(0,s.jsx)(ev.default,{showSearch:!0,placeholder:"Select or search for existing credentials",optionFilterProp:"children",filterOption:(e,l)=>{var t;return(null!==(t=null==l?void 0:l.label)&&void 0!==t?t:"").toLowerCase().includes(e.toLowerCase())},options:[{value:null,label:"None"},...p.map(e=>({value:e.credential_name,label:e.credential_name}))],allowClear:!0})}),(0,s.jsx)(eg.Z.Item,{noStyle:!0,shouldUpdate:(e,l)=>e.litellm_credential_name!==l.litellm_credential_name||e.provider!==l.provider,children:e=>{let{getFieldValue:l}=e,t=l("litellm_credential_name");return(console.log("\uD83D\uDD11 Credential Name Changed:",t),t)?null:(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)("div",{className:"flex items-center my-4",children:[(0,s.jsx)("div",{className:"flex-grow border-t border-gray-200"}),(0,s.jsx)("span",{className:"px-4 text-gray-500 text-sm",children:"OR"}),(0,s.jsx)("div",{className:"flex-grow border-t border-gray-200"})]}),(0,s.jsx)(eP,{selectedProvider:r,uploadProps:m})]})}}),(0,s.jsxs)("div",{className:"flex items-center my-4",children:[(0,s.jsx)("div",{className:"flex-grow border-t border-gray-200"}),(0,s.jsx)("span",{className:"px-4 text-gray-500 text-sm",children:"Additional Model Info Settings"}),(0,s.jsx)("div",{className:"flex-grow border-t border-gray-200"})]}),(X||!ee)&&(0,s.jsx)(eg.Z.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,s.jsx)(M.Z,{title:S?"":"This is an enterprise-only feature. Upgrade to premium to restrict model+credential combinations to a specific team.",placement:"top",children:(0,s.jsx)(ln.Z,{checked:G,onChange:e=>{U(e),e||l.setFieldValue("team_id",void 0)},disabled:!S})})}),G&&(X||!ee)&&(0,s.jsx)(eg.Z.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:G&&!X,message:"Please select a team."}],children:(0,s.jsx)(ld.Z,{teams:x,disabled:!S})}),X&&(0,s.jsx)(s.Fragment,{children:(0,s.jsx)(eg.Z.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,s.jsx)(ev.default,{mode:"tags",showSearch:!0,placeholder:"Select existing groups or type to create new ones",optionFilterProp:"children",tokenSeparators:[","],options:H.map(e=>({value:e,label:e})),maxTagCount:"responsive",allowClear:!0})})}),(0,s.jsx)(lv,{showAdvancedSettings:u,setShowAdvancedSettings:h,teams:x,guardrailsList:T||[],tagsList:V||{}})]}),(0,s.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,s.jsx)(M.Z,{title:"Get help on our github",children:(0,s.jsx)(Q.default.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})}),(0,s.jsxs)("div",{className:"space-x-2",children:[(0,s.jsx)(_.ZP,{onClick:B,loading:y,children:"Test Connect"}),(0,s.jsx)(_.ZP,{htmlType:"submit",children:"Add Model"})]})]})]})})}),(0,s.jsx)(ea.Z,{title:"Connection Test Results",open:v,onCancel:()=>{b(!1),N(!1)},footer:[(0,s.jsx)(_.ZP,{onClick:()=>{b(!1),N(!1)},children:"Close"},"close")],width:700,children:v&&(0,s.jsx)(eQ,{formValues:l.getFieldsValue(),accessToken:C,testMode:g,modelName:l.getFieldValue("model_name")||l.getFieldValue("model"),onClose:()=>{b(!1),N(!1)},onTestComplete:()=>N(!1)},w)})]})},lA=e=>{let{form:l,handleOk:t,selectedProvider:a,setSelectedProvider:r,providerModels:i,setProviderModelsFn:n,getPlaceholder:o,uploadProps:d,showAdvancedSettings:c,setShowAdvancedSettings:m,teams:u,credentials:h,accessToken:x,userRole:p}=e,[g]=eg.Z.useForm();return(0,s.jsx)(s.Fragment,{children:(0,s.jsxs)(eH.v0,{className:"w-full",children:[(0,s.jsxs)(eH.td,{className:"mb-4",children:[(0,s.jsx)(eH.OK,{children:"Add Model"}),(0,s.jsx)(eH.OK,{children:"Add Auto Router"})]}),(0,s.jsxs)(eH.nP,{children:[(0,s.jsx)(eH.x4,{children:(0,s.jsx)(lS,{form:l,handleOk:t,selectedProvider:a,setSelectedProvider:r,providerModels:i,setProviderModelsFn:n,getPlaceholder:o,uploadProps:d,showAdvancedSettings:c,setShowAdvancedSettings:m,teams:u,credentials:h})}),(0,s.jsx)(eH.x4,{children:(0,s.jsx)(lt,{form:g,handleOk:()=>{g.validateFields().then(e=>{e0(e,x,g,t)}).catch(e=>{console.error("Validation failed:",e)})},accessToken:x,userRole:p})})]})]})})},lE=t(8048),lP=t(4156),lM=t(15731),lL=t(91126);let lF=(e,l,t,a,r,i,n,o,d,c,m)=>[{header:()=>(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)(lP.Z,{checked:t,indeterminate:l.length>0&&!t,onChange:e=>r(e.target.checked),onClick:e=>e.stopPropagation()}),(0,s.jsx)("span",{children:"Model ID"})]}),accessorKey:"model_info.id",enableSorting:!0,sortingFn:"alphanumeric",cell:e=>{let{row:t}=e,r=t.original,i=r.model_name,n=l.includes(i);return(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)(lP.Z,{checked:n,onChange:e=>a(i,e.target.checked),onClick:e=>e.stopPropagation()}),(0,s.jsx)(M.Z,{title:r.model_info.id,children:(0,s.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:()=>m&&m(r.model_info.id),children:r.model_info.id})})]})}},{header:"Model Name",accessorKey:"model_name",enableSorting:!0,sortingFn:"alphanumeric",cell:e=>{let{row:l}=e,t=l.original,a=o(t)||t.model_name;return(0,s.jsx)("div",{className:"font-medium text-sm",children:(0,s.jsx)(M.Z,{title:a,children:(0,s.jsx)("div",{className:"truncate max-w-[200px]",children:a})})})}},{header:"Health Status",accessorKey:"health_status",enableSorting:!0,sortingFn:(e,l,t)=>{var s,a;let r=e.getValue("health_status")||"unknown",i=l.getValue("health_status")||"unknown",n={healthy:0,checking:1,unknown:2,unhealthy:3};return(null!==(s=n[r])&&void 0!==s?s:4)-(null!==(a=n[i])&&void 0!==a?a:4)},cell:l=>{var t;let{row:a}=l,r=a.original,i={status:r.health_status,loading:r.health_loading,error:r.health_error};if(i.loading)return(0,s.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,s.jsxs)("div",{className:"flex space-x-1",children:[(0,s.jsx)("div",{className:"w-2 h-2 bg-indigo-500 rounded-full animate-pulse"}),(0,s.jsx)("div",{className:"w-2 h-2 bg-indigo-500 rounded-full animate-pulse",style:{animationDelay:"0.2s"}}),(0,s.jsx)("div",{className:"w-2 h-2 bg-indigo-500 rounded-full animate-pulse",style:{animationDelay:"0.4s"}})]}),(0,s.jsx)(e3.x,{className:"text-gray-600 text-sm",children:"Checking..."})]});let o=r.model_name,d="healthy"===i.status&&(null===(t=e[o])||void 0===t?void 0:t.successResponse);return(0,s.jsxs)("div",{className:"flex items-center space-x-2",children:[n(i.status),d&&c&&(0,s.jsx)(M.Z,{title:"View response details",placement:"top",children:(0,s.jsx)("button",{onClick:()=>{var l;return c(o,null===(l=e[o])||void 0===l?void 0:l.successResponse)},className:"p-1 text-green-600 hover:text-green-800 hover:bg-green-50 rounded cursor-pointer transition-colors",children:(0,s.jsx)(lM.Z,{className:"h-4 w-4"})})})]})}},{header:"Error Details",accessorKey:"health_error",enableSorting:!1,cell:l=>{let{row:t}=l,a=t.original.model_name,r=e[a];if(!(null==r?void 0:r.error))return(0,s.jsx)(e3.x,{className:"text-gray-400 text-sm",children:"No errors"});let i=r.error,n=r.fullError||r.error;return(0,s.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,s.jsx)("div",{className:"max-w-[200px]",children:(0,s.jsx)(M.Z,{title:i,placement:"top",children:(0,s.jsx)(e3.x,{className:"text-red-600 text-sm truncate",children:i})})}),d&&n!==i&&(0,s.jsx)(M.Z,{title:"View full error details",placement:"top",children:(0,s.jsx)("button",{onClick:()=>d(a,i,n),className:"p-1 text-red-600 hover:text-red-800 hover:bg-red-50 rounded cursor-pointer transition-colors",children:(0,s.jsx)(lM.Z,{className:"h-4 w-4"})})})]})}},{header:"Last Check",accessorKey:"last_check",enableSorting:!0,sortingFn:(e,l,t)=>{let s=e.getValue("last_check")||"Never checked",a=l.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:e=>{let{row:l}=e,t=l.original;return(0,s.jsx)(e3.x,{className:"text-gray-600 text-sm",children:t.health_loading?"Check in progress...":t.last_check})}},{header:"Last Success",accessorKey:"last_success",enableSorting:!0,sortingFn:(e,l,t)=>{let s=e.getValue("last_success")||"Never succeeded",a=l.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:l=>{let{row:t}=l,a=e[t.original.model_name],r=(null==a?void 0:a.lastSuccess)||"None";return(0,s.jsx)(e3.x,{className:"text-gray-600 text-sm",children:r})}},{header:"Actions",id:"actions",cell:e=>{let{row:l}=e,t=l.original,a=t.model_name,r=t.health_status&&"none"!==t.health_status,n=t.health_loading?"Checking...":r?"Re-run Health Check":"Run Health Check";return(0,s.jsx)(M.Z,{title:n,placement:"top",children:(0,s.jsx)("button",{className:"p-2 rounded-md transition-colors ".concat(t.health_loading?"text-gray-400 cursor-not-allowed bg-gray-100":"text-indigo-600 hover:text-indigo-700 hover:bg-indigo-50"),onClick:()=>{t.health_loading||i(a)},disabled:t.health_loading,children:t.health_loading?(0,s.jsxs)("div",{className:"flex space-x-1",children:[(0,s.jsx)("div",{className:"w-1 h-1 bg-gray-400 rounded-full animate-pulse"}),(0,s.jsx)("div",{className:"w-1 h-1 bg-gray-400 rounded-full animate-pulse",style:{animationDelay:"0.2s"}}),(0,s.jsx)("div",{className:"w-1 h-1 bg-gray-400 rounded-full animate-pulse",style:{animationDelay:"0.4s"}})]}):r?(0,s.jsx)(eO.Z,{className:"h-4 w-4"}):(0,s.jsx)(lL.Z,{className:"h-4 w-4"})})})},enableSorting:!1}],lI=[{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"}];var lT=e=>{let{accessToken:l,modelData:t,all_models_on_proxy:r,getDisplayModelName:i,setSelectedModelId:n}=e,[o,d]=(0,f.useState)({}),[c,m]=(0,f.useState)([]),[u,h]=(0,f.useState)(!1),[x,p]=(0,f.useState)(!1),[g,j]=(0,f.useState)(null),[v,b]=(0,f.useState)(!1),[y,N]=(0,f.useState)(null);(0,f.useRef)(null),(0,f.useEffect)(()=>{l&&(null==t?void 0:t.data)&&(async()=>{let e={};t.data.forEach(l=>{e[l.model_name]={status:"none",lastCheck:"None",lastSuccess:"None",loading:!1,error:void 0,fullError:void 0,successResponse:void 0}});try{let s=await (0,a.latestHealthChecksCall)(l);s&&s.latest_health_checks&&"object"==typeof s.latest_health_checks&&Object.entries(s.latest_health_checks).forEach(l=>{let[s,a]=l;if(!a)return;let r=null,i=t.data.find(e=>e.model_name===s);if(i)r=i.model_name;else{let e=t.data.find(e=>e.model_info&&e.model_info.id===s);if(e)r=e.model_name;else if(a.model_name){let e=t.data.find(e=>e.model_name===a.model_name);e&&(r=e.model_name)}}if(r){let l=a.error_message||void 0;e[r]={status:a.status||"unknown",lastCheck:a.checked_at?new Date(a.checked_at).toLocaleString():"None",lastSuccess:"healthy"===a.status&&a.checked_at?new Date(a.checked_at).toLocaleString():"None",loading:!1,error:l?w(l):void 0,fullError:l,successResponse:"healthy"===a.status?a:void 0}}})}catch(e){console.warn("Failed to load health check history (using default states):",e)}d(e)})()},[l,t]);let w=e=>{var l;if(!e)return"Health check failed";let t="string"==typeof e?e:JSON.stringify(e),s=t.match(/(\w+Error):\s*(\d{3})/i);if(s)return"".concat(s[1],": ").concat(s[2]);let a=t.match(/(AuthenticationError|RateLimitError|BadRequestError|InternalServerError|TimeoutError|NotFoundError|ForbiddenError|ServiceUnavailableError|BadGatewayError|ContentPolicyViolationError|\w+Error)/i),r=t.match(/\b(400|401|403|404|408|429|500|502|503|504)\b/);if(a&&r)return"".concat(a[1],": ").concat(r[1]);if(r){let e=r[1];return"".concat({400:"BadRequestError",401:"AuthenticationError",403:"ForbiddenError",404:"NotFoundError",408:"TimeoutError",429:"RateLimitError",500:"InternalServerError",502:"BadGatewayError",503:"ServiceUnavailableError",504:"GatewayTimeoutError"}[e],": ").concat(e)}if(a){let e=a[1],l={AuthenticationError:"401",RateLimitError:"429",BadRequestError:"400",InternalServerError:"500",TimeoutError:"408",NotFoundError:"404",ForbiddenError:"403",ServiceUnavailableError:"503",BadGatewayError:"502",GatewayTimeoutError:"504",ContentPolicyViolationError:"400"}[e];return l?"".concat(e,": ").concat(l):e}for(let{pattern:e,replacement:l}of lI)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 i=t.replace(/[\n\r]+/g," ").replace(/\s+/g," ").trim(),n=null===(l=i.split(/[.!?]/)[0])||void 0===l?void 0:l.trim();return n&&n.length>0?n.length>100?n.substring(0,97)+"...":n:i.length>100?i.substring(0,97)+"...":i},Z=async e=>{if(l){d(l=>({...l,[e]:{...l[e],loading:!0,status:"checking"}}));try{var s,r;let i=await (0,a.individualModelHealthCheckCall)(l,e),n=new Date().toLocaleString();if(i.unhealthy_count>0&&i.unhealthy_endpoints&&i.unhealthy_endpoints.length>0){let l=(null===(s=i.unhealthy_endpoints[0])||void 0===s?void 0:s.error)||"Health check failed",t=w(l);d(s=>{var a;return{...s,[e]:{status:"unhealthy",lastCheck:n,lastSuccess:(null===(a=s[e])||void 0===a?void 0:a.lastSuccess)||"None",loading:!1,error:t,fullError:l}}})}else d(l=>({...l,[e]:{status:"healthy",lastCheck:n,lastSuccess:n,loading:!1,successResponse:i}}));try{let s=await (0,a.latestHealthChecksCall)(l),i=t.data.find(l=>l.model_name===e);if(i){let l=i.model_info.id,t=null===(r=s.latest_health_checks)||void 0===r?void 0:r[l];if(t){let l=t.error_message||void 0;d(s=>{var a,r,i,n,o,d,c;return{...s,[e]:{status:t.status||(null===(a=s[e])||void 0===a?void 0:a.status)||"unknown",lastCheck:t.checked_at?new Date(t.checked_at).toLocaleString():(null===(r=s[e])||void 0===r?void 0:r.lastCheck)||"None",lastSuccess:"healthy"===t.status?t.checked_at?new Date(t.checked_at).toLocaleString():(null===(i=s[e])||void 0===i?void 0:i.lastSuccess)||"None":(null===(n=s[e])||void 0===n?void 0:n.lastSuccess)||"None",loading:!1,error:l?w(l):null===(o=s[e])||void 0===o?void 0:o.error,fullError:l||(null===(d=s[e])||void 0===d?void 0:d.fullError),successResponse:"healthy"===t.status?t:null===(c=s[e])||void 0===c?void 0:c.successResponse}}})}}}catch(e){console.debug("Could not fetch updated status from database (non-critical):",e)}}catch(a){let l=new Date().toLocaleString(),t=a instanceof Error?a.message:String(a),s=w(t);d(a=>{var r;return{...a,[e]:{status:"unhealthy",lastCheck:l,lastSuccess:(null===(r=a[e])||void 0===r?void 0:r.lastSuccess)||"None",loading:!1,error:s,fullError:t}}})}}},C=async()=>{let e=c.length>0?c:r,s=e.reduce((e,l)=>(e[l]={...o[l],loading:!0,status:"checking"},e),{});d(e=>({...e,...s}));let i={},n=e.map(async e=>{if(l)try{let s=await (0,a.individualModelHealthCheckCall)(l,e);i[e]=s;let r=new Date().toLocaleString();if(s.unhealthy_count>0&&s.unhealthy_endpoints&&s.unhealthy_endpoints.length>0){var t;let l=(null===(t=s.unhealthy_endpoints[0])||void 0===t?void 0:t.error)||"Health check failed",a=w(l);d(t=>{var s;return{...t,[e]:{status:"unhealthy",lastCheck:r,lastSuccess:(null===(s=t[e])||void 0===s?void 0:s.lastSuccess)||"None",loading:!1,error:a,fullError:l}}})}else d(l=>({...l,[e]:{status:"healthy",lastCheck:r,lastSuccess:r,loading:!1,successResponse:s}}))}catch(a){console.error("Health check failed for ".concat(e,":"),a);let l=new Date().toLocaleString(),t=a instanceof Error?a.message:String(a),s=w(t);d(a=>{var r;return{...a,[e]:{status:"unhealthy",lastCheck:l,lastSuccess:(null===(r=a[e])||void 0===r?void 0:r.lastSuccess)||"None",loading:!1,error:s,fullError:t}}})}});await Promise.allSettled(n);try{if(!l)return;let s=await (0,a.latestHealthChecksCall)(l);s.latest_health_checks&&Object.entries(s.latest_health_checks).forEach(l=>{let[s,a]=l,r=t.data.find(e=>e.model_info.id===s);if(r&&e.includes(r.model_name)&&a){let e=r.model_name,l=a.error_message||void 0;d(t=>{let s=t[e];return{...t,[e]:{status:a.status||(null==s?void 0:s.status)||"unknown",lastCheck:a.checked_at?new Date(a.checked_at).toLocaleString():(null==s?void 0:s.lastCheck)||"None",lastSuccess:"healthy"===a.status&&a.checked_at?new Date(a.checked_at).toLocaleString():(null==s?void 0:s.lastSuccess)||"None",loading:!1,error:l?w(l):null==s?void 0:s.error,fullError:l||(null==s?void 0:s.fullError),successResponse:"healthy"===a.status?a:null==s?void 0:s.successResponse}}})}})}catch(e){console.warn("Failed to fetch updated health statuses from database (non-critical):",e)}},k=e=>{h(e),e?m(r):m([])},S=()=>{p(!1),j(null)},P=()=>{b(!1),N(null)};return(0,s.jsxs)("div",{children:[(0,s.jsx)("div",{className:"mb-6",children:(0,s.jsxs)("div",{className:"flex justify-between items-center",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)(W.Z,{children:"Model Health Status"}),(0,s.jsx)(D.Z,{className:"text-gray-600 mt-1",children:"Run health checks on individual models to verify they are working correctly"})]}),(0,s.jsxs)("div",{className:"flex items-center gap-3",children:[c.length>0&&(0,s.jsx)(E.Z,{size:"sm",variant:"light",onClick:()=>k(!1),className:"px-3 py-1 text-sm",children:"Clear Selection"}),(0,s.jsx)(E.Z,{size:"sm",variant:"secondary",onClick:C,disabled:Object.values(o).some(e=>e.loading),className:"px-3 py-1 text-sm",children:c.length>0&&c.length{l?m(l=>[...l,e]):(m(l=>l.filter(l=>l!==e)),h(!1))},k,Z,e=>{switch(e){case"healthy":return(0,s.jsx)(A.Z,{color:"emerald",children:"healthy"});case"unhealthy":return(0,s.jsx)(A.Z,{color:"red",children:"unhealthy"});case"checking":return(0,s.jsx)(A.Z,{color:"blue",children:"checking"});case"none":return(0,s.jsx)(A.Z,{color:"gray",children:"none"});default:return(0,s.jsx)(A.Z,{color:"gray",children:"unknown"})}},i,(e,l,t)=>{j({modelName:e,cleanedError:l,fullError:t}),p(!0)},(e,l)=>{N({modelName:e,response:l}),b(!0)},n),data:t.data.map(e=>{let l=o[e.model_name]||{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}}),isLoading:!1})}),(0,s.jsx)(ea.Z,{title:g?"Health Check Error - ".concat(g.modelName):"Error Details",open:x,onCancel:S,footer:[(0,s.jsx)(_.ZP,{onClick:S,children:"Close"},"close")],width:800,children:g&&(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"Error:"}),(0,s.jsx)("div",{className:"mt-2 p-3 bg-red-50 border border-red-200 rounded-md",children:(0,s.jsx)(D.Z,{className:"text-red-800",children:g.cleanedError})})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"Full Error Details:"}),(0,s.jsx)("div",{className:"mt-2 p-3 bg-gray-50 border border-gray-200 rounded-md max-h-96 overflow-y-auto",children:(0,s.jsx)("pre",{className:"text-sm text-gray-800 whitespace-pre-wrap",children:g.fullError})})]})]})}),(0,s.jsx)(ea.Z,{title:y?"Health Check Response - ".concat(y.modelName):"Response Details",open:v,onCancel:P,footer:[(0,s.jsx)(_.ZP,{onClick:P,children:"Close"},"close")],width:800,children:y&&(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"Status:"}),(0,s.jsx)("div",{className:"mt-2 p-3 bg-green-50 border border-green-200 rounded-md",children:(0,s.jsx)(D.Z,{className:"text-green-800",children:"Health check passed successfully"})})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"Response Details:"}),(0,s.jsx)("div",{className:"mt-2 p-3 bg-gray-50 border border-gray-200 rounded-md max-h-96 overflow-y-auto",children:(0,s.jsx)("pre",{className:"text-sm text-gray-800 whitespace-pre-wrap",children:JSON.stringify(y.response,null,2)})})]})]})})]})},lR=t(47686),lO=t(77355),lV=t(93416),lq=t(95704),lz=e=>{let{accessToken:l,initialModelGroupAlias:t={},onAliasUpdate:r}=e,[i,n]=(0,f.useState)([]),[o,d]=(0,f.useState)({aliasName:"",targetModelGroup:""}),[c,m]=(0,f.useState)(null),[u,h]=(0,f.useState)(!0);(0,f.useEffect)(()=>{n(Object.entries(t).map((e,l)=>{var t;let[s,a]=e;return{id:"".concat(l,"-").concat(s),aliasName:s,targetModelGroup:"string"==typeof a?a:null!==(t=null==a?void 0:a.model)&&void 0!==t?t:""}}))},[t]);let x=async e=>{if(!l)return console.error("Access token is missing"),!1;try{let t={};return e.forEach(e=>{t[e.aliasName]=e.targetModelGroup}),console.log("Saving model group alias:",t),await (0,a.setCallbacksCall)(l,{router_settings:{model_group_alias:t}}),r&&r(t),!0}catch(e){return console.error("Failed to save model group alias settings:",e),eo.Z.fromBackend("Failed to save model group alias settings"),!1}},p=async()=>{if(!o.aliasName||!o.targetModelGroup){eo.Z.fromBackend("Please provide both alias name and target model group");return}if(i.some(e=>e.aliasName===o.aliasName)){eo.Z.fromBackend("An alias with this name already exists");return}let e=[...i,{id:"".concat(Date.now(),"-").concat(o.aliasName),aliasName:o.aliasName,targetModelGroup:o.targetModelGroup}];await x(e)&&(n(e),d({aliasName:"",targetModelGroup:""}),eo.Z.success("Alias added successfully"))},g=e=>{m({...e})},j=async()=>{if(!c)return;if(!c.aliasName||!c.targetModelGroup){eo.Z.fromBackend("Please provide both alias name and target model group");return}if(i.some(e=>e.id!==c.id&&e.aliasName===c.aliasName)){eo.Z.fromBackend("An alias with this name already exists");return}let e=i.map(e=>e.id===c.id?c:e);await x(e)&&(n(e),m(null),eo.Z.success("Alias updated successfully"))},v=()=>{m(null)},_=async e=>{let l=i.filter(l=>l.id!==e);await x(l)&&(n(l),eo.Z.success("Alias deleted successfully"))},b=i.reduce((e,l)=>(e[l.aliasName]=l.targetModelGroup,e),{});return(0,s.jsxs)(lq.Zb,{className:"mb-6",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between cursor-pointer",onClick:()=>h(!u),children:[(0,s.jsxs)("div",{className:"flex flex-col",children:[(0,s.jsx)(lq.Dx,{className:"mb-0",children:"Model Group Alias Settings"}),(0,s.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,s.jsx)("div",{className:"flex items-center",children:u?(0,s.jsx)(y.Z,{className:"w-5 h-5 text-gray-500"}):(0,s.jsx)(lR.Z,{className:"w-5 h-5 text-gray-500"})})]}),u&&(0,s.jsxs)("div",{className:"mt-4",children:[(0,s.jsxs)("div",{className:"mb-6",children:[(0,s.jsx)(lq.xv,{className:"text-sm font-medium text-gray-700 mb-2",children:"Add New Alias"}),(0,s.jsxs)("div",{className:"grid grid-cols-3 gap-4",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"block text-xs text-gray-500 mb-1",children:"Alias Name"}),(0,s.jsx)("input",{type:"text",value:o.aliasName,onChange:e=>d({...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,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"block text-xs text-gray-500 mb-1",children:"Target Model Group"}),(0,s.jsx)("input",{type:"text",value:o.targetModelGroup,onChange:e=>d({...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,s.jsx)("div",{className:"flex items-end",children:(0,s.jsxs)("button",{onClick:p,disabled:!o.aliasName||!o.targetModelGroup,className:"flex items-center px-4 py-2 rounded-md text-sm ".concat(o.aliasName&&o.targetModelGroup?"bg-green-600 text-white hover:bg-green-700":"bg-gray-300 text-gray-500 cursor-not-allowed"),children:[(0,s.jsx)(lO.Z,{className:"w-4 h-4 mr-1"}),"Add Alias"]})})]})]}),(0,s.jsx)(lq.xv,{className:"text-sm font-medium text-gray-700 mb-2",children:"Manage Existing Aliases"}),(0,s.jsx)("div",{className:"rounded-lg custom-border relative mb-6",children:(0,s.jsx)("div",{className:"overflow-x-auto",children:(0,s.jsxs)(lq.iA,{className:"[&_td]:py-0.5 [&_th]:py-1",children:[(0,s.jsx)(lq.ss,{children:(0,s.jsxs)(lq.SC,{children:[(0,s.jsx)(lq.xs,{className:"py-1 h-8",children:"Alias Name"}),(0,s.jsx)(lq.xs,{className:"py-1 h-8",children:"Target Model Group"}),(0,s.jsx)(lq.xs,{className:"py-1 h-8",children:"Actions"})]})}),(0,s.jsxs)(lq.RM,{children:[i.map(e=>(0,s.jsx)(lq.SC,{className:"h-8",children:c&&c.id===e.id?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(lq.pj,{className:"py-0.5",children:(0,s.jsx)("input",{type:"text",value:c.aliasName,onChange:e=>m({...c,aliasName:e.target.value}),className:"w-full px-2 py-1 border border-gray-300 rounded-md text-sm"})}),(0,s.jsx)(lq.pj,{className:"py-0.5",children:(0,s.jsx)("input",{type:"text",value:c.targetModelGroup,onChange:e=>m({...c,targetModelGroup:e.target.value}),className:"w-full px-2 py-1 border border-gray-300 rounded-md text-sm"})}),(0,s.jsx)(lq.pj,{className:"py-0.5 whitespace-nowrap",children:(0,s.jsxs)("div",{className:"flex space-x-2",children:[(0,s.jsx)("button",{onClick:j,className:"text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded hover:bg-blue-100",children:"Save"}),(0,s.jsx)("button",{onClick:v,className:"text-xs bg-gray-50 text-gray-600 px-2 py-1 rounded hover:bg-gray-100",children:"Cancel"})]})})]}):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(lq.pj,{className:"py-0.5 text-sm text-gray-900",children:e.aliasName}),(0,s.jsx)(lq.pj,{className:"py-0.5 text-sm text-gray-500",children:e.targetModelGroup}),(0,s.jsx)(lq.pj,{className:"py-0.5 whitespace-nowrap",children:(0,s.jsxs)("div",{className:"flex space-x-2",children:[(0,s.jsx)("button",{onClick:()=>g(e),className:"text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded hover:bg-blue-100",children:(0,s.jsx)(lV.Z,{className:"w-3 h-3"})}),(0,s.jsx)("button",{onClick:()=>_(e.id),className:"text-xs bg-red-50 text-red-600 px-2 py-1 rounded hover:bg-red-100",children:(0,s.jsx)(S.Z,{className:"w-3 h-3"})})]})})]})},e.id)),0===i.length&&(0,s.jsx)(lq.SC,{children:(0,s.jsx)(lq.pj,{colSpan:3,className:"py-0.5 text-sm text-gray-500 text-center",children:"No aliases added yet. Add a new alias above."})})]})]})})}),(0,s.jsxs)(lq.Zb,{children:[(0,s.jsx)(lq.Dx,{className:"mb-4",children:"Configuration Example"}),(0,s.jsx)(lq.xv,{className:"text-gray-600 mb-4",children:"Here's how your current aliases would look in the config.yaml:"}),(0,s.jsx)("div",{className:"bg-gray-100 rounded-lg p-4 font-mono text-sm",children:(0,s.jsxs)("div",{className:"text-gray-700",children:["router_settings:",(0,s.jsx)("br",{}),"\xa0\xa0model_group_alias:",0===Object.keys(b).length?(0,s.jsxs)("span",{className:"text-gray-500",children:[(0,s.jsx)("br",{}),"\xa0\xa0\xa0\xa0# No aliases configured yet"]}):Object.entries(b).map(e=>{let[l,t]=e;return(0,s.jsxs)("span",{children:[(0,s.jsx)("br",{}),'\xa0\xa0\xa0\xa0"',l,'": "',t,'"']},l)})]})})]})]})]})},lD=t(10900),lB=t(12514),lG=t(49566),lU=t(30401),lH=t(78867),lK=t(59872),lJ=e=>{let{isVisible:l,onCancel:t,onSuccess:r,modelData:i,accessToken:n,userRole:o}=e,[d]=eg.Z.useForm(),[c,m]=(0,f.useState)(!1),[u,h]=(0,f.useState)([]),[x,p]=(0,f.useState)([]),[g,j]=(0,f.useState)(!1),[v,b]=(0,f.useState)(!1),[y,N]=(0,f.useState)(null);(0,f.useEffect)(()=>{l&&i&&w()},[l,i]),(0,f.useEffect)(()=>{let e=async()=>{if(n)try{let e=await (0,a.modelAvailableCall)(n,"","",!1,null,!0,!0);h(e.data.map(e=>e.id))}catch(e){console.error("Error fetching model access groups:",e)}},t=async()=>{if(n)try{let e=await (0,e1.p)(n);p(e)}catch(e){console.error("Error fetching model info:",e)}};l&&(e(),t())},[l,n]);let w=()=>{try{var e,l,t,s,a,r;let n=null;(null===(e=i.litellm_params)||void 0===e?void 0:e.auto_router_config)&&(n="string"==typeof i.litellm_params.auto_router_config?JSON.parse(i.litellm_params.auto_router_config):i.litellm_params.auto_router_config),N(n),d.setFieldsValue({auto_router_name:i.model_name,auto_router_default_model:(null===(l=i.litellm_params)||void 0===l?void 0:l.auto_router_default_model)||"",auto_router_embedding_model:(null===(t=i.litellm_params)||void 0===t?void 0:t.auto_router_embedding_model)||"",model_access_group:(null===(s=i.model_info)||void 0===s?void 0:s.access_groups)||[]});let o=new Set(x.map(e=>e.model_group));j(!o.has(null===(a=i.litellm_params)||void 0===a?void 0:a.auto_router_default_model)),b(!o.has(null===(r=i.litellm_params)||void 0===r?void 0:r.auto_router_embedding_model))}catch(e){console.error("Error parsing auto router config:",e),eo.Z.fromBackend("Error loading auto router configuration")}},Z=async()=>{try{m(!0);let e=await d.validateFields(),l={...i.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},s={...i.model_info,access_groups:e.model_access_group||[]},o={model_name:e.auto_router_name,litellm_params:l,model_info:s};await (0,a.modelPatchUpdateCall)(n,o,i.model_info.id);let c={...i,model_name:e.auto_router_name,litellm_params:l,model_info:s};eo.Z.success("Auto router configuration updated successfully"),r(c),t()}catch(e){console.error("Error updating auto router:",e),eo.Z.fromBackend("Failed to update auto router configuration")}finally{m(!1)}},C=x.map(e=>({value:e.model_group,label:e.model_group}));return(0,s.jsx)(ea.Z,{title:"Edit Auto Router Configuration",open:l,onCancel:t,footer:[(0,s.jsx)(_.ZP,{onClick:t,children:"Cancel"},"cancel"),(0,s.jsx)(_.ZP,{loading:c,onClick:Z,children:"Save Changes"},"submit")],width:1e3,destroyOnClose:!0,children:(0,s.jsxs)("div",{className:"space-y-6",children:[(0,s.jsx)(eN.x,{className:"text-gray-600",children:"Edit the auto router configuration including routing logic, default models, and access settings."}),(0,s.jsxs)(eg.Z,{form:d,layout:"vertical",className:"space-y-4",children:[(0,s.jsx)(eg.Z.Item,{label:"Auto Router Name",name:"auto_router_name",rules:[{required:!0,message:"Auto router name is required"}],children:(0,s.jsx)(eN.o,{placeholder:"e.g., auto_router_1, smart_routing"})}),(0,s.jsx)("div",{className:"w-full",children:(0,s.jsx)(e9,{modelInfo:x,value:y,onChange:e=>{N(e)}})}),(0,s.jsx)(eg.Z.Item,{label:"Default Model",name:"auto_router_default_model",rules:[{required:!0,message:"Default model is required"}],children:(0,s.jsx)(ev.default,{placeholder:"Select a default model",onChange:e=>{j("custom"===e)},options:[...C,{value:"custom",label:"Enter custom model name"}],showSearch:!0})}),(0,s.jsx)(eg.Z.Item,{label:"Embedding Model",name:"auto_router_embedding_model",children:(0,s.jsx)(ev.default,{placeholder:"Select an embedding model (optional)",onChange:e=>{b("custom"===e)},options:[...C,{value:"custom",label:"Enter custom model name"}],showSearch:!0,allowClear:!0})}),"Admin"===o&&(0,s.jsx)(eg.Z.Item,{label:"Model Access Groups",name:"model_access_group",tooltip:"Control who can access this auto router",children:(0,s.jsx)(ev.default,{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})})]})]})})};let{Title:lW,Link:lY}=Q.default;var l$=e=>{let{isVisible:l,onCancel:t,onAddCredential:a,existingCredential:r,setIsCredentialModalOpen:i}=e,[n]=eg.Z.useForm();return console.log("existingCredential in add credentials tab: ".concat(JSON.stringify(r))),(0,s.jsx)(ea.Z,{title:"Reuse Credentials",visible:l,onCancel:()=>{t(),n.resetFields()},footer:null,width:600,children:(0,s.jsxs)(eg.Z,{form:n,onFinish:e=>{a(e),n.resetFields(),i(!1)},layout:"vertical",children:[(0,s.jsx)(eg.Z.Item,{label:"Credential Name:",name:"credential_name",rules:[{required:!0,message:"Credential name is required"}],initialValue:null==r?void 0:r.credential_name,children:(0,s.jsx)(ej.o,{placeholder:"Enter a friendly name for these credentials"})}),Object.entries((null==r?void 0:r.credential_values)||{}).map(e=>{let[l,t]=e;return(0,s.jsx)(eg.Z.Item,{label:l,name:l,initialValue:t,children:(0,s.jsx)(ej.o,{placeholder:"Enter ".concat(l),disabled:!0})},l)}),(0,s.jsxs)("div",{className:"flex justify-between items-center",children:[(0,s.jsx)(M.Z,{title:"Get help on our github",children:(0,s.jsx)(lY,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})}),(0,s.jsxs)("div",{children:[(0,s.jsx)(_.ZP,{onClick:()=>{t(),n.resetFields()},style:{marginRight:10},children:"Cancel"}),(0,s.jsx)(_.ZP,{htmlType:"submit",children:"Reuse Credentials"})]})]})]})})};function lX(e){var l,t,r,i,n,o,d,c,h,x,p,g,j,v,b,y,N,w,Z,C,A,P,F,I,V,q,B,G,U,H,J,Y,$;let{modelId:X,onClose:Q,accessToken:ee,userID:el,userRole:et,onModelUpdate:es,modelAccessGroups:er}=e,[ei]=eg.Z.useForm(),[en,ed]=(0,f.useState)(null),[ec,em]=(0,f.useState)(!1),[eu,eh]=(0,f.useState)(!1),[ex,ep]=(0,f.useState)(!1),[ej,e_]=(0,f.useState)(!1),[eb,ey]=(0,f.useState)(!1),[eN,ew]=(0,f.useState)(!1),[eZ,eC]=(0,f.useState)(null),[eS,eA]=(0,f.useState)(!1),[eE,eP]=(0,f.useState)({}),[eM,eL]=(0,f.useState)(!1),[eF,eI]=(0,f.useState)([]),[eT,eR]=(0,f.useState)({}),{data:eV,isLoading:eq}=(0,u.XP)(1,50,void 0,X),{data:eU}=m(),{data:eH}=(0,u.VI)(),eK=e=>null!=eU&&"object"==typeof eU&&e in eU?eU[e].litellm_provider:"openai",eJ=(0,f.useMemo)(()=>(null==eV?void 0:eV.data)&&0!==eV.data.length&&K(eV,eK).data[0]||null,[eV,eU]),eW=("Admin"===et||(null==eJ?void 0:null===(l=eJ.model_info)||void 0===l?void 0:l.created_by)===el)&&(null==eJ?void 0:null===(t=eJ.model_info)||void 0===t?void 0:t.db_model),eY="Admin"===et,e$=(null==eJ?void 0:null===(r=eJ.litellm_params)||void 0===r?void 0:r.auto_router_config)!=null,eX=(null==eJ?void 0:null===(i=eJ.litellm_params)||void 0===i?void 0:i.litellm_credential_name)!=null&&(null==eJ?void 0:null===(n=eJ.litellm_params)||void 0===n?void 0:n.litellm_credential_name)!=void 0;(0,f.useEffect)(()=>{if(eJ&&!en){var e,l,t,s,a,r,i;let n=eJ;n.litellm_model_name||(n={...n,litellm_model_name:null!==(i=null!==(r=null!==(a=null==n?void 0:null===(l=n.litellm_params)||void 0===l?void 0:l.litellm_model_name)&&void 0!==a?a:null==n?void 0:null===(t=n.litellm_params)||void 0===t?void 0:t.model)&&void 0!==r?r:null==n?void 0:null===(s=n.model_info)||void 0===s?void 0:s.key)&&void 0!==i?i:null}),ed(n),(null==n?void 0:null===(e=n.litellm_params)||void 0===e?void 0:e.cache_control_injection_points)&&eA(!0)}},[eJ,en]),(0,f.useEffect)(()=>{let e=async()=>{var e,l,t,s,r,i,n;if(!ee||eJ)return;let o=await (0,a.modelInfoV1Call)(ee,X);console.log("modelInfoResponse, ",o);let d=o.data[0];d&&!d.litellm_model_name&&(d={...d,litellm_model_name:null!==(n=null!==(i=null!==(r=null==d?void 0:null===(l=d.litellm_params)||void 0===l?void 0:l.litellm_model_name)&&void 0!==r?r:null==d?void 0:null===(t=d.litellm_params)||void 0===t?void 0:t.model)&&void 0!==i?i:null==d?void 0:null===(s=d.model_info)||void 0===s?void 0:s.key)&&void 0!==n?n:null}),ed(d),(null==d?void 0:null===(e=d.litellm_params)||void 0===e?void 0:e.cache_control_injection_points)&&eA(!0)},l=async()=>{if(ee)try{let e=(await (0,a.getGuardrailsList)(ee)).guardrails.map(e=>e.guardrail_name);eI(e)}catch(e){console.error("Failed to fetch guardrails:",e)}},t=async()=>{if(ee)try{let e=await (0,a.tagListCall)(ee);eR(e)}catch(e){console.error("Failed to fetch tags:",e)}};(async()=>{if(console.log("accessToken, ",ee),!ee||eX)return;let e=await (0,a.credentialGetCall)(ee,null,X);console.log("existingCredentialResponse, ",e),eC({credential_name:e.credential_name,credential_values:e.credential_values,credential_info:e.credential_info})})(),e(),l(),t()},[ee,X]);let eQ=async e=>{var l;if(console.log("values, ",e),!ee)return;let t={credential_name:e.credential_name,model_id:X,credential_info:{custom_llm_provider:null===(l=en.litellm_params)||void 0===l?void 0:l.custom_llm_provider}};eo.Z.info("Storing credential.."),console.log("credentialResponse, ",await (0,a.credentialCreateCall)(ee,t)),eo.Z.success("Credential stored successfully")},e0=async e=>{try{var l;let t;if(!ee)return;ey(!0),console.log("values.model_name, ",e.model_name);let s={};try{s=e.litellm_extra_params?JSON.parse(e.litellm_extra_params):{}}catch(e){eo.Z.fromBackend("Invalid JSON in LiteLLM Params"),ey(!1);return}let r={...e.litellm_params,...s,model:e.litellm_model_name,api_base:e.api_base,custom_llm_provider:e.custom_llm_provider,organization:e.organization,tpm:e.tpm,rpm:e.rpm,max_retries:e.max_retries,timeout:e.timeout,stream_timeout:e.stream_timeout,input_cost_per_token:e.input_cost/1e6,output_cost_per_token:e.output_cost/1e6,tags:e.tags};e.guardrails&&(r.guardrails=e.guardrails),e.cache_control&&(null===(l=e.cache_control_injection_points)||void 0===l?void 0:l.length)>0?r.cache_control_injection_points=e.cache_control_injection_points:delete r.cache_control_injection_points;try{t=e.model_info?JSON.parse(e.model_info):eJ.model_info,e.model_access_group&&(t={...t,access_groups:e.model_access_group}),void 0!==e.health_check_model&&(t={...t,health_check_model:e.health_check_model})}catch(e){eo.Z.fromBackend("Invalid JSON in Model Info");return}let i={model_name:e.model_name,litellm_params:r,model_info:t};await (0,a.modelPatchUpdateCall)(ee,i,X);let n={...en,model_name:e.model_name,litellm_model_name:e.litellm_model_name,litellm_params:r,model_info:t};ed(n),es&&es(n),eo.Z.success("Model settings updated successfully"),e_(!1),ew(!1)}catch(e){console.error("Error updating model:",e),eo.Z.fromBackend("Failed to update model settings")}finally{ey(!1)}};if(eq)return(0,s.jsxs)("div",{className:"p-4",children:[(0,s.jsx)(E.Z,{icon:lD.Z,variant:"light",onClick:Q,className:"mb-4",children:"Back to Models"}),(0,s.jsx)(D.Z,{children:"Loading..."})]});if(!eJ)return(0,s.jsxs)("div",{className:"p-4",children:[(0,s.jsx)(E.Z,{icon:lD.Z,variant:"light",onClick:Q,className:"mb-4",children:"Back to Models"}),(0,s.jsx)(D.Z,{children:"Model not found"})]});let e1=async()=>{if(ee)try{var e,l,t;eo.Z.info("Testing connection...");let s=await (0,a.testConnectionRequest)(ee,{custom_llm_provider:en.litellm_params.custom_llm_provider,litellm_credential_name:en.litellm_params.litellm_credential_name,model:en.litellm_model_name},{mode:null===(e=en.model_info)||void 0===e?void 0:e.mode},null===(l=en.model_info)||void 0===l?void 0:l.mode);if("success"===s.status)eo.Z.success("Connection test successful!");else throw Error((null==s?void 0:null===(t=s.result)||void 0===t?void 0:t.error)||(null==s?void 0:s.message)||"Unknown error")}catch(e){e instanceof Error?eo.Z.error("Error testing connection: "+(0,lf.aS)(e.message,100)):eo.Z.error("Error testing connection: "+String(e))}},e2=async()=>{try{if(eh(!0),!ee)return;await (0,a.modelDeleteCall)(ee,X),eo.Z.success("Model deleted successfully"),es&&es({deleted:!0,model_info:{id:X}}),Q()}catch(e){console.error("Error deleting the model:",e),eo.Z.fromBackend("Failed to delete model")}finally{eh(!1),em(!1)}},e4=async(e,l)=>{await (0,lK.vQ)(e)&&(eP(e=>({...e,[l]:!0})),setTimeout(()=>{eP(e=>({...e,[l]:!1}))},2e3))},e5=eJ.litellm_model_name.includes("*");return console.log("isWildcardModel, ",e5),(0,s.jsxs)("div",{className:"p-4",children:[(0,s.jsxs)("div",{className:"flex justify-between items-center mb-6",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)(E.Z,{icon:lD.Z,variant:"light",onClick:Q,className:"mb-4",children:"Back to Models"}),(0,s.jsxs)(W.Z,{children:["Public Model Name: ",T(eJ)]}),(0,s.jsxs)("div",{className:"flex items-center cursor-pointer",children:[(0,s.jsx)(D.Z,{className:"text-gray-500 font-mono",children:eJ.model_info.id}),(0,s.jsx)(_.ZP,{type:"text",size:"small",icon:eE["model-id"]?(0,s.jsx)(lU.Z,{size:12}):(0,s.jsx)(lH.Z,{size:12}),onClick:()=>e4(eJ.model_info.id,"model-id"),className:"left-2 z-10 transition-all duration-200 ".concat(eE["model-id"]?"text-green-600 bg-green-50 border-green-200":"text-gray-500 hover:text-gray-700 hover:bg-gray-100")})]})]}),(0,s.jsxs)("div",{className:"flex gap-2",children:[(0,s.jsx)(E.Z,{variant:"secondary",icon:eO.Z,onClick:e1,className:"flex items-center gap-2","data-testid":"test-connection-button",children:"Test Connection"}),(0,s.jsx)(E.Z,{icon:k.Z,variant:"secondary",onClick:()=>ep(!0),className:"flex items-center",disabled:!eY,"data-testid":"reuse-credentials-button",children:"Re-use Credentials"}),(0,s.jsx)(E.Z,{icon:S.Z,variant:"secondary",onClick:()=>em(!0),className:"flex items-center text-red-500 border-red-500 hover:text-red-700",disabled:!eW,"data-testid":"delete-model-button",children:"Delete Model"})]})]}),(0,s.jsxs)(eD.Z,{children:[(0,s.jsxs)(eB.Z,{className:"mb-6",children:[(0,s.jsx)(ez.Z,{children:"Overview"}),(0,s.jsx)(ez.Z,{children:"Raw JSON"})]}),(0,s.jsxs)(eG.Z,{children:[(0,s.jsxs)(z.Z,{children:[(0,s.jsxs)(O.Z,{numItems:1,numItemsSm:2,numItemsLg:3,className:"gap-6 mb-6",children:[(0,s.jsxs)(lB.Z,{children:[(0,s.jsx)(D.Z,{children:"Provider"}),(0,s.jsxs)("div",{className:"mt-2 flex items-center space-x-2",children:[eJ.provider&&(0,s.jsx)("img",{src:(0,L.dr)(eJ.provider).logo,alt:"".concat(eJ.provider," logo"),className:"w-4 h-4",onError:e=>{let l=e.currentTarget,t=l.parentElement;if(t&&t.contains(l))try{var s;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=(null===(s=eJ.provider)||void 0===s?void 0:s.charAt(0))||"-",t.replaceChild(e,l)}catch(e){console.error("Failed to replace provider logo fallback:",e)}}}),(0,s.jsx)(W.Z,{children:eJ.provider||"Not Set"})]})]}),(0,s.jsxs)(lB.Z,{children:[(0,s.jsx)(D.Z,{children:"LiteLLM Model"}),(0,s.jsx)("div",{className:"mt-2 overflow-hidden",children:(0,s.jsx)(M.Z,{title:eJ.litellm_model_name||"Not Set",children:(0,s.jsx)("div",{className:"break-all text-sm font-medium leading-relaxed cursor-pointer",children:eJ.litellm_model_name||"Not Set"})})})]}),(0,s.jsxs)(lB.Z,{children:[(0,s.jsx)(D.Z,{children:"Pricing"}),(0,s.jsxs)("div",{className:"mt-2",children:[(0,s.jsxs)(D.Z,{children:["Input: $",eJ.input_cost,"/1M tokens"]}),(0,s.jsxs)(D.Z,{children:["Output: $",eJ.output_cost,"/1M tokens"]})]})]})]}),(0,s.jsxs)("div",{className:"mb-6 text-sm text-gray-500 flex items-center gap-x-6",children:[(0,s.jsxs)("div",{className:"flex items-center gap-x-2",children:[(0,s.jsx)("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,s.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"," ",eJ.model_info.created_at?new Date(eJ.model_info.created_at).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"}):"Not Set"]}),(0,s.jsxs)("div",{className:"flex items-center gap-x-2",children:[(0,s.jsx)("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,s.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 ",eJ.model_info.created_by||"Not Set"]})]}),(0,s.jsxs)(lB.Z,{children:[(0,s.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,s.jsx)(W.Z,{children:"Model Settings"}),(0,s.jsxs)("div",{className:"flex gap-2",children:[e$&&eW&&!eN&&(0,s.jsx)(E.Z,{onClick:()=>eL(!0),className:"flex items-center",children:"Edit Auto Router"}),eW?!eN&&(0,s.jsx)(E.Z,{onClick:()=>ew(!0),className:"flex items-center",children:"Edit Settings"}):(0,s.jsx)(M.Z,{title:"Only DB models can be edited. You must be an admin or the creator of the model to edit it.",children:(0,s.jsx)(R.Z,{})})]})]}),en?(0,s.jsx)(eg.Z,{form:ei,onFinish:e0,initialValues:{model_name:en.model_name,litellm_model_name:en.litellm_model_name,api_base:en.litellm_params.api_base,custom_llm_provider:en.litellm_params.custom_llm_provider,organization:en.litellm_params.organization,tpm:en.litellm_params.tpm,rpm:en.litellm_params.rpm,max_retries:en.litellm_params.max_retries,timeout:en.litellm_params.timeout,stream_timeout:en.litellm_params.stream_timeout,input_cost:en.litellm_params.input_cost_per_token?1e6*en.litellm_params.input_cost_per_token:(null===(o=en.model_info)||void 0===o?void 0:o.input_cost_per_token)*1e6||null,output_cost:(null===(d=en.litellm_params)||void 0===d?void 0:d.output_cost_per_token)?1e6*en.litellm_params.output_cost_per_token:(null===(c=en.model_info)||void 0===c?void 0:c.output_cost_per_token)*1e6||null,cache_control:null!==(h=en.litellm_params)&&void 0!==h&&!!h.cache_control_injection_points,cache_control_injection_points:(null===(x=en.litellm_params)||void 0===x?void 0:x.cache_control_injection_points)||[],model_access_group:Array.isArray(null===(p=en.model_info)||void 0===p?void 0:p.access_groups)?en.model_info.access_groups:[],guardrails:Array.isArray(null===(g=en.litellm_params)||void 0===g?void 0:g.guardrails)?en.litellm_params.guardrails:[],tags:Array.isArray(null===(j=en.litellm_params)||void 0===j?void 0:j.tags)?en.litellm_params.tags:[],health_check_model:e5?null===(v=en.model_info)||void 0===v?void 0:v.health_check_model:null,litellm_extra_params:JSON.stringify(en.litellm_params||{},null,2)},layout:"vertical",onValuesChange:()=>e_(!0),children:(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"Model Name"}),eN?(0,s.jsx)(eg.Z.Item,{name:"model_name",className:"mb-0",children:(0,s.jsx)(lG.Z,{placeholder:"Enter model name"})}):(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:en.model_name})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"LiteLLM Model Name"}),eN?(0,s.jsx)(eg.Z.Item,{name:"litellm_model_name",className:"mb-0",children:(0,s.jsx)(lG.Z,{placeholder:"Enter LiteLLM model name"})}):(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:en.litellm_model_name})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"Input Cost (per 1M tokens)"}),eN?(0,s.jsx)(eg.Z.Item,{name:"input_cost",className:"mb-0",children:(0,s.jsx)(lx.Z,{placeholder:"Enter input cost"})}):(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:(null==en?void 0:null===(b=en.litellm_params)||void 0===b?void 0:b.input_cost_per_token)?((null===(y=en.litellm_params)||void 0===y?void 0:y.input_cost_per_token)*1e6).toFixed(4):(null==en?void 0:null===(N=en.model_info)||void 0===N?void 0:N.input_cost_per_token)?(1e6*en.model_info.input_cost_per_token).toFixed(4):null})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"Output Cost (per 1M tokens)"}),eN?(0,s.jsx)(eg.Z.Item,{name:"output_cost",className:"mb-0",children:(0,s.jsx)(lx.Z,{placeholder:"Enter output cost"})}):(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:(null==en?void 0:null===(w=en.litellm_params)||void 0===w?void 0:w.output_cost_per_token)?(1e6*en.litellm_params.output_cost_per_token).toFixed(4):(null==en?void 0:null===(Z=en.model_info)||void 0===Z?void 0:Z.output_cost_per_token)?(1e6*en.model_info.output_cost_per_token).toFixed(4):null})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"API Base"}),eN?(0,s.jsx)(eg.Z.Item,{name:"api_base",className:"mb-0",children:(0,s.jsx)(lG.Z,{placeholder:"Enter API base"})}):(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:(null===(C=en.litellm_params)||void 0===C?void 0:C.api_base)||"Not Set"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"Custom LLM Provider"}),eN?(0,s.jsx)(eg.Z.Item,{name:"custom_llm_provider",className:"mb-0",children:(0,s.jsx)(lG.Z,{placeholder:"Enter custom LLM provider"})}):(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:(null===(A=en.litellm_params)||void 0===A?void 0:A.custom_llm_provider)||"Not Set"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"Organization"}),eN?(0,s.jsx)(eg.Z.Item,{name:"organization",className:"mb-0",children:(0,s.jsx)(lG.Z,{placeholder:"Enter organization"})}):(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:(null===(P=en.litellm_params)||void 0===P?void 0:P.organization)||"Not Set"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"TPM (Tokens per Minute)"}),eN?(0,s.jsx)(eg.Z.Item,{name:"tpm",className:"mb-0",children:(0,s.jsx)(lx.Z,{placeholder:"Enter TPM"})}):(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:(null===(F=en.litellm_params)||void 0===F?void 0:F.tpm)||"Not Set"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"RPM (Requests per Minute)"}),eN?(0,s.jsx)(eg.Z.Item,{name:"rpm",className:"mb-0",children:(0,s.jsx)(lx.Z,{placeholder:"Enter RPM"})}):(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:(null===(I=en.litellm_params)||void 0===I?void 0:I.rpm)||"Not Set"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"Max Retries"}),eN?(0,s.jsx)(eg.Z.Item,{name:"max_retries",className:"mb-0",children:(0,s.jsx)(lx.Z,{placeholder:"Enter max retries"})}):(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:(null===(V=en.litellm_params)||void 0===V?void 0:V.max_retries)||"Not Set"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"Timeout (seconds)"}),eN?(0,s.jsx)(eg.Z.Item,{name:"timeout",className:"mb-0",children:(0,s.jsx)(lx.Z,{placeholder:"Enter timeout"})}):(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:(null===(q=en.litellm_params)||void 0===q?void 0:q.timeout)||"Not Set"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"Stream Timeout (seconds)"}),eN?(0,s.jsx)(eg.Z.Item,{name:"stream_timeout",className:"mb-0",children:(0,s.jsx)(lx.Z,{placeholder:"Enter stream timeout"})}):(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:(null===(B=en.litellm_params)||void 0===B?void 0:B.stream_timeout)||"Not Set"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"Model Access Groups"}),eN?(0,s.jsx)(eg.Z.Item,{name:"model_access_group",className:"mb-0",children:(0,s.jsx)(ev.default,{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:null==er?void 0:er.map(e=>({value:e,label:e}))})}):(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:(null===(G=en.model_info)||void 0===G?void 0:G.access_groups)?Array.isArray(en.model_info.access_groups)?en.model_info.access_groups.length>0?(0,s.jsx)("div",{className:"flex flex-wrap gap-1",children:en.model_info.access_groups.map((e,l)=>(0,s.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":en.model_info.access_groups:"Not Set"})]}),(0,s.jsxs)("div",{children:[(0,s.jsxs)(D.Z,{className:"font-medium",children:["Guardrails",(0,s.jsx)(M.Z,{title:"Apply safety guardrails to this model to filter content or enforce policies",children:(0,s.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/quick_start",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,s.jsx)(R.Z,{style:{marginLeft:"4px"}})})})]}),eN?(0,s.jsx)(eg.Z.Item,{name:"guardrails",className:"mb-0",children:(0,s.jsx)(ev.default,{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:eF.map(e=>({value:e,label:e}))})}):(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:(null===(U=en.litellm_params)||void 0===U?void 0:U.guardrails)?Array.isArray(en.litellm_params.guardrails)?en.litellm_params.guardrails.length>0?(0,s.jsx)("div",{className:"flex flex-wrap gap-1",children:en.litellm_params.guardrails.map((e,l)=>(0,s.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":en.litellm_params.guardrails:"Not Set"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"Tags"}),eN?(0,s.jsx)(eg.Z.Item,{name:"tags",className:"mb-0",children:(0,s.jsx)(ev.default,{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(eT).map(e=>({value:e.name,label:e.name,title:e.description||e.name}))})}):(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:(null===(H=en.litellm_params)||void 0===H?void 0:H.tags)?Array.isArray(en.litellm_params.tags)?en.litellm_params.tags.length>0?(0,s.jsx)("div",{className:"flex flex-wrap gap-1",children:en.litellm_params.tags.map((e,l)=>(0,s.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":en.litellm_params.tags:"Not Set"})]}),e5&&(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"Health Check Model"}),eN?(0,s.jsx)(eg.Z.Item,{name:"health_check_model",className:"mb-0",children:(0,s.jsx)(ev.default,{showSearch:!0,placeholder:"Select existing health check model",optionFilterProp:"children",allowClear:!0,options:(()=>{var e;let l=eJ.litellm_model_name.split("/")[0];return(null==eH?void 0:null===(e=eH.data)||void 0===e?void 0:e.filter(e=>{var t;return(null===(t=e.providers)||void 0===t?void 0:t.includes(l))&&e.model_group!==eJ.litellm_model_name}).map(e=>({value:e.model_group,label:e.model_group})))||[]})()})}):(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:(null===(J=en.model_info)||void 0===J?void 0:J.health_check_model)||"Not Set"})]}),eN?(0,s.jsx)(lg,{form:ei,showCacheControl:eS,onCacheControlChange:e=>eA(e)}):(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"Cache Control"}),(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:(null===(Y=en.litellm_params)||void 0===Y?void 0:Y.cache_control_injection_points)?(0,s.jsxs)("div",{children:[(0,s.jsx)("p",{children:"Enabled"}),(0,s.jsx)("div",{className:"mt-2",children:en.litellm_params.cache_control_injection_points.map((e,l)=>(0,s.jsxs)("div",{className:"text-sm text-gray-600 mb-1",children:["Location: ",e.location,",",e.role&&(0,s.jsxs)("span",{children:[" Role: ",e.role]}),void 0!==e.index&&(0,s.jsxs)("span",{children:[" Index: ",e.index]})]},l))})]}):"Disabled"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"Model Info"}),eN?(0,s.jsx)(eg.Z.Item,{name:"model_info",className:"mb-0",children:(0,s.jsx)(ek.default.TextArea,{rows:4,placeholder:'{"gpt-4": 100, "claude-v1": 200}',defaultValue:JSON.stringify(eJ.model_info,null,2)})}):(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:(0,s.jsx)("pre",{className:"bg-gray-100 p-2 rounded text-xs overflow-auto mt-1",children:JSON.stringify(en.model_info,null,2)})})]}),(0,s.jsxs)("div",{children:[(0,s.jsxs)(D.Z,{className:"font-medium",children:["LiteLLM Params",(0,s.jsx)(M.Z,{title:"Optional litellm params used for making a litellm.completion() call. Some params are automatically added by LiteLLM.",children:(0,s.jsx)("a",{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,s.jsx)(R.Z,{style:{marginLeft:"4px"}})})})]}),eN?(0,s.jsx)(eg.Z.Item,{name:"litellm_extra_params",rules:[{validator:lf.Ac}],children:(0,s.jsx)(ek.default.TextArea,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}):(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:(0,s.jsx)("pre",{className:"bg-gray-100 p-2 rounded text-xs overflow-auto mt-1",children:JSON.stringify(en.litellm_params,null,2)})})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(D.Z,{className:"font-medium",children:"Team ID"}),(0,s.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:eJ.model_info.team_id||"Not Set"})]})]}),eN&&(0,s.jsxs)("div",{className:"mt-6 flex justify-end gap-2",children:[(0,s.jsx)(E.Z,{variant:"secondary",onClick:()=>{ei.resetFields(),e_(!1),ew(!1)},disabled:eb,children:"Cancel"}),(0,s.jsx)(E.Z,{variant:"primary",onClick:()=>ei.submit(),loading:eb,children:"Save Changes"})]})]})}):(0,s.jsx)(D.Z,{children:"Loading..."})]})]}),(0,s.jsx)(z.Z,{children:(0,s.jsx)(lB.Z,{children:(0,s.jsx)("pre",{className:"bg-gray-100 p-4 rounded text-xs overflow-auto",children:JSON.stringify(eJ,null,2)})})})]})]}),(0,s.jsx)(ef.Z,{isOpen:ec,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:(null==eJ?void 0:eJ.model_name)||"Not Set"},{label:"LiteLLM Model Name",value:(null==eJ?void 0:eJ.litellm_model_name)||"Not Set"},{label:"Provider",value:(null==eJ?void 0:eJ.provider)||"Not Set"},{label:"Created By",value:(null==eJ?void 0:null===($=eJ.model_info)||void 0===$?void 0:$.created_by)||"Not Set"}],onCancel:()=>em(!1),onOk:e2,confirmLoading:eu}),ex&&!eX?(0,s.jsx)(l$,{isVisible:ex,onCancel:()=>ep(!1),onAddCredential:eQ,existingCredential:eZ,setIsCredentialModalOpen:ep}):(0,s.jsx)(ea.Z,{open:ex,onCancel:()=>ep(!1),title:"Using Existing Credential",children:(0,s.jsx)(D.Z,{children:eJ.litellm_params.litellm_credential_name})}),(0,s.jsx)(lJ,{isVisible:eM,onCancel:()=>eL(!1),onSuccess:e=>{ed(e),es&&es(e)},modelData:en||eJ,accessToken:ee||"",userRole:et||""})]})}var lQ=t(27593),l0=t(56147),l1=e=>{var l;let{premiumUser:t,teams:r}=e,{accessToken:i,token:o,userRole:c,userId:x}=(0,n.Z)(),[p]=eg.Z.useForm(),[g,j]=(0,f.useState)(""),[v,_]=(0,f.useState)([]),[b,y]=(0,f.useState)(L.Cl.Anthropic),[N,w]=(0,f.useState)(null),[Z,C]=(0,f.useState)(null),[k,S]=(0,f.useState)(null),[A,E]=(0,f.useState)(0),[M,F]=(0,f.useState)({}),[I,R]=(0,f.useState)(!1),[V,q]=(0,f.useState)(null),[B,G]=(0,f.useState)(null),[U,H]=(0,f.useState)(0),W=(0,eV.NL)(),{data:Y,isLoading:$,refetch:ee}=(0,u.XP)(),{data:el,isLoading:et}=m(),{data:es,isLoading:ea}=d(),er=(null==es?void 0:es.credentials)||[],{data:ei,isLoading:en}=(0,h.L)(),ed=(0,f.useMemo)(()=>{if(!(null==Y?void 0:Y.data))return[];let e=new Set;for(let l of Y.data)e.add(l.model_name);return Array.from(e).sort()},[null==Y?void 0:Y.data]),ec=(0,f.useMemo)(()=>{if(!(null==Y?void 0:Y.data))return[];let e=new Set;for(let l of Y.data){let t=l.model_info;if(null==t?void 0:t.access_groups)for(let l of t.access_groups)e.add(l)}return Array.from(e)},[null==Y?void 0:Y.data]),eu=(0,f.useMemo)(()=>(null==Y?void 0:Y.data)?Y.data.map(e=>e.model_name):[],[null==Y?void 0:Y.data]),ex=e=>null!=el&&"object"==typeof el&&e in el?el[e].litellm_provider:"openai",ep=(0,f.useMemo)(()=>(null==Y?void 0:Y.data)?K(Y,ex):{data:[]},[null==Y?void 0:Y.data,ex]),ef=c&&(0,eR.P4)(c),ej=c&&eR.lo.includes(c),ev=x&&(0,eR.yV)(r,x),e_=ej&&(null==ei?void 0:null===(l=ei.values)||void 0===l?void 0:l.disable_model_add_for_internal_users)===!0,eb=!ef&&(e_||!ev),ey={name:"file",accept:".json",pastable:!1,beforeUpload:e=>{if("application/json"===e.type){let l=new FileReader;l.onload=e=>{if(e.target){let l=e.target.result;p.setFieldsValue({vertex_credentials:l})}},l.readAsText(e)}return!1},onChange(e){"done"===e.file.status?eo.Z.success("".concat(e.file.name," file uploaded successfully")):"error"===e.file.status&&eo.Z.fromBackend("".concat(e.file.name," file upload failed."))}},eN=()=>{j(new Date().toLocaleString()),W.invalidateQueries({queryKey:["models","list"]}),ee()},ew=async()=>{if(i)try{let e={router_settings:{}};"global"===N?(k&&(e.router_settings.retry_policy=k),eo.Z.success("Global retry settings saved successfully")):(Z&&(e.router_settings.model_group_retry_policy=Z),eo.Z.success("Retry settings saved successfully for ".concat(N))),await (0,a.setCallbacksCall)(i,e)}catch(e){eo.Z.fromBackend("Failed to save retry settings")}};if((0,f.useEffect)(()=>{if(!i||!o||!c||!x||!Y)return;let e=async()=>{try{let e=(await (0,a.getCallbacksCall)(i,x,c)).router_settings,l=e.model_group_retry_policy,t=e.num_retries;C(l),S(e.retry_policy),E(t);let s=e.model_group_alias||{};F(s)}catch(e){console.error("Error fetching model data:",e)}};i&&o&&c&&x&&Y&&e()},[i,o,c,x,Y]),c&&"Admin Viewer"==c){let{Title:e,Paragraph:l}=Q.default;return(0,s.jsxs)("div",{children:[(0,s.jsx)(e,{level:1,children:"Access Denied"}),(0,s.jsx)(l,{children:"Ask your proxy admin for access to view all models"})]})}let eZ=async()=>{try{let e=await p.validateFields();await eh(e,i,p,eN)}catch(t){var e;let l=(null===(e=t.errorFields)||void 0===e?void 0:e.map(e=>"".concat(e.name.join("."),": ").concat(e.errors.join(", "))).join(" | "))||"Unknown validation error";eo.Z.fromBackend("Please fill in the following required fields: ".concat(l))}};return(Object.keys(L.Cl).find(e=>L.Cl[e]===b),B)?(0,s.jsx)("div",{className:"w-full h-full",children:(0,s.jsx)(l0.Z,{teamId:B,onClose:()=>G(null),accessToken:i,is_team_admin:"Admin"===c,is_proxy_admin:"Proxy Admin"===c,userModels:eu,editTeam:!1,onUpdate:eN,premiumUser:t})}):(0,s.jsx)("div",{className:"w-full mx-4 h-[75vh]",children:(0,s.jsx)(O.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:(0,s.jsxs)(eq.Z,{numColSpan:1,className:"flex flex-col gap-2",children:[(0,s.jsx)("div",{className:"flex justify-between items-center mb-4",children:(0,s.jsxs)("div",{children:[(0,s.jsx)("h2",{className:"text-lg font-semibold",children:"Model Management"}),eR.ZL.includes(c)?(0,s.jsx)("p",{className:"text-sm text-gray-600",children:"Add and manage models for the proxy"}):(0,s.jsx)("p",{className:"text-sm text-gray-600",children:"Add models for teams you are an admin for."})]})}),(0,s.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,s.jsx)("div",{className:"flex-shrink-0 w-10 h-10 bg-white rounded-full flex items-center justify-center border border-blue-200",children:(0,s.jsx)(eU.Z,{style:{fontSize:"18px",color:"#6366f1"}})}),(0,s.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,s.jsx)("h4",{className:"text-gray-900 font-semibold text-sm m-0",children:"Missing a provider?"}),(0,s.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,s.jsxs)("a",{href:"https://models.litellm.ai/?request=true",target:"_blank",rel:"noopener noreferrer",className:"flex-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,s.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,s.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"})})]})]}),V&&!($||et||ea||en)?(0,s.jsx)(lX,{modelId:V,onClose:()=>{q(null)},accessToken:i,userID:x,userRole:c,onModelUpdate:e=>{W.invalidateQueries({queryKey:["models","list"]}),eN()},modelAccessGroups:ec}):(0,s.jsxs)(eD.Z,{index:U,onIndexChange:H,className:"gap-2 h-[75vh] w-full ",children:[(0,s.jsxs)(eB.Z,{className:"flex justify-between mt-2 w-full items-center",children:[(0,s.jsxs)("div",{className:"flex",children:[eR.ZL.includes(c)?(0,s.jsx)(ez.Z,{children:"All Models"}):(0,s.jsx)(ez.Z,{children:"Your Models"}),!eb&&(0,s.jsx)(ez.Z,{children:"Add Model"}),eR.ZL.includes(c)&&(0,s.jsx)(ez.Z,{children:"LLM Credentials"}),eR.ZL.includes(c)&&(0,s.jsx)(ez.Z,{children:"Pass-Through Endpoints"}),eR.ZL.includes(c)&&(0,s.jsx)(ez.Z,{children:"Health Status"}),eR.ZL.includes(c)&&(0,s.jsx)(ez.Z,{children:"Model Retry Settings"}),eR.ZL.includes(c)&&(0,s.jsx)(ez.Z,{children:"Model Group Alias"}),eR.ZL.includes(c)&&(0,s.jsx)(ez.Z,{children:"Price Data Reload"})]}),(0,s.jsxs)("div",{className:"flex items-center space-x-2",children:[g&&(0,s.jsxs)(D.Z,{children:["Last Refreshed: ",g]}),(0,s.jsx)(P.Z,{icon:eO.Z,variant:"shadow",size:"xs",className:"self-center",onClick:eN})]})]}),(0,s.jsxs)(eG.Z,{children:[(0,s.jsx)(J,{selectedModelGroup:N,setSelectedModelGroup:w,availableModelGroups:ed,availableModelAccessGroups:ec,setSelectedModelId:q,setSelectedTeamId:G}),!eb&&(0,s.jsx)(z.Z,{className:"h-full",children:(0,s.jsx)(lA,{form:p,handleOk:eZ,selectedProvider:b,setSelectedProvider:y,providerModels:v,setProviderModelsFn:e=>{_((0,L.bK)(e,el))},getPlaceholder:L.ph,uploadProps:ey,showAdvancedSettings:I,setShowAdvancedSettings:R,teams:r,credentials:er,accessToken:i,userRole:c})}),(0,s.jsx)(z.Z,{children:(0,s.jsx)(eT,{uploadProps:ey})}),(0,s.jsx)(z.Z,{children:(0,s.jsx)(lQ.Z,{accessToken:i,userRole:c,userID:x,modelData:ep,premiumUser:t})}),(0,s.jsx)(z.Z,{children:(0,s.jsx)(lT,{accessToken:i,modelData:ep,all_models_on_proxy:eu,getDisplayModelName:T,setSelectedModelId:q})}),(0,s.jsx)(X,{selectedModelGroup:N,setSelectedModelGroup:w,availableModelGroups:ed,globalRetryPolicy:k,setGlobalRetryPolicy:S,defaultRetry:A,modelGroupRetryPolicy:Z,setModelGroupRetryPolicy:C,handleSaveRetrySettings:ew}),(0,s.jsx)(z.Z,{children:(0,s.jsx)(lz,{accessToken:i,initialModelGroupAlias:M,onAliasUpdate:F})}),(0,s.jsx)(em,{})]})]})]})})})}},27593:function(e,l,t){t.d(l,{Z:function(){return Y}});var s=t(57437),a=t(2265),r=t(78489),i=t(47323),n=t(84264),o=t(96761),d=t(19250),c=t(99981),m=t(33866),u=t(15731),h=t(53410),x=t(74998),p=t(59341),g=t(49566),f=t(12514),j=t(97765),v=t(37592),_=t(10032),b=t(22116),y=t(51653),N=t(24199),w=t(12660),Z=t(15424),C=t(58760),k=t(5545),S=t(45246),A=t(96473),E=t(31283),P=e=>{let{value:l={},onChange:t}=e,[r,i]=(0,a.useState)(Object.entries(l)),n=e=>{let l=r.filter((l,t)=>t!==e);i(l),null==t||t(Object.fromEntries(l))},o=(e,l,s)=>{let a=[...r];a[e]=[l,s],i(a),null==t||t(Object.fromEntries(a))};return(0,s.jsxs)("div",{children:[r.map((e,l)=>{let[t,a]=e;return(0,s.jsxs)(C.Z,{style:{display:"flex",marginBottom:8},align:"center",children:[(0,s.jsx)(E.o,{placeholder:"Header Name",value:t,onChange:e=>o(l,e.target.value,a)}),(0,s.jsx)(E.o,{placeholder:"Header Value",value:a,onChange:e=>o(l,t,e.target.value)}),(0,s.jsx)("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",height:"100%"},children:(0,s.jsx)(S.Z,{onClick:()=>n(l),style:{cursor:"pointer"}})})]},l)}),(0,s.jsx)(k.ZP,{type:"dashed",onClick:()=>{i([...r,["",""]])},icon:(0,s.jsx)(A.Z,{}),children:"Add Header"})]})},M=t(77565),L=e=>{let{pathValue:l,targetValue:t,includeSubpath:a}=e,r=(0,d.getProxyBaseUrl)();return l&&t?(0,s.jsxs)(f.Z,{className:"p-5",children:[(0,s.jsx)(o.Z,{className:"text-lg font-semibold text-gray-900 mb-2",children:"Route Preview"}),(0,s.jsx)(j.Z,{className:"text-gray-600 mb-5",children:"How your requests will be routed"}),(0,s.jsxs)("div",{className:"space-y-5",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("div",{className:"text-base font-semibold text-gray-900 mb-3",children:"Basic routing:"}),(0,s.jsxs)("div",{className:"flex items-center gap-4",children:[(0,s.jsxs)("div",{className:"flex-1 bg-gray-50 border border-gray-200 rounded-lg p-3",children:[(0,s.jsx)("div",{className:"text-sm text-gray-600 mb-2",children:"Your endpoint"}),(0,s.jsx)("code",{className:"font-mono text-sm text-gray-900",children:l?"".concat(r).concat(l):""})]}),(0,s.jsx)("div",{className:"text-gray-400",children:(0,s.jsx)(M.Z,{className:"text-lg"})}),(0,s.jsxs)("div",{className:"flex-1 bg-gray-50 border border-gray-200 rounded-lg p-3",children:[(0,s.jsx)("div",{className:"text-sm text-gray-600 mb-2",children:"Forwards to"}),(0,s.jsx)("code",{className:"font-mono text-sm text-gray-900",children:t})]})]})]}),a&&(0,s.jsx)(s.Fragment,{children:(0,s.jsxs)("div",{children:[(0,s.jsx)("div",{className:"text-base font-semibold text-gray-900 mb-3",children:"With subpaths:"}),(0,s.jsxs)("div",{className:"flex items-center gap-4",children:[(0,s.jsxs)("div",{className:"flex-1 bg-gray-50 border border-gray-200 rounded-lg p-3",children:[(0,s.jsx)("div",{className:"text-sm text-gray-600 mb-2",children:"Your endpoint + subpath"}),(0,s.jsxs)("code",{className:"font-mono text-sm text-gray-900",children:[l&&"".concat(r).concat(l),(0,s.jsx)("span",{className:"text-blue-600",children:"/v1/text-to-image/base/model"})]})]}),(0,s.jsx)("div",{className:"text-gray-400",children:(0,s.jsx)(M.Z,{className:"text-lg"})}),(0,s.jsxs)("div",{className:"flex-1 bg-gray-50 border border-gray-200 rounded-lg p-3",children:[(0,s.jsx)("div",{className:"text-sm text-gray-600 mb-2",children:"Forwards to"}),(0,s.jsxs)("code",{className:"font-mono text-sm text-gray-900",children:[t,(0,s.jsx)("span",{className:"text-blue-600",children:"/v1/text-to-image/base/model"})]})]})]}),(0,s.jsxs)("div",{className:"mt-3 text-sm text-gray-600",children:["Any path after ",l," will be appended to the target URL"]})]})}),!a&&(0,s.jsx)("div",{className:"mt-4 p-3 bg-blue-50 rounded-md border border-blue-200",children:(0,s.jsxs)("div",{className:"flex items-start",children:[(0,s.jsx)(Z.Z,{className:"text-blue-500 mt-0.5 mr-2 flex-shrink-0"}),(0,s.jsxs)("div",{className:"text-sm text-blue-700",children:[(0,s.jsx)("span",{className:"font-medium",children:"Not seeing the routing you wanted?"})," Try enabling - Include Subpaths - above - this allows subroutes like"," ",(0,s.jsx)("code",{className:"bg-blue-100 px-1 py-0.5 rounded font-mono text-xs",children:"/api/v1/models"})," to be forwarded automatically."]})]})})]})]}):null},F=t(9114),I=t(63709),T=e=>{let{premiumUser:l,authEnabled:t,onAuthChange:a}=e;return(0,s.jsxs)(f.Z,{className:"p-6",children:[(0,s.jsx)(o.Z,{className:"text-lg font-semibold text-gray-900 mb-2",children:"Security"}),(0,s.jsx)(j.Z,{className:"text-gray-600 mb-4",children:"When enabled, requests to this endpoint will require a valid LiteLLM Virtual Key"}),l?(0,s.jsx)(_.Z.Item,{name:"auth",valuePropName:"checked",className:"mb-0",children:(0,s.jsx)(I.Z,{checked:t,onChange:e=>{a(e)}})}):(0,s.jsxs)("div",{children:[(0,s.jsxs)("div",{className:"flex items-center mb-3",children:[(0,s.jsx)(I.Z,{disabled:!0,checked:!1,style:{outline:"2px solid #d1d5db",outlineOffset:"2px"}}),(0,s.jsx)("span",{className:"ml-2 text-sm text-gray-400",children:"Authentication (Premium)"})]}),(0,s.jsx)("div",{className:"p-3 bg-yellow-50 border border-yellow-200 rounded-lg",children:(0,s.jsxs)(n.Z,{className:"text-sm text-yellow-800",children:["Setting authentication for pass-through endpoints is a LiteLLM Enterprise feature. Get a trial key"," ",(0,s.jsx)("a",{href:"https://www.litellm.ai/#pricing",target:"_blank",rel:"noopener noreferrer",className:"underline",children:"here"}),"."]})})]})]})},R=t(67479),O=e=>{let{accessToken:l,value:t={},onChange:r,disabled:i=!1}=e,[n,d]=(0,a.useState)(Object.keys(t)),[m,u]=(0,a.useState)(t);(0,a.useEffect)(()=>{u(t),d(Object.keys(t))},[t]);let h=(e,l,t)=>{var s,a;let i=m[e]||{},n={...m,[e]:{...i,[l]:t.length>0?t:void 0}};(null===(s=n[e])||void 0===s?void 0:s.request_fields)||(null===(a=n[e])||void 0===a?void 0:a.response_fields)||(n[e]=null),u(n),r&&r(n)};return(0,s.jsxs)(f.Z,{className:"p-6",children:[(0,s.jsx)(o.Z,{className:"text-lg font-semibold text-gray-900 mb-2",children:"Guardrails"}),(0,s.jsx)(j.Z,{className:"text-gray-600 mb-6",children:"Configure guardrails to enforce policies on requests and responses. Guardrails are opt-in for passthrough endpoints."}),(0,s.jsx)(y.Z,{message:(0,s.jsxs)("span",{children:["Field-Level Targeting"," ",(0,s.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,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("div",{children:"Optionally specify which fields to check. If left empty, the entire request/response is sent to the guardrail."}),(0,s.jsxs)("div",{className:"text-xs space-y-1 mt-2",children:[(0,s.jsx)("div",{className:"font-medium",children:"Common Examples:"}),(0,s.jsxs)("div",{children:["• ",(0,s.jsx)("code",{className:"bg-gray-100 px-1 rounded",children:"query"})," - Single field"]}),(0,s.jsxs)("div",{children:["• ",(0,s.jsx)("code",{className:"bg-gray-100 px-1 rounded",children:"documents[*].text"})," - All text in documents array"]}),(0,s.jsxs)("div",{children:["• ",(0,s.jsx)("code",{className:"bg-gray-100 px-1 rounded",children:"messages[*].content"})," - All message contents"]})]})]}),type:"info",showIcon:!0,className:"mb-4"}),(0,s.jsx)(_.Z.Item,{label:(0,s.jsxs)("span",{className:"text-sm font-medium text-gray-700 flex items-center",children:["Select Guardrails",(0,s.jsx)(c.Z,{title:"Choose which guardrails should run on this endpoint. Org/team/key level guardrails will also be included.",children:(0,s.jsx)(Z.Z,{className:"ml-2 text-blue-400 hover:text-blue-600 cursor-help"})})]}),children:(0,s.jsx)(R.Z,{accessToken:l,value:n,onChange:e=>{d(e);let l={};e.forEach(e=>{l[e]=m[e]||null}),u(l),r&&r(l)},disabled:i})}),n.length>0&&(0,s.jsxs)("div",{className:"mt-6 space-y-4",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between mb-3",children:[(0,s.jsx)("div",{className:"text-sm font-medium text-gray-700",children:"Field Targeting (Optional)"}),(0,s.jsx)("div",{className:"text-xs text-gray-500",children:"\uD83D\uDCA1 Tip: Leave empty to check entire payload"})]}),n.map(e=>{var l,t;return(0,s.jsxs)(f.Z,{className:"p-4 bg-gray-50",children:[(0,s.jsx)("div",{className:"text-sm font-medium text-gray-900 mb-3",children:e}),(0,s.jsxs)("div",{className:"space-y-3",children:[(0,s.jsxs)("div",{children:[(0,s.jsxs)("div",{className:"flex items-center justify-between mb-1",children:[(0,s.jsxs)("label",{className:"text-xs text-gray-600 flex items-center",children:["Request Fields (pre_call)",(0,s.jsx)(c.Z,{title:(0,s.jsxs)("div",{children:[(0,s.jsx)("div",{className:"font-medium mb-1",children:"Specify which request fields to check"}),(0,s.jsxs)("div",{className:"text-xs space-y-1",children:[(0,s.jsx)("div",{children:"Examples:"}),(0,s.jsx)("div",{children:"• query"}),(0,s.jsx)("div",{children:"• documents[*].text"}),(0,s.jsx)("div",{children:"• messages[*].content"})]})]}),children:(0,s.jsx)(Z.Z,{className:"ml-1 text-gray-400"})})]}),(0,s.jsxs)("div",{className:"flex gap-1",children:[(0,s.jsx)("button",{type:"button",onClick:()=>{var l;let t=(null===(l=m[e])||void 0===l?void 0:l.request_fields)||[];h(e,"request_fields",[...t,"query"])},className:"text-xs px-2 py-1 bg-white border border-gray-300 rounded hover:bg-gray-50",disabled:i,children:"+ query"}),(0,s.jsx)("button",{type:"button",onClick:()=>{var l;let t=(null===(l=m[e])||void 0===l?void 0:l.request_fields)||[];h(e,"request_fields",[...t,"documents[*]"])},className:"text-xs px-2 py-1 bg-white border border-gray-300 rounded hover:bg-gray-50",disabled:i,children:"+ documents[*]"})]})]}),(0,s.jsx)(v.default,{mode:"tags",style:{width:"100%"},placeholder:"Type field name or use + buttons above (e.g., query, documents[*].text)",value:(null===(l=m[e])||void 0===l?void 0:l.request_fields)||[],onChange:l=>h(e,"request_fields",l),disabled:i,tokenSeparators:[","]})]}),(0,s.jsxs)("div",{children:[(0,s.jsxs)("div",{className:"flex items-center justify-between mb-1",children:[(0,s.jsxs)("label",{className:"text-xs text-gray-600 flex items-center",children:["Response Fields (post_call)",(0,s.jsx)(c.Z,{title:(0,s.jsxs)("div",{children:[(0,s.jsx)("div",{className:"font-medium mb-1",children:"Specify which response fields to check"}),(0,s.jsxs)("div",{className:"text-xs space-y-1",children:[(0,s.jsx)("div",{children:"Examples:"}),(0,s.jsx)("div",{children:"• results[*].text"}),(0,s.jsx)("div",{children:"• choices[*].message.content"})]})]}),children:(0,s.jsx)(Z.Z,{className:"ml-1 text-gray-400"})})]}),(0,s.jsx)("div",{className:"flex gap-1",children:(0,s.jsx)("button",{type:"button",onClick:()=>{var l;let t=(null===(l=m[e])||void 0===l?void 0:l.response_fields)||[];h(e,"response_fields",[...t,"results[*]"])},className:"text-xs px-2 py-1 bg-white border border-gray-300 rounded hover:bg-gray-50",disabled:i,children:"+ results[*]"})})]}),(0,s.jsx)(v.default,{mode:"tags",style:{width:"100%"},placeholder:"Type field name or use + buttons above (e.g., results[*].text)",value:(null===(t=m[e])||void 0===t?void 0:t.response_fields)||[],onChange:l=>h(e,"response_fields",l),disabled:i,tokenSeparators:[","]})]})]})]},e)})]})]})};let{Option:V}=v.default;var q=e=>{let{accessToken:l,setPassThroughItems:t,passThroughItems:i,premiumUser:n=!1}=e,[m]=_.Z.useForm(),[u,h]=(0,a.useState)(!1),[x,v]=(0,a.useState)(!1),[C,k]=(0,a.useState)(""),[S,A]=(0,a.useState)(""),[E,M]=(0,a.useState)(""),[I,R]=(0,a.useState)(!0),[V,q]=(0,a.useState)(!1),[z,D]=(0,a.useState)({}),B=()=>{m.resetFields(),A(""),M(""),R(!0),D({}),h(!1)},G=e=>{let l=e;e&&!e.startsWith("/")&&(l="/"+e),A(l),m.setFieldsValue({path:l})},U=async e=>{console.log("addPassThrough called with:",e),v(!0);try{!n&&"auth"in e&&delete e.auth,z&&Object.keys(z).length>0&&(e.guardrails=z),console.log("formValues: ".concat(JSON.stringify(e)));let s=(await (0,d.createPassThroughEndpoint)(l,e)).endpoints[0],a=[...i,s];t(a),F.Z.success("Pass-through endpoint created successfully"),m.resetFields(),A(""),M(""),R(!0),D({}),h(!1)}catch(e){F.Z.fromBackend("Error creating pass-through endpoint: "+e)}finally{v(!1)}};return(0,s.jsxs)("div",{children:[(0,s.jsx)(r.Z,{className:"mx-auto mb-4 mt-4",onClick:()=>h(!0),children:"+ Add Pass-Through Endpoint"}),(0,s.jsx)(b.Z,{title:(0,s.jsxs)("div",{className:"flex items-center space-x-3 pb-4 border-b border-gray-100",children:[(0,s.jsx)(w.Z,{className:"text-xl text-blue-500"}),(0,s.jsx)("h2",{className:"text-xl font-semibold text-gray-900",children:"Add Pass-Through Endpoint"})]}),open:u,width:1e3,onCancel:B,footer:null,className:"top-8",styles:{body:{padding:"24px"},header:{padding:"24px 24px 0 24px",border:"none"}},children:(0,s.jsxs)("div",{className:"mt-6",children:[(0,s.jsx)(y.Z,{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,s.jsxs)(_.Z,{form:m,onFinish:U,layout:"vertical",className:"space-y-6",initialValues:{include_subpath:!0,path:S,target:E},children:[(0,s.jsxs)(f.Z,{className:"p-5",children:[(0,s.jsx)(o.Z,{className:"text-lg font-semibold text-gray-900 mb-2",children:"Route Configuration"}),(0,s.jsx)(j.Z,{className:"text-gray-600 mb-5",children:"Configure how requests to your domain will be forwarded to the target API"}),(0,s.jsxs)("div",{className:"space-y-5",children:[(0,s.jsx)(_.Z.Item,{label:(0,s.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,s.jsx)("div",{className:"text-xs text-gray-500 mt-1",children:"Example: /bria, /adobe-photoshop, /elasticsearch"}),className:"mb-4",children:(0,s.jsx)("div",{className:"flex items-center",children:(0,s.jsx)(g.Z,{placeholder:"bria",value:S,onChange:e=>G(e.target.value),className:"flex-1"})})}),(0,s.jsx)(_.Z.Item,{label:(0,s.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,s.jsx)("div",{className:"text-xs text-gray-500 mt-1",children:"Example:https://engine.prod.bria-api.com"}),className:"mb-4",children:(0,s.jsx)(g.Z,{placeholder:"https://engine.prod.bria-api.com",value:E,onChange:e=>{M(e.target.value),m.setFieldsValue({target:e.target.value})}})}),(0,s.jsxs)("div",{className:"flex items-center justify-between py-3",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("div",{className:"text-sm font-medium text-gray-700",children:"Include Subpaths"}),(0,s.jsx)("div",{className:"text-xs text-gray-500 mt-0.5",children:"Forward all subpaths to the target API (recommended for REST APIs)"})]}),(0,s.jsx)(_.Z.Item,{name:"include_subpath",valuePropName:"checked",className:"mb-0",children:(0,s.jsx)(p.Z,{checked:I,onChange:R})})]})]})]}),(0,s.jsx)(L,{pathValue:S,targetValue:E,includeSubpath:I}),(0,s.jsxs)(f.Z,{className:"p-6",children:[(0,s.jsx)(o.Z,{className:"text-lg font-semibold text-gray-900 mb-2",children:"Headers"}),(0,s.jsx)(j.Z,{className:"text-gray-600 mb-6",children:"Add headers that will be sent with every request to the target API"}),(0,s.jsx)(_.Z.Item,{label:(0,s.jsxs)("span",{className:"text-sm font-medium text-gray-700 flex items-center",children:["Authentication Headers",(0,s.jsx)(c.Z,{title:"Authentication and other headers to forward with requests",children:(0,s.jsx)(Z.Z,{className:"ml-2 text-blue-400 hover:text-blue-600 cursor-help"})})]}),name:"headers",rules:[{required:!0,message:"Please configure the headers"}],extra:(0,s.jsxs)("div",{className:"text-xs text-gray-500 mt-2",children:[(0,s.jsx)("div",{className:"font-medium mb-1",children:"Add authentication tokens and other required headers"}),(0,s.jsx)("div",{children:"Common examples: auth_token, Authorization, x-api-key"})]}),children:(0,s.jsx)(P,{})})]}),(0,s.jsx)(T,{premiumUser:n,authEnabled:V,onAuthChange:e=>{q(e),m.setFieldsValue({auth:e})}}),(0,s.jsx)(O,{accessToken:l,value:z,onChange:D}),(0,s.jsxs)(f.Z,{className:"p-6",children:[(0,s.jsx)(o.Z,{className:"text-lg font-semibold text-gray-900 mb-2",children:"Billing"}),(0,s.jsx)(j.Z,{className:"text-gray-600 mb-6",children:"Optional cost tracking for this endpoint"}),(0,s.jsx)(_.Z.Item,{label:(0,s.jsxs)("span",{className:"text-sm font-medium text-gray-700 flex items-center",children:["Cost Per Request (USD)",(0,s.jsx)(c.Z,{title:"Optional: Track costs for requests to this endpoint",children:(0,s.jsx)(Z.Z,{className:"ml-2 text-gray-400 hover:text-gray-600"})})]}),name:"cost_per_request",extra:(0,s.jsx)("div",{className:"text-xs text-gray-500 mt-2",children:"The cost charged for each request through this endpoint"}),children:(0,s.jsx)(N.Z,{min:0,step:.001,precision:4,placeholder:"2.0000",size:"large"})})]}),(0,s.jsxs)("div",{className:"flex items-center justify-end space-x-3 pt-6 border-t border-gray-100",children:[(0,s.jsx)(r.Z,{variant:"secondary",onClick:B,children:"Cancel"}),(0,s.jsx)(r.Z,{variant:"primary",loading:x,onClick:()=>{console.log("Submit button clicked"),m.submit()},children:x?"Creating...":"Add Pass-Through Endpoint"})]})]})]})})]})},z=t(30078),D=t(4260),B=t(19015),G=t(87769),U=t(42208);let H=e=>{let{value:l}=e,[t,r]=(0,a.useState)(!1),i=JSON.stringify(l,null,2);return(0,s.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,s.jsx)("pre",{className:"font-mono text-xs bg-gray-50 p-2 rounded max-w-md overflow-auto",children:t?i:"••••••••"}),(0,s.jsx)("button",{onClick:()=>r(!t),className:"p-1 hover:bg-gray-100 rounded",type:"button",children:t?(0,s.jsx)(G.Z,{className:"w-4 h-4 text-gray-500"}):(0,s.jsx)(U.Z,{className:"w-4 h-4 text-gray-500"})})]})};var K=e=>{let{endpointData:l,onClose:t,accessToken:r,isAdmin:i,premiumUser:n=!1,onEndpointUpdated:o}=e,[c,m]=(0,a.useState)(l),[u,h]=(0,a.useState)(!1),[x,p]=(0,a.useState)(!1),[g,f]=(0,a.useState)((null==l?void 0:l.auth)||!1),[j,v]=(0,a.useState)((null==l?void 0:l.guardrails)||{}),[b]=_.Z.useForm(),y=async e=>{try{if(!r||!(null==c?void 0:c.id))return;let l={};if(e.headers)try{l="string"==typeof e.headers?JSON.parse(e.headers):e.headers}catch(e){F.Z.fromBackend("Invalid JSON format for headers");return}let t={path:c.path,target:e.target,headers:l,include_subpath:e.include_subpath,cost_per_request:e.cost_per_request,auth:n?e.auth:void 0,guardrails:j&&Object.keys(j).length>0?j:void 0};await (0,d.updatePassThroughEndpoint)(r,c.id,t),m({...c,...t}),p(!1),o&&o()}catch(e){console.error("Error updating endpoint:",e),F.Z.fromBackend("Failed to update pass through endpoint")}},N=async()=>{try{if(!r||!(null==c?void 0:c.id))return;await (0,d.deletePassThroughEndpointsCall)(r,c.id),F.Z.success("Pass through endpoint deleted successfully"),t(),o&&o()}catch(e){console.error("Error deleting endpoint:",e),F.Z.fromBackend("Failed to delete pass through endpoint")}};return u?(0,s.jsx)("div",{className:"p-4",children:"Loading..."}):c?(0,s.jsxs)("div",{className:"p-4",children:[(0,s.jsx)("div",{className:"flex justify-between items-center mb-6",children:(0,s.jsxs)("div",{children:[(0,s.jsx)(k.ZP,{onClick:t,className:"mb-4",children:"← Back"}),(0,s.jsxs)(z.Dx,{children:["Pass Through Endpoint: ",c.path]}),(0,s.jsx)(z.xv,{className:"text-gray-500 font-mono",children:c.id})]})}),(0,s.jsxs)(z.v0,{children:[(0,s.jsxs)(z.td,{className:"mb-4",children:[(0,s.jsx)(z.OK,{children:"Overview"},"overview"),i?(0,s.jsx)(z.OK,{children:"Settings"},"settings"):(0,s.jsx)(s.Fragment,{})]}),(0,s.jsxs)(z.nP,{children:[(0,s.jsxs)(z.x4,{children:[(0,s.jsxs)(z.rj,{numItems:1,numItemsSm:2,numItemsLg:3,className:"gap-6",children:[(0,s.jsxs)(z.Zb,{children:[(0,s.jsx)(z.xv,{children:"Path"}),(0,s.jsx)("div",{className:"mt-2",children:(0,s.jsx)(z.Dx,{className:"font-mono",children:c.path})})]}),(0,s.jsxs)(z.Zb,{children:[(0,s.jsx)(z.xv,{children:"Target"}),(0,s.jsx)("div",{className:"mt-2",children:(0,s.jsx)(z.Dx,{children:c.target})})]}),(0,s.jsxs)(z.Zb,{children:[(0,s.jsx)(z.xv,{children:"Configuration"}),(0,s.jsxs)("div",{className:"mt-2 space-y-2",children:[(0,s.jsx)("div",{children:(0,s.jsx)(z.Ct,{color:c.include_subpath?"green":"gray",children:c.include_subpath?"Include Subpath":"Exact Path"})}),(0,s.jsx)("div",{children:(0,s.jsx)(z.Ct,{color:c.auth?"blue":"gray",children:c.auth?"Auth Required":"No Auth"})}),void 0!==c.cost_per_request&&(0,s.jsx)("div",{children:(0,s.jsxs)(z.xv,{children:["Cost per request: $",c.cost_per_request]})})]})]})]}),(0,s.jsx)("div",{className:"mt-6",children:(0,s.jsx)(L,{pathValue:c.path,targetValue:c.target,includeSubpath:c.include_subpath||!1})}),c.headers&&Object.keys(c.headers).length>0&&(0,s.jsxs)(z.Zb,{className:"mt-6",children:[(0,s.jsxs)("div",{className:"flex justify-between items-center",children:[(0,s.jsx)(z.xv,{className:"font-medium",children:"Headers"}),(0,s.jsxs)(z.Ct,{color:"blue",children:[Object.keys(c.headers).length," headers configured"]})]}),(0,s.jsx)("div",{className:"mt-4",children:(0,s.jsx)(H,{value:c.headers})})]}),c.guardrails&&Object.keys(c.guardrails).length>0&&(0,s.jsxs)(z.Zb,{className:"mt-6",children:[(0,s.jsxs)("div",{className:"flex justify-between items-center",children:[(0,s.jsx)(z.xv,{className:"font-medium",children:"Guardrails"}),(0,s.jsxs)(z.Ct,{color:"purple",children:[Object.keys(c.guardrails).length," guardrails configured"]})]}),(0,s.jsx)("div",{className:"mt-4 space-y-2",children:Object.entries(c.guardrails).map(e=>{let[l,t]=e;return(0,s.jsxs)("div",{className:"p-3 bg-gray-50 rounded",children:[(0,s.jsx)("div",{className:"font-medium text-sm",children:l}),t&&(t.request_fields||t.response_fields)&&(0,s.jsxs)("div",{className:"mt-2 text-xs text-gray-600 space-y-1",children:[t.request_fields&&(0,s.jsxs)("div",{children:["Request fields: ",t.request_fields.join(", ")]}),t.response_fields&&(0,s.jsxs)("div",{children:["Response fields: ",t.response_fields.join(", ")]})]}),!t&&(0,s.jsx)("div",{className:"text-xs text-gray-600 mt-1",children:"Uses entire payload"})]},l)})})]})]}),i&&(0,s.jsx)(z.x4,{children:(0,s.jsxs)(z.Zb,{children:[(0,s.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,s.jsx)(z.Dx,{children:"Pass Through Endpoint Settings"}),(0,s.jsx)("div",{className:"space-x-2",children:!x&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(z.zx,{onClick:()=>p(!0),children:"Edit Settings"}),(0,s.jsx)(z.zx,{onClick:N,variant:"secondary",color:"red",children:"Delete Endpoint"})]})})]}),x?(0,s.jsxs)(_.Z,{form:b,onFinish:y,initialValues:{target:c.target,headers:c.headers?JSON.stringify(c.headers,null,2):"",include_subpath:c.include_subpath||!1,cost_per_request:c.cost_per_request,auth:c.auth||!1},layout:"vertical",children:[(0,s.jsx)(_.Z.Item,{label:"Target URL",name:"target",rules:[{required:!0,message:"Please input a target URL"}],children:(0,s.jsx)(z.oi,{placeholder:"https://api.example.com"})}),(0,s.jsx)(_.Z.Item,{label:"Headers (JSON)",name:"headers",children:(0,s.jsx)(D.default.TextArea,{rows:5,placeholder:'{"Authorization": "Bearer your-token", "Content-Type": "application/json"}'})}),(0,s.jsx)(_.Z.Item,{label:"Include Subpath",name:"include_subpath",valuePropName:"checked",children:(0,s.jsx)(I.Z,{})}),(0,s.jsx)(_.Z.Item,{label:"Cost per Request",name:"cost_per_request",children:(0,s.jsx)(B.Z,{min:0,step:.01,precision:2,placeholder:"0.00",addonBefore:"$"})}),(0,s.jsx)(T,{premiumUser:n,authEnabled:g,onAuthChange:e=>{f(e),b.setFieldsValue({auth:e})}}),(0,s.jsx)("div",{className:"mt-4",children:(0,s.jsx)(O,{accessToken:r||"",value:j,onChange:v})}),(0,s.jsxs)("div",{className:"flex justify-end gap-2 mt-6",children:[(0,s.jsx)(k.ZP,{onClick:()=>p(!1),children:"Cancel"}),(0,s.jsx)(z.zx,{children:"Save Changes"})]})]}):(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)(z.xv,{className:"font-medium",children:"Path"}),(0,s.jsx)("div",{className:"font-mono",children:c.path})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(z.xv,{className:"font-medium",children:"Target URL"}),(0,s.jsx)("div",{children:c.target})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(z.xv,{className:"font-medium",children:"Include Subpath"}),(0,s.jsx)(z.Ct,{color:c.include_subpath?"green":"gray",children:c.include_subpath?"Yes":"No"})]}),void 0!==c.cost_per_request&&(0,s.jsxs)("div",{children:[(0,s.jsx)(z.xv,{className:"font-medium",children:"Cost per Request"}),(0,s.jsxs)("div",{children:["$",c.cost_per_request]})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(z.xv,{className:"font-medium",children:"Authentication Required"}),(0,s.jsx)(z.Ct,{color:c.auth?"green":"gray",children:c.auth?"Yes":"No"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(z.xv,{className:"font-medium",children:"Headers"}),c.headers&&Object.keys(c.headers).length>0?(0,s.jsx)("div",{className:"mt-2",children:(0,s.jsx)(H,{value:c.headers})}):(0,s.jsx)("div",{className:"text-gray-500",children:"No headers configured"})]})]})]})})]})]})]}):(0,s.jsx)("div",{className:"p-4",children:"Pass through endpoint not found"})},J=t(12322);let W=e=>{let{value:l}=e,[t,r]=(0,a.useState)(!1),i=JSON.stringify(l);return(0,s.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,s.jsx)("span",{className:"font-mono text-xs",children:t?i:"••••••••"}),(0,s.jsx)("button",{onClick:()=>r(!t),className:"p-1 hover:bg-gray-100 rounded",type:"button",children:t?(0,s.jsx)(G.Z,{className:"w-4 h-4 text-gray-500"}):(0,s.jsx)(U.Z,{className:"w-4 h-4 text-gray-500"})})]})};var Y=e=>{let{accessToken:l,userRole:t,userID:p,modelData:g,premiumUser:f}=e,[j,v]=(0,a.useState)([]),[_,b]=(0,a.useState)(null),[y,N]=(0,a.useState)(!1),[w,Z]=(0,a.useState)(null);(0,a.useEffect)(()=>{l&&t&&p&&(0,d.getPassThroughEndpointsCall)(l).then(e=>{v(e.endpoints)})},[l,t,p]);let C=async e=>{Z(e),N(!0)},k=async()=>{if(null!=w&&l){try{await (0,d.deletePassThroughEndpointsCall)(l,w);let e=j.filter(e=>e.id!==w);v(e),F.Z.success("Endpoint deleted successfully.")}catch(e){console.error("Error deleting the endpoint:",e),F.Z.fromBackend("Error deleting the endpoint: "+e)}N(!1),Z(null)}},S=(e,l)=>{C(e)},A=[{header:"ID",accessorKey:"id",cell:e=>(0,s.jsx)(c.Z,{title:e.row.original.id,children:(0,s.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&&b(e.row.original.id),children:e.row.original.id})})},{header:"Path",accessorKey:"path"},{header:"Target",accessorKey:"target",cell:e=>(0,s.jsx)(n.Z,{children:e.getValue()})},{header:()=>(0,s.jsxs)("div",{className:"flex items-center gap-1",children:[(0,s.jsx)("span",{children:"Authentication"}),(0,s.jsx)(c.Z,{title:"LiteLLM Virtual Key required to call endpoint",children:(0,s.jsx)(u.Z,{className:"w-4 h-4 text-gray-400 cursor-help"})})]}),accessorKey:"auth",cell:e=>(0,s.jsx)(m.Z,{color:e.getValue()?"green":"gray",children:e.getValue()?"Yes":"No"})},{header:"Headers",accessorKey:"headers",cell:e=>(0,s.jsx)(W,{value:e.getValue()||{}})},{header:"Actions",id:"actions",cell:e=>{let{row:l}=e;return(0,s.jsxs)("div",{className:"flex space-x-1",children:[(0,s.jsx)(i.Z,{icon:h.Z,size:"sm",onClick:()=>l.original.id&&b(l.original.id),title:"Edit"}),(0,s.jsx)(i.Z,{icon:x.Z,size:"sm",onClick:()=>S(l.original.id,l.index),title:"Delete"})]})}}];if(!l)return null;if(_){console.log("selectedEndpointId",_),console.log("generalSettings",j);let e=j.find(e=>e.id===_);return e?(0,s.jsx)(K,{endpointData:e,onClose:()=>b(null),accessToken:l,isAdmin:"Admin"===t||"admin"===t,premiumUser:f,onEndpointUpdated:()=>{l&&(0,d.getPassThroughEndpointsCall)(l).then(e=>{v(e.endpoints)})}}):(0,s.jsx)("div",{children:"Endpoint not found"})}return(0,s.jsxs)("div",{children:[(0,s.jsxs)("div",{children:[(0,s.jsx)(o.Z,{children:"Pass Through Endpoints"}),(0,s.jsx)(n.Z,{className:"text-tremor-content",children:"Configure and manage your pass-through endpoints"})]}),(0,s.jsx)(q,{accessToken:l,setPassThroughItems:v,passThroughItems:j,premiumUser:f}),(0,s.jsx)(J.w,{data:j,columns:A,renderSubComponent:()=>(0,s.jsx)("div",{}),getRowCanExpand:()=>!1,isLoading:!1,noDataMessage:"No pass-through endpoints configured"}),y&&(0,s.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,s.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,s.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,s.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,s.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,s.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,s.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,s.jsx)("div",{className:"sm:flex sm:items-start",children:(0,s.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,s.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Pass-Through Endpoint"}),(0,s.jsx)("div",{className:"mt-2",children:(0,s.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,s.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,s.jsx)(r.Z,{onClick:k,color:"red",className:"ml-2",children:"Delete"}),(0,s.jsx)(r.Z,{onClick:()=>{N(!1),Z(null)},children:"Cancel"})]})]})]})})]})}},12322:function(e,l,t){t.d(l,{w:function(){return o}});var s=t(57437),a=t(2265),r=t(71594),i=t(24525),n=t(19130);function o(e){let{data:l=[],columns:t,getRowCanExpand:o,renderSubComponent:d,isLoading:c=!1,loadingMessage:m="\uD83D\uDE85 Loading logs...",noDataMessage:u="No logs found"}=e,h=(0,r.b7)({data:l,columns:t,getRowCanExpand:o,getRowId:(e,l)=>{var t;return null!==(t=null==e?void 0:e.request_id)&&void 0!==t?t:String(l)},getCoreRowModel:(0,i.sC)(),getExpandedRowModel:(0,i.rV)()});return(0,s.jsx)("div",{className:"rounded-lg custom-border overflow-x-auto w-full max-w-full box-border",children:(0,s.jsxs)(n.iA,{className:"[&_td]:py-0.5 [&_th]:py-1 table-fixed w-full box-border",style:{minWidth:"400px"},children:[(0,s.jsx)(n.ss,{children:h.getHeaderGroups().map(e=>(0,s.jsx)(n.SC,{children:e.headers.map(e=>(0,s.jsx)(n.xs,{className:"py-1 h-8",children:e.isPlaceholder?null:(0,r.ie)(e.column.columnDef.header,e.getContext())},e.id))},e.id))}),(0,s.jsx)(n.RM,{children:c?(0,s.jsx)(n.SC,{children:(0,s.jsx)(n.pj,{colSpan:t.length,className:"h-8 text-center",children:(0,s.jsx)("div",{className:"text-center text-gray-500",children:(0,s.jsx)("p",{children:m})})})}):h.getRowModel().rows.length>0?h.getRowModel().rows.map(e=>(0,s.jsxs)(a.Fragment,{children:[(0,s.jsx)(n.SC,{className:"h-8",children:e.getVisibleCells().map(e=>(0,s.jsx)(n.pj,{className:"py-0.5 max-h-8 overflow-hidden text-ellipsis whitespace-nowrap",children:(0,r.ie)(e.column.columnDef.cell,e.getContext())},e.id))}),e.getIsExpanded()&&(0,s.jsx)(n.SC,{children:(0,s.jsx)(n.pj,{colSpan:e.getVisibleCells().length,className:"p-0",children:(0,s.jsx)("div",{className:"w-full max-w-full overflow-hidden box-border",children:d({row:e})})})})]},e.id)):(0,s.jsx)(n.SC,{children:(0,s.jsx)(n.pj,{colSpan:t.length,className:"h-8 text-center",children:(0,s.jsx)("div",{className:"text-center text-gray-500",children:(0,s.jsx)("p",{children:u})})})})})]})})}}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/1716-1c0ba935a144e6ff.js b/litellm/proxy/_experimental/out/_next/static/chunks/1716-1c0ba935a144e6ff.js deleted file mode 100644 index a7f835359b0..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/1716-1c0ba935a144e6ff.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1716],{41649:function(e,t,n){n.d(t,{Z:function(){return u}});var o=n(5853),i=n(2265),a=n(47187),r=n(7084),c=n(26898),l=n(13241),s=n(1153);let d={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"}},m={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"}},g=(0,s.fn)("Badge"),u=i.forwardRef((e,t)=>{let{color:n,icon:u,size:p=r.u8.SM,tooltip:b,className:h,children:f}=e,v=(0,o._T)(e,["color","icon","size","tooltip","className","children"]),S=u||null,{tooltipProps:x,getReferenceProps:k}=(0,a.l)();return i.createElement("span",Object.assign({ref:(0,s.lq)([t,x.refs.setReference]),className:(0,l.q)(g("root"),"w-max shrink-0 inline-flex justify-center items-center cursor-default rounded-tremor-small ring-1 ring-inset",n?(0,l.q)((0,s.bM)(n,c.K.background).bgColor,(0,s.bM)(n,c.K.iconText).textColor,(0,s.bM)(n,c.K.iconRing).ringColor,"bg-opacity-10 ring-opacity-20","dark:bg-opacity-5 dark:ring-opacity-60"):(0,l.q)("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"),d[p].paddingX,d[p].paddingY,d[p].fontSize,h)},k,v),i.createElement(a.Z,Object.assign({text:b},x)),S?i.createElement(S,{className:(0,l.q)(g("icon"),"shrink-0 -ml-1 mr-1.5",m[p].height,m[p].width)}):null,i.createElement("span",{className:(0,l.q)(g("text"),"whitespace-nowrap")},f))});u.displayName="Badge"},67101:function(e,t,n){n.d(t,{Z:function(){return d}});var o=n(5853),i=n(13241),a=n(1153),r=n(2265),c=n(9496);let l=(0,a.fn)("Grid"),s=(e,t)=>e&&Object.keys(t).includes(String(e))?t[e]:"",d=r.forwardRef((e,t)=>{let{numItems:n=1,numItemsSm:a,numItemsMd:d,numItemsLg:m,children:g,className:u}=e,p=(0,o._T)(e,["numItems","numItemsSm","numItemsMd","numItemsLg","children","className"]),b=s(n,c._m),h=s(a,c.LH),f=s(d,c.l5),v=s(m,c.N4),S=(0,i.q)(b,h,f,v);return r.createElement("div",Object.assign({ref:t,className:(0,i.q)(l("root"),"grid",S,u)},p),g)});d.displayName="Grid"},9496:function(e,t,n){n.d(t,{LH:function(){return i},N4:function(){return r},PT:function(){return c},SP:function(){return l},VS:function(){return s},_m:function(){return o},_w:function(){return d},l5:function(){return a}});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"},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"},a={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"},r={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"},c={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"},l={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"},s={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"},d={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"}},23496:function(e,t,n){n.d(t,{Z:function(){return f}});var o=n(2265),i=n(36760),a=n.n(i),r=n(71744),c=n(33759),l=n(93463),s=n(12918),d=n(99320),m=n(71140);let g=e=>{let{componentCls:t}=e;return{[t]:{"&-horizontal":{["&".concat(t)]:{"&-sm":{marginBlock:e.marginXS},"&-md":{marginBlock:e.margin}}}}}},u=e=>{let{componentCls:t,sizePaddingEdgeHorizontal:n,colorSplit:o,lineWidth:i,textPaddingInline:a,orientationMargin:r,verticalMarginInline:c}=e;return{[t]:Object.assign(Object.assign({},(0,s.Wf)(e)),{borderBlockStart:"".concat((0,l.bf)(i)," solid ").concat(o),"&-vertical":{position:"relative",top:"-0.06em",display:"inline-block",height:"0.9em",marginInline:c,marginBlock:0,verticalAlign:"middle",borderTop:0,borderInlineStart:"".concat((0,l.bf)(i)," solid ").concat(o)},"&-horizontal":{display:"flex",clear:"both",width:"100%",minWidth:"100%",margin:"".concat((0,l.bf)(e.marginLG)," 0")},["&-horizontal".concat(t,"-with-text")]:{display:"flex",alignItems:"center",margin:"".concat((0,l.bf)(e.dividerHorizontalWithTextGutterMargin)," 0"),color:e.colorTextHeading,fontWeight:500,fontSize:e.fontSizeLG,whiteSpace:"nowrap",textAlign:"center",borderBlockStart:"0 ".concat(o),"&::before, &::after":{position:"relative",width:"50%",borderBlockStart:"".concat((0,l.bf)(i)," solid transparent"),borderBlockStartColor:"inherit",borderBlockEnd:0,transform:"translateY(50%)",content:"''"}},["&-horizontal".concat(t,"-with-text-start")]:{"&::before":{width:"calc(".concat(r," * 100%)")},"&::after":{width:"calc(100% - ".concat(r," * 100%)")}},["&-horizontal".concat(t,"-with-text-end")]:{"&::before":{width:"calc(100% - ".concat(r," * 100%)")},"&::after":{width:"calc(".concat(r," * 100%)")}},["".concat(t,"-inner-text")]:{display:"inline-block",paddingBlock:0,paddingInline:a},"&-dashed":{background:"none",borderColor:o,borderStyle:"dashed",borderWidth:"".concat((0,l.bf)(i)," 0 0")},["&-horizontal".concat(t,"-with-text").concat(t,"-dashed")]:{"&::before, &::after":{borderStyle:"dashed none none"}},["&-vertical".concat(t,"-dashed")]:{borderInlineStartWidth:i,borderInlineEnd:0,borderBlockStart:0,borderBlockEnd:0},"&-dotted":{background:"none",borderColor:o,borderStyle:"dotted",borderWidth:"".concat((0,l.bf)(i)," 0 0")},["&-horizontal".concat(t,"-with-text").concat(t,"-dotted")]:{"&::before, &::after":{borderStyle:"dotted none none"}},["&-vertical".concat(t,"-dotted")]:{borderInlineStartWidth:i,borderInlineEnd:0,borderBlockStart:0,borderBlockEnd:0},["&-plain".concat(t,"-with-text")]:{color:e.colorText,fontWeight:"normal",fontSize:e.fontSize},["&-horizontal".concat(t,"-with-text-start").concat(t,"-no-default-orientation-margin-start")]:{"&::before":{width:0},"&::after":{width:"100%"},["".concat(t,"-inner-text")]:{paddingInlineStart:n}},["&-horizontal".concat(t,"-with-text-end").concat(t,"-no-default-orientation-margin-end")]:{"&::before":{width:"100%"},"&::after":{width:0},["".concat(t,"-inner-text")]:{paddingInlineEnd:n}}})}};var p=(0,d.I$)("Divider",e=>{let t=(0,m.IX)(e,{dividerHorizontalWithTextGutterMargin:e.margin,sizePaddingEdgeHorizontal:0});return[u(t),g(t)]},e=>({textPaddingInline:"1em",orientationMargin:.05,verticalMarginInline:e.marginXS}),{unitless:{orientationMargin:!0}}),b=function(e,t){var n={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&0>t.indexOf(o)&&(n[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,o=Object.getOwnPropertySymbols(e);it.indexOf(o[i])&&Object.prototype.propertyIsEnumerable.call(e,o[i])&&(n[o[i]]=e[o[i]]);return n};let h={small:"sm",middle:"md"};var f=e=>{let{getPrefixCls:t,direction:n,className:i,style:l}=(0,r.dj)("divider"),{prefixCls:s,type:d="horizontal",orientation:m="center",orientationMargin:g,className:u,rootClassName:f,children:v,dashed:S,variant:x="solid",plain:k,style:y,size:C}=e,z=b(e,["prefixCls","type","orientation","orientationMargin","className","rootClassName","children","dashed","variant","plain","style","size"]),w=t("divider",s),[E,N,j]=p(w),I=h[(0,c.Z)(C)],M=!!v,B=o.useMemo(()=>"left"===m?"rtl"===n?"end":"start":"right"===m?"rtl"===n?"start":"end":m,[n,m]),O="start"===B&&null!=g,P="end"===B&&null!=g,Z=a()(w,i,N,j,"".concat(w,"-").concat(d),{["".concat(w,"-with-text")]:M,["".concat(w,"-with-text-").concat(B)]:M,["".concat(w,"-dashed")]:!!S,["".concat(w,"-").concat(x)]:"solid"!==x,["".concat(w,"-plain")]:!!k,["".concat(w,"-rtl")]:"rtl"===n,["".concat(w,"-no-default-orientation-margin-start")]:O,["".concat(w,"-no-default-orientation-margin-end")]:P,["".concat(w,"-").concat(I)]:!!I},u,f),T=o.useMemo(()=>"number"==typeof g?g:/^\d+$/.test(g)?Number(g):g,[g]);return E(o.createElement("div",Object.assign({className:Z,style:Object.assign(Object.assign({},l),y)},z,{role:"separator"}),v&&"vertical"!==d&&o.createElement("span",{className:"".concat(w,"-inner-text"),style:{marginInlineStart:O?T:void 0,marginInlineEnd:P?T:void 0}},v)))}},40049:function(e,t,n){n.d(t,{Z:function(){return ei}});var o=n(2265),i=n(1119),a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M272.9 512l265.4-339.1c4.1-5.2.4-12.9-6.3-12.9h-77.3c-4.9 0-9.6 2.3-12.6 6.1L186.8 492.3a31.99 31.99 0 000 39.5l255.3 326.1c3 3.9 7.7 6.1 12.6 6.1H532c6.7 0 10.4-7.7 6.3-12.9L272.9 512zm304 0l265.4-339.1c4.1-5.2.4-12.9-6.3-12.9h-77.3c-4.9 0-9.6 2.3-12.6 6.1L490.8 492.3a31.99 31.99 0 000 39.5l255.3 326.1c3 3.9 7.7 6.1 12.6 6.1H836c6.7 0 10.4-7.7 6.3-12.9L576.9 512z"}}]},name:"double-left",theme:"outlined"},r=n(55015),c=o.forwardRef(function(e,t){return o.createElement(r.Z,(0,i.Z)({},e,{ref:t,icon:a}))}),l={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M533.2 492.3L277.9 166.1c-3-3.9-7.7-6.1-12.6-6.1H188c-6.7 0-10.4 7.7-6.3 12.9L447.1 512 181.7 851.1A7.98 7.98 0 00188 864h77.3c4.9 0 9.6-2.3 12.6-6.1l255.3-326.1c9.1-11.7 9.1-27.9 0-39.5zm304 0L581.9 166.1c-3-3.9-7.7-6.1-12.6-6.1H492c-6.7 0-10.4 7.7-6.3 12.9L751.1 512 485.7 851.1A7.98 7.98 0 00492 864h77.3c4.9 0 9.6-2.3 12.6-6.1l255.3-326.1c9.1-11.7 9.1-27.9 0-39.5z"}}]},name:"double-right",theme:"outlined"},s=o.forwardRef(function(e,t){return o.createElement(r.Z,(0,i.Z)({},e,{ref:t,icon:l}))}),d=n(15327),m=n(77565),g=n(36760),u=n.n(g),p=n(11993),b=n(41154),h=n(31686),f=n(26365),v=n(50506),S=n(95814),x=n(18242);n(32559);var k={items_per_page:"条/页",jump_to:"跳至",jump_to_confirm:"确定",page:"页",prev_page:"上一页",next_page:"下一页",prev_5:"向前 5 页",next_5:"向后 5 页",prev_3:"向前 3 页",next_3:"向后 3 页",page_size:"页码"},y=[10,20,50,100],C=function(e){var t=e.pageSizeOptions,n=void 0===t?y:t,i=e.locale,a=e.changeSize,r=e.pageSize,c=e.goButton,l=e.quickGo,s=e.rootPrefixCls,d=e.disabled,m=e.buildOptionText,g=e.showSizeChanger,u=e.sizeChangerRender,p=o.useState(""),b=(0,f.Z)(p,2),h=b[0],v=b[1],x=function(){return!h||Number.isNaN(h)?void 0:Number(h)},k="function"==typeof m?m:function(e){return"".concat(e," ").concat(i.items_per_page)},C=function(e){""!==h&&(e.keyCode===S.Z.ENTER||"click"===e.type)&&(v(""),null==l||l(x()))},z="".concat(s,"-options");if(!g&&!l)return null;var w=null,E=null,N=null;return g&&u&&(w=u({disabled:d,size:r,onSizeChange:function(e){null==a||a(Number(e))},"aria-label":i.page_size,className:"".concat(z,"-size-changer"),options:(n.some(function(e){return e.toString()===r.toString()})?n:n.concat([r]).sort(function(e,t){return(Number.isNaN(Number(e))?0:Number(e))-(Number.isNaN(Number(t))?0:Number(t))})).map(function(e){return{label:k(e),value:e}})})),l&&(c&&(N="boolean"==typeof c?o.createElement("button",{type:"button",onClick:C,onKeyUp:C,disabled:d,className:"".concat(z,"-quick-jumper-button")},i.jump_to_confirm):o.createElement("span",{onClick:C,onKeyUp:C},c)),E=o.createElement("div",{className:"".concat(z,"-quick-jumper")},i.jump_to,o.createElement("input",{disabled:d,type:"text",value:h,onChange:function(e){v(e.target.value)},onKeyUp:C,onBlur:function(e){!c&&""!==h&&(v(""),e.relatedTarget&&(e.relatedTarget.className.indexOf("".concat(s,"-item-link"))>=0||e.relatedTarget.className.indexOf("".concat(s,"-item"))>=0)||null==l||l(x()))},"aria-label":i.page}),i.page,N)),o.createElement("li",{className:z},w,E)},z=function(e){var t=e.rootPrefixCls,n=e.page,i=e.active,a=e.className,r=e.showTitle,c=e.onClick,l=e.onKeyPress,s=e.itemRender,d="".concat(t,"-item"),m=u()(d,"".concat(d,"-").concat(n),(0,p.Z)((0,p.Z)({},"".concat(d,"-active"),i),"".concat(d,"-disabled"),!n),a),g=s(n,"page",o.createElement("a",{rel:"nofollow"},n));return g?o.createElement("li",{title:r?String(n):null,className:m,onClick:function(){c(n)},onKeyDown:function(e){l(e,c,n)},tabIndex:0},g):null},w=function(e,t,n){return n};function E(){}function N(e){var t=Number(e);return"number"==typeof t&&!Number.isNaN(t)&&isFinite(t)&&Math.floor(t)===t}function j(e,t,n){return Math.floor((n-1)/(void 0===e?t:e))+1}var I=function(e){var t,n,a,r,c=e.prefixCls,l=void 0===c?"rc-pagination":c,s=e.selectPrefixCls,d=e.className,m=e.current,g=e.defaultCurrent,y=e.total,I=void 0===y?0:y,M=e.pageSize,B=e.defaultPageSize,O=e.onChange,P=void 0===O?E:O,Z=e.hideOnSinglePage,T=e.align,H=e.showPrevNextJumpers,D=e.showQuickJumper,_=e.showLessItems,A=e.showTitle,W=void 0===A||A,R=e.onShowSizeChange,q=void 0===R?E:R,X=e.locale,L=void 0===X?k:X,K=e.style,G=e.totalBoundaryShowSizeChanger,U=e.disabled,J=e.simple,Y=e.showTotal,F=e.showSizeChanger,Q=void 0===F?I>(void 0===G?50:G):F,V=e.sizeChangerRender,$=e.pageSizeOptions,ee=e.itemRender,et=void 0===ee?w:ee,en=e.jumpPrevIcon,eo=e.jumpNextIcon,ei=e.prevIcon,ea=e.nextIcon,er=o.useRef(null),ec=(0,v.Z)(10,{value:M,defaultValue:void 0===B?10:B}),el=(0,f.Z)(ec,2),es=el[0],ed=el[1],em=(0,v.Z)(1,{value:m,defaultValue:void 0===g?1:g,postState:function(e){return Math.max(1,Math.min(e,j(void 0,es,I)))}}),eg=(0,f.Z)(em,2),eu=eg[0],ep=eg[1],eb=o.useState(eu),eh=(0,f.Z)(eb,2),ef=eh[0],ev=eh[1];(0,o.useEffect)(function(){ev(eu)},[eu]);var eS=Math.max(1,eu-(_?3:5)),ex=Math.min(j(void 0,es,I),eu+(_?3:5));function ek(t,n){var i=t||o.createElement("button",{type:"button","aria-label":n,className:"".concat(l,"-item-link")});return"function"==typeof t&&(i=o.createElement(t,(0,h.Z)({},e))),i}function ey(e){var t=e.target.value,n=j(void 0,es,I);return""===t?t:Number.isNaN(Number(t))?ef:t>=n?n:Number(t)}var eC=I>es&&D;function ez(e){var t=ey(e);switch(t!==ef&&ev(t),e.keyCode){case S.Z.ENTER:ew(t);break;case S.Z.UP:ew(t-1);break;case S.Z.DOWN:ew(t+1)}}function ew(e){if(N(e)&&e!==eu&&N(I)&&I>0&&!U){var t=j(void 0,es,I),n=e;return e>t?n=t:e<1&&(n=1),n!==ef&&ev(n),ep(n),null==P||P(n,es),n}return eu}var eE=eu>1,eN=eu2?n-2:0),i=2;iI?I:eu*es])),eD=null,e_=j(void 0,es,I);if(Z&&I<=es)return null;var eA=[],eW={rootPrefixCls:l,onClick:ew,onKeyPress:eO,showTitle:W,itemRender:et,page:-1},eR=eu-1>0?eu-1:0,eq=eu+1=2*eU&&3!==eu&&(eA[0]=o.cloneElement(eA[0],{className:u()("".concat(l,"-item-after-jump-prev"),eA[0].props.className)}),eA.unshift(eZ)),e_-eu>=2*eU&&eu!==e_-2){var e2=eA[eA.length-1];eA[eA.length-1]=o.cloneElement(e2,{className:u()("".concat(l,"-item-before-jump-next"),e2.props.className)}),eA.push(eD)}1!==e$&&eA.unshift(o.createElement(z,(0,i.Z)({},eW,{key:1,page:1}))),e0!==e_&&eA.push(o.createElement(z,(0,i.Z)({},eW,{key:e_,page:e_})))}var e3=(t=et(eR,"prev",ek(ei,"prev page")),o.isValidElement(t)?o.cloneElement(t,{disabled:!eE}):t);if(e3){var e5=!eE||!e_;e3=o.createElement("li",{title:W?L.prev_page:null,onClick:ej,tabIndex:e5?null:0,onKeyDown:function(e){eO(e,ej)},className:u()("".concat(l,"-prev"),(0,p.Z)({},"".concat(l,"-disabled"),e5)),"aria-disabled":e5},e3)}var e6=(n=et(eq,"next",ek(ea,"next page")),o.isValidElement(n)?o.cloneElement(n,{disabled:!eN}):n);e6&&(J?(a=!eN,r=eE?0:null):r=(a=!eN||!e_)?null:0,e6=o.createElement("li",{title:W?L.next_page:null,onClick:eI,tabIndex:r,onKeyDown:function(e){eO(e,eI)},className:u()("".concat(l,"-next"),(0,p.Z)({},"".concat(l,"-disabled"),a)),"aria-disabled":a},e6));var e9=u()(l,d,(0,p.Z)((0,p.Z)((0,p.Z)((0,p.Z)((0,p.Z)({},"".concat(l,"-start"),"start"===T),"".concat(l,"-center"),"center"===T),"".concat(l,"-end"),"end"===T),"".concat(l,"-simple"),J),"".concat(l,"-disabled"),U));return o.createElement("ul",(0,i.Z)({className:e9,style:K,ref:er},eT),eH,e3,J?eG:eA,e6,o.createElement(C,{locale:L,rootPrefixCls:l,disabled:U,selectPrefixCls:void 0===s?"rc-select":s,changeSize:function(e){var t=j(e,es,I),n=eu>t&&0!==t?t:eu;ed(e),ev(n),null==q||q(eu,e),ep(n),null==P||P(n,e)},pageSize:es,pageSizeOptions:$,quickGo:eC?ew:null,goButton:eK,showSizeChanger:Q,sizeChangerRender:V}))},M=n(96257),B=n(71744),O=n(33759),P=n(28617),Z=n(55274),T=n(37592),H=n(91691),D=n(93463),_=n(31282),A=n(37433),W=n(65265),R=n(12918),q=n(71140),X=n(99320);let L=e=>{let{componentCls:t}=e;return{["".concat(t,"-disabled")]:{"&, &:hover":{cursor:"not-allowed",["".concat(t,"-item-link")]:{color:e.colorTextDisabled,cursor:"not-allowed"}},"&:focus-visible":{cursor:"not-allowed",["".concat(t,"-item-link")]:{color:e.colorTextDisabled,cursor:"not-allowed"}}},["&".concat(t,"-disabled")]:{cursor:"not-allowed",["".concat(t,"-item")]:{cursor:"not-allowed",backgroundColor:"transparent","&:hover, &:active":{backgroundColor:"transparent"},a:{color:e.colorTextDisabled,backgroundColor:"transparent",border:"none",cursor:"not-allowed"},"&-active":{borderColor:e.colorBorder,backgroundColor:e.itemActiveBgDisabled,"&:hover, &:active":{backgroundColor:e.itemActiveBgDisabled},a:{color:e.itemActiveColorDisabled}}},["".concat(t,"-item-link")]:{color:e.colorTextDisabled,cursor:"not-allowed","&:hover, &:active":{backgroundColor:"transparent"},["".concat(t,"-simple&")]:{backgroundColor:"transparent","&:hover, &:active":{backgroundColor:"transparent"}}},["".concat(t,"-simple-pager")]:{color:e.colorTextDisabled},["".concat(t,"-jump-prev, ").concat(t,"-jump-next")]:{["".concat(t,"-item-link-icon")]:{opacity:0},["".concat(t,"-item-ellipsis")]:{opacity:1}}}}},K=e=>{let{componentCls:t}=e;return{["&".concat(t,"-mini ").concat(t,"-total-text, &").concat(t,"-mini ").concat(t,"-simple-pager")]:{height:e.itemSizeSM,lineHeight:(0,D.bf)(e.itemSizeSM)},["&".concat(t,"-mini ").concat(t,"-item")]:{minWidth:e.itemSizeSM,height:e.itemSizeSM,margin:0,lineHeight:(0,D.bf)(e.calc(e.itemSizeSM).sub(2).equal())},["&".concat(t,"-mini ").concat(t,"-prev, &").concat(t,"-mini ").concat(t,"-next")]:{minWidth:e.itemSizeSM,height:e.itemSizeSM,margin:0,lineHeight:(0,D.bf)(e.itemSizeSM)},["&".concat(t,"-mini:not(").concat(t,"-disabled)")]:{["".concat(t,"-prev, ").concat(t,"-next")]:{["&:hover ".concat(t,"-item-link")]:{backgroundColor:e.colorBgTextHover},["&:active ".concat(t,"-item-link")]:{backgroundColor:e.colorBgTextActive},["&".concat(t,"-disabled:hover ").concat(t,"-item-link")]:{backgroundColor:"transparent"}}},["\n &".concat(t,"-mini ").concat(t,"-prev ").concat(t,"-item-link,\n &").concat(t,"-mini ").concat(t,"-next ").concat(t,"-item-link\n ")]:{backgroundColor:"transparent",borderColor:"transparent","&::after":{height:e.itemSizeSM,lineHeight:(0,D.bf)(e.itemSizeSM)}},["&".concat(t,"-mini ").concat(t,"-jump-prev, &").concat(t,"-mini ").concat(t,"-jump-next")]:{height:e.itemSizeSM,marginInlineEnd:0,lineHeight:(0,D.bf)(e.itemSizeSM)},["&".concat(t,"-mini ").concat(t,"-options")]:{marginInlineStart:e.paginationMiniOptionsMarginInlineStart,"&-size-changer":{top:e.miniOptionsSizeChangerTop},"&-quick-jumper":{height:e.itemSizeSM,lineHeight:(0,D.bf)(e.itemSizeSM),input:Object.assign(Object.assign({},(0,_.x0)(e)),{width:e.paginationMiniQuickJumperInputWidth,height:e.controlHeightSM})}}}},G=e=>{let{componentCls:t}=e;return{["&".concat(t,"-simple")]:{["".concat(t,"-prev, ").concat(t,"-next")]:{height:e.itemSize,lineHeight:(0,D.bf)(e.itemSize),verticalAlign:"top",["".concat(t,"-item-link")]:{height:e.itemSize,backgroundColor:"transparent",border:0,"&:hover":{backgroundColor:e.colorBgTextHover},"&:active":{backgroundColor:e.colorBgTextActive},"&::after":{height:e.itemSize,lineHeight:(0,D.bf)(e.itemSize)}}},["".concat(t,"-simple-pager")]:{display:"inline-flex",alignItems:"center",height:e.itemSize,marginInlineEnd:e.marginXS,input:{boxSizing:"border-box",height:"100%",width:e.quickJumperInputWidth,padding:"0 ".concat((0,D.bf)(e.paginationItemPaddingInline)),textAlign:"center",backgroundColor:e.itemInputBg,border:"".concat((0,D.bf)(e.lineWidth)," ").concat(e.lineType," ").concat(e.colorBorder),borderRadius:e.borderRadius,outline:"none",transition:"border-color ".concat(e.motionDurationMid),color:"inherit","&:hover":{borderColor:e.colorPrimary},"&:focus":{borderColor:e.colorPrimaryHover,boxShadow:"".concat((0,D.bf)(e.inputOutlineOffset)," 0 ").concat((0,D.bf)(e.controlOutlineWidth)," ").concat(e.controlOutline)},"&[disabled]":{color:e.colorTextDisabled,backgroundColor:e.colorBgContainerDisabled,borderColor:e.colorBorder,cursor:"not-allowed"}}},["&".concat(t,"-disabled")]:{["".concat(t,"-prev, ").concat(t,"-next")]:{["".concat(t,"-item-link")]:{"&:hover, &:active":{backgroundColor:"transparent"}}}},["&".concat(t,"-mini")]:{["".concat(t,"-prev, ").concat(t,"-next")]:{height:e.itemSizeSM,lineHeight:(0,D.bf)(e.itemSizeSM),["".concat(t,"-item-link")]:{height:e.itemSizeSM,"&::after":{height:e.itemSizeSM,lineHeight:(0,D.bf)(e.itemSizeSM)}}},["".concat(t,"-simple-pager")]:{height:e.itemSizeSM,input:{width:e.paginationMiniQuickJumperInputWidth}}}}}},U=e=>{let{componentCls:t}=e;return{["".concat(t,"-jump-prev, ").concat(t,"-jump-next")]:{outline:0,["".concat(t,"-item-container")]:{position:"relative",["".concat(t,"-item-link-icon")]:{color:e.colorPrimary,fontSize:e.fontSizeSM,opacity:0,transition:"all ".concat(e.motionDurationMid),"&-svg":{top:0,insetInlineEnd:0,bottom:0,insetInlineStart:0,margin:"auto"}},["".concat(t,"-item-ellipsis")]:{position:"absolute",top:0,insetInlineEnd:0,bottom:0,insetInlineStart:0,display:"block",margin:"auto",color:e.colorTextDisabled,letterSpacing:e.paginationEllipsisLetterSpacing,textAlign:"center",textIndent:e.paginationEllipsisTextIndent,opacity:1,transition:"all ".concat(e.motionDurationMid)}},"&:hover":{["".concat(t,"-item-link-icon")]:{opacity:1},["".concat(t,"-item-ellipsis")]:{opacity:0}}},["\n ".concat(t,"-prev,\n ").concat(t,"-jump-prev,\n ").concat(t,"-jump-next\n ")]:{marginInlineEnd:e.marginXS},["\n ".concat(t,"-prev,\n ").concat(t,"-next,\n ").concat(t,"-jump-prev,\n ").concat(t,"-jump-next\n ")]:{display:"inline-block",minWidth:e.itemSize,height:e.itemSize,color:e.colorText,fontFamily:e.fontFamily,lineHeight:(0,D.bf)(e.itemSize),textAlign:"center",verticalAlign:"middle",listStyle:"none",borderRadius:e.borderRadius,cursor:"pointer",transition:"all ".concat(e.motionDurationMid)},["".concat(t,"-prev, ").concat(t,"-next")]:{outline:0,button:{color:e.colorText,cursor:"pointer",userSelect:"none"},["".concat(t,"-item-link")]:{display:"block",width:"100%",height:"100%",padding:0,fontSize:e.fontSizeSM,textAlign:"center",backgroundColor:"transparent",border:"".concat((0,D.bf)(e.lineWidth)," ").concat(e.lineType," transparent"),borderRadius:e.borderRadius,outline:"none",transition:"all ".concat(e.motionDurationMid)},["&:hover ".concat(t,"-item-link")]:{backgroundColor:e.colorBgTextHover},["&:active ".concat(t,"-item-link")]:{backgroundColor:e.colorBgTextActive},["&".concat(t,"-disabled:hover")]:{["".concat(t,"-item-link")]:{backgroundColor:"transparent"}}},["".concat(t,"-slash")]:{marginInlineEnd:e.paginationSlashMarginInlineEnd,marginInlineStart:e.paginationSlashMarginInlineStart},["".concat(t,"-options")]:{display:"inline-block",marginInlineStart:e.margin,verticalAlign:"middle","&-size-changer":{display:"inline-block",width:"auto"},"&-quick-jumper":{display:"inline-block",height:e.controlHeight,marginInlineStart:e.marginXS,lineHeight:(0,D.bf)(e.controlHeight),verticalAlign:"top",input:Object.assign(Object.assign(Object.assign({},(0,_.ik)(e)),(0,W.$U)(e,{borderColor:e.colorBorder,hoverBorderColor:e.colorPrimaryHover,activeBorderColor:e.colorPrimary,activeShadow:e.activeShadow})),{"&[disabled]":Object.assign({},(0,W.Xy)(e)),width:e.quickJumperInputWidth,height:e.controlHeight,boxSizing:"border-box",margin:0,marginInlineStart:e.marginXS,marginInlineEnd:e.marginXS})}}}},J=e=>{let{componentCls:t}=e;return{["".concat(t,"-item")]:{display:"inline-block",minWidth:e.itemSize,height:e.itemSize,marginInlineEnd:e.marginXS,fontFamily:e.fontFamily,lineHeight:(0,D.bf)(e.calc(e.itemSize).sub(2).equal()),textAlign:"center",verticalAlign:"middle",listStyle:"none",backgroundColor:e.itemBg,border:"".concat((0,D.bf)(e.lineWidth)," ").concat(e.lineType," transparent"),borderRadius:e.borderRadius,outline:0,cursor:"pointer",userSelect:"none",a:{display:"block",padding:"0 ".concat((0,D.bf)(e.paginationItemPaddingInline)),color:e.colorText,"&:hover":{textDecoration:"none"}},["&:not(".concat(t,"-item-active)")]:{"&:hover":{transition:"all ".concat(e.motionDurationMid),backgroundColor:e.colorBgTextHover},"&:active":{backgroundColor:e.colorBgTextActive}},"&-active":{fontWeight:e.fontWeightStrong,backgroundColor:e.itemActiveBg,borderColor:e.colorPrimary,a:{color:e.itemActiveColor},"&:hover":{borderColor:e.colorPrimaryHover},"&:hover a":{color:e.itemActiveColorHover}}}}},Y=e=>{let{componentCls:t}=e;return{[t]:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},(0,R.Wf)(e)),{display:"flex",flexWrap:"wrap",rowGap:e.paddingXS,"&-start":{justifyContent:"start"},"&-center":{justifyContent:"center"},"&-end":{justifyContent:"end"},"ul, ol":{margin:0,padding:0,listStyle:"none"},"&::after":{display:"block",clear:"both",height:0,overflow:"hidden",visibility:"hidden",content:'""'},["".concat(t,"-total-text")]:{display:"inline-block",height:e.itemSize,marginInlineEnd:e.marginXS,lineHeight:(0,D.bf)(e.calc(e.itemSize).sub(2).equal()),verticalAlign:"middle"}}),J(e)),U(e)),G(e)),K(e)),L(e)),{["@media only screen and (max-width: ".concat(e.screenLG,"px)")]:{["".concat(t,"-item")]:{"&-after-jump-prev, &-before-jump-next":{display:"none"}}},["@media only screen and (max-width: ".concat(e.screenSM,"px)")]:{["".concat(t,"-options")]:{display:"none"}}}),["&".concat(e.componentCls,"-rtl")]:{direction:"rtl"}}},F=e=>{let{componentCls:t}=e;return{["".concat(t,":not(").concat(t,"-disabled)")]:{["".concat(t,"-item")]:Object.assign({},(0,R.Qy)(e)),["".concat(t,"-jump-prev, ").concat(t,"-jump-next")]:{"&:focus-visible":Object.assign({["".concat(t,"-item-link-icon")]:{opacity:1},["".concat(t,"-item-ellipsis")]:{opacity:0}},(0,R.oN)(e))},["".concat(t,"-prev, ").concat(t,"-next")]:{["&:focus-visible ".concat(t,"-item-link")]:(0,R.oN)(e)}}}},Q=e=>Object.assign({itemBg:e.colorBgContainer,itemSize:e.controlHeight,itemSizeSM:e.controlHeightSM,itemActiveBg:e.colorBgContainer,itemActiveColor:e.colorPrimary,itemActiveColorHover:e.colorPrimaryHover,itemLinkBg:e.colorBgContainer,itemActiveColorDisabled:e.colorTextDisabled,itemActiveBgDisabled:e.controlItemBgActiveDisabled,itemInputBg:e.colorBgContainer,miniOptionsSizeChangerTop:0},(0,A.T)(e)),V=e=>(0,q.IX)(e,{inputOutlineOffset:0,quickJumperInputWidth:e.calc(e.controlHeightLG).mul(1.25).equal(),paginationMiniOptionsMarginInlineStart:e.calc(e.marginXXS).div(2).equal(),paginationMiniQuickJumperInputWidth:e.calc(e.controlHeightLG).mul(1.1).equal(),paginationItemPaddingInline:e.calc(e.marginXXS).mul(1.5).equal(),paginationEllipsisLetterSpacing:e.calc(e.marginXXS).div(2).equal(),paginationSlashMarginInlineStart:e.marginSM,paginationSlashMarginInlineEnd:e.marginSM,paginationEllipsisTextIndent:"0.13em"},(0,A.e)(e));var $=(0,X.I$)("Pagination",e=>{let t=V(e);return[Y(t),F(t)]},Q);let ee=e=>{let{componentCls:t}=e;return{["".concat(t).concat(t,"-bordered").concat(t,"-disabled:not(").concat(t,"-mini)")]:{"&, &:hover":{["".concat(t,"-item-link")]:{borderColor:e.colorBorder}},"&:focus-visible":{["".concat(t,"-item-link")]:{borderColor:e.colorBorder}},["".concat(t,"-item, ").concat(t,"-item-link")]:{backgroundColor:e.colorBgContainerDisabled,borderColor:e.colorBorder,["&:hover:not(".concat(t,"-item-active)")]:{backgroundColor:e.colorBgContainerDisabled,borderColor:e.colorBorder,a:{color:e.colorTextDisabled}},["&".concat(t,"-item-active")]:{backgroundColor:e.itemActiveBgDisabled}},["".concat(t,"-prev, ").concat(t,"-next")]:{"&:hover button":{backgroundColor:e.colorBgContainerDisabled,borderColor:e.colorBorder,color:e.colorTextDisabled},["".concat(t,"-item-link")]:{backgroundColor:e.colorBgContainerDisabled,borderColor:e.colorBorder}}},["".concat(t).concat(t,"-bordered:not(").concat(t,"-mini)")]:{["".concat(t,"-prev, ").concat(t,"-next")]:{"&:hover button":{borderColor:e.colorPrimaryHover,backgroundColor:e.itemBg},["".concat(t,"-item-link")]:{backgroundColor:e.itemLinkBg,borderColor:e.colorBorder},["&:hover ".concat(t,"-item-link")]:{borderColor:e.colorPrimary,backgroundColor:e.itemBg,color:e.colorPrimary},["&".concat(t,"-disabled")]:{["".concat(t,"-item-link")]:{borderColor:e.colorBorder,color:e.colorTextDisabled}}},["".concat(t,"-item")]:{backgroundColor:e.itemBg,border:"".concat((0,D.bf)(e.lineWidth)," ").concat(e.lineType," ").concat(e.colorBorder),["&:hover:not(".concat(t,"-item-active)")]:{borderColor:e.colorPrimary,backgroundColor:e.itemBg,a:{color:e.colorPrimary}},"&-active":{borderColor:e.colorPrimary}}}}};var et=(0,X.bk)(["Pagination","bordered"],e=>ee(V(e)),Q);function en(e){return(0,o.useMemo)(()=>"boolean"==typeof e?[e,{}]:e&&"object"==typeof e?[!0,e]:[void 0,void 0],[e])}var eo=function(e,t){var n={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&0>t.indexOf(o)&&(n[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,o=Object.getOwnPropertySymbols(e);it.indexOf(o[i])&&Object.prototype.propertyIsEnumerable.call(e,o[i])&&(n[o[i]]=e[o[i]]);return n},ei=e=>{let{align:t,prefixCls:n,selectPrefixCls:i,className:a,rootClassName:r,style:l,size:g,locale:p,responsive:b,showSizeChanger:h,selectComponentClass:f,pageSizeOptions:v}=e,S=eo(e,["align","prefixCls","selectPrefixCls","className","rootClassName","style","size","locale","responsive","showSizeChanger","selectComponentClass","pageSizeOptions"]),{xs:x}=(0,P.Z)(b),[,k]=(0,H.ZP)(),{getPrefixCls:y,direction:C,showSizeChanger:z,className:w,style:E}=(0,B.dj)("pagination"),N=y("pagination",n),[j,D,_]=$(N),A=(0,O.Z)(g),W="small"===A||!!(x&&!A&&b),[R]=(0,Z.Z)("Pagination",M.Z),q=Object.assign(Object.assign({},R),p),[X,L]=en(h),[K,G]=en(z),U=null!=L?L:G,J=f||T.default,Y=o.useMemo(()=>v?v.map(e=>Number(e)):void 0,[v]),F=o.useMemo(()=>{let e=o.createElement("span",{className:"".concat(N,"-item-ellipsis")},"•••"),t=o.createElement("button",{className:"".concat(N,"-item-link"),type:"button",tabIndex:-1},"rtl"===C?o.createElement(m.Z,null):o.createElement(d.Z,null));return{prevIcon:t,nextIcon:o.createElement("button",{className:"".concat(N,"-item-link"),type:"button",tabIndex:-1},"rtl"===C?o.createElement(d.Z,null):o.createElement(m.Z,null)),jumpPrevIcon:o.createElement("a",{className:"".concat(N,"-item-link")},o.createElement("div",{className:"".concat(N,"-item-container")},"rtl"===C?o.createElement(s,{className:"".concat(N,"-item-link-icon")}):o.createElement(c,{className:"".concat(N,"-item-link-icon")}),e)),jumpNextIcon:o.createElement("a",{className:"".concat(N,"-item-link")},o.createElement("div",{className:"".concat(N,"-item-container")},"rtl"===C?o.createElement(c,{className:"".concat(N,"-item-link-icon")}):o.createElement(s,{className:"".concat(N,"-item-link-icon")}),e))}},[C,N]),Q=y("select",i),V=u()({["".concat(N,"-").concat(t)]:!!t,["".concat(N,"-mini")]:W,["".concat(N,"-rtl")]:"rtl"===C,["".concat(N,"-bordered")]:k.wireframe},w,a,r,D,_),ee=Object.assign(Object.assign({},E),l);return j(o.createElement(o.Fragment,null,k.wireframe&&o.createElement(et,{prefixCls:N}),o.createElement(I,Object.assign({},F,S,{style:ee,prefixCls:N,selectPrefixCls:Q,className:V,locale:q,pageSizeOptions:Y,showSizeChanger:null!=X?X:K,sizeChangerRender:e=>{var t;let{disabled:n,size:i,onSizeChange:a,"aria-label":r,className:c,options:l}=e,{className:s,onChange:d}=U||{},m=null===(t=l.find(e=>String(e.value)===String(i)))||void 0===t?void 0:t.value;return o.createElement(J,Object.assign({disabled:n,showSearch:!0,popupMatchSelectWidth:!1,getPopupContainer:e=>e.parentNode,"aria-label":r,options:l},U,{value:m,onChange:(e,t)=>{null==a||a(e),null==d||d(e,t)},size:W?"small":"middle",className:u()(c,s)}))}}))))}}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/1717-bb1b888f6ccc52d6.js b/litellm/proxy/_experimental/out/_next/static/chunks/1717-bb1b888f6ccc52d6.js deleted file mode 100644 index 85a7967f39f..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/1717-bb1b888f6ccc52d6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1717],{58747:function(e,t,n){n.d(t,{Z:function(){return a}});var r=n(5853),o=n(2265);let a=e=>{var t=(0,r._T)(e,[]);return o.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"},t),o.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"}))}},4537:function(e,t,n){n.d(t,{Z:function(){return a}});var r=n(5853),o=n(2265);let a=e=>{var t=(0,r._T)(e,[]);return o.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"},t),o.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"}))}},27281:function(e,t,n){n.d(t,{Z:function(){return f}});var r=n(5853),o=n(58747),a=n(2265),l=n(4537),i=n(13241),c=n(1153),s=n(96398),u=n(51975),d=n(85238),m=n(44140);let b=(0,c.fn)("Select"),f=a.forwardRef((e,t)=>{let{defaultValue:n="",value:c,onValueChange:f,placeholder:p="Select...",disabled:g=!1,icon:v,enableClear:h=!1,required:w,children:y,name:E,error:x=!1,errorMessage:N,className:O,id:C}=e,k=(0,r._T)(e,["defaultValue","value","onValueChange","placeholder","disabled","icon","enableClear","required","children","name","error","errorMessage","className","id"]),S=(0,a.useRef)(null),j=a.Children.toArray(y),[T,R]=(0,m.Z)(n,c),I=(0,a.useMemo)(()=>{let e=a.Children.toArray(y).filter(a.isValidElement);return(0,s.sl)(e)},[y]);return a.createElement("div",{className:(0,i.q)("w-full min-w-[10rem] text-tremor-default",O)},a.createElement("div",{className:"relative"},a.createElement("select",{title:"select-hidden",required:w,className:(0,i.q)("h-full w-full absolute left-0 top-0 -z-10 opacity-0"),value:T,onChange:e=>{e.preventDefault()},name:E,disabled:g,id:C,onFocus:()=>{let e=S.current;e&&e.focus()}},a.createElement("option",{className:"hidden",value:"",disabled:!0,hidden:!0},p),j.map(e=>{let t=e.props.value,n=e.props.children;return a.createElement("option",{className:"hidden",key:t,value:t},n)})),a.createElement(u.Ri,Object.assign({as:"div",ref:t,defaultValue:T,value:T,onChange:e=>{null==f||f(e),R(e)},disabled:g,id:C},k),e=>{var t;let{value:n}=e;return a.createElement(a.Fragment,null,a.createElement(u.Y4,{ref:S,className:(0,i.q)("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",v?"pl-10":"pl-3",(0,s.um)((0,s.Uh)(n),g,x))},v&&a.createElement("span",{className:(0,i.q)("absolute inset-y-0 left-0 flex items-center ml-px pl-2.5")},a.createElement(v,{className:(0,i.q)(b("Icon"),"flex-none h-5 w-5","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle")})),a.createElement("span",{className:"w-[90%] block truncate"},n&&null!==(t=I.get(n))&&void 0!==t?t:p),a.createElement("span",{className:(0,i.q)("absolute inset-y-0 right-0 flex items-center mr-3")},a.createElement(o.Z,{className:(0,i.q)(b("arrowDownIcon"),"flex-none h-5 w-5","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle")}))),h&&T?a.createElement("button",{type:"button",className:(0,i.q)("absolute inset-y-0 right-0 flex items-center mr-8"),onClick:e=>{e.preventDefault(),R(""),null==f||f("")}},a.createElement(l.Z,{className:(0,i.q)(b("clearIcon"),"flex-none h-4 w-4","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle")})):null,a.createElement(d.u,{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.createElement(u.O_,{anchor:"bottom start",className:(0,i.q)("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)))})),x&&N?a.createElement("p",{className:(0,i.q)("errorMessage","text-sm text-rose-500 mt-1")},N):null)});f.displayName="Select"},67982:function(e,t,n){n.d(t,{Z:function(){return c}});var r=n(5853),o=n(13241),a=n(1153),l=n(2265);let i=(0,a.fn)("Divider"),c=l.forwardRef((e,t)=>{let{className:n,children:a}=e,c=(0,r._T)(e,["className","children"]);return l.createElement("div",Object.assign({ref:t,className:(0,o.q)(i("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",n)},c),a?l.createElement(l.Fragment,null,l.createElement("div",{className:(0,o.q)("w-full h-[1px] bg-tremor-border dark:bg-dark-tremor-border")}),l.createElement("div",{className:(0,o.q)("text-inherit whitespace-nowrap")},a),l.createElement("div",{className:(0,o.q)("w-full h-[1px] bg-tremor-border dark:bg-dark-tremor-border")})):l.createElement("div",{className:(0,o.q)("w-full h-[1px] bg-tremor-border dark:bg-dark-tremor-border")}))});c.displayName="Divider"},33866:function(e,t,n){n.d(t,{Z:function(){return F}});var r=n(2265),o=n(36760),a=n.n(o),l=n(66632),i=n(93350),c=n(19722),s=n(71744),u=n(93463),d=n(12918),m=n(18536),b=n(71140),f=n(99320);let p=new u.E4("antStatusProcessing",{"0%":{transform:"scale(0.8)",opacity:.5},"100%":{transform:"scale(2.4)",opacity:0}}),g=new u.E4("antZoomBadgeIn",{"0%":{transform:"scale(0) translate(50%, -50%)",opacity:0},"100%":{transform:"scale(1) translate(50%, -50%)"}}),v=new u.E4("antZoomBadgeOut",{"0%":{transform:"scale(1) translate(50%, -50%)"},"100%":{transform:"scale(0) translate(50%, -50%)",opacity:0}}),h=new u.E4("antNoWrapperZoomBadgeIn",{"0%":{transform:"scale(0)",opacity:0},"100%":{transform:"scale(1)"}}),w=new u.E4("antNoWrapperZoomBadgeOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0)",opacity:0}}),y=new u.E4("antBadgeLoadingCircle",{"0%":{transformOrigin:"50%"},"100%":{transform:"translate(50%, -50%) rotate(360deg)",transformOrigin:"50%"}}),E=e=>{let{componentCls:t,iconCls:n,antCls:r,badgeShadowSize:o,textFontSize:a,textFontSizeSM:l,statusSize:i,dotSize:c,textFontWeight:s,indicatorHeight:b,indicatorHeightSM:f,marginXS:E,calc:x}=e,N="".concat(r,"-scroll-number"),O=(0,m.Z)(e,(e,n)=>{let{darkColor:r}=n;return{["&".concat(t," ").concat(t,"-color-").concat(e)]:{background:r,["&:not(".concat(t,"-count)")]:{color:r},"a:hover &":{background:r}}}});return{[t]:Object.assign(Object.assign(Object.assign(Object.assign({},(0,d.Wf)(e)),{position:"relative",display:"inline-block",width:"fit-content",lineHeight:1,["".concat(t,"-count")]:{display:"inline-flex",justifyContent:"center",zIndex:e.indicatorZIndex,minWidth:b,height:b,color:e.badgeTextColor,fontWeight:s,fontSize:a,lineHeight:(0,u.bf)(b),whiteSpace:"nowrap",textAlign:"center",background:e.badgeColor,borderRadius:x(b).div(2).equal(),boxShadow:"0 0 0 ".concat((0,u.bf)(o)," ").concat(e.badgeShadowColor),transition:"background ".concat(e.motionDurationMid),a:{color:e.badgeTextColor},"a:hover":{color:e.badgeTextColor},"a:hover &":{background:e.badgeColorHover}},["".concat(t,"-count-sm")]:{minWidth:f,height:f,fontSize:l,lineHeight:(0,u.bf)(f),borderRadius:x(f).div(2).equal()},["".concat(t,"-multiple-words")]:{padding:"0 ".concat((0,u.bf)(e.paddingXS)),bdi:{unicodeBidi:"plaintext"}},["".concat(t,"-dot")]:{zIndex:e.indicatorZIndex,width:c,minWidth:c,height:c,background:e.badgeColor,borderRadius:"100%",boxShadow:"0 0 0 ".concat((0,u.bf)(o)," ").concat(e.badgeShadowColor)},["".concat(t,"-count, ").concat(t,"-dot, ").concat(N,"-custom-component")]:{position:"absolute",top:0,insetInlineEnd:0,transform:"translate(50%, -50%)",transformOrigin:"100% 0%",["&".concat(n,"-spin")]:{animationName:y,animationDuration:"1s",animationIterationCount:"infinite",animationTimingFunction:"linear"}},["&".concat(t,"-status")]:{lineHeight:"inherit",verticalAlign:"baseline",["".concat(t,"-status-dot")]:{position:"relative",top:-1,display:"inline-block",width:i,height:i,verticalAlign:"middle",borderRadius:"50%"},["".concat(t,"-status-success")]:{backgroundColor:e.colorSuccess},["".concat(t,"-status-processing")]:{overflow:"visible",color:e.colorInfo,backgroundColor:e.colorInfo,borderColor:"currentcolor","&::after":{position:"absolute",top:0,insetInlineStart:0,width:"100%",height:"100%",borderWidth:o,borderStyle:"solid",borderColor:"inherit",borderRadius:"50%",animationName:p,animationDuration:e.badgeProcessingDuration,animationIterationCount:"infinite",animationTimingFunction:"ease-in-out",content:'""'}},["".concat(t,"-status-default")]:{backgroundColor:e.colorTextPlaceholder},["".concat(t,"-status-error")]:{backgroundColor:e.colorError},["".concat(t,"-status-warning")]:{backgroundColor:e.colorWarning},["".concat(t,"-status-text")]:{marginInlineStart:E,color:e.colorText,fontSize:e.fontSize}}}),O),{["".concat(t,"-zoom-appear, ").concat(t,"-zoom-enter")]:{animationName:g,animationDuration:e.motionDurationSlow,animationTimingFunction:e.motionEaseOutBack,animationFillMode:"both"},["".concat(t,"-zoom-leave")]:{animationName:v,animationDuration:e.motionDurationSlow,animationTimingFunction:e.motionEaseOutBack,animationFillMode:"both"},["&".concat(t,"-not-a-wrapper")]:{["".concat(t,"-zoom-appear, ").concat(t,"-zoom-enter")]:{animationName:h,animationDuration:e.motionDurationSlow,animationTimingFunction:e.motionEaseOutBack},["".concat(t,"-zoom-leave")]:{animationName:w,animationDuration:e.motionDurationSlow,animationTimingFunction:e.motionEaseOutBack},["&:not(".concat(t,"-status)")]:{verticalAlign:"middle"},["".concat(N,"-custom-component, ").concat(t,"-count")]:{transform:"none"},["".concat(N,"-custom-component, ").concat(N)]:{position:"relative",top:"auto",display:"block",transformOrigin:"50% 50%"}},[N]:{overflow:"hidden",transition:"all ".concat(e.motionDurationMid," ").concat(e.motionEaseOutBack),["".concat(N,"-only")]:{position:"relative",display:"inline-block",height:b,transition:"all ".concat(e.motionDurationSlow," ").concat(e.motionEaseOutBack),WebkitTransformStyle:"preserve-3d",WebkitBackfaceVisibility:"hidden",["> p".concat(N,"-only-unit")]:{height:b,margin:0,WebkitTransformStyle:"preserve-3d",WebkitBackfaceVisibility:"hidden"}},["".concat(N,"-symbol")]:{verticalAlign:"top"}},"&-rtl":{direction:"rtl",["".concat(t,"-count, ").concat(t,"-dot, ").concat(N,"-custom-component")]:{transform:"translate(-50%, -50%)"}}})}},x=e=>{let{fontHeight:t,lineWidth:n,marginXS:r,colorBorderBg:o}=e,a=e.colorTextLightSolid,l=e.colorError,i=e.colorErrorHover;return(0,b.IX)(e,{badgeFontHeight:t,badgeShadowSize:n,badgeTextColor:a,badgeColor:l,badgeColorHover:i,badgeShadowColor:o,badgeProcessingDuration:"1.2s",badgeRibbonOffset:r,badgeRibbonCornerTransform:"scaleY(0.75)",badgeRibbonCornerFilter:"brightness(75%)"})},N=e=>{let{fontSize:t,lineHeight:n,fontSizeSM:r,lineWidth:o}=e;return{indicatorZIndex:"auto",indicatorHeight:Math.round(t*n)-2*o,indicatorHeightSM:t,dotSize:r/2,textFontSize:r,textFontSizeSM:r,textFontWeight:"normal",statusSize:r/2}};var O=(0,f.I$)("Badge",e=>E(x(e)),N);let C=e=>{let{antCls:t,badgeFontHeight:n,marginXS:r,badgeRibbonOffset:o,calc:a}=e,l="".concat(t,"-ribbon"),i=(0,m.Z)(e,(e,t)=>{let{darkColor:n}=t;return{["&".concat(l,"-color-").concat(e)]:{background:n,color:n}}});return{["".concat(t,"-ribbon-wrapper")]:{position:"relative"},[l]:Object.assign(Object.assign(Object.assign(Object.assign({},(0,d.Wf)(e)),{position:"absolute",top:r,padding:"0 ".concat((0,u.bf)(e.paddingXS)),color:e.colorPrimary,lineHeight:(0,u.bf)(n),whiteSpace:"nowrap",backgroundColor:e.colorPrimary,borderRadius:e.borderRadiusSM,["".concat(l,"-text")]:{color:e.badgeTextColor},["".concat(l,"-corner")]:{position:"absolute",top:"100%",width:o,height:o,color:"currentcolor",border:"".concat((0,u.bf)(a(o).div(2).equal())," solid"),transform:e.badgeRibbonCornerTransform,transformOrigin:"top",filter:e.badgeRibbonCornerFilter}}),i),{["&".concat(l,"-placement-end")]:{insetInlineEnd:a(o).mul(-1).equal(),borderEndEndRadius:0,["".concat(l,"-corner")]:{insetInlineEnd:0,borderInlineEndColor:"transparent",borderBlockEndColor:"transparent"}},["&".concat(l,"-placement-start")]:{insetInlineStart:a(o).mul(-1).equal(),borderEndStartRadius:0,["".concat(l,"-corner")]:{insetInlineStart:0,borderBlockEndColor:"transparent",borderInlineStartColor:"transparent"}},"&-rtl":{direction:"rtl"}})}};var k=(0,f.I$)(["Badge","Ribbon"],e=>C(x(e)),N);let S=e=>{let t;let{prefixCls:n,value:o,current:l,offset:i=0}=e;return i&&(t={position:"absolute",top:"".concat(i,"00%"),left:0}),r.createElement("span",{style:t,className:a()("".concat(n,"-only-unit"),{current:l})},o)};var j=e=>{let t,n;let{prefixCls:o,count:a,value:l}=e,i=Number(l),c=Math.abs(a),[s,u]=r.useState(i),[d,m]=r.useState(c),b=()=>{u(i),m(c)};if(r.useEffect(()=>{let e=setTimeout(b,1e3);return()=>clearTimeout(e)},[i]),s===i||Number.isNaN(i)||Number.isNaN(s))t=[r.createElement(S,Object.assign({},e,{key:i,current:!0}))],n={transition:"none"};else{t=[];let o=i+10,a=[];for(let e=i;e<=o;e+=1)a.push(e);let l=de%10===s);t=(l<0?a.slice(0,u+1):a.slice(u)).map((t,n)=>r.createElement(S,Object.assign({},e,{key:t,value:t%10,offset:l<0?n-u:n,current:n===u}))),n={transform:"translateY(".concat(-function(e,t,n){let r=e,o=0;for(;(r+10)%10!==t;)r+=n,o+=n;return o}(s,i,l),"00%)")}}return r.createElement("span",{className:"".concat(o,"-only"),style:n,onTransitionEnd:b},t)},T=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&0>t.indexOf(r)&&(n[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])&&(n[r[o]]=e[r[o]]);return n};let R=r.forwardRef((e,t)=>{let{prefixCls:n,count:o,className:l,motionClassName:i,style:u,title:d,show:m,component:b="sup",children:f}=e,p=T(e,["prefixCls","count","className","motionClassName","style","title","show","component","children"]),{getPrefixCls:g}=r.useContext(s.E_),v=g("scroll-number",n),h=Object.assign(Object.assign({},p),{"data-show":m,style:u,className:a()(v,l,i),title:d}),w=o;if(o&&Number(o)%1==0){let e=String(o).split("");w=r.createElement("bdi",null,e.map((t,n)=>r.createElement(j,{prefixCls:v,count:Number(o),value:t,key:e.length-n})))}return((null==u?void 0:u.borderColor)&&(h.style=Object.assign(Object.assign({},u),{boxShadow:"0 0 0 1px ".concat(u.borderColor," inset")})),f)?(0,c.Tm)(f,e=>({className:a()("".concat(v,"-custom-component"),null==e?void 0:e.className,i)})):r.createElement(b,Object.assign({},h,{ref:t}),w)});var I=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&0>t.indexOf(r)&&(n[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])&&(n[r[o]]=e[r[o]]);return n};let z=r.forwardRef((e,t)=>{var n,o,u,d,m;let{prefixCls:b,scrollNumberPrefixCls:f,children:p,status:g,text:v,color:h,count:w=null,overflowCount:y=99,dot:E=!1,size:x="default",title:N,offset:C,style:k,className:S,rootClassName:j,classNames:T,styles:z,showZero:F=!1}=e,Z=I(e,["prefixCls","scrollNumberPrefixCls","children","status","text","color","count","overflowCount","dot","size","title","offset","style","className","rootClassName","classNames","styles","showZero"]),{getPrefixCls:M,direction:P,badge:L}=r.useContext(s.E_),q=M("badge",b),[D,B,H]=O(q),W=w>y?"".concat(y,"+"):w,A="0"===W||0===W||"0"===v||0===v,V=null===w||A&&!F,_=(null!=g||null!=h)&&V,U=null!=g||!A,X=E&&!A,Y=X?"":W,J=(0,r.useMemo)(()=>((null==Y||""===Y)&&(null==v||""===v)||A&&!F)&&!X,[Y,A,F,X,v]),$=(0,r.useRef)(w);J||($.current=w);let G=$.current,K=(0,r.useRef)(Y);J||(K.current=Y);let Q=K.current,ee=(0,r.useRef)(X);J||(ee.current=X);let et=(0,r.useMemo)(()=>{if(!C)return Object.assign(Object.assign({},null==L?void 0:L.style),k);let e={marginTop:C[1]};return"rtl"===P?e.left=Number.parseInt(C[0],10):e.right=-Number.parseInt(C[0],10),Object.assign(Object.assign(Object.assign({},e),null==L?void 0:L.style),k)},[P,C,k,null==L?void 0:L.style]),en=null!=N?N:"string"==typeof G||"number"==typeof G?G:void 0,er=!J&&(0===v?F:!!v&&!0!==v),eo=er?r.createElement("span",{className:"".concat(q,"-status-text")},v):null,ea=G&&"object"==typeof G?(0,c.Tm)(G,e=>({style:Object.assign(Object.assign({},et),e.style)})):void 0,el=(0,i.o2)(h,!1),ei=a()(null==T?void 0:T.indicator,null===(n=null==L?void 0:L.classNames)||void 0===n?void 0:n.indicator,{["".concat(q,"-status-dot")]:_,["".concat(q,"-status-").concat(g)]:!!g,["".concat(q,"-color-").concat(h)]:el}),ec={};h&&!el&&(ec.color=h,ec.background=h);let es=a()(q,{["".concat(q,"-status")]:_,["".concat(q,"-not-a-wrapper")]:!p,["".concat(q,"-rtl")]:"rtl"===P},S,j,null==L?void 0:L.className,null===(o=null==L?void 0:L.classNames)||void 0===o?void 0:o.root,null==T?void 0:T.root,B,H);if(!p&&_&&(v||U||!V)){let e=et.color;return D(r.createElement("span",Object.assign({},Z,{className:es,style:Object.assign(Object.assign(Object.assign({},null==z?void 0:z.root),null===(u=null==L?void 0:L.styles)||void 0===u?void 0:u.root),et)}),r.createElement("span",{className:ei,style:Object.assign(Object.assign(Object.assign({},null==z?void 0:z.indicator),null===(d=null==L?void 0:L.styles)||void 0===d?void 0:d.indicator),ec)}),er&&r.createElement("span",{style:{color:e},className:"".concat(q,"-status-text")},v)))}return D(r.createElement("span",Object.assign({ref:t},Z,{className:es,style:Object.assign(Object.assign({},null===(m=null==L?void 0:L.styles)||void 0===m?void 0:m.root),null==z?void 0:z.root)}),p,r.createElement(l.ZP,{visible:!J,motionName:"".concat(q,"-zoom"),motionAppear:!1,motionDeadline:1e3},e=>{var t,n;let{className:o}=e,l=M("scroll-number",f),i=ee.current,c=a()(null==T?void 0:T.indicator,null===(t=null==L?void 0:L.classNames)||void 0===t?void 0:t.indicator,{["".concat(q,"-dot")]:i,["".concat(q,"-count")]:!i,["".concat(q,"-count-sm")]:"small"===x,["".concat(q,"-multiple-words")]:!i&&Q&&Q.toString().length>1,["".concat(q,"-status-").concat(g)]:!!g,["".concat(q,"-color-").concat(h)]:el}),s=Object.assign(Object.assign(Object.assign({},null==z?void 0:z.indicator),null===(n=null==L?void 0:L.styles)||void 0===n?void 0:n.indicator),et);return h&&!el&&((s=s||{}).background=h),r.createElement(R,{prefixCls:l,show:!J,motionClassName:o,className:c,count:Q,title:en,style:s,key:"scrollNumber"},ea)}),eo))});z.Ribbon=e=>{let{className:t,prefixCls:n,style:o,color:l,children:c,text:u,placement:d="end",rootClassName:m}=e,{getPrefixCls:b,direction:f}=r.useContext(s.E_),p=b("ribbon",n),g="".concat(p,"-wrapper"),[v,h,w]=k(p,g),y=(0,i.o2)(l,!1),E=a()(p,"".concat(p,"-placement-").concat(d),{["".concat(p,"-rtl")]:"rtl"===f,["".concat(p,"-color-").concat(l)]:y},t),x={},N={};return l&&!y&&(x.background=l,N.color=l),v(r.createElement("div",{className:a()(g,m,h,w)},c,r.createElement("div",{className:a()(E,h),style:Object.assign(Object.assign({},x),o)},r.createElement("span",{className:"".concat(p,"-text")},u),r.createElement("div",{className:"".concat(p,"-corner"),style:N}))))};var F=z},85238:function(e,t,n){let r;n.d(t,{u:function(){return j}});var o=n(2265),a=n(59456),l=n(93980),i=n(25289),c=n(73389),s=n(43507),u=n(180),d=n(67561),m=n(98218),b=n(28294),f=n(95504),p=n(72468),g=n(38929);function v(e){var t;return!!(e.enter||e.enterFrom||e.enterTo||e.leave||e.leaveFrom||e.leaveTo)||(null!=(t=e.as)?t:N)!==o.Fragment||1===o.Children.count(e.children)}let h=(0,o.createContext)(null);h.displayName="TransitionContext";var w=((r=w||{}).Visible="visible",r.Hidden="hidden",r);let y=(0,o.createContext)(null);function E(e){return"children"in e?E(e.children):e.current.filter(e=>{let{el:t}=e;return null!==t.current}).filter(e=>{let{state:t}=e;return"visible"===t}).length>0}function x(e,t){let n=(0,s.E)(e),r=(0,o.useRef)([]),c=(0,i.t)(),u=(0,a.G)(),d=(0,l.z)(function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:g.l4.Hidden,o=r.current.findIndex(t=>{let{el:n}=t;return n===e});-1!==o&&((0,p.E)(t,{[g.l4.Unmount](){r.current.splice(o,1)},[g.l4.Hidden](){r.current[o].state="hidden"}}),u.microTask(()=>{var e;!E(r)&&c.current&&(null==(e=n.current)||e.call(n))}))}),m=(0,l.z)(e=>{let t=r.current.find(t=>{let{el:n}=t;return n===e});return t?"visible"!==t.state&&(t.state="visible"):r.current.push({el:e,state:"visible"}),()=>d(e,g.l4.Unmount)}),b=(0,o.useRef)([]),f=(0,o.useRef)(Promise.resolve()),v=(0,o.useRef)({enter:[],leave:[]}),h=(0,l.z)((e,n,r)=>{b.current.splice(0),t&&(t.chains.current[n]=t.chains.current[n].filter(t=>{let[n]=t;return n!==e})),null==t||t.chains.current[n].push([e,new Promise(e=>{b.current.push(e)})]),null==t||t.chains.current[n].push([e,new Promise(e=>{Promise.all(v.current[n].map(e=>{let[t,n]=e;return n})).then(()=>e())})]),"enter"===n?f.current=f.current.then(()=>null==t?void 0:t.wait.current).then(()=>r(n)):r(n)}),w=(0,l.z)((e,t,n)=>{Promise.all(v.current[t].splice(0).map(e=>{let[t,n]=e;return n})).then(()=>{var e;null==(e=b.current.shift())||e()}).then(()=>n(t))});return(0,o.useMemo)(()=>({children:r,register:m,unregister:d,onStart:h,onStop:w,wait:f,chains:v}),[m,d,r,h,w,v,f])}y.displayName="NestingContext";let N=o.Fragment,O=g.VN.RenderStrategy,C=(0,g.yV)(function(e,t){let{show:n,appear:r=!1,unmount:a=!0,...i}=e,s=(0,o.useRef)(null),m=v(e),f=(0,d.T)(...m?[s,t]:null===t?[]:[t]);(0,u.H)();let p=(0,b.oJ)();if(void 0===n&&null!==p&&(n=(p&b.ZM.Open)===b.ZM.Open),void 0===n)throw Error("A is used but it is missing a `show={true | false}` prop.");let[w,N]=(0,o.useState)(n?"visible":"hidden"),C=x(()=>{n||N("hidden")}),[S,j]=(0,o.useState)(!0),T=(0,o.useRef)([n]);(0,c.e)(()=>{!1!==S&&T.current[T.current.length-1]!==n&&(T.current.push(n),j(!1))},[T,n]);let R=(0,o.useMemo)(()=>({show:n,appear:r,initial:S}),[n,r,S]);(0,c.e)(()=>{n?N("visible"):E(C)||null===s.current||N("hidden")},[n,C]);let I={unmount:a},z=(0,l.z)(()=>{var t;S&&j(!1),null==(t=e.beforeEnter)||t.call(e)}),F=(0,l.z)(()=>{var t;S&&j(!1),null==(t=e.beforeLeave)||t.call(e)}),Z=(0,g.L6)();return o.createElement(y.Provider,{value:C},o.createElement(h.Provider,{value:R},Z({ourProps:{...I,as:o.Fragment,children:o.createElement(k,{ref:f,...I,...i,beforeEnter:z,beforeLeave:F})},theirProps:{},defaultTag:o.Fragment,features:O,visible:"visible"===w,name:"Transition"})))}),k=(0,g.yV)(function(e,t){var n,r;let{transition:a=!0,beforeEnter:i,afterEnter:s,beforeLeave:w,afterLeave:C,enter:k,enterFrom:S,enterTo:j,entered:T,leave:R,leaveFrom:I,leaveTo:z,...F}=e,[Z,M]=(0,o.useState)(null),P=(0,o.useRef)(null),L=v(e),q=(0,d.T)(...L?[P,t,M]:null===t?[]:[t]),D=null==(n=F.unmount)||n?g.l4.Unmount:g.l4.Hidden,{show:B,appear:H,initial:W}=function(){let e=(0,o.useContext)(h);if(null===e)throw Error("A is used but it is missing a parent or .");return e}(),[A,V]=(0,o.useState)(B?"visible":"hidden"),_=function(){let e=(0,o.useContext)(y);if(null===e)throw Error("A is used but it is missing a parent or .");return e}(),{register:U,unregister:X}=_;(0,c.e)(()=>U(P),[U,P]),(0,c.e)(()=>{if(D===g.l4.Hidden&&P.current){if(B&&"visible"!==A){V("visible");return}return(0,p.E)(A,{hidden:()=>X(P),visible:()=>U(P)})}},[A,P,U,X,B,D]);let Y=(0,u.H)();(0,c.e)(()=>{if(L&&Y&&"visible"===A&&null===P.current)throw Error("Did you forget to passthrough the `ref` to the actual DOM node?")},[P,A,Y,L]);let J=W&&!H,$=H&&B&&W,G=(0,o.useRef)(!1),K=x(()=>{G.current||(V("hidden"),X(P))},_),Q=(0,l.z)(e=>{G.current=!0,K.onStart(P,e?"enter":"leave",e=>{"enter"===e?null==i||i():"leave"===e&&(null==w||w())})}),ee=(0,l.z)(e=>{let t=e?"enter":"leave";G.current=!1,K.onStop(P,t,e=>{"enter"===e?null==s||s():"leave"===e&&(null==C||C())}),"leave"!==t||E(K)||(V("hidden"),X(P))});(0,o.useEffect)(()=>{L&&a||(Q(B),ee(B))},[B,L,a]);let et=!(!a||!L||!Y||J),[,en]=(0,m.Y)(et,Z,B,{start:Q,end:ee}),er=(0,g.oA)({ref:q,className:(null==(r=(0,f.A)(F.className,$&&k,$&&S,en.enter&&k,en.enter&&en.closed&&S,en.enter&&!en.closed&&j,en.leave&&R,en.leave&&!en.closed&&I,en.leave&&en.closed&&z,!en.transition&&B&&T))?void 0:r.trim())||void 0,...(0,m.X)(en)}),eo=0;"visible"===A&&(eo|=b.ZM.Open),"hidden"===A&&(eo|=b.ZM.Closed),en.enter&&(eo|=b.ZM.Opening),en.leave&&(eo|=b.ZM.Closing);let ea=(0,g.L6)();return o.createElement(y.Provider,{value:K},o.createElement(b.up,{value:eo},ea({ourProps:er,theirProps:F,defaultTag:N,features:O,visible:"visible"===A,name:"Transition.Child"})))}),S=(0,g.yV)(function(e,t){let n=null!==(0,o.useContext)(h),r=null!==(0,b.oJ)();return o.createElement(o.Fragment,null,!n&&r?o.createElement(C,{ref:t,...e}):o.createElement(k,{ref:t,...e}))}),j=Object.assign(C,{Child:S,Root:C})}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/1789-a56ee544e60cd01d.js b/litellm/proxy/_experimental/out/_next/static/chunks/1789-a56ee544e60cd01d.js deleted file mode 100644 index b252b89cf2f..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/1789-a56ee544e60cd01d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1789],{25512:function(e,s,l){l.d(s,{P:function(){return t.Z},Q:function(){return i.Z}});var t=l(27281),i=l(57365)},51789:function(e,s,l){l.d(s,{Z:function(){return e1}});var t=l(57437),i=l(2265),r=l(57840),n=l(51653),a=l(99376),o=l(10032),c=l(4260),d=l(5545),u=l(22116);l(25512);var m=l(78489),g=l(94789),p=l(12514),x=l(12485),h=l(18135),_=l(35242),f=l(29706),j=l(77991),y=l(21626),v=l(97214),b=l(28241),S=l(58834),Z=l(69552),w=l(71876),N=l(37592),I=l(4156),C=l(56522),k=l(19250),O=l(9114),E=l(85968);let T={google:"https://artificialanalysis.ai/img/logos/google_small.svg",microsoft:"https://upload.wikimedia.org/wikipedia/commons/a/a8/Microsoft_Azure_Logo.svg",okta:"https://www.okta.com/sites/default/files/Okta_Logo_BrightBlue_Medium.png",generic:""},L={google:{envVarMap:{google_client_id:"GOOGLE_CLIENT_ID",google_client_secret:"GOOGLE_CLIENT_SECRET"},fields:[{label:"Google Client ID",name:"google_client_id"},{label:"Google Client Secret",name:"google_client_secret"}]},microsoft:{envVarMap:{microsoft_client_id:"MICROSOFT_CLIENT_ID",microsoft_client_secret:"MICROSOFT_CLIENT_SECRET",microsoft_tenant:"MICROSOFT_TENANT"},fields:[{label:"Microsoft Client ID",name:"microsoft_client_id"},{label:"Microsoft Client Secret",name:"microsoft_client_secret"},{label:"Microsoft Tenant",name:"microsoft_tenant"}]},okta:{envVarMap:{generic_client_id:"GENERIC_CLIENT_ID",generic_client_secret:"GENERIC_CLIENT_SECRET",generic_authorization_endpoint:"GENERIC_AUTHORIZATION_ENDPOINT",generic_token_endpoint:"GENERIC_TOKEN_ENDPOINT",generic_userinfo_endpoint:"GENERIC_USERINFO_ENDPOINT"},fields:[{label:"Generic Client ID",name:"generic_client_id"},{label:"Generic Client Secret",name:"generic_client_secret"},{label:"Authorization Endpoint",name:"generic_authorization_endpoint",placeholder:"https://your-domain/authorize"},{label:"Token Endpoint",name:"generic_token_endpoint",placeholder:"https://your-domain/token"},{label:"Userinfo Endpoint",name:"generic_userinfo_endpoint",placeholder:"https://your-domain/userinfo"}]},generic:{envVarMap:{generic_client_id:"GENERIC_CLIENT_ID",generic_client_secret:"GENERIC_CLIENT_SECRET",generic_authorization_endpoint:"GENERIC_AUTHORIZATION_ENDPOINT",generic_token_endpoint:"GENERIC_TOKEN_ENDPOINT",generic_userinfo_endpoint:"GENERIC_USERINFO_ENDPOINT"},fields:[{label:"Generic Client ID",name:"generic_client_id"},{label:"Generic Client Secret",name:"generic_client_secret"},{label:"Authorization Endpoint",name:"generic_authorization_endpoint"},{label:"Token Endpoint",name:"generic_token_endpoint"},{label:"Userinfo Endpoint",name:"generic_userinfo_endpoint"}]}};var P=e=>{let{isAddSSOModalVisible:s,isInstructionsModalVisible:l,handleAddSSOOk:r,handleAddSSOCancel:n,handleShowInstructions:a,handleInstructionsOk:m,handleInstructionsCancel:g,form:p,accessToken:x,ssoConfigured:h=!1}=e,[_,f]=(0,i.useState)(!1);(0,i.useEffect)(()=>{(async()=>{if(s&&x)try{let s=await (0,k.getSSOSettings)(x);if(console.log("Raw SSO data received:",s),s&&s.values){var e,l,t,i,r,n;console.log("SSO values:",s.values),console.log("user_email from API:",s.values.user_email);let a=null;s.values.google_client_id?a="google":s.values.microsoft_client_id?a="microsoft":s.values.generic_client_id&&(a=(null===(e=s.values.generic_authorization_endpoint)||void 0===e?void 0:e.includes("okta"))||(null===(l=s.values.generic_authorization_endpoint)||void 0===l?void 0:l.includes("auth0"))?"okta":"generic");let o={};if(s.values.role_mappings){let e=s.values.role_mappings,l=e=>e&&0!==e.length?e.join(", "):"";o={use_role_mappings:!0,group_claim:e.group_claim,default_role:e.default_role||"internal_user",proxy_admin_teams:l(null===(t=e.roles)||void 0===t?void 0:t.proxy_admin),admin_viewer_teams:l(null===(i=e.roles)||void 0===i?void 0:i.proxy_admin_viewer),internal_user_teams:l(null===(r=e.roles)||void 0===r?void 0:r.internal_user),internal_viewer_teams:l(null===(n=e.roles)||void 0===n?void 0:n.internal_user_viewer)}}let c={sso_provider:a,proxy_base_url:s.values.proxy_base_url,user_email:s.values.user_email,...s.values,...o};console.log("Setting form values:",c),p.resetFields(),setTimeout(()=>{p.setFieldsValue(c),console.log("Form values set, current form values:",p.getFieldsValue())},100)}}catch(e){console.error("Failed to load SSO settings:",e)}})()},[s,x,p]);let j=async e=>{if(!x){O.Z.fromBackend("No access token available");return}try{let{proxy_admin_teams:s,admin_viewer_teams:l,internal_user_teams:t,internal_viewer_teams:i,default_role:r,group_claim:n,use_role_mappings:o,...c}=e,d={...c};if(o){let e=e=>e&&""!==e.trim()?e.split(",").map(e=>e.trim()).filter(e=>e.length>0):[];d.role_mappings={provider:"generic",group_claim:n,default_role:({internal_user_viewer:"internal_user_viewer",internal_user:"internal_user",proxy_admin_viewer:"proxy_admin_viewer",proxy_admin:"proxy_admin"})[r]||"internal_user",roles:{proxy_admin:e(s),proxy_admin_viewer:e(l),internal_user:e(t),internal_user_viewer:e(i)}}}await (0,k.updateSSOSettings)(x,d),a(e)}catch(e){O.Z.fromBackend("Failed to save SSO settings: "+(0,E.O)(e))}},y=async()=>{if(!x){O.Z.fromBackend("No access token available");return}try{await (0,k.updateSSOSettings)(x,{google_client_id:null,google_client_secret:null,microsoft_client_id:null,microsoft_client_secret:null,microsoft_tenant:null,generic_client_id:null,generic_client_secret:null,generic_authorization_endpoint:null,generic_token_endpoint:null,generic_userinfo_endpoint:null,proxy_base_url:null,user_email:null,sso_provider:null,role_mappings:null}),p.resetFields(),f(!1),r(),O.Z.success("SSO settings cleared successfully")}catch(e){console.error("Failed to clear SSO settings:",e),O.Z.fromBackend("Failed to clear SSO settings")}},v=e=>{let s=L[e];return s?s.fields.map(e=>(0,t.jsx)(o.Z.Item,{label:e.label,name:e.name,rules:[{required:!0,message:"Please enter the ".concat(e.label.toLowerCase())}],children:e.name.includes("client")?(0,t.jsx)(c.default.Password,{}):(0,t.jsx)(C.o,{placeholder:e.placeholder})},e.name)):null};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(u.Z,{title:h?"Edit SSO Settings":"Add SSO",visible:s,width:800,footer:null,onOk:r,onCancel:n,children:(0,t.jsxs)(o.Z,{form:p,onFinish:j,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(o.Z.Item,{label:"SSO Provider",name:"sso_provider",rules:[{required:!0,message:"Please select an SSO provider"}],children:(0,t.jsx)(N.default,{children:Object.entries(T).map(e=>{let[s,l]=e;return(0,t.jsx)(N.default.Option,{value:s,children:(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",padding:"4px 0"},children:[l&&(0,t.jsx)("img",{src:l,alt:s,style:{height:24,width:24,marginRight:12,objectFit:"contain"}}),(0,t.jsxs)("span",{children:["okta"===s.toLowerCase()?"Okta / Auth0":s.charAt(0).toUpperCase()+s.slice(1)," ","SSO"]})]})},s)})})}),(0,t.jsx)(o.Z.Item,{noStyle:!0,shouldUpdate:(e,s)=>e.sso_provider!==s.sso_provider,children:e=>{let{getFieldValue:s}=e,l=s("sso_provider");return l?v(l):null}}),(0,t.jsx)(o.Z.Item,{label:"Proxy Admin Email",name:"user_email",rules:[{required:!0,message:"Please enter the email of the proxy admin"}],children:(0,t.jsx)(C.o,{})}),(0,t.jsx)(o.Z.Item,{label:"Proxy Base URL",name:"proxy_base_url",normalize:e=>null==e?void 0:e.trim(),rules:[{required:!0,message:"Please enter the proxy base url"},{pattern:/^https?:\/\/.+/,message:"URL must start with http:// or https://"},{validator:(e,s)=>s&&/^https?:\/\/.+/.test(s)&&s.endsWith("/")?Promise.reject("URL must not end with a trailing slash"):Promise.resolve()}],children:(0,t.jsx)(C.o,{placeholder:"https://example.com"})}),(0,t.jsx)(o.Z.Item,{noStyle:!0,shouldUpdate:(e,s)=>e.sso_provider!==s.sso_provider,children:e=>{let{getFieldValue:s}=e,l=s("sso_provider");return"okta"===l||"generic"===l?(0,t.jsx)(o.Z.Item,{label:"Use Role Mappings",name:"use_role_mappings",valuePropName:"checked",children:(0,t.jsx)(I.Z,{})}):null}}),(0,t.jsx)(o.Z.Item,{noStyle:!0,shouldUpdate:(e,s)=>e.use_role_mappings!==s.use_role_mappings,children:e=>{let{getFieldValue:s}=e;return s("use_role_mappings")?(0,t.jsx)(o.Z.Item,{label:"Group Claim",name:"group_claim",rules:[{required:!0,message:"Please enter the group claim"}],children:(0,t.jsx)(C.o,{})}):null}}),(0,t.jsx)(o.Z.Item,{noStyle:!0,shouldUpdate:(e,s)=>e.use_role_mappings!==s.use_role_mappings,children:e=>{let{getFieldValue:s}=e;return s("use_role_mappings")?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(o.Z.Item,{label:"Default Role",name:"default_role",initialValue:"Internal User",children:(0,t.jsxs)(N.default,{children:[(0,t.jsx)(N.default.Option,{value:"internal_user_viewer",children:"Internal Viewer"}),(0,t.jsx)(N.default.Option,{value:"internal_user",children:"Internal User"}),(0,t.jsx)(N.default.Option,{value:"proxy_admin_viewer",children:"Admin Viewer"}),(0,t.jsx)(N.default.Option,{value:"proxy_admin",children:"Proxy Admin"})]})}),(0,t.jsx)(o.Z.Item,{label:"Proxy Admin Teams",name:"proxy_admin_teams",children:(0,t.jsx)(C.o,{})}),(0,t.jsx)(o.Z.Item,{label:"Admin Viewer Teams",name:"admin_viewer_teams",children:(0,t.jsx)(C.o,{})}),(0,t.jsx)(o.Z.Item,{label:"Internal User Teams",name:"internal_user_teams",children:(0,t.jsx)(C.o,{})}),(0,t.jsx)(o.Z.Item,{label:"Internal Viewer Teams",name:"internal_viewer_teams",children:(0,t.jsx)(C.o,{})})]}):null}})]}),(0,t.jsxs)("div",{style:{textAlign:"right",marginTop:"10px",display:"flex",justifyContent:"flex-end",alignItems:"center",gap:"8px"},children:[h&&(0,t.jsx)(d.ZP,{onClick:()=>f(!0),style:{backgroundColor:"#6366f1",borderColor:"#6366f1",color:"white"},onMouseEnter:e=>{e.currentTarget.style.backgroundColor="#5558eb",e.currentTarget.style.borderColor="#5558eb"},onMouseLeave:e=>{e.currentTarget.style.backgroundColor="#6366f1",e.currentTarget.style.borderColor="#6366f1"},children:"Clear"}),(0,t.jsx)(d.ZP,{htmlType:"submit",children:"Save"})]})]})}),(0,t.jsxs)(u.Z,{title:"Confirm Clear SSO Settings",visible:_,onOk:y,onCancel:()=>f(!1),okText:"Yes, Clear",cancelText:"Cancel",okButtonProps:{danger:!0,style:{backgroundColor:"#dc2626",borderColor:"#dc2626"}},children:[(0,t.jsx)("p",{children:"Are you sure you want to clear all SSO settings? This action cannot be undone."}),(0,t.jsx)("p",{children:"Users will no longer be able to login using SSO after this change."})]}),(0,t.jsxs)(u.Z,{title:"SSO Setup Instructions",visible:l,width:800,footer:null,onOk:m,onCancel:g,children:[(0,t.jsx)("p",{children:"Follow these steps to complete the SSO setup:"}),(0,t.jsx)(C.x,{className:"mt-2",children:"1. DO NOT Exit this TAB"}),(0,t.jsx)(C.x,{className:"mt-2",children:"2. Open a new tab, visit your proxy base url"}),(0,t.jsx)(C.x,{className:"mt-2",children:"3. Confirm your SSO is configured correctly and you can login on the new Tab"}),(0,t.jsx)(C.x,{className:"mt-2",children:"4. If Step 3 is successful, you can close this tab"}),(0,t.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,t.jsx)(d.ZP,{onClick:m,children:"Done"})})]})]})},A=l(67982),U=l(67101),R=l(84264),M=l(49566),z=l(96761),F=l(29233),G=l(62272),D=l(23639),B=l(92403),V=l(29271),q=l(34419),Y=e=>{let{accessToken:s,userID:l,proxySettings:r}=e,[n]=o.Z.useForm(),[a,c]=(0,i.useState)(!1),[d,u]=(0,i.useState)(null),[x,h]=(0,i.useState)("");(0,i.useEffect)(()=>{let e="";h(r&&r.PROXY_BASE_URL&&void 0!==r.PROXY_BASE_URL?r.PROXY_BASE_URL:window.location.origin)},[r]);let _="".concat(x,"/scim/v2"),f=async e=>{if(!s||!l){O.Z.fromBackend("You need to be logged in to create a SCIM token");return}try{c(!0);let t={key_alias:e.key_alias||"SCIM Access Token",team_id:null,models:[],allowed_routes:["/scim/*"]},i=await (0,k.keyCreateCall)(s,l,t);u(i),O.Z.success("SCIM token created successfully")}catch(e){console.error("Error creating SCIM token:",e),O.Z.fromBackend("Failed to create SCIM token: "+(0,E.O)(e))}finally{c(!1)}};return(0,t.jsx)(U.Z,{numItems:1,children:(0,t.jsxs)(p.Z,{children:[(0,t.jsx)("div",{className:"flex items-center mb-4",children:(0,t.jsx)(z.Z,{children:"SCIM Configuration"})}),(0,t.jsx)(R.Z,{className:"text-gray-600",children:"System for Cross-domain Identity Management (SCIM) allows you to automatically provision and manage users and groups in LiteLLM."}),(0,t.jsx)(A.Z,{}),(0,t.jsxs)("div",{className:"space-y-8",children:[(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center mb-2",children:[(0,t.jsx)("div",{className:"flex items-center justify-center w-6 h-6 rounded-full bg-blue-100 text-blue-700 mr-2",children:"1"}),(0,t.jsxs)(z.Z,{className:"text-lg flex items-center",children:[(0,t.jsx)(G.Z,{className:"h-5 w-5 mr-2"}),"SCIM Tenant URL"]})]}),(0,t.jsx)(R.Z,{className:"text-gray-600 mb-3",children:"Use this URL in your identity provider SCIM integration settings."}),(0,t.jsxs)("div",{className:"flex items-center",children:[(0,t.jsx)(M.Z,{value:_,disabled:!0,className:"flex-grow"}),(0,t.jsx)(F.CopyToClipboard,{text:_,onCopy:()=>O.Z.success("URL copied to clipboard"),children:(0,t.jsxs)(m.Z,{variant:"primary",className:"ml-2 flex items-center",children:[(0,t.jsx)(D.Z,{className:"h-4 w-4 mr-1"}),"Copy"]})})]})]}),(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center mb-2",children:[(0,t.jsx)("div",{className:"flex items-center justify-center w-6 h-6 rounded-full bg-blue-100 text-blue-700 mr-2",children:"2"}),(0,t.jsxs)(z.Z,{className:"text-lg flex items-center",children:[(0,t.jsx)(B.Z,{className:"h-5 w-5 mr-2"}),"Authentication Token"]})]}),(0,t.jsx)(g.Z,{title:"Using SCIM",color:"blue",className:"mb-4",children:"You need a SCIM token to authenticate with the SCIM API. Create one below and use it in your SCIM provider configuration."}),d?(0,t.jsxs)(p.Z,{className:"border border-yellow-300 bg-yellow-50",children:[(0,t.jsxs)("div",{className:"flex items-center mb-2 text-yellow-800",children:[(0,t.jsx)(V.Z,{className:"h-5 w-5 mr-2"}),(0,t.jsx)(z.Z,{className:"text-lg text-yellow-800",children:"Your SCIM Token"})]}),(0,t.jsx)(R.Z,{className:"text-yellow-800 mb-4 font-medium",children:"Make sure to copy this token now. You will not be able to see it again."}),(0,t.jsxs)("div",{className:"flex items-center",children:[(0,t.jsx)(M.Z,{value:d.key,className:"flex-grow mr-2 bg-white",type:"password",disabled:!0}),(0,t.jsx)(F.CopyToClipboard,{text:d.key,onCopy:()=>O.Z.success("Token copied to clipboard"),children:(0,t.jsxs)(m.Z,{variant:"primary",className:"flex items-center",children:[(0,t.jsx)(D.Z,{className:"h-4 w-4 mr-1"}),"Copy"]})})]}),(0,t.jsxs)(m.Z,{className:"mt-4 flex items-center",variant:"secondary",onClick:()=>u(null),children:[(0,t.jsx)(q.Z,{className:"h-4 w-4 mr-1"}),"Create Another Token"]})]}):(0,t.jsx)("div",{className:"bg-gray-50 p-4 rounded-lg",children:(0,t.jsxs)(o.Z,{form:n,onFinish:f,layout:"vertical",children:[(0,t.jsx)(o.Z.Item,{name:"key_alias",label:"Token Name",rules:[{required:!0,message:"Please enter a name for your token"}],children:(0,t.jsx)(M.Z,{placeholder:"SCIM Access Token"})}),(0,t.jsx)(o.Z.Item,{children:(0,t.jsxs)(m.Z,{variant:"primary",type:"submit",loading:a,className:"flex items-center",children:[(0,t.jsx)(B.Z,{className:"h-4 w-4 mr-1"}),"Create SCIM Token"]})})]})})]})]})]})})},K=e=>{let{accessToken:s,onSuccess:l}=e,[r]=o.Z.useForm(),[n,a]=(0,i.useState)(!1);(0,i.useEffect)(()=>{(async()=>{if(s)try{let e=await (0,k.getSSOSettings)(s);if(e&&e.values){let s=e.values.ui_access_mode,l={};s&&"object"==typeof s?l={ui_access_mode_type:s.type,restricted_sso_group:s.restricted_sso_group,sso_group_jwt_field:s.sso_group_jwt_field}:"string"==typeof s&&(l={ui_access_mode_type:s,restricted_sso_group:e.values.restricted_sso_group,sso_group_jwt_field:e.values.team_ids_jwt_field||e.values.sso_group_jwt_field}),r.setFieldsValue(l)}}catch(e){console.error("Failed to load UI access settings:",e)}})()},[s,r]);let c=async e=>{if(!s){O.Z.fromBackend("No access token available");return}a(!0);try{let t;t="all_authenticated_users"===e.ui_access_mode_type?{ui_access_mode:"none"}:{ui_access_mode:{type:e.ui_access_mode_type,restricted_sso_group:e.restricted_sso_group,sso_group_jwt_field:e.sso_group_jwt_field}},await (0,k.updateSSOSettings)(s,t),l()}catch(e){console.error("Failed to save UI access settings:",e),O.Z.fromBackend("Failed to save UI access settings")}finally{a(!1)}};return(0,t.jsxs)("div",{style:{padding:"16px"},children:[(0,t.jsx)("div",{style:{marginBottom:"16px"},children:(0,t.jsx)(C.x,{style:{fontSize:"14px",color:"#6b7280"},children:"Configure who can access the UI interface and how group information is extracted from JWT tokens."})}),(0,t.jsxs)(o.Z,{form:r,onFinish:c,layout:"vertical",children:[(0,t.jsx)(o.Z.Item,{label:"UI Access Mode",name:"ui_access_mode_type",tooltip:"Controls who can access the UI interface",children:(0,t.jsxs)(N.default,{placeholder:"Select access mode",children:[(0,t.jsx)(N.default.Option,{value:"all_authenticated_users",children:"All Authenticated Users"}),(0,t.jsx)(N.default.Option,{value:"restricted_sso_group",children:"Restricted SSO Group"})]})}),(0,t.jsx)(o.Z.Item,{noStyle:!0,shouldUpdate:(e,s)=>e.ui_access_mode_type!==s.ui_access_mode_type,children:e=>{let{getFieldValue:s}=e;return"restricted_sso_group"===s("ui_access_mode_type")?(0,t.jsx)(o.Z.Item,{label:"Restricted SSO Group",name:"restricted_sso_group",rules:[{required:!0,message:"Please enter the restricted SSO group"}],children:(0,t.jsx)(C.o,{placeholder:"ui-access-group"})}):null}}),(0,t.jsx)(o.Z.Item,{label:"SSO Group JWT Field",name:"sso_group_jwt_field",tooltip:"JWT field name that contains team/group information. Use dot notation to access nested fields.",children:(0,t.jsx)(C.o,{placeholder:"groups"})}),(0,t.jsx)("div",{style:{textAlign:"right",marginTop:"16px"},children:(0,t.jsx)(d.ZP,{type:"primary",htmlType:"submit",loading:n,style:{backgroundColor:"#6366f1",borderColor:"#6366f1"},children:"Update UI Access Control"})})]})]})},H=l(12363),W=l(55584),Q=l(29827),J=l(21770),X=l(90246);let $=(0,X.n)("uiSettings"),ee=e=>{let s=(0,Q.NL)();return(0,J.D)({mutationFn:async s=>{if(!e)throw Error("Access token is required");return(0,k.updateUiSettings)(e,s)},onSuccess:()=>{s.invalidateQueries({queryKey:$.all})}})};var es=l(39760),el=l(1633);let et={"api-keys":"Manage virtual keys for API access and authentication","llm-playground":"Interactive playground for testing LLM requests",models:"Configure and manage LLM models and endpoints",agents:"Create and manage AI agents","mcp-servers":"Configure Model Context Protocol servers",guardrails:"Set up content moderation and safety guardrails",policies:"Define access control and usage policies","search-tools":"Configure RAG search and retrieval tools","vector-stores":"Manage vector databases for embeddings",new_usage:"View usage analytics and metrics",logs:"Access request and response logs",users:"Manage internal user accounts and permissions",teams:"Create and manage teams for access control",organizations:"Manage organizations and their members",budgets:"Set and monitor spending budgets",api_ref:"Browse API documentation and endpoints","model-hub-table":"Explore available AI models and providers","learning-resources":"Access tutorials and documentation",caching:"Configure response caching settings","transform-request":"Set up request transformation rules","cost-tracking":"Track and analyze API costs","ui-theme":"Customize dashboard appearance","tag-management":"Organize resources with tags",prompts:"Manage and version prompt templates","claude-code-plugins":"Configure Claude Code plugins",usage:"View legacy usage dashboard","router-settings":"Configure routing and load balancing settings","logging-and-alerts":"Set up logging and alert configurations","admin-panel":"Access admin panel and settings"};var ei=l(20347);let er=e=>!e||0===e.length||e.some(e=>ei.lo.includes(e)),en=()=>{let e=[];return el.j.forEach(s=>{s.items.forEach(l=>{if(l.page&&"tools"!==l.page&&"experimental"!==l.page&&"settings"!==l.page&&er(l.roles)){let t="string"==typeof l.label?l.label:l.key;e.push({page:l.page,label:t,group:s.groupLabel,description:et[l.page]||"No description available"})}if(l.children){let t="string"==typeof l.label?l.label:l.key;l.children.forEach(l=>{if(er(l.roles)){let i="string"==typeof l.label?l.label:l.key;e.push({page:l.page,label:i,group:"".concat(s.groupLabel," > ").concat(t),description:et[l.page]||"No description available"})}})}})}),e};var ea=l(58760),eo=l(3810),ec=l(44851);function ed(e){let{enabledPagesInternalUsers:s,enabledPagesPropertyDescription:l,isUpdating:n,onUpdate:a}=e,o=null!=s,c=(0,i.useMemo)(()=>en(),[]),u=(0,i.useMemo)(()=>{let e={};return c.forEach(s=>{e[s.group]||(e[s.group]=[]),e[s.group].push(s)}),e},[c]),[m,g]=(0,i.useState)(s||[]);return(0,i.useMemo)(()=>{s?g(s):g([])},[s]),(0,t.jsxs)(ea.Z,{direction:"vertical",size:"middle",style:{width:"100%"},children:[(0,t.jsxs)(ea.Z,{direction:"vertical",size:4,children:[(0,t.jsxs)(ea.Z,{align:"center",children:[(0,t.jsx)(r.default.Text,{strong:!0,children:"Internal User Page Visibility"}),!o&&(0,t.jsx)(eo.Z,{color:"default",style:{marginLeft:"8px"},children:"Not set (all pages visible)"}),o&&(0,t.jsxs)(eo.Z,{color:"blue",style:{marginLeft:"8px"},children:[m.length," page",1!==m.length?"s":""," selected"]})]}),l&&(0,t.jsx)(r.default.Text,{type:"secondary",children:l}),(0,t.jsx)(r.default.Text,{type:"secondary",style:{fontSize:"12px",fontStyle:"italic"},children:"By default, all pages are visible to internal users. Select specific pages to restrict visibility."}),(0,t.jsx)(r.default.Text,{type:"secondary",style:{fontSize:"12px",color:"#8b5cf6"},children:"Note: Only pages accessible to internal user roles are shown here. Admin-only pages are excluded as they cannot be made visible to internal users regardless of this setting."})]}),(0,t.jsx)(ec.default,{items:[{key:"page-visibility",label:"Configure Page Visibility",children:(0,t.jsxs)(ea.Z,{direction:"vertical",size:"middle",style:{width:"100%"},children:[(0,t.jsx)(I.Z.Group,{value:m,onChange:g,style:{width:"100%"},children:(0,t.jsx)(ea.Z,{direction:"vertical",size:"middle",style:{width:"100%"},children:Object.entries(u).map(e=>{let[s,l]=e;return(0,t.jsxs)("div",{children:[(0,t.jsx)(r.default.Text,{strong:!0,style:{fontSize:"11px",color:"#6b7280",letterSpacing:"0.05em",display:"block",marginBottom:"8px"},children:s}),(0,t.jsx)(ea.Z,{direction:"vertical",size:"small",style:{marginLeft:"16px",width:"100%"},children:l.map(e=>(0,t.jsx)("div",{style:{marginBottom:"4px"},children:(0,t.jsx)(I.Z,{value:e.page,children:(0,t.jsxs)(ea.Z,{direction:"vertical",size:0,children:[(0,t.jsx)(r.default.Text,{children:e.label}),(0,t.jsx)(r.default.Text,{type:"secondary",style:{fontSize:"12px"},children:e.description})]})})},e.page))})]},s)})})}),(0,t.jsxs)(ea.Z,{children:[(0,t.jsx)(d.ZP,{type:"primary",onClick:()=>{a({enabled_ui_pages_internal_users:m.length>0?m:null})},loading:n,disabled:n,children:"Save Page Visibility Settings"}),o&&(0,t.jsx)(d.ZP,{onClick:()=>{g([]),a({enabled_ui_pages_internal_users:null})},loading:n,disabled:n,children:"Reset to Default (All Pages)"})]})]})}]})]})}var eu=l(5945),em=l(50337),eg=l(63709),ep=l(23496);function ex(){var e,s,l,i,a,o;let{accessToken:c}=(0,es.Z)(),{data:d,isLoading:u,isError:m,error:g}=(0,W.L)(),{mutate:p,isPending:x,error:h}=ee(c),_=null==d?void 0:d.field_schema,f=null==_?void 0:null===(e=_.properties)||void 0===e?void 0:e.disable_model_add_for_internal_users,j=null==_?void 0:null===(s=_.properties)||void 0===s?void 0:s.disable_team_admin_delete_team_user,y=null==_?void 0:null===(l=_.properties)||void 0===l?void 0:l.enabled_ui_pages_internal_users,v=null!==(i=null==d?void 0:d.values)&&void 0!==i?i:{},b=!!v.disable_model_add_for_internal_users,S=!!v.disable_team_admin_delete_team_user;return(0,t.jsx)(eu.Z,{title:"UI Settings",children:u?(0,t.jsx)(em.Z,{active:!0}):m?(0,t.jsx)(n.Z,{type:"error",message:"Could not load UI settings",description:g instanceof Error?g.message:void 0}):(0,t.jsxs)(ea.Z,{direction:"vertical",size:"large",style:{width:"100%"},children:[(null==_?void 0:_.description)&&(0,t.jsx)(r.default.Paragraph,{style:{marginBottom:0},children:_.description}),h&&(0,t.jsx)(n.Z,{type:"error",message:"Could not update UI settings",description:h instanceof Error?h.message:void 0}),(0,t.jsxs)(ea.Z,{align:"start",size:"middle",children:[(0,t.jsx)(eg.Z,{checked:b,disabled:x,loading:x,onChange:e=>{p({disable_model_add_for_internal_users:e},{onSuccess:()=>{O.Z.success("UI settings updated successfully")},onError:e=>{O.Z.fromBackend(e)}})},"aria-label":null!==(a=null==f?void 0:f.description)&&void 0!==a?a:"Disable model add for internal users"}),(0,t.jsxs)(ea.Z,{direction:"vertical",size:4,children:[(0,t.jsx)(r.default.Text,{strong:!0,children:"Disable model add for internal users"}),(null==f?void 0:f.description)&&(0,t.jsx)(r.default.Text,{type:"secondary",children:f.description})]})]}),(0,t.jsxs)(ea.Z,{align:"start",size:"middle",children:[(0,t.jsx)(eg.Z,{checked:S,disabled:x,loading:x,onChange:e=>{p({disable_team_admin_delete_team_user:e},{onSuccess:()=>{O.Z.success("UI settings updated successfully")},onError:e=>{O.Z.fromBackend(e)}})},"aria-label":null!==(o=null==j?void 0:j.description)&&void 0!==o?o:"Disable team admin delete team user"}),(0,t.jsxs)(ea.Z,{direction:"vertical",size:4,children:[(0,t.jsx)(r.default.Text,{strong:!0,children:"Disable team admin delete team user"}),(null==j?void 0:j.description)&&(0,t.jsx)(r.default.Text,{type:"secondary",children:j.description})]})]}),(0,t.jsx)(ep.Z,{}),(0,t.jsx)(ed,{enabledPagesInternalUsers:v.enabled_ui_pages_internal_users,enabledPagesPropertyDescription:null==y?void 0:y.description,isUpdating:x,onUpdate:e=>{p(e,{onSuccess:()=>{O.Z.success("Page visibility settings updated successfully")},onError:e=>{O.Z.fromBackend(e)}})}})]})})}var eh=l(11713);let e_=(0,X.n)("sso"),ef=()=>{let{accessToken:e,userId:s,userRole:l}=(0,es.Z)();return(0,eh.a)({queryKey:e_.detail("settings"),queryFn:async()=>await (0,k.getSSOSettings)(e),enabled:!!(e&&s&&l)})};var ej=l(76188),ey=l(88906),ev=l(15868),eb=l(18930);let eS={google:"https://artificialanalysis.ai/img/logos/google_small.svg",microsoft:"https://upload.wikimedia.org/wikipedia/commons/a/a8/Microsoft_Azure_Logo.svg",okta:"https://www.okta.com/sites/default/files/Okta_Logo_BrightBlue_Medium.png",generic:""},eZ={google:"Google SSO",microsoft:"Microsoft SSO",okta:"Okta / Auth0 SSO",generic:"Generic SSO"},ew={internal_user_viewer:"Internal Viewer",internal_user:"Internal User",proxy_admin_viewer:"Proxy Admin Viewer",proxy_admin:"Proxy Admin"};var eN=l(31283);let eI={google:{envVarMap:{google_client_id:"GOOGLE_CLIENT_ID",google_client_secret:"GOOGLE_CLIENT_SECRET"},fields:[{label:"Google Client ID",name:"google_client_id"},{label:"Google Client Secret",name:"google_client_secret"}]},microsoft:{envVarMap:{microsoft_client_id:"MICROSOFT_CLIENT_ID",microsoft_client_secret:"MICROSOFT_CLIENT_SECRET",microsoft_tenant:"MICROSOFT_TENANT"},fields:[{label:"Microsoft Client ID",name:"microsoft_client_id"},{label:"Microsoft Client Secret",name:"microsoft_client_secret"},{label:"Microsoft Tenant",name:"microsoft_tenant"}]},okta:{envVarMap:{generic_client_id:"GENERIC_CLIENT_ID",generic_client_secret:"GENERIC_CLIENT_SECRET",generic_authorization_endpoint:"GENERIC_AUTHORIZATION_ENDPOINT",generic_token_endpoint:"GENERIC_TOKEN_ENDPOINT",generic_userinfo_endpoint:"GENERIC_USERINFO_ENDPOINT"},fields:[{label:"Generic Client ID",name:"generic_client_id"},{label:"Generic Client Secret",name:"generic_client_secret"},{label:"Authorization Endpoint",name:"generic_authorization_endpoint",placeholder:"https://your-domain/authorize"},{label:"Token Endpoint",name:"generic_token_endpoint",placeholder:"https://your-domain/token"},{label:"Userinfo Endpoint",name:"generic_userinfo_endpoint",placeholder:"https://your-domain/userinfo"}]},generic:{envVarMap:{generic_client_id:"GENERIC_CLIENT_ID",generic_client_secret:"GENERIC_CLIENT_SECRET",generic_authorization_endpoint:"GENERIC_AUTHORIZATION_ENDPOINT",generic_token_endpoint:"GENERIC_TOKEN_ENDPOINT",generic_userinfo_endpoint:"GENERIC_USERINFO_ENDPOINT"},fields:[{label:"Generic Client ID",name:"generic_client_id"},{label:"Generic Client Secret",name:"generic_client_secret"},{label:"Authorization Endpoint",name:"generic_authorization_endpoint"},{label:"Token Endpoint",name:"generic_token_endpoint"},{label:"Userinfo Endpoint",name:"generic_userinfo_endpoint"}]}},eC=e=>{let s=eI[e];return s?s.fields.map(e=>(0,t.jsx)(o.Z.Item,{label:e.label,name:e.name,rules:[{required:!0,message:"Please enter the ".concat(e.label.toLowerCase())}],children:e.name.includes("client")?(0,t.jsx)(c.default.Password,{}):(0,t.jsx)(eN.o,{placeholder:e.placeholder})},e.name)):null};var ek=e=>{let{form:s,onFormSubmit:l}=e;return(0,t.jsx)("div",{children:(0,t.jsxs)(o.Z,{form:s,onFinish:l,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,t.jsx)(o.Z.Item,{label:"SSO Provider",name:"sso_provider",rules:[{required:!0,message:"Please select an SSO provider"}],children:(0,t.jsx)(N.default,{children:Object.entries(eS).map(e=>{let[s,l]=e;return(0,t.jsx)(N.default.Option,{value:s,children:(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",padding:"4px 0"},children:[l&&(0,t.jsx)("img",{src:l,alt:s,style:{height:24,width:24,marginRight:12,objectFit:"contain"}}),(0,t.jsx)("span",{children:eZ[s]||s.charAt(0).toUpperCase()+s.slice(1)+" SSO"})]})},s)})})}),(0,t.jsx)(o.Z.Item,{noStyle:!0,shouldUpdate:(e,s)=>e.sso_provider!==s.sso_provider,children:e=>{let{getFieldValue:s}=e,l=s("sso_provider");return l?eC(l):null}}),(0,t.jsx)(o.Z.Item,{label:"Proxy Admin Email",name:"user_email",rules:[{required:!0,message:"Please enter the email of the proxy admin"}],children:(0,t.jsx)(eN.o,{})}),(0,t.jsx)(o.Z.Item,{label:"Proxy Base URL",name:"proxy_base_url",normalize:e=>null==e?void 0:e.trim(),rules:[{required:!0,message:"Please enter the proxy base url"},{pattern:/^https?:\/\/.+/,message:"URL must start with http:// or https://"},{validator:(e,s)=>s&&/^https?:\/\/.+/.test(s)&&s.endsWith("/")?Promise.reject("URL must not end with a trailing slash"):Promise.resolve()}],children:(0,t.jsx)(eN.o,{placeholder:"https://example.com"})}),(0,t.jsx)(o.Z.Item,{noStyle:!0,shouldUpdate:(e,s)=>e.sso_provider!==s.sso_provider,children:e=>{let{getFieldValue:s}=e,l=s("sso_provider");return"okta"===l||"generic"===l?(0,t.jsx)(o.Z.Item,{label:"Use Role Mappings",name:"use_role_mappings",valuePropName:"checked",children:(0,t.jsx)(I.Z,{})}):null}}),(0,t.jsx)(o.Z.Item,{noStyle:!0,shouldUpdate:(e,s)=>e.use_role_mappings!==s.use_role_mappings||e.sso_provider!==s.sso_provider,children:e=>{let{getFieldValue:s}=e,l=s("use_role_mappings"),i=s("sso_provider");return l&&("okta"===i||"generic"===i)?(0,t.jsx)(o.Z.Item,{label:"Group Claim",name:"group_claim",rules:[{required:!0,message:"Please enter the group claim"}],children:(0,t.jsx)(eN.o,{})}):null}}),(0,t.jsx)(o.Z.Item,{noStyle:!0,shouldUpdate:(e,s)=>e.use_role_mappings!==s.use_role_mappings||e.sso_provider!==s.sso_provider,children:e=>{let{getFieldValue:s}=e,l=s("use_role_mappings"),i=s("sso_provider");return l&&("okta"===i||"generic"===i)?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(o.Z.Item,{label:"Default Role",name:"default_role",initialValue:"Internal User",children:(0,t.jsxs)(N.default,{children:[(0,t.jsx)(N.default.Option,{value:"internal_user_viewer",children:"Internal Viewer"}),(0,t.jsx)(N.default.Option,{value:"internal_user",children:"Internal User"}),(0,t.jsx)(N.default.Option,{value:"proxy_admin_viewer",children:"Admin Viewer"}),(0,t.jsx)(N.default.Option,{value:"proxy_admin",children:"Proxy Admin"})]})}),(0,t.jsx)(o.Z.Item,{label:"Proxy Admin Teams",name:"proxy_admin_teams",children:(0,t.jsx)(eN.o,{})}),(0,t.jsx)(o.Z.Item,{label:"Admin Viewer Teams",name:"admin_viewer_teams",children:(0,t.jsx)(eN.o,{})}),(0,t.jsx)(o.Z.Item,{label:"Internal User Teams",name:"internal_user_teams",children:(0,t.jsx)(eN.o,{})}),(0,t.jsx)(o.Z.Item,{label:"Internal Viewer Teams",name:"internal_viewer_teams",children:(0,t.jsx)(eN.o,{})})]}):null}})]})})};let eO=()=>{let{accessToken:e}=(0,es.Z)();return(0,J.D)({mutationFn:async s=>{if(!e)throw Error("Access token is required");return await (0,k.updateSSOSettings)(e,s)}})},eE=e=>{let{proxy_admin_teams:s,admin_viewer_teams:l,internal_user_teams:t,internal_viewer_teams:i,default_role:r,group_claim:n,use_role_mappings:a,...o}=e,c={...o};if(a){let e=e=>e&&""!==e.trim()?e.split(",").map(e=>e.trim()).filter(e=>e.length>0):[];c.role_mappings={provider:"generic",group_claim:n,default_role:({internal_user_viewer:"internal_user_viewer",internal_user:"internal_user",proxy_admin_viewer:"proxy_admin_viewer",proxy_admin:"proxy_admin"})[r]||"internal_user",roles:{proxy_admin:e(s),proxy_admin_viewer:e(l),internal_user:e(t),internal_user_viewer:e(i)}}}return c},eT=e=>{if(e.google_client_id)return"google";if(e.microsoft_client_id)return"microsoft";if(e.generic_client_id){var s,l;return(null===(s=e.generic_authorization_endpoint)||void 0===s?void 0:s.includes("okta"))||(null===(l=e.generic_authorization_endpoint)||void 0===l?void 0:l.includes("auth0"))?"okta":"generic"}return null};var eL=e=>{let{isVisible:s,onCancel:l,onSuccess:i}=e,[r]=o.Z.useForm(),{mutateAsync:n,isPending:a}=eO(),c=async e=>{let s=eE(e);await n(s,{onSuccess:()=>{O.Z.success("SSO settings added successfully"),i()},onError:e=>{O.Z.fromBackend("Failed to save SSO settings: "+(0,E.O)(e))}})},m=()=>{r.resetFields(),l()};return(0,t.jsx)(u.Z,{title:"Add SSO",open:s,width:800,footer:(0,t.jsxs)(ea.Z,{children:[(0,t.jsx)(d.ZP,{onClick:m,disabled:a,children:"Cancel"}),(0,t.jsx)(d.ZP,{loading:a,onClick:()=>r.submit(),children:a?"Adding...":"Add SSO"})]}),onCancel:m,children:(0,t.jsx)(ek,{form:r,onFormSubmit:c})})},eP=l(21609),eA=e=>{let{isVisible:s,onCancel:l,onSuccess:i}=e,{data:r}=ef(),{mutateAsync:n,isPending:a}=eO(),o=async()=>{await n({google_client_id:null,google_client_secret:null,microsoft_client_id:null,microsoft_client_secret:null,microsoft_tenant:null,generic_client_id:null,generic_client_secret:null,generic_authorization_endpoint:null,generic_token_endpoint:null,generic_userinfo_endpoint:null,proxy_base_url:null,user_email:null,sso_provider:null,role_mappings:null},{onSuccess:()=>{O.Z.success("SSO settings cleared successfully"),l(),i()},onError:e=>{O.Z.fromBackend("Failed to clear SSO settings: "+(0,E.O)(e))}})};return(0,t.jsx)(eP.Z,{isOpen:s,title:"Confirm Clear SSO Settings",alertMessage:"This action cannot be undone.",message:"Are you sure you want to clear all SSO settings? Users will no longer be able to login using SSO after this change.",resourceInformationTitle:"SSO Settings",resourceInformation:[{label:"Provider",value:(null==r?void 0:r.values)&&eT(null==r?void 0:r.values)||"Generic"}],onCancel:l,onOk:o,confirmLoading:a})},eU=e=>{let{isVisible:s,onCancel:l,onSuccess:r}=e,[n]=o.Z.useForm(),a=ef(),{mutateAsync:c,isPending:m}=eO();(0,i.useEffect)(()=>{if(s&&a.data&&a.data.values){var e,l,t,i,r,o;let s=a.data;console.log("Raw SSO data received:",s),console.log("SSO values:",s.values),console.log("user_email from API:",s.values.user_email);let c=null;s.values.google_client_id?c="google":s.values.microsoft_client_id?c="microsoft":s.values.generic_client_id&&(c=(null===(e=s.values.generic_authorization_endpoint)||void 0===e?void 0:e.includes("okta"))||(null===(l=s.values.generic_authorization_endpoint)||void 0===l?void 0:l.includes("auth0"))?"okta":"generic");let d={};if(s.values.role_mappings){let e=s.values.role_mappings,l=e=>e&&0!==e.length?e.join(", "):"";d={use_role_mappings:!0,group_claim:e.group_claim,default_role:e.default_role||"internal_user",proxy_admin_teams:l(null===(t=e.roles)||void 0===t?void 0:t.proxy_admin),admin_viewer_teams:l(null===(i=e.roles)||void 0===i?void 0:i.proxy_admin_viewer),internal_user_teams:l(null===(r=e.roles)||void 0===r?void 0:r.internal_user),internal_viewer_teams:l(null===(o=e.roles)||void 0===o?void 0:o.internal_user_viewer)}}let u={sso_provider:c,...s.values,...d};console.log("Setting form values:",u),n.resetFields(),setTimeout(()=>{n.setFieldsValue(u),console.log("Form values set, current form values:",n.getFieldsValue())},100)}},[s,a.data,n]);let g=async e=>{try{let s=eE(e);await c(s,{onSuccess:()=>{O.Z.success("SSO settings updated successfully"),r()},onError:e=>{O.Z.fromBackend("Failed to save SSO settings: "+(0,E.O)(e))}})}catch(e){O.Z.fromBackend("Failed to process SSO settings: "+(0,E.O)(e))}},p=()=>{n.resetFields(),l()};return(0,t.jsx)(u.Z,{title:"Edit SSO Settings",open:s,width:800,footer:(0,t.jsxs)(ea.Z,{children:[(0,t.jsx)(d.ZP,{onClick:p,disabled:m,children:"Cancel"}),(0,t.jsx)(d.ZP,{loading:m,onClick:()=>n.submit(),children:m?"Saving...":"Save"})]}),onCancel:p,children:(0,t.jsx)(ek,{form:n,onFormSubmit:g})})},eR=l(42208),eM=l(87769);function ez(e){let{defaultHidden:s=!0,value:l}=e,[r,n]=(0,i.useState)(s);return(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("span",{className:"font-mono text-gray-600 flex-1",children:l?r?"•".repeat(l.length):l:(0,t.jsx)("span",{className:"text-gray-400 italic",children:"Not configured"})}),l&&(0,t.jsx)(d.ZP,{type:"text",size:"small",icon:r?(0,t.jsx)(eR.Z,{className:"w-4 h-4"}):(0,t.jsx)(eM.Z,{className:"w-4 h-4"}),onClick:()=>n(!r),className:"text-gray-400 hover:text-gray-600"})]})}var eF=l(56609),eG=l(95805);let{Title:eD,Text:eB}=r.default;function eV(e){let{roleMappings:s}=e;if(!s)return null;let l=[{title:"Role",dataIndex:"role",key:"role",render:e=>(0,t.jsx)(eB,{strong:!0,children:ew[e]})},{title:"Mapped Groups",dataIndex:"groups",key:"groups",render:e=>(0,t.jsx)(t.Fragment,{children:e.length>0?e.map((e,s)=>(0,t.jsx)(eo.Z,{color:"blue",children:e},s)):(0,t.jsx)(eB,{className:"text-gray-400 italic",children:"No groups mapped"})})}];return(0,t.jsxs)(eu.Z,{children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)(eG.Z,{className:"w-6 h-6 text-gray-400 mb-2"}),(0,t.jsx)(eD,{level:3,children:"Role Mappings"})]}),(0,t.jsxs)("div",{className:"space-y-8",children:[(0,t.jsxs)("div",{className:"grid grid-cols-2 gap-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(eD,{level:5,children:"Group Claim"}),(0,t.jsx)("div",{children:(0,t.jsx)(eB,{code:!0,children:s.group_claim})})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(eD,{level:5,children:"Default Role"}),(0,t.jsx)("div",{children:(0,t.jsx)(eB,{strong:!0,children:ew[s.default_role]})})]})]}),(0,t.jsx)(ep.Z,{}),(0,t.jsx)(eF.Z,{columns:l,dataSource:Object.entries(s.roles).map(e=>{let[s,l]=e;return{role:s,groups:l}}),pagination:!1,bordered:!0,size:"small",className:"w-full"})]})]})}var eq=l(85180);let{Title:eY,Paragraph:eK}=r.default;function eH(e){let{onAdd:s}=e;return(0,t.jsx)("div",{className:"bg-white p-12 rounded-lg border border-dashed border-gray-300 text-center w-full",children:(0,t.jsx)(eq.Z,{image:eq.Z.PRESENTED_IMAGE_SIMPLE,description:(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)(eY,{level:4,children:"No SSO Configuration Found"}),(0,t.jsx)(eK,{type:"secondary",className:"max-w-md mx-auto",children:"Configure Single Sign-On (SSO) to enable seamless authentication for your team members using your identity provider."})]}),children:(0,t.jsx)(d.ZP,{type:"primary",size:"large",onClick:s,className:"flex items-center gap-2 mx-auto mt-4",children:"Configure SSO"})})})}let{Title:eW,Text:eQ}=r.default;function eJ(){return(0,t.jsx)(eu.Z,{children:(0,t.jsxs)(ea.Z,{direction:"vertical",size:"large",className:"w-full",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)(ey.Z,{className:"w-6 h-6 text-gray-400"}),(0,t.jsxs)("div",{children:[(0,t.jsx)(eW,{level:3,children:"SSO Configuration"}),(0,t.jsx)(eQ,{type:"secondary",children:"Manage Single Sign-On authentication settings"})]})]}),(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)(em.Z.Button,{active:!0,size:"default",style:{width:170,height:32}}),(0,t.jsx)(em.Z.Button,{active:!0,size:"default",style:{width:190,height:32}})]})]}),(0,t.jsxs)(ej.Z,{bordered:!0,column:{xxl:1,xl:1,lg:1,md:1,sm:1,xs:1},children:[(0,t.jsx)(ej.Z.Item,{label:(0,t.jsx)(em.Z.Node,{active:!0,style:{width:80,height:16}}),children:(0,t.jsx)("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:(0,t.jsx)(em.Z.Node,{active:!0,style:{width:100,height:16}})})}),(0,t.jsx)(ej.Z.Item,{label:(0,t.jsx)(em.Z.Node,{active:!0,style:{width:80,height:16}}),children:(0,t.jsx)(em.Z.Node,{active:!0,style:{width:200,height:16}})}),(0,t.jsx)(ej.Z.Item,{label:(0,t.jsx)(em.Z.Node,{active:!0,style:{width:80,height:16}}),children:(0,t.jsx)(em.Z.Node,{active:!0,style:{width:250,height:16}})}),(0,t.jsx)(ej.Z.Item,{label:(0,t.jsx)(em.Z.Node,{active:!0,style:{width:80,height:16}}),children:(0,t.jsx)(em.Z.Node,{active:!0,style:{width:180,height:16}})}),(0,t.jsx)(ej.Z.Item,{label:(0,t.jsx)(em.Z.Node,{active:!0,style:{width:80,height:16}}),children:(0,t.jsx)(em.Z.Node,{active:!0,style:{width:220,height:16}})})]})]})})}let{Title:eX,Text:e$}=r.default;function e0(){let{data:e,refetch:s,isLoading:l}=ef(),[r,n]=(0,i.useState)(!1),[a,o]=(0,i.useState)(!1),[c,u]=(0,i.useState)(!1),m=!!(null==e?void 0:e.values.google_client_id)||!!(null==e?void 0:e.values.microsoft_client_id)||!!(null==e?void 0:e.values.generic_client_id),g=(null==e?void 0:e.values)?eT(e.values):null,p=!!(null==e?void 0:e.values.role_mappings),x=e=>(0,t.jsx)(e$,{className:"font-mono text-gray-600 text-sm",copyable:!!e,children:e||"-"}),h=e=>e||(0,t.jsx)("span",{className:"text-gray-400 italic",children:"Not configured"}),_={column:{xxl:1,xl:1,lg:1,md:1,sm:1,xs:1}},f={google:{providerText:eZ.google,fields:[{label:"Client ID",render:e=>(0,t.jsx)(ez,{value:e.google_client_id})},{label:"Client Secret",render:e=>(0,t.jsx)(ez,{value:e.google_client_secret})},{label:"Proxy Base URL",render:e=>h(e.proxy_base_url)}]},microsoft:{providerText:eZ.microsoft,fields:[{label:"Client ID",render:e=>(0,t.jsx)(ez,{value:e.microsoft_client_id})},{label:"Client Secret",render:e=>(0,t.jsx)(ez,{value:e.microsoft_client_secret})},{label:"Tenant",render:e=>h(e.microsoft_tenant)},{label:"Proxy Base URL",render:e=>h(e.proxy_base_url)}]},okta:{providerText:eZ.okta,fields:[{label:"Client ID",render:e=>(0,t.jsx)(ez,{value:e.generic_client_id})},{label:"Client Secret",render:e=>(0,t.jsx)(ez,{value:e.generic_client_secret})},{label:"Authorization Endpoint",render:e=>x(e.generic_authorization_endpoint)},{label:"Token Endpoint",render:e=>x(e.generic_token_endpoint)},{label:"User Info Endpoint",render:e=>x(e.generic_userinfo_endpoint)},{label:"Proxy Base URL",render:e=>h(e.proxy_base_url)}]},generic:{providerText:eZ.generic,fields:[{label:"Client ID",render:e=>(0,t.jsx)(ez,{value:e.generic_client_id})},{label:"Client Secret",render:e=>(0,t.jsx)(ez,{value:e.generic_client_secret})},{label:"Authorization Endpoint",render:e=>x(e.generic_authorization_endpoint)},{label:"Token Endpoint",render:e=>x(e.generic_token_endpoint)},{label:"User Info Endpoint",render:e=>x(e.generic_userinfo_endpoint)},{label:"Proxy Base URL",render:e=>h(e.proxy_base_url)}]}};return(0,t.jsxs)(t.Fragment,{children:[l?(0,t.jsx)(eJ,{}):(0,t.jsxs)(ea.Z,{direction:"vertical",size:"large",className:"w-full",children:[(0,t.jsx)(eu.Z,{children:(0,t.jsxs)(ea.Z,{direction:"vertical",size:"large",className:"w-full",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)(ey.Z,{className:"w-6 h-6 text-gray-400"}),(0,t.jsxs)("div",{children:[(0,t.jsx)(eX,{level:3,children:"SSO Configuration"}),(0,t.jsx)(e$,{type:"secondary",children:"Manage Single Sign-On authentication settings"})]})]}),(0,t.jsx)("div",{className:"flex items-center gap-3",children:m&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(d.ZP,{icon:(0,t.jsx)(ev.Z,{className:"w-4 h-4"}),onClick:()=>u(!0),children:"Edit SSO Settings"}),(0,t.jsx)(d.ZP,{danger:!0,icon:(0,t.jsx)(eb.Z,{className:"w-4 h-4"}),onClick:()=>n(!0),children:"Delete SSO Settings"})]})})]}),m?(()=>{if(!(null==e?void 0:e.values)||!g)return null;let{values:s}=e,l=f[g];return l?(0,t.jsxs)(ej.Z,{bordered:!0,..._,children:[(0,t.jsx)(ej.Z.Item,{label:"Provider",children:(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[eS[g]&&(0,t.jsx)("img",{src:eS[g],alt:g,style:{height:24,width:24,objectFit:"contain"}}),(0,t.jsx)("span",{children:l.providerText})]})}),l.fields.map((e,l)=>(0,t.jsx)(ej.Z.Item,{label:e.label,children:e.render(s)},l))]}):null})():(0,t.jsx)(eH,{onAdd:()=>o(!0)})]})}),p&&(0,t.jsx)(eV,{roleMappings:null==e?void 0:e.values.role_mappings})]}),(0,t.jsx)(eA,{isVisible:r,onCancel:()=>n(!1),onSuccess:()=>s()}),(0,t.jsx)(eL,{isVisible:a,onCancel:()=>o(!1),onSuccess:()=>{o(!1),s()}}),(0,t.jsx)(eU,{isVisible:c,onCancel:()=>u(!1),onSuccess:()=>{u(!1),s()}})]})}var e1=e=>{let{searchParams:s,accessToken:l,userID:N,showSSOBanner:I,premiumUser:C,proxySettings:E,userRole:T}=e,[L]=o.Z.useForm(),[A]=o.Z.useForm(),{Title:U,Paragraph:R}=r.default,[M,z]=(0,i.useState)(""),[F,G]=(0,i.useState)(null),[D,B]=(0,i.useState)(null),[V,q]=(0,i.useState)(!1),[W,Q]=(0,i.useState)(!1),[J,X]=(0,i.useState)(!1),[$,ee]=(0,i.useState)(!1),[es,el]=(0,i.useState)(!1),[et,ei]=(0,i.useState)(!1),[er,en]=(0,i.useState)(!1),[ea,eo]=(0,i.useState)(!1),[ec,ed]=(0,i.useState)(!1),[eu,em]=(0,i.useState)(!1),[eg,ep]=(0,i.useState)([]),[eh,e_]=(0,i.useState)(null),[ef,ej]=(0,i.useState)(!1);(0,a.useRouter)();let[ey,ev]=(0,i.useState)(null);console.log=function(){};let eb=(0,H.n)(),eS="All IP Addresses Allowed",eZ=eb;eZ+="/fallback/login";let ew=async()=>{if(l)try{let e=await (0,k.getSSOSettings)(l);if(console.log("SSO data:",e),e&&e.values){let s=e.values.google_client_id&&e.values.google_client_secret,l=e.values.microsoft_client_id&&e.values.microsoft_client_secret,t=e.values.generic_client_id&&e.values.generic_client_secret;ej(s||l||t)}else ej(!1)}catch(e){console.error("Error checking SSO configuration:",e),ej(!1)}},eN=async()=>{try{if(!0!==C){O.Z.fromBackend("This feature is only available for premium users. Please upgrade your account.");return}if(l){let e=await (0,k.getAllowedIPs)(l);ep(e&&e.length>0?e:[eS])}else ep([eS])}catch(e){console.error("Error fetching allowed IPs:",e),O.Z.fromBackend("Failed to fetch allowed IPs ".concat(e)),ep([eS])}finally{!0===C&&en(!0)}},eI=async e=>{try{if(l){await (0,k.addAllowedIP)(l,e.ip);let s=await (0,k.getAllowedIPs)(l);ep(s),O.Z.success("IP address added successfully")}}catch(e){console.error("Error adding IP:",e),O.Z.fromBackend("Failed to add IP address ".concat(e))}finally{eo(!1)}},eC=async e=>{e_(e),ed(!0)},ek=async()=>{if(eh&&l)try{await (0,k.deleteAllowedIP)(l,eh);let e=await (0,k.getAllowedIPs)(l);ep(e.length>0?e:[eS]),O.Z.success("IP address deleted successfully")}catch(e){console.error("Error deleting IP:",e),O.Z.fromBackend("Failed to delete IP address ".concat(e))}finally{ed(!1),e_(null)}};(0,i.useEffect)(()=>{(async()=>{if(null!=l){let e=[],s=await (0,k.userGetAllUsersCall)(l,"proxy_admin_viewer");console.log("proxy admin viewer response: ",s);let t=s.users;console.log("proxy viewers response: ".concat(t)),t.forEach(s=>{e.push({user_role:s.user_role,user_id:s.user_id,user_email:s.user_email})}),console.log("proxy viewers: ".concat(t));let i=(await (0,k.userGetAllUsersCall)(l,"proxy_admin")).users;i.forEach(s=>{e.push({user_role:s.user_role,user_id:s.user_id,user_email:s.user_email})}),console.log("proxy admins: ".concat(i)),console.log("combinedList: ".concat(e)),G(e),ev(await (0,k.getPossibleUserRoles)(l))}})()},[l]),(0,i.useEffect)(()=>{ew()},[l,C]);let eO=()=>{em(!1)};return console.log("admins: ".concat(null==F?void 0:F.length)),(0,t.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,t.jsx)(U,{level:4,children:"Admin Access "}),(0,t.jsx)(R,{children:"Go to 'Internal Users' page to add other admins."}),(0,t.jsxs)(h.Z,{children:[(0,t.jsxs)(_.Z,{children:[(0,t.jsx)(x.Z,{children:"SSO Settings"}),(0,t.jsx)(x.Z,{children:"Security Settings"}),(0,t.jsx)(x.Z,{children:"SCIM"}),(0,t.jsx)(x.Z,{children:"UI Settings"})]}),(0,t.jsxs)(j.Z,{children:[(0,t.jsx)(f.Z,{children:(0,t.jsx)(e0,{})}),(0,t.jsxs)(f.Z,{children:[(0,t.jsxs)(p.Z,{children:[(0,t.jsx)(U,{level:4,children:" ✨ Security Settings"}),(0,t.jsx)(n.Z,{message:"SSO Configuration Deprecated",description:"Editing SSO Settings on this page is deprecated and will be removed in a future version. Please use the SSO Settings tab for SSO configuration.",type:"warning",showIcon:!0}),(0,t.jsxs)("div",{style:{display:"flex",flexDirection:"column",gap:"1rem",marginTop:"1rem",marginLeft:"0.5rem"},children:[(0,t.jsx)("div",{children:(0,t.jsx)(m.Z,{style:{width:"150px"},onClick:()=>el(!0),children:ef?"Edit SSO Settings":"Add SSO"})}),(0,t.jsx)("div",{children:(0,t.jsx)(m.Z,{style:{width:"150px"},onClick:eN,children:"Allowed IPs"})}),(0,t.jsx)("div",{children:(0,t.jsx)(m.Z,{style:{width:"150px"},onClick:()=>!0===C?em(!0):O.Z.fromBackend("Only premium users can configure UI access control"),children:"UI Access Control"})})]})]}),(0,t.jsxs)("div",{className:"flex justify-start mb-4",children:[(0,t.jsx)(P,{isAddSSOModalVisible:es,isInstructionsModalVisible:et,handleAddSSOOk:()=>{el(!1),L.resetFields(),l&&C&&ew()},handleAddSSOCancel:()=>{el(!1),L.resetFields()},handleShowInstructions:e=>{el(!1),ei(!0)},handleInstructionsOk:()=>{ei(!1),l&&C&&ew()},handleInstructionsCancel:()=>{ei(!1),l&&C&&ew()},form:L,accessToken:l,ssoConfigured:ef}),(0,t.jsx)(u.Z,{title:"Manage Allowed IP Addresses",width:800,visible:er,onCancel:()=>en(!1),footer:[(0,t.jsx)(m.Z,{className:"mx-1",onClick:()=>eo(!0),children:"Add IP Address"},"add"),(0,t.jsx)(m.Z,{onClick:()=>en(!1),children:"Close"},"close")],children:(0,t.jsxs)(y.Z,{children:[(0,t.jsx)(S.Z,{children:(0,t.jsxs)(w.Z,{children:[(0,t.jsx)(Z.Z,{children:"IP Address"}),(0,t.jsx)(Z.Z,{className:"text-right",children:"Action"})]})}),(0,t.jsx)(v.Z,{children:eg.map((e,s)=>(0,t.jsxs)(w.Z,{children:[(0,t.jsx)(b.Z,{children:e}),(0,t.jsx)(b.Z,{className:"text-right",children:e!==eS&&(0,t.jsx)(m.Z,{onClick:()=>eC(e),color:"red",size:"xs",children:"Delete"})})]},s))})]})}),(0,t.jsx)(u.Z,{title:"Add Allowed IP Address",visible:ea,onCancel:()=>eo(!1),footer:null,children:(0,t.jsxs)(o.Z,{onFinish:eI,children:[(0,t.jsx)(o.Z.Item,{name:"ip",rules:[{required:!0,message:"Please enter an IP address"}],children:(0,t.jsx)(c.default,{placeholder:"Enter IP address"})}),(0,t.jsx)(o.Z.Item,{children:(0,t.jsx)(d.ZP,{htmlType:"submit",children:"Add IP Address"})})]})}),(0,t.jsx)(u.Z,{title:"Confirm Delete",visible:ec,onCancel:()=>ed(!1),onOk:ek,footer:[(0,t.jsx)(m.Z,{className:"mx-1",onClick:()=>ek(),children:"Yes"},"delete"),(0,t.jsx)(m.Z,{onClick:()=>ed(!1),children:"Close"},"close")],children:(0,t.jsxs)("p",{children:["Are you sure you want to delete the IP address: ",eh,"?"]})}),(0,t.jsx)(u.Z,{title:"UI Access Control Settings",visible:eu,width:600,footer:null,onOk:eO,onCancel:()=>{em(!1)},children:(0,t.jsx)(K,{accessToken:l,onSuccess:()=>{eO(),O.Z.success("UI Access Control settings updated successfully")}})})]}),(0,t.jsxs)(g.Z,{title:"Login without SSO",color:"teal",children:["If you need to login without sso, you can access"," ",(0,t.jsxs)("a",{href:eZ,target:"_blank",children:[(0,t.jsx)("b",{children:eZ})," "]})]})]}),(0,t.jsx)(f.Z,{children:(0,t.jsx)(Y,{accessToken:l,userID:N,proxySettings:E})}),(0,t.jsx)(f.Z,{children:(0,t.jsx)(ex,{})})]})]})]})}},1633:function(e,s,l){l.d(s,{j:function(){return R}});var t=l(57437),i=l(39823),r=l(39760),n=l(92403),a=l(28595),o=l(68208),c=l(69993),d=l(58630),u=l(57400),m=l(93750),g=l(29436),p=l(44625),x=l(9775),h=l(48231),_=l(15883),f=l(41361),j=l(37527),y=l(99458),v=l(12660),b=l(88009),S=l(71916),Z=l(41169),w=l(38434),N=l(71891),I=l(55322),C=l(11429),k=l(13817),O=l(18310),E=l(60985),T=l(2265),L=l(20347),P=l(79262),A=l(91027);let{Sider:U}=k.default,R=[{groupLabel:"AI GATEWAY",items:[{key:"api-keys",page:"api-keys",label:"Virtual Keys",icon:(0,t.jsx)(n.Z,{})},{key:"llm-playground",page:"llm-playground",label:"Playground",icon:(0,t.jsx)(a.Z,{}),roles:L.LQ},{key:"models",page:"models",label:"Models + Endpoints",icon:(0,t.jsx)(o.Z,{}),roles:L.LQ},{key:"agents",page:"agents",label:"Agents",icon:(0,t.jsx)(c.Z,{}),roles:L.LQ},{key:"mcp-servers",page:"mcp-servers",label:"MCP Servers",icon:(0,t.jsx)(d.Z,{})},{key:"guardrails",page:"guardrails",label:"Guardrails",icon:(0,t.jsx)(u.Z,{}),roles:L.ZL},{key:"policies",page:"policies",label:(0,t.jsxs)("span",{className:"flex items-center gap-4",children:["Policies ",(0,t.jsx)(A.Z,{})]}),icon:(0,t.jsx)(m.Z,{}),roles:L.ZL},{key:"tools",page:"tools",label:"Tools",icon:(0,t.jsx)(d.Z,{}),children:[{key:"search-tools",page:"search-tools",label:"Search Tools",icon:(0,t.jsx)(g.Z,{})},{key:"vector-stores",page:"vector-stores",label:"Vector Stores",icon:(0,t.jsx)(p.Z,{})}]}]},{groupLabel:"OBSERVABILITY",items:[{key:"new_usage",page:"new_usage",icon:(0,t.jsx)(x.Z,{}),roles:[...L.ZL,...L.lo],label:"Usage"},{key:"logs",page:"logs",label:(0,t.jsxs)("span",{className:"flex items-center gap-4",children:["Logs ",(0,t.jsx)(A.Z,{})]}),icon:(0,t.jsx)(h.Z,{})}]},{groupLabel:"ACCESS CONTROL",items:[{key:"users",page:"users",label:"Internal Users",icon:(0,t.jsx)(_.Z,{}),roles:L.ZL},{key:"teams",page:"teams",label:"Teams",icon:(0,t.jsx)(f.Z,{})},{key:"organizations",page:"organizations",label:"Organizations",icon:(0,t.jsx)(j.Z,{}),roles:L.ZL},{key:"budgets",page:"budgets",label:"Budgets",icon:(0,t.jsx)(y.Z,{}),roles:L.ZL}]},{groupLabel:"DEVELOPER TOOLS",items:[{key:"api_ref",page:"api_ref",label:"API Reference",icon:(0,t.jsx)(v.Z,{})},{key:"model-hub-table",page:"model-hub-table",label:"AI Hub",icon:(0,t.jsx)(b.Z,{})},{key:"learning-resources",page:"learning-resources",label:"Learning Resources",icon:(0,t.jsx)(S.Z,{}),external_url:"https://models.litellm.ai/cookbook"},{key:"experimental",page:"experimental",label:"Experimental",icon:(0,t.jsx)(Z.Z,{}),children:[{key:"caching",page:"caching",label:"Caching",icon:(0,t.jsx)(p.Z,{}),roles:L.ZL},{key:"prompts",page:"prompts",label:"Prompts",icon:(0,t.jsx)(w.Z,{}),roles:L.ZL},{key:"transform-request",page:"transform-request",label:"API Playground",icon:(0,t.jsx)(v.Z,{}),roles:[...L.ZL,...L.lo]},{key:"tag-management",page:"tag-management",label:"Tag Management",icon:(0,t.jsx)(N.Z,{}),roles:L.ZL},{key:"claude-code-plugins",page:"claude-code-plugins",label:"Claude Code Plugins",icon:(0,t.jsx)(d.Z,{}),roles:L.ZL},{key:"4",page:"usage",label:"Old Usage",icon:(0,t.jsx)(x.Z,{})}]}]},{groupLabel:"SETTINGS",roles:L.ZL,items:[{key:"settings",page:"settings",label:(0,t.jsx)("span",{className:"flex items-center gap-4",children:"Settings"}),icon:(0,t.jsx)(I.Z,{}),roles:L.ZL,children:[{key:"router-settings",page:"router-settings",label:"Router Settings",icon:(0,t.jsx)(I.Z,{}),roles:L.ZL},{key:"logging-and-alerts",page:"logging-and-alerts",label:"Logging & Alerts",icon:(0,t.jsx)(I.Z,{}),roles:L.ZL},{key:"admin-panel",page:"admin-panel",label:"Admin Settings",icon:(0,t.jsx)(I.Z,{}),roles:L.ZL},{key:"cost-tracking",page:"cost-tracking",label:"Cost Tracking",icon:(0,t.jsx)(x.Z,{}),roles:L.ZL},{key:"ui-theme",page:"ui-theme",label:"UI Theme",icon:(0,t.jsx)(C.Z,{}),roles:L.ZL}]}]}];s.Z=e=>{let{setPage:s,defaultSelectedKey:l,collapsed:n=!1,enabledPagesInternalUsers:a}=e,{userId:o,accessToken:c,userRole:d}=(0,r.Z)(),{data:u}=(0,i.q)(),m=(0,T.useMemo)(()=>!!o&&!!u&&u.some(e=>{var s;return null===(s=e.members)||void 0===s?void 0:s.some(e=>e.user_id===o&&"org_admin"===e.user_role)}),[o,u]),g=e=>{let l=new URLSearchParams(window.location.search);l.set("page",e),window.history.pushState(null,"","?".concat(l.toString())),s(e)},p=e=>{let s=(0,L.tY)(d);return null!=a&&console.log("[LeftNav] Filtering with enabled pages:",{userRole:d,isAdmin:s,enabledPagesInternalUsers:a}),e.map(e=>({...e,children:e.children?p(e.children):void 0})).filter(e=>{if("organizations"===e.key){if(!(!e.roles||e.roles.includes(d)||m))return!1;if(!s&&null!=a){let s=a.includes(e.page);return console.log('[LeftNav] Page "'.concat(e.page,'" (').concat(e.key,"): ").concat(s?"VISIBLE":"HIDDEN")),s}return!0}if(e.roles&&!e.roles.includes(d))return!1;if(!s&&null!=a){if(e.children&&e.children.length>0&&e.children.some(e=>a.includes(e.page)))return console.log('[LeftNav] Parent "'.concat(e.page,'" (').concat(e.key,"): VISIBLE (has visible children)")),!0;let s=a.includes(e.page);return console.log('[LeftNav] Page "'.concat(e.page,'" (').concat(e.key,"): ").concat(s?"VISIBLE":"HIDDEN")),s}return!0})},x=(e=>{for(let s of R)for(let l of s.items){if(l.page===e)return l.key;if(l.children){let s=l.children.find(s=>s.page===e);if(s)return s.key}}return"api-keys"})(l);return(0,t.jsx)(k.default,{children:(0,t.jsxs)(U,{theme:"light",width:220,collapsed:n,collapsedWidth:80,collapsible:!0,trigger:null,style:{transition:"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)",position:"relative"},children:[(0,t.jsx)(O.ZP,{theme:{components:{Menu:{iconSize:15,fontSize:13,itemMarginInline:4,itemPaddingInline:8,itemHeight:30,itemBorderRadius:6,subMenuItemBorderRadius:6,groupTitleFontSize:10,groupTitleLineHeight:1.5}}},children:(0,t.jsx)(E.Z,{mode:"inline",selectedKeys:[x],defaultOpenKeys:[],inlineCollapsed:n,className:"custom-sidebar-menu",style:{borderRight:0,backgroundColor:"transparent",fontSize:"13px",paddingTop:"4px"},items:(()=>{let e=[];return R.forEach(s=>{if(s.roles&&!s.roles.includes(d))return;let l=p(s.items);0!==l.length&&e.push({type:"group",label:n?null:(0,t.jsx)("span",{style:{fontSize:"10px",fontWeight:600,color:"#6b7280",letterSpacing:"0.05em",padding:"12px 0 4px 12px",display:"block",marginBottom:"2px"},children:s.groupLabel}),children:l.map(e=>{var s;return{key:e.key,icon:e.icon,label:e.label,children:null===(s=e.children)||void 0===s?void 0:s.map(e=>({key:e.key,icon:e.icon,label:e.label,onClick:()=>{e.external_url?window.open(e.external_url,"_blank"):g(e.page)}})),onClick:e.children?void 0:()=>{e.external_url?window.open(e.external_url,"_blank"):g(e.page)}}})})}),e})()})}),(0,L.tY)(d)&&!n&&(0,t.jsx)(P.Z,{accessToken:c,width:220})]})})}},79262:function(e,s,l){l.d(s,{Z:function(){return g}});var t=l(57437);l(1309);var i=l(76865),r=l(70525),n=l(95805),a=l(51817),o=l(21047);l(22135),l(40875);var c=l(49663),d=l(2265),u=l(19250);let m=function(){for(var e=arguments.length,s=Array(e),l=0;l{(async()=>{if(s){y(!0),b(null);try{let e=await (0,u.getRemainingUsers)(s);f(e)}catch(e){console.error("Failed to fetch usage data:",e),b("Failed to load usage data")}finally{y(!1)}}})()},[s]);let{isOverLimit:S,isNearLimit:Z,usagePercentage:w,userMetrics:N,teamMetrics:I}=(e=>{if(!e)return{isOverLimit:!1,isNearLimit:!1,usagePercentage:0,userMetrics:{isOverLimit:!1,isNearLimit:!1,usagePercentage:0},teamMetrics:{isOverLimit:!1,isNearLimit:!1,usagePercentage:0}};let s=e.total_users?e.total_users_used/e.total_users*100:0,l=s>100,t=s>=80&&s<=100,i=e.total_teams?e.total_teams_used/e.total_teams*100:0,r=i>100,n=i>=80&&i<=100,a=l||r;return{isOverLimit:a,isNearLimit:(t||n)&&!a,usagePercentage:Math.max(s,i),userMetrics:{isOverLimit:l,isNearLimit:t,usagePercentage:s},teamMetrics:{isOverLimit:r,isNearLimit:n,usagePercentage:i}}})(_),C=()=>S?(0,t.jsx)(i.Z,{className:"h-3 w-3"}):Z?(0,t.jsx)(r.Z,{className:"h-3 w-3"}):null;return s&&((null==_?void 0:_.total_users)!==null||(null==_?void 0:_.total_teams)!==null)?(0,t.jsx)("div",{className:"fixed bottom-4 left-4 z-50",style:{width:"".concat(Math.min(l,220),"px")},children:(0,t.jsx)(()=>x?(0,t.jsx)("button",{onClick:()=>h(!1),className:m("bg-white border border-gray-200 rounded-lg shadow-sm p-3 hover:shadow-md transition-all w-full"),title:"Show usage details",children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(n.Z,{className:"h-4 w-4 flex-shrink-0"}),(S||Z)&&(0,t.jsx)("span",{className:"flex-shrink-0",children:C()}),(0,t.jsxs)("div",{className:"flex items-center gap-2 text-sm font-medium truncate",children:[_&&null!==_.total_users&&(0,t.jsxs)("span",{className:m("flex-shrink-0 px-1.5 py-0.5 rounded text-xs border",N.isOverLimit&&"bg-red-50 text-red-700 border-red-200",N.isNearLimit&&"bg-yellow-50 text-yellow-700 border-yellow-200",!N.isOverLimit&&!N.isNearLimit&&"bg-gray-50 text-gray-700 border-gray-200"),children:["U: ",_.total_users_used,"/",_.total_users]}),_&&null!==_.total_teams&&(0,t.jsxs)("span",{className:m("flex-shrink-0 px-1.5 py-0.5 rounded text-xs border",I.isOverLimit&&"bg-red-50 text-red-700 border-red-200",I.isNearLimit&&"bg-yellow-50 text-yellow-700 border-yellow-200",!I.isOverLimit&&!I.isNearLimit&&"bg-gray-50 text-gray-700 border-gray-200"),children:["T: ",_.total_teams_used,"/",_.total_teams]}),!_||null===_.total_users&&null===_.total_teams&&(0,t.jsx)("span",{className:"truncate",children:"Usage"})]})]})}):j?(0,t.jsx)("div",{className:"bg-white border border-gray-200 rounded-lg shadow-sm p-4 w-full",children:(0,t.jsxs)("div",{className:"flex items-center justify-center gap-2 py-2",children:[(0,t.jsx)(a.Z,{className:"h-4 w-4 animate-spin"}),(0,t.jsx)("span",{className:"text-sm text-gray-500 truncate",children:"Loading..."})]})}):v||!_?(0,t.jsx)("div",{className:"bg-white border border-gray-200 rounded-lg shadow-sm p-4 group w-full",children:(0,t.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,t.jsx)("div",{className:"flex-1 min-w-0",children:(0,t.jsx)("span",{className:"text-sm text-gray-500 truncate block",children:v||"No data"})}),(0,t.jsx)("button",{onClick:()=>h(!0),className:"opacity-0 group-hover:opacity-100 p-1 hover:bg-gray-100 rounded transition-all flex-shrink-0",title:"Minimize",children:(0,t.jsx)(o.Z,{className:"h-3 w-3 text-gray-400"})})]})}):(0,t.jsxs)("div",{className:m("bg-white border rounded-lg shadow-sm p-3 transition-all duration-200 group w-full"),children:[(0,t.jsxs)("div",{className:"flex items-center justify-between gap-2 mb-3",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 min-w-0 flex-1",children:[(0,t.jsx)(n.Z,{className:"h-4 w-4 flex-shrink-0"}),(0,t.jsx)("span",{className:"font-medium text-sm truncate",children:"Usage"})]}),(0,t.jsx)("button",{onClick:()=>h(!0),className:"opacity-0 group-hover:opacity-100 p-1 hover:bg-gray-100 rounded transition-all flex-shrink-0",title:"Minimize",children:(0,t.jsx)(o.Z,{className:"h-3 w-3 text-gray-400"})})]}),(0,t.jsxs)("div",{className:"space-y-3 text-sm",children:[null!==_.total_users&&(0,t.jsxs)("div",{className:m("space-y-1 border rounded-md p-2",N.isOverLimit&&"border-red-200 bg-red-50",N.isNearLimit&&"border-yellow-200 bg-yellow-50"),children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 text-xs text-gray-600 mb-1",children:[(0,t.jsx)(n.Z,{className:"h-3 w-3"}),(0,t.jsx)("span",{className:"font-medium",children:"Users"}),(0,t.jsx)("span",{className:m("ml-1 px-1.5 py-0.5 rounded border",N.isOverLimit&&"bg-red-50 text-red-700 border-red-200",N.isNearLimit&&"bg-yellow-50 text-yellow-700 border-yellow-200",!N.isOverLimit&&!N.isNearLimit&&"bg-gray-50 text-gray-600 border-gray-200"),children:N.isOverLimit?"Over limit":N.isNearLimit?"Near limit":"OK"})]}),(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsx)("span",{className:"text-gray-600 text-xs",children:"Used:"}),(0,t.jsxs)("span",{className:"font-medium text-right",children:[_.total_users_used,"/",_.total_users]})]}),(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsx)("span",{className:"text-gray-600 text-xs",children:"Remaining:"}),(0,t.jsx)("span",{className:m("font-medium text-right",N.isOverLimit&&"text-red-600",N.isNearLimit&&"text-yellow-600"),children:_.total_users_remaining})]}),(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsx)("span",{className:"text-gray-600 text-xs",children:"Usage:"}),(0,t.jsxs)("span",{className:"font-medium text-right",children:[Math.round(N.usagePercentage),"%"]})]}),(0,t.jsx)("div",{className:"w-full bg-gray-200 rounded-full h-2",children:(0,t.jsx)("div",{className:m("h-2 rounded-full transition-all duration-300",N.isOverLimit&&"bg-red-500",N.isNearLimit&&"bg-yellow-500",!N.isOverLimit&&!N.isNearLimit&&"bg-green-500"),style:{width:"".concat(Math.min(N.usagePercentage,100),"%")}})})]}),null!==_.total_teams&&(0,t.jsxs)("div",{className:m("space-y-1 border rounded-md p-2",I.isOverLimit&&"border-red-200 bg-red-50",I.isNearLimit&&"border-yellow-200 bg-yellow-50"),children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 text-xs text-gray-600 mb-1",children:[(0,t.jsx)(c.Z,{className:"h-3 w-3"}),(0,t.jsx)("span",{className:"font-medium",children:"Teams"}),(0,t.jsx)("span",{className:m("ml-1 px-1.5 py-0.5 rounded border",I.isOverLimit&&"bg-red-50 text-red-700 border-red-200",I.isNearLimit&&"bg-yellow-50 text-yellow-700 border-yellow-200",!I.isOverLimit&&!I.isNearLimit&&"bg-gray-50 text-gray-600 border-gray-200"),children:I.isOverLimit?"Over limit":I.isNearLimit?"Near limit":"OK"})]}),(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsx)("span",{className:"text-gray-600 text-xs",children:"Used:"}),(0,t.jsxs)("span",{className:"font-medium text-right",children:[_.total_teams_used,"/",_.total_teams]})]}),(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsx)("span",{className:"text-gray-600 text-xs",children:"Remaining:"}),(0,t.jsx)("span",{className:m("font-medium text-right",I.isOverLimit&&"text-red-600",I.isNearLimit&&"text-yellow-600"),children:_.total_teams_remaining})]}),(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsx)("span",{className:"text-gray-600 text-xs",children:"Usage:"}),(0,t.jsxs)("span",{className:"font-medium text-right",children:[Math.round(I.usagePercentage),"%"]})]}),(0,t.jsx)("div",{className:"w-full bg-gray-200 rounded-full h-2",children:(0,t.jsx)("div",{className:m("h-2 rounded-full transition-all duration-300",I.isOverLimit&&"bg-red-500",I.isNearLimit&&"bg-yellow-500",!I.isOverLimit&&!I.isNearLimit&&"bg-green-500"),style:{width:"".concat(Math.min(I.usagePercentage,100),"%")}})})]})]})]}),{})}):null}}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/1901-4d02d1f2a71cdbf7.js b/litellm/proxy/_experimental/out/_next/static/chunks/1901-4d02d1f2a71cdbf7.js new file mode 100644 index 00000000000..f19de7216fa --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/1901-4d02d1f2a71cdbf7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1901],{91027:function(e,s,a){a.d(s,{Z:function(){return o}});var t=a(57437),l=a(33866),r=a(2265),n=a(9245);function i(e){let s=s=>{"disableShowNewBadge"===s.key&&e()},a=s=>{let{key:a}=s.detail;"disableShowNewBadge"===a&&e()};return window.addEventListener("storage",s),window.addEventListener(n.Qg,a),()=>{window.removeEventListener("storage",s),window.removeEventListener(n.Qg,a)}}function d(){return"true"===(0,n.le)("disableShowNewBadge")}function o(e){let{children:s}=e;return(0,r.useSyncExternalStore)(i,d)?s?(0,t.jsx)(t.Fragment,{children:s}):null:s?(0,t.jsx)(l.Z,{color:"blue",count:"New",children:s}):(0,t.jsx)(l.Z,{color:"blue",count:"New"})}},12363:function(e,s,a){a.d(s,{d:function(){return r},n:function(){return l}});var t=a(2265);let l=()=>{let[e,s]=(0,t.useState)("http://localhost:4000");return(0,t.useEffect)(()=>{{let{protocol:e,host:a}=window.location;s("".concat(e,"//").concat(a))}},[]),e},r=25},30841:function(e,s,a){a.d(s,{IE:function(){return r},LO:function(){return l},cT:function(){return n}});var t=a(19250);let l=async e=>{if(!e)return[];try{let{aliases:s}=await (0,t.keyAliasesCall)(e);return Array.from(new Set((s||[]).filter(Boolean)))}catch(e){return console.error("Error fetching all key aliases:",e),[]}},r=async(e,s)=>{if(!e)return[];try{let a=[],l=1,r=!0;for(;r;){let n=await (0,t.teamListCall)(e,s||null,null);a=[...a,...n],l{if(!e)return[];try{let s=[],a=1,l=!0;for(;l;){let r=await (0,t.organizationListCall)(e);s=[...s,...r],a{let{options:s,onApplyFilters:a,onResetFilters:o,initialValues:m={},buttonLabel:x="Filters"}=e,[u,h]=(0,l.useState)(!1),[g,p]=(0,l.useState)(m),[j,f]=(0,l.useState)({}),[v,y]=(0,l.useState)({}),[b,N]=(0,l.useState)({}),[w,_]=(0,l.useState)({}),k=(0,l.useCallback)(c()(async(e,s)=>{if(s.isSearchable&&s.searchFn){y(e=>({...e,[s.name]:!0}));try{let a=await s.searchFn(e);f(e=>({...e,[s.name]:a}))}catch(e){console.error("Error searching:",e),f(e=>({...e,[s.name]:[]}))}finally{y(e=>({...e,[s.name]:!1}))}}},300),[]),S=(0,l.useCallback)(async e=>{if(e.isSearchable&&e.searchFn&&!w[e.name]){y(s=>({...s,[e.name]:!0})),_(s=>({...s,[e.name]:!0}));try{let s=await e.searchFn("");f(a=>({...a,[e.name]:s}))}catch(s){console.error("Error loading initial options:",s),f(s=>({...s,[e.name]:[]}))}finally{y(s=>({...s,[e.name]:!1}))}}},[w]);(0,l.useEffect)(()=>{u&&s.forEach(e=>{e.isSearchable&&!w[e.name]&&S(e)})},[u,s,S,w]);let C=(e,s)=>{let t={...g,[e]:s};p(t),a(t)},L=(e,s)=>{e&&s.isSearchable&&!w[s.name]&&S(s)};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)(r.ZP,{icon:(0,t.jsx)(d.Z,{className:"h-4 w-4"}),onClick:()=>h(!u),className:"flex items-center gap-2",children:x}),(0,t.jsx)(r.ZP,{onClick:()=>{let e={};s.forEach(s=>{e[s.name]=""}),p(e),o()},children:"Reset Filters"})]}),u&&(0,t.jsx)("div",{className:"grid grid-cols-3 gap-x-6 gap-y-4 mb-6",children:["Team ID","Status","Organization ID","Key Alias","User ID","End User","Error Code","Key Hash","Model"].map(e=>{let a=s.find(s=>s.label===e||s.name===e);return a?(0,t.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,t.jsx)("label",{className:"text-sm text-gray-600",children:a.label||a.name}),a.isSearchable?(0,t.jsx)(n.default,{showSearch:!0,className:"w-full",placeholder:"Search ".concat(a.label||a.name,"..."),value:g[a.name]||void 0,onChange:e=>C(a.name,e),onDropdownVisibleChange:e=>L(e,a),onSearch:e=>{N(s=>({...s,[a.name]:e})),a.searchFn&&k(e,a)},filterOption:!1,loading:v[a.name],options:j[a.name]||[],allowClear:!0,notFoundContent:v[a.name]?"Loading...":"No results found"}):a.options?(0,t.jsx)(n.default,{className:"w-full",placeholder:"Select ".concat(a.label||a.name,"..."),value:g[a.name]||void 0,onChange:e=>C(a.name,e),allowClear:!0,children:a.options.map(e=>(0,t.jsx)(n.default.Option,{value:e.value,children:e.label},e.value))}):(0,t.jsx)(i.default,{className:"w-full",placeholder:"Enter ".concat(a.label||a.name,"..."),value:g[a.name]||"",onChange:e=>C(a.name,e.target.value),allowClear:!0})]},a.name):null})})]})}},31901:function(e,s,a){a.d(s,{I:function(){return eU},Z:function(){return eV}});var t=a(57437),l=a(77398),r=a.n(l),n=a(11713),i=a(2265),d=a(29827),o=a(19250),c=a(12322),m=a(59872),x=a(41649),u=a(78489),h=a(99981),g=a(42673);let p=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"}},j=e=>{let{utcTime:s}=e;return(0,t.jsx)("span",{style:{fontFamily:"monospace",width:"180px",display:"inline-block"},children:p(s)})},f=(e,s)=>{var a,t;return(null===(t=e.metadata)||void 0===t?void 0:null===(a=t.mcp_tool_call_metadata)||void 0===a?void 0:a.mcp_server_logo_url)?e.metadata.mcp_tool_call_metadata.mcp_server_logo_url:s?(0,g.dr)(s).logo:""},v=[{id:"expander",header:()=>null,cell:e=>{let{row:s}=e;return(0,t.jsx)(()=>{let[e,a]=i.useState(s.getIsExpanded()),l=i.useCallback(()=>{a(e=>!e),s.getToggleExpandedHandler()()},[s]);return s.getCanExpand()?(0,t.jsx)("button",{onClick:l,style:{cursor:"pointer"},"aria-label":e?"Collapse row":"Expand row",className:"w-6 h-6 flex items-center justify-center focus:outline-none",children:(0,t.jsx)("svg",{className:"w-4 h-4 transform transition-transform duration-75 ".concat(e?"rotate-90":""),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})}):(0,t.jsx)("span",{className:"w-6 h-6 flex items-center justify-center",children:"●"})},{})}},{header:"Time",accessorKey:"startTime",cell:e=>(0,t.jsx)(j,{utcTime:e.getValue()})},{header:"Status",accessorKey:"metadata.status",cell:e=>{let s="failure"!==(e.getValue()||"Success").toLowerCase();return(0,t.jsx)("span",{className:"px-2 py-1 rounded-md text-xs font-medium inline-block text-center w-16 ".concat(s?"bg-green-100 text-green-800":"bg-red-100 text-red-800"),children:s?"Success":"Failure"})}},{header:"Session ID",accessorKey:"session_id",cell:e=>{let s=String(e.getValue()||""),a=e.row.original.onSessionClick;return(0,t.jsx)(h.Z,{title:String(e.getValue()||""),children:(0,t.jsx)(u.Z,{size:"xs",variant:"light",className:"font-mono text-blue-500 bg-blue-50 hover:bg-blue-100 text-xs font-normal text-xs max-w-[15ch] truncate block",onClick:()=>null==a?void 0:a(s),children:String(e.getValue()||"")})})}},{header:"Request ID",accessorKey:"request_id",cell:e=>(0,t.jsx)(h.Z,{title:String(e.getValue()||""),children:(0,t.jsx)("span",{className:"font-mono text-xs max-w-[15ch] truncate block",children:String(e.getValue()||"")})})},{header:"Cost",accessorKey:"spend",cell:e=>(0,t.jsx)(h.Z,{title:"$".concat(String(e.getValue()||0)," "),children:(0,t.jsx)("span",{children:(0,m.GS)(e.getValue()||0)})})},{header:"Duration (s)",accessorKey:"duration",cell:e=>(0,t.jsx)(h.Z,{title:String(e.getValue()||"-"),children:(0,t.jsx)("span",{className:"max-w-[15ch] truncate block",children:String(e.getValue()||"-")})})},{header:"Team Name",accessorKey:"metadata.user_api_key_team_alias",cell:e=>(0,t.jsx)(h.Z,{title:String(e.getValue()||"-"),children:(0,t.jsx)("span",{className:"max-w-[15ch] truncate block",children:String(e.getValue()||"-")})})},{header:"Key Hash",accessorKey:"metadata.user_api_key",cell:e=>{let s=String(e.getValue()||"-"),a=e.row.original.onKeyHashClick;return(0,t.jsx)(h.Z,{title:s,children:(0,t.jsx)("span",{className:"font-mono max-w-[15ch] truncate block cursor-pointer hover:text-blue-600",onClick:()=>null==a?void 0:a(s),children:s})})}},{header:"Key Name",accessorKey:"metadata.user_api_key_alias",cell:e=>(0,t.jsx)(h.Z,{title:String(e.getValue()||"-"),children:(0,t.jsx)("span",{className:"max-w-[15ch] truncate block",children:String(e.getValue()||"-")})})},{header:"Model",accessorKey:"model",cell:e=>{let s=e.row.original,a=s.custom_llm_provider,l=String(e.getValue()||"");return(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[a&&(0,t.jsx)("img",{src:f(s,a),alt:"",className:"w-4 h-4",onError:e=>{e.target.style.display="none"}}),(0,t.jsx)(h.Z,{title:l,children:(0,t.jsx)("span",{className:"max-w-[15ch] truncate block",children:l})})]})}},{header:"Tokens",accessorKey:"total_tokens",cell:e=>{let s=e.row.original;return(0,t.jsxs)("span",{className:"text-sm",children:[String(s.total_tokens||"0"),(0,t.jsxs)("span",{className:"text-gray-400 text-xs ml-1",children:["(",String(s.prompt_tokens||"0"),"+",String(s.completion_tokens||"0"),")"]})]})}},{header:"Internal User",accessorKey:"user",cell:e=>(0,t.jsx)(h.Z,{title:String(e.getValue()||"-"),children:(0,t.jsx)("span",{className:"max-w-[15ch] truncate block",children:String(e.getValue()||"-")})})},{header:"End User",accessorKey:"end_user",cell:e=>(0,t.jsx)(h.Z,{title:String(e.getValue()||"-"),children:(0,t.jsx)("span",{className:"max-w-[15ch] truncate block",children:String(e.getValue()||"-")})})},{header:"Tags",accessorKey:"request_tags",cell:e=>{let s=e.getValue();if(!s||0===Object.keys(s).length)return"-";let a=Object.entries(s),l=a[0],r=a.slice(1);return(0,t.jsx)("div",{className:"flex flex-wrap gap-1",children:(0,t.jsx)(h.Z,{title:(0,t.jsx)("div",{className:"flex flex-col gap-1",children:a.map(e=>{let[s,a]=e;return(0,t.jsxs)("span",{children:[s,": ",String(a)]},s)})}),children:(0,t.jsxs)("span",{className:"px-2 py-1 bg-gray-100 rounded-full text-xs",children:[l[0],": ",String(l[1]),r.length>0&&" +".concat(r.length)]})})})}}],y=e=>(0,t.jsx)(x.Z,{color:"gray",className:"flex items-center gap-1",children:(0,t.jsx)("span",{className:"whitespace-nowrap text-xs",children:e})}),b=[{id:"expander",header:()=>null,cell:e=>{let{row:s}=e;return(0,t.jsx)(()=>{let[e,a]=i.useState(s.getIsExpanded()),l=i.useCallback(()=>{a(e=>!e),s.getToggleExpandedHandler()()},[s]);return s.getCanExpand()?(0,t.jsx)("button",{onClick:l,style:{cursor:"pointer"},"aria-label":e?"Collapse row":"Expand row",className:"w-6 h-6 flex items-center justify-center focus:outline-none",children:(0,t.jsx)("svg",{className:"w-4 h-4 transform transition-transform ".concat(e?"rotate-90":""),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})}):(0,t.jsx)("span",{className:"w-6 h-6 flex items-center justify-center",children:"●"})},{})}},{header:"Timestamp",accessorKey:"updated_at",cell:e=>(0,t.jsx)(j,{utcTime:e.getValue()})},{header:"Table Name",accessorKey:"table_name",cell:e=>{let s=e.getValue(),a=s;switch(s){case"LiteLLM_VerificationToken":a="Keys";break;case"LiteLLM_TeamTable":a="Teams";break;case"LiteLLM_OrganizationTable":a="Organizations";break;case"LiteLLM_UserTable":a="Users";break;case"LiteLLM_ProxyModelTable":a="Models";break;default:a=s}return(0,t.jsx)("span",{children:a})}},{header:"Action",accessorKey:"action",cell:e=>(0,t.jsx)("span",{children:y(e.getValue())})},{header:"Changed By",accessorKey:"changed_by",cell:e=>{let s=e.row.original.changed_by,a=e.row.original.changed_by_api_key;return(0,t.jsxs)("div",{className:"space-y-1",children:[(0,t.jsx)("div",{className:"font-medium",children:s}),a&&(0,t.jsx)(h.Z,{title:a,children:(0,t.jsxs)("div",{className:"text-xs text-muted-foreground max-w-[15ch] truncate",children:[" ",a]})})]})}},{header:"Affected Item ID",accessorKey:"object_id",cell:e=>(0,t.jsx)(()=>{let s=e.getValue(),[a,l]=(0,i.useState)(!1);if(!s)return(0,t.jsx)(t.Fragment,{children:"-"});let r=async()=>{try{await navigator.clipboard.writeText(String(s)),l(!0),setTimeout(()=>l(!1),1500)}catch(e){console.error("Failed to copy object ID: ",e)}};return(0,t.jsx)(h.Z,{title:a?"Copied!":String(s),children:(0,t.jsx)("span",{className:"max-w-[20ch] truncate block cursor-pointer hover:text-blue-600",onClick:r,children:String(s)})})},{})}],N=async(e,s,a,t)=>{console.log("prefetchLogDetails called with",e.length,"logs");let l=e.map(e=>{if(e.request_id)return console.log("Prefetching details for request_id:",e.request_id),t.prefetchQuery({queryKey:["logDetails",e.request_id,s],queryFn:async()=>{console.log("Fetching details for",e.request_id);let t=await (0,o.uiSpendLogDetailsCall)(a,e.request_id,s);return console.log("Received details for",e.request_id,":",t?"success":"failed"),t},staleTime:6e5,gcTime:6e5})});try{let e=await Promise.all(l);return console.log("All prefetch promises completed:",e.length),e}catch(e){throw console.error("Error in prefetchLogDetails:",e),e}};var w=a(9114),_=a(86669);function k(e){let{row:s,hasMessages:a,hasResponse:l,hasError:r,errorInfo:n,getRawRequest:i,formattedResponse:d}=e,o=async e=>{try{if(navigator.clipboard&&window.isSecureContext)return await navigator.clipboard.writeText(e),!0;{let s=document.createElement("textarea");s.value=e,s.style.position="fixed",s.style.opacity="0",document.body.appendChild(s),s.focus(),s.select();let a=document.execCommand("copy");if(document.body.removeChild(s),!a)throw Error("execCommand failed");return!0}}catch(e){return console.error("Copy failed:",e),!1}},c=async()=>{await o(JSON.stringify(i(),null,2))?w.Z.success("Request copied to clipboard"):w.Z.fromBackend("Failed to copy request")},m=async()=>{await o(JSON.stringify(d(),null,2))?w.Z.success("Response copied to clipboard"):w.Z.fromBackend("Failed to copy response")};return(0,t.jsxs)("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4 w-full max-w-full overflow-hidden box-border",children:[(0,t.jsxs)("div",{className:"bg-white rounded-lg shadow w-full max-w-full overflow-hidden",children:[(0,t.jsxs)("div",{className:"flex justify-between items-center p-4 border-b",children:[(0,t.jsx)("h3",{className:"text-lg font-medium",children:"Request"}),(0,t.jsx)("button",{onClick:c,className:"p-1 hover:bg-gray-200 rounded",title:"Copy request",children:(0,t.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,t.jsx)("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2"}),(0,t.jsx)("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]})})]}),(0,t.jsx)("div",{className:"p-4 overflow-auto max-h-96 w-full max-w-full box-border",children:(0,t.jsx)("div",{className:"[&_[role='tree']]:bg-white [&_[role='tree']]:text-slate-900",children:(0,t.jsx)(_.gc,{data:i(),style:_.jF,clickToExpandNode:!0})})})]}),(0,t.jsxs)("div",{className:"bg-white rounded-lg shadow w-full max-w-full overflow-hidden",children:[(0,t.jsxs)("div",{className:"flex justify-between items-center p-4 border-b",children:[(0,t.jsxs)("h3",{className:"text-lg font-medium",children:["Response",r&&(0,t.jsxs)("span",{className:"ml-2 text-sm text-red-600",children:["• HTTP code ",(null==n?void 0:n.error_code)||400]})]}),(0,t.jsx)("button",{onClick:m,className:"p-1 hover:bg-gray-200 rounded",title:"Copy response",disabled:!l,children:(0,t.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,t.jsx)("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2"}),(0,t.jsx)("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]})})]}),(0,t.jsx)("div",{className:"p-4 overflow-auto max-h-96 w-full max-w-full box-border",children:l?(0,t.jsx)("div",{className:"[&_[role='tree']]:bg-white [&_[role='tree']]:text-slate-900",children:(0,t.jsx)(_.gc,{data:d(),style:_.jF,clickToExpandNode:!0})}):(0,t.jsx)("div",{className:"text-gray-500 text-sm italic text-center py-4",children:"Response data not available"})})]})]})}a(52621);let S=e=>{var s;let{errorInfo:a}=e,[l,r]=i.useState({}),[n,d]=i.useState(!1),o=e=>{r(s=>({...s,[e]:!s[e]}))},c=a.traceback&&(s=a.traceback)?Array.from(s.matchAll(/File "([^"]+)", line (\d+)/g)).map(e=>{let a=e[1],t=e[2],l=a.split("/").pop()||a,r=e.index||0,n=s.indexOf('File "',r+1),i=n>-1?s.substring(r,n).trim():s.substring(r).trim(),d=i.split("\n"),o="";return d.length>1&&(o=d[d.length-1].trim()),{filePath:a,fileName:l,lineNumber:t,code:o,inFunction:i.includes(" in ")?i.split(" in ")[1].split("\n")[0]:""}}):[];return(0,t.jsxs)("div",{className:"bg-white rounded-lg shadow",children:[(0,t.jsx)("div",{className:"p-4 border-b",children:(0,t.jsxs)("h3",{className:"text-lg font-medium flex items-center text-red-600",children:[(0,t.jsx)("svg",{className:"w-5 h-5 mr-2",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})}),"Error Details"]})}),(0,t.jsxs)("div",{className:"p-4",children:[(0,t.jsxs)("div",{className:"bg-red-50 rounded-md p-4 mb-4",children:[(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"text-red-800 font-medium w-20",children:"Type:"}),(0,t.jsx)("span",{className:"text-red-700",children:a.error_class||"Unknown Error"})]}),(0,t.jsxs)("div",{className:"flex mt-2",children:[(0,t.jsx)("span",{className:"text-red-800 font-medium w-20 flex-shrink-0",children:"Message:"}),(0,t.jsx)("span",{className:"text-red-700 break-words whitespace-pre-wrap",children:a.error_message||"Unknown error occurred"})]})]}),a.traceback&&(0,t.jsxs)("div",{className:"mt-4",children:[(0,t.jsxs)("div",{className:"flex justify-between items-center mb-2",children:[(0,t.jsx)("h4",{className:"font-medium",children:"Traceback"}),(0,t.jsxs)("div",{className:"flex items-center space-x-4",children:[(0,t.jsx)("button",{onClick:()=>{let e=!n;if(d(e),c.length>0){let s={};c.forEach((a,t)=>{s[t]=e}),r(s)}},className:"text-gray-500 hover:text-gray-700 flex items-center text-sm",children:n?"Collapse All":"Expand All"}),(0,t.jsxs)("button",{onClick:()=>navigator.clipboard.writeText(a.traceback||""),className:"text-gray-500 hover:text-gray-700 flex items-center",title:"Copy traceback",children:[(0,t.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,t.jsx)("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2"}),(0,t.jsx)("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]}),(0,t.jsx)("span",{className:"ml-1",children:"Copy"})]})]})]}),(0,t.jsx)("div",{className:"bg-white rounded-md border border-gray-200 overflow-hidden shadow-sm",children:c.map((e,s)=>(0,t.jsxs)("div",{className:"border-b border-gray-200 last:border-b-0",children:[(0,t.jsxs)("div",{className:"px-4 py-2 flex items-center justify-between cursor-pointer hover:bg-gray-50",onClick:()=>o(s),children:[(0,t.jsxs)("div",{className:"flex items-center",children:[(0,t.jsx)("span",{className:"text-gray-400 mr-2 w-12 text-right",children:e.lineNumber}),(0,t.jsx)("span",{className:"text-gray-600 font-medium",children:e.fileName}),(0,t.jsx)("span",{className:"text-gray-500 mx-1",children:"in"}),(0,t.jsx)("span",{className:"text-indigo-600 font-medium",children:e.inFunction||e.fileName})]}),(0,t.jsx)("svg",{className:"w-5 h-5 text-gray-500 transition-transform ".concat(l[s]?"transform rotate-180":""),fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]}),(l[s]||!1)&&e.code&&(0,t.jsx)("div",{className:"px-12 py-2 font-mono text-sm text-gray-800 bg-gray-50 overflow-x-auto border-t border-gray-100",children:e.code})]},s))})]})]})]})};var C=a(20347);let L=e=>{let{show:s}=e;return s?(0,t.jsxs)("div",{className:"bg-blue-50 border border-blue-200 rounded-lg p-4 flex items-start",children:[(0,t.jsx)("div",{className:"text-blue-500 mr-3 flex-shrink-0 mt-0.5",children:(0,t.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,t.jsx)("circle",{cx:"12",cy:"12",r:"10"}),(0,t.jsx)("line",{x1:"12",y1:"16",x2:"12",y2:"12"}),(0,t.jsx)("line",{x1:"12",y1:"8",x2:"12.01",y2:"8"})]})}),(0,t.jsxs)("div",{children:[(0,t.jsx)("h4",{className:"text-sm font-medium text-blue-800",children:"Request/Response Data Not Available"}),(0,t.jsxs)("p",{className:"text-sm text-blue-700 mt-1",children:["To view request and response details, enable prompt storage in your LiteLLM configuration by adding the following to your ",(0,t.jsx)("code",{className:"bg-blue-100 px-1 py-0.5 rounded",children:"proxy_config.yaml"})," file:"]}),(0,t.jsx)("pre",{className:"mt-2 bg-white p-3 rounded border border-blue-200 text-xs font-mono overflow-auto",children:"general_settings:\n store_model_in_db: true\n store_prompts_in_spend_logs: true"}),(0,t.jsx)("p",{className:"text-xs text-blue-700 mt-2",children:"Note: This will only affect new requests after the configuration change."})]})]}):null};var D=a(50665),M=a(12514),E=a(35829),T=a(84264),A=a(96761),R=a(10900),z=a(5545),O=a(30401),Z=a(78867);let I=e=>{let{sessionId:s,logs:a,onBack:l}=e,[r,n]=(0,i.useState)(null),[d,o]=(0,i.useState)({}),x=a.reduce((e,s)=>e+(s.spend||0),0),g=a.reduce((e,s)=>e+(s.total_tokens||0),0),p=a.reduce((e,s)=>{var a,t;return e+((null===(t=s.metadata)||void 0===t?void 0:null===(a=t.additional_usage_values)||void 0===a?void 0:a.cache_read_input_tokens)||0)},0),j=a.reduce((e,s)=>{var a,t;return e+((null===(t=s.metadata)||void 0===t?void 0:null===(a=t.additional_usage_values)||void 0===a?void 0:a.cache_creation_input_tokens)||0)},0),f=g+p+j,y=a.length>0?new Date(a[0].startTime):new Date;(((a.length>0?new Date(a[a.length-1].endTime):new Date).getTime()-y.getTime())/1e3).toFixed(2),a.map(e=>({time:new Date(e.startTime).toISOString(),tokens:e.total_tokens||0,cost:e.spend||0}));let b=async(e,s)=>{await (0,m.vQ)(e)&&(o(e=>({...e,[s]:!0})),setTimeout(()=>{o(e=>({...e,[s]:!1}))},2e3))};return(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"mb-8",children:[(0,t.jsx)(u.Z,{icon:R.Z,variant:"light",onClick:l,className:"mb-4",children:"Back to All Logs"}),(0,t.jsxs)("div",{className:"mt-4",children:[(0,t.jsx)("h1",{className:"text-2xl font-semibold text-gray-900",children:"Session Details"}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("div",{className:"flex items-center cursor-pointer",children:[(0,t.jsx)("p",{className:"text-sm text-gray-500 font-mono",children:s}),(0,t.jsx)(z.ZP,{type:"text",size:"small",icon:d["session-id"]?(0,t.jsx)(O.Z,{size:12}):(0,t.jsx)(Z.Z,{size:12}),onClick:()=>b(s,"session-id"),className:"left-2 z-10 transition-all duration-200 ".concat(d["session-id"]?"text-green-600 bg-green-50 border-green-200":"text-gray-500 hover:text-gray-700 hover:bg-gray-100")})]}),(0,t.jsxs)("a",{href:"https://docs.litellm.ai/docs/proxy/ui_logs_sessions",target:"_blank",rel:"noopener noreferrer",className:"text-sm text-blue-600 hover:text-blue-800 flex items-center gap-1",children:["Get started with session management here",(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:"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"})})]})]})]})]}),(0,t.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-4 gap-4",children:[(0,t.jsxs)(M.Z,{children:[(0,t.jsx)(T.Z,{children:"Total Requests"}),(0,t.jsx)(E.Z,{children:a.length})]}),(0,t.jsxs)(M.Z,{children:[(0,t.jsx)(T.Z,{children:"Total Cost"}),(0,t.jsxs)(E.Z,{children:["$",(0,m.pw)(x,6)]})]}),(0,t.jsx)(h.Z,{title:(0,t.jsxs)("div",{className:"text-white min-w-[200px]",children:[(0,t.jsx)("div",{className:"text-lg font-medium mb-3",children:"Usage breakdown"}),(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"text-base font-medium mb-2",children:"Input usage:"}),(0,t.jsxs)("div",{className:"space-y-2 text-sm text-gray-300",children:[(0,t.jsxs)("div",{className:"flex justify-between",children:[(0,t.jsx)("span",{children:"input:"}),(0,t.jsx)("span",{className:"ml-8",children:(0,m.pw)(a.reduce((e,s)=>e+(s.prompt_tokens||0),0))})]}),p>0&&(0,t.jsxs)("div",{className:"flex justify-between",children:[(0,t.jsx)("span",{children:"input_cached_tokens:"}),(0,t.jsx)("span",{className:"ml-8",children:(0,m.pw)(p)})]}),j>0&&(0,t.jsxs)("div",{className:"flex justify-between",children:[(0,t.jsx)("span",{children:"input_cache_creation_tokens:"}),(0,t.jsx)("span",{className:"ml-8",children:(0,m.pw)(j)})]})]})]}),(0,t.jsxs)("div",{className:"border-t border-gray-600 pt-3",children:[(0,t.jsx)("div",{className:"text-base font-medium mb-2",children:"Output usage:"}),(0,t.jsx)("div",{className:"space-y-2 text-sm text-gray-300",children:(0,t.jsxs)("div",{className:"flex justify-between",children:[(0,t.jsx)("span",{children:"output:"}),(0,t.jsx)("span",{className:"ml-8",children:(0,m.pw)(a.reduce((e,s)=>e+(s.completion_tokens||0),0))})]})})]}),(0,t.jsx)("div",{className:"border-t border-gray-600 pt-3",children:(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsx)("span",{className:"text-base font-medium",children:"Total usage:"}),(0,t.jsx)("span",{className:"text-sm text-gray-300",children:(0,m.pw)(f)})]})})]})]}),placement:"top",overlayStyle:{minWidth:"300px"},children:(0,t.jsxs)(M.Z,{children:[(0,t.jsxs)("div",{className:"flex items-center justify-between",children:[(0,t.jsx)(T.Z,{children:"Total Tokens"}),(0,t.jsx)("span",{className:"text-gray-400 text-sm",children:"ⓘ"})]}),(0,t.jsx)(E.Z,{children:(0,m.pw)(f)})]})})]}),(0,t.jsx)(A.Z,{children:"Session Logs"}),(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)(c.w,{columns:v,data:a,renderSubComponent:eU,getRowCanExpand:()=>!0,loadingMessage:"Loading logs...",noDataMessage:"No logs found"})})]})};function K(e){let{data:s}=e,[a,l]=(0,i.useState)(!0),[r,n]=(0,i.useState)({});if(!s||0===s.length)return null;let d=e=>new Date(1e3*e).toLocaleString(),o=(e,s)=>"".concat(((s-e)*1e3).toFixed(2),"ms"),c=(e,s)=>{let a="".concat(e,"-").concat(s);n(e=>({...e,[a]:!e[a]}))};return(0,t.jsxs)("div",{className:"bg-white rounded-lg shadow mb-6",children:[(0,t.jsxs)("div",{className:"flex justify-between items-center p-4 border-b cursor-pointer hover:bg-gray-50",onClick:()=>l(!a),children:[(0,t.jsxs)("div",{className:"flex items-center",children:[(0,t.jsx)("svg",{className:"w-5 h-5 mr-2 text-gray-600 transition-transform ".concat(a?"transform rotate-90":""),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})}),(0,t.jsx)("h3",{className:"text-lg font-medium",children:"Vector Store Requests"})]}),(0,t.jsx)("span",{className:"text-sm text-gray-500",children:a?"Click to collapse":"Click to expand"})]}),a&&(0,t.jsx)("div",{className:"p-4",children:s.map((e,s)=>(0,t.jsxs)("div",{className:"mb-6 last:mb-0",children:[(0,t.jsx)("div",{className:"bg-white rounded-lg border p-4 mb-4",children:(0,t.jsxs)("div",{className:"grid grid-cols-2 gap-4",children:[(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Query:"}),(0,t.jsx)("span",{className:"font-mono",children:e.query})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Vector Store ID:"}),(0,t.jsx)("span",{className:"font-mono",children:e.vector_store_id})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Provider:"}),(0,t.jsx)("span",{className:"flex items-center",children:(()=>{let{logo:s,displayName:a}=(0,g.dr)(e.custom_llm_provider);return(0,t.jsxs)(t.Fragment,{children:[s&&(0,t.jsx)("img",{src:s,alt:"".concat(a," logo"),className:"h-5 w-5 mr-2"}),a]})})()})]})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Start Time:"}),(0,t.jsx)("span",{children:d(e.start_time)})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"End Time:"}),(0,t.jsx)("span",{children:d(e.end_time)})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Duration:"}),(0,t.jsx)("span",{children:o(e.start_time,e.end_time)})]})]})]})}),(0,t.jsx)("h4",{className:"font-medium mb-2",children:"Search Results"}),(0,t.jsx)("div",{className:"space-y-2",children:e.vector_store_search_response.data.map((e,a)=>{let l=r["".concat(s,"-").concat(a)]||!1;return(0,t.jsxs)("div",{className:"border rounded-lg overflow-hidden",children:[(0,t.jsxs)("div",{className:"flex items-center p-3 bg-gray-50 cursor-pointer",onClick:()=>c(s,a),children:[(0,t.jsx)("svg",{className:"w-5 h-5 mr-2 transition-transform ".concat(l?"transform rotate-90":""),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})}),(0,t.jsxs)("div",{className:"flex items-center",children:[(0,t.jsxs)("span",{className:"font-medium mr-2",children:["Result ",a+1]}),(0,t.jsxs)("span",{className:"text-gray-500 text-sm",children:["Score: ",(0,t.jsx)("span",{className:"font-mono",children:e.score.toFixed(4)})]})]})]}),l&&(0,t.jsx)("div",{className:"p-3 border-t bg-white",children:e.content.map((e,s)=>(0,t.jsxs)("div",{className:"mb-2 last:mb-0",children:[(0,t.jsx)("div",{className:"text-xs text-gray-500 mb-1",children:e.type}),(0,t.jsx)("pre",{className:"text-xs font-mono whitespace-pre-wrap break-all bg-gray-50 p-2 rounded",children:e.text})]},s))})]},a)})})]},s))})]})}let H=e=>e>=.8?"text-green-600":"text-yellow-600";var P=e=>{let{entities:s}=e,[a,l]=(0,i.useState)(!0),[r,n]=(0,i.useState)({}),d=e=>{n(s=>({...s,[e]:!s[e]}))};return s&&0!==s.length?(0,t.jsxs)("div",{className:"mt-4",children:[(0,t.jsxs)("div",{className:"flex items-center mb-2 cursor-pointer",onClick:()=>l(!a),children:[(0,t.jsx)("svg",{className:"w-5 h-5 mr-2 transition-transform ".concat(a?"transform rotate-90":""),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})}),(0,t.jsxs)("h4",{className:"font-medium",children:["Detected Entities (",s.length,")"]})]}),a&&(0,t.jsx)("div",{className:"space-y-2",children:s.map((e,s)=>{let a=r[s]||!1;return(0,t.jsxs)("div",{className:"border rounded-lg overflow-hidden",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between p-3 bg-gray-50 cursor-pointer hover:bg-gray-100",onClick:()=>d(s),children:[(0,t.jsxs)("div",{className:"flex items-center",children:[(0,t.jsx)("svg",{className:"w-5 h-5 mr-2 transition-transform ".concat(a?"transform rotate-90":""),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})}),(0,t.jsx)("span",{className:"font-medium mr-2",children:e.entity_type}),(0,t.jsxs)("span",{className:"font-mono ".concat(H(e.score)),children:["Score: ",e.score.toFixed(2)]})]}),(0,t.jsxs)("span",{className:"text-xs text-gray-500",children:["Position: ",e.start,"-",e.end]})]}),a&&(0,t.jsx)("div",{className:"p-3 border-t bg-white",children:(0,t.jsxs)("div",{className:"grid grid-cols-2 gap-4 mb-2",children:[(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Entity Type:"}),(0,t.jsx)("span",{children:e.entity_type})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Position:"}),(0,t.jsxs)("span",{children:["Characters ",e.start,"-",e.end]})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Confidence:"}),(0,t.jsx)("span",{className:H(e.score),children:e.score.toFixed(2)})]})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[e.recognition_metadata&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Recognizer:"}),(0,t.jsx)("span",{children:e.recognition_metadata.recognizer_name})]}),(0,t.jsxs)("div",{className:"flex overflow-hidden",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Identifier:"}),(0,t.jsx)("span",{className:"truncate text-xs font-mono",children:e.recognition_metadata.recognizer_identifier})]})]}),e.analysis_explanation&&(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Explanation:"}),(0,t.jsx)("span",{children:e.analysis_explanation})]})]})]})})]},s)})})]}):null};let F=function(e){let s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"slate";return(0,t.jsx)("span",{className:"px-2 py-1 rounded-md text-xs font-medium inline-block ".concat({green:"bg-green-100 text-green-800",red:"bg-red-100 text-red-800",blue:"bg-blue-50 text-blue-700",slate:"bg-slate-100 text-slate-800",amber:"bg-amber-100 text-amber-800"}[s]),children:e})},q=e=>e?F("detected","red"):F("not detected","slate"),Y=e=>{let{title:s,count:a,defaultOpen:l=!0,right:r,children:n}=e,[d,o]=(0,i.useState)(l);return(0,t.jsxs)("div",{className:"border rounded-lg overflow-hidden",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between p-3 bg-gray-50 cursor-pointer hover:bg-gray-100",onClick:()=>o(e=>!e),children:[(0,t.jsxs)("div",{className:"flex items-center",children:[(0,t.jsx)("svg",{className:"w-5 h-5 mr-2 transition-transform ".concat(d?"transform rotate-90":""),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})}),(0,t.jsxs)("h5",{className:"font-medium",children:[s," ","number"==typeof a&&(0,t.jsxs)("span",{className:"text-gray-500 font-normal",children:["(",a,")"]})]})]}),(0,t.jsx)("div",{children:r})]}),d&&(0,t.jsx)("div",{className:"p-3 border-t bg-white",children:n})]})},B=e=>{let{label:s,children:a,mono:l}=e;return(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:s}),(0,t.jsx)("span",{className:l?"font-mono text-sm break-all":"",children:a})]})},V=()=>(0,t.jsx)("div",{className:"my-3 border-t"});var U=e=>{var s,a,l,r,n,i,d,o,c,m;let{response:x}=e;if(!x)return null;let u=null!==(n=null!==(r=x.outputs)&&void 0!==r?r:x.output)&&void 0!==n?n:[],h="GUARDRAIL_INTERVENED"===x.action?"red":"green",g=(0,t.jsxs)("div",{className:"flex flex-wrap gap-2",children:[(null===(s=x.guardrailCoverage)||void 0===s?void 0:s.textCharacters)&&F("text guarded ".concat(null!==(i=x.guardrailCoverage.textCharacters.guarded)&&void 0!==i?i:0,"/").concat(null!==(d=x.guardrailCoverage.textCharacters.total)&&void 0!==d?d:0),"blue"),(null===(a=x.guardrailCoverage)||void 0===a?void 0:a.images)&&F("images guarded ".concat(null!==(o=x.guardrailCoverage.images.guarded)&&void 0!==o?o:0,"/").concat(null!==(c=x.guardrailCoverage.images.total)&&void 0!==c?c:0),"blue")]}),p=x.usage&&(0,t.jsx)("div",{className:"flex flex-wrap gap-2",children:Object.entries(x.usage).map(e=>{let[s,a]=e;return"number"==typeof a?(0,t.jsxs)("span",{className:"px-2 py-1 bg-slate-100 text-slate-800 rounded-md text-xs font-medium",children:[s,": ",a]},s):null})});return(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsxs)("div",{className:"border rounded-lg p-4",children:[(0,t.jsxs)("div",{className:"grid grid-cols-2 gap-4",children:[(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)(B,{label:"Action:",children:F(null!==(m=x.action)&&void 0!==m?m:"N/A",h)}),x.actionReason&&(0,t.jsx)(B,{label:"Action Reason:",children:x.actionReason}),x.blockedResponse&&(0,t.jsx)(B,{label:"Blocked Response:",children:(0,t.jsx)("span",{className:"italic",children:x.blockedResponse})})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)(B,{label:"Coverage:",children:g}),(0,t.jsx)(B,{label:"Usage:",children:p})]})]}),u.length>0&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(V,{}),(0,t.jsx)("h4",{className:"font-medium mb-2",children:"Outputs"}),(0,t.jsx)("div",{className:"space-y-2",children:u.map((e,s)=>{var a;return(0,t.jsx)("div",{className:"p-3 bg-gray-50 rounded-md",children:(0,t.jsx)("div",{className:"text-sm whitespace-pre-wrap",children:null!==(a=e.text)&&void 0!==a?a:(0,t.jsx)("em",{children:"(non-text output)"})})},s)})})]})]}),(null===(l=x.assessments)||void 0===l?void 0:l.length)?(0,t.jsx)("div",{className:"space-y-3",children:x.assessments.map((e,s)=>{var a,l,r,n,i,d,o,c,m,x,u,h,g,p,j,f,v,y,b,N,w,_,k,S;let C=(0,t.jsxs)("div",{className:"flex flex-wrap gap-1",children:[e.wordPolicy&&F("word","slate"),e.contentPolicy&&F("content","slate"),e.topicPolicy&&F("topic","slate"),e.sensitiveInformationPolicy&&F("sensitive-info","slate"),e.contextualGroundingPolicy&&F("contextual-grounding","slate"),e.automatedReasoningPolicy&&F("automated-reasoning","slate")]});return(0,t.jsxs)(Y,{title:"Assessment #".concat(s+1),defaultOpen:!0,right:(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(null===(a=e.invocationMetrics)||void 0===a?void 0:a.guardrailProcessingLatency)!=null&&F("".concat(e.invocationMetrics.guardrailProcessingLatency," ms"),"amber"),C]}),children:[e.wordPolicy&&(0,t.jsxs)("div",{className:"mb-3",children:[(0,t.jsx)("h6",{className:"font-medium mb-2",children:"Word Policy"}),(null!==(f=null===(l=e.wordPolicy.customWords)||void 0===l?void 0:l.length)&&void 0!==f?f:0)>0&&(0,t.jsx)(Y,{title:"Custom Words",defaultOpen:!0,children:(0,t.jsx)("div",{className:"space-y-2",children:e.wordPolicy.customWords.map((e,s)=>{var a;return(0,t.jsxs)("div",{className:"flex justify-between items-center p-2 bg-gray-50 rounded",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[F(null!==(a=e.action)&&void 0!==a?a:"N/A",e.detected?"red":"slate"),(0,t.jsx)("span",{className:"font-mono text-sm break-all",children:e.match})]}),q(e.detected)]},s)})})}),(null!==(v=null===(r=e.wordPolicy.managedWordLists)||void 0===r?void 0:r.length)&&void 0!==v?v:0)>0&&(0,t.jsx)(Y,{title:"Managed Word Lists",defaultOpen:!1,children:(0,t.jsx)("div",{className:"space-y-2",children:e.wordPolicy.managedWordLists.map((e,s)=>{var a;return(0,t.jsxs)("div",{className:"flex justify-between items-center p-2 bg-gray-50 rounded",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[F(null!==(a=e.action)&&void 0!==a?a:"N/A",e.detected?"red":"slate"),(0,t.jsx)("span",{className:"font-mono text-sm break-all",children:e.match}),e.type&&F(e.type,"slate")]}),q(e.detected)]},s)})})})]}),(null===(i=e.contentPolicy)||void 0===i?void 0:null===(n=i.filters)||void 0===n?void 0:n.length)?(0,t.jsxs)("div",{className:"mb-3",children:[(0,t.jsx)("h6",{className:"font-medium mb-2",children:"Content Policy"}),(0,t.jsx)("div",{className:"overflow-x-auto",children:(0,t.jsxs)("table",{className:"min-w-full text-sm",children:[(0,t.jsx)("thead",{children:(0,t.jsxs)("tr",{className:"text-left text-gray-600",children:[(0,t.jsx)("th",{className:"py-1 pr-4",children:"Type"}),(0,t.jsx)("th",{className:"py-1 pr-4",children:"Action"}),(0,t.jsx)("th",{className:"py-1 pr-4",children:"Detected"}),(0,t.jsx)("th",{className:"py-1 pr-4",children:"Strength"}),(0,t.jsx)("th",{className:"py-1 pr-4",children:"Confidence"})]})}),(0,t.jsx)("tbody",{children:e.contentPolicy.filters.map((e,s)=>{var a,l,r,n;return(0,t.jsxs)("tr",{className:"border-t",children:[(0,t.jsx)("td",{className:"py-1 pr-4",children:null!==(a=e.type)&&void 0!==a?a:"—"}),(0,t.jsx)("td",{className:"py-1 pr-4",children:F(null!==(l=e.action)&&void 0!==l?l:"—",e.detected?"red":"slate")}),(0,t.jsx)("td",{className:"py-1 pr-4",children:q(e.detected)}),(0,t.jsx)("td",{className:"py-1 pr-4",children:null!==(r=e.filterStrength)&&void 0!==r?r:"—"}),(0,t.jsx)("td",{className:"py-1 pr-4",children:null!==(n=e.confidence)&&void 0!==n?n:"—"})]},s)})})]})})]}):null,(null===(o=e.contextualGroundingPolicy)||void 0===o?void 0:null===(d=o.filters)||void 0===d?void 0:d.length)?(0,t.jsxs)("div",{className:"mb-3",children:[(0,t.jsx)("h6",{className:"font-medium mb-2",children:"Contextual Grounding"}),(0,t.jsx)("div",{className:"overflow-x-auto",children:(0,t.jsxs)("table",{className:"min-w-full text-sm",children:[(0,t.jsx)("thead",{children:(0,t.jsxs)("tr",{className:"text-left text-gray-600",children:[(0,t.jsx)("th",{className:"py-1 pr-4",children:"Type"}),(0,t.jsx)("th",{className:"py-1 pr-4",children:"Action"}),(0,t.jsx)("th",{className:"py-1 pr-4",children:"Detected"}),(0,t.jsx)("th",{className:"py-1 pr-4",children:"Score"}),(0,t.jsx)("th",{className:"py-1 pr-4",children:"Threshold"})]})}),(0,t.jsx)("tbody",{children:e.contextualGroundingPolicy.filters.map((e,s)=>{var a,l,r,n;return(0,t.jsxs)("tr",{className:"border-t",children:[(0,t.jsx)("td",{className:"py-1 pr-4",children:null!==(a=e.type)&&void 0!==a?a:"—"}),(0,t.jsx)("td",{className:"py-1 pr-4",children:F(null!==(l=e.action)&&void 0!==l?l:"—",e.detected?"red":"slate")}),(0,t.jsx)("td",{className:"py-1 pr-4",children:q(e.detected)}),(0,t.jsx)("td",{className:"py-1 pr-4",children:null!==(r=e.score)&&void 0!==r?r:"—"}),(0,t.jsx)("td",{className:"py-1 pr-4",children:null!==(n=e.threshold)&&void 0!==n?n:"—"})]},s)})})]})})]}):null,e.sensitiveInformationPolicy&&(0,t.jsxs)("div",{className:"mb-3",children:[(0,t.jsx)("h6",{className:"font-medium mb-2",children:"Sensitive Information"}),(null!==(y=null===(c=e.sensitiveInformationPolicy.piiEntities)||void 0===c?void 0:c.length)&&void 0!==y?y:0)>0&&(0,t.jsx)(Y,{title:"PII Entities",defaultOpen:!0,children:(0,t.jsx)("div",{className:"space-y-2",children:e.sensitiveInformationPolicy.piiEntities.map((e,s)=>{var a;return(0,t.jsxs)("div",{className:"flex justify-between items-center p-2 bg-gray-50 rounded",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[F(null!==(a=e.action)&&void 0!==a?a:"N/A",e.detected?"red":"slate"),e.type&&F(e.type,"slate"),(0,t.jsx)("span",{className:"font-mono text-xs break-all",children:e.match})]}),q(e.detected)]},s)})})}),(null!==(b=null===(m=e.sensitiveInformationPolicy.regexes)||void 0===m?void 0:m.length)&&void 0!==b?b:0)>0&&(0,t.jsx)(Y,{title:"Custom Regexes",defaultOpen:!1,children:(0,t.jsx)("div",{className:"space-y-2",children:e.sensitiveInformationPolicy.regexes.map((e,s)=>{var a,l;return(0,t.jsxs)("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between p-2 bg-gray-50 rounded gap-1",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[F(null!==(a=e.action)&&void 0!==a?a:"N/A",e.detected?"red":"slate"),(0,t.jsx)("span",{className:"font-medium",children:null!==(l=e.name)&&void 0!==l?l:"regex"}),(0,t.jsx)("span",{className:"font-mono text-xs break-all",children:e.regex})]}),(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[q(e.detected),e.match&&(0,t.jsx)("span",{className:"font-mono text-xs break-all",children:e.match})]})]},s)})})})]}),(null===(u=e.topicPolicy)||void 0===u?void 0:null===(x=u.topics)||void 0===x?void 0:x.length)?(0,t.jsxs)("div",{className:"mb-3",children:[(0,t.jsx)("h6",{className:"font-medium mb-2",children:"Topic Policy"}),(0,t.jsx)("div",{className:"flex flex-wrap gap-2",children:e.topicPolicy.topics.map((e,s)=>{var a,l;return(0,t.jsx)("div",{className:"px-3 py-1.5 bg-gray-50 rounded-md text-xs",children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[F(null!==(a=e.action)&&void 0!==a?a:"N/A",e.detected?"red":"slate"),(0,t.jsx)("span",{className:"font-medium",children:null!==(l=e.name)&&void 0!==l?l:"topic"}),e.type&&F(e.type,"slate"),q(e.detected)]})},s)})})]}):null,e.invocationMetrics&&(0,t.jsx)(Y,{title:"Invocation Metrics",defaultOpen:!1,children:(0,t.jsxs)("div",{className:"grid grid-cols-2 gap-4",children:[(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)(B,{label:"Latency (ms)",children:null!==(N=e.invocationMetrics.guardrailProcessingLatency)&&void 0!==N?N:"—"}),(0,t.jsx)(B,{label:"Coverage:",children:(0,t.jsxs)("div",{className:"flex flex-wrap gap-2",children:[(null===(h=e.invocationMetrics.guardrailCoverage)||void 0===h?void 0:h.textCharacters)&&F("text ".concat(null!==(w=e.invocationMetrics.guardrailCoverage.textCharacters.guarded)&&void 0!==w?w:0,"/").concat(null!==(_=e.invocationMetrics.guardrailCoverage.textCharacters.total)&&void 0!==_?_:0),"blue"),(null===(g=e.invocationMetrics.guardrailCoverage)||void 0===g?void 0:g.images)&&F("images ".concat(null!==(k=e.invocationMetrics.guardrailCoverage.images.guarded)&&void 0!==k?k:0,"/").concat(null!==(S=e.invocationMetrics.guardrailCoverage.images.total)&&void 0!==S?S:0),"blue")]})})]}),(0,t.jsx)("div",{className:"space-y-2",children:(0,t.jsx)(B,{label:"Usage:",children:(0,t.jsx)("div",{className:"flex flex-wrap gap-2",children:e.invocationMetrics.usage&&Object.entries(e.invocationMetrics.usage).map(e=>{let[s,a]=e;return"number"==typeof a?(0,t.jsxs)("span",{className:"px-2 py-1 bg-slate-100 text-slate-800 rounded-md text-xs font-medium",children:[s,": ",a]},s):null})})})})]})}),(null===(j=e.automatedReasoningPolicy)||void 0===j?void 0:null===(p=j.findings)||void 0===p?void 0:p.length)?(0,t.jsx)(Y,{title:"Automated Reasoning Findings",defaultOpen:!1,children:(0,t.jsx)("div",{className:"space-y-2",children:e.automatedReasoningPolicy.findings.map((e,s)=>(0,t.jsx)("pre",{className:"bg-gray-50 rounded p-2 text-xs overflow-x-auto",children:JSON.stringify(e,null,2)},s))})}):null]},s)})}):null,(0,t.jsx)(Y,{title:"Raw Bedrock Guardrail Response",defaultOpen:!1,children:(0,t.jsx)("pre",{className:"bg-gray-50 rounded p-3 text-xs overflow-x-auto",children:JSON.stringify(x,null,2)})})]})};let W=function(e){let s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"slate";return(0,t.jsx)("span",{className:"px-2 py-1 rounded-md text-xs font-medium inline-block ".concat({green:"bg-green-100 text-green-800",red:"bg-red-100 text-red-800",blue:"bg-blue-50 text-blue-700",slate:"bg-slate-100 text-slate-800",amber:"bg-amber-100 text-amber-800"}[s]),children:e})},J=e=>{let{title:s,count:a,defaultOpen:l=!0,children:r}=e,[n,d]=(0,i.useState)(l);return(0,t.jsxs)("div",{className:"border rounded-lg overflow-hidden",children:[(0,t.jsx)("div",{className:"flex items-center justify-between p-3 bg-gray-50 cursor-pointer hover:bg-gray-100",onClick:()=>d(e=>!e),children:(0,t.jsxs)("div",{className:"flex items-center",children:[(0,t.jsx)("svg",{className:"w-5 h-5 mr-2 transition-transform ".concat(n?"transform rotate-90":""),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})}),(0,t.jsxs)("h5",{className:"font-medium",children:[s," ","number"==typeof a&&(0,t.jsxs)("span",{className:"text-gray-500 font-normal",children:["(",a,")"]})]})]})}),n&&(0,t.jsx)("div",{className:"p-3 border-t bg-white",children:r})]})},G=e=>{let{label:s,children:a,mono:l}=e;return(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:s}),(0,t.jsx)("span",{className:l?"font-mono text-sm break-all":"",children:a})]})};var Q=e=>{let{response:s}=e;if(!s||"string"==typeof s)return"string"==typeof s&&s?(0,t.jsx)("div",{className:"bg-white rounded-lg border border-red-200 p-4",children:(0,t.jsxs)("div",{className:"text-red-800",children:[(0,t.jsx)("h5",{className:"font-medium mb-2",children:"Error"}),(0,t.jsx)("p",{className:"text-sm",children:s})]})}):null;let a=Array.isArray(s)?s:[];if(0===a.length)return(0,t.jsx)("div",{className:"bg-white rounded-lg border border-gray-200 p-4",children:(0,t.jsx)("div",{className:"text-gray-600 text-sm",children:"No detections found"})});let l=a.filter(e=>"pattern"===e.type),r=a.filter(e=>"blocked_word"===e.type),n=a.filter(e=>"category_keyword"===e.type),i=a.filter(e=>"BLOCK"===e.action).length,d=a.filter(e=>"MASK"===e.action).length,o=a.length;return(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsx)("div",{className:"bg-white rounded-lg border border-gray-200 p-4",children:(0,t.jsxs)("div",{className:"grid grid-cols-2 gap-4",children:[(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)(G,{label:"Total Detections:",children:(0,t.jsx)("span",{className:"font-semibold",children:o})}),(0,t.jsx)(G,{label:"Actions:",children:(0,t.jsxs)("div",{className:"flex flex-wrap gap-2",children:[i>0&&W("".concat(i," blocked"),"red"),d>0&&W("".concat(d," masked"),"blue"),0===i&&0===d&&W("passed","green")]})})]}),(0,t.jsx)("div",{className:"space-y-2",children:(0,t.jsx)(G,{label:"By Type:",children:(0,t.jsxs)("div",{className:"flex flex-wrap gap-2",children:[l.length>0&&W("".concat(l.length," patterns"),"slate"),r.length>0&&W("".concat(r.length," keywords"),"slate"),n.length>0&&W("".concat(n.length," categories"),"slate")]})})})]})}),l.length>0&&(0,t.jsx)(J,{title:"Patterns Matched",count:l.length,defaultOpen:!0,children:(0,t.jsx)("div",{className:"space-y-2",children:l.map((e,s)=>(0,t.jsx)("div",{className:"p-3 bg-gray-50 rounded-md",children:(0,t.jsxs)("div",{className:"grid grid-cols-2 gap-4",children:[(0,t.jsx)("div",{className:"space-y-1",children:(0,t.jsx)(G,{label:"Pattern:",children:e.pattern_name||"unknown"})}),(0,t.jsx)("div",{className:"space-y-1",children:(0,t.jsx)(G,{label:"Action:",children:W(e.action,"BLOCK"===e.action?"red":"blue")})})]})},s))})}),r.length>0&&(0,t.jsx)(J,{title:"Blocked Words Detected",count:r.length,defaultOpen:!0,children:(0,t.jsx)("div",{className:"space-y-2",children:r.map((e,s)=>(0,t.jsx)("div",{className:"p-3 bg-gray-50 rounded-md",children:(0,t.jsxs)("div",{className:"grid grid-cols-2 gap-4",children:[(0,t.jsxs)("div",{className:"space-y-1",children:[(0,t.jsx)(G,{label:"Keyword:",mono:!0,children:e.keyword||"unknown"}),e.description&&(0,t.jsx)(G,{label:"Description:",children:e.description})]}),(0,t.jsx)("div",{className:"space-y-1",children:(0,t.jsx)(G,{label:"Action:",children:W(e.action,"BLOCK"===e.action?"red":"blue")})})]})},s))})}),n.length>0&&(0,t.jsx)(J,{title:"Category Keywords Detected",count:n.length,defaultOpen:!0,children:(0,t.jsx)("div",{className:"space-y-2",children:n.map((e,s)=>(0,t.jsx)("div",{className:"p-3 bg-gray-50 rounded-md",children:(0,t.jsxs)("div",{className:"grid grid-cols-2 gap-4",children:[(0,t.jsxs)("div",{className:"space-y-1",children:[(0,t.jsx)(G,{label:"Category:",children:e.category||"unknown"}),(0,t.jsx)(G,{label:"Keyword:",mono:!0,children:e.keyword||"unknown"}),e.severity&&(0,t.jsx)(G,{label:"Severity:",children:W(e.severity,"high"===e.severity?"red":"medium"===e.severity?"amber":"slate")})]}),(0,t.jsx)("div",{className:"space-y-1",children:(0,t.jsx)(G,{label:"Action:",children:W(e.action,"BLOCK"===e.action?"red":"blue")})})]})},s))})}),(0,t.jsx)(J,{title:"Raw Detection Data",defaultOpen:!1,children:(0,t.jsx)("pre",{className:"bg-gray-50 rounded p-3 text-xs overflow-x-auto",children:JSON.stringify(a,null,2)})})]})};let $=e=>new Date(1e3*e).toLocaleString(),X=new Set(["presidio","bedrock","litellm_content_filter"]),ee=e=>{let{response:s}=e,[a,l]=(0,i.useState)(!1);return(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsxs)("div",{className:"border rounded-lg overflow-hidden",children:[(0,t.jsx)("div",{className:"flex items-center justify-between p-3 bg-gray-50 cursor-pointer hover:bg-gray-100",onClick:()=>l(!a),children:(0,t.jsxs)("div",{className:"flex items-center",children:[(0,t.jsx)("svg",{className:"w-5 h-5 mr-2 transition-transform ".concat(a?"transform rotate-90":""),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})}),(0,t.jsx)("h5",{className:"font-medium",children:"Raw Guardrail Response"})]})}),a&&(0,t.jsx)("div",{className:"p-3 border-t bg-white",children:(0,t.jsx)("pre",{className:"bg-gray-50 rounded p-3 text-xs overflow-x-auto",children:JSON.stringify(s,null,2)})})]})})},es=e=>{var s,a;let{entry:l,index:r,total:n}=e,i=null!==(s=l.guardrail_provider)&&void 0!==s?s:"presidio",d=null!==(a=l.guardrail_status)&&void 0!==a?a:"unknown",o="success"===d.toLowerCase(),c=l.masked_entity_count||{},m=Object.values(c).reduce((e,s)=>e+("number"==typeof s?s:0),0),x=l.guardrail_response,u=Array.isArray(x)?x:[],g="bedrock"!==i||null===x||"object"!=typeof x||Array.isArray(x)?void 0:x;return(0,t.jsxs)("div",{className:"bg-white rounded-lg border border-gray-200 p-4",children:[n>1&&(0,t.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[(0,t.jsxs)("h4",{className:"text-base font-semibold",children:["Guardrail #",r+1,(0,t.jsx)("span",{className:"ml-2 font-mono text-sm text-gray-600",children:l.guardrail_name})]}),(0,t.jsx)("span",{className:"px-2 py-0.5 bg-gray-100 text-gray-600 rounded-md text-xs capitalize",children:i})]}),(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)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Guardrail Name:"}),(0,t.jsx)("span",{className:"font-mono break-words",children:l.guardrail_name})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Mode:"}),(0,t.jsx)("span",{className:"font-mono break-words",children:l.guardrail_mode})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Status:"}),(0,t.jsx)(h.Z,{title:o?null:"Guardrail failed to run.",placement:"top",arrow:!0,destroyTooltipOnHide:!0,children:(0,t.jsx)("span",{className:"px-2 py-1 rounded-md text-xs font-medium inline-block ".concat(o?"bg-green-100 text-green-800":"bg-red-100 text-red-800 cursor-help"),children:d})})]})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Start Time:"}),(0,t.jsx)("span",{children:$(l.start_time)})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"End Time:"}),(0,t.jsx)("span",{children:$(l.end_time)})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Duration:"}),(0,t.jsxs)("span",{children:[l.duration.toFixed(4),"s"]})]})]})]}),m>0&&(0,t.jsxs)("div",{className:"mt-4 pt-4 border-t",children:[(0,t.jsx)("h5",{className:"font-medium mb-2",children:"Masked Entity Summary"}),(0,t.jsx)("div",{className:"flex flex-wrap gap-2",children:Object.entries(c).map(e=>{let[s,a]=e;return(0,t.jsxs)("span",{className:"px-3 py-1.5 bg-blue-50 text-blue-700 rounded-md text-xs font-medium",children:[s,": ",a]},s)})})]}),"presidio"===i&&u.length>0&&(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)(P,{entities:u})}),"bedrock"===i&&g&&(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)(U,{response:g})}),"litellm_content_filter"===i&&x&&(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)(Q,{response:x})}),i&&!X.has(i)&&x&&(0,t.jsx)(ee,{response:x})]})};var ea=e=>{let{data:s}=e,a=Array.isArray(s)?s.filter(e=>!!e):s?[s]:[],[l,r]=(0,i.useState)(!0),n=1===a.length?a[0].guardrail_name:"".concat(a.length," guardrails"),d=Array.from(new Set(a.map(e=>e.guardrail_status))).every(e=>"success"===(null!=e?e:"").toLowerCase()),o=a.reduce((e,s)=>e+Object.values(s.masked_entity_count||{}).reduce((e,s)=>e+("number"==typeof s?s:0),0),0);return 0===a.length?null:(0,t.jsxs)("div",{className:"bg-white rounded-lg shadow mb-6",children:[(0,t.jsxs)("div",{className:"flex justify-between items-center p-4 border-b cursor-pointer hover:bg-gray-50",onClick:()=>r(!l),children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("svg",{className:"w-5 h-5 text-gray-600 transition-transform ".concat(l?"transform rotate-90":""),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})}),(0,t.jsx)("h3",{className:"text-lg font-medium",children:"Guardrail Information"}),(0,t.jsx)(h.Z,{title:d?null:"Guardrail failed to run.",placement:"top",arrow:!0,destroyTooltipOnHide:!0,children:(0,t.jsx)("span",{className:"ml-2 px-2 py-1 rounded-md text-xs font-medium inline-block ".concat(d?"bg-green-100 text-green-800":"bg-red-100 text-red-800 cursor-help"),children:d?"success":"failure"})}),(0,t.jsx)("span",{className:"ml-2 font-mono text-sm text-gray-600",children:n}),o>0&&(0,t.jsxs)("span",{className:"ml-2 px-2 py-1 bg-blue-50 text-blue-700 rounded-md text-xs font-medium",children:[o," masked ",1===o?"entity":"entities"]})]}),(0,t.jsx)("span",{className:"text-sm text-gray-500",children:l?"Click to collapse":"Click to expand"})]}),l&&(0,t.jsx)("div",{className:"p-4 space-y-6",children:a.map((e,s)=>{var l;return(0,t.jsx)(es,{entry:e,index:s,total:a.length},"".concat(null!==(l=e.guardrail_name)&&void 0!==l?l:"guardrail","-").concat(s))})})]})},et=a(87452),el=a(88829),er=a(72208);let en=e=>null==e?"-":"$".concat((0,m.pw)(e,8)),ei=e=>null==e?"-":"".concat((100*e).toFixed(2),"%"),ed=e=>{var s;let{costBreakdown:a,totalSpend:l}=e;if(!a)return null;let r=void 0!==a.discount_percent&&0!==a.discount_percent||void 0!==a.discount_amount&&0!==a.discount_amount,n=void 0!==a.margin_percent&&0!==a.margin_percent||void 0!==a.margin_fixed_amount&&0!==a.margin_fixed_amount||void 0!==a.margin_total_amount&&0!==a.margin_total_amount;return void 0!==a.input_cost||void 0!==a.output_cost||r||n?(0,t.jsx)("div",{className:"bg-white rounded-lg shadow w-full max-w-full overflow-hidden",children:(0,t.jsxs)(et.Z,{children:[(0,t.jsx)(er.Z,{className:"p-4 border-b hover:bg-gray-50 transition-colors text-left",children:(0,t.jsxs)("div",{className:"flex items-center justify-between w-full",children:[(0,t.jsx)("h3",{className:"text-lg font-medium text-gray-900",children:"Cost Breakdown"}),(0,t.jsxs)("div",{className:"flex items-center space-x-2 mr-4",children:[(0,t.jsx)("span",{className:"text-sm text-gray-500",children:"Total:"}),(0,t.jsx)("span",{className:"text-sm font-semibold text-gray-900",children:en(l)})]})]})}),(0,t.jsx)(el.Z,{className:"px-0",children:(0,t.jsxs)("div",{className:"p-6 space-y-4",children:[(0,t.jsxs)("div",{className:"space-y-2 max-w-2xl",children:[(0,t.jsxs)("div",{className:"flex text-sm",children:[(0,t.jsx)("span",{className:"text-gray-600 font-medium w-1/3",children:"Input Cost:"}),(0,t.jsx)("span",{className:"text-gray-900",children:en(a.input_cost)})]}),(0,t.jsxs)("div",{className:"flex text-sm",children:[(0,t.jsx)("span",{className:"text-gray-600 font-medium w-1/3",children:"Output Cost:"}),(0,t.jsx)("span",{className:"text-gray-900",children:en(a.output_cost)})]}),void 0!==a.tool_usage_cost&&a.tool_usage_cost>0&&(0,t.jsxs)("div",{className:"flex text-sm",children:[(0,t.jsx)("span",{className:"text-gray-600 font-medium w-1/3",children:"Tool Usage Cost:"}),(0,t.jsx)("span",{className:"text-gray-900",children:en(a.tool_usage_cost)})]})]}),(0,t.jsx)("div",{className:"pt-2 border-t border-gray-100 max-w-2xl",children:(0,t.jsxs)("div",{className:"flex text-sm font-semibold",children:[(0,t.jsx)("span",{className:"text-gray-900 w-1/3",children:"Original LLM Cost:"}),(0,t.jsx)("span",{className:"text-gray-900",children:en(a.original_cost)})]})}),(r||n)&&(0,t.jsxs)("div",{className:"pt-2 space-y-2 max-w-2xl",children:[r&&(0,t.jsxs)("div",{className:"space-y-2",children:[void 0!==a.discount_percent&&0!==a.discount_percent&&(0,t.jsxs)("div",{className:"flex text-sm text-gray-600",children:[(0,t.jsxs)("span",{className:"font-medium w-1/3",children:["Discount (",ei(a.discount_percent),"):"]}),(0,t.jsxs)("span",{className:"text-gray-900",children:["-",en(a.discount_amount)]})]}),void 0!==a.discount_amount&&void 0===a.discount_percent&&(0,t.jsxs)("div",{className:"flex text-sm text-gray-600",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Discount Amount:"}),(0,t.jsxs)("span",{className:"text-gray-900",children:["-",en(a.discount_amount)]})]})]}),n&&(0,t.jsxs)("div",{className:"space-y-2",children:[void 0!==a.margin_percent&&0!==a.margin_percent&&(0,t.jsxs)("div",{className:"flex text-sm text-gray-600",children:[(0,t.jsxs)("span",{className:"font-medium w-1/3",children:["Margin (",ei(a.margin_percent),"):"]}),(0,t.jsxs)("span",{className:"text-gray-900",children:["+",en((a.margin_total_amount||0)-(a.margin_fixed_amount||0))]})]}),void 0!==a.margin_fixed_amount&&0!==a.margin_fixed_amount&&(0,t.jsxs)("div",{className:"flex text-sm text-gray-600",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Margin:"}),(0,t.jsxs)("span",{className:"text-gray-900",children:["+",en(a.margin_fixed_amount)]})]})]})]}),(0,t.jsx)("div",{className:"mt-4 pt-4 border-t border-gray-200 max-w-2xl",children:(0,t.jsxs)("div",{className:"flex items-center",children:[(0,t.jsx)("span",{className:"font-bold text-sm text-gray-900 w-1/3",children:"Final Calculated Cost:"}),(0,t.jsx)("span",{className:"text-sm font-bold text-gray-900",children:en(null!==(s=a.total_cost)&&void 0!==s?s:l)})]})})]})})]})}):null};var eo=a(23048),ec=a(30841),em=a(7310),ex=a.n(em),eu=a(12363);let eh={TEAM_ID:"Team ID",KEY_HASH:"Key Hash",REQUEST_ID:"Request ID",MODEL:"Model",USER_ID:"User ID",END_USER:"End User",STATUS:"Status",KEY_ALIAS:"Key Alias",ERROR_CODE:"Error Code"};var eg=a(59341),ep=a(12485),ej=a(18135),ef=a(35242),ev=a(29706),ey=a(77991),eb=a(92280);let eN="".concat("../ui/assets/","audit-logs-preview.png");function ew(e){let{userID:s,userRole:a,token:l,accessToken:d,isActive:x,premiumUser:u,allTeams:h}=e,[g,p]=(0,i.useState)(r()().subtract(24,"hours").format("YYYY-MM-DDTHH:mm")),j=(0,i.useRef)(null),f=(0,i.useRef)(null),[v,y]=(0,i.useState)(1),[N]=(0,i.useState)(50),[w,_]=(0,i.useState)({}),[k,S]=(0,i.useState)(""),[C,L]=(0,i.useState)(""),[D,M]=(0,i.useState)(""),[E,T]=(0,i.useState)("all"),[A,R]=(0,i.useState)("all"),[z,O]=(0,i.useState)(!1),[Z,I]=(0,i.useState)(!1),K=(0,n.a)({queryKey:["all_audit_logs",d,l,a,s,g],queryFn:async()=>{if(!d||!l||!a||!s)return[];let e=r()(g).utc().format("YYYY-MM-DD HH:mm:ss"),t=r()().utc().format("YYYY-MM-DD HH:mm:ss"),n=[],i=1,c=1;do{let s=await (0,o.uiAuditLogsCall)(d,e,t,i,50);n=n.concat(s.audit_logs),c=s.total_pages,i++}while(i<=c);return n},enabled:!!d&&!!l&&!!a&&!!s&&x,refetchInterval:5e3,refetchIntervalInBackground:!0}),H=(0,i.useCallback)(async e=>{if(d)try{let s=(await (0,o.keyListCall)(d,null,null,e,null,null,1,10)).keys.find(s=>s.key_alias===e);s?L(s.token):L("")}catch(e){console.error("Error fetching key hash for alias:",e),L("")}},[d]);(0,i.useEffect)(()=>{if(!d)return;let e=!1,s=!1;w["Team ID"]?k!==w["Team ID"]&&(S(w["Team ID"]),e=!0):""!==k&&(S(""),e=!0),w["Key Hash"]?C!==w["Key Hash"]&&(L(w["Key Hash"]),s=!0):w["Key Alias"]?H(w["Key Alias"]):""!==C&&(L(""),s=!0),(e||s)&&y(1)},[w,d,H,k,C]),(0,i.useEffect)(()=>{y(1)},[k,C,g,D,E,A]),(0,i.useEffect)(()=>{function e(e){j.current&&!j.current.contains(e.target)&&O(!1),f.current&&!f.current.contains(e.target)&&I(!1)}return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[]);let P=(0,i.useMemo)(()=>K.data?K.data.filter(e=>{var s,a,t,l,r,n,i;let d=!0,o=!0,c=!0,m=!0,x=!0;if(k){let r="string"==typeof e.before_value?null===(s=JSON.parse(e.before_value))||void 0===s?void 0:s.team_id:null===(a=e.before_value)||void 0===a?void 0:a.team_id,n="string"==typeof e.updated_values?null===(t=JSON.parse(e.updated_values))||void 0===t?void 0:t.team_id:null===(l=e.updated_values)||void 0===l?void 0:l.team_id;d=r===k||n===k}if(C)try{let s="string"==typeof e.before_value?JSON.parse(e.before_value):e.before_value,a="string"==typeof e.updated_values?JSON.parse(e.updated_values):e.updated_values,t=null==s?void 0:s.token,l=null==a?void 0:a.token;o="string"==typeof t&&t.includes(C)||"string"==typeof l&&l.includes(C)}catch(e){o=!1}if(D&&(c=null===(r=e.object_id)||void 0===r?void 0:r.toLowerCase().includes(D.toLowerCase())),"all"!==E&&(m=(null===(n=e.action)||void 0===n?void 0:n.toLowerCase())===E.toLowerCase()),"all"!==A){let s="";switch(A){case"keys":s="litellm_verificationtoken";break;case"teams":s="litellm_teamtable";break;case"users":s="litellm_usertable";break;default:s=A}x=(null===(i=e.table_name)||void 0===i?void 0:i.toLowerCase())===s}return d&&o&&c&&m&&x}):[],[K.data,k,C,D,E,A]),F=P.length,q=Math.ceil(F/N)||1,Y=(0,i.useMemo)(()=>{let e=(v-1)*N,s=e+N;return P.slice(e,s)},[P,v,N]),B=!K.data||0===K.data.length,V=(0,i.useCallback)(e=>{let{row:s}=e;return(0,t.jsx)(e=>{let{rowData:s}=e,{before_value:a,updated_values:l,table_name:r,action:n}=s,i=(e,s)=>{if(!e||0===Object.keys(e).length)return(0,t.jsx)(eb.x,{children:"N/A"});if(s){let s=Object.keys(e),a=["token","spend","max_budget"];if(s.every(e=>a.includes(e))&&s.length>0)return(0,t.jsxs)("div",{children:[s.includes("token")&&(0,t.jsxs)("p",{children:[(0,t.jsx)("strong",{children:"Token:"})," ",e.token||"N/A"]}),s.includes("spend")&&(0,t.jsxs)("p",{children:[(0,t.jsx)("strong",{children:"Spend:"})," ",void 0!==e.spend?"$".concat((0,m.pw)(e.spend,6)):"N/A"]}),s.includes("max_budget")&&(0,t.jsxs)("p",{children:[(0,t.jsx)("strong",{children:"Max Budget:"})," ",void 0!==e.max_budget?"$".concat((0,m.pw)(e.max_budget,6)):"N/A"]})]});if(e["No differing fields detected in 'before' state"]||e["No differing fields detected in 'updated' state"]||e["No fields changed"])return(0,t.jsx)(eb.x,{children:e[Object.keys(e)[0]]})}return(0,t.jsx)("pre",{className:"p-2 bg-gray-50 border rounded text-xs overflow-auto max-h-60",children:JSON.stringify(e,null,2)})},d=a,o=l;if(("updated"===n||"rotated"===n)&&a&&l&&("LiteLLM_TeamTable"===r||"LiteLLM_UserTable"===r||"LiteLLM_VerificationToken"===r)){let e={},s={};new Set([...Object.keys(a),...Object.keys(l)]).forEach(t=>{JSON.stringify(a[t])!==JSON.stringify(l[t])&&(a.hasOwnProperty(t)&&(e[t]=a[t]),l.hasOwnProperty(t)&&(s[t]=l[t]))}),Object.keys(a).forEach(t=>{l.hasOwnProperty(t)||e.hasOwnProperty(t)||(e[t]=a[t],s[t]=void 0)}),Object.keys(l).forEach(t=>{a.hasOwnProperty(t)||s.hasOwnProperty(t)||(s[t]=l[t],e[t]=void 0)}),d=Object.keys(e).length>0?e:{"No differing fields detected in 'before' state":"N/A"},o=Object.keys(s).length>0?s:{"No differing fields detected in 'updated' state":"N/A"},0===Object.keys(e).length&&0===Object.keys(s).length&&(d={"No fields changed":"N/A"},o={"No fields changed":"N/A"})}return(0,t.jsxs)("div",{className:"-mx-4 p-4 bg-slate-100 border-y border-slate-300 grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("h4",{className:"font-semibold mb-2 text-sm text-slate-700",children:"Before Value:"}),i(d,"LiteLLM_VerificationToken"===r)]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("h4",{className:"font-semibold mb-2 text-sm text-slate-700",children:"Updated Value:"}),i(o,"LiteLLM_VerificationToken"===r)]})]})},{rowData:s.original})},[]);if(!u)return(0,t.jsxs)("div",{style:{textAlign:"center",marginTop:"20px"},children:[(0,t.jsx)("h1",{style:{display:"block",marginBottom:"10px"},children:"✨ Enterprise Feature."}),(0,t.jsx)(eb.x,{style:{display:"block",marginBottom:"10px"},children:"This is a LiteLLM Enterprise feature, and requires a valid key to use."}),(0,t.jsx)(eb.x,{style:{display:"block",marginBottom:"20px",fontStyle:"italic"},children:"Here's a preview of what Audit Logs offer:"}),(0,t.jsx)("img",{src:eN,alt:"Audit Logs Preview",style:{maxWidth:"100%",maxHeight:"700px",borderRadius:"8px",boxShadow:"0 4px 8px rgba(0,0,0,0.1)",margin:"0 auto"},onError:e=>{console.error("Failed to load audit logs preview image"),e.target.style.display="none"}})]});let U=F>0?(v-1)*N+1:0,W=Math.min(v*N,F);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("div",{className:"flex items-center justify-between mb-4"}),(0,t.jsxs)("div",{className:"bg-white rounded-lg shadow",children:[(0,t.jsxs)("div",{className:"border-b px-6 py-4",children:[(0,t.jsx)("h1",{className:"text-xl font-semibold py-4",children:"Audit Logs"}),(0,t.jsx)(e=>{let{show:s}=e;return s?(0,t.jsxs)("div",{className:"bg-blue-50 border border-blue-200 rounded-lg p-4 flex items-start mb-6",children:[(0,t.jsx)("div",{className:"text-blue-500 mr-3 flex-shrink-0 mt-0.5",children:(0,t.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,t.jsx)("circle",{cx:"12",cy:"12",r:"10"}),(0,t.jsx)("line",{x1:"12",y1:"16",x2:"12",y2:"12"}),(0,t.jsx)("line",{x1:"12",y1:"8",x2:"12.01",y2:"8"})]})}),(0,t.jsxs)("div",{children:[(0,t.jsx)("h4",{className:"text-sm font-medium text-blue-800",children:"Audit Logs Not Available"}),(0,t.jsx)("p",{className:"text-sm text-blue-700 mt-1",children:"To enable audit logging, add the following configuration to your LiteLLM proxy configuration file:"}),(0,t.jsx)("pre",{className:"mt-2 bg-white p-3 rounded border border-blue-200 text-xs font-mono overflow-auto",children:"litellm_settings:\n store_audit_logs: true"}),(0,t.jsx)("p",{className:"text-xs text-blue-700 mt-2",children:"Note: This will only affect new requests after the configuration change and proxy restart."})]})]}):null},{show:B}),(0,t.jsxs)("div",{className:"flex flex-col md:flex-row items-start md:items-center justify-between space-y-4 md:space-y-0",children:[(0,t.jsx)("div",{className:"flex flex-wrap items-center gap-3",children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("div",{className:"flex items-center",children:(0,t.jsx)("input",{type:"text",placeholder:"Search by Object ID...",value:D,onChange:e=>M(e.target.value),className:"px-3 py-2 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"})}),(0,t.jsxs)("button",{onClick:()=>{K.refetch()},className:"px-3 py-2 text-sm border rounded-md hover:bg-gray-50 flex items-center gap-2",title:"Refresh data",children:[(0,t.jsx)("svg",{className:"w-4 h-4 ".concat(K.isFetching?"animate-spin":""),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"})}),(0,t.jsx)("span",{children:"Refresh"})]})]})}),(0,t.jsxs)("div",{className:"flex items-center space-x-4",children:[(0,t.jsxs)("div",{className:"relative",ref:j,children:[(0,t.jsx)("label",{htmlFor:"actionFilterDisplay",className:"mr-2 text-sm font-medium text-gray-700 sr-only",children:"Action:"}),(0,t.jsxs)("button",{id:"actionFilterDisplay",onClick:()=>O(!z),className:"px-3 py-2 text-sm border rounded-md hover:bg-gray-50 flex items-center gap-2 bg-white w-40 text-left justify-between",children:[(0,t.jsxs)("span",{children:["all"===E&&"All Actions","created"===E&&"Created","updated"===E&&"Updated","deleted"===E&&"Deleted","rotated"===E&&"Rotated"]}),(0,t.jsx)("svg",{className:"w-4 h-4 text-gray-500",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M19 9l-7 7-7-7"})})]}),z&&(0,t.jsx)("div",{className:"absolute left-0 mt-2 w-40 bg-white rounded-lg shadow-lg border p-1 z-50",children:(0,t.jsx)("div",{className:"space-y-1",children:[{label:"All Actions",value:"all"},{label:"Created",value:"created"},{label:"Updated",value:"updated"},{label:"Deleted",value:"deleted"},{label:"Rotated",value:"rotated"}].map(e=>(0,t.jsx)("button",{className:"w-full px-3 py-2 text-left text-sm hover:bg-gray-50 rounded-md ".concat(E===e.value?"bg-blue-50 text-blue-600 font-medium":"font-normal"),onClick:()=>{T(e.value),O(!1)},children:e.label},e.value))})})]}),(0,t.jsxs)("div",{className:"relative",ref:f,children:[(0,t.jsx)("label",{htmlFor:"tableFilterDisplay",className:"mr-2 text-sm font-medium text-gray-700 sr-only",children:"Table:"}),(0,t.jsxs)("button",{id:"tableFilterDisplay",onClick:()=>I(!Z),className:"px-3 py-2 text-sm border rounded-md hover:bg-gray-50 flex items-center gap-2 bg-white w-40 text-left justify-between",children:[(0,t.jsxs)("span",{children:["all"===A&&"All Tables","keys"===A&&"Keys","teams"===A&&"Teams","users"===A&&"Users"]}),(0,t.jsx)("svg",{className:"w-4 h-4 text-gray-500",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M19 9l-7 7-7-7"})})]}),Z&&(0,t.jsx)("div",{className:"absolute left-0 mt-2 w-40 bg-white rounded-lg shadow-lg border p-1 z-50",children:(0,t.jsx)("div",{className:"space-y-1",children:[{label:"All Tables",value:"all"},{label:"Keys",value:"keys"},{label:"Teams",value:"teams"},{label:"Users",value:"users"}].map(e=>(0,t.jsx)("button",{className:"w-full px-3 py-2 text-left text-sm hover:bg-gray-50 rounded-md ".concat(A===e.value?"bg-blue-50 text-blue-600 font-medium":"font-normal"),onClick:()=>{R(e.value),I(!1)},children:e.label},e.value))})})]}),(0,t.jsxs)("span",{className:"text-sm text-gray-700",children:["Showing ",K.isLoading?"...":U," -"," ",K.isLoading?"...":W," of"," ",K.isLoading?"...":F," results"]}),(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsxs)("span",{className:"text-sm text-gray-700",children:["Page ",K.isLoading?"...":v," of"," ",K.isLoading?"...":q]}),(0,t.jsx)("button",{onClick:()=>y(e=>Math.max(1,e-1)),disabled:K.isLoading||1===v,className:"px-3 py-1 text-sm border rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed",children:"Previous"}),(0,t.jsx)("button",{onClick:()=>y(e=>Math.min(q,e+1)),disabled:K.isLoading||v===q,className:"px-3 py-1 text-sm border rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed",children:"Next"})]})]})]})]}),(0,t.jsx)(c.w,{columns:b,data:Y,renderSubComponent:V,getRowCanExpand:()=>!0})]})]})}let e_=(e,s,a)=>{if(e)return"".concat(r()(s).format("MMM D, h:mm A")," - ").concat(r()(a).format("MMM D, h:mm A"));let t=r()(),l=r()(s),n=t.diff(l,"minutes");if(n>=0&&n<2)return"Last 1 Minute";if(n>=2&&n<16)return"Last 15 Minutes";if(n>=16&&n<61)return"Last Hour";let i=t.diff(l,"hours");return i>=1&&i<5?"Last 4 Hours":i>=5&&i<25?"Last 24 Hours":i>=25&&i<169?"Last 7 Days":"".concat(l.format("MMM D")," - ").concat(t.format("MMM D"))};var ek=a(9309),eS=a(30280),eC=a(44633),eL=a(86462),eD=a(49084),eM=a(71594),eE=a(24525),eT=a(19130);function eA(e){let{keys:s,totalCount:a,isLoading:l,isFetching:r,pageIndex:n,pageSize:d,onPageChange:o}=e,[c,x]=(0,i.useState)([{id:"deleted_at",desc:!0}]),[u,g]=(0,i.useState)({pageIndex:n,pageSize:d});i.useEffect(()=>{g({pageIndex:n,pageSize:d})},[n,d]);let p=[{id:"token",accessorKey:"token",header:"Key ID",size:150,maxSize:250,cell:e=>{let s=e.getValue();return(0,t.jsx)(h.Z,{title:s,children:(0,t.jsx)("span",{className:"font-mono text-blue-500 text-xs truncate block max-w-[250px]",children:s||"-"})})}},{id:"key_alias",accessorKey:"key_alias",header:"Key Alias",size:150,maxSize:200,cell:e=>{let s=e.getValue();return(0,t.jsx)(h.Z,{title:s,children:(0,t.jsx)("span",{className:"font-mono text-xs truncate block max-w-[200px]",children:null!=s?s:"-"})})}},{id:"team_alias",accessorKey:"team_alias",header:"Team Alias",size:120,maxSize:180,cell:e=>{let s=e.getValue();return(0,t.jsx)("span",{className:"truncate block max-w-[180px]",children:s||"-"})}},{id:"spend",accessorKey:"spend",header:"Spend (USD)",size:100,maxSize:140,cell:e=>(0,t.jsx)("span",{className:"block max-w-[140px]",children:(0,m.pw)(e.getValue(),4)})},{id:"max_budget",accessorKey:"max_budget",header:"Budget (USD)",size:110,maxSize:150,cell:e=>{let s=e.getValue();return(0,t.jsx)("span",{className:"block max-w-[150px]",children:null===s?"Unlimited":"$".concat((0,m.pw)(s))})}},{id:"user_email",accessorKey:"user_email",header:"User Email",size:160,maxSize:250,cell:e=>{let s=e.getValue();return(0,t.jsx)(h.Z,{title:s,children:(0,t.jsx)("span",{className:"font-mono text-xs truncate block max-w-[250px]",children:null!=s?s:"-"})})}},{id:"user_id",accessorKey:"user_id",header:"User ID",size:120,maxSize:200,cell:e=>{let s=e.getValue();return(0,t.jsx)(h.Z,{title:s||void 0,children:(0,t.jsx)("span",{className:"truncate block max-w-[200px]",children:s||"-"})})}},{id:"created_at",accessorKey:"created_at",header:"Created At",size:120,maxSize:140,cell:e=>{let s=e.getValue();return(0,t.jsx)("span",{className:"block max-w-[140px]",children:s?new Date(s).toLocaleDateString():"-"})}},{id:"created_by",accessorKey:"created_by",header:"Created By",size:120,maxSize:180,cell:e=>{let s=e.row.original.created_by;return(0,t.jsx)(h.Z,{title:s||void 0,children:(0,t.jsx)("span",{className:"truncate block max-w-[180px]",children:s||"-"})})}},{id:"deleted_at",accessorKey:"deleted_at",header:"Deleted At",size:120,maxSize:140,cell:e=>{let s=e.row.original.deleted_at;return(0,t.jsx)("span",{className:"block max-w-[140px]",children:s?new Date(s).toLocaleDateString():"-"})}},{id:"deleted_by",accessorKey:"deleted_by",header:"Deleted By",size:120,maxSize:180,cell:e=>{let s=e.row.original.deleted_by;return(0,t.jsx)(h.Z,{title:s||void 0,children:(0,t.jsx)("span",{className:"truncate block max-w-[180px]",children:s||"-"})})}}],j=(0,eM.b7)({data:s,columns:p,columnResizeMode:"onChange",columnResizeDirection:"ltr",state:{sorting:c,pagination:u},onSortingChange:x,onPaginationChange:e=>{let s="function"==typeof e?e(u):e;g(s),o(s.pageIndex)},getCoreRowModel:(0,eE.sC)(),getSortedRowModel:(0,eE.tj)(),getPaginationRowModel:(0,eE.G_)(),enableSorting:!0,manualSorting:!1,manualPagination:!0,pageCount:Math.ceil(a/d)}),{pageIndex:f}=j.getState().pagination,v=f*d+1,y="".concat(v," - ").concat(Math.min((f+1)*d,a));return(0,t.jsx)("div",{className:"w-full h-full overflow-hidden",children:(0,t.jsxs)("div",{className:"border-b py-4 flex-1 overflow-hidden",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between w-full mb-4",children:[l||r?(0,t.jsx)("span",{className:"inline-flex text-sm text-gray-700",children:"Loading..."}):(0,t.jsxs)("span",{className:"inline-flex text-sm text-gray-700",children:["Showing ",y," of ",a," results"]}),(0,t.jsxs)("div",{className:"inline-flex items-center gap-2",children:[l||r?(0,t.jsx)("span",{className:"text-sm text-gray-700",children:"Loading..."}):(0,t.jsxs)("span",{className:"text-sm text-gray-700",children:["Page ",f+1," of ",j.getPageCount()]}),(0,t.jsx)("button",{onClick:()=>j.previousPage(),disabled:l||r||!j.getCanPreviousPage(),className:"px-3 py-1 text-sm border rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed",children:"Previous"}),(0,t.jsx)("button",{onClick:()=>j.nextPage(),disabled:l||r||!j.getCanNextPage(),className:"px-3 py-1 text-sm border rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed",children:"Next"})]})]}),(0,t.jsx)("div",{className:"h-[75vh] overflow-auto",children:(0,t.jsx)("div",{className:"rounded-lg custom-border relative",children:(0,t.jsx)("div",{className:"overflow-x-auto",children:(0,t.jsxs)(eT.iA,{className:"[&_td]:py-0.5 [&_th]:py-1",style:{width:j.getCenterTotalSize()},children:[(0,t.jsx)(eT.ss,{children:j.getHeaderGroups().map(e=>(0,t.jsx)(eT.SC,{children:e.headers.map(e=>(0,t.jsx)(eT.xs,{"data-header-id":e.id,className:"py-1 h-8 relative hover:bg-gray-50",style:{width:e.getSize(),maxWidth:e.column.columnDef.maxSize,position:"relative"},onMouseEnter:()=>{let s=document.querySelector('[data-header-id="'.concat(e.id,'"] .resizer'));s&&(s.style.opacity="0.5")},onMouseLeave:()=>{let s=document.querySelector('[data-header-id="'.concat(e.id,'"] .resizer'));s&&!e.column.getIsResizing()&&(s.style.opacity="0")},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,eM.ie)(e.column.columnDef.header,e.getContext())}),(0,t.jsx)("div",{className:"w-4",children:e.column.getIsSorted()?({asc:(0,t.jsx)(eC.Z,{className:"h-4 w-4 text-blue-500"}),desc:(0,t.jsx)(eL.Z,{className:"h-4 w-4 text-blue-500"})})[e.column.getIsSorted()]:(0,t.jsx)(eD.Z,{className:"h-4 w-4 text-gray-400"})}),(0,t.jsx)("div",{onDoubleClick:()=>e.column.resetSize(),onMouseDown:e.getResizeHandler(),onTouchStart:e.getResizeHandler(),className:"resizer ".concat(j.options.columnResizeDirection," ").concat(e.column.getIsResizing()?"isResizing":""),style:{position:"absolute",right:0,top:0,height:"100%",width:"5px",background:e.column.getIsResizing()?"#3b82f6":"transparent",cursor:"col-resize",userSelect:"none",touchAction:"none",opacity:e.column.getIsResizing()?1:0}})]})},e.id))},e.id))}),(0,t.jsx)(eT.RM,{children:l||r?(0,t.jsx)(eT.SC,{children:(0,t.jsx)(eT.pj,{colSpan:p.length,className:"h-8 text-center",children:(0,t.jsx)("div",{className:"text-center text-gray-500",children:(0,t.jsx)("p",{children:"\uD83D\uDE85 Loading keys..."})})})}):s.length>0?j.getRowModel().rows.map(e=>(0,t.jsx)(eT.SC,{className:"h-8",children:e.getVisibleCells().map(e=>(0,t.jsx)(eT.pj,{style:{width:e.column.getSize(),maxWidth:e.column.columnDef.maxSize,whiteSpace:"pre-wrap",overflow:"hidden"},className:"py-0.5 max-h-8 overflow-hidden text-ellipsis whitespace-nowrap",children:(0,eM.ie)(e.column.columnDef.cell,e.getContext())},e.id))},e.id)):(0,t.jsx)(eT.SC,{children:(0,t.jsx)(eT.pj,{colSpan:p.length,className:"h-8 text-center",children:(0,t.jsx)("div",{className:"text-center text-gray-500",children:(0,t.jsx)("p",{children:"No deleted keys found"})})})})})]})})})})]})})}function eR(){let[e,s]=(0,i.useState)(0),[a]=(0,i.useState)(50),{data:l,isPending:r,isFetching:n}=(0,eS.Tv)(e+1,a);return(0,t.jsx)(eA,{keys:(null==l?void 0:l.keys)||[],totalCount:(null==l?void 0:l.total_count)||0,isLoading:r,isFetching:n,pageIndex:e,pageSize:a,onPageChange:s})}var ez=a(47359),eO=a(21626),eZ=a(97214),eI=a(28241),eK=a(58834),eH=a(69552),eP=a(71876),eF=a(46468);function eq(e){let{teams:s,isLoading:a,isFetching:l}=e,[r,n]=(0,i.useState)([{id:"deleted_at",desc:!0}]),d=[{id:"team_alias",accessorKey:"team_alias",header:"Team Name",size:150,maxSize:200,cell:e=>{let s=e.getValue();return(0,t.jsx)(h.Z,{title:s||void 0,children:(0,t.jsx)("span",{className:"truncate block max-w-[200px]",children:s||"-"})})}},{id:"team_id",accessorKey:"team_id",header:"Team ID",size:150,maxSize:250,cell:e=>{let s=e.getValue();return(0,t.jsx)(h.Z,{title:s,children:(0,t.jsx)("span",{className:"font-mono text-blue-500 text-xs truncate block max-w-[250px]",children:s||"-"})})}},{id:"created_at",accessorKey:"created_at",header:"Created",size:120,maxSize:140,cell:e=>{let s=e.getValue();return(0,t.jsx)("span",{className:"block max-w-[140px]",children:s?new Date(s).toLocaleDateString():"-"})}},{id:"spend",accessorKey:"spend",header:"Spend (USD)",size:100,maxSize:140,cell:e=>{let s=e.row.original.spend;return(0,t.jsx)("span",{className:"block max-w-[140px]",children:void 0!==s?(0,m.pw)(s,4):"-"})}},{id:"max_budget",accessorKey:"max_budget",header:"Budget (USD)",size:110,maxSize:150,cell:e=>{let s=e.getValue();return(0,t.jsx)("span",{className:"block max-w-[150px]",children:null==s?"No limit":"$".concat((0,m.pw)(s))})}},{id:"models",accessorKey:"models",header:"Models",size:200,maxSize:300,cell:e=>{let s=e.getValue();return Array.isArray(s)&&0!==s.length?(0,t.jsxs)("div",{className:"flex flex-wrap gap-1 max-w-[300px]",children:[s.slice(0,3).map((e,s)=>"all-proxy-models"===e?(0,t.jsx)(x.Z,{size:"xs",color:"red",children:(0,t.jsx)(T.Z,{children:"All Proxy Models"})},s):(0,t.jsx)(x.Z,{size:"xs",color:"blue",children:(0,t.jsx)(T.Z,{children:e.length>30?"".concat((0,eF.W0)(e).slice(0,30),"..."):(0,eF.W0)(e)})},s)),s.length>3&&(0,t.jsx)(x.Z,{size:"xs",color:"gray",children:(0,t.jsxs)(T.Z,{children:["+",s.length-3," ",s.length-3==1?"more model":"more models"]})})]}):(0,t.jsx)(x.Z,{size:"xs",color:"red",children:(0,t.jsx)(T.Z,{children:"All Proxy Models"})})}},{id:"organization_id",accessorKey:"organization_id",header:"Organization",size:150,maxSize:200,cell:e=>{let s=e.getValue();return(0,t.jsx)(h.Z,{title:s||void 0,children:(0,t.jsx)("span",{className:"truncate block max-w-[200px]",children:s||"-"})})}},{id:"deleted_at",accessorKey:"deleted_at",header:"Deleted At",size:120,maxSize:140,cell:e=>{let s=e.row.original.deleted_at;return(0,t.jsx)("span",{className:"block max-w-[140px]",children:s?new Date(s).toLocaleDateString():"-"})}},{id:"deleted_by",accessorKey:"deleted_by",header:"Deleted By",size:120,maxSize:180,cell:e=>{let s=e.row.original.deleted_by;return(0,t.jsx)(h.Z,{title:s||void 0,children:(0,t.jsx)("span",{className:"truncate block max-w-[180px]",children:s||"-"})})}}],o=(0,eM.b7)({data:s,columns:d,columnResizeMode:"onChange",columnResizeDirection:"ltr",state:{sorting:r},onSortingChange:n,getCoreRowModel:(0,eE.sC)(),getSortedRowModel:(0,eE.tj)(),enableSorting:!0,manualSorting:!1});return(0,t.jsx)("div",{className:"w-full h-full overflow-hidden",children:(0,t.jsxs)("div",{className:"border-b py-4 flex-1 overflow-hidden",children:[(0,t.jsx)("div",{className:"flex items-center justify-between w-full mb-4",children:a||l?(0,t.jsx)("span",{className:"inline-flex text-sm text-gray-700",children:"Loading..."}):(0,t.jsxs)("span",{className:"inline-flex text-sm text-gray-700",children:["Showing ",s.length," ",1===s.length?"team":"teams"]})}),(0,t.jsx)("div",{className:"h-[75vh] overflow-auto",children:(0,t.jsx)("div",{className:"rounded-lg custom-border relative",children:(0,t.jsx)("div",{className:"overflow-x-auto",children:(0,t.jsxs)(eO.Z,{className:"[&_td]:py-0.5 [&_th]:py-1",style:{width:o.getCenterTotalSize()},children:[(0,t.jsx)(eK.Z,{children:o.getHeaderGroups().map(e=>(0,t.jsx)(eP.Z,{children:e.headers.map(e=>(0,t.jsx)(eH.Z,{"data-header-id":e.id,className:"py-1 h-8 relative hover:bg-gray-50",style:{width:e.getSize(),maxWidth:e.column.columnDef.maxSize,position:"relative"},onMouseEnter:()=>{let s=document.querySelector('[data-header-id="'.concat(e.id,'"] .resizer'));s&&(s.style.opacity="0.5")},onMouseLeave:()=>{let s=document.querySelector('[data-header-id="'.concat(e.id,'"] .resizer'));s&&!e.column.getIsResizing()&&(s.style.opacity="0")},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,eM.ie)(e.column.columnDef.header,e.getContext())}),(0,t.jsx)("div",{className:"w-4",children:e.column.getIsSorted()?({asc:(0,t.jsx)(eC.Z,{className:"h-4 w-4 text-blue-500"}),desc:(0,t.jsx)(eL.Z,{className:"h-4 w-4 text-blue-500"})})[e.column.getIsSorted()]:(0,t.jsx)(eD.Z,{className:"h-4 w-4 text-gray-400"})}),(0,t.jsx)("div",{onDoubleClick:()=>e.column.resetSize(),onMouseDown:e.getResizeHandler(),onTouchStart:e.getResizeHandler(),className:"resizer ".concat(o.options.columnResizeDirection," ").concat(e.column.getIsResizing()?"isResizing":""),style:{position:"absolute",right:0,top:0,height:"100%",width:"5px",background:e.column.getIsResizing()?"#3b82f6":"transparent",cursor:"col-resize",userSelect:"none",touchAction:"none",opacity:e.column.getIsResizing()?1:0}})]})},e.id))},e.id))}),(0,t.jsx)(eZ.Z,{children:a||l?(0,t.jsx)(eP.Z,{children:(0,t.jsx)(eI.Z,{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:"\uD83D\uDE85 Loading teams..."})})})}):s.length>0?o.getRowModel().rows.map(e=>(0,t.jsx)(eP.Z,{className:"h-8",children:e.getVisibleCells().map(e=>(0,t.jsx)(eI.Z,{style:{width:e.column.getSize(),maxWidth:e.column.columnDef.maxSize,whiteSpace:"pre-wrap",overflow:"hidden"},className:"py-0.5 max-h-8 overflow-hidden text-ellipsis whitespace-nowrap",children:(0,eM.ie)(e.column.columnDef.cell,e.getContext())},e.id))},e.id)):(0,t.jsx)(eP.Z,{children:(0,t.jsx)(eI.Z,{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:"No deleted teams found"})})})})})]})})})})]})})}function eY(){let{data:e,isPending:s,isFetching:a}=(0,ez.iN)(1,100);return(0,t.jsx)(eq,{teams:e||[],isLoading:s,isFetching:a})}var eB=a(91027);function eV(e){var s,a,l;let{accessToken:m,token:x,userRole:u,userID:h,allTeams:g,premiumUser:p}=e,[j,f]=(0,i.useState)(""),[y,b]=(0,i.useState)(!1),[w,_]=(0,i.useState)(!1),[k,S]=(0,i.useState)(1),[L]=(0,i.useState)(50),M=(0,i.useRef)(null),E=(0,i.useRef)(null),T=(0,i.useRef)(null),[A,R]=(0,i.useState)(r()().subtract(24,"hours").format("YYYY-MM-DDTHH:mm")),[z,O]=(0,i.useState)(r()().format("YYYY-MM-DDTHH:mm")),[Z,K]=(0,i.useState)(!1),[H,P]=(0,i.useState)(!1),[F,q]=(0,i.useState)(""),[Y,B]=(0,i.useState)(""),[V,U]=(0,i.useState)(""),[W,J]=(0,i.useState)(""),[G,Q]=(0,i.useState)(""),[$,X]=(0,i.useState)(null),[ee,es]=(0,i.useState)(null),[ea,et]=(0,i.useState)(""),[el,er]=(0,i.useState)(""),[en,ei]=(0,i.useState)(u&&C.lo.includes(u)),[ed,em]=(0,i.useState)("request logs"),[eb,eN]=(0,i.useState)(null),[ek,eS]=(0,i.useState)(null),eC=(0,d.NL)(),[eL,eD]=(0,i.useState)(()=>{let e=sessionStorage.getItem("isLiveTail");return null===e||JSON.parse(e)});(0,i.useEffect)(()=>{sessionStorage.setItem("isLiveTail",JSON.stringify(eL))},[eL]);let[eM,eE]=(0,i.useState)({value:24,unit:"hours"});(0,i.useEffect)(()=>{(async()=>{ee&&m&&X({...(await (0,o.keyInfoV1Call)(m,ee)).info,token:ee,api_key:ee})})()},[ee,m]),(0,i.useEffect)(()=>{function e(e){M.current&&!M.current.contains(e.target)&&_(!1),E.current&&!E.current.contains(e.target)&&b(!1),T.current&&!T.current.contains(e.target)&&P(!1)}return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[]),(0,i.useEffect)(()=>{u&&C.lo.includes(u)&&ei(!0)},[u]);let eT=(0,n.a)({queryKey:["logs","table",k,L,A,z,V,W,en?h:null,ea,G],queryFn:async()=>{if(!m||!x||!u||!h)return{data:[],total:0,page:1,page_size:L,total_pages:0};let e=r()(A).utc().format("YYYY-MM-DD HH:mm:ss"),s=Z?r()(z).utc().format("YYYY-MM-DD HH:mm:ss"):r()().utc().format("YYYY-MM-DD HH:mm:ss"),a=await (0,o.uiSpendLogsCall)(m,W||void 0,V||void 0,void 0,e,s,k,L,en?h:void 0,el,ea,G);return await N(a.data,e,m,eC),a.data=a.data.map(s=>{let a=eC.getQueryData(["logDetails",s.request_id,e]);return(null==a?void 0:a.messages)&&(null==a?void 0:a.response)&&(s.messages=a.messages,s.response=a.response),s}),a},enabled:!!m&&!!x&&!!u&&!!h&&"request logs"===ed,refetchInterval:!!eL&&1===k&&15e3,refetchIntervalInBackground:!0}),eA=eT.data||{data:[],total:0,page:1,page_size:L||10,total_pages:1},{filters:ez,filteredLogs:eO,allTeams:eZ,allKeyAliases:eI,handleFilterChange:eK,handleFilterReset:eH}=function(e){let{logs:s,accessToken:a,startTime:t,endTime:l,pageSize:d=eu.d,isCustomDate:c,setCurrentPage:m,userID:x,userRole:u}=e,h=(0,i.useMemo)(()=>({[eh.TEAM_ID]:"",[eh.KEY_HASH]:"",[eh.REQUEST_ID]:"",[eh.MODEL]:"",[eh.USER_ID]:"",[eh.END_USER]:"",[eh.STATUS]:"",[eh.KEY_ALIAS]:"",[eh.ERROR_CODE]:""}),[]),[g,p]=(0,i.useState)(h),[j,f]=(0,i.useState)({data:[],total:0,page:1,page_size:50,total_pages:0}),v=(0,i.useRef)(0),y=(0,i.useCallback)(async function(e){let s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;if(!a)return;console.log("Filters being sent to API:",e);let n=Date.now();v.current=n;let i=r()(t).utc().format("YYYY-MM-DD HH:mm:ss"),m=c?r()(l).utc().format("YYYY-MM-DD HH:mm:ss"):r()().utc().format("YYYY-MM-DD HH:mm:ss");try{let t=await (0,o.uiSpendLogsCall)(a,e[eh.KEY_HASH]||void 0,e[eh.TEAM_ID]||void 0,e[eh.REQUEST_ID]||void 0,i,m,s,d,e[eh.USER_ID]||void 0,e[eh.END_USER]||void 0,e[eh.STATUS]||void 0,e[eh.MODEL]||void 0,e[eh.KEY_ALIAS]||void 0,e[eh.ERROR_CODE]||void 0);n===v.current&&t.data&&f(t)}catch(e){console.error("Error searching users:",e)}},[a,t,l,c,d]),b=(0,i.useMemo)(()=>ex()((e,s)=>y(e,s),300),[y]);(0,i.useEffect)(()=>()=>b.cancel(),[b]);let N=(0,n.a)({queryKey:["allKeys"],queryFn:async()=>{if(!a)throw Error("Access token required");return await (0,ec.LO)(a)},enabled:!!a}).data||[],w=(0,i.useMemo)(()=>!!(g[eh.KEY_ALIAS]||g[eh.KEY_HASH]||g[eh.REQUEST_ID]||g[eh.USER_ID]||g[eh.END_USER]||g[eh.ERROR_CODE]),[g]),_=(0,i.useMemo)(()=>{if(!s||!s.data)return{data:[],total:0,page:1,page_size:50,total_pages:0};if(w)return s;let e=[...s.data];return g[eh.TEAM_ID]&&(e=e.filter(e=>e.team_id===g[eh.TEAM_ID])),g[eh.STATUS]&&(e=e.filter(e=>"success"===g[eh.STATUS]?!e.status||"success"===e.status:e.status===g[eh.STATUS])),g[eh.MODEL]&&(e=e.filter(e=>e.model===g[eh.MODEL])),g[eh.KEY_HASH]&&(e=e.filter(e=>e.api_key===g[eh.KEY_HASH])),g[eh.END_USER]&&(e=e.filter(e=>e.end_user===g[eh.END_USER])),g[eh.ERROR_CODE]&&(e=e.filter(e=>{let s=(e.metadata||{}).error_information;return s&&s.error_code===g[eh.ERROR_CODE]})),{data:e,total:s.total,page:s.page,page_size:s.page_size,total_pages:s.total_pages}},[s,g,w]),k=(0,i.useMemo)(()=>w?j&&j.data&&j.data.length>0?j:s||{data:[],total:0,page:1,page_size:50,total_pages:0}:_,[w,j,_,s]),{data:S}=(0,n.a)({queryKey:["allTeamsForLogFilters",a],queryFn:async()=>a&&await (0,ec.IE)(a)||[],enabled:!!a});return{filters:g,filteredLogs:k,allKeyAliases:N,allTeams:S,handleFilterChange:e=>{p(s=>{let a={...s,...e};for(let e of Object.keys(h))e in a||(a[e]=h[e]);return JSON.stringify(a)!==JSON.stringify(s)&&(m(1),b(a,1)),a})},handleFilterReset:()=>{p(h),f({data:[],total:0,page:1,page_size:50,total_pages:0}),b(h,1)}}}({logs:eA,accessToken:m,startTime:A,endTime:z,pageSize:L,isCustomDate:Z,setCurrentPage:S,userID:h,userRole:u}),eP=(0,i.useCallback)(async e=>{if(m)try{let s=(await (0,o.keyListCall)(m,null,null,e,null,null,k,L)).keys.find(s=>s.key_alias===e);s&&J(s.token)}catch(e){console.error("Error fetching key hash for alias:",e)}},[m,k,L]);(0,i.useEffect)(()=>{m&&(ez["Team ID"]?U(ez["Team ID"]):U(""),et(ez.Status||""),Q(ez.Model||""),er(ez["End User"]||""),ez["Key Hash"]?J(ez["Key Hash"]):ez["Key Alias"]?eP(ez["Key Alias"]):J(""))},[ez,m,eP]);let eF=(0,n.a)({queryKey:["sessionLogs",ek],queryFn:async()=>{if(!m||!ek)return{data:[],total:0,page:1,page_size:50,total_pages:1};let e=await (0,o.sessionSpendLogsCall)(m,ek);return{data:e.data||e||[],total:(e.data||e||[]).length,page:1,page_size:1e3,total_pages:1}},enabled:!!m&&!!ek});if((0,i.useEffect)(()=>{var e;(null===(e=eT.data)||void 0===e?void 0:e.data)&&eb&&!eT.data.data.some(e=>e.request_id===eb)&&eN(null)},[null===(s=eT.data)||void 0===s?void 0:s.data,eb]),!m||!x||!u||!h)return null;let eq=eO.data.filter(e=>!j||e.request_id.includes(j)||e.model.includes(j)||e.user&&e.user.includes(j)).map(e=>({...e,duration:(Date.parse(e.endTime)-Date.parse(e.startTime))/1e3,onKeyHashClick:e=>es(e),onSessionClick:e=>{e&&eS(e)}}))||[],eV=(null===(l=eF.data)||void 0===l?void 0:null===(a=l.data)||void 0===a?void 0:a.map(e=>({...e,onKeyHashClick:e=>es(e),onSessionClick:e=>{}})))||[],eW=function(e){let s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",a=new Set;return e.forEach(e=>{let t=e.metadata||{};if("failure"===t.status&&t.error_information){let e=t.error_information.error_code;e&&(!s||e.toLowerCase().includes(s.toLowerCase()))&&a.add(e)}}),Array.from(a).map(e=>({label:e,value:e}))},eJ=[{name:"Team ID",label:"Team ID",isSearchable:!0,searchFn:async e=>g&&0!==g.length?g.filter(s=>s.team_id.toLowerCase().includes(e.toLowerCase())||s.team_alias&&s.team_alias.toLowerCase().includes(e.toLowerCase())).map(e=>({label:"".concat(e.team_alias||e.team_id," (").concat(e.team_id,")"),value:e.team_id})):[]},{name:"Status",label:"Status",isSearchable:!1,options:[{label:"Success",value:"success"},{label:"Failure",value:"failure"}]},{name:"Model",label:"Model",isSearchable:!1},{name:"Key Alias",label:"Key Alias",isSearchable:!0,searchFn:async e=>m?(await (0,ec.LO)(m)).filter(s=>s.toLowerCase().includes(e.toLowerCase())).map(e=>({label:e,value:e})):[]},{name:"End User",label:"End User",isSearchable:!0,searchFn:async e=>{if(!m)return[];let s=await (0,o.allEndUsersCall)(m);return((null==s?void 0:s.map(e=>e.user_id))||[]).filter(s=>s.toLowerCase().includes(e.toLowerCase())).map(e=>({label:e,value:e}))}},{name:"Error Code",label:"Error Code",isSearchable:!0,searchFn:async e=>eW(eA.data,e)},{name:"Key Hash",label:"Key Hash",isSearchable:!1}];if(ek&&eF.data)return(0,t.jsx)("div",{className:"w-full p-6",children:(0,t.jsx)(I,{sessionId:ek,logs:eF.data.data,onBack:()=>eS(null)})});let eG=[{label:"Last 15 Minutes",value:15,unit:"minutes"},{label:"Last Hour",value:1,unit:"hours"},{label:"Last 4 Hours",value:4,unit:"hours"},{label:"Last 24 Hours",value:24,unit:"hours"},{label:"Last 7 Days",value:7,unit:"days"}],eQ=eG.find(e=>e.value===eM.value&&e.unit===eM.unit),e$=Z?e_(Z,A,z):null==eQ?void 0:eQ.label;return(0,t.jsx)("div",{className:"w-full max-w-screen p-6 overflow-x-hidden box-border",children:(0,t.jsxs)(ej.Z,{defaultIndex:0,onIndexChange:e=>em(0===e?"request logs":"audit logs"),children:[(0,t.jsxs)(ef.Z,{children:[(0,t.jsx)(ep.Z,{children:"Request Logs"}),(0,t.jsx)(ep.Z,{children:"Audit Logs"}),(0,t.jsx)(ep.Z,{children:(0,t.jsxs)(t.Fragment,{children:["Deleted Keys ",(0,t.jsx)(eB.Z,{})]})}),(0,t.jsx)(ep.Z,{children:(0,t.jsxs)(t.Fragment,{children:["Deleted Teams ",(0,t.jsx)(eB.Z,{})]})})]}),(0,t.jsxs)(ey.Z,{children:[(0,t.jsxs)(ev.Z,{children:[(0,t.jsx)("div",{className:"flex items-center justify-between mb-4",children:(0,t.jsx)("h1",{className:"text-xl font-semibold",children:ek?(0,t.jsxs)(t.Fragment,{children:["Session: ",(0,t.jsx)("span",{className:"font-mono",children:ek}),(0,t.jsx)("button",{className:"ml-4 px-3 py-1 text-sm border rounded hover:bg-gray-50",onClick:()=>eS(null),children:"← Back to All Logs"})]}):"Request Logs"})}),$&&ee&&$.api_key===ee?(0,t.jsx)(D.Z,{keyId:ee,keyData:$,teams:g,onClose:()=>es(null),backButtonText:"Back to Logs"}):ek?(0,t.jsx)("div",{className:"bg-white rounded-lg shadow",children:(0,t.jsx)(c.w,{columns:v,data:eV,renderSubComponent:eU,getRowCanExpand:()=>!0})}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(eo.Z,{options:eJ,onApplyFilters:eK,onResetFilters:eH}),(0,t.jsxs)("div",{className:"bg-white rounded-lg shadow w-full max-w-full box-border",children:[(0,t.jsx)("div",{className:"border-b px-6 py-4 w-full max-w-full box-border",children:(0,t.jsxs)("div",{className:"flex flex-col md:flex-row items-start md:items-center justify-between space-y-4 md:space-y-0 w-full max-w-full box-border",children:[(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-3 w-full max-w-full box-border",children:[(0,t.jsxs)("div",{className:"relative w-64 min-w-0 flex-shrink-0",children:[(0,t.jsx)("input",{type:"text",placeholder:"Search by Request ID",className:"w-full px-3 py-2 pl-8 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",value:j,onChange:e=>f(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)("div",{className:"flex items-center gap-2 min-w-0 flex-shrink",children:[(0,t.jsxs)("div",{className:"relative z-50",ref:T,children:[(0,t.jsxs)("button",{onClick:()=>P(!H),className:"px-3 py-2 text-sm border rounded-md hover:bg-gray-50 flex items-center gap-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:"M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"})}),e$]}),H&&(0,t.jsx)("div",{className:"absolute right-0 mt-2 w-64 bg-white rounded-lg shadow-lg border p-2 z-50",children:(0,t.jsxs)("div",{className:"space-y-1",children:[eG.map(e=>(0,t.jsx)("button",{className:"w-full px-3 py-2 text-left text-sm hover:bg-gray-50 rounded-md ".concat(e$===e.label?"bg-blue-50 text-blue-600":""),onClick:()=>{O(r()().format("YYYY-MM-DDTHH:mm")),R(r()().subtract(e.value,e.unit).format("YYYY-MM-DDTHH:mm")),eE({value:e.value,unit:e.unit}),K(!1),P(!1)},children:e.label},e.label)),(0,t.jsx)("div",{className:"border-t my-2"}),(0,t.jsx)("button",{className:"w-full px-3 py-2 text-left text-sm hover:bg-gray-50 rounded-md ".concat(Z?"bg-blue-50 text-blue-600":""),onClick:()=>K(!Z),children:"Custom Range"})]})})]}),(0,t.jsx)(()=>(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("span",{className:"text-sm font-medium text-gray-900",children:"Live Tail"}),(0,t.jsx)(eg.Z,{color:"green",checked:eL,defaultChecked:!0,onChange:eD})]}),{}),(0,t.jsxs)("button",{onClick:()=>{eT.refetch()},className:"px-3 py-2 text-sm border rounded-md hover:bg-gray-50 flex items-center gap-2",title:"Refresh data",children:[(0,t.jsx)("svg",{className:"w-4 h-4 ".concat(eT.isFetching?"animate-spin":""),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"})}),(0,t.jsx)("span",{children:"Refresh"})]})]}),Z&&(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("div",{children:(0,t.jsx)("input",{type:"datetime-local",value:A,onChange:e=>{R(e.target.value),S(1)},className:"px-3 py-2 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"})}),(0,t.jsx)("span",{className:"text-gray-500",children:"to"}),(0,t.jsx)("div",{children:(0,t.jsx)("input",{type:"datetime-local",value:z,onChange:e=>{O(e.target.value),S(1)},className:"px-3 py-2 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"})})]})]}),(0,t.jsxs)("div",{className:"flex items-center space-x-4",children:[(0,t.jsxs)("span",{className:"text-sm text-gray-700 whitespace-nowrap",children:["Showing ",eT.isLoading?"...":eO?(k-1)*L+1:0," -"," ",eT.isLoading?"...":eO?Math.min(k*L,eO.total):0," ","of ",eT.isLoading?"...":eO?eO.total:0," results"]}),(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsxs)("span",{className:"text-sm text-gray-700 min-w-[90px]",children:["Page ",eT.isLoading?"...":k," of"," ",eT.isLoading?"...":eO?eO.total_pages:1]}),(0,t.jsx)("button",{onClick:()=>S(e=>Math.max(1,e-1)),disabled:eT.isLoading||1===k,className:"px-3 py-1 text-sm border rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed",children:"Previous"}),(0,t.jsx)("button",{onClick:()=>S(e=>Math.min(eO.total_pages||1,e+1)),disabled:eT.isLoading||k===(eO.total_pages||1),className:"px-3 py-1 text-sm border rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed",children:"Next"})]})]})]})}),eL&&1===k&&(0,t.jsxs)("div",{className:"mb-4 px-4 py-2 bg-green-50 border border-greem-200 rounded-md flex items-center justify-between",children:[(0,t.jsx)("div",{className:"flex items-center gap-2",children:(0,t.jsx)("span",{className:"text-sm text-green-700",children:"Auto-refreshing every 15 seconds"})}),(0,t.jsx)("button",{onClick:()=>eD(!1),className:"text-sm text-green-600 hover:text-green-800",children:"Stop"})]}),(0,t.jsx)(c.w,{columns:v,data:eq,renderSubComponent:eU,getRowCanExpand:()=>!0})]})]})]}),(0,t.jsx)(ev.Z,{children:(0,t.jsx)(ew,{userID:h,userRole:u,token:x,accessToken:m,isActive:"audit logs"===ed,premiumUser:p,allTeams:g})}),(0,t.jsx)(ev.Z,{children:(0,t.jsx)(eR,{})}),(0,t.jsx)(ev.Z,{children:(0,t.jsx)(eY,{})})]})]})})}function eU(e){var s,a,l,r,n,i,d,o,c,x,u,g;let{row:p}=e,j=e=>{if("string"==typeof e)try{return JSON.parse(e)}catch(e){}return e},f=p.original.metadata||{},v="failure"===f.status,y=v?f.error_information:null,b=p.original.messages&&(Array.isArray(p.original.messages)?p.original.messages.length>0:Object.keys(p.original.messages).length>0),N=p.original.response&&Object.keys(j(p.original.response)).length>0,w=f.vector_store_request_metadata&&Array.isArray(f.vector_store_request_metadata)&&f.vector_store_request_metadata.length>0,_=null===(s=p.original.metadata)||void 0===s?void 0:s.guardrail_information,C=Array.isArray(_)?_:_?[_]:[],D=C.length>0,M=C.reduce((e,s)=>{let a=null==s?void 0:s.masked_entity_count;return a?e+Object.values(a).reduce((e,s)=>"number"==typeof s?e+s:e,0):e},0),E=1===C.length?null!==(g=null===(a=C[0])||void 0===a?void 0:a.guardrail_name)&&void 0!==g?g:"-":C.length>1?"".concat(C.length," guardrails"):"-",T=(0,ek.aS)(p.original.request_id,64);return(0,t.jsxs)("div",{className:"p-6 bg-gray-50 space-y-6 w-full max-w-full overflow-hidden box-border",children:[(0,t.jsxs)("div",{className:"bg-white rounded-lg shadow w-full max-w-full overflow-hidden",children:[(0,t.jsx)("div",{className:"p-4 border-b",children:(0,t.jsx)("h3",{className:"text-lg font-medium",children:"Request Details"})}),(0,t.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4 p-4 w-full max-w-full overflow-hidden",children:[(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Request ID:"}),p.original.request_id.length>64?(0,t.jsx)(h.Z,{title:p.original.request_id,children:(0,t.jsx)("span",{className:"font-mono text-sm",children:T})}):(0,t.jsx)("span",{className:"font-mono text-sm",children:p.original.request_id})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Model:"}),(0,t.jsx)("span",{children:p.original.model})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Model ID:"}),(0,t.jsx)("span",{children:p.original.model_id})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Call Type:"}),(0,t.jsx)("span",{children:p.original.call_type})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Provider:"}),(0,t.jsx)("span",{children:p.original.custom_llm_provider||"-"})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"API Base:"}),(0,t.jsx)(h.Z,{title:p.original.api_base||"-",children:(0,t.jsx)("span",{className:"max-w-[15ch] truncate block",children:p.original.api_base||"-"})})]}),(null==p?void 0:null===(l=p.original)||void 0===l?void 0:l.requester_ip_address)&&(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"IP Address:"}),(0,t.jsx)("span",{children:null==p?void 0:null===(r=p.original)||void 0===r?void 0:r.requester_ip_address})]}),D&&(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Guardrail:"}),(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"font-mono",children:E}),M>0&&(0,t.jsxs)("span",{className:"ml-2 px-2 py-0.5 bg-blue-50 text-blue-700 rounded-md text-xs font-medium",children:[M," masked"]})]})]})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Tokens:"}),(0,t.jsxs)("span",{children:[p.original.total_tokens," (",p.original.prompt_tokens," prompt tokens +"," ",p.original.completion_tokens," completion tokens)"]})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Cache Read Tokens:"}),(0,t.jsx)("span",{children:(0,m.pw)((null===(i=p.original.metadata)||void 0===i?void 0:null===(n=i.additional_usage_values)||void 0===n?void 0:n.cache_read_input_tokens)||0)})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Cache Creation Tokens:"}),(0,t.jsx)("span",{children:(0,m.pw)(null===(d=p.original.metadata)||void 0===d?void 0:d.additional_usage_values.cache_creation_input_tokens)})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Cost:"}),(0,t.jsxs)("span",{children:["$",(0,m.pw)(p.original.spend||0,6)]})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Cache Hit:"}),(0,t.jsx)("span",{children:p.original.cache_hit})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Status:"}),(0,t.jsx)("span",{className:"px-2 py-1 rounded-md text-xs font-medium inline-block text-center w-16 ".concat("failure"!==((null===(o=p.original.metadata)||void 0===o?void 0:o.status)||"Success").toLowerCase()?"bg-green-100 text-green-800":"bg-red-100 text-red-800"),children:"failure"!==((null===(c=p.original.metadata)||void 0===c?void 0:c.status)||"Success").toLowerCase()?"Success":"Failure"})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Start Time:"}),(0,t.jsx)("span",{children:p.original.startTime})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"End Time:"}),(0,t.jsx)("span",{children:p.original.endTime})]}),(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"Duration:"}),(0,t.jsxs)("span",{children:[p.original.duration," s."]})]}),(null===(x=p.original.metadata)||void 0===x?void 0:x.litellm_overhead_time_ms)!==void 0&&(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)("span",{className:"font-medium w-1/3",children:"LiteLLM Overhead:"}),(0,t.jsxs)("span",{children:[p.original.metadata.litellm_overhead_time_ms," ms"]})]})]})]})]}),(0,t.jsx)(ed,{costBreakdown:null===(u=p.original.metadata)||void 0===u?void 0:u.cost_breakdown,totalSpend:p.original.spend||0}),(0,t.jsx)(L,{show:!b&&!N}),(0,t.jsx)("div",{className:"w-full max-w-full overflow-hidden",children:(0,t.jsx)(k,{row:p,hasMessages:b,hasResponse:N,hasError:v,errorInfo:y,getRawRequest:()=>{var e;return(null===(e=p.original)||void 0===e?void 0:e.proxy_server_request)?j(p.original.proxy_server_request):j(p.original.messages)},formattedResponse:()=>v&&y?{error:{message:y.error_message||"An error occurred",type:y.error_class||"error",code:y.error_code||"unknown",param:null}}:j(p.original.response)})}),D&&(0,t.jsx)(ea,{data:_}),w&&(0,t.jsx)(K,{data:f.vector_store_request_metadata}),v&&y&&(0,t.jsx)(S,{errorInfo:y}),p.original.request_tags&&Object.keys(p.original.request_tags).length>0&&(0,t.jsxs)("div",{className:"bg-white rounded-lg shadow",children:[(0,t.jsx)("div",{className:"flex justify-between items-center p-4 border-b",children:(0,t.jsx)("h3",{className:"text-lg font-medium",children:"Request Tags"})}),(0,t.jsx)("div",{className:"p-4",children:(0,t.jsx)("div",{className:"flex flex-wrap gap-2",children:Object.entries(p.original.request_tags).map(e=>{let[s,a]=e;return(0,t.jsxs)("span",{className:"px-2 py-1 bg-gray-100 rounded-full text-xs",children:[s,": ",String(a)]},s)})})})]}),p.original.metadata&&Object.keys(p.original.metadata).length>0&&(0,t.jsxs)("div",{className:"bg-white rounded-lg shadow",children:[(0,t.jsxs)("div",{className:"flex justify-between items-center p-4 border-b",children:[(0,t.jsx)("h3",{className:"text-lg font-medium",children:"Metadata"}),(0,t.jsx)("button",{onClick:()=>{navigator.clipboard.writeText(JSON.stringify(p.original.metadata,null,2))},className:"p-1 hover:bg-gray-200 rounded",title:"Copy metadata",children:(0,t.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,t.jsx)("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2"}),(0,t.jsx)("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]})})]}),(0,t.jsx)("div",{className:"p-4 overflow-auto max-h-64",children:(0,t.jsx)("pre",{className:"text-xs font-mono whitespace-pre-wrap break-all",children:JSON.stringify(p.original.metadata,null,2)})})]})]})}}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/1994-6637a121c9ee1602.js b/litellm/proxy/_experimental/out/_next/static/chunks/1994-6637a121c9ee1602.js new file mode 100644 index 00000000000..90f29480d63 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/1994-6637a121c9ee1602.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1994],{4156:function(e,n,t){t.d(n,{Z:function(){return O}});var o=t(2265),a=t(36760),r=t.n(a),c=t(20873),l=t(28791),i=t(6694),s=t(34709),u=t(71744),d=t(86586),b=t(64024),p=t(39109);let f=o.createContext(null);var v=t(23159),m=t(66531),h=function(e,n){var t={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&0>n.indexOf(o)&&(t[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,o=Object.getOwnPropertySymbols(e);an.indexOf(o[a])&&Object.prototype.propertyIsEnumerable.call(e,o[a])&&(t[o[a]]=e[o[a]]);return t};let g=o.forwardRef((e,n)=>{var t;let{prefixCls:a,className:g,rootClassName:C,children:y,indeterminate:k=!1,style:x,onMouseEnter:O,onMouseLeave:E,skipGroup:S=!1,disabled:w}=e,Z=h(e,["prefixCls","className","rootClassName","children","indeterminate","style","onMouseEnter","onMouseLeave","skipGroup","disabled"]),{getPrefixCls:P,direction:N,checkbox:j}=o.useContext(u.E_),I=o.useContext(f),{isFormItemInput:R}=o.useContext(p.aM),z=o.useContext(d.Z),B=null!==(t=(null==I?void 0:I.disabled)||w)&&void 0!==t?t:z,D=o.useRef(Z.value),M=o.useRef(null),_=(0,l.sQ)(n,M);o.useEffect(()=>{null==I||I.registerValue(Z.value)},[]),o.useEffect(()=>{if(!S)return Z.value!==D.current&&(null==I||I.cancelValue(D.current),null==I||I.registerValue(Z.value),D.current=Z.value),()=>null==I?void 0:I.cancelValue(Z.value)},[Z.value]),o.useEffect(()=>{var e;(null===(e=M.current)||void 0===e?void 0:e.input)&&(M.current.input.indeterminate=k)},[k]);let W=P("checkbox",a),q=(0,b.Z)(W),[H,T,G]=(0,v.ZP)(W,q),V=Object.assign({},Z);I&&!S&&(V.onChange=function(){for(var e=arguments.length,n=Array(e),t=0;tn.indexOf(o)&&(t[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,o=Object.getOwnPropertySymbols(e);an.indexOf(o[a])&&Object.prototype.propertyIsEnumerable.call(e,o[a])&&(t[o[a]]=e[o[a]]);return t};let x=o.forwardRef((e,n)=>{let{defaultValue:t,children:a,options:c=[],prefixCls:l,className:i,rootClassName:s,style:d,onChange:p}=e,m=k(e,["defaultValue","children","options","prefixCls","className","rootClassName","style","onChange"]),{getPrefixCls:h,direction:x}=o.useContext(u.E_),[O,E]=o.useState(m.value||t||[]),[S,w]=o.useState([]);o.useEffect(()=>{"value"in m&&E(m.value||[])},[m.value]);let Z=o.useMemo(()=>c.map(e=>"string"==typeof e||"number"==typeof e?{label:e,value:e}:e),[c]),P=e=>{w(n=>n.filter(n=>n!==e))},N=e=>{w(n=>[].concat((0,C.Z)(n),[e]))},j=e=>{let n=O.indexOf(e.value),t=(0,C.Z)(O);-1===n?t.push(e.value):t.splice(n,1),"value"in m||E(t),null==p||p(t.filter(e=>S.includes(e)).sort((e,n)=>Z.findIndex(n=>n.value===e)-Z.findIndex(e=>e.value===n)))},I=h("checkbox",l),R="".concat(I,"-group"),z=(0,b.Z)(I),[B,D,M]=(0,v.ZP)(I,z),_=(0,y.Z)(m,["value","disabled"]),W=c.length?Z.map(e=>o.createElement(g,{prefixCls:I,key:e.value.toString(),disabled:"disabled"in e?e.disabled:m.disabled,value:e.value,checked:O.includes(e.value),onChange:e.onChange,className:r()("".concat(R,"-item"),e.className),style:e.style,title:e.title,id:e.id,required:e.required},e.label)):a,q=o.useMemo(()=>({toggleOption:j,value:O,disabled:m.disabled,name:m.name,registerValue:N,cancelValue:P}),[j,O,m.disabled,m.name,N,P]),H=r()(R,{["".concat(R,"-rtl")]:"rtl"===x},i,s,M,z,D);return B(o.createElement("div",Object.assign({className:H,style:d},_,{ref:n}),o.createElement(f.Provider,{value:q},W)))});g.Group=x,g.__ANT_CHECKBOX=!0;var O=g},23159:function(e,n,t){t.d(n,{C2:function(){return i}});var o=t(93463),a=t(12918),r=t(71140),c=t(99320);let l=e=>{let{checkboxCls:n}=e,t="".concat(n,"-wrapper");return[{["".concat(n,"-group")]:Object.assign(Object.assign({},(0,a.Wf)(e)),{display:"inline-flex",flexWrap:"wrap",columnGap:e.marginXS,["> ".concat(e.antCls,"-row")]:{flex:1}}),[t]:Object.assign(Object.assign({},(0,a.Wf)(e)),{display:"inline-flex",alignItems:"baseline",cursor:"pointer","&:after":{display:"inline-block",width:0,overflow:"hidden",content:"'\\a0'"},["& + ".concat(t)]:{marginInlineStart:0},["&".concat(t,"-in-form-item")]:{'input[type="checkbox"]':{width:14,height:14}}}),[n]:Object.assign(Object.assign({},(0,a.Wf)(e)),{position:"relative",whiteSpace:"nowrap",lineHeight:1,cursor:"pointer",borderRadius:e.borderRadiusSM,alignSelf:"center",["".concat(n,"-input")]:{position:"absolute",inset:0,zIndex:1,cursor:"pointer",opacity:0,margin:0,["&:focus-visible + ".concat(n,"-inner")]:(0,a.oN)(e)},["".concat(n,"-inner")]:{boxSizing:"border-box",display:"block",width:e.checkboxSize,height:e.checkboxSize,direction:"ltr",backgroundColor:e.colorBgContainer,border:"".concat((0,o.bf)(e.lineWidth)," ").concat(e.lineType," ").concat(e.colorBorder),borderRadius:e.borderRadiusSM,borderCollapse:"separate",transition:"all ".concat(e.motionDurationSlow),"&:after":{boxSizing:"border-box",position:"absolute",top:"50%",insetInlineStart:"25%",display:"table",width:e.calc(e.checkboxSize).div(14).mul(5).equal(),height:e.calc(e.checkboxSize).div(14).mul(8).equal(),border:"".concat((0,o.bf)(e.lineWidthBold)," solid ").concat(e.colorWhite),borderTop:0,borderInlineStart:0,transform:"rotate(45deg) scale(0) translate(-50%,-50%)",opacity:0,content:'""',transition:"all ".concat(e.motionDurationFast," ").concat(e.motionEaseInBack,", opacity ").concat(e.motionDurationFast)}},"& + span":{paddingInlineStart:e.paddingXS,paddingInlineEnd:e.paddingXS}})},{["\n ".concat(t,":not(").concat(t,"-disabled),\n ").concat(n,":not(").concat(n,"-disabled)\n ")]:{["&:hover ".concat(n,"-inner")]:{borderColor:e.colorPrimary}},["".concat(t,":not(").concat(t,"-disabled)")]:{["&:hover ".concat(n,"-checked:not(").concat(n,"-disabled) ").concat(n,"-inner")]:{backgroundColor:e.colorPrimaryHover,borderColor:"transparent"},["&:hover ".concat(n,"-checked:not(").concat(n,"-disabled):after")]:{borderColor:e.colorPrimaryHover}}},{["".concat(n,"-checked")]:{["".concat(n,"-inner")]:{backgroundColor:e.colorPrimary,borderColor:e.colorPrimary,"&:after":{opacity:1,transform:"rotate(45deg) scale(1) translate(-50%,-50%)",transition:"all ".concat(e.motionDurationMid," ").concat(e.motionEaseOutBack," ").concat(e.motionDurationFast)}}},["\n ".concat(t,"-checked:not(").concat(t,"-disabled),\n ").concat(n,"-checked:not(").concat(n,"-disabled)\n ")]:{["&:hover ".concat(n,"-inner")]:{backgroundColor:e.colorPrimaryHover,borderColor:"transparent"}}},{[n]:{"&-indeterminate":{"&":{["".concat(n,"-inner")]:{backgroundColor:"".concat(e.colorBgContainer),borderColor:"".concat(e.colorBorder),"&:after":{top:"50%",insetInlineStart:"50%",width:e.calc(e.fontSizeLG).div(2).equal(),height:e.calc(e.fontSizeLG).div(2).equal(),backgroundColor:e.colorPrimary,border:0,transform:"translate(-50%, -50%) scale(1)",opacity:1,content:'""'}},["&:hover ".concat(n,"-inner")]:{backgroundColor:"".concat(e.colorBgContainer),borderColor:"".concat(e.colorPrimary)}}}}},{["".concat(t,"-disabled")]:{cursor:"not-allowed"},["".concat(n,"-disabled")]:{["&, ".concat(n,"-input")]:{cursor:"not-allowed",pointerEvents:"none"},["".concat(n,"-inner")]:{background:e.colorBgContainerDisabled,borderColor:e.colorBorder,"&:after":{borderColor:e.colorTextDisabled}},"&:after":{display:"none"},"& + span":{color:e.colorTextDisabled},["&".concat(n,"-indeterminate ").concat(n,"-inner::after")]:{background:e.colorTextDisabled}}}]};function i(e,n){return l((0,r.IX)(n,{checkboxCls:".".concat(e),checkboxSize:n.controlInteractiveSize}))}n.ZP=(0,c.I$)("Checkbox",(e,n)=>{let{prefixCls:t}=n;return[i(t,e)]})},66531:function(e,n,t){t.d(n,{Z:function(){return r}});var o=t(2265),a=t(53346);function r(e){let n=o.useRef(null),t=()=>{a.Z.cancel(n.current),n.current=null};return[()=>{t(),n.current=(0,a.Z)(()=>{n.current=null})},o=>{n.current&&(o.stopPropagation(),t()),null==e||e(o)}]}},20873:function(e,n,t){var o=t(1119),a=t(31686),r=t(11993),c=t(26365),l=t(6989),i=t(36760),s=t.n(i),u=t(50506),d=t(2265),b=["prefixCls","className","style","checked","disabled","defaultChecked","type","title","onChange"],p=(0,d.forwardRef)(function(e,n){var t=e.prefixCls,i=void 0===t?"rc-checkbox":t,p=e.className,f=e.style,v=e.checked,m=e.disabled,h=e.defaultChecked,g=e.type,C=void 0===g?"checkbox":g,y=e.title,k=e.onChange,x=(0,l.Z)(e,b),O=(0,d.useRef)(null),E=(0,d.useRef)(null),S=(0,u.Z)(void 0!==h&&h,{value:v}),w=(0,c.Z)(S,2),Z=w[0],P=w[1];(0,d.useImperativeHandle)(n,function(){return{focus:function(e){var n;null===(n=O.current)||void 0===n||n.focus(e)},blur:function(){var e;null===(e=O.current)||void 0===e||e.blur()},input:O.current,nativeElement:E.current}});var N=s()(i,p,(0,r.Z)((0,r.Z)({},"".concat(i,"-checked"),Z),"".concat(i,"-disabled"),m));return d.createElement("span",{className:N,title:y,style:f,ref:E},d.createElement("input",(0,o.Z)({},x,{className:"".concat(i,"-input"),ref:O,onChange:function(n){m||("checked"in e||P(n.target.checked),null==k||k({target:(0,a.Z)((0,a.Z)({},e),{},{type:C,checked:n.target.checked}),stopPropagation:function(){n.stopPropagation()},preventDefault:function(){n.preventDefault()},nativeEvent:n.nativeEvent}))},disabled:m,checked:!!Z,type:C})),d.createElement("span",{className:"".concat(i,"-inner")}))});n.Z=p}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/2-253aec8d55c7bb6f.js b/litellm/proxy/_experimental/out/_next/static/chunks/2-253aec8d55c7bb6f.js deleted file mode 100644 index 85f8498f5f2..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/2-253aec8d55c7bb6f.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[2],{49634:function(e,t,r){"use strict";r.d(t,{Z:function(){return i}});var n=r(1119),o=r(2265),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"},l=r(55015),i=o.forwardRef(function(e,t){return o.createElement(l.Z,(0,n.Z)({},e,{ref:t,icon:a}))})},60216:function(e,t,r){"use strict";r.d(t,{Z:function(){return i}});var n=r(1119),o=r(2265),a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M854.6 288.6L639.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 42h216v494zM514.1 580.1l-61.8-102.4c-2.2-3.6-6.1-5.8-10.3-5.8h-38.4c-2.3 0-4.5.6-6.4 1.9-5.6 3.5-7.3 10.9-3.7 16.6l82.3 130.4-83.4 132.8a12.04 12.04 0 0010.2 18.4h34.5c4.2 0 8-2.2 10.2-5.7L510 664.8l62.3 101.4c2.2 3.6 6.1 5.7 10.2 5.7H620c2.3 0 4.5-.7 6.5-1.9 5.6-3.6 7.2-11 3.6-16.6l-84-130.4 85.3-132.5a12.04 12.04 0 00-10.1-18.5h-35.7c-4.2 0-8.1 2.2-10.3 5.8l-61.2 102.3z"}}]},name:"file-excel",theme:"outlined"},l=r(55015),i=o.forwardRef(function(e,t){return o.createElement(l.Z,(0,n.Z)({},e,{ref:t,icon:a}))})},10798:function(e,t,r){"use strict";r.d(t,{Z:function(){return i}});var n=r(1119),o=r(2265),a={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"},l=r(55015),i=o.forwardRef(function(e,t){return o.createElement(l.Z,(0,n.Z)({},e,{ref:t,icon:a}))})},64739:function(e,t,r){"use strict";r.d(t,{Z:function(){return i}});var n=r(1119),o=r(2265),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"},l=r(55015),i=o.forwardRef(function(e,t){return o.createElement(l.Z,(0,n.Z)({},e,{ref:t,icon:a}))})},46783:function(e,t,r){"use strict";r.d(t,{Z:function(){return i}});var n=r(1119),o=r(2265),a={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M885.2 446.3l-.2-.8-112.2-285.1c-5-16.1-19.9-27.2-36.8-27.2H281.2c-17 0-32.1 11.3-36.9 27.6L139.4 443l-.3.7-.2.8c-1.3 4.9-1.7 9.9-1 14.8-.1 1.6-.2 3.2-.2 4.8V830a60.9 60.9 0 0060.8 60.8h627.2c33.5 0 60.8-27.3 60.9-60.8V464.1c0-1.3 0-2.6-.1-3.7.4-4.9 0-9.6-1.3-14.1zm-295.8-43l-.3 15.7c-.8 44.9-31.8 75.1-77.1 75.1-22.1 0-41.1-7.1-54.8-20.6S436 441.2 435.6 419l-.3-15.7H229.5L309 210h399.2l81.7 193.3H589.4zm-375 76.8h157.3c24.3 57.1 76 90.8 140.4 90.8 33.7 0 65-9.4 90.3-27.2 22.2-15.6 39.5-37.4 50.7-63.6h156.5V814H214.4V480.1z"}}]},name:"inbox",theme:"outlined"},l=r(55015),i=o.forwardRef(function(e,t){return o.createElement(l.Z,(0,n.Z)({},e,{ref:t,icon:a}))})},23907:function(e,t,r){"use strict";r.d(t,{Z:function(){return i}});var n=r(1119),o=r(2265),a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"defs",attrs:{},children:[{tag:"style",attrs:{}}]},{tag:"path",attrs:{d:"M931.4 498.9L94.9 79.5c-3.4-1.7-7.3-2.1-11-1.2a15.99 15.99 0 00-11.7 19.3l86.2 352.2c1.3 5.3 5.2 9.6 10.4 11.3l147.7 50.7-147.6 50.7c-5.2 1.8-9.1 6-10.3 11.3L72.2 926.5c-.9 3.7-.5 7.6 1.2 10.9 3.9 7.9 13.5 11.1 21.5 7.2l836.5-417c3.1-1.5 5.6-4.1 7.2-7.1 3.9-8 .7-17.6-7.2-21.6zM170.8 826.3l50.3-205.6 295.2-101.3c2.3-.8 4.2-2.6 5-5 1.4-4.2-.8-8.7-5-10.2L221.1 403 171 198.2l628 314.9-628.2 313.2z"}}]},name:"send",theme:"outlined"},l=r(55015),i=o.forwardRef(function(e,t){return o.createElement(l.Z,(0,n.Z)({},e,{ref:t,icon:a}))})},40312:function(e,t,r){"use strict";r.d(t,{Z:function(){return i}});var n=r(1119),o=r(2265),a={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M922.9 701.9H327.4l29.9-60.9 496.8-.9c16.8 0 31.2-12 34.2-28.6l68.8-385.1c1.8-10.1-.9-20.5-7.5-28.4a34.99 34.99 0 00-26.6-12.5l-632-2.1-5.4-25.4c-3.4-16.2-18-28-34.6-28H96.5a35.3 35.3 0 100 70.6h125.9L246 312.8l58.1 281.3-74.8 122.1a34.96 34.96 0 00-3 36.8c6 11.9 18.1 19.4 31.5 19.4h62.8a102.43 102.43 0 00-20.6 61.7c0 56.6 46 102.6 102.6 102.6s102.6-46 102.6-102.6c0-22.3-7.4-44-20.6-61.7h161.1a102.43 102.43 0 00-20.6 61.7c0 56.6 46 102.6 102.6 102.6s102.6-46 102.6-102.6c0-22.3-7.4-44-20.6-61.7H923c19.4 0 35.3-15.8 35.3-35.3a35.42 35.42 0 00-35.4-35.2zM305.7 253l575.8 1.9-56.4 315.8-452.3.8L305.7 253zm96.9 612.7c-17.4 0-31.6-14.2-31.6-31.6 0-17.4 14.2-31.6 31.6-31.6s31.6 14.2 31.6 31.6a31.6 31.6 0 01-31.6 31.6zm325.1 0c-17.4 0-31.6-14.2-31.6-31.6 0-17.4 14.2-31.6 31.6-31.6s31.6 14.2 31.6 31.6a31.6 31.6 0 01-31.6 31.6z"}}]},name:"shopping-cart",theme:"outlined"},l=r(55015),i=o.forwardRef(function(e,t){return o.createElement(l.Z,(0,n.Z)({},e,{ref:t,icon:a}))})},59664:function(e,t,r){"use strict";r.d(t,{Z:function(){return O}});var n=r(5853),o=r(2265),a=r(47625),l=r(93765),i=r(54061),s=r(97059),c=r(62994),u=r(25311),d=(0,l.z)({chartName:"LineChart",GraphicalChild:i.x,axisComponents:[{axisType:"xAxis",AxisComp:s.K},{axisType:"yAxis",AxisComp:c.B}],formatAxisMap:u.t9}),h=r(56940),m=r(26680),p=r(8147),f=r(22190),g=r(81889),b=r(65278),k=r(98593),y=r(92666),v=r(32644),x=r(7084),w=r(26898),E=r(13241),C=r(1153);let O=o.forwardRef((e,t)=>{let{data:r=[],categories:l=[],index:u,colors:O=w.s,valueFormatter:M=C.Cj,startEndOnly:Z=!1,showXAxis:N=!0,showYAxis:q=!0,yAxisWidth:S=56,intervalType:j="equidistantPreserveStart",animationDuration:z=900,showAnimation:L=!1,showTooltip:_=!0,showLegend:A=!0,showGridLines:V=!0,autoMinValue:T=!1,curveType:H="linear",minValue:F,maxValue:P,connectNulls:R=!1,allowDecimals:D=!0,noDataText:B,className:Q,onValueChange:K,enableLegendSlider:I=!1,customTooltip:W,rotateLabelX:G,padding:X=N||q?{left:20,right:20}:{left:0,right:0},tickGap:J=5,xAxisLabel:Y,yAxisLabel:$}=e,U=(0,n._T)(e,["data","categories","index","colors","valueFormatter","startEndOnly","showXAxis","showYAxis","yAxisWidth","intervalType","animationDuration","showAnimation","showTooltip","showLegend","showGridLines","autoMinValue","curveType","minValue","maxValue","connectNulls","allowDecimals","noDataText","className","onValueChange","enableLegendSlider","customTooltip","rotateLabelX","padding","tickGap","xAxisLabel","yAxisLabel"]),[ee,et]=(0,o.useState)(60),[er,en]=(0,o.useState)(void 0),[eo,ea]=(0,o.useState)(void 0),el=(0,v.me)(l,O),ei=(0,v.i4)(T,F,P),es=!!K;function ec(e){es&&(e===eo&&!er||(0,v.FB)(r,e)&&er&&er.dataKey===e?(ea(void 0),null==K||K(null)):(ea(e),null==K||K({eventType:"category",categoryClicked:e})),en(void 0))}return o.createElement("div",Object.assign({ref:t,className:(0,E.q)("w-full h-80",Q)},U),o.createElement(a.h,{className:"h-full w-full"},(null==r?void 0:r.length)?o.createElement(d,{data:r,onClick:es&&(eo||er)?()=>{en(void 0),ea(void 0),null==K||K(null)}:void 0,margin:{bottom:Y?30:void 0,left:$?20:void 0,right:$?5:void 0,top:5}},V?o.createElement(h.q,{className:(0,E.q)("stroke-1","stroke-tremor-border","dark:stroke-dark-tremor-border"),horizontal:!0,vertical:!1}):null,o.createElement(s.K,{padding:X,hide:!N,dataKey:u,interval:Z?"preserveStartEnd":j,tick:{transform:"translate(0, 6)"},ticks:Z?[r[0][u],r[r.length-1][u]]:void 0,fill:"",stroke:"",className:(0,E.q)("text-tremor-label","fill-tremor-content","dark:fill-dark-tremor-content"),tickLine:!1,axisLine:!1,minTickGap:J,angle:null==G?void 0:G.angle,dy:null==G?void 0:G.verticalShift,height:null==G?void 0:G.xAxisHeight},Y&&o.createElement(m._,{position:"insideBottom",offset:-20,className:"fill-tremor-content-emphasis text-tremor-default font-medium dark:fill-dark-tremor-content-emphasis"},Y)),o.createElement(c.B,{width:S,hide:!q,axisLine:!1,tickLine:!1,type:"number",domain:ei,tick:{transform:"translate(-3, 0)"},fill:"",stroke:"",className:(0,E.q)("text-tremor-label","fill-tremor-content","dark:fill-dark-tremor-content"),tickFormatter:M,allowDecimals:D},$&&o.createElement(m._,{position:"insideLeft",style:{textAnchor:"middle"},angle:-90,offset:-15,className:"fill-tremor-content-emphasis text-tremor-default font-medium dark:fill-dark-tremor-content-emphasis"},$)),o.createElement(p.u,{wrapperStyle:{outline:"none"},isAnimationActive:!1,cursor:{stroke:"#d1d5db",strokeWidth:1},content:_?e=>{let{active:t,payload:r,label:n}=e;return W?o.createElement(W,{payload:null==r?void 0:r.map(e=>{var t;return Object.assign(Object.assign({},e),{color:null!==(t=el.get(e.dataKey))&&void 0!==t?t:x.fr.Gray})}),active:t,label:n}):o.createElement(k.ZP,{active:t,payload:r,label:n,valueFormatter:M,categoryColors:el})}:o.createElement(o.Fragment,null),position:{y:0}}),A?o.createElement(f.D,{verticalAlign:"top",height:ee,content:e=>{let{payload:t}=e;return(0,b.Z)({payload:t},el,et,eo,es?e=>ec(e):void 0,I)}}):null,l.map(e=>{var t;return o.createElement(i.x,{className:(0,E.q)((0,C.bM)(null!==(t=el.get(e))&&void 0!==t?t:x.fr.Gray,w.K.text).strokeColor),strokeOpacity:er||eo&&eo!==e?.3:1,activeDot:e=>{var t;let{cx:n,cy:a,stroke:l,strokeLinecap:i,strokeLinejoin:s,strokeWidth:c,dataKey:u}=e;return o.createElement(g.o,{className:(0,E.q)("stroke-tremor-background dark:stroke-dark-tremor-background",K?"cursor-pointer":"",(0,C.bM)(null!==(t=el.get(u))&&void 0!==t?t:x.fr.Gray,w.K.text).fillColor),cx:n,cy:a,r:5,fill:"",stroke:l,strokeLinecap:i,strokeLinejoin:s,strokeWidth:c,onClick:(t,n)=>{n.stopPropagation(),es&&(e.index===(null==er?void 0:er.index)&&e.dataKey===(null==er?void 0:er.dataKey)||(0,v.FB)(r,e.dataKey)&&eo&&eo===e.dataKey?(ea(void 0),en(void 0),null==K||K(null)):(ea(e.dataKey),en({index:e.index,dataKey:e.dataKey}),null==K||K(Object.assign({eventType:"dot",categoryClicked:e.dataKey},e.payload))))}})},dot:t=>{var n;let{stroke:a,strokeLinecap:l,strokeLinejoin:i,strokeWidth:s,cx:c,cy:u,dataKey:d,index:h}=t;return(0,v.FB)(r,e)&&!(er||eo&&eo!==e)||(null==er?void 0:er.index)===h&&(null==er?void 0:er.dataKey)===e?o.createElement(g.o,{key:h,cx:c,cy:u,r:5,stroke:a,fill:"",strokeLinecap:l,strokeLinejoin:i,strokeWidth:s,className:(0,E.q)("stroke-tremor-background dark:stroke-dark-tremor-background",K?"cursor-pointer":"",(0,C.bM)(null!==(n=el.get(d))&&void 0!==n?n:x.fr.Gray,w.K.text).fillColor)}):o.createElement(o.Fragment,{key:h})},key:e,name:e,type:H,dataKey:e,stroke:"",strokeWidth:2,strokeLinejoin:"round",strokeLinecap:"round",isAnimationActive:L,animationDuration:z,connectNulls:R})}),K?l.map(e=>o.createElement(i.x,{className:(0,E.q)("cursor-pointer"),strokeOpacity:0,key:e,name:e,type:H,dataKey:e,stroke:"transparent",fill:"transparent",legendType:"none",tooltipType:"none",strokeWidth:12,connectNulls:R,onClick:(e,t)=>{t.stopPropagation();let{name:r}=e;ec(r)}})):null):o.createElement(y.Z,{noDataText:B})))});O.displayName="LineChart"},16853:function(e,t,r){"use strict";r.d(t,{Z:function(){return u}});var n=r(5853),o=r(96398),a=r(44140),l=r(2265),i=r(13241),s=r(1153);let c=(0,s.fn)("Textarea"),u=l.forwardRef((e,t)=>{let{value:r,defaultValue:u="",placeholder:d="Type...",error:h=!1,errorMessage:m,disabled:p=!1,className:f,onChange:g,onValueChange:b,autoHeight:k=!1}=e,y=(0,n._T)(e,["value","defaultValue","placeholder","error","errorMessage","disabled","className","onChange","onValueChange","autoHeight"]),[v,x]=(0,a.Z)(u,r),w=(0,l.useRef)(null),E=(0,o.Uh)(v);return(0,l.useEffect)(()=>{let e=w.current;if(k&&e){e.style.height="60px";let t=e.scrollHeight;e.style.height=t+"px"}},[k,w,v]),l.createElement(l.Fragment,null,l.createElement("textarea",Object.assign({ref:(0,s.lq)([w,t]),value:v,placeholder:d,disabled:p,className:(0,i.q)(c("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,o.um)(E,p,h),p?"placeholder:text-tremor-content-subtle dark:placeholder:text-dark-tremor-content-subtle":"placeholder:text-tremor-content dark:placeholder:text-dark-tremor-content",f),"data-testid":"text-area",onChange:e=>{null==g||g(e),x(e.target.value),null==b||b(e.target.value)}},y)),h&&m?l.createElement("p",{className:(0,i.q)(c("errorMessage"),"text-sm text-red-500 mt-1")},m):null)});u.displayName="Textarea"},35829:function(e,t,r){"use strict";r.d(t,{Z:function(){return s}});var n=r(5853),o=r(26898),a=r(13241),l=r(1153),i=r(2265);let s=i.forwardRef((e,t)=>{let{color:r,children:s,className:c}=e,u=(0,n._T)(e,["color","children","className"]);return i.createElement("p",Object.assign({ref:t,className:(0,a.q)("font-semibold text-tremor-metric",r?(0,l.bM)(r,o.K.darkText).textColor:"text-tremor-content-strong dark:text-dark-tremor-content-strong",c)},u),s)});s.displayName="Metric"},96889:function(e,t,r){"use strict";r.d(t,{Z:function(){return u}});var n=r(5853),o=r(2265),a=r(26898),l=r(13241),i=r(1153);let s=(0,i.fn)("BarList");function c(e,t){let{data:r=[],color:c,valueFormatter:u=i.Cj,showAnimation:d=!1,onValueChange:h,sortOrder:m="descending",className:p}=e,f=(0,n._T)(e,["data","color","valueFormatter","showAnimation","onValueChange","sortOrder","className"]),g=h?"button":"div",b=o.useMemo(()=>"none"===m?r:[...r].sort((e,t)=>"ascending"===m?e.value-t.value:t.value-e.value),[r,m]),k=o.useMemo(()=>{let e=Math.max(...b.map(e=>e.value),0);return b.map(t=>0===t.value?0:Math.max(t.value/e*100,2))},[b]);return o.createElement("div",Object.assign({ref:t,className:(0,l.q)(s("root"),"flex justify-between space-x-6",p),"aria-sort":m},f),o.createElement("div",{className:(0,l.q)(s("bars"),"relative w-full space-y-1.5")},b.map((e,t)=>{var r,n,u;let m=e.icon;return o.createElement(g,{key:null!==(r=e.key)&&void 0!==r?r:t,onClick:()=>{null==h||h(e)},className:(0,l.q)(s("bar"),"group w-full flex items-center rounded-tremor-small",h?["cursor-pointer","hover:bg-tremor-background-muted dark:hover:bg-dark-tremor-background-subtle/40"]:"")},o.createElement("div",{className:(0,l.q)("flex items-center rounded transition-all bg-opacity-40","h-8",e.color||c?[(0,i.bM)(null!==(n=e.color)&&void 0!==n?n:c,a.K.background).bgColor,h?"group-hover:bg-opacity-30":""]:"bg-tremor-brand-subtle dark:bg-dark-tremor-brand-subtle/60",!h||e.color||c?"":"group-hover:bg-tremor-brand-subtle/30 group-hover:dark:bg-dark-tremor-brand-subtle/70",t===b.length-1?"mb-0":"",d?"duration-500":""),style:{width:"".concat(k[t],"%"),transition:d?"all 1s":""}},o.createElement("div",{className:(0,l.q)("absolute left-2 pr-4 flex max-w-full")},m?o.createElement(m,{className:(0,l.q)(s("barIcon"),"flex-none h-5 w-5 mr-2","text-tremor-content","dark:text-dark-tremor-content")}):null,e.href?o.createElement("a",{href:e.href,target:null!==(u=e.target)&&void 0!==u?u:"_blank",rel:"noreferrer",className:(0,l.q)(s("barLink"),"whitespace-nowrap hover:underline truncate text-tremor-default",h?"cursor-pointer":"","text-tremor-content-emphasis","dark:text-dark-tremor-content-emphasis"),onClick:e=>e.stopPropagation()},e.name):o.createElement("p",{className:(0,l.q)(s("barText"),"whitespace-nowrap truncate text-tremor-default","text-tremor-content-emphasis","dark:text-dark-tremor-content-emphasis")},e.name))))})),o.createElement("div",{className:s("labels")},b.map((e,t)=>{var r;return o.createElement("div",{key:null!==(r=e.key)&&void 0!==r?r:t,className:(0,l.q)(s("labelWrapper"),"flex justify-end items-center","h-8",t===b.length-1?"mb-0":"mb-1.5")},o.createElement("p",{className:(0,l.q)(s("labelText"),"whitespace-nowrap leading-none truncate text-tremor-default","text-tremor-content-emphasis","dark:text-dark-tremor-content-emphasis")},u(e.value)))})))}c.displayName="BarList";let u=o.forwardRef(c)},45235:function(e,t,r){"use strict";r.d(t,{Z:function(){return C}});var n=r(2265),o=r(74126),a=r(53346),l=r(19722),i=r(36760),s=r.n(i),c=r(18242),u=r(71744),d=r(50337),h=e=>{let t;let{value:r,formatter:o,precision:a,decimalSeparator:l,groupSeparator:i="",prefixCls:s}=e;if("function"==typeof o)t=o(r);else{let e=String(r),o=e.match(/^(-?)(\d*)(\.(\d+))?$/);if(o&&"-"!==e){let e=o[1],r=o[2]||"0",c=o[4]||"";r=r.replace(/\B(?=(\d{3})+(?!\d))/g,i),"number"==typeof a&&(c=c.padEnd(a,"0").slice(0,a>0?a:0)),c&&(c="".concat(l).concat(c)),t=[n.createElement("span",{key:"int",className:"".concat(s,"-content-value-int")},e,r),c&&n.createElement("span",{key:"decimal",className:"".concat(s,"-content-value-decimal")},c)]}else t=e}return n.createElement("span",{className:"".concat(s,"-content-value")},t)},m=r(12918),p=r(99320),f=r(71140);let g=e=>{let{componentCls:t,marginXXS:r,padding:n,colorTextDescription:o,titleFontSize:a,colorTextHeading:l,contentFontSize:i,fontFamily:s}=e;return{[t]:Object.assign(Object.assign({},(0,m.Wf)(e)),{["".concat(t,"-title")]:{marginBottom:r,color:o,fontSize:a},["".concat(t,"-skeleton")]:{paddingTop:n},["".concat(t,"-content")]:{color:l,fontSize:i,fontFamily:s,["".concat(t,"-content-value")]:{display:"inline-block",direction:"ltr"},["".concat(t,"-content-prefix, ").concat(t,"-content-suffix")]:{display:"inline-block"},["".concat(t,"-content-prefix")]:{marginInlineEnd:r},["".concat(t,"-content-suffix")]:{marginInlineStart:r}}})}};var b=(0,p.I$)("Statistic",e=>g((0,f.IX)(e,{})),e=>{let{fontSizeHeading3:t,fontSize:r}=e;return{titleFontSize:r,contentFontSize:t}}),k=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 y=n.forwardRef((e,t)=>{let{prefixCls:r,className:o,rootClassName:a,style:l,valueStyle:i,value:m=0,title:p,valueRender:f,prefix:g,suffix:y,loading:v=!1,formatter:x,precision:w,decimalSeparator:E=".",groupSeparator:C=",",onMouseEnter:O,onMouseLeave:M}=e,Z=k(e,["prefixCls","className","rootClassName","style","valueStyle","value","title","valueRender","prefix","suffix","loading","formatter","precision","decimalSeparator","groupSeparator","onMouseEnter","onMouseLeave"]),{getPrefixCls:N,direction:q,className:S,style:j}=(0,u.dj)("statistic"),z=N("statistic",r),[L,_,A]=b(z),V=n.createElement(h,{decimalSeparator:E,groupSeparator:C,prefixCls:z,formatter:x,precision:w,value:m}),T=s()(z,{["".concat(z,"-rtl")]:"rtl"===q},S,o,a,_,A),H=n.useRef(null);n.useImperativeHandle(t,()=>({nativeElement:H.current}));let F=(0,c.Z)(Z,{aria:!0,data:!0});return L(n.createElement("div",Object.assign({},F,{ref:H,className:T,style:Object.assign(Object.assign({},j),l),onMouseEnter:O,onMouseLeave:M}),p&&n.createElement("div",{className:"".concat(z,"-title")},p),n.createElement(d.Z,{paragraph:!1,loading:v,className:"".concat(z,"-skeleton"),active:!0},n.createElement("div",{style:i,className:"".concat(z,"-content")},g&&n.createElement("span",{className:"".concat(z,"-content-prefix")},g),f?f(V):V,y&&n.createElement("span",{className:"".concat(z,"-content-suffix")},y)))))}),v=[["Y",31536e6],["M",2592e6],["D",864e5],["H",36e5],["m",6e4],["s",1e3],["S",1]];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},w=e=>{let{value:t,format:r="HH:mm:ss",onChange:i,onFinish:s,type:c}=e,u=x(e,["value","format","onChange","onFinish","type"]),d="countdown"===c,[h,m]=n.useState(null),p=(0,o.zX)(()=>{let e=Date.now(),r=new Date(t).getTime();return m({}),null==i||i(d?r-e:e-r),!d||!(r{let e;let t=()=>{e=(0,a.Z)(()=>{p()&&t()})};return t(),()=>a.Z.cancel(e)},[t,d]),n.useEffect(()=>{m({})},[]),n.createElement(y,Object.assign({},u,{value:t,valueRender:e=>(0,l.Tm)(e,{title:void 0}),formatter:(e,t)=>h?function(e,t,r){let{format:n=""}=t,o=new Date(e).getTime(),a=Date.now();return function(e,t){let r=e,n=/\[[^\]]*]/g,o=(t.match(n)||[]).map(e=>e.slice(1,-1)),a=t.replace(n,"[]"),l=v.reduce((e,t)=>{let[n,o]=t;if(e.includes(n)){let t=Math.floor(r/o);return r-=t*o,e.replace(RegExp("".concat(n,"+"),"g"),e=>{let r=e.length;return t.toString().padStart(r,"0")})}return e},a),i=0;return l.replace(n,()=>{let e=o[i];return i+=1,e})}(r?Math.max(o-a,0):Math.max(a-o,0),n)}(e,Object.assign(Object.assign({},t),{format:r}),d):"-"}))},E=n.memo(e=>n.createElement(w,Object.assign({},e,{type:"countdown"})));y.Timer=w,y.Countdown=E;var C=y},2651:function(e,t,r){"use strict";r.d(t,{Z:function(){return y}});var n=r(93463),o=r(11938),a=r(70774),l=r(73602),i=r(91691),s=r(25119),c=r(37628),u=r(32417),d=r(4877),h=r(57943),m=r(12789),p=r(54558);let f=(e,t)=>new p.t(e).setA(t).toRgbString(),g=(e,t)=>new p.t(e).lighten(t).toHexString(),b=e=>{let t=(0,h.R_)(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]}},k=(e,t)=>{let r=e||"#000",n=t||"#fff";return{colorBgBase:r,colorTextBase:n,colorText:f(n,.85),colorTextSecondary:f(n,.65),colorTextTertiary:f(n,.45),colorTextQuaternary:f(n,.25),colorFill:f(n,.18),colorFillSecondary:f(n,.12),colorFillTertiary:f(n,.08),colorFillQuaternary:f(n,.04),colorBgSolid:f(n,.95),colorBgSolidHover:f(n,1),colorBgSolidActive:f(n,.9),colorBgElevated:g(r,12),colorBgContainer:g(r,8),colorBgLayout:g(r,0),colorBgSpotlight:g(r,26),colorBgBlur:f(n,.04),colorBorder:g(r,26),colorBorderSecondary:g(r,19)}};var y={defaultSeed:s.u_.token,useToken:function(){let[e,t,r]=(0,i.ZP)();return{theme:e,token:t,hashId:r}},defaultAlgorithm:c.Z,darkAlgorithm:(e,t)=>{let r=Object.keys(a.M).map(t=>{let r=(0,h.R_)(e[t],{theme:"dark"});return Array.from({length:10},()=>1).reduce((e,n,o)=>(e["".concat(t,"-").concat(o+1)]=r[o],e["".concat(t).concat(o+1)]=r[o],e),{})}).reduce((e,t)=>e=Object.assign(Object.assign({},e),t),{}),n=null!=t?t:(0,c.Z)(e),o=(0,m.Z)(e,{generateColorPalettes:b,generateNeutralColorPalettes:k});return Object.assign(Object.assign(Object.assign(Object.assign({},n),r),o),{colorPrimaryBg:o.colorPrimaryBorder,colorPrimaryBgHover:o.colorPrimaryBorderHover})},compactAlgorithm:(e,t)=>{let r=null!=t?t:(0,c.Z)(e),n=r.fontSizeSM,o=r.controlHeight-4;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},r),function(e){let{sizeUnit:t,sizeStep:r}=e,n=r-2;return{sizeXXL:t*(n+10),sizeXL:t*(n+6),sizeLG:t*(n+2),sizeMD:t*(n+2),sizeMS:t*(n+1),size:t*n,sizeSM:t*n,sizeXS:t*(n-1),sizeXXS:t*(n-1)}}(null!=t?t:e)),(0,d.Z)(n)),{controlHeight:o}),(0,u.Z)(Object.assign(Object.assign({},r),{controlHeight:o})))},getDesignToken:e=>{let t=(null==e?void 0:e.algorithm)?(0,n.jG)(e.algorithm):o.Z,r=Object.assign(Object.assign({},a.Z),null==e?void 0:e.token);return(0,n.t2)(r,{override:null==e?void 0:e.token},t,l.Z)},defaultConfig:s.u_,_internalContext:s.Mj}},76858:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("arrow-right",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"m12 5 7 7-7 7",key:"xquz4c"}]])},82222:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("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"}]])},41671:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("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"}]])},66344:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("circle-user-round",[["path",{d:"M18 20a6 6 0 0 0-12 0",key:"1qehca"}],["circle",{cx:"12",cy:"10",r:"4",key:"1h16sb"}],["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]])},5136:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("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"}]])},64935:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("code",[["path",{d:"m16 18 6-6-6-6",key:"eg8j8"}],["path",{d:"m8 6-6 6 6 6",key:"ppft3o"}]])},96362:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("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"}]])},3577:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("funnel",[["path",{d:"M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z",key:"sc7q7i"}]])},29202:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("globe",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20",key:"13o1zl"}],["path",{d:"M2 12h20",key:"9i4pu4"}]])},33245:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("info",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]])},54001:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("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"}]])},11:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("message-square",[["path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z",key:"1lielz"}]])},33276:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("play",[["polygon",{points:"6 3 20 12 6 21 6 3",key:"1oa8hb"}]])},69076:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("rotate-ccw",[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}]])},73247:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("search",[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]])},96137:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("server",[["rect",{width:"20",height:"8",x:"2",y:"2",rx:"2",ry:"2",key:"ngkwjq"}],["rect",{width:"20",height:"8",x:"2",y:"14",rx:"2",ry:"2",key:"iecqi9"}],["line",{x1:"6",x2:"6.01",y1:"6",y2:"6",key:"16zg32"}],["line",{x1:"6",x2:"6.01",y1:"18",y2:"18",key:"nzw8ys"}]])},80221:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("terminal",[["path",{d:"M12 19h8",key:"baeox8"}],["path",{d:"m4 17 6-6-6-6",key:"1yngyt"}]])},17689:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("upload",[["path",{d:"M12 3v12",key:"1x0j5s"}],["path",{d:"m17 8-5-5-5 5",key:"7q97r8"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}]])},79862:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("user-round",[["circle",{cx:"12",cy:"8",r:"5",key:"1hypcn"}],["path",{d:"M20 21a8 8 0 0 0-16 0",key:"rfgkzh"}]])},92369:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("user",[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]])},11239:function(e,t,r){"use strict";r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("zap",[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]])},86669:function(e,t,r){"use strict";r.d(t,{gc:function(){return v},jF:function(){return k}});var n=r(2265);let o=e=>"boolean"==typeof e||e instanceof Boolean,a=e=>"number"==typeof e||e instanceof Number,l=e=>"bigint"==typeof e||e instanceof BigInt,i=e=>!!e&&e instanceof Date,s=e=>"string"==typeof e||e instanceof String,c=e=>Array.isArray(e),u=e=>"object"==typeof e&&null!==e,d=e=>!!e&&e instanceof Object&&"function"==typeof e;function h(e,t){return void 0===t&&(t=!1),!e||t?`"${e}"`:e}function m(e){let{field:t,value:r,data:o,lastElement:a,openBracket:l,closeBracket:i,level:s,style:c,shouldExpandNode:u,clickToExpandNode:d,outerRef:m,beforeExpandChange:p}=e,f=(0,n.useRef)(!1),[g,k]=(0,n.useState)(()=>u(s,r,t)),y=(0,n.useRef)(null);(0,n.useEffect)(()=>{f.current?k(u(s,r,t)):f.current=!0},[u]);let v=(0,n.useId)();if(0===o.length)return function(e){let{field:t,openBracket:r,closeBracket:o,lastElement:a,style:l}=e;return(0,n.createElement)("div",{className:l.basicChildStyle,role:"treeitem","aria-selected":void 0},(t||""===t)&&(0,n.createElement)("span",{className:l.label},h(t,l.quotesForFieldNames),":"),(0,n.createElement)("span",{className:l.punctuation},r),(0,n.createElement)("span",{className:l.punctuation},o),!a&&(0,n.createElement)("span",{className:l.punctuation},","))}({field:t,openBracket:l,closeBracket:i,lastElement:a,style:c});let x=g?c.collapseIcon:c.expandIcon,w=g?c.ariaLables.collapseJson:c.ariaLables.expandJson,E=s+1,C=o.length-1,O=e=>{g!==e&&(!p||p({level:s,value:r,field:t,newExpandValue:e}))&&k(e)},M=e=>{if("ArrowRight"===e.key||"ArrowLeft"===e.key)e.preventDefault(),O("ArrowRight"===e.key);else if("ArrowUp"===e.key||"ArrowDown"===e.key){e.preventDefault();let t="ArrowUp"===e.key?-1:1;if(!m.current)return;let r=m.current.querySelectorAll("[role=button]"),n=-1;for(let e=0;e{var e;O(!g);let t=y.current;if(!t)return;let r=null===(e=m.current)||void 0===e?void 0:e.querySelector('[role=button][tabindex="0"]');r&&(r.tabIndex=-1),t.tabIndex=0,t.focus()};return(0,n.createElement)("div",{className:c.basicChildStyle,role:"treeitem","aria-expanded":g,"aria-selected":void 0},(0,n.createElement)("span",{className:x,onClick:Z,onKeyDown:M,role:"button","aria-label":w,"aria-expanded":g,"aria-controls":g?v:void 0,ref:y,tabIndex:0===s?0:-1}),(t||""===t)&&(d?(0,n.createElement)("span",{className:c.clickableLabel,onClick:Z,onKeyDown:M},h(t,c.quotesForFieldNames),":"):(0,n.createElement)("span",{className:c.label},h(t,c.quotesForFieldNames),":")),(0,n.createElement)("span",{className:c.punctuation},l),g?(0,n.createElement)("ul",{id:v,role:"group",className:c.childFieldsContainer},o.map((e,t)=>(0,n.createElement)(b,{key:e[0]||t,field:e[0],value:e[1],style:c,lastElement:t===C,level:E,shouldExpandNode:u,clickToExpandNode:d,beforeExpandChange:p,outerRef:m}))):(0,n.createElement)("span",{className:c.collapsedContent,onClick:Z,onKeyDown:M}),(0,n.createElement)("span",{className:c.punctuation},i),!a&&(0,n.createElement)("span",{className:c.punctuation},","))}function p(e){let{field:t,value:r,style:n,lastElement:o,shouldExpandNode:a,clickToExpandNode:l,level:i,outerRef:s,beforeExpandChange:c}=e;return m({field:t,value:r,lastElement:o||!1,level:i,openBracket:"{",closeBracket:"}",style:n,shouldExpandNode:a,clickToExpandNode:l,data:Object.keys(r).map(e=>[e,r[e]]),outerRef:s,beforeExpandChange:c})}function f(e){let{field:t,value:r,style:n,lastElement:o,level:a,shouldExpandNode:l,clickToExpandNode:i,outerRef:s,beforeExpandChange:c}=e;return m({field:t,value:r,lastElement:o||!1,level:a,openBracket:"[",closeBracket:"]",style:n,shouldExpandNode:l,clickToExpandNode:i,data:r.map(e=>[void 0,e]),outerRef:s,beforeExpandChange:c})}function g(e){let t,{field:r,value:c,style:u,lastElement:m}=e,p=u.otherValue;if(null===c)t="null",p=u.nullValue;else if(void 0===c)t="undefined",p=u.undefinedValue;else if(s(c)){var f;f=!u.noQuotesForStringValues,t=u.stringifyStringValues?JSON.stringify(c):f?`"${c}"`:c,p=u.stringValue}else o(c)?(t=c?"true":"false",p=u.booleanValue):a(c)?(t=c.toString(),p=u.numberValue):l(c)?(t=`${c.toString()}n`,p=u.numberValue):t=i(c)?c.toISOString():d(c)?"function() { }":c.toString();return(0,n.createElement)("div",{className:u.basicChildStyle,role:"treeitem","aria-selected":void 0},(r||""===r)&&(0,n.createElement)("span",{className:u.label},h(r,u.quotesForFieldNames),":"),(0,n.createElement)("span",{className:p},t),!m&&(0,n.createElement)("span",{className:u.punctuation},","))}function b(e){let t=e.value;return c(t)?(0,n.createElement)(f,Object.assign({},e)):!u(t)||i(t)||d(t)?(0,n.createElement)(g,Object.assign({},e)):(0,n.createElement)(p,Object.assign({},e))}let k={container:"_2IvMF _GzYRV",basicChildStyle:"_2bkNM",childFieldsContainer:"_1BXBN",label:"_1MGIk",clickableLabel:"_2YKJg _1MGIk _1MFti",nullValue:"_2T6PJ",undefinedValue:"_1Gho6",stringValue:"_vGjyY",booleanValue:"_3zQKs",numberValue:"_1bQdo",otherValue:"_1xvuR",punctuation:"_3uHL6 _3eOF8",collapseIcon:"_oLqym _f10Tu _1MFti _1LId0",expandIcon:"_2AXVT _f10Tu _1MFti _1UmXx",collapsedContent:"_2KJWg _1pNG9 _1MFti",noQuotesForStringValues:!1,quotesForFieldNames:!1,ariaLables:{collapseJson:"collapse JSON",expandJson:"expand JSON"},stringifyStringValues:!1},y=()=>!0,v=e=>{let{data:t,style:r=k,shouldExpandNode:o=y,clickToExpandNode:a=!1,beforeExpandChange:l,compactTopLevel:i,...s}=e,c=(0,n.useRef)(null);return(0,n.createElement)("div",Object.assign({"aria-label":"JSON view"},s,{className:r.container,ref:c,role:"tree"}),i&&u(t)?Object.entries(t).map(e=>{let[t,i]=e;return(0,n.createElement)(b,{key:t,field:t,value:i,style:{...k,...r},lastElement:!0,level:1,shouldExpandNode:o,clickToExpandNode:a,beforeExpandChange:l,outerRef:c})}):(0,n.createElement)(b,{value:t,style:{...k,...r},lastElement:!0,level:0,shouldExpandNode:o,clickToExpandNode:a,outerRef:c,beforeExpandChange:l}))}},1479:function(e,t){"use strict";t.Z={'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%)"}}},52621:function(){},82422:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 13l4 4L19 7"}))});t.Z=o},51853:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.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"}))});t.Z=o},71437:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"}),n.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"}))});t.Z=o},82376:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21"}))});t.Z=o},2356:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.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"}))});t.Z=o},17732:function(e,t,r){"use strict";var n=r(2265);let o=n.forwardRef(function(e,t){return n.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),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"}))});t.Z=o},21623:function(e,t,r){"use strict";r.d(t,{S:function(){return f}});var n=r(45345),o=r(21733),a=r(18238),l=r(24112),i=class extends l.l{constructor(e={}){super(),this.config=e,this.#e=new Map}#e;build(e,t,r){let a=t.queryKey,l=t.queryHash??(0,n.Rm)(a,t),i=this.get(l);return i||(i=new o.A({client:e,queryKey:a,queryHash:l,options:e.defaultQueryOptions(t),state:r,defaultOptions:e.getQueryDefaults(a)}),this.add(i)),i}add(e){this.#e.has(e.queryHash)||(this.#e.set(e.queryHash,e),this.notify({type:"added",query:e}))}remove(e){let t=this.#e.get(e.queryHash);t&&(e.destroy(),t===e&&this.#e.delete(e.queryHash),this.notify({type:"removed",query:e}))}clear(){a.Vr.batch(()=>{this.getAll().forEach(e=>{this.remove(e)})})}get(e){return this.#e.get(e)}getAll(){return[...this.#e.values()]}find(e){let t={exact:!0,...e};return this.getAll().find(e=>(0,n._x)(t,e))}findAll(e={}){let t=this.getAll();return Object.keys(e).length>0?t.filter(t=>(0,n._x)(e,t)):t}notify(e){a.Vr.batch(()=>{this.listeners.forEach(t=>{t(e)})})}onFocus(){a.Vr.batch(()=>{this.getAll().forEach(e=>{e.onFocus()})})}onOnline(){a.Vr.batch(()=>{this.getAll().forEach(e=>{e.onOnline()})})}},s=r(2894),c=class extends l.l{constructor(e={}){super(),this.config=e,this.#t=new Set,this.#r=new Map,this.#n=0}#t;#r;#n;build(e,t,r){let n=new s.m({client:e,mutationCache:this,mutationId:++this.#n,options:e.defaultMutationOptions(t),state:r});return this.add(n),n}add(e){this.#t.add(e);let t=u(e);if("string"==typeof t){let r=this.#r.get(t);r?r.push(e):this.#r.set(t,[e])}this.notify({type:"added",mutation:e})}remove(e){if(this.#t.delete(e)){let t=u(e);if("string"==typeof t){let r=this.#r.get(t);if(r){if(r.length>1){let t=r.indexOf(e);-1!==t&&r.splice(t,1)}else r[0]===e&&this.#r.delete(t)}}}this.notify({type:"removed",mutation:e})}canRun(e){let t=u(e);if("string"!=typeof t)return!0;{let r=this.#r.get(t),n=r?.find(e=>"pending"===e.state.status);return!n||n===e}}runNext(e){let t=u(e);if("string"!=typeof t)return Promise.resolve();{let r=this.#r.get(t)?.find(t=>t!==e&&t.state.isPaused);return r?.continue()??Promise.resolve()}}clear(){a.Vr.batch(()=>{this.#t.forEach(e=>{this.notify({type:"removed",mutation:e})}),this.#t.clear(),this.#r.clear()})}getAll(){return Array.from(this.#t)}find(e){let t={exact:!0,...e};return this.getAll().find(e=>(0,n.X7)(t,e))}findAll(e={}){return this.getAll().filter(t=>(0,n.X7)(e,t))}notify(e){a.Vr.batch(()=>{this.listeners.forEach(t=>{t(e)})})}resumePausedMutations(){let e=this.getAll().filter(e=>e.state.isPaused);return a.Vr.batch(()=>Promise.all(e.map(e=>e.continue().catch(n.ZT))))}};function u(e){return e.options.scope?.id}var d=r(87045),h=r(57853);function m(e){return{onFetch:(t,r)=>{let o=t.options,a=t.fetchOptions?.meta?.fetchMore?.direction,l=t.state.data?.pages||[],i=t.state.data?.pageParams||[],s={pages:[],pageParams:[]},c=0,u=async()=>{let r=!1,u=e=>{Object.defineProperty(e,"signal",{enumerable:!0,get:()=>(t.signal.aborted?r=!0:t.signal.addEventListener("abort",()=>{r=!0}),t.signal)})},d=(0,n.cG)(t.options,t.fetchOptions),h=async(e,o,a)=>{if(r)return Promise.reject();if(null==o&&e.pages.length)return Promise.resolve(e);let l=(()=>{let e={client:t.client,queryKey:t.queryKey,pageParam:o,direction:a?"backward":"forward",meta:t.options.meta};return u(e),e})(),i=await d(l),{maxPages:s}=t.options,c=a?n.Ht:n.VX;return{pages:c(e.pages,i,s),pageParams:c(e.pageParams,o,s)}};if(a&&l.length){let e="backward"===a,t={pages:l,pageParams:i},r=(e?function(e,{pages:t,pageParams:r}){return t.length>0?e.getPreviousPageParam?.(t[0],t,r[0],r):void 0}:p)(o,t);s=await h(t,r,e)}else{let t=e??l.length;do{let e=0===c?i[0]??o.initialPageParam:p(o,s);if(c>0&&null==e)break;s=await h(s,e),c++}while(ct.options.persister?.(u,{client:t.client,queryKey:t.queryKey,meta:t.options.meta,signal:t.signal},r):t.fetchFn=u}}}function p(e,{pages:t,pageParams:r}){let n=t.length-1;return t.length>0?e.getNextPageParam(t[n],t,r[n],r):void 0}var f=class{#o;#a;#l;#i;#s;#c;#u;#d;constructor(e={}){this.#o=e.queryCache||new i,this.#a=e.mutationCache||new c,this.#l=e.defaultOptions||{},this.#i=new Map,this.#s=new Map,this.#c=0}mount(){this.#c++,1===this.#c&&(this.#u=d.j.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#o.onFocus())}),this.#d=h.N.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#o.onOnline())}))}unmount(){this.#c--,0===this.#c&&(this.#u?.(),this.#u=void 0,this.#d?.(),this.#d=void 0)}isFetching(e){return this.#o.findAll({...e,fetchStatus:"fetching"}).length}isMutating(e){return this.#a.findAll({...e,status:"pending"}).length}getQueryData(e){let t=this.defaultQueryOptions({queryKey:e});return this.#o.get(t.queryHash)?.state.data}ensureQueryData(e){let t=this.defaultQueryOptions(e),r=this.#o.build(this,t),o=r.state.data;return void 0===o?this.fetchQuery(e):(e.revalidateIfStale&&r.isStaleByTime((0,n.KC)(t.staleTime,r))&&this.prefetchQuery(t),Promise.resolve(o))}getQueriesData(e){return this.#o.findAll(e).map(({queryKey:e,state:t})=>[e,t.data])}setQueryData(e,t,r){let o=this.defaultQueryOptions({queryKey:e}),a=this.#o.get(o.queryHash),l=a?.state.data,i=(0,n.SE)(t,l);if(void 0!==i)return this.#o.build(this,o).setData(i,{...r,manual:!0})}setQueriesData(e,t,r){return a.Vr.batch(()=>this.#o.findAll(e).map(({queryKey:e})=>[e,this.setQueryData(e,t,r)]))}getQueryState(e){let t=this.defaultQueryOptions({queryKey:e});return this.#o.get(t.queryHash)?.state}removeQueries(e){let t=this.#o;a.Vr.batch(()=>{t.findAll(e).forEach(e=>{t.remove(e)})})}resetQueries(e,t){let r=this.#o;return a.Vr.batch(()=>(r.findAll(e).forEach(e=>{e.reset()}),this.refetchQueries({type:"active",...e},t)))}cancelQueries(e,t={}){let r={revert:!0,...t};return Promise.all(a.Vr.batch(()=>this.#o.findAll(e).map(e=>e.cancel(r)))).then(n.ZT).catch(n.ZT)}invalidateQueries(e,t={}){return a.Vr.batch(()=>(this.#o.findAll(e).forEach(e=>{e.invalidate()}),e?.refetchType==="none")?Promise.resolve():this.refetchQueries({...e,type:e?.refetchType??e?.type??"active"},t))}refetchQueries(e,t={}){let r={...t,cancelRefetch:t.cancelRefetch??!0};return Promise.all(a.Vr.batch(()=>this.#o.findAll(e).filter(e=>!e.isDisabled()&&!e.isStatic()).map(e=>{let t=e.fetch(void 0,r);return r.throwOnError||(t=t.catch(n.ZT)),"paused"===e.state.fetchStatus?Promise.resolve():t}))).then(n.ZT)}fetchQuery(e){let t=this.defaultQueryOptions(e);void 0===t.retry&&(t.retry=!1);let r=this.#o.build(this,t);return r.isStaleByTime((0,n.KC)(t.staleTime,r))?r.fetch(t):Promise.resolve(r.state.data)}prefetchQuery(e){return this.fetchQuery(e).then(n.ZT).catch(n.ZT)}fetchInfiniteQuery(e){return e.behavior=m(e.pages),this.fetchQuery(e)}prefetchInfiniteQuery(e){return this.fetchInfiniteQuery(e).then(n.ZT).catch(n.ZT)}ensureInfiniteQueryData(e){return e.behavior=m(e.pages),this.ensureQueryData(e)}resumePausedMutations(){return h.N.isOnline()?this.#a.resumePausedMutations():Promise.resolve()}getQueryCache(){return this.#o}getMutationCache(){return this.#a}getDefaultOptions(){return this.#l}setDefaultOptions(e){this.#l=e}setQueryDefaults(e,t){this.#i.set((0,n.Ym)(e),{queryKey:e,defaultOptions:t})}getQueryDefaults(e){let t=[...this.#i.values()],r={};return t.forEach(t=>{(0,n.to)(e,t.queryKey)&&Object.assign(r,t.defaultOptions)}),r}setMutationDefaults(e,t){this.#s.set((0,n.Ym)(e),{mutationKey:e,defaultOptions:t})}getMutationDefaults(e){let t=[...this.#s.values()],r={};return t.forEach(t=>{(0,n.to)(e,t.mutationKey)&&Object.assign(r,t.defaultOptions)}),r}defaultQueryOptions(e){if(e._defaulted)return e;let t={...this.#l.queries,...this.getQueryDefaults(e.queryKey),...e,_defaulted:!0};return t.queryHash||(t.queryHash=(0,n.Rm)(t.queryKey,t)),void 0===t.refetchOnReconnect&&(t.refetchOnReconnect="always"!==t.networkMode),void 0===t.throwOnError&&(t.throwOnError=!!t.suspense),!t.networkMode&&t.persister&&(t.networkMode="offlineFirst"),t.queryFn===n.CN&&(t.enabled=!1),t}defaultMutationOptions(e){return e?._defaulted?e:{...this.#l.mutations,...e?.mutationKey&&this.getMutationDefaults(e.mutationKey),...e,_defaulted:!0}}clear(){this.#o.clear(),this.#a.clear()}}},19616:function(e,t,r){"use strict";r.d(t,{G:function(){return l}});var n=r(2265);let o={enabled:!0,leading:!1,trailing:!0,wait:0,onExecute:()=>{}};class a{constructor(e,t){this.fn=e,this._canLeadingExecute=!0,this._isPending=!1,this._executionCount=0,this._options={...o,...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 l(e,t){let[r,o]=(0,n.useState)(e),l=function(e,t){let[r]=(0,n.useState)(()=>{var r;return Object.getOwnPropertyNames(Object.getPrototypeOf(r=new a(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 r.setOptions(t),r}(o,t);return[r,l.maybeExecute,l]}}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/6894-8c74216e23aa271e.js b/litellm/proxy/_experimental/out/_next/static/chunks/2068-2c78bfc32dc0de5f.js similarity index 89% rename from litellm/proxy/_experimental/out/_next/static/chunks/6894-8c74216e23aa271e.js rename to litellm/proxy/_experimental/out/_next/static/chunks/2068-2c78bfc32dc0de5f.js index 7b7fe0e8953..7a344f59032 100644 --- a/litellm/proxy/_experimental/out/_next/static/chunks/6894-8c74216e23aa271e.js +++ b/litellm/proxy/_experimental/out/_next/static/chunks/2068-2c78bfc32dc0de5f.js @@ -1,4 +1,4 @@ -"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[6894],{21626:function(e,t,l){l.d(t,{Z:function(){return a}});var n=l(5853),o=l(2265),i=l(13241);let r=(0,l(1153).fn)("Table"),a=o.forwardRef((e,t)=>{let{children:l,className:a}=e,u=(0,n._T)(e,["children","className"]);return o.createElement("div",{className:(0,i.q)(r("root"),"overflow-auto",a)},o.createElement("table",Object.assign({ref:t,className:(0,i.q)(r("table"),"w-full text-tremor-default","text-tremor-content","dark:text-dark-tremor-content")},u),l))});a.displayName="Table"},97214:function(e,t,l){l.d(t,{Z:function(){return a}});var n=l(5853),o=l(2265),i=l(13241);let r=(0,l(1153).fn)("TableBody"),a=o.forwardRef((e,t)=>{let{children:l,className:a}=e,u=(0,n._T)(e,["children","className"]);return o.createElement(o.Fragment,null,o.createElement("tbody",Object.assign({ref:t,className:(0,i.q)(r("root"),"align-top divide-y","divide-tremor-border","dark:divide-dark-tremor-border",a)},u),l))});a.displayName="TableBody"},28241:function(e,t,l){l.d(t,{Z:function(){return a}});var n=l(5853),o=l(2265),i=l(13241);let r=(0,l(1153).fn)("TableCell"),a=o.forwardRef((e,t)=>{let{children:l,className:a}=e,u=(0,n._T)(e,["children","className"]);return o.createElement(o.Fragment,null,o.createElement("td",Object.assign({ref:t,className:(0,i.q)(r("root"),"align-middle whitespace-nowrap text-left p-4",a)},u),l))});a.displayName="TableCell"},58834:function(e,t,l){l.d(t,{Z:function(){return a}});var n=l(5853),o=l(2265),i=l(13241);let r=(0,l(1153).fn)("TableHead"),a=o.forwardRef((e,t)=>{let{children:l,className:a}=e,u=(0,n._T)(e,["children","className"]);return o.createElement(o.Fragment,null,o.createElement("thead",Object.assign({ref:t,className:(0,i.q)(r("root"),"text-left","text-tremor-content","dark:text-dark-tremor-content",a)},u),l))});a.displayName="TableHead"},69552:function(e,t,l){l.d(t,{Z:function(){return a}});var n=l(5853),o=l(2265),i=l(13241);let r=(0,l(1153).fn)("TableHeaderCell"),a=o.forwardRef((e,t)=>{let{children:l,className:a}=e,u=(0,n._T)(e,["children","className"]);return o.createElement(o.Fragment,null,o.createElement("th",Object.assign({ref:t,className:(0,i.q)(r("root"),"whitespace-nowrap text-left font-semibold top-0 px-4 py-3.5","text-tremor-content-strong","dark:text-dark-tremor-content-strong",a)},u),l))});a.displayName="TableHeaderCell"},71876:function(e,t,l){l.d(t,{Z:function(){return a}});var n=l(5853),o=l(2265),i=l(13241);let r=(0,l(1153).fn)("TableRow"),a=o.forwardRef((e,t)=>{let{children:l,className:a}=e,u=(0,n._T)(e,["children","className"]);return o.createElement(o.Fragment,null,o.createElement("tr",Object.assign({ref:t,className:(0,i.q)(r("row"),a)},u),l))});a.displayName="TableRow"},71594:function(e,t,l){l.d(t,{b7:function(){return r},ie:function(){return i}});var n=l(2265),o=l(24525);function i(e,t){return e?"function"==typeof e&&(()=>{let t=Object.getPrototypeOf(e);return t.prototype&&t.prototype.isReactComponent})()||"function"==typeof e||"object"==typeof e&&"symbol"==typeof e.$$typeof&&["react.memo","react.forward_ref"].includes(e.$$typeof.description)?n.createElement(e,t):e:null}function r(e){let t={state:{},onStateChange:()=>{},renderFallbackValue:null,...e},[l]=n.useState(()=>({current:(0,o.W_)(t)})),[i,r]=n.useState(()=>l.current.initialState);return l.current.setOptions(t=>({...t,...e,state:{...i,...e.state},onStateChange:t=>{r(t),null==e.onStateChange||e.onStateChange(t)}})),l.current}},24525:function(e,t,l){function n(e,t){return"function"==typeof e?e(t):e}function o(e,t){return l=>{t.setState(t=>({...t,[e]:n(l,t[e])}))}}function i(e){return e instanceof Function}function r(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{let{color:l,children:u,className:g}=e,s=(0,n._T)(e,["color","children","className"]);return a.createElement("p",Object.assign({ref:t,className:(0,i.q)("font-medium text-tremor-title",l?(0,r.bM)(l,o.K.darkText).textColor:"text-tremor-content-strong dark:text-dark-tremor-content-strong",g)},s),u)});u.displayName="Title"},71594:function(e,t,l){l.d(t,{b7:function(){return r},ie:function(){return i}});var n=l(2265),o=l(24525);function i(e,t){return e?"function"==typeof e&&(()=>{let t=Object.getPrototypeOf(e);return t.prototype&&t.prototype.isReactComponent})()||"function"==typeof e||"object"==typeof e&&"symbol"==typeof e.$$typeof&&["react.memo","react.forward_ref"].includes(e.$$typeof.description)?n.createElement(e,t):e:null}function r(e){let t={state:{},onStateChange:()=>{},renderFallbackValue:null,...e},[l]=n.useState(()=>({current:(0,o.W_)(t)})),[i,r]=n.useState(()=>l.current.initialState);return l.current.setOptions(t=>({...t,...e,state:{...i,...e.state},onStateChange:t=>{r(t),null==e.onStateChange||e.onStateChange(t)}})),l.current}},24525:function(e,t,l){function n(e,t){return"function"==typeof e?e(t):e}function o(e,t){return l=>{t.setState(t=>({...t,[e]:n(l,t[e])}))}}function i(e){return e instanceof Function}function r(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}}l.d(t,{G_:function(){return X},W_:function(){return q},rV:function(){return U},sC:function(){return j},tj:function(){return Z}});let u="debugHeaders";function g(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 s(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 u=[],s=(e,t)=>{let o={depth:t,id:[n,`${t}`].filter(Boolean).join("_"),headers:[]},i=[];e.forEach(e=>{let r;let a=[...i].reverse()[0],u=e.column.depth===o.depth,s=!1;if(u&&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=g(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}),u.push(o),t>0&&s(i,t-1)};s(t.map((e,t)=>g(l,e,{depth:r,index:t})),r-1),u.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=u[0])?void 0:i.headers)?o:[]),u}let d=(e,t,l,n,o,i,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);return null!=l&&l.accessorFn?(l.columnDef.getUniqueValues?g._uniqueValuesCache[t]=l.columnDef.getUniqueValues(g.original,n):g._uniqueValuesCache[t]=[g.getValue(t)],g._uniqueValuesCache[t]):void 0},renderValue:t=>{var l;return null!=(l=g.getValue(t))?l:e.options.renderFallbackValue},subRows:null!=i?i:[],getLeafRows:()=>(function(e,t){let l=[],n=e=>{e.forEach(e=>{l.push(e);let o=t(e);null!=o&&o.length&&n(o)})};return n(e),l})(g.subRows,e=>e.subRows),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:r(()=>[e.getAllLeafColumns()],t=>t.map(t=>(function(e,t,l,n){let o={id:`${t.id}_${l.id}`,row:t,column:l,getValue:()=>t.getValue(n),renderValue:()=>{var t;return null!=(t=o.getValue())?t:e.options.renderFallbackValue},getContext:r(()=>[e,l,t,o],(e,t,l,n)=>({table:e,column:t,row:l,cell:n,getValue:n.getValue,renderValue:n.renderValue}),a(e.options,"debugCells","cell.getContext"))};return e._features.forEach(n=>{null==n.createCell||n.createCell(o,l,t,e)},{}),o})(e,g,t,t.id)),a(e.options,"debugRows","getAllCells")),_getAllCellsByColumnId:r(()=>[g.getAllCells()],e=>e.reduce((e,t)=>(e[t.column.id]=t,e),{}),a(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))};c.autoRemove=e=>R(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=>R(e);let f=(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())};f.autoRemove=e=>R(e);let m=(e,t,l)=>{var n;return null==(n=e.getValue(t))?void 0:n.includes(l)};m.autoRemove=e=>R(e);let C=(e,t,l)=>!l.some(l=>{var n;return!(null!=(n=e.getValue(t))&&n.includes(l))});C.autoRemove=e=>R(e)||!(null!=e&&e.length);let w=(e,t,l)=>l.some(l=>{var n;return null==(n=e.getValue(t))?void 0:n.includes(l)});w.autoRemove=e=>R(e)||!(null!=e&&e.length);let S=(e,t,l)=>e.getValue(t)===l;S.autoRemove=e=>R(e);let h=(e,t,l)=>e.getValue(t)==l;h.autoRemove=e=>R(e);let b=(e,t,l)=>{let[n,o]=l,i=e.getValue(t);return i>=n&&i<=o};b.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]},b.autoRemove=e=>R(e)||R(e[0])&&R(e[1]);let v={includesString:c,includesStringSensitive:p,equalsString:f,arrIncludes:m,arrIncludesAll:C,arrIncludesSome:w,equals:S,weakEquals:h,inNumberRange:b};function R(e){return null==e||""===e}function F(e,t,l){return!!e&&!!e.autoRemove&&e.autoRemove(t,l)||void 0===t||"string"==typeof t&&!t}let M={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=+o)>=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},V=()=>({left:[],right:[]}),P={size:150,minSize:20,maxSize:Number.MAX_SAFE_INTEGER},I=()=>({startOffset:null,startSize:null,deltaOffset:null,deltaPercentage:null,isResizingColumn:!1,columnSizingStart:[]}),x=null;function _(e){return"touchstart"===e.type}function y(e,t){return t?"center"===t?e.getCenterVisibleLeafColumns():"left"===t?e.getLeftVisibleLeafColumns():e.getRightVisibleLeafColumns():e.getVisibleLeafColumns()}let E=()=>({pageIndex:0,pageSize:10}),G=()=>({top:[],bottom:[]}),L=(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=>L(e,t.id,l,n,o))};function A(e,t){let l=e.getState().rowSelection,n=[],o={},i=function(e,t){return e.map(e=>{var t;let r=H(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 H(e,t){var l;return null!=(l=t[e.id])&&l}function D(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()&&(H(e,t)?i=!0:o=!1),e.subRows&&e.subRows.length)){let l=D(e,t);"all"===l?i=!0:("some"===l&&(i=!0),o=!1)}}),o?"all":!!i&&"some"}let z=/([0-9]+)/gm;function O(e,t){return e===t?0:e>t?1:-1}function T(e){return"number"==typeof e?isNaN(e)||e===1/0||e===-1/0?"":String(e):"string"==typeof e?e:""}function N(e,t){let l=e.split(z).filter(Boolean),n=t.split(z).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)=>N(T(e.getValue(l)).toLowerCase(),T(t.getValue(l)).toLowerCase()),alphanumericCaseSensitive:(e,t,l)=>N(T(e.getValue(l)),T(t.getValue(l))),text:(e,t,l)=>O(T(e.getValue(l)).toLowerCase(),T(t.getValue(l)).toLowerCase()),textCaseSensitive:(e,t,l)=>O(T(e.getValue(l)),T(t.getValue(l))),datetime:(e,t,l)=>{let n=e.getValue(l),o=t.getValue(l);return n>o?1:nO(e.getValue(l),t.getValue(l))},k=[{createTable:e=>{e.getHeaderGroups=r(()=>[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 s(t,[...a,...l.filter(e=>!(null!=n&&n.includes(e.id))&&!(null!=o&&o.includes(e.id))),...u],e)},a(e.options,u,"getHeaderGroups")),e.getCenterHeaderGroups=r(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.left,e.getState().columnPinning.right],(t,l,n,o)=>s(t,l=l.filter(e=>!(null!=n&&n.includes(e.id))&&!(null!=o&&o.includes(e.id))),e,"center"),a(e.options,u,"getCenterHeaderGroups")),e.getLeftHeaderGroups=r(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.left],(t,l,n)=>{var o;return s(t,null!=(o=null==n?void 0:n.map(e=>l.find(t=>t.id===e)).filter(Boolean))?o:[],e,"left")},a(e.options,u,"getLeftHeaderGroups")),e.getRightHeaderGroups=r(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.right],(t,l,n)=>{var o;return s(t,null!=(o=null==n?void 0:n.map(e=>l.find(t=>t.id===e)).filter(Boolean))?o:[],e,"right")},a(e.options,u,"getRightHeaderGroups")),e.getFooterGroups=r(()=>[e.getHeaderGroups()],e=>[...e].reverse(),a(e.options,u,"getFooterGroups")),e.getLeftFooterGroups=r(()=>[e.getLeftHeaderGroups()],e=>[...e].reverse(),a(e.options,u,"getLeftFooterGroups")),e.getCenterFooterGroups=r(()=>[e.getCenterHeaderGroups()],e=>[...e].reverse(),a(e.options,u,"getCenterFooterGroups")),e.getRightFooterGroups=r(()=>[e.getRightHeaderGroups()],e=>[...e].reverse(),a(e.options,u,"getRightFooterGroups")),e.getFlatHeaders=r(()=>[e.getHeaderGroups()],e=>e.map(e=>e.headers).flat(),a(e.options,u,"getFlatHeaders")),e.getLeftFlatHeaders=r(()=>[e.getLeftHeaderGroups()],e=>e.map(e=>e.headers).flat(),a(e.options,u,"getLeftFlatHeaders")),e.getCenterFlatHeaders=r(()=>[e.getCenterHeaderGroups()],e=>e.map(e=>e.headers).flat(),a(e.options,u,"getCenterFlatHeaders")),e.getRightFlatHeaders=r(()=>[e.getRightHeaderGroups()],e=>e.map(e=>e.headers).flat(),a(e.options,u,"getRightFlatHeaders")),e.getCenterLeafHeaders=r(()=>[e.getCenterFlatHeaders()],e=>e.filter(e=>{var t;return!(null!=(t=e.subHeaders)&&t.length)}),a(e.options,u,"getCenterLeafHeaders")),e.getLeftLeafHeaders=r(()=>[e.getLeftFlatHeaders()],e=>e.filter(e=>{var t;return!(null!=(t=e.subHeaders)&&t.length)}),a(e.options,u,"getLeftLeafHeaders")),e.getRightLeafHeaders=r(()=>[e.getRightFlatHeaders()],e=>e.filter(e=>{var t;return!(null!=(t=e.subHeaders)&&t.length)}),a(e.options,u,"getRightLeafHeaders")),e.getLeafHeaders=r(()=>[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()},a(e.options,u,"getLeafHeaders"))}},{getInitialState:e=>({columnVisibility:{},...e}),getDefaultOptions:e=>({onColumnVisibilityChange:o("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=r(()=>[e.getAllCells(),t.getState().columnVisibility],e=>e.filter(e=>e.column.getIsVisible()),a(t.options,"debugRows","_getAllVisibleCells")),e.getVisibleCells=r(()=>[e.getLeftVisibleCells(),e.getCenterVisibleCells(),e.getRightVisibleCells()],(e,t,l)=>[...e,...t,...l],a(t.options,"debugRows","getVisibleCells"))},createTable:e=>{let t=(t,l)=>r(()=>[l(),l().filter(e=>e.getIsVisible()).map(e=>e.id).join("_")],e=>e.filter(e=>null==e.getIsVisible?void 0:e.getIsVisible()),a(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:o("columnOrder",e)}),createColumn:(e,t)=>{e.getIndex=r(e=>[y(t,e)],t=>t.findIndex(t=>t.id===e.id),a(t.options,"debugColumns","getIndex")),e.getIsFirstColumn=l=>{var n;return(null==(n=y(t,l)[0])?void 0:n.id)===e.id},e.getIsLastColumn=l=>{var n;let o=y(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=r(()=>[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;return function(e,t,l){if(!(null!=t&&t.length)||!l)return e;let n=e.filter(e=>!t.includes(e.id));return"remove"===l?n:[...t.map(t=>e.find(e=>e.id===t)).filter(Boolean),...n]}(o,t,l)},a(e.options,"debugTable","_getOrderColumnsFn"))}},{getInitialState:e=>({columnPinning:V(),...e}),getDefaultOptions:e=>({onColumnPinningChange:o("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=r(()=>[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))},a(t.options,"debugRows","getCenterVisibleCells")),e.getLeftVisibleCells=r(()=>[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"})),a(t.options,"debugRows","getLeftVisibleCells")),e.getRightVisibleCells=r(()=>[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"})),a(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?V():null!=(l=null==(n=e.initialState)?void 0:n.columnPinning)?l:V())},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=r(()=>[e.getAllLeafColumns(),e.getState().columnPinning.left],(e,t)=>(null!=t?t:[]).map(t=>e.find(e=>e.id===t)).filter(Boolean),a(e.options,"debugColumns","getLeftLeafColumns")),e.getRightLeafColumns=r(()=>[e.getAllLeafColumns(),e.getState().columnPinning.right],(e,t)=>(null!=t?t:[]).map(t=>e.find(e=>e.id===t)).filter(Boolean),a(e.options,"debugColumns","getRightLeafColumns")),e.getCenterLeafColumns=r(()=>[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))},a(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:o("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 i(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=l=>{t.setColumnFilters(t=>{var o,i;let r=e.getFilterFn(),a=null==t?void 0:t.find(t=>t.id===e.id),u=n(l,a?a.value:void 0);if(F(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 l=e.getAllLeafColumns();null==e.options.onColumnFiltersChange||e.options.onColumnFiltersChange(e=>{var o;return null==(o=n(t,e))?void 0:o.filter(e=>{let t=l.find(t=>t.id===e.id);return!(t&&F(t.getFilterFn(),e.value,t))})})},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:o("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 i(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:o("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(z).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 i(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;let 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 c;(s=[...r,{id:e.id,desc:d}]).splice(0,s.length-(null!=(c=t.options.maxMultiSortColCount)?c: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:o("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?M.sum:"[object Date]"===Object.prototype.toString.call(n)?M.extent:void 0},e.getAggregationFn=()=>{var l,n;if(!e)throw Error();return i(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:M[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:o("expanded",e),paginateExpandedRows:!0}),createTable:e=>{let t=!1,l=!1;e._autoResetExpanded=()=>{var n,o;if(!t){e._queue(()=>{t=!0});return}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:{...E(),...null==e?void 0:e.pagination}}),getDefaultOptions:e=>({onPaginationChange:o("pagination",e)}),createTable:e=>{let t=!1,l=!1;e._autoResetPageIndex=()=>{var n,o;if(!t){e._queue(()=>{t=!0});return}if(null!=(n=null!=(o=e.options.autoResetAll)?o:e.options.autoResetPageIndex)?n:!e.options.manualPagination){if(l)return;l=!0,e._queue(()=>{e.resetPageIndex(),l=!1})}},e.setPagination=t=>null==e.options.onPaginationChange?void 0:e.options.onPaginationChange(e=>n(t,e)),e.resetPagination=t=>{var l;e.setPagination(t?E():null!=(l=e.initialState.pagination)?l:E())},e.setPageIndex=t=>{e.setPagination(l=>{let o=n(t,l.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)),{...l,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 l=Math.max(1,n(t,e.pageSize)),o=e.pageSize*e.pageIndex;return{...e,pageIndex:Math.floor(o/l),pageSize:l}})},e.setPageCount=t=>e.setPagination(l=>{var o;let i=n(t,null!=(o=e.options.pageCount)?o:-1);return"number"==typeof i&&(i=Math.max(-1,i)),{...l,pageCount:i}}),e.getPageOptions=r(()=>[e.getPageCount()],e=>{let t=[];return e&&e>0&&(t=[...Array(e)].fill(null).map((e,t)=>t)),t},a(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:G(),...e}),getDefaultOptions:e=>({onRowPinningChange:o("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?G():null!=(l=null==(n=e.initialState)?void 0:n.rowPinning)?l:G())},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=r(()=>[e.getRowModel().rows,e.getState().rowPinning.top],(t,l)=>e._getPinnedRows(t,l,"top"),a(e.options,"debugRows","getTopRows")),e.getBottomRows=r(()=>[e.getRowModel().rows,e.getState().rowPinning.bottom],(t,l)=>e._getPinnedRows(t,l,"bottom"),a(e.options,"debugRows","getBottomRows")),e.getCenterRows=r(()=>[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))},a(e.options,"debugRows","getCenterRows"))}},{getInitialState:e=>({rowSelection:{},...e}),getDefaultOptions:e=>({onRowSelectionChange:o("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=>{L(o,t.id,n,!0,e)}),o}),e.getPreSelectedRowModel=()=>e.getCoreRowModel(),e.getSelectedRowModel=r(()=>[e.getState().rowSelection,e.getCoreRowModel()],(t,l)=>Object.keys(t).length?A(e,l):{rows:[],flatRows:[],rowsById:{}},a(e.options,"debugTable","getSelectedRowModel")),e.getFilteredSelectedRowModel=r(()=>[e.getState().rowSelection,e.getFilteredRowModel()],(t,l)=>Object.keys(t).length?A(e,l):{rows:[],flatRows:[],rowsById:{}},a(e.options,"debugTable","getFilteredSelectedRowModel")),e.getGroupedSelectedRowModel=r(()=>[e.getState().rowSelection,e.getSortedRowModel()],(t,l)=>Object.keys(t).length?A(e,l):{rows:[],flatRows:[],rowsById:{}},a(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 L(a,e.id,l,null==(r=null==n?void 0:n.selectChildren)||r,t),a})},e.getIsSelected=()=>{let{rowSelection:l}=t.getState();return H(e,l)},e.getIsSomeSelected=()=>{let{rowSelection:l}=t.getState();return"some"===D(e,l)},e.getIsAllSubRowsSelected=()=>{let{rowSelection:l}=t.getState();return"all"===D(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:()=>P,getInitialState:e=>({columnSizing:{},columnSizingInfo:I(),...e}),getDefaultOptions:e=>({columnResizeMode:"onEnd",columnResizeDirection:"ltr",onColumnSizingChange:o("columnSizing",e),onColumnSizingInfoChange:o("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:P.minSize,null!=(n=null!=i?i:e.columnDef.size)?n:P.size),null!=(o=e.columnDef.maxSize)?o:P.maxSize)},e.getStart=r(e=>[e,y(t,e),t.getState().columnSizing],(t,l)=>l.slice(0,e.getIndex(t)).reduce((e,t)=>e+t.getSize(),0),a(t.options,"debugColumns","getStart")),e.getAfter=r(e=>[e,y(t,e),t.getState().columnSizing],(t,l)=>l.slice(e.getIndex(t)+1).reduce((e,t)=>e+t.getSize(),0),a(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(),_(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=_(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("move",e),c=e=>{s("end",e),t.setColumnSizingInfo(e=>({...e,isResizingColumn:!1,startOffset:null,startSize:null,deltaOffset:null,deltaPercentage:null,columnSizingStart:[]}))},p=l||("undefined"!=typeof document?document:null),f={moveHandler:e=>d(e.clientX),upHandler:e=>{null==p||p.removeEventListener("mousemove",f.moveHandler),null==p||p.removeEventListener("mouseup",f.upHandler),c(e.clientX)}},m={moveHandler:e=>(e.cancelable&&(e.preventDefault(),e.stopPropagation()),d(e.touches[0].clientX),!1),upHandler:e=>{var t;null==p||p.removeEventListener("touchmove",m.moveHandler),null==p||p.removeEventListener("touchend",m.upHandler),e.cancelable&&(e.preventDefault(),e.stopPropagation()),c(null==(t=e.touches[0])?void 0:t.clientX)}},C=!!function(){if("boolean"==typeof x)return x;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 x=e}()&&{passive:!1};_(i)?(null==p||p.addEventListener("touchmove",m.moveHandler,C),null==p||p.addEventListener("touchend",m.upHandler,C)):(null==p||p.addEventListener("mousemove",f.moveHandler,C),null==p||p.addEventListener("mouseup",f.upHandler,C)),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?I():null!=(l=e.initialState.columnSizingInfo)?l:I())},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 q(e){var t,l;let o=[...k,...null!=(t=e._features)?t:[]],i={_features:o},u=i._features.reduce((e,t)=>Object.assign(e,null==t.getDefaultOptions?void 0:t.getDefaultOptions(i)),{}),g=e=>i.options.mergeOptions?i.options.mergeOptions(u,e):{...u,...e},s={...null!=(l=e.initialState)?l:{}};i._features.forEach(e=>{var t;s=null!=(t=null==e.getInitialState?void 0:e.getInitialState(s))?t:s});let d=[],c=!1,p={_features:o,options:{...u,...e},initialState:s,_queue:e=>{d.push(e),c||(c=!0,Promise.resolve().then(()=>{for(;d.length;)d.shift()();c=!1}).catch(e=>setTimeout(()=>{throw e})))},reset:()=>{i.setState(i.initialState)},setOptions:e=>{let t=n(e,i.options);i.options=g(t)},getState:()=>i.options.state,setState:e=>{null==i.options.onStateChange||i.options.onStateChange(e)},_getRowId:(e,t,l)=>{var n;return null!=(n=null==i.options.getRowId?void 0:i.options.getRowId(e,t,l))?n:`${l?[l.id,t].join("."):t}`},getCoreRowModel:()=>(i._getCoreRowModel||(i._getCoreRowModel=i.options.getCoreRowModel(i)),i._getCoreRowModel()),getRowModel:()=>i.getPaginationRowModel(),getRow:(e,t)=>{let l=(t?i.getPrePaginationRowModel():i.getRowModel()).rowsById[e];if(!l&&!(l=i.getCoreRowModel().rowsById[e]))throw Error();return l},_getDefaultColumnDef:r(()=>[i.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},...i._features.reduce((e,t)=>Object.assign(e,null==t.getDefaultColumnDef?void 0:t.getDefaultColumnDef()),{}),...e}},a(e,"debugColumns","_getDefaultColumnDef")),_getColumnDefs:()=>i.options.columns,getAllColumns:r(()=>[i._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,i;let u;let g={...e._getDefaultColumnDef(),...t},s=g.accessorKey,d=null!=(o=null!=(i=g.id)?i: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 c={id:`${String(d)}`,accessorFn:u,parent:n,depth:l,columnDef:g,columns:[],getFlatColumns:r(()=>[!0],()=>{var e;return[c,...null==(e=c.columns)?void 0:e.flatMap(e=>e.getFlatColumns())]},a(e.options,"debugColumns","column.getFlatColumns")),getLeafColumns:r(()=>[e._getOrderColumnsFn()],e=>{var t;return null!=(t=c.columns)&&t.length?e(c.columns.flatMap(e=>e.getLeafColumns())):[c]},a(e.options,"debugColumns","column.getLeafColumns"))};for(let t of e._features)null==t.createColumn||t.createColumn(c,e);return c}(i,e,n,l);return o.columns=e.columns?t(e.columns,o,n+1):[],o})};return t(e)},a(e,"debugColumns","getAllColumns")),getAllFlatColumns:r(()=>[i.getAllColumns()],e=>e.flatMap(e=>e.getFlatColumns()),a(e,"debugColumns","getAllFlatColumns")),_getAllFlatColumnsById:r(()=>[i.getAllFlatColumns()],e=>e.reduce((e,t)=>(e[t.id]=t,e),{}),a(e,"debugColumns","getAllFlatColumnsById")),getAllLeafColumns:r(()=>[i.getAllColumns(),i._getOrderColumnsFn()],(e,t)=>t(e.flatMap(e=>e.getLeafColumns())),a(e,"debugColumns","getAllLeafColumns")),getColumn:e=>i._getAllFlatColumnsById()[e]};Object.assign(i,p);for(let e=0;er(()=>[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()))}function U(){return e=>r(()=>[e.getState().expanded,e.getPreExpandedRowModel(),e.options.paginateExpandedRows],(e,t,l)=>t.rows.length&&(!0===e||Object.keys(null!=e?e:{}).length)&&l?$(t):t,a(e.options,"debugTable","getExpandedRowModel"))}function $(e){let t=[],l=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}}function X(e){return e=>r(()=>[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}:$({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},a(e.options,"debugTable","getPaginationRowModel"))}function Z(){return e=>r(()=>[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}},a(e.options,"debugTable","getSortedRowModel",()=>e._autoResetPageIndex()))}}}]); \ No newline at end of file + color: hsl(${Math.max(0,Math.min(120-120*n,120))}deg 100% 31%);`,null==l?void 0:l.key)}return n}}function a(e,t,l,n){return{debug:()=>{var l;return null!=(l=null==e?void 0:e.debugAll)?l:e[t]},key:!1,onChange:n}}l.d(t,{G_:function(){return X},W_:function(){return N},rV:function(){return U},sC:function(){return j},tj:function(){return K}});let u="debugHeaders";function g(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 s(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 u=[],s=(e,t)=>{let o={depth:t,id:[n,`${t}`].filter(Boolean).join("_"),headers:[]},i=[];e.forEach(e=>{let r;let a=[...i].reverse()[0],u=e.column.depth===o.depth,s=!1;if(u&&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=g(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}),u.push(o),t>0&&s(i,t-1)};s(t.map((e,t)=>g(l,e,{depth:r,index:t})),r-1),u.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=u[0])?void 0:i.headers)?o:[]),u}let d=(e,t,l,n,o,i,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);return null!=l&&l.accessorFn?(l.columnDef.getUniqueValues?g._uniqueValuesCache[t]=l.columnDef.getUniqueValues(g.original,n):g._uniqueValuesCache[t]=[g.getValue(t)],g._uniqueValuesCache[t]):void 0},renderValue:t=>{var l;return null!=(l=g.getValue(t))?l:e.options.renderFallbackValue},subRows:null!=i?i:[],getLeafRows:()=>(function(e,t){let l=[],n=e=>{e.forEach(e=>{l.push(e);let o=t(e);null!=o&&o.length&&n(o)})};return n(e),l})(g.subRows,e=>e.subRows),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:r(()=>[e.getAllLeafColumns()],t=>t.map(t=>(function(e,t,l,n){let o={id:`${t.id}_${l.id}`,row:t,column:l,getValue:()=>t.getValue(n),renderValue:()=>{var t;return null!=(t=o.getValue())?t:e.options.renderFallbackValue},getContext:r(()=>[e,l,t,o],(e,t,l,n)=>({table:e,column:t,row:l,cell:n,getValue:n.getValue,renderValue:n.renderValue}),a(e.options,"debugCells","cell.getContext"))};return e._features.forEach(n=>{null==n.createCell||n.createCell(o,l,t,e)},{}),o})(e,g,t,t.id)),a(e.options,"debugRows","getAllCells")),_getAllCellsByColumnId:r(()=>[g.getAllCells()],e=>e.reduce((e,t)=>(e[t.column.id]=t,e),{}),a(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))};c.autoRemove=e=>b(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=>b(e);let f=(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())};f.autoRemove=e=>b(e);let m=(e,t,l)=>{var n;return null==(n=e.getValue(t))?void 0:n.includes(l)};m.autoRemove=e=>b(e);let C=(e,t,l)=>!l.some(l=>{var n;return!(null!=(n=e.getValue(t))&&n.includes(l))});C.autoRemove=e=>b(e)||!(null!=e&&e.length);let w=(e,t,l)=>l.some(l=>{var n;return null==(n=e.getValue(t))?void 0:n.includes(l)});w.autoRemove=e=>b(e)||!(null!=e&&e.length);let S=(e,t,l)=>e.getValue(t)===l;S.autoRemove=e=>b(e);let R=(e,t,l)=>e.getValue(t)==l;R.autoRemove=e=>b(e);let v=(e,t,l)=>{let[n,o]=l,i=e.getValue(t);return i>=n&&i<=o};v.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]},v.autoRemove=e=>b(e)||b(e[0])&&b(e[1]);let h={includesString:c,includesStringSensitive:p,equalsString:f,arrIncludes:m,arrIncludesAll:C,arrIncludesSome:w,equals:S,weakEquals:R,inNumberRange:v};function b(e){return null==e||""===e}function F(e,t,l){return!!e&&!!e.autoRemove&&e.autoRemove(t,l)||void 0===t||"string"==typeof t&&!t}let M={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=+o)>=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},V=()=>({left:[],right:[]}),P={size:150,minSize:20,maxSize:Number.MAX_SAFE_INTEGER},I=()=>({startOffset:null,startSize:null,deltaOffset:null,deltaPercentage:null,isResizingColumn:!1,columnSizingStart:[]}),x=null;function _(e){return"touchstart"===e.type}function y(e,t){return t?"center"===t?e.getCenterVisibleLeafColumns():"left"===t?e.getLeftVisibleLeafColumns():e.getRightVisibleLeafColumns():e.getVisibleLeafColumns()}let E=()=>({pageIndex:0,pageSize:10}),G=()=>({top:[],bottom:[]}),L=(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=>L(e,t.id,l,n,o))};function A(e,t){let l=e.getState().rowSelection,n=[],o={},i=function(e,t){return e.map(e=>{var t;let r=H(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 H(e,t){var l;return null!=(l=t[e.id])&&l}function D(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()&&(H(e,t)?i=!0:o=!1),e.subRows&&e.subRows.length)){let l=D(e,t);"all"===l?i=!0:("some"===l&&(i=!0),o=!1)}}),o?"all":!!i&&"some"}let z=/([0-9]+)/gm;function O(e,t){return e===t?0:e>t?1:-1}function T(e){return"number"==typeof e?isNaN(e)||e===1/0||e===-1/0?"":String(e):"string"==typeof e?e:""}function B(e,t){let l=e.split(z).filter(Boolean),n=t.split(z).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 k={alphanumeric:(e,t,l)=>B(T(e.getValue(l)).toLowerCase(),T(t.getValue(l)).toLowerCase()),alphanumericCaseSensitive:(e,t,l)=>B(T(e.getValue(l)),T(t.getValue(l))),text:(e,t,l)=>O(T(e.getValue(l)).toLowerCase(),T(t.getValue(l)).toLowerCase()),textCaseSensitive:(e,t,l)=>O(T(e.getValue(l)),T(t.getValue(l))),datetime:(e,t,l)=>{let n=e.getValue(l),o=t.getValue(l);return n>o?1:nO(e.getValue(l),t.getValue(l))},q=[{createTable:e=>{e.getHeaderGroups=r(()=>[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 s(t,[...a,...l.filter(e=>!(null!=n&&n.includes(e.id))&&!(null!=o&&o.includes(e.id))),...u],e)},a(e.options,u,"getHeaderGroups")),e.getCenterHeaderGroups=r(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.left,e.getState().columnPinning.right],(t,l,n,o)=>s(t,l=l.filter(e=>!(null!=n&&n.includes(e.id))&&!(null!=o&&o.includes(e.id))),e,"center"),a(e.options,u,"getCenterHeaderGroups")),e.getLeftHeaderGroups=r(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.left],(t,l,n)=>{var o;return s(t,null!=(o=null==n?void 0:n.map(e=>l.find(t=>t.id===e)).filter(Boolean))?o:[],e,"left")},a(e.options,u,"getLeftHeaderGroups")),e.getRightHeaderGroups=r(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.right],(t,l,n)=>{var o;return s(t,null!=(o=null==n?void 0:n.map(e=>l.find(t=>t.id===e)).filter(Boolean))?o:[],e,"right")},a(e.options,u,"getRightHeaderGroups")),e.getFooterGroups=r(()=>[e.getHeaderGroups()],e=>[...e].reverse(),a(e.options,u,"getFooterGroups")),e.getLeftFooterGroups=r(()=>[e.getLeftHeaderGroups()],e=>[...e].reverse(),a(e.options,u,"getLeftFooterGroups")),e.getCenterFooterGroups=r(()=>[e.getCenterHeaderGroups()],e=>[...e].reverse(),a(e.options,u,"getCenterFooterGroups")),e.getRightFooterGroups=r(()=>[e.getRightHeaderGroups()],e=>[...e].reverse(),a(e.options,u,"getRightFooterGroups")),e.getFlatHeaders=r(()=>[e.getHeaderGroups()],e=>e.map(e=>e.headers).flat(),a(e.options,u,"getFlatHeaders")),e.getLeftFlatHeaders=r(()=>[e.getLeftHeaderGroups()],e=>e.map(e=>e.headers).flat(),a(e.options,u,"getLeftFlatHeaders")),e.getCenterFlatHeaders=r(()=>[e.getCenterHeaderGroups()],e=>e.map(e=>e.headers).flat(),a(e.options,u,"getCenterFlatHeaders")),e.getRightFlatHeaders=r(()=>[e.getRightHeaderGroups()],e=>e.map(e=>e.headers).flat(),a(e.options,u,"getRightFlatHeaders")),e.getCenterLeafHeaders=r(()=>[e.getCenterFlatHeaders()],e=>e.filter(e=>{var t;return!(null!=(t=e.subHeaders)&&t.length)}),a(e.options,u,"getCenterLeafHeaders")),e.getLeftLeafHeaders=r(()=>[e.getLeftFlatHeaders()],e=>e.filter(e=>{var t;return!(null!=(t=e.subHeaders)&&t.length)}),a(e.options,u,"getLeftLeafHeaders")),e.getRightLeafHeaders=r(()=>[e.getRightFlatHeaders()],e=>e.filter(e=>{var t;return!(null!=(t=e.subHeaders)&&t.length)}),a(e.options,u,"getRightLeafHeaders")),e.getLeafHeaders=r(()=>[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()},a(e.options,u,"getLeafHeaders"))}},{getInitialState:e=>({columnVisibility:{},...e}),getDefaultOptions:e=>({onColumnVisibilityChange:o("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=r(()=>[e.getAllCells(),t.getState().columnVisibility],e=>e.filter(e=>e.column.getIsVisible()),a(t.options,"debugRows","_getAllVisibleCells")),e.getVisibleCells=r(()=>[e.getLeftVisibleCells(),e.getCenterVisibleCells(),e.getRightVisibleCells()],(e,t,l)=>[...e,...t,...l],a(t.options,"debugRows","getVisibleCells"))},createTable:e=>{let t=(t,l)=>r(()=>[l(),l().filter(e=>e.getIsVisible()).map(e=>e.id).join("_")],e=>e.filter(e=>null==e.getIsVisible?void 0:e.getIsVisible()),a(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:o("columnOrder",e)}),createColumn:(e,t)=>{e.getIndex=r(e=>[y(t,e)],t=>t.findIndex(t=>t.id===e.id),a(t.options,"debugColumns","getIndex")),e.getIsFirstColumn=l=>{var n;return(null==(n=y(t,l)[0])?void 0:n.id)===e.id},e.getIsLastColumn=l=>{var n;let o=y(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=r(()=>[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;return function(e,t,l){if(!(null!=t&&t.length)||!l)return e;let n=e.filter(e=>!t.includes(e.id));return"remove"===l?n:[...t.map(t=>e.find(e=>e.id===t)).filter(Boolean),...n]}(o,t,l)},a(e.options,"debugTable","_getOrderColumnsFn"))}},{getInitialState:e=>({columnPinning:V(),...e}),getDefaultOptions:e=>({onColumnPinningChange:o("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=r(()=>[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))},a(t.options,"debugRows","getCenterVisibleCells")),e.getLeftVisibleCells=r(()=>[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"})),a(t.options,"debugRows","getLeftVisibleCells")),e.getRightVisibleCells=r(()=>[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"})),a(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?V():null!=(l=null==(n=e.initialState)?void 0:n.columnPinning)?l:V())},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=r(()=>[e.getAllLeafColumns(),e.getState().columnPinning.left],(e,t)=>(null!=t?t:[]).map(t=>e.find(e=>e.id===t)).filter(Boolean),a(e.options,"debugColumns","getLeftLeafColumns")),e.getRightLeafColumns=r(()=>[e.getAllLeafColumns(),e.getState().columnPinning.right],(e,t)=>(null!=t?t:[]).map(t=>e.find(e=>e.id===t)).filter(Boolean),a(e.options,"debugColumns","getRightLeafColumns")),e.getCenterLeafColumns=r(()=>[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))},a(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:o("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?h.includesString:"number"==typeof n?h.inNumberRange:"boolean"==typeof n||null!==n&&"object"==typeof n?h.equals:Array.isArray(n)?h.arrIncludes:h.weakEquals},e.getFilterFn=()=>{var l,n;return i(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:h[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=l=>{t.setColumnFilters(t=>{var o,i;let r=e.getFilterFn(),a=null==t?void 0:t.find(t=>t.id===e.id),u=n(l,a?a.value:void 0);if(F(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 l=e.getAllLeafColumns();null==e.options.onColumnFiltersChange||e.options.onColumnFiltersChange(e=>{var o;return null==(o=n(t,e))?void 0:o.filter(e=>{let t=l.find(t=>t.id===e.id);return!(t&&F(t.getFilterFn(),e.value,t))})})},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:o("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=()=>h.includesString,e.getGlobalFilterFn=()=>{var t,l;let{globalFilterFn:n}=e.options;return i(n)?n:"auto"===n?e.getGlobalAutoFilterFn():null!=(t=null==(l=e.options.filterFns)?void 0:l[n])?t:h[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:o("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 k.datetime;if("string"==typeof l&&(n=!0,l.split(z).length>1))return k.alphanumeric}return n?k.text:k.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 i(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:k[e.columnDef.sortingFn]},e.toggleSorting=(l,n)=>{let o=e.getNextSortingOrder(),i=null!=l;t.setSorting(r=>{let a;let 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 c;(s=[...r,{id:e.id,desc:d}]).splice(0,s.length-(null!=(c=t.options.maxMultiSortColCount)?c: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:o("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?M.sum:"[object Date]"===Object.prototype.toString.call(n)?M.extent:void 0},e.getAggregationFn=()=>{var l,n;if(!e)throw Error();return i(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:M[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:o("expanded",e),paginateExpandedRows:!0}),createTable:e=>{let t=!1,l=!1;e._autoResetExpanded=()=>{var n,o;if(!t){e._queue(()=>{t=!0});return}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:{...E(),...null==e?void 0:e.pagination}}),getDefaultOptions:e=>({onPaginationChange:o("pagination",e)}),createTable:e=>{let t=!1,l=!1;e._autoResetPageIndex=()=>{var n,o;if(!t){e._queue(()=>{t=!0});return}if(null!=(n=null!=(o=e.options.autoResetAll)?o:e.options.autoResetPageIndex)?n:!e.options.manualPagination){if(l)return;l=!0,e._queue(()=>{e.resetPageIndex(),l=!1})}},e.setPagination=t=>null==e.options.onPaginationChange?void 0:e.options.onPaginationChange(e=>n(t,e)),e.resetPagination=t=>{var l;e.setPagination(t?E():null!=(l=e.initialState.pagination)?l:E())},e.setPageIndex=t=>{e.setPagination(l=>{let o=n(t,l.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)),{...l,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 l=Math.max(1,n(t,e.pageSize)),o=e.pageSize*e.pageIndex;return{...e,pageIndex:Math.floor(o/l),pageSize:l}})},e.setPageCount=t=>e.setPagination(l=>{var o;let i=n(t,null!=(o=e.options.pageCount)?o:-1);return"number"==typeof i&&(i=Math.max(-1,i)),{...l,pageCount:i}}),e.getPageOptions=r(()=>[e.getPageCount()],e=>{let t=[];return e&&e>0&&(t=[...Array(e)].fill(null).map((e,t)=>t)),t},a(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:G(),...e}),getDefaultOptions:e=>({onRowPinningChange:o("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?G():null!=(l=null==(n=e.initialState)?void 0:n.rowPinning)?l:G())},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=r(()=>[e.getRowModel().rows,e.getState().rowPinning.top],(t,l)=>e._getPinnedRows(t,l,"top"),a(e.options,"debugRows","getTopRows")),e.getBottomRows=r(()=>[e.getRowModel().rows,e.getState().rowPinning.bottom],(t,l)=>e._getPinnedRows(t,l,"bottom"),a(e.options,"debugRows","getBottomRows")),e.getCenterRows=r(()=>[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))},a(e.options,"debugRows","getCenterRows"))}},{getInitialState:e=>({rowSelection:{},...e}),getDefaultOptions:e=>({onRowSelectionChange:o("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=>{L(o,t.id,n,!0,e)}),o}),e.getPreSelectedRowModel=()=>e.getCoreRowModel(),e.getSelectedRowModel=r(()=>[e.getState().rowSelection,e.getCoreRowModel()],(t,l)=>Object.keys(t).length?A(e,l):{rows:[],flatRows:[],rowsById:{}},a(e.options,"debugTable","getSelectedRowModel")),e.getFilteredSelectedRowModel=r(()=>[e.getState().rowSelection,e.getFilteredRowModel()],(t,l)=>Object.keys(t).length?A(e,l):{rows:[],flatRows:[],rowsById:{}},a(e.options,"debugTable","getFilteredSelectedRowModel")),e.getGroupedSelectedRowModel=r(()=>[e.getState().rowSelection,e.getSortedRowModel()],(t,l)=>Object.keys(t).length?A(e,l):{rows:[],flatRows:[],rowsById:{}},a(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 L(a,e.id,l,null==(r=null==n?void 0:n.selectChildren)||r,t),a})},e.getIsSelected=()=>{let{rowSelection:l}=t.getState();return H(e,l)},e.getIsSomeSelected=()=>{let{rowSelection:l}=t.getState();return"some"===D(e,l)},e.getIsAllSubRowsSelected=()=>{let{rowSelection:l}=t.getState();return"all"===D(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:()=>P,getInitialState:e=>({columnSizing:{},columnSizingInfo:I(),...e}),getDefaultOptions:e=>({columnResizeMode:"onEnd",columnResizeDirection:"ltr",onColumnSizingChange:o("columnSizing",e),onColumnSizingInfoChange:o("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:P.minSize,null!=(n=null!=i?i:e.columnDef.size)?n:P.size),null!=(o=e.columnDef.maxSize)?o:P.maxSize)},e.getStart=r(e=>[e,y(t,e),t.getState().columnSizing],(t,l)=>l.slice(0,e.getIndex(t)).reduce((e,t)=>e+t.getSize(),0),a(t.options,"debugColumns","getStart")),e.getAfter=r(e=>[e,y(t,e),t.getState().columnSizing],(t,l)=>l.slice(e.getIndex(t)+1).reduce((e,t)=>e+t.getSize(),0),a(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(),_(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=_(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("move",e),c=e=>{s("end",e),t.setColumnSizingInfo(e=>({...e,isResizingColumn:!1,startOffset:null,startSize:null,deltaOffset:null,deltaPercentage:null,columnSizingStart:[]}))},p=l||("undefined"!=typeof document?document:null),f={moveHandler:e=>d(e.clientX),upHandler:e=>{null==p||p.removeEventListener("mousemove",f.moveHandler),null==p||p.removeEventListener("mouseup",f.upHandler),c(e.clientX)}},m={moveHandler:e=>(e.cancelable&&(e.preventDefault(),e.stopPropagation()),d(e.touches[0].clientX),!1),upHandler:e=>{var t;null==p||p.removeEventListener("touchmove",m.moveHandler),null==p||p.removeEventListener("touchend",m.upHandler),e.cancelable&&(e.preventDefault(),e.stopPropagation()),c(null==(t=e.touches[0])?void 0:t.clientX)}},C=!!function(){if("boolean"==typeof x)return x;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 x=e}()&&{passive:!1};_(i)?(null==p||p.addEventListener("touchmove",m.moveHandler,C),null==p||p.addEventListener("touchend",m.upHandler,C)):(null==p||p.addEventListener("mousemove",f.moveHandler,C),null==p||p.addEventListener("mouseup",f.upHandler,C)),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?I():null!=(l=e.initialState.columnSizingInfo)?l:I())},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 N(e){var t,l;let o=[...q,...null!=(t=e._features)?t:[]],i={_features:o},u=i._features.reduce((e,t)=>Object.assign(e,null==t.getDefaultOptions?void 0:t.getDefaultOptions(i)),{}),g=e=>i.options.mergeOptions?i.options.mergeOptions(u,e):{...u,...e},s={...null!=(l=e.initialState)?l:{}};i._features.forEach(e=>{var t;s=null!=(t=null==e.getInitialState?void 0:e.getInitialState(s))?t:s});let d=[],c=!1,p={_features:o,options:{...u,...e},initialState:s,_queue:e=>{d.push(e),c||(c=!0,Promise.resolve().then(()=>{for(;d.length;)d.shift()();c=!1}).catch(e=>setTimeout(()=>{throw e})))},reset:()=>{i.setState(i.initialState)},setOptions:e=>{let t=n(e,i.options);i.options=g(t)},getState:()=>i.options.state,setState:e=>{null==i.options.onStateChange||i.options.onStateChange(e)},_getRowId:(e,t,l)=>{var n;return null!=(n=null==i.options.getRowId?void 0:i.options.getRowId(e,t,l))?n:`${l?[l.id,t].join("."):t}`},getCoreRowModel:()=>(i._getCoreRowModel||(i._getCoreRowModel=i.options.getCoreRowModel(i)),i._getCoreRowModel()),getRowModel:()=>i.getPaginationRowModel(),getRow:(e,t)=>{let l=(t?i.getPrePaginationRowModel():i.getRowModel()).rowsById[e];if(!l&&!(l=i.getCoreRowModel().rowsById[e]))throw Error();return l},_getDefaultColumnDef:r(()=>[i.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},...i._features.reduce((e,t)=>Object.assign(e,null==t.getDefaultColumnDef?void 0:t.getDefaultColumnDef()),{}),...e}},a(e,"debugColumns","_getDefaultColumnDef")),_getColumnDefs:()=>i.options.columns,getAllColumns:r(()=>[i._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,i;let u;let g={...e._getDefaultColumnDef(),...t},s=g.accessorKey,d=null!=(o=null!=(i=g.id)?i: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 c={id:`${String(d)}`,accessorFn:u,parent:n,depth:l,columnDef:g,columns:[],getFlatColumns:r(()=>[!0],()=>{var e;return[c,...null==(e=c.columns)?void 0:e.flatMap(e=>e.getFlatColumns())]},a(e.options,"debugColumns","column.getFlatColumns")),getLeafColumns:r(()=>[e._getOrderColumnsFn()],e=>{var t;return null!=(t=c.columns)&&t.length?e(c.columns.flatMap(e=>e.getLeafColumns())):[c]},a(e.options,"debugColumns","column.getLeafColumns"))};for(let t of e._features)null==t.createColumn||t.createColumn(c,e);return c}(i,e,n,l);return o.columns=e.columns?t(e.columns,o,n+1):[],o})};return t(e)},a(e,"debugColumns","getAllColumns")),getAllFlatColumns:r(()=>[i.getAllColumns()],e=>e.flatMap(e=>e.getFlatColumns()),a(e,"debugColumns","getAllFlatColumns")),_getAllFlatColumnsById:r(()=>[i.getAllFlatColumns()],e=>e.reduce((e,t)=>(e[t.id]=t,e),{}),a(e,"debugColumns","getAllFlatColumnsById")),getAllLeafColumns:r(()=>[i.getAllColumns(),i._getOrderColumnsFn()],(e,t)=>t(e.flatMap(e=>e.getLeafColumns())),a(e,"debugColumns","getAllLeafColumns")),getColumn:e=>i._getAllFlatColumnsById()[e]};Object.assign(i,p);for(let e=0;er(()=>[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()))}function U(){return e=>r(()=>[e.getState().expanded,e.getPreExpandedRowModel(),e.options.paginateExpandedRows],(e,t,l)=>t.rows.length&&(!0===e||Object.keys(null!=e?e:{}).length)&&l?$(t):t,a(e.options,"debugTable","getExpandedRowModel"))}function $(e){let t=[],l=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}}function X(e){return e=>r(()=>[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}:$({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},a(e.options,"debugTable","getPaginationRowModel"))}function K(){return e=>r(()=>[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}},a(e.options,"debugTable","getSortedRowModel",()=>e._autoResetPageIndex()))}}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/2136-2c0d6e8c18d2c5c4.js b/litellm/proxy/_experimental/out/_next/static/chunks/2136-2c0d6e8c18d2c5c4.js new file mode 100644 index 00000000000..caf79b501e8 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/2136-2c0d6e8c18d2c5c4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[2136,1623],{69993:function(e,t,r){r.d(t,{Z:function(){return s}});var n=r(1119),a=r(2265),i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M300 328a60 60 0 10120 0 60 60 0 10-120 0zM852 64H172c-17.7 0-32 14.3-32 32v660c0 17.7 14.3 32 32 32h680c17.7 0 32-14.3 32-32V96c0-17.7-14.3-32-32-32zm-32 660H204V128h616v596zM604 328a60 60 0 10120 0 60 60 0 10-120 0zm250.2 556H169.8c-16.5 0-29.8 14.3-29.8 32v36c0 4.4 3.3 8 7.4 8h729.1c4.1 0 7.4-3.6 7.4-8v-36c.1-17.7-13.2-32-29.7-32zM664 508H360c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h304c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"}}]},name:"robot",theme:"outlined"},o=r(55015),s=a.forwardRef(function(e,t){return a.createElement(o.Z,(0,n.Z)({},e,{ref:t,icon:i}))})},47323:function(e,t,r){r.d(t,{Z:function(){return p}});var n=r(5853),a=r(2265),i=r(47187),o=r(7084),s=r(13241),u=r(1153),l=r(26898);let c={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"}},h={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:""}},f=(e,t)=>{switch(e){case"simple":return{textColor:t?(0,u.bM)(t,l.K.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:"",borderColor:"",ringColor:""};case"light":return{textColor:t?(0,u.bM)(t,l.K.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,s.q)((0,u.bM)(t,l.K.background).bgColor,"bg-opacity-20"):"bg-tremor-brand-muted dark:bg-dark-tremor-brand-muted",borderColor:"",ringColor:""};case"shadow":return{textColor:t?(0,u.bM)(t,l.K.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,s.q)((0,u.bM)(t,l.K.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,u.bM)(t,l.K.text).textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",bgColor:t?(0,s.q)((0,u.bM)(t,l.K.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,u.bM)(t,l.K.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,s.q)((0,u.bM)(t,l.K.background).bgColor,"bg-opacity-20"):"bg-tremor-background dark:bg-dark-tremor-background",borderColor:t?(0,u.bM)(t,l.K.ring).borderColor:"border-tremor-brand-subtle dark:border-dark-tremor-brand-subtle",ringColor:t?(0,s.q)((0,u.bM)(t,l.K.ring).ringColor,"ring-opacity-40"):"ring-tremor-brand-muted dark:ring-dark-tremor-brand-muted"}}},m=(0,u.fn)("Icon"),p=a.forwardRef((e,t)=>{let{icon:r,variant:l="simple",tooltip:p,size:g=o.u8.SM,color:b,className:y}=e,v=(0,n._T)(e,["icon","variant","tooltip","size","color","className"]),w=f(l,b),{tooltipProps:C,getReferenceProps:k}=(0,i.l)();return a.createElement("span",Object.assign({ref:(0,u.lq)([t,C.refs.setReference]),className:(0,s.q)(m("root"),"inline-flex shrink-0 items-center justify-center",w.bgColor,w.textColor,w.borderColor,w.ringColor,h[l].rounded,h[l].border,h[l].shadow,h[l].ring,c[g].paddingX,c[g].paddingY,y)},k,v),a.createElement(i.Z,Object.assign({text:p},C)),a.createElement(r,{className:(0,s.q)(m("icon"),"shrink-0",d[g].height,d[g].width)}))});p.displayName="Icon"},49804:function(e,t,r){r.d(t,{Z:function(){return l}});var n=r(5853),a=r(13241),i=r(1153),o=r(2265),s=r(9496);let u=(0,i.fn)("Col"),l=o.forwardRef((e,t)=>{let{numColSpan:r=1,numColSpanSm:i,numColSpanMd:l,numColSpanLg:c,children:d,className:h}=e,f=(0,n._T)(e,["numColSpan","numColSpanSm","numColSpanMd","numColSpanLg","children","className"]),m=(e,t)=>e&&Object.keys(t).includes(String(e))?t[e]:"";return o.createElement("div",Object.assign({ref:t,className:(0,a.q)(u("root"),(()=>{let e=m(r,s.PT),t=m(i,s.SP),n=m(l,s.VS),o=m(c,s._w);return(0,a.q)(e,t,n,o)})(),h)},f),d)});l.displayName="Col"},94789:function(e,t,r){r.d(t,{Z:function(){return l}});var n=r(5853),a=r(2265),i=r(26898),o=r(13241),s=r(1153);let u=(0,s.fn)("Callout"),l=a.forwardRef((e,t)=>{let{title:r,icon:l,color:c,className:d,children:h}=e,f=(0,n._T)(e,["title","icon","color","className","children"]);return a.createElement("div",Object.assign({ref:t,className:(0,o.q)(u("root"),"flex flex-col overflow-hidden rounded-tremor-default text-tremor-default border-l-4 py-3 pr-3 pl-4",c?(0,o.q)((0,s.bM)(c,i.K.background).bgColor,(0,s.bM)(c,i.K.darkBorder).borderColor,(0,s.bM)(c,i.K.darkText).textColor,"dark:bg-opacity-10 bg-opacity-10"):(0,o.q)("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"),d)},f),a.createElement("div",{className:(0,o.q)(u("header"),"flex items-start")},l?a.createElement(l,{className:(0,o.q)(u("icon"),"flex-none h-5 w-5 mr-1.5")}):null,a.createElement("h4",{className:(0,o.q)(u("title"),"font-semibold")},r)),a.createElement("p",{className:(0,o.q)(u("body"),"overflow-y-auto",h?"mt-2":"")},h))});l.displayName="Callout"},32489:function(e,t,r){r.d(t,{Z:function(){return n}});let n=(0,r(79205).Z)("x",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]])},10900:function(e,t,r){var n=r(2265);let a=n.forwardRef(function(e,t){return n.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),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10 19l-7-7m0 0l7-7m-7 7h18"}))});t.Z=a},91777:function(e,t,r){var n=r(2265);let a=n.forwardRef(function(e,t){return n.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),n.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"}))});t.Z=a},47686:function(e,t,r){var n=r(2265);let a=n.forwardRef(function(e,t){return n.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),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9 5l7 7-7 7"}))});t.Z=a},58710:function(e,t,r){var n=r(2265);let a=n.forwardRef(function(e,t){return n.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),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"}))});t.Z=a},82182:function(e,t,r){var n=r(2265);let a=n.forwardRef(function(e,t){return n.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),n.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"}),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"}))});t.Z=a},79814:function(e,t,r){var n=r(2265);let a=n.forwardRef(function(e,t){return n.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),n.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"}))});t.Z=a},2356:function(e,t,r){var n=r(2265);let a=n.forwardRef(function(e,t){return n.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),n.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"}))});t.Z=a},93416:function(e,t,r){var n=r(2265);let a=n.forwardRef(function(e,t){return n.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),n.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"}))});t.Z=a},77355:function(e,t,r){var n=r(2265);let a=n.forwardRef(function(e,t){return n.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),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 9v3m0 0v3m0-3h3m-3 0H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z"}))});t.Z=a},22452:function(e,t,r){var n=r(2265);let a=n.forwardRef(function(e,t){return n.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),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 4v16m8-8H4"}))});t.Z=a},25327:function(e,t,r){var n=r(2265);let a=n.forwardRef(function(e,t){return n.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),n.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"}))});t.Z=a},49084:function(e,t,r){var n=r(2265);let a=n.forwardRef(function(e,t){return n.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),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4"}))});t.Z=a},3497:function(e,t,r){var n=r(2265);let a=n.forwardRef(function(e,t){return n.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),n.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"}))});t.Z=a},2894:function(e,t,r){r.d(t,{R:function(){return s},m:function(){return o}});var n=r(18238),a=r(7989),i=r(11255),o=class extends a.F{#e;#t;#r;#n;constructor(e){super(),this.#e=e.client,this.mutationId=e.mutationId,this.#r=e.mutationCache,this.#t=[],this.state=e.state||s(),this.setOptions(e.options),this.scheduleGc()}setOptions(e){this.options=e,this.updateGcTime(this.options.gcTime)}get meta(){return this.options.meta}addObserver(e){this.#t.includes(e)||(this.#t.push(e),this.clearGcTimeout(),this.#r.notify({type:"observerAdded",mutation:this,observer:e}))}removeObserver(e){this.#t=this.#t.filter(t=>t!==e),this.scheduleGc(),this.#r.notify({type:"observerRemoved",mutation:this,observer:e})}optionalRemove(){this.#t.length||("pending"===this.state.status?this.scheduleGc():this.#r.remove(this))}continue(){return this.#n?.continue()??this.execute(this.state.variables)}async execute(e){let t=()=>{this.#a({type:"continue"})},r={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};this.#n=(0,i.Mz)({fn:()=>this.options.mutationFn?this.options.mutationFn(e,r):Promise.reject(Error("No mutationFn found")),onFail:(e,t)=>{this.#a({type:"failed",failureCount:e,error:t})},onPause:()=>{this.#a({type:"pause"})},onContinue:t,retry:this.options.retry??0,retryDelay:this.options.retryDelay,networkMode:this.options.networkMode,canRun:()=>this.#r.canRun(this)});let n="pending"===this.state.status,a=!this.#n.canStart();try{if(n)t();else{this.#a({type:"pending",variables:e,isPaused:a}),await this.#r.config.onMutate?.(e,this,r);let t=await this.options.onMutate?.(e,r);t!==this.state.context&&this.#a({type:"pending",context:t,variables:e,isPaused:a})}let i=await this.#n.start();return await this.#r.config.onSuccess?.(i,e,this.state.context,this,r),await this.options.onSuccess?.(i,e,this.state.context,r),await this.#r.config.onSettled?.(i,null,this.state.variables,this.state.context,this,r),await this.options.onSettled?.(i,null,e,this.state.context,r),this.#a({type:"success",data:i}),i}catch(t){try{throw await this.#r.config.onError?.(t,e,this.state.context,this,r),await this.options.onError?.(t,e,this.state.context,r),await this.#r.config.onSettled?.(void 0,t,this.state.variables,this.state.context,this,r),await this.options.onSettled?.(void 0,t,e,this.state.context,r),t}finally{this.#a({type:"error",error:t})}}finally{this.#r.runNext(this)}}#a(e){this.state=(t=>{switch(e.type){case"failed":return{...t,failureCount:e.failureCount,failureReason:e.error};case"pause":return{...t,isPaused:!0};case"continue":return{...t,isPaused:!1};case"pending":return{...t,context:e.context,data:void 0,failureCount:0,failureReason:null,error:null,isPaused:e.isPaused,status:"pending",variables:e.variables,submittedAt:Date.now()};case"success":return{...t,data:e.data,failureCount:0,failureReason:null,error:null,status:"success",isPaused:!1};case"error":return{...t,data:void 0,error:e.error,failureCount:t.failureCount+1,failureReason:e.error,isPaused:!1,status:"error"}}})(this.state),n.Vr.batch(()=>{this.#t.forEach(t=>{t.onMutationUpdate(e)}),this.#r.notify({mutation:this,type:"updated",action:e})})}};function s(){return{context:void 0,data:void 0,error:null,failureCount:0,failureReason:null,isPaused:!1,status:"idle",variables:void 0,submittedAt:0}}},21623:function(e,t,r){r.d(t,{S:function(){return p}});var n=r(45345),a=r(21733),i=r(18238),o=r(24112),s=class extends o.l{constructor(e={}){super(),this.config=e,this.#i=new Map}#i;build(e,t,r){let i=t.queryKey,o=t.queryHash??(0,n.Rm)(i,t),s=this.get(o);return s||(s=new a.A({client:e,queryKey:i,queryHash:o,options:e.defaultQueryOptions(t),state:r,defaultOptions:e.getQueryDefaults(i)}),this.add(s)),s}add(e){this.#i.has(e.queryHash)||(this.#i.set(e.queryHash,e),this.notify({type:"added",query:e}))}remove(e){let t=this.#i.get(e.queryHash);t&&(e.destroy(),t===e&&this.#i.delete(e.queryHash),this.notify({type:"removed",query:e}))}clear(){i.Vr.batch(()=>{this.getAll().forEach(e=>{this.remove(e)})})}get(e){return this.#i.get(e)}getAll(){return[...this.#i.values()]}find(e){let t={exact:!0,...e};return this.getAll().find(e=>(0,n._x)(t,e))}findAll(e={}){let t=this.getAll();return Object.keys(e).length>0?t.filter(t=>(0,n._x)(e,t)):t}notify(e){i.Vr.batch(()=>{this.listeners.forEach(t=>{t(e)})})}onFocus(){i.Vr.batch(()=>{this.getAll().forEach(e=>{e.onFocus()})})}onOnline(){i.Vr.batch(()=>{this.getAll().forEach(e=>{e.onOnline()})})}},u=r(2894),l=class extends o.l{constructor(e={}){super(),this.config=e,this.#o=new Set,this.#s=new Map,this.#u=0}#o;#s;#u;build(e,t,r){let n=new u.m({client:e,mutationCache:this,mutationId:++this.#u,options:e.defaultMutationOptions(t),state:r});return this.add(n),n}add(e){this.#o.add(e);let t=c(e);if("string"==typeof t){let r=this.#s.get(t);r?r.push(e):this.#s.set(t,[e])}this.notify({type:"added",mutation:e})}remove(e){if(this.#o.delete(e)){let t=c(e);if("string"==typeof t){let r=this.#s.get(t);if(r){if(r.length>1){let t=r.indexOf(e);-1!==t&&r.splice(t,1)}else r[0]===e&&this.#s.delete(t)}}}this.notify({type:"removed",mutation:e})}canRun(e){let t=c(e);if("string"!=typeof t)return!0;{let r=this.#s.get(t),n=r?.find(e=>"pending"===e.state.status);return!n||n===e}}runNext(e){let t=c(e);if("string"!=typeof t)return Promise.resolve();{let r=this.#s.get(t)?.find(t=>t!==e&&t.state.isPaused);return r?.continue()??Promise.resolve()}}clear(){i.Vr.batch(()=>{this.#o.forEach(e=>{this.notify({type:"removed",mutation:e})}),this.#o.clear(),this.#s.clear()})}getAll(){return Array.from(this.#o)}find(e){let t={exact:!0,...e};return this.getAll().find(e=>(0,n.X7)(t,e))}findAll(e={}){return this.getAll().filter(t=>(0,n.X7)(e,t))}notify(e){i.Vr.batch(()=>{this.listeners.forEach(t=>{t(e)})})}resumePausedMutations(){let e=this.getAll().filter(e=>e.state.isPaused);return i.Vr.batch(()=>Promise.all(e.map(e=>e.continue().catch(n.ZT))))}};function c(e){return e.options.scope?.id}var d=r(87045),h=r(57853);function f(e){return{onFetch:(t,r)=>{let a=t.options,i=t.fetchOptions?.meta?.fetchMore?.direction,o=t.state.data?.pages||[],s=t.state.data?.pageParams||[],u={pages:[],pageParams:[]},l=0,c=async()=>{let r=!1,c=e=>{Object.defineProperty(e,"signal",{enumerable:!0,get:()=>(t.signal.aborted?r=!0:t.signal.addEventListener("abort",()=>{r=!0}),t.signal)})},d=(0,n.cG)(t.options,t.fetchOptions),h=async(e,a,i)=>{if(r)return Promise.reject();if(null==a&&e.pages.length)return Promise.resolve(e);let o=(()=>{let e={client:t.client,queryKey:t.queryKey,pageParam:a,direction:i?"backward":"forward",meta:t.options.meta};return c(e),e})(),s=await d(o),{maxPages:u}=t.options,l=i?n.Ht:n.VX;return{pages:l(e.pages,s,u),pageParams:l(e.pageParams,a,u)}};if(i&&o.length){let e="backward"===i,t={pages:o,pageParams:s},r=(e?function(e,{pages:t,pageParams:r}){return t.length>0?e.getPreviousPageParam?.(t[0],t,r[0],r):void 0}:m)(a,t);u=await h(t,r,e)}else{let t=e??o.length;do{let e=0===l?s[0]??a.initialPageParam:m(a,u);if(l>0&&null==e)break;u=await h(u,e),l++}while(lt.options.persister?.(c,{client:t.client,queryKey:t.queryKey,meta:t.options.meta,signal:t.signal},r):t.fetchFn=c}}}function m(e,{pages:t,pageParams:r}){let n=t.length-1;return t.length>0?e.getNextPageParam(t[n],t,r[n],r):void 0}var p=class{#l;#r;#c;#d;#h;#f;#m;#p;constructor(e={}){this.#l=e.queryCache||new s,this.#r=e.mutationCache||new l,this.#c=e.defaultOptions||{},this.#d=new Map,this.#h=new Map,this.#f=0}mount(){this.#f++,1===this.#f&&(this.#m=d.j.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#l.onFocus())}),this.#p=h.N.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#l.onOnline())}))}unmount(){this.#f--,0===this.#f&&(this.#m?.(),this.#m=void 0,this.#p?.(),this.#p=void 0)}isFetching(e){return this.#l.findAll({...e,fetchStatus:"fetching"}).length}isMutating(e){return this.#r.findAll({...e,status:"pending"}).length}getQueryData(e){let t=this.defaultQueryOptions({queryKey:e});return this.#l.get(t.queryHash)?.state.data}ensureQueryData(e){let t=this.defaultQueryOptions(e),r=this.#l.build(this,t),a=r.state.data;return void 0===a?this.fetchQuery(e):(e.revalidateIfStale&&r.isStaleByTime((0,n.KC)(t.staleTime,r))&&this.prefetchQuery(t),Promise.resolve(a))}getQueriesData(e){return this.#l.findAll(e).map(({queryKey:e,state:t})=>[e,t.data])}setQueryData(e,t,r){let a=this.defaultQueryOptions({queryKey:e}),i=this.#l.get(a.queryHash),o=i?.state.data,s=(0,n.SE)(t,o);if(void 0!==s)return this.#l.build(this,a).setData(s,{...r,manual:!0})}setQueriesData(e,t,r){return i.Vr.batch(()=>this.#l.findAll(e).map(({queryKey:e})=>[e,this.setQueryData(e,t,r)]))}getQueryState(e){let t=this.defaultQueryOptions({queryKey:e});return this.#l.get(t.queryHash)?.state}removeQueries(e){let t=this.#l;i.Vr.batch(()=>{t.findAll(e).forEach(e=>{t.remove(e)})})}resetQueries(e,t){let r=this.#l;return i.Vr.batch(()=>(r.findAll(e).forEach(e=>{e.reset()}),this.refetchQueries({type:"active",...e},t)))}cancelQueries(e,t={}){let r={revert:!0,...t};return Promise.all(i.Vr.batch(()=>this.#l.findAll(e).map(e=>e.cancel(r)))).then(n.ZT).catch(n.ZT)}invalidateQueries(e,t={}){return i.Vr.batch(()=>(this.#l.findAll(e).forEach(e=>{e.invalidate()}),e?.refetchType==="none")?Promise.resolve():this.refetchQueries({...e,type:e?.refetchType??e?.type??"active"},t))}refetchQueries(e,t={}){let r={...t,cancelRefetch:t.cancelRefetch??!0};return Promise.all(i.Vr.batch(()=>this.#l.findAll(e).filter(e=>!e.isDisabled()&&!e.isStatic()).map(e=>{let t=e.fetch(void 0,r);return r.throwOnError||(t=t.catch(n.ZT)),"paused"===e.state.fetchStatus?Promise.resolve():t}))).then(n.ZT)}fetchQuery(e){let t=this.defaultQueryOptions(e);void 0===t.retry&&(t.retry=!1);let r=this.#l.build(this,t);return r.isStaleByTime((0,n.KC)(t.staleTime,r))?r.fetch(t):Promise.resolve(r.state.data)}prefetchQuery(e){return this.fetchQuery(e).then(n.ZT).catch(n.ZT)}fetchInfiniteQuery(e){return e.behavior=f(e.pages),this.fetchQuery(e)}prefetchInfiniteQuery(e){return this.fetchInfiniteQuery(e).then(n.ZT).catch(n.ZT)}ensureInfiniteQueryData(e){return e.behavior=f(e.pages),this.ensureQueryData(e)}resumePausedMutations(){return h.N.isOnline()?this.#r.resumePausedMutations():Promise.resolve()}getQueryCache(){return this.#l}getMutationCache(){return this.#r}getDefaultOptions(){return this.#c}setDefaultOptions(e){this.#c=e}setQueryDefaults(e,t){this.#d.set((0,n.Ym)(e),{queryKey:e,defaultOptions:t})}getQueryDefaults(e){let t=[...this.#d.values()],r={};return t.forEach(t=>{(0,n.to)(e,t.queryKey)&&Object.assign(r,t.defaultOptions)}),r}setMutationDefaults(e,t){this.#h.set((0,n.Ym)(e),{mutationKey:e,defaultOptions:t})}getMutationDefaults(e){let t=[...this.#h.values()],r={};return t.forEach(t=>{(0,n.to)(e,t.mutationKey)&&Object.assign(r,t.defaultOptions)}),r}defaultQueryOptions(e){if(e._defaulted)return e;let t={...this.#c.queries,...this.getQueryDefaults(e.queryKey),...e,_defaulted:!0};return t.queryHash||(t.queryHash=(0,n.Rm)(t.queryKey,t)),void 0===t.refetchOnReconnect&&(t.refetchOnReconnect="always"!==t.networkMode),void 0===t.throwOnError&&(t.throwOnError=!!t.suspense),!t.networkMode&&t.persister&&(t.networkMode="offlineFirst"),t.queryFn===n.CN&&(t.enabled=!1),t}defaultMutationOptions(e){return e?._defaulted?e:{...this.#c.mutations,...e?.mutationKey&&this.getMutationDefaults(e.mutationKey),...e,_defaulted:!0}}clear(){this.#l.clear(),this.#r.clear()}}},92668:function(e,t,r){r.d(t,{I:function(){return s}});var n=r(59121),a=r(31091),i=r(63497),o=r(99649);function s(e,t){let{years:r=0,months:s=0,weeks:u=0,days:l=0,hours:c=0,minutes:d=0,seconds:h=0}=t,f=(0,o.Q)(e),m=s||r?(0,a.z)(f,s+12*r):f,p=l||u?(0,n.E)(m,l+7*u):m;return(0,i.L)(e,p.getTime()+1e3*(h+60*(d+60*c)))}},59121:function(e,t,r){r.d(t,{E:function(){return i}});var n=r(99649),a=r(63497);function i(e,t){let r=(0,n.Q)(e);return isNaN(t)?(0,a.L)(e,NaN):(t&&r.setDate(r.getDate()+t),r)}},31091:function(e,t,r){r.d(t,{z:function(){return i}});var n=r(99649),a=r(63497);function i(e,t){let r=(0,n.Q)(e);if(isNaN(t))return(0,a.L)(e,NaN);if(!t)return r;let i=r.getDate(),o=(0,a.L)(e,r.getTime());return(o.setMonth(r.getMonth()+t+1,0),i>=o.getDate())?o:(r.setFullYear(o.getFullYear(),o.getMonth(),i),r)}},63497:function(e,t,r){r.d(t,{L:function(){return n}});function n(e,t){return e instanceof Date?new e.constructor(t):new Date(t)}},99649:function(e,t,r){r.d(t,{Q:function(){return n}});function n(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)}}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/2172-c97c9e958a9c36e3.js b/litellm/proxy/_experimental/out/_next/static/chunks/2172-c97c9e958a9c36e3.js deleted file mode 100644 index 195498ee042..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/2172-c97c9e958a9c36e3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[2172],{15327:function(e,t,r){r.d(t,{Z:function(){return l}});var o=r(1119),n=r(2265),c={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"},a=r(55015),l=n.forwardRef(function(e,t){return n.createElement(a.Z,(0,o.Z)({},e,{ref:t,icon:c}))})},77565:function(e,t,r){r.d(t,{Z:function(){return l}});var o=r(1119),n=r(2265),c={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"}}]},name:"right",theme:"outlined"},a=r(55015),l=n.forwardRef(function(e,t){return n.createElement(a.Z,(0,o.Z)({},e,{ref:t,icon:c}))})},3632:function(e,t,r){r.d(t,{Z:function(){return l}});var o=r(1119),n=r(2265),c={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"},a=r(55015),l=n.forwardRef(function(e,t){return n.createElement(a.Z,(0,o.Z)({},e,{ref:t,icon:c}))})},15883:function(e,t,r){r.d(t,{Z:function(){return l}});var o=r(1119),n=r(2265),c={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"}}]},name:"user",theme:"outlined"},a=r(55015),l=n.forwardRef(function(e,t){return n.createElement(a.Z,(0,o.Z)({},e,{ref:t,icon:c}))})},84264:function(e,t,r){r.d(t,{Z:function(){return l}});var o=r(26898),n=r(13241),c=r(1153),a=r(2265);let l=a.forwardRef((e,t)=>{let{color:r,className:l,children:i}=e;return a.createElement("p",{ref:t,className:(0,n.q)("text-tremor-default",r?(0,c.bM)(r,o.K.text).textColor:(0,n.q)("text-tremor-content","dark:text-dark-tremor-content"),l)},i)});l.displayName="Text"},3810:function(e,t,r){r.d(t,{Z:function(){return B}});var o=r(2265),n=r(36760),c=r.n(n),a=r(18694),l=r(93350),i=r(53445),s=r(19722),u=r(6694),d=r(71744),f=r(93463),g=r(54558),h=r(12918),p=r(71140),m=r(99320);let v=e=>{let{paddingXXS:t,lineWidth:r,tagPaddingHorizontal:o,componentCls:n,calc:c}=e,a=c(o).sub(r).equal(),l=c(t).sub(r).equal();return{[n]:Object.assign(Object.assign({},(0,h.Wf)(e)),{display:"inline-block",height:"auto",marginInlineEnd:e.marginXS,paddingInline:a,fontSize:e.tagFontSize,lineHeight:e.tagLineHeight,whiteSpace:"nowrap",background:e.defaultBg,border:"".concat((0,f.bf)(e.lineWidth)," ").concat(e.lineType," ").concat(e.colorBorder),borderRadius:e.borderRadiusSM,opacity:1,transition:"all ".concat(e.motionDurationMid),textAlign:"start",position:"relative",["&".concat(n,"-rtl")]:{direction:"rtl"},"&, a, a:hover":{color:e.defaultColor},["".concat(n,"-close-icon")]:{marginInlineStart:l,fontSize:e.tagIconSize,color:e.colorIcon,cursor:"pointer",transition:"all ".concat(e.motionDurationMid),"&:hover":{color:e.colorTextHeading}},["&".concat(n,"-has-color")]:{borderColor:"transparent",["&, a, a:hover, ".concat(e.iconCls,"-close, ").concat(e.iconCls,"-close:hover")]:{color:e.colorTextLightSolid}},"&-checkable":{backgroundColor:"transparent",borderColor:"transparent",cursor:"pointer",["&:not(".concat(n,"-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"},["> ".concat(e.iconCls," + span, > span + ").concat(e.iconCls)]:{marginInlineStart:a}}),["".concat(n,"-borderless")]:{borderColor:"transparent",background:e.tagBorderlessBg}}},b=e=>{let{lineWidth:t,fontSizeIcon:r,calc:o}=e,n=e.fontSizeSM;return(0,p.IX)(e,{tagFontSize:n,tagLineHeight:(0,f.bf)(o(e.lineHeightSM).mul(n).equal()),tagIconSize:o(r).sub(o(t).mul(2)).equal(),tagPaddingHorizontal:8,tagBorderlessBg:e.defaultBg})},k=e=>({defaultBg:new g.t(e.colorFillQuaternary).onBackground(e.colorBgContainer).toHexString(),defaultColor:e.colorText});var w=(0,m.I$)("Tag",e=>v(b(e)),k),C=function(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&0>t.indexOf(o)&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var n=0,o=Object.getOwnPropertySymbols(e);nt.indexOf(o[n])&&Object.prototype.propertyIsEnumerable.call(e,o[n])&&(r[o[n]]=e[o[n]]);return r};let y=o.forwardRef((e,t)=>{let{prefixCls:r,style:n,className:a,checked:l,children:i,icon:s,onChange:u,onClick:f}=e,g=C(e,["prefixCls","style","className","checked","children","icon","onChange","onClick"]),{getPrefixCls:h,tag:p}=o.useContext(d.E_),m=h("tag",r),[v,b,k]=w(m),y=c()(m,"".concat(m,"-checkable"),{["".concat(m,"-checkable-checked")]:l},null==p?void 0:p.className,a,b,k);return v(o.createElement("span",Object.assign({},g,{ref:t,style:Object.assign(Object.assign({},n),null==p?void 0:p.style),className:y,onClick:e=>{null==u||u(!l),null==f||f(e)}}),s,o.createElement("span",null,i)))});var x=r(18536);let E=e=>(0,x.Z)(e,(t,r)=>{let{textColor:o,lightBorderColor:n,lightColor:c,darkColor:a}=r;return{["".concat(e.componentCls).concat(e.componentCls,"-").concat(t)]:{color:o,background:c,borderColor:n,"&-inverse":{color:e.colorTextLightSolid,background:a,borderColor:a},["&".concat(e.componentCls,"-borderless")]:{borderColor:"transparent"}}}});var O=(0,m.bk)(["Tag","preset"],e=>E(b(e)),k);let Z=(e,t,r)=>{let o="string"!=typeof r?r:r.charAt(0).toUpperCase()+r.slice(1);return{["".concat(e.componentCls).concat(e.componentCls,"-").concat(t)]:{color:e["color".concat(r)],background:e["color".concat(o,"Bg")],borderColor:e["color".concat(o,"Border")],["&".concat(e.componentCls,"-borderless")]:{borderColor:"transparent"}}}};var j=(0,m.bk)(["Tag","status"],e=>{let t=b(e);return[Z(t,"success","Success"),Z(t,"processing","Info"),Z(t,"error","Error"),Z(t,"warning","Warning")]},k),S=function(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&0>t.indexOf(o)&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var n=0,o=Object.getOwnPropertySymbols(e);nt.indexOf(o[n])&&Object.prototype.propertyIsEnumerable.call(e,o[n])&&(r[o[n]]=e[o[n]]);return r};let L=o.forwardRef((e,t)=>{let{prefixCls:r,className:n,rootClassName:f,style:g,children:h,icon:p,color:m,onClose:v,bordered:b=!0,visible:k}=e,C=S(e,["prefixCls","className","rootClassName","style","children","icon","color","onClose","bordered","visible"]),{getPrefixCls:y,direction:x,tag:E}=o.useContext(d.E_),[Z,L]=o.useState(!0),B=(0,a.Z)(C,["closeIcon","closable"]);o.useEffect(()=>{void 0!==k&&L(k)},[k]);let M=(0,l.o2)(m),N=(0,l.yT)(m),R=M||N,z=Object.assign(Object.assign({backgroundColor:m&&!R?m:void 0},null==E?void 0:E.style),g),I=y("tag",r),[P,T,A]=w(I),H=c()(I,null==E?void 0:E.className,{["".concat(I,"-").concat(m)]:R,["".concat(I,"-has-color")]:m&&!R,["".concat(I,"-hidden")]:!Z,["".concat(I,"-rtl")]:"rtl"===x,["".concat(I,"-borderless")]:!b},n,f,T,A),W=e=>{e.stopPropagation(),null==v||v(e),e.defaultPrevented||L(!1)},[,V]=(0,i.b)((0,i.w)(e),(0,i.w)(E),{closable:!1,closeIconRender:e=>{let t=o.createElement("span",{className:"".concat(I,"-close-icon"),onClick:W},e);return(0,s.wm)(e,t,e=>({onClick:t=>{var r;null===(r=null==e?void 0:e.onClick)||void 0===r||r.call(e,t),W(t)},className:c()(null==e?void 0:e.className,"".concat(I,"-close-icon"))}))}}),_="function"==typeof C.onClick||h&&"a"===h.type,q=p||null,F=q?o.createElement(o.Fragment,null,q,h&&o.createElement("span",null,h)):h,U=o.createElement("span",Object.assign({},B,{ref:t,className:H,style:z}),F,V,M&&o.createElement(O,{key:"preset",prefixCls:I}),N&&o.createElement(j,{key:"status",prefixCls:I}));return P(_?o.createElement(u.Z,{component:"Tag"},U):U)});L.CheckableTag=y;var B=L},79205:function(e,t,r){r.d(t,{Z:function(){return d}});var o=r(2265);let n=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),c=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(e,t,r)=>r?r.toUpperCase():t.toLowerCase()),a=e=>{let t=c(e);return t.charAt(0).toUpperCase()+t.slice(1)},l=function(){for(var e=arguments.length,t=Array(e),r=0;r!!e&&""!==e.trim()&&r.indexOf(e)===t).join(" ").trim()},i=e=>{for(let t in e)if(t.startsWith("aria-")||"role"===t||"title"===t)return!0};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 u=(0,o.forwardRef)((e,t)=>{let{color:r="currentColor",size:n=24,strokeWidth:c=2,absoluteStrokeWidth:a,className:u="",children:d,iconNode:f,...g}=e;return(0,o.createElement)("svg",{ref:t,...s,width:n,height:n,stroke:r,strokeWidth:a?24*Number(c)/Number(n):c,className:l("lucide",u),...!d&&!i(g)&&{"aria-hidden":"true"},...g},[...f.map(e=>{let[t,r]=e;return(0,o.createElement)(t,r)}),...Array.isArray(d)?d:[d]])}),d=(e,t)=>{let r=(0,o.forwardRef)((r,c)=>{let{className:i,...s}=r;return(0,o.createElement)(u,{ref:c,iconNode:t,className:l("lucide-".concat(n(a(e))),"lucide-".concat(e),i),...s})});return r.displayName=a(e),r}},30401:function(e,t,r){r.d(t,{Z:function(){return o}});let o=(0,r(79205).Z)("check",[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]])},78867:function(e,t,r){r.d(t,{Z:function(){return o}});let o=(0,r(79205).Z)("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"}]])},99397:function(e,t,r){r.d(t,{Z:function(){return o}});let o=(0,r(79205).Z)("plus",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]])},10900:function(e,t,r){var o=r(2265);let n=o.forwardRef(function(e,t){return o.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),o.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10 19l-7-7m0 0l7-7m-7 7h18"}))});t.Z=n},86462:function(e,t,r){var o=r(2265);let n=o.forwardRef(function(e,t){return o.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),o.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"}))});t.Z=n},44633:function(e,t,r){var o=r(2265);let n=o.forwardRef(function(e,t){return o.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),o.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 15l7-7 7 7"}))});t.Z=n},93416:function(e,t,r){var o=r(2265);let n=o.forwardRef(function(e,t){return o.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),o.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"}))});t.Z=n},49084:function(e,t,r){var o=r(2265);let n=o.forwardRef(function(e,t){return o.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),o.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4"}))});t.Z=n},74998:function(e,t,r){var o=r(2265);let n=o.forwardRef(function(e,t){return o.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),o.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"}))});t.Z=n}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/2202-a83ad035a17401aa.js b/litellm/proxy/_experimental/out/_next/static/chunks/2202-a83ad035a17401aa.js new file mode 100644 index 00000000000..fe20b03d919 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/2202-a83ad035a17401aa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[2202],{19431:function(e,s,t){t.d(s,{x:function(){return a.Z},z:function(){return l.Z}});var l=t(78489),a=t(84264)},65925:function(e,s,t){t.d(s,{m:function(){return i}});var l=t(57437);t(2265);var a=t(37592);let{Option:r}=a.default,i=e=>e?({"24h":"daily","7d":"weekly","30d":"monthly"})[e]||e:"Not set";s.Z=e=>{let{value:s,onChange:t,className:i="",style:n={}}=e;return(0,l.jsxs)(a.default,{style:{width:"100%",...n},value:s||void 0,onChange:t,className:i,placeholder:"n/a",allowClear:!0,children:[(0,l.jsx)(r,{value:"24h",children:"daily"}),(0,l.jsx)(r,{value:"7d",children:"weekly"}),(0,l.jsx)(r,{value:"30d",children:"monthly"})]})}},84376:function(e,s,t){var l=t(57437);t(2265);var a=t(37592);s.Z=e=>{let{teams:s,value:t,onChange:r,disabled:i}=e;return console.log("disabled",i),(0,l.jsx)(a.default,{showSearch:!0,placeholder:"Search or select a team",value:t,onChange:r,disabled:i,allowClear:!0,filterOption:(e,t)=>{if(!t)return!1;let l=null==s?void 0:s.find(e=>e.team_id===t.key);if(!l)return!1;let a=e.toLowerCase().trim(),r=(l.team_alias||"").toLowerCase(),i=(l.team_id||"").toLowerCase();return r.includes(a)||i.includes(a)},optionFilterProp:"children",children:null==s?void 0:s.map(e=>(0,l.jsxs)(a.default.Option,{value:e.team_id,children:[(0,l.jsx)("span",{className:"font-medium",children:e.team_alias})," ",(0,l.jsxs)("span",{className:"text-gray-500",children:["(",e.team_id,")"]})]},e.team_id))})}},7765:function(e,s,t){t.d(s,{Z:function(){return K}});var l=t(57437),a=t(2265),r=t(37592),i=t(10032),n=t(4260),d=t(5545),o=t(22116),c=t(87452),m=t(88829),u=t(72208),x=t(78489),h=t(43227),f=t(84264),p=t(49566),j=t(96761),g=t(98187),v=t(19250),b=t(19431),y=t(57840),N=t(65319),w=t(56609),_=t(73879),C=t(34310),k=t(38434),S=t(26349),Z=t(35291),U=t(3632),I=t(15452),V=t.n(I),L=t(71157),P=t(44643),R=t(88532),E=t(29233),O=t(9114),T=e=>{let{accessToken:s,teams:t,possibleUIRoles:r,onUsersCreated:i}=e,[n,d]=(0,a.useState)(!1),[c,m]=(0,a.useState)([]),[u,x]=(0,a.useState)(!1),[h,f]=(0,a.useState)(null),[p,j]=(0,a.useState)(null),[g,I]=(0,a.useState)(null),[T,z]=(0,a.useState)(null),[F,B]=(0,a.useState)(null),[D,M]=(0,a.useState)("http://localhost:4000");(0,a.useEffect)(()=>{(async()=>{try{let e=await (0,v.getProxyUISettings)(s);B(e)}catch(e){console.error("Error fetching UI settings:",e)}})(),M(new URL("/",window.location.href).toString())},[s]);let A=async()=>{x(!0);let e=c.map(e=>({...e,status:"pending"}));m(e);let t=!1;for(let i=0;ie.trim()).filter(Boolean),0===e.teams.length&&delete e.teams),n.models&&"string"==typeof n.models&&""!==n.models.trim()&&(e.models=n.models.split(",").map(e=>e.trim()).filter(Boolean),0===e.models.length&&delete e.models),n.max_budget&&""!==n.max_budget.toString().trim()){let s=parseFloat(n.max_budget.toString());!isNaN(s)&&s>0&&(e.max_budget=s)}n.budget_duration&&""!==n.budget_duration.trim()&&(e.budget_duration=n.budget_duration.trim()),n.metadata&&"string"==typeof n.metadata&&""!==n.metadata.trim()&&(e.metadata=n.metadata.trim()),console.log("Sending user data:",e);let a=await (0,v.userCreateCall)(s,null,e);if(console.log("Full response:",a),a&&(a.key||a.user_id)){t=!0,console.log("Success case triggered");let e=(null===(l=a.data)||void 0===l?void 0:l.user_id)||a.user_id;try{if(null==F?void 0:F.SSO_ENABLED){let e=new URL("/ui",D).toString();m(s=>s.map((s,t)=>t===i?{...s,status:"success",key:a.key||a.user_id,invitation_link:e}:s))}else{let t=await (0,v.invitationCreateCall)(s,e),l=new URL("/ui?invitation_id=".concat(t.id),D).toString();m(e=>e.map((e,s)=>s===i?{...e,status:"success",key:a.key||a.user_id,invitation_link:l}:e))}}catch(e){console.error("Error creating invitation:",e),m(e=>e.map((e,s)=>s===i?{...e,status:"success",key:a.key||a.user_id,error:"User created but failed to generate invitation link"}:e))}}else{console.log("Error case triggered");let e=(null==a?void 0:a.error)||"Failed to create user";console.log("Error message:",e),m(s=>s.map((s,t)=>t===i?{...s,status:"failed",error:e}:s))}}catch(s){console.error("Caught error:",s);let e=(null==s?void 0:null===(r=s.response)||void 0===r?void 0:null===(a=r.data)||void 0===a?void 0:a.error)||(null==s?void 0:s.message)||String(s);m(s=>s.map((s,t)=>t===i?{...s,status:"failed",error:e}:s))}}x(!1),t&&i&&i()};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(b.z,{className:"mb-0",onClick:()=>d(!0),children:"+ Bulk Invite Users"}),(0,l.jsx)(o.Z,{title:"Bulk Invite Users",visible:n,width:800,onCancel:()=>d(!1),bodyStyle:{maxHeight:"70vh",overflow:"auto"},footer:null,children:(0,l.jsx)("div",{className:"flex flex-col",children:0===c.length?(0,l.jsxs)("div",{className:"mb-6",children:[(0,l.jsxs)("div",{className:"flex items-center mb-4",children:[(0,l.jsx)("div",{className:"w-8 h-8 rounded-full bg-blue-500 text-white flex items-center justify-center mr-3",children:"1"}),(0,l.jsx)("h3",{className:"text-lg font-medium",children:"Download and fill the template"})]}),(0,l.jsxs)("div",{className:"ml-11 mb-6",children:[(0,l.jsx)("p",{className:"mb-4",children:"Add multiple users at once by following these steps:"}),(0,l.jsxs)("ol",{className:"list-decimal list-inside space-y-2 ml-2 mb-4",children:[(0,l.jsx)("li",{children:"Download our CSV template"}),(0,l.jsx)("li",{children:"Add your users' information to the spreadsheet"}),(0,l.jsx)("li",{children:"Save the file and upload it here"}),(0,l.jsx)("li",{children:"After creation, download the results file containing the Virtual Keys for each user"})]}),(0,l.jsxs)("div",{className:"bg-gray-50 p-4 rounded-md border border-gray-200 mb-4",children:[(0,l.jsx)("h4",{className:"font-medium mb-2",children:"Template Column Names"}),(0,l.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3",children:[(0,l.jsxs)("div",{className:"flex items-start",children:[(0,l.jsx)("div",{className:"w-3 h-3 rounded-full bg-red-500 mt-1.5 mr-2 flex-shrink-0"}),(0,l.jsxs)("div",{children:[(0,l.jsx)("p",{className:"font-medium",children:"user_email"}),(0,l.jsx)("p",{className:"text-sm text-gray-600",children:"User's email address (required)"})]})]}),(0,l.jsxs)("div",{className:"flex items-start",children:[(0,l.jsx)("div",{className:"w-3 h-3 rounded-full bg-red-500 mt-1.5 mr-2 flex-shrink-0"}),(0,l.jsxs)("div",{children:[(0,l.jsx)("p",{className:"font-medium",children:"user_role"}),(0,l.jsx)("p",{className:"text-sm text-gray-600",children:'User\'s role (one of: "proxy_admin", "proxy_admin_viewer", "internal_user", "internal_user_viewer")'})]})]}),(0,l.jsxs)("div",{className:"flex items-start",children:[(0,l.jsx)("div",{className:"w-3 h-3 rounded-full bg-gray-300 mt-1.5 mr-2 flex-shrink-0"}),(0,l.jsxs)("div",{children:[(0,l.jsx)("p",{className:"font-medium",children:"teams"}),(0,l.jsx)("p",{className:"text-sm text-gray-600",children:'Comma-separated team IDs (e.g., "team-1,team-2")'})]})]}),(0,l.jsxs)("div",{className:"flex items-start",children:[(0,l.jsx)("div",{className:"w-3 h-3 rounded-full bg-gray-300 mt-1.5 mr-2 flex-shrink-0"}),(0,l.jsxs)("div",{children:[(0,l.jsx)("p",{className:"font-medium",children:"max_budget"}),(0,l.jsx)("p",{className:"text-sm text-gray-600",children:'Maximum budget as a number (e.g., "100")'})]})]}),(0,l.jsxs)("div",{className:"flex items-start",children:[(0,l.jsx)("div",{className:"w-3 h-3 rounded-full bg-gray-300 mt-1.5 mr-2 flex-shrink-0"}),(0,l.jsxs)("div",{children:[(0,l.jsx)("p",{className:"font-medium",children:"budget_duration"}),(0,l.jsx)("p",{className:"text-sm text-gray-600",children:'Budget reset period (e.g., "30d", "1mo")'})]})]}),(0,l.jsxs)("div",{className:"flex items-start",children:[(0,l.jsx)("div",{className:"w-3 h-3 rounded-full bg-gray-300 mt-1.5 mr-2 flex-shrink-0"}),(0,l.jsxs)("div",{children:[(0,l.jsx)("p",{className:"font-medium",children:"models"}),(0,l.jsx)("p",{className:"text-sm text-gray-600",children:'Comma-separated allowed models (e.g., "gpt-3.5-turbo,gpt-4")'})]})]})]})]}),(0,l.jsxs)(b.z,{onClick:()=>{let e=new Blob([V().unparse([["user_email","user_role","teams","max_budget","budget_duration","models"],["user@example.com","internal_user","team-id-1,team-id-2","100","30d","gpt-3.5-turbo,gpt-4"]])],{type:"text/csv"}),s=window.URL.createObjectURL(e),t=document.createElement("a");t.href=s,t.download="bulk_users_template.csv",document.body.appendChild(t),t.click(),document.body.removeChild(t),window.URL.revokeObjectURL(s)},size:"lg",className:"w-full md:w-auto",children:[(0,l.jsx)(_.Z,{className:"mr-2"})," Download CSV Template"]})]}),(0,l.jsxs)("div",{className:"flex items-center mb-4",children:[(0,l.jsx)("div",{className:"w-8 h-8 rounded-full bg-blue-500 text-white flex items-center justify-center mr-3",children:"2"}),(0,l.jsx)("h3",{className:"text-lg font-medium",children:"Upload your completed CSV"})]}),(0,l.jsxs)("div",{className:"ml-11",children:[T?(0,l.jsxs)("div",{className:"mb-4 p-4 rounded-md border ".concat(g?"bg-red-50 border-red-200":"bg-blue-50 border-blue-200"),children:[(0,l.jsxs)("div",{className:"flex items-center justify-between",children:[(0,l.jsxs)("div",{className:"flex items-center",children:[g?(0,l.jsx)(C.Z,{className:"text-red-500 text-xl mr-3"}):(0,l.jsx)(k.Z,{className:"text-blue-500 text-xl mr-3"}),(0,l.jsxs)("div",{children:[(0,l.jsx)(y.default.Text,{strong:!0,className:g?"text-red-800":"text-blue-800",children:T.name}),(0,l.jsxs)(y.default.Text,{className:"block text-xs ".concat(g?"text-red-600":"text-blue-600"),children:[(T.size/1024).toFixed(1)," KB • ",new Date().toLocaleDateString()]})]})]}),(0,l.jsxs)(b.z,{size:"xs",variant:"secondary",onClick:()=>{z(null),m([]),f(null),j(null),I(null)},className:"flex items-center",children:[(0,l.jsx)(S.Z,{className:"mr-1"})," Remove"]})]}),g?(0,l.jsxs)("div",{className:"mt-3 text-red-600 text-sm flex items-start",children:[(0,l.jsx)(Z.Z,{className:"mr-2 mt-0.5"}),(0,l.jsx)("span",{children:g})]}):!p&&(0,l.jsxs)("div",{className:"mt-3 flex items-center",children:[(0,l.jsx)("div",{className:"w-full bg-gray-200 rounded-full h-1.5",children:(0,l.jsx)("div",{className:"bg-blue-500 h-1.5 rounded-full w-full animate-pulse"})}),(0,l.jsx)("span",{className:"ml-2 text-xs text-blue-600",children:"Processing..."})]})]}):(0,l.jsx)(N.default,{beforeUpload:e=>((f(null),j(null),I(null),z(e),"text/csv"===e.type||e.name.endsWith(".csv"))?e.size>5242880?I("File is too large (".concat((e.size/1048576).toFixed(1)," MB). Please upload a CSV file smaller than 5MB.")):V().parse(e,{complete:e=>{if(!e.data||0===e.data.length){j("The CSV file appears to be empty. Please upload a file with data."),m([]);return}if(1===e.data.length){j("The CSV file only contains headers but no user data. Please add user data to your CSV."),m([]);return}let s=e.data[0];if(0===s.length||1===s.length&&""===s[0]){j("The CSV file doesn't contain any column headers. Please make sure your CSV has headers."),m([]);return}let l=["user_email","user_role"].filter(e=>!s.includes(e));if(l.length>0){j("Your CSV is missing these required columns: ".concat(l.join(", "),". Please add these columns to your CSV file.")),m([]);return}try{let l=e.data.slice(1).map((e,l)=>{var a,r,i,n,d,o;if(0===e.length||1===e.length&&""===e[0])return null;if(e.length=parseFloat(c.max_budget.toString())&&m.push("Max budget must be greater than 0")),c.budget_duration&&!c.budget_duration.match(/^\d+[dhmwy]$|^\d+mo$/)&&m.push('Invalid budget duration format "'.concat(c.budget_duration,'". Use format like "30d", "1mo", "2w", "6h"')),c.teams&&"string"==typeof c.teams&&t&&t.length>0){let e=t.map(e=>e.team_id),s=c.teams.split(",").map(e=>e.trim()).filter(s=>!e.includes(s));s.length>0&&m.push("Unknown team(s): ".concat(s.join(", ")))}return m.length>0&&(c.isValid=!1,c.error=m.join(", ")),c}).filter(Boolean),a=l.filter(e=>e.isValid);m(l),0===l.length?j("No valid data rows found in the CSV file. Please check your file format."):0===a.length?f("No valid users found in the CSV. Please check the errors below and fix your CSV file."):a.length{f("Failed to parse CSV file: ".concat(e.message)),m([])},header:!1}):(I("Invalid file type: ".concat(e.name,". Please upload a CSV file (.csv extension).")),O.Z.fromBackend("Invalid file type. Please upload a CSV file.")),!1),accept:".csv",maxCount:1,showUploadList:!1,children:(0,l.jsxs)("div",{className:"border-2 border-dashed border-gray-300 rounded-lg p-8 text-center hover:border-blue-500 transition-colors cursor-pointer",children:[(0,l.jsx)(U.Z,{className:"text-3xl text-gray-400 mb-2"}),(0,l.jsx)("p",{className:"mb-1",children:"Drag and drop your CSV file here"}),(0,l.jsx)("p",{className:"text-sm text-gray-500 mb-3",children:"or"}),(0,l.jsx)(b.z,{size:"sm",children:"Browse files"}),(0,l.jsx)("p",{className:"text-xs text-gray-500 mt-4",children:"Only CSV files (.csv) are supported"})]})}),p&&(0,l.jsx)("div",{className:"mb-4 p-4 bg-yellow-50 border border-yellow-200 rounded-md",children:(0,l.jsxs)("div",{className:"flex items-start",children:[(0,l.jsx)(R.Z,{className:"h-5 w-5 text-yellow-500 mr-2 mt-0.5"}),(0,l.jsxs)("div",{children:[(0,l.jsx)(y.default.Text,{strong:!0,className:"text-yellow-800",children:"CSV Structure Error"}),(0,l.jsx)(y.default.Paragraph,{className:"text-yellow-700 mt-1 mb-0",children:p}),(0,l.jsx)(y.default.Paragraph,{className:"text-yellow-700 mt-2 mb-0",children:"Please download our template and ensure your CSV follows the required format."})]})]})})]})]}):(0,l.jsxs)("div",{className:"mb-6",children:[(0,l.jsxs)("div",{className:"flex items-center mb-4",children:[(0,l.jsx)("div",{className:"w-8 h-8 rounded-full bg-blue-500 text-white flex items-center justify-center mr-3",children:"3"}),(0,l.jsx)("h3",{className:"text-lg font-medium",children:c.some(e=>"success"===e.status||"failed"===e.status)?"User Creation Results":"Review and create users"})]}),h&&(0,l.jsx)("div",{className:"ml-11 mb-4 p-4 bg-red-50 border border-red-200 rounded-md",children:(0,l.jsxs)("div",{className:"flex items-start",children:[(0,l.jsx)(Z.Z,{className:"text-red-500 mr-2 mt-1"}),(0,l.jsxs)("div",{children:[(0,l.jsx)(b.x,{className:"text-red-600 font-medium",children:h}),c.some(e=>!e.isValid)&&(0,l.jsxs)("ul",{className:"mt-2 list-disc list-inside text-red-600 text-sm",children:[(0,l.jsx)("li",{children:"Check the table below for specific errors in each row"}),(0,l.jsx)("li",{children:"Common issues include invalid email formats, missing required fields, or incorrect role values"}),(0,l.jsx)("li",{children:"Fix these issues in your CSV file and upload again"})]})]})]})}),(0,l.jsxs)("div",{className:"ml-11",children:[(0,l.jsxs)("div",{className:"flex justify-between items-center mb-3",children:[(0,l.jsx)("div",{className:"flex items-center",children:c.some(e=>"success"===e.status||"failed"===e.status)?(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)(b.x,{className:"text-lg font-medium mr-3",children:"Creation Summary"}),(0,l.jsxs)(b.x,{className:"text-sm bg-green-100 text-green-800 px-2 py-1 rounded mr-2",children:[c.filter(e=>"success"===e.status).length," Successful"]}),c.some(e=>"failed"===e.status)&&(0,l.jsxs)(b.x,{className:"text-sm bg-red-100 text-red-800 px-2 py-1 rounded",children:[c.filter(e=>"failed"===e.status).length," Failed"]})]}):(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)(b.x,{className:"text-lg font-medium mr-3",children:"User Preview"}),(0,l.jsxs)(b.x,{className:"text-sm bg-blue-100 text-blue-800 px-2 py-1 rounded",children:[c.filter(e=>e.isValid).length," of ",c.length," users valid"]})]})}),!c.some(e=>"success"===e.status||"failed"===e.status)&&(0,l.jsxs)("div",{className:"flex space-x-3",children:[(0,l.jsx)(b.z,{onClick:()=>{m([]),f(null)},variant:"secondary",children:"Back"}),(0,l.jsx)(b.z,{onClick:A,disabled:0===c.filter(e=>e.isValid).length||u,children:u?"Creating...":"Create ".concat(c.filter(e=>e.isValid).length," Users")})]})]}),c.some(e=>"success"===e.status)&&(0,l.jsx)("div",{className:"mb-4 p-4 bg-blue-50 border border-blue-200 rounded-md",children:(0,l.jsxs)("div",{className:"flex items-start",children:[(0,l.jsx)("div",{className:"mr-3 mt-1",children:(0,l.jsx)(P.Z,{className:"h-5 w-5 text-blue-500"})}),(0,l.jsxs)("div",{children:[(0,l.jsx)(b.x,{className:"font-medium text-blue-800",children:"User creation complete"}),(0,l.jsxs)(b.x,{className:"block text-sm text-blue-700 mt-1",children:[(0,l.jsx)("span",{className:"font-medium",children:"Next step:"})," Download the credentials file containing Virtual Keys and invitation links. Users will need these Virtual Keys to make LLM requests through LiteLLM."]})]})]})}),(0,l.jsx)(w.Z,{dataSource:c,columns:[{title:"Row",dataIndex:"rowNumber",key:"rowNumber",width:80},{title:"Email",dataIndex:"user_email",key:"user_email"},{title:"Role",dataIndex:"user_role",key:"user_role"},{title:"Teams",dataIndex:"teams",key:"teams"},{title:"Budget",dataIndex:"max_budget",key:"max_budget"},{title:"Status",key:"status",render:(e,s)=>s.isValid?s.status&&"pending"!==s.status?"success"===s.status?(0,l.jsxs)("div",{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)(P.Z,{className:"h-5 w-5 text-green-500 mr-2"}),(0,l.jsx)("span",{className:"text-green-500",children:"Success"})]}),s.invitation_link&&(0,l.jsx)("div",{className:"mt-1",children:(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)("span",{className:"text-xs text-gray-500 truncate max-w-[150px]",children:s.invitation_link}),(0,l.jsx)(E.CopyToClipboard,{text:s.invitation_link,onCopy:()=>O.Z.success("Invitation link copied!"),children:(0,l.jsx)("button",{className:"ml-1 text-blue-500 text-xs hover:text-blue-700",children:"Copy"})})]})})]}):(0,l.jsxs)("div",{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)(L.Z,{className:"h-5 w-5 text-red-500 mr-2"}),(0,l.jsx)("span",{className:"text-red-500",children:"Failed"})]}),s.error&&(0,l.jsx)("span",{className:"text-sm text-red-500 ml-7",children:JSON.stringify(s.error)})]}):(0,l.jsx)("span",{className:"text-gray-500",children:"Pending"}):(0,l.jsxs)("div",{children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)(L.Z,{className:"h-5 w-5 text-red-500 mr-2"}),(0,l.jsx)("span",{className:"text-red-500",children:"Invalid"})]}),s.error&&(0,l.jsx)("span",{className:"text-sm text-red-500 ml-7",children:s.error})]})}],size:"small",pagination:{pageSize:5},scroll:{y:300},rowClassName:e=>e.isValid?"":"bg-red-50"}),!c.some(e=>"success"===e.status||"failed"===e.status)&&(0,l.jsxs)("div",{className:"flex justify-end mt-4",children:[(0,l.jsx)(b.z,{onClick:()=>{m([]),f(null)},variant:"secondary",className:"mr-3",children:"Back"}),(0,l.jsx)(b.z,{onClick:A,disabled:0===c.filter(e=>e.isValid).length||u,children:u?"Creating...":"Create ".concat(c.filter(e=>e.isValid).length," Users")})]}),c.some(e=>"success"===e.status||"failed"===e.status)&&(0,l.jsxs)("div",{className:"flex justify-end mt-4",children:[(0,l.jsx)(b.z,{onClick:()=>{m([]),f(null)},variant:"secondary",className:"mr-3",children:"Start New Bulk Import"}),(0,l.jsxs)(b.z,{onClick:()=>{let e=c.map(e=>({user_email:e.user_email,user_role:e.user_role,status:e.status,key:e.key||"",invitation_link:e.invitation_link||"",error:e.error||""})),s=new Blob([V().unparse(e)],{type:"text/csv"}),t=window.URL.createObjectURL(s),l=document.createElement("a");l.href=t,l.download="bulk_users_results.csv",document.body.appendChild(l),l.click(),document.body.removeChild(l),window.URL.revokeObjectURL(t)},variant:"primary",className:"flex items-center",children:[(0,l.jsx)(_.Z,{className:"mr-2"})," Download User Credentials"]})]})]})]})})})]})},z=t(99981),F=t(15424),B=t(46468),D=t(29827),M=t(84376);let{Option:A}=r.default,q=()=>"undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){let s=16*Math.random()|0;return("x"==e?s:3&s|8).toString(16)});var K=e=>{let{userID:s,accessToken:t,teams:b,possibleUIRoles:y,onUserCreated:N,isEmbedded:w=!1}=e,_=(0,D.NL)(),[C,k]=(0,a.useState)(null),[S]=i.Z.useForm(),[Z,U]=(0,a.useState)(!1),[I,V]=(0,a.useState)(!1),[L,P]=(0,a.useState)([]),[R,E]=(0,a.useState)(!1),[A,K]=(0,a.useState)(null),[J,W]=(0,a.useState)(null);(0,a.useEffect)(()=>{let e=async()=>{try{let e=await (0,v.modelAvailableCall)(t,s,"any"),l=[];for(let s=0;s{var l,a,r;try{O.Z.info("Making API Call"),w||U(!0),e.models&&0!==e.models.length||"proxy_admin"===e.user_role||(console.log("formValues.user_role",e.user_role),e.models=["no-default-models"]),console.log("formValues in create user:",e);let a=await (0,v.userCreateCall)(t,null,e);await _.invalidateQueries({queryKey:["userList"]}),console.log("user create Response:",a),V(!0);let r=(null===(l=a.data)||void 0===l?void 0:l.user_id)||a.user_id;if(N&&w){N(r),S.resetFields();return}if(null==C?void 0:C.SSO_ENABLED){let e={id:q(),user_id:r,is_accepted:!1,accepted_at:null,expires_at:new Date(Date.now()+6048e5),created_at:new Date,created_by:s,updated_at:new Date,updated_by:s,has_user_setup_sso:!0};K(e),E(!0)}else(0,v.invitationCreateCall)(t,r).then(e=>{e.has_user_setup_sso=!1,K(e),E(!0)});O.Z.success("API user Created"),S.resetFields(),localStorage.removeItem("userData"+s)}catch(s){let e=(null===(r=s.response)||void 0===r?void 0:null===(a=r.data)||void 0===a?void 0:a.detail)||(null==s?void 0:s.message)||"Error creating the user";O.Z.fromBackend(e),console.error("Error creating the user:",s)}};return w?(0,l.jsxs)(i.Z,{form:S,onFinish:$,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(i.Z.Item,{label:"User Email",name:"user_email",children:(0,l.jsx)(p.Z,{placeholder:""})}),(0,l.jsx)(i.Z.Item,{label:"User Role",name:"user_role",children:(0,l.jsx)(r.default,{children:y&&Object.entries(y).map(e=>{let[s,{ui_label:t,description:a}]=e;return(0,l.jsx)(h.Z,{value:s,title:t,children:(0,l.jsxs)("div",{className:"flex",children:[t," ",(0,l.jsx)("p",{className:"ml-2",style:{color:"gray",fontSize:"12px"},children:a})]})},s)})})}),(0,l.jsx)(i.Z.Item,{label:"Team",name:"team_id",children:(0,l.jsx)(r.default,{placeholder:"Select Team",style:{width:"100%"},children:(0,l.jsx)(M.Z,{teams:b})})}),(0,l.jsx)(i.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(n.default.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(d.ZP,{htmlType:"submit",children:"Create User"})})]}):(0,l.jsxs)("div",{className:"flex gap-2",children:[(0,l.jsx)(x.Z,{className:"mb-0",onClick:()=>U(!0),children:"+ Invite User"}),(0,l.jsx)(T,{accessToken:t,teams:b,possibleUIRoles:y}),(0,l.jsxs)(o.Z,{title:"Invite User",visible:Z,width:800,footer:null,onOk:()=>{U(!1),S.resetFields()},onCancel:()=>{U(!1),V(!1),S.resetFields()},children:[(0,l.jsx)(f.Z,{className:"mb-1",children:"Create a User who can own keys"}),(0,l.jsxs)(i.Z,{form:S,onFinish:$,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,l.jsx)(i.Z.Item,{label:"User Email",name:"user_email",children:(0,l.jsx)(p.Z,{placeholder:""})}),(0,l.jsx)(i.Z.Item,{label:(0,l.jsxs)("span",{children:["Global Proxy Role"," ",(0,l.jsx)(z.Z,{title:"This is the role that the user will globally on the proxy. This role is independent of any team/org specific roles.",children:(0,l.jsx)(F.Z,{})})]}),name:"user_role",children:(0,l.jsx)(r.default,{children:y&&Object.entries(y).map(e=>{let[s,{ui_label:t,description:a}]=e;return(0,l.jsx)(h.Z,{value:s,title:t,children:(0,l.jsxs)("div",{className:"flex",children:[t," ",(0,l.jsx)("p",{className:"ml-2",style:{color:"gray",fontSize:"12px"},children:a})]})},s)})})}),(0,l.jsx)(i.Z.Item,{label:"Team",className:"gap-2",name:"team_id",help:"If selected, user will be added as a 'user' role to the team.",children:(0,l.jsx)(M.Z,{teams:b})}),(0,l.jsx)(i.Z.Item,{label:"Metadata",name:"metadata",children:(0,l.jsx)(n.default.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,l.jsxs)(c.Z,{children:[(0,l.jsx)(u.Z,{children:(0,l.jsx)(j.Z,{children:"Personal Key Creation"})}),(0,l.jsx)(m.Z,{children:(0,l.jsx)(i.Z.Item,{className:"gap-2",label:(0,l.jsxs)("span",{children:["Models"," ",(0,l.jsx)(z.Z,{title:"Models user has access to, outside of team scope.",children:(0,l.jsx)(F.Z,{style:{marginLeft:"4px"}})})]}),name:"models",help:"Models user has access to, outside of team scope.",children:(0,l.jsxs)(r.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,l.jsx)(r.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),(0,l.jsx)(r.default.Option,{value:"no-default-models",children:"No Default Models"},"no-default-models"),L.map(e=>(0,l.jsx)(r.default.Option,{value:e,children:(0,B.W0)(e)},e))]})})})]}),(0,l.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,l.jsx)(d.ZP,{htmlType:"submit",children:"Create User"})})]})]}),I&&(0,l.jsx)(g.Z,{isInvitationLinkModalVisible:R,setIsInvitationLinkModalVisible:E,baseUrl:J||"",invitationLinkData:A})]})}},98187:function(e,s,t){t.d(s,{Z:function(){return o}});var l=t(57437);t(2265);var a=t(57840),r=t(22116),i=t(29233),n=t(19431),d=t(9114);function o(e){let{isInvitationLinkModalVisible:s,setIsInvitationLinkModalVisible:t,baseUrl:o,invitationLinkData:c,modalType:m="invitation"}=e,{Title:u,Paragraph:x}=a.default,h=()=>{if(!o)return"";let e=new URL(o).pathname,s=e&&"/"!==e?"".concat(e,"/ui"):"ui";if(null==c?void 0:c.has_user_setup_sso)return new URL(s,o).toString();let t="".concat(s,"?invitation_id=").concat(null==c?void 0:c.id);return"resetPassword"===m&&(t+="&action=reset_password"),new URL(t,o).toString()};return(0,l.jsxs)(r.Z,{title:"invitation"===m?"Invitation Link":"Reset Password Link",visible:s,width:800,footer:null,onOk:()=>{t(!1)},onCancel:()=>{t(!1)},children:[(0,l.jsx)(x,{children:"invitation"===m?"Copy and send the generated link to onboard this user to the proxy.":"Copy and send the generated link to the user to reset their password."}),(0,l.jsxs)("div",{className:"flex justify-between pt-5 pb-2",children:[(0,l.jsx)(n.x,{className:"text-base",children:"User ID"}),(0,l.jsx)(n.x,{children:null==c?void 0:c.user_id})]}),(0,l.jsxs)("div",{className:"flex justify-between pt-5 pb-2",children:[(0,l.jsx)(n.x,{children:"invitation"===m?"Invitation Link":"Reset Password Link"}),(0,l.jsx)(n.x,{children:(0,l.jsx)(n.x,{children:h()})})]}),(0,l.jsx)("div",{className:"flex justify-end mt-5",children:(0,l.jsx)(i.CopyToClipboard,{text:h(),onCopy:()=>d.Z.success("Copied!"),children:(0,l.jsx)(n.z,{variant:"primary",children:"invitation"===m?"Copy invitation link":"Copy password reset link"})})})]})}}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/2227-5ae3f36b0a81c5b4.js b/litellm/proxy/_experimental/out/_next/static/chunks/2227-5ae3f36b0a81c5b4.js new file mode 100644 index 00000000000..58d3db1949b --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/2227-5ae3f36b0a81c5b4.js @@ -0,0 +1 @@ +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[2227],{75105:function(e,t,n){"use strict";n.d(t,{Z:function(){return eo}});var r=n(5853),o=n(2265),i=n(47625),a=n(93765),l=n(61994),c=n(84735),s=n(86757),u=n.n(s),d=n(95645),p=n.n(d),f=n(77571),m=n.n(f),h=n(82559),y=n.n(h),v=n(21652),b=n.n(v),g=n(57165),k=n(81889),x=n(9841),A=n(58772),O=n(34067),w=n(16630),j=n(85355),E=n(82944),P=["layout","type","stroke","connectNulls","isRange","ref"],S=["key"];function L(e){return(L="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 N(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n={};for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r)){if(t.indexOf(r)>=0)continue;n[r]=e[r]}return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function C(){return(C=Object.assign?Object.assign.bind():function(e){for(var t=1;t0||!b()(l,r)||!b()(c,o))?this.renderAreaWithAnimation(e,t):this.renderAreaStatically(r,o,e,t)}},{key:"render",value:function(){var e,t=this.props,n=t.hide,r=t.dot,i=t.points,a=t.className,c=t.top,s=t.left,u=t.xAxis,d=t.yAxis,p=t.width,f=t.height,h=t.isAnimationActive,y=t.id;if(n||!i||!i.length)return null;var v=this.state.isAnimationFinished,b=1===i.length,g=(0,l.Z)("recharts-area",a),k=u&&u.allowDataOverflow,O=d&&d.allowDataOverflow,w=k||O,j=m()(y)?this.id:y,P=null!==(e=(0,E.L6)(r,!1))&&void 0!==e?e:{r:3,strokeWidth:2},S=P.r,L=P.strokeWidth,N=((0,E.jf)(r)?r:{}).clipDot,C=void 0===N||N,T=2*(void 0===S?3:S)+(void 0===L?2:L);return o.createElement(x.m,{className:g},k||O?o.createElement("defs",null,o.createElement("clipPath",{id:"clipPath-".concat(j)},o.createElement("rect",{x:k?s:s-p/2,y:O?c:c-f/2,width:k?p:2*p,height:O?f:2*f})),!C&&o.createElement("clipPath",{id:"clipPath-dots-".concat(j)},o.createElement("rect",{x:s-T/2,y:c-T/2,width:p+T,height:f+T}))):null,b?null:this.renderArea(w,j),(r||b)&&this.renderDots(w,C,j),(!h||v)&&A.e.renderCallByParent(this.props,i))}}],n=[{key:"getDerivedStateFromProps",value:function(e,t){return e.animationId!==t.prevAnimationId?{prevAnimationId:e.animationId,curPoints:e.points,curBaseLine:e.baseLine,prevPoints:t.curPoints,prevBaseLine:t.curBaseLine}:e.points!==t.curPoints||e.baseLine!==t.curBaseLine?{curPoints:e.points,curBaseLine:e.baseLine}:null}}],t&&D(r.prototype,t),n&&D(r,n),Object.defineProperty(r,"prototype",{writable:!1}),r}(o.PureComponent);B(K,"displayName","Area"),B(K,"defaultProps",{stroke:"#3182bd",fill:"#3182bd",fillOpacity:.6,xAxisId:0,yAxisId:0,legendType:"line",connectNulls:!1,points:[],dot:!1,activeDot:!0,hide:!1,isAnimationActive:!O.x.isSsr,animationBegin:0,animationDuration:1500,animationEasing:"ease"}),B(K,"getBaseValue",function(e,t,n,r){var o=e.layout,i=e.baseValue,a=t.props.baseValue,l=null!=a?a:i;if((0,w.hj)(l)&&"number"==typeof l)return l;var c="horizontal"===o?r:n,s=c.scale.domain();if("number"===c.type){var u=Math.max(s[0],s[1]),d=Math.min(s[0],s[1]);return"dataMin"===l?d:"dataMax"===l?u:u<0?u:Math.max(Math.min(s[0],s[1]),0)}return"dataMin"===l?s[0]:"dataMax"===l?s[1]:s[0]}),B(K,"getComposedData",function(e){var t,n=e.props,r=e.item,o=e.xAxis,i=e.yAxis,a=e.xAxisTicks,l=e.yAxisTicks,c=e.bandSize,s=e.dataKey,u=e.stackedData,d=e.dataStartIndex,p=e.displayedData,f=e.offset,m=n.layout,h=u&&u.length,y=K.getBaseValue(n,r,o,i),v="horizontal"===m,b=!1,g=p.map(function(e,t){h?n=u[d+t]:Array.isArray(n=(0,j.F$)(e,s))?b=!0:n=[y,n];var n,r=null==n[1]||h&&null==(0,j.F$)(e,s);return v?{x:(0,j.Hv)({axis:o,ticks:a,bandSize:c,entry:e,index:t}),y:r?null:i.scale(n[1]),value:n,payload:e}:{x:r?null:o.scale(n[1]),y:(0,j.Hv)({axis:i,ticks:l,bandSize:c,entry:e,index:t}),value:n,payload:e}});return t=h||b?g.map(function(e){var t=Array.isArray(e.value)?e.value[0]:null;return v?{x:e.x,y:null!=t&&null!=e.y?i.scale(t):null}:{x:null!=t?o.scale(t):null,y:e.y}}):v?i.scale(y):o.scale(y),R({points:g,baseLine:t,layout:m,isRange:b},f)}),B(K,"renderDotItem",function(e,t){var n;if(o.isValidElement(e))n=o.cloneElement(e,t);else if(u()(e))n=e(t);else{var r=(0,l.Z)("recharts-area-dot","boolean"!=typeof e?e.className:""),i=t.key,a=N(t,S);n=o.createElement(k.o,C({},a,{key:i,className:r}))}return n});var _=n(97059),H=n(62994),W=n(25311),z=(0,a.z)({chartName:"AreaChart",GraphicalChild:K,axisComponents:[{axisType:"xAxis",AxisComp:_.K},{axisType:"yAxis",AxisComp:H.B}],formatAxisMap:W.t9}),V=n(56940),G=n(26680),q=n(8147),$=n(22190),X=n(54061),U=n(65278),Y=n(98593),Q=n(92666),J=n(32644),ee=n(7084),et=n(26898),en=n(13241),er=n(1153);let eo=o.forwardRef((e,t)=>{let{data:n=[],categories:a=[],index:l,stack:c=!1,colors:s=et.s,valueFormatter:u=er.Cj,startEndOnly:d=!1,showXAxis:p=!0,showYAxis:f=!0,yAxisWidth:m=56,intervalType:h="equidistantPreserveStart",showAnimation:y=!1,animationDuration:v=900,showTooltip:b=!0,showLegend:g=!0,showGridLines:x=!0,showGradient:A=!0,autoMinValue:O=!1,curveType:w="linear",minValue:j,maxValue:E,connectNulls:P=!1,allowDecimals:S=!0,noDataText:L,className:N,onValueChange:C,enableLegendSlider:T=!1,customTooltip:R,rotateLabelX:D,padding:M=(p||f)&&(!d||f)?{left:20,right:20}:{left:0,right:0},tickGap:I=5,xAxisLabel:Z,yAxisLabel:B}=e,F=(0,r._T)(e,["data","categories","index","stack","colors","valueFormatter","startEndOnly","showXAxis","showYAxis","yAxisWidth","intervalType","showAnimation","animationDuration","showTooltip","showLegend","showGridLines","showGradient","autoMinValue","curveType","minValue","maxValue","connectNulls","allowDecimals","noDataText","className","onValueChange","enableLegendSlider","customTooltip","rotateLabelX","padding","tickGap","xAxisLabel","yAxisLabel"]),[W,eo]=(0,o.useState)(60),[ei,ea]=(0,o.useState)(void 0),[el,ec]=(0,o.useState)(void 0),es=(0,J.me)(a,s),eu=(0,J.i4)(O,j,E),ed=!!C;function ep(e){ed&&(e===el&&!ei||(0,J.FB)(n,e)&&ei&&ei.dataKey===e?(ec(void 0),null==C||C(null)):(ec(e),null==C||C({eventType:"category",categoryClicked:e})),ea(void 0))}return o.createElement("div",Object.assign({ref:t,className:(0,en.q)("w-full h-80",N)},F),o.createElement(i.h,{className:"h-full w-full"},(null==n?void 0:n.length)?o.createElement(z,{data:n,onClick:ed&&(el||ei)?()=>{ea(void 0),ec(void 0),null==C||C(null)}:void 0,margin:{bottom:Z?30:void 0,left:B?20:void 0,right:B?5:void 0,top:5}},x?o.createElement(V.q,{className:(0,en.q)("stroke-1","stroke-tremor-border","dark:stroke-dark-tremor-border"),horizontal:!0,vertical:!1}):null,o.createElement(_.K,{padding:M,hide:!p,dataKey:l,tick:{transform:"translate(0, 6)"},ticks:d?[n[0][l],n[n.length-1][l]]:void 0,fill:"",stroke:"",className:(0,en.q)("text-tremor-label","fill-tremor-content","dark:fill-dark-tremor-content"),interval:d?"preserveStartEnd":h,tickLine:!1,axisLine:!1,minTickGap:I,angle:null==D?void 0:D.angle,dy:null==D?void 0:D.verticalShift,height:null==D?void 0:D.xAxisHeight},Z&&o.createElement(G._,{position:"insideBottom",offset:-20,className:"fill-tremor-content-emphasis text-tremor-default font-medium dark:fill-dark-tremor-content-emphasis"},Z)),o.createElement(H.B,{width:m,hide:!f,axisLine:!1,tickLine:!1,type:"number",domain:eu,tick:{transform:"translate(-3, 0)"},fill:"",stroke:"",className:(0,en.q)("text-tremor-label","fill-tremor-content","dark:fill-dark-tremor-content"),tickFormatter:u,allowDecimals:S},B&&o.createElement(G._,{position:"insideLeft",style:{textAnchor:"middle"},angle:-90,offset:-15,className:"fill-tremor-content-emphasis text-tremor-default font-medium dark:fill-dark-tremor-content-emphasis"},B)),o.createElement(q.u,{wrapperStyle:{outline:"none"},isAnimationActive:!1,cursor:{stroke:"#d1d5db",strokeWidth:1},content:b?e=>{let{active:t,payload:n,label:r}=e;return R?o.createElement(R,{payload:null==n?void 0:n.map(e=>{var t;return Object.assign(Object.assign({},e),{color:null!==(t=es.get(e.dataKey))&&void 0!==t?t:ee.fr.Gray})}),active:t,label:r}):o.createElement(Y.ZP,{active:t,payload:n,label:r,valueFormatter:u,categoryColors:es})}:o.createElement(o.Fragment,null),position:{y:0}}),g?o.createElement($.D,{verticalAlign:"top",height:W,content:e=>{let{payload:t}=e;return(0,U.Z)({payload:t},es,eo,el,ed?e=>ep(e):void 0,T)}}):null,a.map(e=>{var t,n,r;let i=(null!==(t=es.get(e))&&void 0!==t?t:ee.fr.Gray).replace("#","");return o.createElement("defs",{key:e},A?o.createElement("linearGradient",{className:(0,er.bM)(null!==(n=es.get(e))&&void 0!==n?n:ee.fr.Gray,et.K.text).textColor,id:i,x1:"0",y1:"0",x2:"0",y2:"1"},o.createElement("stop",{offset:"5%",stopColor:"currentColor",stopOpacity:ei||el&&el!==e?.15:.4}),o.createElement("stop",{offset:"95%",stopColor:"currentColor",stopOpacity:0})):o.createElement("linearGradient",{className:(0,er.bM)(null!==(r=es.get(e))&&void 0!==r?r:ee.fr.Gray,et.K.text).textColor,id:i,x1:"0",y1:"0",x2:"0",y2:"1"},o.createElement("stop",{stopColor:"currentColor",stopOpacity:ei||el&&el!==e?.1:.3})))}),a.map(e=>{var t,r;let i=(null!==(t=es.get(e))&&void 0!==t?t:ee.fr.Gray).replace("#","");return o.createElement(K,{className:(0,er.bM)(null!==(r=es.get(e))&&void 0!==r?r:ee.fr.Gray,et.K.text).strokeColor,strokeOpacity:ei||el&&el!==e?.3:1,activeDot:e=>{var t;let{cx:r,cy:i,stroke:a,strokeLinecap:l,strokeLinejoin:c,strokeWidth:s,dataKey:u}=e;return o.createElement(k.o,{className:(0,en.q)("stroke-tremor-background dark:stroke-dark-tremor-background",C?"cursor-pointer":"",(0,er.bM)(null!==(t=es.get(u))&&void 0!==t?t:ee.fr.Gray,et.K.text).fillColor),cx:r,cy:i,r:5,fill:"",stroke:a,strokeLinecap:l,strokeLinejoin:c,strokeWidth:s,onClick:(t,r)=>{r.stopPropagation(),ed&&(e.index===(null==ei?void 0:ei.index)&&e.dataKey===(null==ei?void 0:ei.dataKey)||(0,J.FB)(n,e.dataKey)&&el&&el===e.dataKey?(ec(void 0),ea(void 0),null==C||C(null)):(ec(e.dataKey),ea({index:e.index,dataKey:e.dataKey}),null==C||C(Object.assign({eventType:"dot",categoryClicked:e.dataKey},e.payload))))}})},dot:t=>{var r;let{stroke:i,strokeLinecap:a,strokeLinejoin:l,strokeWidth:c,cx:s,cy:u,dataKey:d,index:p}=t;return(0,J.FB)(n,e)&&!(ei||el&&el!==e)||(null==ei?void 0:ei.index)===p&&(null==ei?void 0:ei.dataKey)===e?o.createElement(k.o,{key:p,cx:s,cy:u,r:5,stroke:i,fill:"",strokeLinecap:a,strokeLinejoin:l,strokeWidth:c,className:(0,en.q)("stroke-tremor-background dark:stroke-dark-tremor-background",C?"cursor-pointer":"",(0,er.bM)(null!==(r=es.get(d))&&void 0!==r?r:ee.fr.Gray,et.K.text).fillColor)}):o.createElement(o.Fragment,{key:p})},key:e,name:e,type:w,dataKey:e,stroke:"",fill:"url(#".concat(i,")"),strokeWidth:2,strokeLinejoin:"round",strokeLinecap:"round",isAnimationActive:y,animationDuration:v,stackId:c?"a":void 0,connectNulls:P})}),C?a.map(e=>o.createElement(X.x,{className:(0,en.q)("cursor-pointer"),strokeOpacity:0,key:e,name:e,type:w,dataKey:e,stroke:"transparent",fill:"transparent",legendType:"none",tooltipType:"none",strokeWidth:12,connectNulls:P,onClick:(e,t)=>{t.stopPropagation();let{name:n}=e;ep(n)}})):null):o.createElement(Q.Z,{noDataText:L})))});eo.displayName="AreaChart"},14042:function(e,t,n){"use strict";n.d(t,{Z:function(){return e_}});var r=n(5853),o=n(7084),i=n(26898),a=n(13241),l=n(1153),c=n(2265),s=n(60474),u=n(47625),d=n(93765),p=n(86757),f=n.n(p),m=n(61994),h=n(9841),y=n(81889),v=n(82944),b=["points","className","baseLinePoints","connectNulls"];function g(){return(g=Object.assign?Object.assign.bind():function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:[],t=[[]];return e.forEach(function(e){A(e)?t[t.length-1].push(e):t[t.length-1].length>0&&t.push([])}),A(e[0])&&t[t.length-1].push(e[0]),t[t.length-1].length<=0&&(t=t.slice(0,-1)),t},w=function(e,t){var n=O(e);t&&(n=[n.reduce(function(e,t){return[].concat(k(e),k(t))},[])]);var r=n.map(function(e){return e.reduce(function(e,t,n){return"".concat(e).concat(0===n?"M":"L").concat(t.x,",").concat(t.y)},"")}).join("");return 1===n.length?"".concat(r,"Z"):r},j=function(e,t,n){var r=w(e,n);return"".concat("Z"===r.slice(-1)?r.slice(0,-1):r,"L").concat(w(t.reverse(),n).slice(1))},E=function(e){var t=e.points,n=e.className,r=e.baseLinePoints,o=e.connectNulls,i=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n={};for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r)){if(t.indexOf(r)>=0)continue;n[r]=e[r]}return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,b);if(!t||!t.length)return null;var a=(0,m.Z)("recharts-polygon",n);if(r&&r.length){var l=i.stroke&&"none"!==i.stroke,s=j(t,r,o);return c.createElement("g",{className:a},c.createElement("path",g({},(0,v.L6)(i,!0),{fill:"Z"===s.slice(-1)?i.fill:"none",stroke:"none",d:s})),l?c.createElement("path",g({},(0,v.L6)(i,!0),{fill:"none",d:w(t,o)})):null,l?c.createElement("path",g({},(0,v.L6)(i,!0),{fill:"none",d:w(r,o)})):null)}var u=w(t,o);return c.createElement("path",g({},(0,v.L6)(i,!0),{fill:"Z"===u.slice(-1)?i.fill:"none",className:a,d:u}))},P=n(58811),S=n(41637),L=n(39206);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 C(){return(C=Object.assign?Object.assign.bind():function(e){for(var t=1;t1e-5?"outer"===t?"start":"end":n<-.00001?"outer"===t?"end":"start":"middle"}},{key:"renderAxisLine",value:function(){var e=this.props,t=e.cx,n=e.cy,r=e.radius,o=e.axisLine,i=e.axisLineType,a=R(R({},(0,v.L6)(this.props,!1)),{},{fill:"none"},(0,v.L6)(o,!1));if("circle"===i)return c.createElement(y.o,C({className:"recharts-polar-angle-axis-line"},a,{cx:t,cy:n,r:r}));var l=this.props.ticks.map(function(e){return(0,L.op)(t,n,r,e.coordinate)});return c.createElement(E,C({className:"recharts-polar-angle-axis-line"},a,{points:l}))}},{key:"renderTicks",value:function(){var e=this,t=this.props,n=t.ticks,o=t.tick,i=t.tickLine,a=t.tickFormatter,l=t.stroke,s=(0,v.L6)(this.props,!1),u=(0,v.L6)(o,!1),d=R(R({},s),{},{fill:"none"},(0,v.L6)(i,!1)),p=n.map(function(t,n){var p=e.getTickLineCoord(t),f=R(R(R({textAnchor:e.getTickTextAnchor(t)},s),{},{stroke:"none",fill:l},u),{},{index:n,payload:t,x:p.x2,y:p.y2});return c.createElement(h.m,C({className:(0,m.Z)("recharts-polar-angle-axis-tick",(0,L.$S)(o)),key:"tick-".concat(t.coordinate)},(0,S.bw)(e.props,t,n)),i&&c.createElement("line",C({className:"recharts-polar-angle-axis-tick-line"},d,p)),o&&r.renderTickItem(o,f,a?a(t.value,n):t.value))});return c.createElement(h.m,{className:"recharts-polar-angle-axis-ticks"},p)}},{key:"render",value:function(){var e=this.props,t=e.ticks,n=e.radius,r=e.axisLine;return!(n<=0)&&t&&t.length?c.createElement(h.m,{className:(0,m.Z)("recharts-polar-angle-axis",this.props.className)},r&&this.renderAxisLine(),this.renderTicks()):null}}],n=[{key:"renderTickItem",value:function(e,t,n){return c.isValidElement(e)?c.cloneElement(e,t):f()(e)?e(t):c.createElement(P.x,C({},t,{className:"recharts-polar-angle-axis-tick-value"}),n)}}],t&&D(r.prototype,t),n&&D(r,n),Object.defineProperty(r,"prototype",{writable:!1}),r}(c.PureComponent);B(_,"displayName","PolarAngleAxis"),B(_,"axisType","angleAxis"),B(_,"defaultProps",{type:"category",angleAxisId:0,scale:"auto",cx:0,cy:0,orientation:"outer",axisLine:!0,tickLine:!0,tickSize:8,tick:!0,hide:!1,allowDuplicatedCategory:!0});var H=n(35802),W=n.n(H),z=n(37891),V=n.n(z),G=n(26680),q=["cx","cy","angle","ticks","axisLine"],$=["ticks","tick","angle","tickFormatter","stroke"];function X(e){return(X="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 U(){return(U=Object.assign?Object.assign.bind():function(e){for(var t=1;t=0)continue;n[r]=e[r]}return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function ee(e,t){for(var n=0;n0?es()(e,"paddingAngle",0):0;if(n){var l=(0,eb.k4)(n.endAngle-n.startAngle,e.endAngle-e.startAngle),c=ej(ej({},e),{},{startAngle:i+a,endAngle:i+l(r)+a});o.push(c),i=c.endAngle}else{var s=e.endAngle,d=e.startAngle,p=(0,eb.k4)(0,s-d)(r),f=ej(ej({},e),{},{startAngle:i+a,endAngle:i+p+a});o.push(f),i=f.endAngle}}),c.createElement(h.m,null,e.renderSectorsStatically(o))})}},{key:"attachKeyboardHandlers",value:function(e){var t=this;e.onkeydown=function(e){if(!e.altKey)switch(e.key){case"ArrowLeft":var n=++t.state.sectorToFocus%t.sectorRefs.length;t.sectorRefs[n].focus(),t.setState({sectorToFocus:n});break;case"ArrowRight":var r=--t.state.sectorToFocus<0?t.sectorRefs.length-1:t.state.sectorToFocus%t.sectorRefs.length;t.sectorRefs[r].focus(),t.setState({sectorToFocus:r});break;case"Escape":t.sectorRefs[t.state.sectorToFocus].blur(),t.setState({sectorToFocus:0})}}}},{key:"renderSectors",value:function(){var e=this.props,t=e.sectors,n=e.isAnimationActive,r=this.state.prevSectors;return n&&t&&t.length&&(!r||!ed()(r,t))?this.renderSectorsWithAnimation():this.renderSectorsStatically(t)}},{key:"componentDidMount",value:function(){this.pieRef&&this.attachKeyboardHandlers(this.pieRef)}},{key:"render",value:function(){var e=this,t=this.props,n=t.hide,r=t.sectors,o=t.className,i=t.label,a=t.cx,l=t.cy,s=t.innerRadius,u=t.outerRadius,d=t.isAnimationActive,p=this.state.isAnimationFinished;if(n||!r||!r.length||!(0,eb.hj)(a)||!(0,eb.hj)(l)||!(0,eb.hj)(s)||!(0,eb.hj)(u))return null;var f=(0,m.Z)("recharts-pie",o);return c.createElement(h.m,{tabIndex:this.props.rootTabIndex,className:f,ref:function(t){e.pieRef=t}},this.renderSectors(),i&&this.renderLabels(r),G._.renderCallByParent(this.props,null,!1),(!d||p)&&eh.e.renderCallByParent(this.props,r,!1))}}],n=[{key:"getDerivedStateFromProps",value:function(e,t){return t.prevIsAnimationActive!==e.isAnimationActive?{prevIsAnimationActive:e.isAnimationActive,prevAnimationId:e.animationId,curSectors:e.sectors,prevSectors:[],isAnimationFinished:!0}:e.isAnimationActive&&e.animationId!==t.prevAnimationId?{prevAnimationId:e.animationId,curSectors:e.sectors,prevSectors:t.curSectors,isAnimationFinished:!0}:e.sectors!==t.curSectors?{curSectors:e.sectors,isAnimationFinished:!0}:null}},{key:"getTextAnchor",value:function(e,t){return e>t?"start":e=360?k:k-1)*u,A=a.reduce(function(e,t){var n=(0,eg.F$)(t,g,0);return e+((0,eb.hj)(n)?n:0)},0);return A>0&&(t=a.map(function(e,t){var r,o=(0,eg.F$)(e,g,0),i=(0,eg.F$)(e,p,t),a=((0,eb.hj)(o)?o:0)/A,s=(r=t?n.endAngle+(0,eb.uY)(v)*u*(0!==o?1:0):c)+(0,eb.uY)(v)*((0!==o?h:0)+a*x),d=(r+s)/2,f=(y.innerRadius+y.outerRadius)/2,b=[{name:i,value:o,payload:e,dataKey:g,type:m}],k=(0,L.op)(y.cx,y.cy,f,d);return n=ej(ej(ej({percent:a,cornerRadius:l,name:i,tooltipPayload:b,midAngle:d,middleRadius:f,tooltipPosition:k},e),y),{},{value:(0,eg.F$)(e,g),startAngle:r,endAngle:s,payload:e,paddingAngle:(0,eb.uY)(v)*u})})),ej(ej({},y),{},{sectors:t,data:a})});var eR=(0,d.z)({chartName:"PieChart",GraphicalChild:eT,validateTooltipEventTypes:["item"],defaultTooltipEventType:"item",legendContent:"children",axisComponents:[{axisType:"angleAxis",AxisComp:_},{axisType:"radiusAxis",AxisComp:ea}],formatAxisMap:L.t9,defaultProps:{layout:"centric",startAngle:0,endAngle:360,cx:"50%",cy:"50%",innerRadius:0,outerRadius:"80%"}}),eD=n(8147),eM=n(92666),eI=n(98593);let eZ=e=>{let{active:t,payload:n,valueFormatter:r}=e;if(t&&(null==n?void 0:n[0])){let e=null==n?void 0:n[0];return c.createElement(eI.$B,null,c.createElement("div",{className:(0,a.q)("px-4 py-2")},c.createElement(eI.zX,{value:r(e.value),name:e.name,color:e.payload.color})))}return null},eB=(e,t)=>e.map((e,n)=>{let r=ne||t((0,l.vP)(n.map(e=>e[r]))),eK=e=>{let{cx:t,cy:n,innerRadius:r,outerRadius:o,startAngle:i,endAngle:a,className:l}=e;return c.createElement("g",null,c.createElement(s.L,{cx:t,cy:n,innerRadius:r,outerRadius:o,startAngle:i,endAngle:a,className:l,fill:"",opacity:.3,style:{outline:"none"}}))},e_=c.forwardRef((e,t)=>{let{data:n=[],category:s="value",index:d="name",colors:p=i.s,variant:f="donut",valueFormatter:m=l.Cj,label:h,showLabel:y=!0,animationDuration:v=900,showAnimation:b=!1,showTooltip:g=!0,noDataText:k,onValueChange:x,customTooltip:A,className:O}=e,w=(0,r._T)(e,["data","category","index","colors","variant","valueFormatter","label","showLabel","animationDuration","showAnimation","showTooltip","noDataText","onValueChange","customTooltip","className"]),j="donut"==f,E=eF(h,m,n,s),[P,S]=c.useState(void 0),L=!!x;return(0,c.useEffect)(()=>{let e=document.querySelectorAll(".recharts-pie-sector");e&&e.forEach(e=>{e.setAttribute("style","outline: none")})},[P]),c.createElement("div",Object.assign({ref:t,className:(0,a.q)("w-full h-40",O)},w),c.createElement(u.h,{className:"h-full w-full"},(null==n?void 0:n.length)?c.createElement(eR,{onClick:L&&P?()=>{S(void 0),null==x||x(null)}:void 0,margin:{top:0,left:0,right:0,bottom:0}},y&&j?c.createElement("text",{className:(0,a.q)("fill-tremor-content-emphasis","dark:fill-dark-tremor-content-emphasis"),x:"50%",y:"50%",textAnchor:"middle",dominantBaseline:"middle"},E):null,c.createElement(eT,{className:(0,a.q)("stroke-tremor-background dark:stroke-dark-tremor-background",x?"cursor-pointer":"cursor-default"),data:eB(n,p),cx:"50%",cy:"50%",startAngle:90,endAngle:-270,innerRadius:j?"75%":"0%",outerRadius:"100%",stroke:"",strokeLinejoin:"round",dataKey:s,nameKey:d,isAnimationActive:b,animationDuration:v,onClick:function(e,t,n){n.stopPropagation(),L&&(P===t?(S(void 0),null==x||x(null)):(S(t),null==x||x(Object.assign({eventType:"slice"},e.payload.payload))))},activeIndex:P,inactiveShape:eK,style:{outline:"none"}}),c.createElement(eD.u,{wrapperStyle:{outline:"none"},isAnimationActive:!1,content:g?e=>{var t;let{active:n,payload:r}=e;return A?c.createElement(A,{payload:null==r?void 0:r.map(e=>{var t,n,i;return Object.assign(Object.assign({},e),{color:null!==(i=null===(n=null===(t=null==r?void 0:r[0])||void 0===t?void 0:t.payload)||void 0===n?void 0:n.color)&&void 0!==i?i:o.fr.Gray})}),active:n,label:null===(t=null==r?void 0:r[0])||void 0===t?void 0:t.name}):c.createElement(eZ,{active:n,payload:r,valueFormatter:m})}:c.createElement(c.Fragment,null)})):c.createElement(eM.Z,{noDataText:k})))});e_.displayName="DonutChart"},10968:function(e,t,n){"use strict";n.d(t,{Z:function(){return I}});var r=n(2265),o=n(36760),i=n.n(o),a=n(1119),l=n(26365),c=n(6989),s=n(11993),u=n(31686),d=n(41154),p=n(50506),f=n(18694),m=n(28791),h=n(66632),y=n(27380),v=function(e,t){if(!e)return null;var n={left:e.offsetLeft,right:e.parentElement.clientWidth-e.clientWidth-e.offsetLeft,width:e.clientWidth,top:e.offsetTop,bottom:e.parentElement.clientHeight-e.clientHeight-e.offsetTop,height:e.clientHeight};return t?{left:0,right:0,width:0,top:n.top,bottom:n.bottom,height:n.height}:{left:n.left,right:n.right,width:n.width,top:0,bottom:0,height:0}},b=function(e){return void 0!==e?"".concat(e,"px"):void 0};function g(e){var t=e.prefixCls,n=e.containerRef,o=e.value,a=e.getValueIndex,c=e.motionName,s=e.onMotionStart,d=e.onMotionEnd,p=e.direction,f=e.vertical,g=void 0!==f&&f,k=r.useRef(null),x=r.useState(o),A=(0,l.Z)(x,2),O=A[0],w=A[1],j=function(e){var r,o=a(e),i=null===(r=n.current)||void 0===r?void 0:r.querySelectorAll(".".concat(t,"-item"))[o];return(null==i?void 0:i.offsetParent)&&i},E=r.useState(null),P=(0,l.Z)(E,2),S=P[0],L=P[1],N=r.useState(null),C=(0,l.Z)(N,2),T=C[0],R=C[1];(0,y.Z)(function(){if(O!==o){var e=j(O),t=j(o),n=v(e,g),r=v(t,g);w(o),L(n),R(r),e&&t?s():d()}},[o]);var D=r.useMemo(function(){if(g){var e;return b(null!==(e=null==S?void 0:S.top)&&void 0!==e?e:0)}return"rtl"===p?b(-(null==S?void 0:S.right)):b(null==S?void 0:S.left)},[g,p,S]),M=r.useMemo(function(){if(g){var e;return b(null!==(e=null==T?void 0:T.top)&&void 0!==e?e:0)}return"rtl"===p?b(-(null==T?void 0:T.right)):b(null==T?void 0:T.left)},[g,p,T]);return S&&T?r.createElement(h.ZP,{visible:!0,motionName:c,motionAppear:!0,onAppearStart:function(){return g?{transform:"translateY(var(--thumb-start-top))",height:"var(--thumb-start-height)"}:{transform:"translateX(var(--thumb-start-left))",width:"var(--thumb-start-width)"}},onAppearActive:function(){return g?{transform:"translateY(var(--thumb-active-top))",height:"var(--thumb-active-height)"}:{transform:"translateX(var(--thumb-active-left))",width:"var(--thumb-active-width)"}},onVisibleChanged:function(){L(null),R(null),d()}},function(e,n){var o=e.className,a=e.style,l=(0,u.Z)((0,u.Z)({},a),{},{"--thumb-start-left":D,"--thumb-start-width":b(null==S?void 0:S.width),"--thumb-active-left":M,"--thumb-active-width":b(null==T?void 0:T.width),"--thumb-start-top":D,"--thumb-start-height":b(null==S?void 0:S.height),"--thumb-active-top":M,"--thumb-active-height":b(null==T?void 0:T.height)}),c={ref:(0,m.sQ)(k,n),style:l,className:i()("".concat(t,"-thumb"),o)};return r.createElement("div",c)}):null}var k=["prefixCls","direction","vertical","options","disabled","defaultValue","value","name","onChange","className","motionName"],x=function(e){var t=e.prefixCls,n=e.className,o=e.disabled,a=e.checked,l=e.label,c=e.title,u=e.value,d=e.name,p=e.onChange,f=e.onFocus,m=e.onBlur,h=e.onKeyDown,y=e.onKeyUp,v=e.onMouseDown;return r.createElement("label",{className:i()(n,(0,s.Z)({},"".concat(t,"-item-disabled"),o)),onMouseDown:v},r.createElement("input",{name:d,className:"".concat(t,"-item-input"),type:"radio",disabled:o,checked:a,onChange:function(e){o||p(e,u)},onFocus:f,onBlur:m,onKeyDown:h,onKeyUp:y}),r.createElement("div",{className:"".concat(t,"-item-label"),title:c,"aria-selected":a},l))},A=r.forwardRef(function(e,t){var n,o,h=e.prefixCls,y=void 0===h?"rc-segmented":h,v=e.direction,b=e.vertical,A=e.options,O=void 0===A?[]:A,w=e.disabled,j=e.defaultValue,E=e.value,P=e.name,S=e.onChange,L=e.className,N=e.motionName,C=(0,c.Z)(e,k),T=r.useRef(null),R=r.useMemo(function(){return(0,m.sQ)(T,t)},[T,t]),D=r.useMemo(function(){return O.map(function(e){if("object"===(0,d.Z)(e)&&null!==e){var t=function(e){if(void 0!==e.title)return e.title;if("object"!==(0,d.Z)(e.label)){var t;return null===(t=e.label)||void 0===t?void 0:t.toString()}}(e);return(0,u.Z)((0,u.Z)({},e),{},{title:t})}return{label:null==e?void 0:e.toString(),title:null==e?void 0:e.toString(),value:e}})},[O]),M=(0,p.Z)(null===(n=D[0])||void 0===n?void 0:n.value,{value:E,defaultValue:j}),I=(0,l.Z)(M,2),Z=I[0],B=I[1],F=r.useState(!1),K=(0,l.Z)(F,2),_=K[0],H=K[1],W=function(e,t){B(t),null==S||S(t)},z=(0,f.Z)(C,["children"]),V=r.useState(!1),G=(0,l.Z)(V,2),q=G[0],$=G[1],X=r.useState(!1),U=(0,l.Z)(X,2),Y=U[0],Q=U[1],J=function(){Q(!0)},ee=function(){Q(!1)},et=function(){$(!1)},en=function(e){"Tab"===e.key&&$(!0)},er=function(e){var t=D.findIndex(function(e){return e.value===Z}),n=D.length,r=D[(t+e+n)%n];r&&(B(r.value),null==S||S(r.value))},eo=function(e){switch(e.key){case"ArrowLeft":case"ArrowUp":er(-1);break;case"ArrowRight":case"ArrowDown":er(1)}};return r.createElement("div",(0,a.Z)({role:"radiogroup","aria-label":"segmented control",tabIndex:w?void 0:0},z,{className:i()(y,(o={},(0,s.Z)(o,"".concat(y,"-rtl"),"rtl"===v),(0,s.Z)(o,"".concat(y,"-disabled"),w),(0,s.Z)(o,"".concat(y,"-vertical"),b),o),void 0===L?"":L),ref:R}),r.createElement("div",{className:"".concat(y,"-group")},r.createElement(g,{vertical:b,prefixCls:y,value:Z,containerRef:T,motionName:"".concat(y,"-").concat(void 0===N?"thumb-motion":N),direction:v,getValueIndex:function(e){return D.findIndex(function(t){return t.value===e})},onMotionStart:function(){H(!0)},onMotionEnd:function(){H(!1)}}),D.map(function(e){var t;return r.createElement(x,(0,a.Z)({},e,{name:P,key:e.value,prefixCls:y,className:i()(e.className,"".concat(y,"-item"),(t={},(0,s.Z)(t,"".concat(y,"-item-selected"),e.value===Z&&!_),(0,s.Z)(t,"".concat(y,"-item-focused"),Y&&q&&e.value===Z),t)),checked:e.value===Z,onChange:W,onFocus:J,onBlur:ee,onKeyDown:eo,onKeyUp:en,onMouseDown:et,disabled:!!w||!!e.disabled}))})))}),O=n(92491),w=n(71744),j=n(33759),E=n(93463),P=n(12918),S=n(99320),L=n(71140);function N(e,t){return{["".concat(e,", ").concat(e,":hover, ").concat(e,":focus")]:{color:t.colorTextDisabled,cursor:"not-allowed"}}}function C(e){return{background:e.itemSelectedBg,boxShadow:e.boxShadowTertiary}}let T=Object.assign({overflow:"hidden"},P.vS),R=e=>{let{componentCls:t}=e,n=e.calc(e.controlHeight).sub(e.calc(e.trackPadding).mul(2)).equal(),r=e.calc(e.controlHeightLG).sub(e.calc(e.trackPadding).mul(2)).equal(),o=e.calc(e.controlHeightSM).sub(e.calc(e.trackPadding).mul(2)).equal();return{[t]:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},(0,P.Wf)(e)),{display:"inline-block",padding:e.trackPadding,color:e.itemColor,background:e.trackBg,borderRadius:e.borderRadius,transition:"all ".concat(e.motionDurationMid)}),(0,P.Qy)(e)),{["".concat(t,"-group")]:{position:"relative",display:"flex",alignItems:"stretch",justifyItems:"flex-start",flexDirection:"row",width:"100%"},["&".concat(t,"-rtl")]:{direction:"rtl"},["&".concat(t,"-vertical")]:{["".concat(t,"-group")]:{flexDirection:"column"},["".concat(t,"-thumb")]:{width:"100%",height:0,padding:"0 ".concat((0,E.bf)(e.paddingXXS))}},["&".concat(t,"-block")]:{display:"flex"},["&".concat(t,"-block ").concat(t,"-item")]:{flex:1,minWidth:0},["".concat(t,"-item")]:{position:"relative",textAlign:"center",cursor:"pointer",transition:"color ".concat(e.motionDurationMid),borderRadius:e.borderRadiusSM,transform:"translateZ(0)","&-selected":Object.assign(Object.assign({},C(e)),{color:e.itemSelectedColor}),"&-focused":(0,P.oN)(e),"&::after":{content:'""',position:"absolute",zIndex:-1,width:"100%",height:"100%",top:0,insetInlineStart:0,borderRadius:"inherit",opacity:0,transition:"opacity ".concat(e.motionDurationMid,", background-color ").concat(e.motionDurationMid),pointerEvents:"none"},["&:not(".concat(t,"-item-selected):not(").concat(t,"-item-disabled)")]:{"&:hover, &:active":{color:e.itemHoverColor},"&:hover::after":{opacity:1,backgroundColor:e.itemHoverBg},"&:active::after":{opacity:1,backgroundColor:e.itemActiveBg}},"&-label":Object.assign({minHeight:n,lineHeight:(0,E.bf)(n),padding:"0 ".concat((0,E.bf)(e.segmentedPaddingHorizontal))},T),"&-icon + *":{marginInlineStart:e.calc(e.marginSM).div(2).equal()},"&-input":{position:"absolute",insetBlockStart:0,insetInlineStart:0,width:0,height:0,opacity:0,pointerEvents:"none"}},["".concat(t,"-thumb")]:Object.assign(Object.assign({},C(e)),{position:"absolute",insetBlockStart:0,insetInlineStart:0,width:0,height:"100%",padding:"".concat((0,E.bf)(e.paddingXXS)," 0"),borderRadius:e.borderRadiusSM,["& ~ ".concat(t,"-item:not(").concat(t,"-item-selected):not(").concat(t,"-item-disabled)::after")]:{backgroundColor:"transparent"}}),["&".concat(t,"-lg")]:{borderRadius:e.borderRadiusLG,["".concat(t,"-item-label")]:{minHeight:r,lineHeight:(0,E.bf)(r),padding:"0 ".concat((0,E.bf)(e.segmentedPaddingHorizontal)),fontSize:e.fontSizeLG},["".concat(t,"-item, ").concat(t,"-thumb")]:{borderRadius:e.borderRadius}},["&".concat(t,"-sm")]:{borderRadius:e.borderRadiusSM,["".concat(t,"-item-label")]:{minHeight:o,lineHeight:(0,E.bf)(o),padding:"0 ".concat((0,E.bf)(e.segmentedPaddingHorizontalSM))},["".concat(t,"-item, ").concat(t,"-thumb")]:{borderRadius:e.borderRadiusXS}}}),N("&-disabled ".concat(t,"-item"),e)),N("".concat(t,"-item-disabled"),e)),{["".concat(t,"-thumb-motion-appear-active")]:{transition:"transform ".concat(e.motionDurationSlow," ").concat(e.motionEaseInOut,", width ").concat(e.motionDurationSlow," ").concat(e.motionEaseInOut),willChange:"transform, width"},["&".concat(t,"-shape-round")]:{borderRadius:9999,["".concat(t,"-item, ").concat(t,"-thumb")]:{borderRadius:9999}}})}};var D=(0,S.I$)("Segmented",e=>{let{lineWidth:t,calc:n}=e;return R((0,L.IX)(e,{segmentedPaddingHorizontal:n(e.controlPaddingHorizontal).sub(t).equal(),segmentedPaddingHorizontalSM:n(e.controlPaddingHorizontalSM).sub(t).equal()}))},e=>{let{colorTextLabel:t,colorText:n,colorFillSecondary:r,colorBgElevated:o,colorFill:i,lineWidthBold:a,colorBgLayout:l}=e;return{trackPadding:a,trackBg:l,itemColor:t,itemHoverColor:n,itemHoverBg:r,itemSelectedBg:o,itemActiveBg:i,itemSelectedColor:n}}),M=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&0>t.indexOf(r)&&(n[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])&&(n[r[o]]=e[r[o]]);return n},I=r.forwardRef((e,t)=>{let n=(0,O.Z)(),{prefixCls:o,className:a,rootClassName:l,block:c,options:s=[],size:u="middle",style:d,vertical:p,shape:f="default",name:m=n}=e,h=M(e,["prefixCls","className","rootClassName","block","options","size","style","vertical","shape","name"]),{getPrefixCls:y,direction:v,className:b,style:g}=(0,w.dj)("segmented"),k=y("segmented",o),[x,E,P]=D(k),S=(0,j.Z)(u),L=r.useMemo(()=>s.map(e=>{if("object"==typeof e&&(null==e?void 0:e.icon)){let{icon:t,label:n}=e;return Object.assign(Object.assign({},M(e,["icon","label"])),{label:r.createElement(r.Fragment,null,r.createElement("span",{className:"".concat(k,"-item-icon")},t),n&&r.createElement("span",null,n))})}return e}),[s,k]),N=i()(a,l,b,{["".concat(k,"-block")]:c,["".concat(k,"-sm")]:"small"===S,["".concat(k,"-lg")]:"large"===S,["".concat(k,"-vertical")]:p,["".concat(k,"-shape-").concat(f)]:"round"===f},E,P),C=Object.assign(Object.assign({},g),d);return x(r.createElement(A,Object.assign({},h,{name:m,className:N,style:C,options:L,ref:t,prefixCls:k,direction:v,vertical:p})))})},35802:function(e,t,n){var r=n(67646),o=n(58905),i=n(88157);e.exports=function(e,t){return e&&e.length?r(e,i(t,2),o):void 0}},37891:function(e,t,n){var r=n(67646),o=n(88157),i=n(20121);e.exports=function(e,t){return e&&e.length?r(e,o(t,2),i):void 0}},32489:function(e,t,n){"use strict";n.d(t,{Z:function(){return r}});let r=(0,n(79205).Z)("x",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]])},54061:function(e,t,n){"use strict";n.d(t,{x:function(){return I}});var r=n(2265),o=n(84735),i=n(86757),a=n.n(i),l=n(77571),c=n.n(l),s=n(21652),u=n.n(s),d=n(61994),p=n(57165),f=n(81889),m=n(9841),h=n(58772),y=n(13137),v=n(16630),b=n(82944),g=n(34067),k=n(85355),x=["type","layout","connectNulls","ref"],A=["key"];function O(e){return(O="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 w(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n={};for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r)){if(t.indexOf(r)>=0)continue;n[r]=e[r]}return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function j(){return(j=Object.assign?Object.assign.bind():function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);na){c=[].concat(S(r.slice(0,s)),[a-u]);break}var d=c.length%2==0?[0,l]:[l];return[].concat(S(i.repeat(r,Math.floor(t/o))),S(c),d).map(function(e){return"".concat(e,"px")}).join(", ")}),D(e,"id",(0,v.EL)("recharts-line-")),D(e,"pathRef",function(t){e.mainCurve=t}),D(e,"handleAnimationEnd",function(){e.setState({isAnimationFinished:!0}),e.props.onAnimationEnd&&e.props.onAnimationEnd()}),D(e,"handleAnimationStart",function(){e.setState({isAnimationFinished:!1}),e.props.onAnimationStart&&e.props.onAnimationStart()}),e}return!function(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,"prototype",{writable:!1}),t&&R(e,t)}(i,e),t=[{key:"componentDidMount",value:function(){if(this.props.isAnimationActive){var e=this.getTotalLength();this.setState({totalLength:e})}}},{key:"componentDidUpdate",value:function(){if(this.props.isAnimationActive){var e=this.getTotalLength();e!==this.state.totalLength&&this.setState({totalLength:e})}}},{key:"getTotalLength",value:function(){var e=this.mainCurve;try{return e&&e.getTotalLength&&e.getTotalLength()||0}catch(e){return 0}}},{key:"renderErrorBar",value:function(e,t){if(this.props.isAnimationActive&&!this.state.isAnimationFinished)return null;var n=this.props,o=n.points,i=n.xAxis,a=n.yAxis,l=n.layout,c=n.children,s=(0,b.NN)(c,y.W);if(!s)return null;var u=function(e,t){return{x:e.x,y:e.y,value:e.value,errorVal:(0,k.F$)(e.payload,t)}};return r.createElement(m.m,{clipPath:e?"url(#clipPath-".concat(t,")"):null},s.map(function(e){return r.cloneElement(e,{key:"bar-".concat(e.props.dataKey),data:o,xAxis:i,yAxis:a,layout:l,dataPointFormatter:u})}))}},{key:"renderDots",value:function(e,t,n){if(this.props.isAnimationActive&&!this.state.isAnimationFinished)return null;var o=this.props,a=o.dot,l=o.points,c=o.dataKey,s=(0,b.L6)(this.props,!1),u=(0,b.L6)(a,!0),d=l.map(function(e,t){var n=P(P(P({key:"dot-".concat(t),r:3},s),u),{},{index:t,cx:e.x,cy:e.y,value:e.value,dataKey:c,payload:e.payload,points:l});return i.renderDotItem(a,n)}),p={clipPath:e?"url(#clipPath-".concat(t?"":"dots-").concat(n,")"):null};return r.createElement(m.m,j({className:"recharts-line-dots",key:"dots"},p),d)}},{key:"renderCurveStatically",value:function(e,t,n,o){var i=this.props,a=i.type,l=i.layout,c=i.connectNulls,s=(i.ref,w(i,x)),u=P(P(P({},(0,b.L6)(s,!0)),{},{fill:"none",className:"recharts-line-curve",clipPath:t?"url(#clipPath-".concat(n,")"):null,points:e},o),{},{type:a,layout:l,connectNulls:c});return r.createElement(p.H,j({},u,{pathRef:this.pathRef}))}},{key:"renderCurveWithAnimation",value:function(e,t){var n=this,i=this.props,a=i.points,l=i.strokeDasharray,c=i.isAnimationActive,s=i.animationBegin,u=i.animationDuration,d=i.animationEasing,p=i.animationId,f=i.animateNewValues,m=i.width,h=i.height,y=this.state,b=y.prevPoints,g=y.totalLength;return r.createElement(o.ZP,{begin:s,duration:u,isActive:c,easing:d,from:{t:0},to:{t:1},key:"line-".concat(p),onAnimationEnd:this.handleAnimationEnd,onAnimationStart:this.handleAnimationStart},function(r){var o,i=r.t;if(b){var c=b.length/a.length,s=a.map(function(e,t){var n=Math.floor(t*c);if(b[n]){var r=b[n],o=(0,v.k4)(r.x,e.x),a=(0,v.k4)(r.y,e.y);return P(P({},e),{},{x:o(i),y:a(i)})}if(f){var l=(0,v.k4)(2*m,e.x),s=(0,v.k4)(h/2,e.y);return P(P({},e),{},{x:l(i),y:s(i)})}return P(P({},e),{},{x:e.x,y:e.y})});return n.renderCurveStatically(s,e,t)}var u=(0,v.k4)(0,g)(i);if(l){var d="".concat(l).split(/[,\s]+/gim).map(function(e){return parseFloat(e)});o=n.getStrokeDasharray(u,g,d)}else o=n.generateSimpleStrokeDasharray(g,u);return n.renderCurveStatically(a,e,t,{strokeDasharray:o})})}},{key:"renderCurve",value:function(e,t){var n=this.props,r=n.points,o=n.isAnimationActive,i=this.state,a=i.prevPoints,l=i.totalLength;return o&&r&&r.length&&(!a&&l>0||!u()(a,r))?this.renderCurveWithAnimation(e,t):this.renderCurveStatically(r,e,t)}},{key:"render",value:function(){var e,t=this.props,n=t.hide,o=t.dot,i=t.points,a=t.className,l=t.xAxis,s=t.yAxis,u=t.top,p=t.left,f=t.width,y=t.height,v=t.isAnimationActive,g=t.id;if(n||!i||!i.length)return null;var k=this.state.isAnimationFinished,x=1===i.length,A=(0,d.Z)("recharts-line",a),O=l&&l.allowDataOverflow,w=s&&s.allowDataOverflow,j=O||w,E=c()(g)?this.id:g,P=null!==(e=(0,b.L6)(o,!1))&&void 0!==e?e:{r:3,strokeWidth:2},S=P.r,L=P.strokeWidth,N=((0,b.jf)(o)?o:{}).clipDot,C=void 0===N||N,T=2*(void 0===S?3:S)+(void 0===L?2:L);return r.createElement(m.m,{className:A},O||w?r.createElement("defs",null,r.createElement("clipPath",{id:"clipPath-".concat(E)},r.createElement("rect",{x:O?p:p-f/2,y:w?u:u-y/2,width:O?f:2*f,height:w?y:2*y})),!C&&r.createElement("clipPath",{id:"clipPath-dots-".concat(E)},r.createElement("rect",{x:p-T/2,y:u-T/2,width:f+T,height:y+T}))):null,!x&&this.renderCurve(j,E),this.renderErrorBar(j,E),(x||o)&&this.renderDots(j,C,E),(!v||k)&&h.e.renderCallByParent(this.props,i))}}],n=[{key:"getDerivedStateFromProps",value:function(e,t){return e.animationId!==t.prevAnimationId?{prevAnimationId:e.animationId,curPoints:e.points,prevPoints:t.curPoints}:e.points!==t.curPoints?{curPoints:e.points}:null}},{key:"repeat",value:function(e,t){for(var n=e.length%2!=0?[].concat(S(e),[0]):e,r=[],o=0;o{var e,l,t,a,i,r,n;h.setFieldsValue({user_id:s.user_id,user_email:null===(e=s.user_info)||void 0===e?void 0:e.user_email,user_alias:null===(l=s.user_info)||void 0===l?void 0:l.user_alias,user_role:null===(t=s.user_info)||void 0===t?void 0:t.user_role,models:(null===(a=s.user_info)||void 0===a?void 0:a.models)||[],max_budget:null===(i=s.user_info)||void 0===i?void 0:i.max_budget,budget_duration:null===(r=s.user_info)||void 0===r?void 0:r.budget_duration,metadata:(null===(n=s.user_info)||void 0===n?void 0:n.metadata)?JSON.stringify(s.user_info.metadata,null,2):void 0})},[s,h]),(0,t.jsxs)(p.Z,{form:h,onFinish:e=>{if(e.metadata&&"string"==typeof e.metadata)try{e.metadata=JSON.parse(e.metadata)}catch(e){console.error("Error parsing metadata JSON:",e);return}a(e)},layout:"vertical",children:[!x&&(0,t.jsx)(p.Z.Item,{label:"User ID",name:"user_id",children:(0,t.jsx)(b.Z,{disabled:!0})}),!x&&(0,t.jsx)(p.Z.Item,{label:"Email",name:"user_email",children:(0,t.jsx)(b.Z,{})}),(0,t.jsx)(p.Z.Item,{label:"User Alias",name:"user_alias",children:(0,t.jsx)(b.Z,{})}),(0,t.jsx)(p.Z.Item,{label:(0,t.jsxs)("span",{children:["Global Proxy Role"," ",(0,t.jsx)(f.Z,{title:"This is the role that the user will globally on the proxy. This role is independent of any team/org specific roles.",children:(0,t.jsx)(w.Z,{})})]}),name:"user_role",children:(0,t.jsx)(g.default,{children:m&&Object.entries(m).map(e=>{let[s,{ui_label:l,description:a}]=e;return(0,t.jsx)(_.Z,{value:s,title:l,children:(0,t.jsxs)("div",{className:"flex",children:[l," ",(0,t.jsx)("p",{className:"ml-2",style:{color:"gray",fontSize:"12px"},children:a})]})},s)})})}),(0,t.jsx)(p.Z.Item,{label:(0,t.jsxs)("span",{children:["Personal Models"," ",(0,t.jsx)(f.Z,{title:"Select which models this user can access outside of team-scope. Choose 'All Proxy Models' to grant access to all models available on the proxy.",children:(0,t.jsx)(w.Z,{style:{marginLeft:"4px"}})})]}),name:"models",children:(0,t.jsxs)(g.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},disabled:!Z.ZL.includes(c||""),children:[(0,t.jsx)(g.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),(0,t.jsx)(g.default.Option,{value:"no-default-models",children:"No Default Models"},"no-default-models"),u.map(e=>(0,t.jsx)(g.default.Option,{value:e,children:(0,S.W0)(e)},e))]})}),(0,t.jsx)(p.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,t.jsx)(y.Z,{step:.01,precision:2,style:{width:"100%"}})}),(0,t.jsx)(p.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,t.jsx)(k.Z,{})}),(0,t.jsx)(p.Z.Item,{label:"Metadata",name:"metadata",children:(0,t.jsx)(N.Z,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,t.jsxs)("div",{className:"flex justify-end space-x-2",children:[(0,t.jsx)(r.z,{variant:"secondary",type:"button",onClick:l,children:"Cancel"}),(0,t.jsx)(r.z,{type:"submit",children:"Save Changes"})]})]})}var U=l(9114);let{Text:I,Title:D}=n.default;var z=e=>{let{open:s,onCancel:l,selectedUsers:a,possibleUIRoles:r,accessToken:n,onSuccess:p,teams:f,userRole:y,userModels:_,allowAllUsers:b=!1}=e,[N,S]=(0,i.useState)(!1),[Z,w]=(0,i.useState)([]),[k,z]=(0,i.useState)(null),[A,B]=(0,i.useState)(!1),[E,T]=(0,i.useState)(!1),O=()=>{w([]),z(null),B(!1),T(!1),l()},L=i.useMemo(()=>({user_id:"bulk_edit",user_info:{user_email:"",user_role:"",teams:[],models:[],max_budget:null,spend:0,metadata:{},created_at:null,updated_at:null},keys:[],teams:f||[]}),[f,s]),F=async e=>{if(console.log("formValues",e),!n){U.Z.fromBackend("Access token not found");return}S(!0);try{let s=a.map(e=>e.user_id),t={};e.user_role&&""!==e.user_role&&(t.user_role=e.user_role),null!==e.max_budget&&void 0!==e.max_budget&&(t.max_budget=e.max_budget),e.models&&e.models.length>0&&(t.models=e.models),e.budget_duration&&""!==e.budget_duration&&(t.budget_duration=e.budget_duration),e.metadata&&Object.keys(e.metadata).length>0&&(t.metadata=e.metadata);let i=Object.keys(t).length>0,r=A&&Z.length>0;if(!i&&!r){U.Z.fromBackend("Please modify at least one field or select teams to add users to");return}let o=[];if(i){if(E){let e=await (0,j.userBulkUpdateUserCall)(n,t,void 0,!0);o.push("Updated all users (".concat(e.total_requested," total)"))}else await (0,j.userBulkUpdateUserCall)(n,t,s),o.push("Updated ".concat(s.length," user(s)"))}if(r){let e=[];for(let s of Z)try{let l=null;l=E?null:a.map(e=>({user_id:e.user_id,role:"user",user_email:e.user_email||null}));let t=await (0,j.teamBulkMemberAddCall)(n,s,l||null,k||void 0,E);console.log("result",t),e.push({teamId:s,success:!0,successfulAdditions:t.successful_additions,failedAdditions:t.failed_additions})}catch(l){console.error("Failed to add users to team ".concat(s,":"),l),e.push({teamId:s,success:!1,error:l})}let s=e.filter(e=>e.success),l=e.filter(e=>!e.success);if(s.length>0){let e=s.reduce((e,s)=>e+s.successfulAdditions,0);o.push("Added users to ".concat(s.length," team(s) (").concat(e," total additions)"))}l.length>0&&d.ZP.warning("Failed to add users to ".concat(l.length," team(s)"))}o.length>0&&U.Z.success(o.join(". ")),w([]),z(null),B(!1),T(!1),p(),l()}catch(e){console.error("Bulk operation failed:",e),U.Z.fromBackend("Failed to perform bulk operations")}finally{S(!1)}};return(0,t.jsxs)(o.Z,{open:s,onCancel:O,footer:null,title:E?"Bulk Edit All Users":"Bulk Edit ".concat(a.length," User(s)"),width:800,children:[b&&(0,t.jsxs)("div",{className:"mb-4",children:[(0,t.jsx)(c.Z,{checked:E,onChange:e=>T(e.target.checked),children:(0,t.jsx)(I,{strong:!0,children:"Update ALL users in the system"})}),E&&(0,t.jsx)("div",{style:{marginTop:8},children:(0,t.jsx)(I,{type:"warning",style:{fontSize:"12px"},children:"⚠️ This will apply changes to ALL users in the system, not just the selected ones."})})]}),!E&&(0,t.jsxs)("div",{className:"mb-4",children:[(0,t.jsxs)(D,{level:5,children:["Selected Users (",a.length,"):"]}),(0,t.jsx)(u.Z,{size:"small",bordered:!0,dataSource:a,pagination:!1,scroll:{y:200},rowKey:"user_id",columns:[{title:"User ID",dataIndex:"user_id",key:"user_id",width:"30%",render:e=>(0,t.jsx)(I,{strong:!0,style:{fontSize:"12px"},children:e.length>20?"".concat(e.slice(0,20),"..."):e})},{title:"Email",dataIndex:"user_email",key:"user_email",width:"25%",render:e=>(0,t.jsx)(I,{type:"secondary",style:{fontSize:"12px"},children:e||"No email"})},{title:"Current Role",dataIndex:"user_role",key:"user_role",width:"25%",render:e=>{var s;return(0,t.jsx)(I,{style:{fontSize:"12px"},children:(null==r?void 0:null===(s=r[e])||void 0===s?void 0:s.ui_label)||e})}},{title:"Budget",dataIndex:"max_budget",key:"max_budget",width:"20%",render:e=>(0,t.jsx)(I,{style:{fontSize:"12px"},children:null!==e?"$".concat(e):"Unlimited"})}]})]}),(0,t.jsx)(m.Z,{}),(0,t.jsx)("div",{className:"mb-4",children:(0,t.jsxs)(I,{children:[(0,t.jsx)("strong",{children:"Instructions:"})," Fill in the fields below with the values you want to apply to all selected users. You can bulk edit: role, budget, models, and metadata. You can also add users to teams."]})}),(0,t.jsx)(x.Z,{title:"Team Management",size:"small",className:"mb-4",style:{backgroundColor:"#fafafa"},children:(0,t.jsxs)(h.Z,{direction:"vertical",style:{width:"100%"},children:[(0,t.jsx)(c.Z,{checked:A,onChange:e=>B(e.target.checked),children:"Add selected users to teams"}),A&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(I,{strong:!0,children:"Select Teams:"}),(0,t.jsx)(g.default,{mode:"multiple",placeholder:"Select teams to add users to",value:Z,onChange:w,style:{width:"100%",marginTop:8},options:(null==f?void 0:f.map(e=>({label:e.team_alias||e.team_id,value:e.team_id})))||[]})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(I,{strong:!0,children:"Team Budget (Optional):"}),(0,t.jsx)(v.Z,{placeholder:"Max budget per user in team",value:k,onChange:e=>z(e),style:{width:"100%",marginTop:8},min:0,step:.01,precision:2}),(0,t.jsx)(I,{type:"secondary",style:{fontSize:"12px"},children:"Leave empty for unlimited budget within team limits"})]}),(0,t.jsx)(I,{type:"secondary",style:{fontSize:"12px"},children:'Users will be added with "user" role by default. All users will be added to each selected team.'})]})]})}),(0,t.jsx)(C,{userData:L,onCancel:O,onSubmit:F,teams:f,accessToken:n,userID:"bulk_edit",userRole:y,userModels:_,possibleUIRoles:r,isBulkEdit:!0}),N&&(0,t.jsx)("div",{style:{textAlign:"center",marginTop:"10px"},children:(0,t.jsxs)(I,{children:["Updating ",E?"all users":a.length," user(s)..."]})})]})},A=l(7765),B=l(5545),E=e=>{let{visible:s,possibleUIRoles:l,onCancel:a,user:r,onSubmit:n}=e,[d,c]=(0,i.useState)(r),[u]=p.Z.useForm();(0,i.useEffect)(()=>{u.resetFields()},[r]);let m=async()=>{u.resetFields(),a()},x=async e=>{n(e),u.resetFields(),a()};return r?(0,t.jsx)(o.Z,{visible:s,onCancel:m,footer:null,title:"Edit User "+r.user_id,width:1e3,children:(0,t.jsx)(p.Z,{form:u,onFinish:x,initialValues:r,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(p.Z.Item,{className:"mt-8",label:"User Email",tooltip:"Email of the User",name:"user_email",children:(0,t.jsx)(b.Z,{})}),(0,t.jsx)(p.Z.Item,{label:"user_id",name:"user_id",hidden:!0,children:(0,t.jsx)(b.Z,{})}),(0,t.jsx)(p.Z.Item,{label:"User Role",name:"user_role",children:(0,t.jsx)(g.default,{children:l&&Object.entries(l).map(e=>{let[s,{ui_label:l,description:a}]=e;return(0,t.jsx)(_.Z,{value:s,title:l,children:(0,t.jsxs)("div",{className:"flex",children:[l," ",(0,t.jsx)("p",{className:"ml-2",style:{color:"gray",fontSize:"12px"},children:a})]})},s)})})}),(0,t.jsx)(p.Z.Item,{label:"Spend (USD)",name:"spend",tooltip:"(float) - Spend of all LLM calls completed by this user",help:"Across all keys (including keys with team_id).",children:(0,t.jsx)(v.Z,{min:0,step:.01})}),(0,t.jsx)(p.Z.Item,{label:"User Budget (USD)",name:"max_budget",tooltip:"(float) - Maximum budget of this user",help:"Maximum budget of this user.",children:(0,t.jsx)(y.Z,{min:0,step:.01})}),(0,t.jsx)(p.Z.Item,{label:"Reset Budget",name:"budget_duration",children:(0,t.jsx)(k.Z,{})}),(0,t.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,t.jsx)(B.ZP,{htmlType:"submit",children:"Save"})}),(0,t.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,t.jsx)(B.ZP,{htmlType:"submit",children:"Save"})})]})})}):null},T=l(98187),O=l(59872),L=l(19616),F=l(29827),R=l(11713),P=l(21609),M=l(88913),K=l(63709),V=l(10353),q=l(26349),G=l(96473),J=e=>{var s;let{accessToken:l,possibleUIRoles:a,userID:r,userRole:d}=e,[o,c]=(0,i.useState)(!0),[u,m]=(0,i.useState)(null),[x,h]=(0,i.useState)(!1),[p,f]=(0,i.useState)({}),[y,_]=(0,i.useState)(!1),[b,N]=(0,i.useState)([]),{Paragraph:Z}=n.default,{Option:w}=g.default;(0,i.useEffect)(()=>{(async()=>{if(!l){c(!1);return}try{let e=await (0,j.getInternalUserSettings)(l);if(m(e),f(e.values||{}),l)try{let e=await (0,j.modelAvailableCall)(l,r,d);if(e&&e.data){let s=e.data.map(e=>e.id);N(s)}}catch(e){console.error("Error fetching available models:",e)}}catch(e){console.error("Error fetching SSO settings:",e),U.Z.fromBackend("Failed to fetch SSO settings")}finally{c(!1)}})()},[l]);let C=async()=>{if(l){_(!0);try{let e=Object.entries(p).reduce((e,s)=>{let[l,t]=s;return e[l]=""===t?null:t,e},{}),s=await (0,j.updateInternalUserSettings)(l,e);m({...u,values:s.settings}),h(!1)}catch(e){console.error("Error updating SSO settings:",e),U.Z.fromBackend("Failed to update settings: "+e)}finally{_(!1)}}},I=(e,s)=>{f(l=>({...l,[e]:s}))},D=e=>e&&Array.isArray(e)?e.map(e=>"string"==typeof e?{team_id:e,user_role:"user"}:"object"==typeof e&&e.team_id?{team_id:e.team_id,max_budget_in_team:e.max_budget_in_team,user_role:e.user_role||"user"}:{team_id:"",user_role:"user"}):[],z=e=>{let s=D(e),l=(e,l,t)=>{let a=[...s];a[e]={...a[e],[l]:t},I("teams",a)},a=e=>{I("teams",s.filter((s,l)=>l!==e))};return(0,t.jsxs)("div",{className:"space-y-3",children:[s.map((e,s)=>(0,t.jsxs)("div",{className:"border rounded-lg p-4 bg-gray-50",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-3",children:[(0,t.jsxs)(M.xv,{className:"font-medium",children:["Team ",s+1]}),(0,t.jsx)(M.zx,{size:"sm",variant:"secondary",icon:q.Z,onClick:()=>a(s),className:"text-red-500 hover:text-red-700",children:"Remove"})]}),(0,t.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-3",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(M.xv,{className:"text-sm font-medium mb-1",children:"Team ID"}),(0,t.jsx)(M.oi,{value:e.team_id,onChange:e=>l(s,"team_id",e.target.value),placeholder:"Enter team ID"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(M.xv,{className:"text-sm font-medium mb-1",children:"Max Budget in Team"}),(0,t.jsx)(v.Z,{style:{width:"100%"},value:e.max_budget_in_team,onChange:e=>l(s,"max_budget_in_team",e),placeholder:"Optional",min:0,step:.01,precision:2})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(M.xv,{className:"text-sm font-medium mb-1",children:"User Role"}),(0,t.jsxs)(g.default,{style:{width:"100%"},value:e.user_role,onChange:e=>l(s,"user_role",e),children:[(0,t.jsx)(w,{value:"user",children:"User"}),(0,t.jsx)(w,{value:"admin",children:"Admin"})]})]})]})]},s)),(0,t.jsx)(M.zx,{variant:"secondary",icon:G.Z,onClick:()=>{I("teams",[...s,{team_id:"",user_role:"user"}])},className:"w-full",children:"Add Team"})]})},A=(e,s,l)=>{var i;let r=s.type;if("teams"===e)return(0,t.jsx)("div",{className:"mt-2",children:z(p[e]||[])});if("user_role"===e&&a)return(0,t.jsx)(g.default,{style:{width:"100%"},value:p[e]||"",onChange:s=>I(e,s),className:"mt-2",children:Object.entries(a).filter(e=>{let[s]=e;return s.includes("internal_user")}).map(e=>{let[s,{ui_label:l,description:a}]=e;return(0,t.jsx)(w,{value:s,children:(0,t.jsxs)("div",{className:"flex items-center",children:[(0,t.jsx)("span",{children:l}),(0,t.jsx)("span",{className:"ml-2 text-xs text-gray-500",children:a})]})},s)})});if("budget_duration"===e)return(0,t.jsx)(k.Z,{value:p[e]||null,onChange:s=>I(e,s),className:"mt-2"});if("boolean"===r)return(0,t.jsx)("div",{className:"mt-2",children:(0,t.jsx)(K.Z,{checked:!!p[e],onChange:s=>I(e,s)})});if("array"===r&&(null===(i=s.items)||void 0===i?void 0:i.enum))return(0,t.jsx)(g.default,{mode:"multiple",style:{width:"100%"},value:p[e]||[],onChange:s=>I(e,s),className:"mt-2",children:s.items.enum.map(e=>(0,t.jsx)(w,{value:e,children:e},e))});if("models"===e)return(0,t.jsxs)(g.default,{mode:"multiple",style:{width:"100%"},value:p[e]||[],onChange:s=>I(e,s),className:"mt-2",children:[(0,t.jsx)(w,{value:"no-default-models",children:"No Default Models"},"no-default-models"),(0,t.jsx)(w,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),b.map(e=>(0,t.jsx)(w,{value:e,children:(0,S.W0)(e)},e))]});if("string"===r&&s.enum)return(0,t.jsx)(g.default,{style:{width:"100%"},value:p[e]||"",onChange:s=>I(e,s),className:"mt-2",children:s.enum.map(e=>(0,t.jsx)(w,{value:e,children:e},e))});else return(0,t.jsx)(M.oi,{value:void 0!==p[e]?String(p[e]):"",onChange:s=>I(e,s.target.value),placeholder:s.description||"",className:"mt-2"})},B=(e,s)=>{if(null==s)return(0,t.jsx)("span",{className:"text-gray-400",children:"Not set"});if("teams"===e&&Array.isArray(s)){if(0===s.length)return(0,t.jsx)("span",{className:"text-gray-400",children:"No teams assigned"});let e=D(s);return(0,t.jsx)("div",{className:"space-y-2 mt-1",children:e.map((e,s)=>(0,t.jsx)("div",{className:"border rounded-lg p-3 bg-white",children:(0,t.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-2 text-sm",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"font-medium text-gray-600",children:"Team ID:"}),(0,t.jsx)("p",{className:"text-gray-900",children:e.team_id||"Not specified"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"font-medium text-gray-600",children:"Max Budget:"}),(0,t.jsx)("p",{className:"text-gray-900",children:void 0!==e.max_budget_in_team?"$".concat((0,O.pw)(e.max_budget_in_team,4)):"No limit"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"font-medium text-gray-600",children:"Role:"}),(0,t.jsx)("p",{className:"text-gray-900 capitalize",children:e.user_role})]})]})},s))})}if("user_role"===e&&a&&a[s]){let{ui_label:e,description:l}=a[s];return(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"font-medium",children:e}),l&&(0,t.jsx)("p",{className:"text-xs text-gray-500 mt-1",children:l})]})}return"budget_duration"===e?(0,t.jsx)("span",{children:(0,k.m)(s)}):"boolean"==typeof s?(0,t.jsx)("span",{children:s?"Enabled":"Disabled"}):"models"===e&&Array.isArray(s)?0===s.length?(0,t.jsx)("span",{className:"text-gray-400",children:"None"}):(0,t.jsx)("div",{className:"flex flex-wrap gap-2 mt-1",children:s.map((e,s)=>(0,t.jsx)("span",{className:"px-2 py-1 bg-blue-100 rounded text-xs",children:(0,S.W0)(e)},s))}):"object"==typeof s?Array.isArray(s)?0===s.length?(0,t.jsx)("span",{className:"text-gray-400",children:"None"}):(0,t.jsx)("div",{className:"flex flex-wrap gap-2 mt-1",children:s.map((e,s)=>(0,t.jsx)("span",{className:"px-2 py-1 bg-blue-100 rounded text-xs",children:"object"==typeof e?JSON.stringify(e):String(e)},s))}):(0,t.jsx)("pre",{className:"bg-gray-100 p-2 rounded text-xs overflow-auto mt-1",children:JSON.stringify(s,null,2)}):(0,t.jsx)("span",{children:String(s)})};return o?(0,t.jsx)("div",{className:"flex justify-center items-center h-64",children:(0,t.jsx)(V.Z,{size:"large"})}):u?(0,t.jsxs)(M.Zb,{children:[(0,t.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,t.jsx)(M.Dx,{children:"Default User Settings"}),!o&&u&&(x?(0,t.jsxs)("div",{className:"flex gap-2",children:[(0,t.jsx)(M.zx,{variant:"secondary",onClick:()=>{h(!1),f(u.values||{})},disabled:y,children:"Cancel"}),(0,t.jsx)(M.zx,{onClick:C,loading:y,children:"Save Changes"})]}):(0,t.jsx)(M.zx,{onClick:()=>h(!0),children:"Edit Settings"}))]}),(null==u?void 0:null===(s=u.field_schema)||void 0===s?void 0:s.description)&&(0,t.jsx)(Z,{className:"mb-4",children:u.field_schema.description}),(0,t.jsx)(M.iz,{}),(0,t.jsx)("div",{className:"mt-4 space-y-4",children:(()=>{let{values:e,field_schema:s}=u;return s&&s.properties?Object.entries(s.properties).map(s=>{let[l,a]=s,i=e[l],r=l.replace(/_/g," ").replace(/\b\w/g,e=>e.toUpperCase());return(0,t.jsxs)("div",{className:"mb-6 pb-6 border-b border-gray-200 last:border-0",children:[(0,t.jsx)(M.xv,{className:"font-medium text-lg",children:r}),(0,t.jsx)(Z,{className:"text-sm text-gray-500 mt-1",children:a.description||"No description available"}),x?(0,t.jsx)("div",{className:"mt-2",children:A(l,a,i)}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded",children:B(l,i)})]},l)}):(0,t.jsx)(M.xv,{children:"No schema information available"})})()})]}):(0,t.jsx)(M.Zb,{children:(0,t.jsx)(M.xv,{children:"No settings available or you do not have permission to view them."})})},Q=l(41649),H=l(67101),$=l(47323),W=l(15731),Y=l(53410),X=l(74998),ee=l(23628);let es=(e,s,l,a,i,r)=>{let n=[{header:"User ID",accessorKey:"user_id",enableSorting:!0,cell:e=>{let{row:s}=e;return(0,t.jsx)(f.Z,{title:s.original.user_id,children:(0,t.jsx)("span",{className:"text-xs",children:s.original.user_id?"".concat(s.original.user_id.slice(0,7),"..."):"-"})})}},{header:"Email",accessorKey:"user_email",enableSorting:!0,cell:e=>{let{row:s}=e;return(0,t.jsx)("span",{className:"text-xs",children:s.original.user_email||"-"})}},{header:"Global Proxy Role",accessorKey:"user_role",enableSorting:!0,cell:s=>{var l;let{row:a}=s;return(0,t.jsx)("span",{className:"text-xs",children:(null==e?void 0:null===(l=e[a.original.user_role])||void 0===l?void 0:l.ui_label)||"-"})}},{header:"User Alias",accessorKey:"user_alias",enableSorting:!1,cell:e=>{let{row:s}=e;return(0,t.jsx)("span",{className:"text-xs",children:s.original.user_alias||"-"})}},{header:"Spend (USD)",accessorKey:"spend",enableSorting:!0,cell:e=>{let{row:s}=e;return(0,t.jsx)("span",{className:"text-xs",children:s.original.spend?(0,O.pw)(s.original.spend,4):"-"})}},{header:"Budget (USD)",accessorKey:"max_budget",enableSorting:!1,cell:e=>{let{row:s}=e;return(0,t.jsx)("span",{className:"text-xs",children:null!==s.original.max_budget?s.original.max_budget:"Unlimited"})}},{header:()=>(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("span",{children:"SSO ID"}),(0,t.jsx)(f.Z,{title:"SSO ID is the ID of the user in the SSO provider. If the user is not using SSO, this will be null.",children:(0,t.jsx)(W.Z,{className:"w-4 h-4"})})]}),accessorKey:"sso_user_id",enableSorting:!1,cell:e=>{let{row:s}=e;return(0,t.jsx)("span",{className:"text-xs",children:null!==s.original.sso_user_id?s.original.sso_user_id:"-"})}},{header:"Virtual Keys",accessorKey:"key_count",enableSorting:!1,cell:e=>{let{row:s}=e;return(0,t.jsx)(H.Z,{numItems:2,children:s.original.key_count>0?(0,t.jsxs)(Q.Z,{size:"xs",color:"indigo",children:[s.original.key_count," ",1===s.original.key_count?"Key":"Keys"]}):(0,t.jsx)(Q.Z,{size:"xs",color:"gray",children:"No Keys"})})}},{header:"Created At",accessorKey:"created_at",enableSorting:!0,cell:e=>{let{row:s}=e;return(0,t.jsx)("span",{className:"text-xs",children:s.original.created_at?new Date(s.original.created_at).toLocaleDateString():"-"})}},{header:"Updated At",accessorKey:"updated_at",enableSorting:!1,cell:e=>{let{row:s}=e;return(0,t.jsx)("span",{className:"text-xs",children:s.original.updated_at?new Date(s.original.updated_at).toLocaleDateString():"-"})}},{id:"actions",header:"Actions",enableSorting:!1,cell:e=>{let{row:s}=e;return(0,t.jsxs)("div",{className:"flex gap-2",children:[(0,t.jsx)(f.Z,{title:"Edit user details",children:(0,t.jsx)($.Z,{icon:Y.Z,size:"sm",onClick:()=>i(s.original.user_id,!0),className:"cursor-pointer hover:text-blue-600"})}),(0,t.jsx)(f.Z,{title:"Delete user",children:(0,t.jsx)($.Z,{icon:X.Z,size:"sm",onClick:()=>l(s.original),className:"cursor-pointer hover:text-red-600"})}),(0,t.jsx)(f.Z,{title:"Reset Password",children:(0,t.jsx)($.Z,{icon:ee.Z,size:"sm",onClick:()=>a(s.original.user_id),className:"cursor-pointer hover:text-green-600"})})]})}}];if(r){let{onSelectUser:e,onSelectAll:s,isUserSelected:l,isAllSelected:a,isIndeterminate:i}=r;return[{id:"select",enableSorting:!1,header:()=>(0,t.jsx)(c.Z,{indeterminate:i,checked:a,onChange:e=>s(e.target.checked),onClick:e=>e.stopPropagation()}),cell:s=>{let{row:a}=s;return(0,t.jsx)(c.Z,{checked:l(a.original),onChange:s=>e(a.original,s.target.checked),onClick:e=>e.stopPropagation()})}},...n]}return n};var el=l(71594),et=l(24525),ea=l(27281),ei=l(21626),er=l(97214),en=l(28241),ed=l(58834),eo=l(69552),ec=l(71876),eu=l(44633),em=l(86462),ex=l(49084),eh=l(50337),eg=l(84717),ev=l(10900),ej=l(30401),ep=l(78867);function ef(e){var s,l,a,r,n,d,o,c,u,m,x,h,g,v,p,f,y,_,b,N,S,w,I,D,z,A,E,L,F,R,M,K,V,q,G,J,Q,H,$,W,Y,es,el,et,ea;let{userId:ei,onClose:er,accessToken:en,userRole:ed,onDelete:eo,possibleUIRoles:ec,initialTab:eu=0,startInEditMode:em=!1}=e,[ex,eh]=(0,i.useState)(null),[ef,ey]=(0,i.useState)(!1),[e_,eb]=(0,i.useState)(!1),[eN,eS]=(0,i.useState)(!0),[eZ,ew]=(0,i.useState)(em),[ek,eC]=(0,i.useState)([]),[eU,eI]=(0,i.useState)(!1),[eD,ez]=(0,i.useState)(null),[eA,eB]=(0,i.useState)(null),[eE,eT]=(0,i.useState)(eu),[eO,eL]=(0,i.useState)({}),[eF,eR]=(0,i.useState)(!1);i.useEffect(()=>{eB((0,j.getProxyBaseUrl)())},[]),i.useEffect(()=>{console.log("userId: ".concat(ei,", userRole: ").concat(ed,", accessToken: ").concat(en)),(async()=>{try{if(!en)return;let e=await (0,j.userInfoCall)(en,ei,ed||"",!1,null,null,!0);eh(e);let s=(await (0,j.modelAvailableCall)(en,ei,ed||"")).data.map(e=>e.id);eC(s)}catch(e){console.error("Error fetching user data:",e),U.Z.fromBackend("Failed to fetch user data")}finally{eS(!1)}})()},[en,ei,ed]);let eP=async()=>{if(!en){U.Z.fromBackend("Access token not found");return}try{U.Z.success("Generating password reset link...");let e=await (0,j.invitationCreateCall)(en,ei);ez(e),eI(!0)}catch(e){U.Z.fromBackend("Failed to generate password reset link")}},eM=async()=>{try{if(!en)return;eb(!0),await (0,j.userDeleteCall)(en,[ei]),U.Z.success("User deleted successfully"),eo&&eo(),er()}catch(e){console.error("Error deleting user:",e),U.Z.fromBackend("Failed to delete user")}finally{ey(!1),eb(!1)}},eK=async e=>{try{if(!en||!ex)return;await (0,j.userUpdateUserCall)(en,e,null),eh({...ex,user_info:{...ex.user_info,user_email:e.user_email,user_alias:e.user_alias,models:e.models,max_budget:e.max_budget,budget_duration:e.budget_duration,metadata:e.metadata}}),U.Z.success("User updated successfully"),ew(!1)}catch(e){console.error("Error updating user:",e),U.Z.fromBackend("Failed to update user")}};if(eN)return(0,t.jsxs)("div",{className:"p-4",children:[(0,t.jsx)(eg.zx,{icon:ev.Z,variant:"light",onClick:er,className:"mb-4",children:"Back to Users"}),(0,t.jsx)(eg.xv,{children:"Loading user data..."})]});if(!ex)return(0,t.jsxs)("div",{className:"p-4",children:[(0,t.jsx)(eg.zx,{icon:ev.Z,variant:"light",onClick:er,className:"mb-4",children:"Back to Users"}),(0,t.jsx)(eg.xv,{children:"User not found"})]});let eV=async(e,s)=>{await (0,O.vQ)(e)&&(eL(e=>({...e,[s]:!0})),setTimeout(()=>{eL(e=>({...e,[s]:!1}))},2e3))};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)(eg.zx,{icon:ev.Z,variant:"light",onClick:er,className:"mb-4",children:"Back to Users"}),(0,t.jsx)(eg.Dx,{children:(null===(s=ex.user_info)||void 0===s?void 0:s.user_email)||"User"}),(0,t.jsxs)("div",{className:"flex items-center cursor-pointer",children:[(0,t.jsx)(eg.xv,{className:"text-gray-500 font-mono",children:ex.user_id}),(0,t.jsx)(B.ZP,{type:"text",size:"small",icon:eO["user-id"]?(0,t.jsx)(ej.Z,{size:12}):(0,t.jsx)(ep.Z,{size:12}),onClick:()=>eV(ex.user_id,"user-id"),className:"left-2 z-10 transition-all duration-200 ".concat(eO["user-id"]?"text-green-600 bg-green-50 border-green-200":"text-gray-500 hover:text-gray-700 hover:bg-gray-100")})]})]}),ed&&Z.LQ.includes(ed)&&(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)(eg.zx,{icon:ee.Z,variant:"secondary",onClick:eP,className:"flex items-center",children:"Reset Password"}),(0,t.jsx)(eg.zx,{icon:X.Z,variant:"secondary",onClick:()=>ey(!0),className:"flex items-center text-red-500 border-red-500 hover:text-red-600 hover:border-red-600",children:"Delete User"})]})]}),(0,t.jsx)(P.Z,{isOpen:ef,title:"Delete User?",message:"Are you sure you want to delete this user? This action cannot be undone.",resourceInformationTitle:"User Information",resourceInformation:[{label:"Email",value:null===(l=ex.user_info)||void 0===l?void 0:l.user_email},{label:"User ID",value:ex.user_id,code:!0},{label:"Global Proxy Role",value:(null===(a=ex.user_info)||void 0===a?void 0:a.user_role)&&(null==ec?void 0:null===(r=ec[ex.user_info.user_role])||void 0===r?void 0:r.ui_label)||(null===(n=ex.user_info)||void 0===n?void 0:n.user_role)||"-"},{label:"Total Spend (USD)",value:(null===(d=ex.user_info)||void 0===d?void 0:d.spend)!==null&&(null===(o=ex.user_info)||void 0===o?void 0:o.spend)!==void 0?ex.user_info.spend.toFixed(2):void 0}],onCancel:()=>{ey(!1)},onOk:eM,confirmLoading:e_}),(0,t.jsxs)(eg.v0,{defaultIndex:eE,onIndexChange:eT,children:[(0,t.jsxs)(eg.td,{className:"mb-4",children:[(0,t.jsx)(eg.OK,{children:"Overview"}),(0,t.jsx)(eg.OK,{children:"Details"})]}),(0,t.jsxs)(eg.nP,{children:[(0,t.jsx)(eg.x4,{children:(0,t.jsxs)(eg.rj,{numItems:1,numItemsSm:2,numItemsLg:3,className:"gap-6",children:[(0,t.jsxs)(eg.Zb,{children:[(0,t.jsx)(eg.xv,{children:"Spend"}),(0,t.jsxs)("div",{className:"mt-2",children:[(0,t.jsxs)(eg.Dx,{children:["$",(0,O.pw)((null===(c=ex.user_info)||void 0===c?void 0:c.spend)||0,4)]}),(0,t.jsxs)(eg.xv,{children:["of"," ",(null===(u=ex.user_info)||void 0===u?void 0:u.max_budget)!==null?"$".concat((0,O.pw)(ex.user_info.max_budget,4)):"Unlimited"]})]})]}),(0,t.jsxs)(eg.Zb,{children:[(0,t.jsx)(eg.xv,{children:"Teams"}),(0,t.jsx)("div",{className:"mt-2",children:(null===(m=ex.teams)||void 0===m?void 0:m.length)&&(null===(x=ex.teams)||void 0===x?void 0:x.length)>0?(0,t.jsxs)("div",{className:"flex flex-wrap gap-2",children:[null===(h=ex.teams)||void 0===h?void 0:h.slice(0,eF?ex.teams.length:20).map((e,s)=>(0,t.jsx)(eg.Ct,{color:"blue",title:e.team_alias,children:e.team_alias},s)),!eF&&(null===(g=ex.teams)||void 0===g?void 0:g.length)>20&&(0,t.jsxs)(eg.Ct,{color:"gray",className:"cursor-pointer hover:bg-gray-200 transition-colors",onClick:()=>eR(!0),children:["+",ex.teams.length-20," more"]}),eF&&(null===(v=ex.teams)||void 0===v?void 0:v.length)>20&&(0,t.jsx)(eg.Ct,{color:"gray",className:"cursor-pointer hover:bg-gray-200 transition-colors",onClick:()=>eR(!1),children:"Show Less"})]}):(0,t.jsx)(eg.xv,{children:"No teams"})})]}),(0,t.jsxs)(eg.Zb,{children:[(0,t.jsx)(eg.xv,{children:"Virtual Keys"}),(0,t.jsx)("div",{className:"mt-2",children:(0,t.jsxs)(eg.xv,{children:[(null===(p=ex.keys)||void 0===p?void 0:p.length)||0," ",(null===(f=ex.keys)||void 0===f?void 0:f.length)===1?"Key":"Keys"]})})]}),(0,t.jsxs)(eg.Zb,{children:[(0,t.jsx)(eg.xv,{children:"Personal Models"}),(0,t.jsx)("div",{className:"mt-2",children:(null===(_=ex.user_info)||void 0===_?void 0:null===(y=_.models)||void 0===y?void 0:y.length)&&(null===(N=ex.user_info)||void 0===N?void 0:null===(b=N.models)||void 0===b?void 0:b.length)>0?null===(w=ex.user_info)||void 0===w?void 0:null===(S=w.models)||void 0===S?void 0:S.map((e,s)=>(0,t.jsx)(eg.xv,{children:e},s)):(0,t.jsx)(eg.xv,{children:"All proxy models"})})]})]})}),(0,t.jsx)(eg.x4,{children:(0,t.jsxs)(eg.Zb,{children:[(0,t.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,t.jsx)(eg.Dx,{children:"User Settings"}),!eZ&&ed&&Z.LQ.includes(ed)&&(0,t.jsx)(eg.zx,{onClick:()=>ew(!0),children:"Edit Settings"})]}),eZ&&ex?(0,t.jsx)(C,{userData:ex,onCancel:()=>ew(!1),onSubmit:eK,teams:ex.teams,accessToken:en,userID:ei,userRole:ed,userModels:ek,possibleUIRoles:ec}):(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(eg.xv,{className:"font-medium",children:"User ID"}),(0,t.jsxs)("div",{className:"flex items-center cursor-pointer",children:[(0,t.jsx)(eg.xv,{className:"font-mono",children:ex.user_id}),(0,t.jsx)(B.ZP,{type:"text",size:"small",icon:eO["user-id"]?(0,t.jsx)(ej.Z,{size:12}):(0,t.jsx)(ep.Z,{size:12}),onClick:()=>eV(ex.user_id,"user-id"),className:"left-2 z-10 transition-all duration-200 ".concat(eO["user-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",{children:[(0,t.jsx)(eg.xv,{className:"font-medium",children:"Email"}),(0,t.jsx)(eg.xv,{children:(null===(I=ex.user_info)||void 0===I?void 0:I.user_email)||"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(eg.xv,{className:"font-medium",children:"User Alias"}),(0,t.jsx)(eg.xv,{children:(null===(D=ex.user_info)||void 0===D?void 0:D.user_alias)||"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(eg.xv,{className:"font-medium",children:"Global Proxy Role"}),(0,t.jsx)(eg.xv,{children:(null===(z=ex.user_info)||void 0===z?void 0:z.user_role)||"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(eg.xv,{className:"font-medium",children:"Created"}),(0,t.jsx)(eg.xv,{children:(null===(A=ex.user_info)||void 0===A?void 0:A.created_at)?new Date(ex.user_info.created_at).toLocaleString():"Unknown"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(eg.xv,{className:"font-medium",children:"Last Updated"}),(0,t.jsx)(eg.xv,{children:(null===(E=ex.user_info)||void 0===E?void 0:E.updated_at)?new Date(ex.user_info.updated_at).toLocaleString():"Unknown"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(eg.xv,{className:"font-medium",children:"Teams"}),(0,t.jsx)("div",{className:"flex flex-wrap gap-2 mt-1",children:(null===(L=ex.teams)||void 0===L?void 0:L.length)&&(null===(F=ex.teams)||void 0===F?void 0:F.length)>0?(0,t.jsxs)(t.Fragment,{children:[null===(R=ex.teams)||void 0===R?void 0:R.slice(0,eF?ex.teams.length:20).map((e,s)=>(0,t.jsx)("span",{className:"px-2 py-1 bg-blue-100 rounded text-xs",title:e.team_alias||e.team_id,children:e.team_alias||e.team_id},s)),!eF&&(null===(M=ex.teams)||void 0===M?void 0:M.length)>20&&(0,t.jsxs)("span",{className:"px-2 py-1 bg-gray-100 rounded text-xs cursor-pointer hover:bg-gray-200 transition-colors",onClick:()=>eR(!0),children:["+",ex.teams.length-20," more"]}),eF&&(null===(K=ex.teams)||void 0===K?void 0:K.length)>20&&(0,t.jsx)("span",{className:"px-2 py-1 bg-gray-100 rounded text-xs cursor-pointer hover:bg-gray-200 transition-colors",onClick:()=>eR(!1),children:"Show Less"})]}):(0,t.jsx)(eg.xv,{children:"No teams"})})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(eg.xv,{className:"font-medium",children:"Personal Models"}),(0,t.jsx)("div",{className:"flex flex-wrap gap-2 mt-1",children:(null===(q=ex.user_info)||void 0===q?void 0:null===(V=q.models)||void 0===V?void 0:V.length)&&(null===(J=ex.user_info)||void 0===J?void 0:null===(G=J.models)||void 0===G?void 0:G.length)>0?null===(H=ex.user_info)||void 0===H?void 0:null===(Q=H.models)||void 0===Q?void 0:Q.map((e,s)=>(0,t.jsx)("span",{className:"px-2 py-1 bg-blue-100 rounded text-xs",children:e},s)):(0,t.jsx)(eg.xv,{children:"All proxy models"})})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(eg.xv,{className:"font-medium",children:"Virtual Keys"}),(0,t.jsx)("div",{className:"flex flex-wrap gap-2 mt-1",children:(null===($=ex.keys)||void 0===$?void 0:$.length)&&(null===(W=ex.keys)||void 0===W?void 0:W.length)>0?ex.keys.map((e,s)=>(0,t.jsx)("span",{className:"px-2 py-1 bg-green-100 rounded text-xs",children:e.key_alias||e.token},s)):(0,t.jsx)(eg.xv,{children:"No Virtual Keys"})})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(eg.xv,{className:"font-medium",children:"Max Budget"}),(0,t.jsx)(eg.xv,{children:(null===(Y=ex.user_info)||void 0===Y?void 0:Y.max_budget)!==null&&(null===(es=ex.user_info)||void 0===es?void 0:es.max_budget)!==void 0?"$".concat((0,O.pw)(ex.user_info.max_budget,4)):"Unlimited"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(eg.xv,{className:"font-medium",children:"Budget Reset"}),(0,t.jsx)(eg.xv,{children:(0,k.m)(null!==(ea=null===(el=ex.user_info)||void 0===el?void 0:el.budget_duration)&&void 0!==ea?ea:null)})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(eg.xv,{className:"font-medium",children:"Metadata"}),(0,t.jsx)("pre",{className:"bg-gray-100 p-2 rounded text-xs overflow-auto mt-1",children:JSON.stringify((null===(et=ex.user_info)||void 0===et?void 0:et.metadata)||{},null,2)})]})]})]})})]})]}),(0,t.jsx)(T.Z,{isInvitationLinkModalVisible:eU,setIsInvitationLinkModalVisible:eI,baseUrl:eA||"",invitationLinkData:eD,modalType:"resetPassword"})]})}var ey=l(56083),e_=l(51205),eb=l(57716),eN=l(73247),eS=l(92369),eZ=l(66344);function ew(e){let{data:s=[],columns:l,isLoading:a=!1,onSortChange:r,currentSort:n,accessToken:d,userRole:o,possibleUIRoles:c,handleEdit:u,handleDelete:m,handleResetPassword:x,selectedUsers:h=[],onSelectionChange:g,enableSelection:v=!1,filters:j,updateFilters:p,initialFilters:f,teams:y,userListResponse:b,currentPage:N,handlePageChange:S}=e,[Z,w]=i.useState([{id:(null==n?void 0:n.sortBy)||"created_at",desc:(null==n?void 0:n.sortOrder)==="desc"}]),[k,C]=i.useState(null),[U,I]=i.useState(!1),[D,z]=i.useState(!1),A=function(e){let s=arguments.length>1&&void 0!==arguments[1]&&arguments[1];C(e),I(s)},B=(e,s)=>{g&&(s?g([...h,e]):g(h.filter(s=>s.user_id!==e.user_id)))},E=e=>{g&&(e?g(s):g([]))},T=e=>h.some(s=>s.user_id===e.user_id),O=s.length>0&&h.length===s.length,L=h.length>0&&h.lengthc?es(c,u,m,x,A,v?{selectedUsers:h,onSelectUser:B,onSelectAll:E,isUserSelected:T,isAllSelected:O,isIndeterminate:L}:void 0):l,[c,u,m,x,A,l,v,h,O,L]),R=(0,el.b7)({data:s,columns:F,state:{sorting:Z},onSortingChange:e=>{let s="function"==typeof e?e(Z):e;if(w(s),s&&Array.isArray(s)&&s.length>0&&s[0]){let e=s[0];if(e.id){let s=e.id,l=e.desc?"desc":"asc";null==r||r(s,l)}}else null==r||r("created_at","desc")},getCoreRowModel:(0,et.sC)(),manualSorting:!0,enableSorting:!0});return(i.useEffect(()=>{n&&w([{id:n.sortBy,desc:"desc"===n.sortOrder}])},[n]),k)?(0,t.jsx)(ef,{userId:k,onClose:()=>{C(null),I(!1)},accessToken:d,userRole:o,possibleUIRoles:c,initialTab:U?1:0,startInEditMode:U}):(0,t.jsxs)("div",{className:"bg-white rounded-lg shadow",children:[(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 flex-wrap items-center gap-3",children:[(0,t.jsx)(ey.H,{placeholder:"Search by email...",value:j.email,onChange:e=>p({email:e}),icon:eN.Z}),(0,t.jsx)(e_.c,{onClick:()=>z(!D),active:D,hasActiveFilters:!!(j.user_id||j.user_role||j.team)}),(0,t.jsx)(eb.z,{onClick:()=>{p(f)}})]}),D&&(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-3 mt-3",children:[(0,t.jsx)(ey.H,{placeholder:"Filter by User ID",value:j.user_id,onChange:e=>p({user_id:e}),icon:eS.Z}),(0,t.jsx)(ey.H,{placeholder:"Filter by SSO ID",value:j.sso_user_id,onChange:e=>p({sso_user_id:e}),icon:eZ.Z}),(0,t.jsx)("div",{className:"w-64",children:(0,t.jsx)(ea.Z,{value:j.user_role,onValueChange:e=>p({user_role:e}),placeholder:"Select Role",children:c&&Object.entries(c).map(e=>{let[s,l]=e;return(0,t.jsx)(_.Z,{value:s,children:l.ui_label},s)})})}),(0,t.jsx)("div",{className:"w-64",children:(0,t.jsx)(ea.Z,{value:j.team,onValueChange:e=>p({team:e}),placeholder:"Select Team",children:null==y?void 0:y.map(e=>(0,t.jsx)(_.Z,{value:e.team_id,children:e.team_alias||e.team_id},e.team_id))})})]}),(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[a?(0,t.jsx)(eh.Z.Input,{active:!0,style:{width:192,height:20}}):(0,t.jsxs)("span",{className:"text-sm text-gray-700",children:["Showing"," ",b&&b.users&&b.users.length>0?(b.page-1)*b.page_size+1:0," ","-"," ",b&&b.users?Math.min(b.page*b.page_size,b.total):0," ","of ",b?b.total:0," results"]}),(0,t.jsx)("div",{className:"flex space-x-2",children:a?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(eh.Z.Button,{active:!0,size:"small",style:{width:80,height:30}}),(0,t.jsx)(eh.Z.Button,{active:!0,size:"small",style:{width:60,height:30}})]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("button",{onClick:()=>S(N-1),disabled:1===N,className:"px-3 py-1 text-sm border rounded-md ".concat(1===N?"bg-gray-100 text-gray-400 cursor-not-allowed":"hover:bg-gray-50"),children:"Previous"}),(0,t.jsx)("button",{onClick:()=>S(N+1),disabled:!b||N>=b.total_pages,className:"px-3 py-1 text-sm border rounded-md ".concat(!b||N>=b.total_pages?"bg-gray-100 text-gray-400 cursor-not-allowed":"hover:bg-gray-50"),children:"Next"})]})})]})]})}),(0,t.jsx)("div",{className:"overflow-auto",children:(0,t.jsx)("div",{className:"rounded-lg custom-border relative",children:(0,t.jsx)("div",{className:"overflow-x-auto",children:(0,t.jsxs)(ei.Z,{className:"[&_td]:py-0.5 [&_th]:py-1",children:[(0,t.jsx)(ed.Z,{children:R.getHeaderGroups().map(e=>(0,t.jsx)(ec.Z,{children:e.headers.map(e=>(0,t.jsx)(eo.Z,{className:"py-1 h-8 ".concat("actions"===e.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)]":""," ").concat(e.column.getCanSort()?"cursor-pointer hover:bg-gray-50":""),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,el.ie)(e.column.columnDef.header,e.getContext())}),"actions"!==e.id&&e.column.getCanSort()&&(0,t.jsx)("div",{className:"w-4",children:e.column.getIsSorted()?({asc:(0,t.jsx)(eu.Z,{className:"h-4 w-4 text-blue-500"}),desc:(0,t.jsx)(em.Z,{className:"h-4 w-4 text-blue-500"})})[e.column.getIsSorted()]:(0,t.jsx)(ex.Z,{className:"h-4 w-4 text-gray-400"})})]})},e.id))},e.id))}),(0,t.jsx)(er.Z,{children:a?(0,t.jsx)(ec.Z,{children:(0,t.jsx)(en.Z,{colSpan:F.length,className:"h-8 text-center",children:(0,t.jsx)("div",{className:"text-center text-gray-500",children:(0,t.jsx)("p",{children:"\uD83D\uDE85 Loading users..."})})})}):s.length>0?R.getRowModel().rows.map(e=>(0,t.jsx)(ec.Z,{className:"h-8",children:e.getVisibleCells().map(e=>(0,t.jsx)(en.Z,{className:"py-0.5 max-h-8 overflow-hidden text-ellipsis whitespace-nowrap ".concat("actions"===e.column.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)]":""),onClick:()=>{"user_id"===e.column.id&&A(e.getValue(),!1)},style:{cursor:"user_id"===e.column.id?"pointer":"default",color:"user_id"===e.column.id?"#3b82f6":"inherit"},children:(0,el.ie)(e.column.columnDef.cell,e.getContext())},e.id))},e.id)):(0,t.jsx)(ec.Z,{children:(0,t.jsx)(en.Z,{colSpan:F.length,className:"h-8 text-center",children:(0,t.jsx)("div",{className:"text-center text-gray-500",children:(0,t.jsx)("p",{children:"No users found"})})})})})]})})})})]})}let{Text:ek,Title:eC}=n.default,eU={email:"",user_id:"",user_role:"",sso_user_id:"",team:"",model:"",min_spend:null,max_spend:null,sort_by:"created_at",sort_order:"desc"};var eI=e=>{var s,l,n;let{accessToken:d,token:o,userRole:c,userID:u,teams:m}=e,x=(0,F.NL)(),[h,g]=(0,i.useState)(1),[v,p]=(0,i.useState)(!1),[f,y]=(0,i.useState)(null),[_,b]=(0,i.useState)(!1),[N,S]=(0,i.useState)(!1),[w,k]=(0,i.useState)(null),[C,I]=(0,i.useState)("users"),[D,B]=(0,i.useState)(eU),[M,K,V]=(0,L.G)(D,{wait:300}),[q,G]=(0,i.useState)(!1),[Q,H]=(0,i.useState)(null),[$,W]=(0,i.useState)(null),[Y,X]=(0,i.useState)([]),[ee,el]=(0,i.useState)(!1),[et,ea]=(0,i.useState)(!1),[ei,er]=(0,i.useState)([]),en=e=>{k(e),b(!0)};(0,i.useEffect)(()=>()=>{V.cancel()},[V]),(0,i.useEffect)(()=>{W((0,j.getProxyBaseUrl)())},[]),(0,i.useEffect)(()=>{(async()=>{try{if(!u||!c||!d)return;let e=(await (0,j.modelAvailableCall)(d,u,c)).data.map(e=>e.id);console.log("available_model_names:",e),er(e)}catch(e){console.error("Error fetching user models:",e)}})()},[d,u,c]);let ed=e=>{B(s=>{let l={...s,...e};return K(l),l})},eo=async e=>{if(!d){U.Z.fromBackend("Access token not found");return}try{U.Z.success("Generating password reset link...");let s=await (0,j.invitationCreateCall)(d,e);H(s),G(!0)}catch(e){U.Z.fromBackend("Failed to generate password reset link")}},ec=async()=>{if(w&&d)try{S(!0),await (0,j.userDeleteCall)(d,[w.user_id]),x.setQueriesData({queryKey:["userList"]},e=>{if(void 0===e)return e;let s=e.users.filter(e=>e.user_id!==w.user_id);return{...e,users:s}}),U.Z.success("User deleted successfully")}catch(e){console.error("Error deleting user:",e),U.Z.fromBackend("Failed to delete user")}finally{b(!1),k(null),S(!1)}},eu=async()=>{y(null),p(!1)},em=async e=>{if(console.log("inside handleEditSubmit:",e),d&&o&&c&&u){try{let s=await (0,j.userUpdateUserCall)(d,e,null);x.setQueriesData({queryKey:["userList"]},e=>{if(void 0===e)return e;let l=e.users.map(e=>e.user_id===s.data.user_id?(0,O.nl)(e,s.data):e);return{...e,users:l}}),U.Z.success("User ".concat(e.user_id," updated successfully"))}catch(e){console.error("There was an error updating the user",e)}y(null),p(!1)}},ex=async e=>{g(e)},eg=(0,R.a)({queryKey:["userList",{debouncedFilter:M,currentPage:h}],queryFn:async()=>{if(!d)throw Error("Access token required");return await (0,j.userListCall)(d,M.user_id?[M.user_id]:null,h,25,M.email||null,M.user_role||null,M.team||null,M.sso_user_id||null,M.sort_by,M.sort_order)},enabled:!!(d&&o&&c&&u),placeholderData:e=>e}),ev=eg.data,ej=(0,R.a)({queryKey:["userRoles"],initialData:()=>({}),queryFn:async()=>{if(!d)throw Error("Access token required");return await (0,j.getPossibleUserRoles)(d)},enabled:!!(d&&o&&c&&u)}).data,ep=es(ej,e=>{y(e),p(!0)},en,eo,()=>{});return(0,t.jsxs)("div",{className:"w-full p-8 overflow-hidden",children:[(0,t.jsx)("div",{className:"flex items-center justify-between mb-4",children:(0,t.jsx)("div",{className:"flex space-x-3",children:eg.isLoading?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(eh.Z.Button,{active:!0,size:"default",shape:"default",style:{width:110,height:36}}),(0,t.jsx)(eh.Z.Button,{active:!0,size:"default",shape:"default",style:{width:145,height:36}}),(0,t.jsx)(eh.Z.Button,{active:!0,size:"default",shape:"default",style:{width:110,height:36}})]}):u&&d?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(A.Z,{userID:u,accessToken:d,teams:m,possibleUIRoles:ej}),(0,t.jsx)(r.z,{onClick:()=>{ea(!et),X([])},variant:et?"primary":"secondary",className:"flex items-center",children:et?"Cancel Selection":"Select Users"}),et&&(0,t.jsxs)(r.z,{onClick:()=>{if(0===Y.length){U.Z.fromBackend("Please select users to edit");return}el(!0)},disabled:0===Y.length,className:"flex items-center",children:["Bulk Edit (",Y.length," selected)"]})]}):null})}),(0,t.jsxs)(a.v0,{defaultIndex:0,onIndexChange:e=>I(0===e?"users":"settings"),children:[(0,t.jsxs)(a.td,{className:"mb-4",children:[(0,t.jsx)(a.OK,{children:"Users"}),(0,t.jsx)(a.OK,{children:"Default User Settings"})]}),(0,t.jsxs)(a.nP,{children:[(0,t.jsx)(a.x4,{children:(0,t.jsx)(ew,{data:(null===(s=eg.data)||void 0===s?void 0:s.users)||[],columns:ep,isLoading:eg.isLoading,accessToken:d,userRole:c,onSortChange:(e,s)=>{ed({sort_by:e,sort_order:s})},currentSort:{sortBy:D.sort_by,sortOrder:D.sort_order},possibleUIRoles:ej,handleEdit:e=>{y(e),p(!0)},handleDelete:en,handleResetPassword:eo,enableSelection:et,selectedUsers:Y,onSelectionChange:e=>{X(e)},filters:D,updateFilters:ed,initialFilters:eU,teams:m,userListResponse:ev,currentPage:h,handlePageChange:ex})}),(0,t.jsx)(a.x4,{children:u&&c&&d?(0,t.jsx)(J,{accessToken:d,possibleUIRoles:ej,userID:u,userRole:c}):(0,t.jsx)("div",{className:"flex justify-center items-center h-64",children:(0,t.jsx)(eh.Z,{active:!0,paragraph:{rows:4}})})})]})]}),(0,t.jsx)(E,{visible:v,possibleUIRoles:ej,onCancel:eu,user:f,onSubmit:em}),(0,t.jsx)(P.Z,{isOpen:_,title:"Delete User?",message:"Are you sure you want to delete this user? This action cannot be undone.",resourceInformationTitle:"User Information",resourceInformation:[{label:"Email",value:null==w?void 0:w.user_email},{label:"User ID",value:null==w?void 0:w.user_id,code:!0},{label:"Global Proxy Role",value:w&&(null==ej?void 0:null===(l=ej[w.user_role])||void 0===l?void 0:l.ui_label)||(null==w?void 0:w.user_role)||"-"},{label:"Total Spend (USD)",value:null==w?void 0:null===(n=w.spend)||void 0===n?void 0:n.toFixed(2)}],onCancel:()=>{b(!1),k(null)},onOk:ec,confirmLoading:N}),(0,t.jsx)(T.Z,{isInvitationLinkModalVisible:q,setIsInvitationLinkModalVisible:G,baseUrl:$||"",invitationLinkData:Q,modalType:"resetPassword"}),(0,t.jsx)(z,{open:ee,onCancel:()=>el(!1),selectedUsers:Y,possibleUIRoles:ej,accessToken:d,onSuccess:()=>{x.invalidateQueries({queryKey:["userList"]}),X([]),ea(!1)},teams:m,userRole:c,userModels:ei,allowAllUsers:!!c&&(0,Z.tY)(c)})]})}}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/2344-905d7ecc9d0c6724.js b/litellm/proxy/_experimental/out/_next/static/chunks/2344-905d7ecc9d0c6724.js deleted file mode 100644 index ac70c71a273..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/2344-905d7ecc9d0c6724.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[2344],{38434:function(t,e,n){n.d(e,{Z:function(){return i}});var r=n(1119),a=n(2265),o={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M854.6 288.6L639.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 42h216v494zM504 618H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zM312 490v48c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H320c-4.4 0-8 3.6-8 8z"}}]},name:"file-text",theme:"outlined"},c=n(55015),i=a.forwardRef(function(t,e){return a.createElement(c.Z,(0,r.Z)({},t,{ref:e,icon:o}))})},96473:function(t,e,n){n.d(e,{Z:function(){return i}});var r=n(1119),a=n(2265),o={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"}},{tag:"path",attrs:{d:"M192 474h672q8 0 8 8v60q0 8-8 8H160q-8 0-8-8v-60q0-8 8-8z"}}]},name:"plus",theme:"outlined"},c=n(55015),i=a.forwardRef(function(t,e){return a.createElement(c.Z,(0,r.Z)({},t,{ref:e,icon:o}))})},77565:function(t,e,n){n.d(e,{Z:function(){return i}});var r=n(1119),a=n(2265),o={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"}}]},name:"right",theme:"outlined"},c=n(55015),i=a.forwardRef(function(t,e){return a.createElement(c.Z,(0,r.Z)({},t,{ref:e,icon:o}))})},57400:function(t,e,n){n.d(e,{Z:function(){return i}});var r=n(1119),a=n(2265),o={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64L128 192v384c0 212.1 171.9 384 384 384s384-171.9 384-384V192L512 64zm312 512c0 172.3-139.7 312-312 312S200 748.3 200 576V246l312-110 312 110v330z"}},{tag:"path",attrs:{d:"M378.4 475.1a35.91 35.91 0 00-50.9 0 35.91 35.91 0 000 50.9l129.4 129.4 2.1 2.1a33.98 33.98 0 0048.1 0L730.6 434a33.98 33.98 0 000-48.1l-2.8-2.8a33.98 33.98 0 00-48.1 0L483 579.7 378.4 475.1z"}}]},name:"safety",theme:"outlined"},c=n(55015),i=a.forwardRef(function(t,e){return a.createElement(c.Z,(0,r.Z)({},t,{ref:e,icon:o}))})},15883:function(t,e,n){n.d(e,{Z:function(){return i}});var r=n(1119),a=n(2265),o={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"}}]},name:"user",theme:"outlined"},c=n(55015),i=a.forwardRef(function(t,e){return a.createElement(c.Z,(0,r.Z)({},t,{ref:e,icon:o}))})},23496:function(t,e,n){n.d(e,{Z:function(){return p}});var r=n(2265),a=n(36760),o=n.n(a),c=n(71744),i=n(33759),l=n(93463),d=n(12918),s=n(99320),f=n(71140);let h=t=>{let{componentCls:e}=t;return{[e]:{"&-horizontal":{["&".concat(e)]:{"&-sm":{marginBlock:t.marginXS},"&-md":{marginBlock:t.margin}}}}}},u=t=>{let{componentCls:e,sizePaddingEdgeHorizontal:n,colorSplit:r,lineWidth:a,textPaddingInline:o,orientationMargin:c,verticalMarginInline:i}=t;return{[e]:Object.assign(Object.assign({},(0,d.Wf)(t)),{borderBlockStart:"".concat((0,l.bf)(a)," solid ").concat(r),"&-vertical":{position:"relative",top:"-0.06em",display:"inline-block",height:"0.9em",marginInline:i,marginBlock:0,verticalAlign:"middle",borderTop:0,borderInlineStart:"".concat((0,l.bf)(a)," solid ").concat(r)},"&-horizontal":{display:"flex",clear:"both",width:"100%",minWidth:"100%",margin:"".concat((0,l.bf)(t.marginLG)," 0")},["&-horizontal".concat(e,"-with-text")]:{display:"flex",alignItems:"center",margin:"".concat((0,l.bf)(t.dividerHorizontalWithTextGutterMargin)," 0"),color:t.colorTextHeading,fontWeight:500,fontSize:t.fontSizeLG,whiteSpace:"nowrap",textAlign:"center",borderBlockStart:"0 ".concat(r),"&::before, &::after":{position:"relative",width:"50%",borderBlockStart:"".concat((0,l.bf)(a)," solid transparent"),borderBlockStartColor:"inherit",borderBlockEnd:0,transform:"translateY(50%)",content:"''"}},["&-horizontal".concat(e,"-with-text-start")]:{"&::before":{width:"calc(".concat(c," * 100%)")},"&::after":{width:"calc(100% - ".concat(c," * 100%)")}},["&-horizontal".concat(e,"-with-text-end")]:{"&::before":{width:"calc(100% - ".concat(c," * 100%)")},"&::after":{width:"calc(".concat(c," * 100%)")}},["".concat(e,"-inner-text")]:{display:"inline-block",paddingBlock:0,paddingInline:o},"&-dashed":{background:"none",borderColor:r,borderStyle:"dashed",borderWidth:"".concat((0,l.bf)(a)," 0 0")},["&-horizontal".concat(e,"-with-text").concat(e,"-dashed")]:{"&::before, &::after":{borderStyle:"dashed none none"}},["&-vertical".concat(e,"-dashed")]:{borderInlineStartWidth:a,borderInlineEnd:0,borderBlockStart:0,borderBlockEnd:0},"&-dotted":{background:"none",borderColor:r,borderStyle:"dotted",borderWidth:"".concat((0,l.bf)(a)," 0 0")},["&-horizontal".concat(e,"-with-text").concat(e,"-dotted")]:{"&::before, &::after":{borderStyle:"dotted none none"}},["&-vertical".concat(e,"-dotted")]:{borderInlineStartWidth:a,borderInlineEnd:0,borderBlockStart:0,borderBlockEnd:0},["&-plain".concat(e,"-with-text")]:{color:t.colorText,fontWeight:"normal",fontSize:t.fontSize},["&-horizontal".concat(e,"-with-text-start").concat(e,"-no-default-orientation-margin-start")]:{"&::before":{width:0},"&::after":{width:"100%"},["".concat(e,"-inner-text")]:{paddingInlineStart:n}},["&-horizontal".concat(e,"-with-text-end").concat(e,"-no-default-orientation-margin-end")]:{"&::before":{width:"100%"},"&::after":{width:0},["".concat(e,"-inner-text")]:{paddingInlineEnd:n}}})}};var g=(0,s.I$)("Divider",t=>{let e=(0,f.IX)(t,{dividerHorizontalWithTextGutterMargin:t.margin,sizePaddingEdgeHorizontal:0});return[u(e),h(e)]},t=>({textPaddingInline:"1em",orientationMargin:.05,verticalMarginInline:t.marginXS}),{unitless:{orientationMargin:!0}}),m=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&0>e.indexOf(r)&&(n[r]=t[r]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,r=Object.getOwnPropertySymbols(t);ae.indexOf(r[a])&&Object.prototype.propertyIsEnumerable.call(t,r[a])&&(n[r[a]]=t[r[a]]);return n};let b={small:"sm",middle:"md"};var p=t=>{let{getPrefixCls:e,direction:n,className:a,style:l}=(0,c.dj)("divider"),{prefixCls:d,type:s="horizontal",orientation:f="center",orientationMargin:h,className:u,rootClassName:p,children:v,dashed:w,variant:y="solid",plain:x,style:k,size:z}=t,S=m(t,["prefixCls","type","orientation","orientationMargin","className","rootClassName","children","dashed","variant","plain","style","size"]),Z=e("divider",d),[M,E,B]=g(Z),C=b[(0,i.Z)(z)],I=!!v,O=r.useMemo(()=>"left"===f?"rtl"===n?"end":"start":"right"===f?"rtl"===n?"start":"end":f,[n,f]),j="start"===O&&null!=h,L="end"===O&&null!=h,N=o()(Z,a,E,B,"".concat(Z,"-").concat(s),{["".concat(Z,"-with-text")]:I,["".concat(Z,"-with-text-").concat(O)]:I,["".concat(Z,"-dashed")]:!!w,["".concat(Z,"-").concat(y)]:"solid"!==y,["".concat(Z,"-plain")]:!!x,["".concat(Z,"-rtl")]:"rtl"===n,["".concat(Z,"-no-default-orientation-margin-start")]:j,["".concat(Z,"-no-default-orientation-margin-end")]:L,["".concat(Z,"-").concat(C)]:!!C},u,p),W=r.useMemo(()=>"number"==typeof h?h:/^\d+$/.test(h)?Number(h):h,[h]);return M(r.createElement("div",Object.assign({className:N,style:Object.assign(Object.assign({},l),k)},S,{role:"separator"}),v&&"vertical"!==s&&r.createElement("span",{className:"".concat(Z,"-inner-text"),style:{marginInlineStart:j?W:void 0,marginInlineEnd:L?W:void 0}},v)))}},79205:function(t,e,n){n.d(e,{Z:function(){return f}});var r=n(2265);let a=t=>t.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),o=t=>t.replace(/^([A-Z])|[\s-_]+(\w)/g,(t,e,n)=>n?n.toUpperCase():e.toLowerCase()),c=t=>{let e=o(t);return e.charAt(0).toUpperCase()+e.slice(1)},i=function(){for(var t=arguments.length,e=Array(t),n=0;n!!t&&""!==t.trim()&&n.indexOf(t)===e).join(" ").trim()},l=t=>{for(let e in t)if(e.startsWith("aria-")||"role"===e||"title"===e)return!0};var d={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 s=(0,r.forwardRef)((t,e)=>{let{color:n="currentColor",size:a=24,strokeWidth:o=2,absoluteStrokeWidth:c,className:s="",children:f,iconNode:h,...u}=t;return(0,r.createElement)("svg",{ref:e,...d,width:a,height:a,stroke:n,strokeWidth:c?24*Number(o)/Number(a):o,className:i("lucide",s),...!f&&!l(u)&&{"aria-hidden":"true"},...u},[...h.map(t=>{let[e,n]=t;return(0,r.createElement)(e,n)}),...Array.isArray(f)?f:[f]])}),f=(t,e)=>{let n=(0,r.forwardRef)((n,o)=>{let{className:l,...d}=n;return(0,r.createElement)(s,{ref:o,iconNode:e,className:i("lucide-".concat(a(c(t))),"lucide-".concat(t),l),...d})});return n.displayName=c(t),n}},82222:function(t,e,n){n.d(e,{Z:function(){return r}});let r=(0,n(79205).Z)("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"}]])},51817:function(t,e,n){n.d(e,{Z:function(){return r}});let r=(0,n(79205).Z)("loader-circle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]])},98728:function(t,e,n){n.d(e,{Z:function(){return r}});let r=(0,n(79205).Z)("settings",[["path",{d:"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z",key:"1qme2f"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]])},79862:function(t,e,n){n.d(e,{Z:function(){return r}});let r=(0,n(79205).Z)("user-round",[["circle",{cx:"12",cy:"8",r:"5",key:"1hypcn"}],["path",{d:"M20 21a8 8 0 0 0-16 0",key:"rfgkzh"}]])},32489:function(t,e,n){n.d(e,{Z:function(){return r}});let r=(0,n(79205).Z)("x",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]])},25523:function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"RouterContext",{enumerable:!0,get:function(){return r}});let r=n(47043)._(n(2265)).default.createContext(null)}}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/2353-c94748c0aac514ff.js b/litellm/proxy/_experimental/out/_next/static/chunks/2353-c94748c0aac514ff.js deleted file mode 100644 index 3426c548b25..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/2353-c94748c0aac514ff.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[2353],{57365:function(e,t,n){n.d(t,{Z:function(){return a}});var r=n(5853),o=n(2265),l=n(51975),i=n(13241);let u=(0,n(1153).fn)("SelectItem"),a=o.forwardRef((e,t)=>{let{value:n,icon:a,className:s,children:c}=e,d=(0,r._T)(e,["value","icon","className","children"]);return o.createElement(l.wt,Object.assign({className:(0,i.q)(u("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",s),ref:t,key:n,value:n},d),a&&o.createElement(a,{className:(0,i.q)(u("icon"),"flex-none w-5 h-5 mr-1.5","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle")}),o.createElement("span",{className:"whitespace-nowrap truncate"},null!=c?c:n))});a.displayName="SelectItem"},44140:function(e,t,n){n.d(t,{Z:function(){return o}});var r=n(2265);let o=(e,t)=>{let n=void 0!==t,[o,l]=(0,r.useState)(e);return[n?t:o,e=>{n||l(e)}]}},64803:function(e,t,n){n.d(t,{RR:function(){return v},YF:function(){return d},cv:function(){return f},dp:function(){return m},uY:function(){return p}});var r=n(51050),o=n(2265),l=n(54887),i="undefined"!=typeof document?o.useLayoutEffect:function(){};function u(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(!u(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)&&!u(e[n],t[n]))return!1}return!0}return e!=e&&t!=t}function a(e){return"undefined"==typeof window?1:(e.ownerDocument.defaultView||window).devicePixelRatio||1}function s(e,t){let n=a(e);return Math.round(t*n)/n}function c(e){let t=o.useRef(e);return i(()=>{t.current=e}),t}function d(e){void 0===e&&(e={});let{placement:t="bottom",strategy:n="absolute",middleware:d=[],platform:f,elements:{reference:p,floating:v}={},transform:m=!0,whileElementsMounted:g,open:h}=e,[b,x]=o.useState({x:0,y:0,strategy:n,placement:t,middlewareData:{},isPositioned:!1}),[E,y]=o.useState(d);u(E,d)||y(d);let[S,O]=o.useState(null),[R,w]=o.useState(null),C=o.useCallback(e=>{e!==k.current&&(k.current=e,O(e))},[]),P=o.useCallback(e=>{e!==M.current&&(M.current=e,w(e))},[]),L=p||S,T=v||R,k=o.useRef(null),M=o.useRef(null),I=o.useRef(b),F=null!=g,A=c(g),D=c(f),N=c(h),z=o.useCallback(()=>{if(!k.current||!M.current)return;let e={placement:t,strategy:n,middleware:E};D.current&&(e.platform=D.current),(0,r.oo)(k.current,M.current,e).then(e=>{let t={...e,isPositioned:!1!==N.current};H.current&&!u(I.current,t)&&(I.current=t,l.flushSync(()=>{x(t)}))})},[E,t,n,D,N]);i(()=>{!1===h&&I.current.isPositioned&&(I.current.isPositioned=!1,x(e=>({...e,isPositioned:!1})))},[h]);let H=o.useRef(!1);i(()=>(H.current=!0,()=>{H.current=!1}),[]),i(()=>{if(L&&(k.current=L),T&&(M.current=T),L&&T){if(A.current)return A.current(L,T,z);z()}},[L,T,z,A,F]);let _=o.useMemo(()=>({reference:k,floating:M,setReference:C,setFloating:P}),[C,P]),B=o.useMemo(()=>({reference:L,floating:T}),[L,T]),V=o.useMemo(()=>{let e={position:n,left:0,top:0};if(!B.floating)return e;let t=s(B.floating,b.x),r=s(B.floating,b.y);return m?{...e,transform:"translate("+t+"px, "+r+"px)",...a(B.floating)>=1.5&&{willChange:"transform"}}:{position:n,left:t,top:r}},[n,m,B.floating,b.x,b.y]);return o.useMemo(()=>({...b,update:z,refs:_,elements:B,floatingStyles:V}),[b,z,_,B,V])}let f=(e,t)=>({...(0,r.cv)(e),options:[e,t]}),p=(e,t)=>({...(0,r.uY)(e),options:[e,t]}),v=(e,t)=>({...(0,r.RR)(e),options:[e,t]}),m=(e,t)=>({...(0,r.dp)(e),options:[e,t]})},52307:function(e,t,n){n.d(t,{dk:function(){return f},fw:function(){return d},zH:function(){return c}});var r=n(2265),o=n(93980),l=n(73389),i=n(67561),u=n(87550),a=n(38929);let s=(0,r.createContext)(null);function c(){var e,t;return null!=(t=null==(e=(0,r.useContext)(s))?void 0:e.value)?t:void 0}function d(){let[e,t]=(0,r.useState)([]);return[e.length>0?e.join(" "):void 0,(0,r.useMemo)(()=>function(e){let n=(0,o.z)(e=>(t(t=>[...t,e]),()=>t(t=>{let n=t.slice(),r=n.indexOf(e);return -1!==r&&n.splice(r,1),n}))),l=(0,r.useMemo)(()=>({register:n,slot:e.slot,name:e.name,props:e.props,value:e.value}),[n,e.slot,e.name,e.props,e.value]);return r.createElement(s.Provider,{value:l},e.children)},[t])]}s.displayName="DescriptionContext";let f=Object.assign((0,a.yV)(function(e,t){let n=(0,r.useId)(),o=(0,u.B)(),{id:c="headlessui-description-".concat(n),...d}=e,f=function e(){let t=(0,r.useContext)(s);if(null===t){let t=Error("You used a component, but it is not inside a relevant parent.");throw Error.captureStackTrace&&Error.captureStackTrace(t,e),t}return t}(),p=(0,i.T)(t);(0,l.e)(()=>f.register(c),[c,f.register]);let v=o||!1,m=(0,r.useMemo)(()=>({...f.slot,disabled:v}),[f.slot,v]),g={ref:p,...f.props,id:c};return(0,a.L6)()({ourProps:g,theirProps:d,slot:m,defaultTag:"p",name:f.name||"Description"})}),{})},7935:function(e,t,n){n.d(t,{__:function(){return p},bE:function(){return f},wp:function(){return d}});var r=n(2265),o=n(93980),l=n(73389),i=n(67561),u=n(87550),a=n(80281),s=n(38929);let c=(0,r.createContext)(null);function d(e){var t,n,o;let l=null!=(n=null==(t=(0,r.useContext)(c))?void 0:t.value)?n:void 0;return(null!=(o=null==e?void 0:e.length)?o:0)>0?[l,...e].filter(Boolean).join(" "):l}function f(){let{inherit:e=!1}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=d(),[n,l]=(0,r.useState)([]),i=e?[t,...n].filter(Boolean):n;return[i.length>0?i.join(" "):void 0,(0,r.useMemo)(()=>function(e){let t=(0,o.z)(e=>(l(t=>[...t,e]),()=>l(t=>{let n=t.slice(),r=n.indexOf(e);return -1!==r&&n.splice(r,1),n}))),n=(0,r.useMemo)(()=>({register:t,slot:e.slot,name:e.name,props:e.props,value:e.value}),[t,e.slot,e.name,e.props,e.value]);return r.createElement(c.Provider,{value:n},e.children)},[l])]}c.displayName="LabelContext";let p=Object.assign((0,s.yV)(function(e,t){var n;let d=(0,r.useId)(),f=function e(){let t=(0,r.useContext)(c);if(null===t){let t=Error("You used a ^jr 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

    3YYKR6{ z;eVZ|Xc9msvJQ0a1f4y;rYN*Z_5;#k5yNt59}4U~2)o?E#zdx9 zPC9b=LLI}SMFA4?dA#P8f6NaE>~Tu@QWvI++oir9CgMp4kI?3l&Tc?W#tuAvXxG2o z`NVw(c1}(WAD$T*oemMiJO;GrH~(E)nul4O$X+P9a_fkAVD z)hZipkv%7T(FL6-59!fX{`4|rAO;L`<9N}%Cs89xXqbMdTHEdj8JHIZz{o}u-W2m& z&OGPICmy}@;!E$o_wIVN##_x`8~?yLH50a{KMsbN9U!j5>|hlU)K;d7G`;mLYz=69 z@FSTG8xx#x2fCdkKlwrJhR-*PU73v=dAD4%Qo-r@7FR?hwV$bPA#{vP6+_^1VGJ|E zLL*-s>`D5G_ekwzlk&_{d-mLT|Ks0&a`%bxBO~Jzz9%w4R{F6Z%D<5;GYH^m<+}P_ zbo!~kzHZ|SPTknKaN$5_sl+x!HLu0%+Ibsna-uwqRp4hNNnt1sJ|KZ)syZd21zDGf!+Igp7&cJY zzz_l(3D`7?1sAD}VWLaSP|c}O4bxI*8?I4Ky+xiq>Fs3Q$KCivfH$!3Aa1V?PnRp> zhxd-`|HigwzH)5;(L?)^<`j`6Ipd_+MFz|NV=$Uvu-4yQ>M1Q)-?!|wtIvAl>1Qrk zy4q@0e#2%usZUlXCZ|~zWP1RKV}GfwsA@S$OEZ>|JQAo*z2dzoxul!rgPF{udvfa* z|m);sUsmyWd7yW+Q0uOJ2I7A|K`GLFLi;5Y+A}Tnc-hBbM7Qq(`KuMwR(j& zY#bk+*tBW=$ndfAF1+}``|hojEBvT0axmKgHICZ+Tl4NDr|U zsJKSDIc6&xTed0)dRLdLkvsMr8XKGH@9$0@B1|PpkQ8^jX!kjXpoJl>X^+jiTMCw+ z(mHV>cm4IXH(Zyz;+Lsw^{ZcAe8JVVkN{2QA;jEksMcJA8qjmHi?v-gQ(BL^Pd zKYcKLZjg!*(pl|Df!LCK* zjm?cG)1%2mBbl1yEl^3bQmxbsi|`K}B{di?<}O8DJATLHwFUqc@eyYaku`8^(B5&vr@jjM74WbTM8z=LJ8o4fRjEQSDd`OcM)FMU+K_FsaG}KJ( z1R_oul!0_iVJMtHa|bZFg{7k=izONcT4)9^>cqF`d@xsGlZAZnBVbqt%#N6RGxbL`0(z%2PURZ>>57!(7~NgA3d~vm{mI8K$+zGl7YSi5oK

    \ No newline at end of file +LiteLLM Dashboard
    🚅 LiteLLM
    Loading...
    \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/logs.txt b/litellm/proxy/_experimental/out/logs.txt index 3050cf9f9ed..f0f42af3935 100644 --- a/litellm/proxy/_experimental/out/logs.txt +++ b/litellm/proxy/_experimental/out/logs.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[19056,["1047","static/chunks/e228588e-635e9029d9d88215.js","6990","static/chunks/13b76428-e1bf383848c17260.js","1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","353","static/chunks/353-347e4836f09d94a0.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","7971","static/chunks/7971-76912e9c9a840367.js","6894","static/chunks/6894-8c74216e23aa271e.js","3705","static/chunks/3705-dde102fd596f74e8.js","3898","static/chunks/3898-fc3dbf5a964ea4ca.js","3178","static/chunks/3178-47bc3b9e8cf9bf6c.js","5319","static/chunks/5319-7f07d87ef011d5c9.js","1716","static/chunks/1716-1c0ba935a144e6ff.js","9967","static/chunks/9967-329bb618cc1c8902.js","6609","static/chunks/6609-707213b617f85369.js","2353","static/chunks/2353-c94748c0aac514ff.js","7967","static/chunks/7967-1ac5097c3d83016f.js","1176","static/chunks/1176-9175d7684b344026.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5144","static/chunks/5144-ddfa7a8f89c5d465.js","7914","static/chunks/7914-25af99af34bee64b.js","1098","static/chunks/1098-a1702da59647cf14.js","665","static/chunks/665-05a55da381817c0d.js","8437","static/chunks/8437-d1298f5313ff07fa.js","2100","static/chunks/app/(dashboard)/logs/page-c832262bfde568ab.js"],"default",1] +3:I[19056,["1047","static/chunks/e228588e-635e9029d9d88215.js","6990","static/chunks/13b76428-e1bf383848c17260.js","9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","2409","static/chunks/2409-e94c05c6f11bb939.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","353","static/chunks/353-e55516ea4730f9d4.js","1994","static/chunks/1994-6637a121c9ee1602.js","7138","static/chunks/7138-5b134dc8ad670770.js","7851","static/chunks/7851-c10cbe6fcac2f9d6.js","2068","static/chunks/2068-2c78bfc32dc0de5f.js","8565","static/chunks/8565-5c05f6bbb9d0662f.js","5319","static/chunks/5319-5b2d4bf2dc450f99.js","5333","static/chunks/5333-1540faf81c7d7006.js","8582","static/chunks/8582-3a775364dbf07fa8.js","6609","static/chunks/6609-3e081758ffbe3786.js","4105","static/chunks/4105-9c3c0ee7c494102f.js","2378","static/chunks/2378-252212b7a5e313ce.js","5202","static/chunks/5202-60292daf4bc5c8fb.js","8049","static/chunks/8049-cb52b16664f13e28.js","5144","static/chunks/5144-bbc18c43eade9aef.js","2202","static/chunks/2202-a83ad035a17401aa.js","1098","static/chunks/1098-c3e95c9684ff5e95.js","665","static/chunks/665-d94073042ee5b874.js","1901","static/chunks/1901-4d02d1f2a71cdbf7.js","2100","static/chunks/app/(dashboard)/logs/page-5a10d46ca991b83e.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["logs",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["logs",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/0fc668a8750043fe.css","precedence":"next","crossOrigin":"$undefined"}]]],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","logs","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["logs",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["logs",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/0fc668a8750043fe.css","precedence":"next","crossOrigin":"$undefined"}]]],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","logs","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/logs.html b/litellm/proxy/_experimental/out/logs/index.html similarity index 74% rename from litellm/proxy/_experimental/out/logs.html rename to litellm/proxy/_experimental/out/logs/index.html index cd3c4d2ed03..009e96e58cb 100644 --- a/litellm/proxy/_experimental/out/logs.html +++ b/litellm/proxy/_experimental/out/logs/index.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/mcp/oauth/callback.txt b/litellm/proxy/_experimental/out/mcp/oauth/callback.txt index 1b99bbdb6f8..6e6b91856f2 100644 --- a/litellm/proxy/_experimental/out/mcp/oauth/callback.txt +++ b/litellm/proxy/_experimental/out/mcp/oauth/callback.txt @@ -2,6 +2,6 @@ 3:I[33422,["480","static/chunks/app/mcp/oauth/callback/page-01be1cae3559363d.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["mcp",{"children":["oauth",{"children":["callback",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["mcp",{"children":["oauth",{"children":["callback",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","mcp","children","oauth","children","callback","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","mcp","children","oauth","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","mcp","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$L6",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["mcp",{"children":["oauth",{"children":["callback",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["mcp",{"children":["oauth",{"children":["callback",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","mcp","children","oauth","children","callback","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","mcp","children","oauth","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","mcp","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$L6",null]]]] 6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/mcp/oauth/callback.html b/litellm/proxy/_experimental/out/mcp/oauth/callback/index.html similarity index 95% rename from litellm/proxy/_experimental/out/mcp/oauth/callback.html rename to litellm/proxy/_experimental/out/mcp/oauth/callback/index.html index 65ac33e149e..8dfe2d19e03 100644 --- a/litellm/proxy/_experimental/out/mcp/oauth/callback.html +++ b/litellm/proxy/_experimental/out/mcp/oauth/callback/index.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/model-hub.html b/litellm/proxy/_experimental/out/model-hub.html deleted file mode 100644 index 0456cb68b06..00000000000 --- a/litellm/proxy/_experimental/out/model-hub.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/model-hub.txt b/litellm/proxy/_experimental/out/model-hub.txt index 6ef8c0750eb..4aa2f97413e 100644 --- a/litellm/proxy/_experimental/out/model-hub.txt +++ b/litellm/proxy/_experimental/out/model-hub.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[30615,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","7971","static/chunks/7971-76912e9c9a840367.js","6894","static/chunks/6894-8c74216e23aa271e.js","3705","static/chunks/3705-dde102fd596f74e8.js","3178","static/chunks/3178-47bc3b9e8cf9bf6c.js","2618","static/chunks/2618-062177b80fc4a38e.js","7906","static/chunks/7906-1b1cdd8da2773bb2.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4077","static/chunks/4077-c4828a2983f3aa2b.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","7526","static/chunks/7526-e76a2c2b549bf2d2.js","6554","static/chunks/6554-265013ca56622e1f.js","2678","static/chunks/app/(dashboard)/model-hub/page-0802bc3228446009.js"],"default",1] +3:I[30615,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","1994","static/chunks/1994-6637a121c9ee1602.js","7138","static/chunks/7138-5b134dc8ad670770.js","2068","static/chunks/2068-2c78bfc32dc0de5f.js","8565","static/chunks/8565-5c05f6bbb9d0662f.js","5869","static/chunks/5869-426268ba6ad0ce0c.js","2618","static/chunks/2618-062177b80fc4a38e.js","7906","static/chunks/7906-59ba450db59c8efa.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4077","static/chunks/4077-50cf2a28a79fdcd4.js","8049","static/chunks/8049-cb52b16664f13e28.js","7526","static/chunks/7526-da6b2857a3ca248d.js","3862","static/chunks/3862-064a3fb795c75b62.js","2678","static/chunks/app/(dashboard)/model-hub/page-1479dcb217587498.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["model-hub",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["model-hub",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","model-hub","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["model-hub",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["model-hub",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","model-hub","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/model-hub/index.html b/litellm/proxy/_experimental/out/model-hub/index.html new file mode 100644 index 00000000000..93af4d65b3a --- /dev/null +++ b/litellm/proxy/_experimental/out/model-hub/index.html @@ -0,0 +1 @@ +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/model_hub.html b/litellm/proxy/_experimental/out/model_hub.html deleted file mode 100644 index ab77be9c724..00000000000 --- a/litellm/proxy/_experimental/out/model_hub.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/model_hub.txt b/litellm/proxy/_experimental/out/model_hub.txt index 46ad9117f50..073bad4e99d 100644 --- a/litellm/proxy/_experimental/out/model_hub.txt +++ b/litellm/proxy/_experimental/out/model_hub.txt @@ -1,7 +1,7 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[52829,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","6894","static/chunks/6894-8c74216e23aa271e.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","3554","static/chunks/3554-f22a2e21673afd42.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","7526","static/chunks/7526-e76a2c2b549bf2d2.js","1418","static/chunks/app/model_hub/page-39babd7c1a6e991f.js"],"default",1] +3:I[52829,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","2068","static/chunks/2068-2c78bfc32dc0de5f.js","5869","static/chunks/5869-426268ba6ad0ce0c.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","7926","static/chunks/7926-108623e14caeb770.js","8049","static/chunks/8049-cb52b16664f13e28.js","7526","static/chunks/7526-da6b2857a3ca248d.js","1418","static/chunks/app/model_hub/page-92347d2021ca8580.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["model_hub",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["model_hub",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","model_hub","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$L6",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["model_hub",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["model_hub",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","model_hub","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$L6",null]]]] 6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/model_hub_table.html b/litellm/proxy/_experimental/out/model_hub_table.html deleted file mode 100644 index b5e0303f158..00000000000 --- a/litellm/proxy/_experimental/out/model_hub_table.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/model_hub_table.txt b/litellm/proxy/_experimental/out/model_hub_table.txt index 71da07ba0b4..8ccdde74088 100644 --- a/litellm/proxy/_experimental/out/model_hub_table.txt +++ b/litellm/proxy/_experimental/out/model_hub_table.txt @@ -1,7 +1,7 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[22775,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","7971","static/chunks/7971-76912e9c9a840367.js","6894","static/chunks/6894-8c74216e23aa271e.js","3705","static/chunks/3705-dde102fd596f74e8.js","3178","static/chunks/3178-47bc3b9e8cf9bf6c.js","2618","static/chunks/2618-062177b80fc4a38e.js","7906","static/chunks/7906-1b1cdd8da2773bb2.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4077","static/chunks/4077-c4828a2983f3aa2b.js","1623","static/chunks/1623-54c56cbe1afc3953.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","7526","static/chunks/7526-e76a2c2b549bf2d2.js","6554","static/chunks/6554-265013ca56622e1f.js","9025","static/chunks/app/model_hub_table/page-516d7511795e23d9.js"],"default",1] +3:I[22775,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","1994","static/chunks/1994-6637a121c9ee1602.js","7138","static/chunks/7138-5b134dc8ad670770.js","2068","static/chunks/2068-2c78bfc32dc0de5f.js","8565","static/chunks/8565-5c05f6bbb9d0662f.js","5869","static/chunks/5869-426268ba6ad0ce0c.js","2618","static/chunks/2618-062177b80fc4a38e.js","7906","static/chunks/7906-59ba450db59c8efa.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4077","static/chunks/4077-50cf2a28a79fdcd4.js","1623","static/chunks/1623-54c56cbe1afc3953.js","8049","static/chunks/8049-cb52b16664f13e28.js","7526","static/chunks/7526-da6b2857a3ca248d.js","3862","static/chunks/3862-064a3fb795c75b62.js","9025","static/chunks/app/model_hub_table/page-2ad344049541235f.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["model_hub_table",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["model_hub_table",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","model_hub_table","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$L6",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["model_hub_table",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["model_hub_table",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","model_hub_table","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$L6",null]]]] 6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/model_hub_table/index.html b/litellm/proxy/_experimental/out/model_hub_table/index.html new file mode 100644 index 00000000000..6c17bc92565 --- /dev/null +++ b/litellm/proxy/_experimental/out/model_hub_table/index.html @@ -0,0 +1 @@ +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/models-and-endpoints.html b/litellm/proxy/_experimental/out/models-and-endpoints.html deleted file mode 100644 index e30ff475df7..00000000000 --- a/litellm/proxy/_experimental/out/models-and-endpoints.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/models-and-endpoints.txt b/litellm/proxy/_experimental/out/models-and-endpoints.txt index be39e3b66b1..67b6a45ada6 100644 --- a/litellm/proxy/_experimental/out/models-and-endpoints.txt +++ b/litellm/proxy/_experimental/out/models-and-endpoints.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[6121,["1047","static/chunks/e228588e-635e9029d9d88215.js","1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","353","static/chunks/353-347e4836f09d94a0.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","7971","static/chunks/7971-76912e9c9a840367.js","6894","static/chunks/6894-8c74216e23aa271e.js","3705","static/chunks/3705-dde102fd596f74e8.js","3898","static/chunks/3898-fc3dbf5a964ea4ca.js","3178","static/chunks/3178-47bc3b9e8cf9bf6c.js","5319","static/chunks/5319-7f07d87ef011d5c9.js","1716","static/chunks/1716-1c0ba935a144e6ff.js","9967","static/chunks/9967-329bb618cc1c8902.js","6609","static/chunks/6609-707213b617f85369.js","2353","static/chunks/2353-c94748c0aac514ff.js","2618","static/chunks/2618-062177b80fc4a38e.js","3918","static/chunks/3918-942eadaf4103218b.js","1132","static/chunks/1132-d0fa0c9565944e8f.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5144","static/chunks/5144-ddfa7a8f89c5d465.js","9584","static/chunks/9584-4d5bef7e60cfea45.js","1658","static/chunks/1658-2c9554a5b3840812.js","1664","static/chunks/app/(dashboard)/models-and-endpoints/page-e9561bb2dd6ebb7b.js"],"default",1] +3:I[6121,["1047","static/chunks/e228588e-635e9029d9d88215.js","9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","2409","static/chunks/2409-e94c05c6f11bb939.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","353","static/chunks/353-e55516ea4730f9d4.js","1994","static/chunks/1994-6637a121c9ee1602.js","7138","static/chunks/7138-5b134dc8ad670770.js","7851","static/chunks/7851-c10cbe6fcac2f9d6.js","2068","static/chunks/2068-2c78bfc32dc0de5f.js","8565","static/chunks/8565-5c05f6bbb9d0662f.js","5869","static/chunks/5869-426268ba6ad0ce0c.js","5319","static/chunks/5319-5b2d4bf2dc450f99.js","5333","static/chunks/5333-1540faf81c7d7006.js","8582","static/chunks/8582-3a775364dbf07fa8.js","6609","static/chunks/6609-3e081758ffbe3786.js","2618","static/chunks/2618-062177b80fc4a38e.js","766","static/chunks/766-baf0336e8ba5c686.js","4306","static/chunks/4306-f891b96cf0ee333b.js","2820","static/chunks/2820-592c2b4ff874a913.js","8049","static/chunks/8049-cb52b16664f13e28.js","5144","static/chunks/5144-bbc18c43eade9aef.js","9584","static/chunks/9584-9d4fd7b3d6a7c9e7.js","9841","static/chunks/9841-721a173be76941d1.js","1664","static/chunks/app/(dashboard)/models-and-endpoints/page-b69988590beaa5c8.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["models-and-endpoints",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["models-and-endpoints",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","models-and-endpoints","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["models-and-endpoints",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["models-and-endpoints",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","models-and-endpoints","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/tools/mcp-servers.html b/litellm/proxy/_experimental/out/models-and-endpoints/index.html similarity index 58% rename from litellm/proxy/_experimental/out/tools/mcp-servers.html rename to litellm/proxy/_experimental/out/models-and-endpoints/index.html index 48f8117a8c7..d40187b4f42 100644 --- a/litellm/proxy/_experimental/out/tools/mcp-servers.html +++ b/litellm/proxy/_experimental/out/models-and-endpoints/index.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/onboarding.html b/litellm/proxy/_experimental/out/onboarding.html deleted file mode 100644 index 0a1c697f265..00000000000 --- a/litellm/proxy/_experimental/out/onboarding.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/onboarding.txt b/litellm/proxy/_experimental/out/onboarding.txt index 19f2f76c56e..d2b9d0d0299 100644 --- a/litellm/proxy/_experimental/out/onboarding.txt +++ b/litellm/proxy/_experimental/out/onboarding.txt @@ -1,7 +1,7 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[12011,["3665","static/chunks/3014691f-ba91873bc8fe3fad.js","1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","4865","static/chunks/4865-c1c0885a93c327fa.js","2901","static/chunks/2901-b2d9f739800f0159.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","8461","static/chunks/app/onboarding/page-a989f5336329736d.js"],"default",1] +3:I[12011,["3665","static/chunks/3014691f-ba91873bc8fe3fad.js","9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","4865","static/chunks/4865-c1c0885a93c327fa.js","2901","static/chunks/2901-0cdd0656eb7463d6.js","8049","static/chunks/8049-cb52b16664f13e28.js","8461","static/chunks/app/onboarding/page-17ecf5bf068f8157.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["onboarding",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["onboarding",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","onboarding","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$L6",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["onboarding",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["onboarding",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","onboarding","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$L6",null]]]] 6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/organizations.html b/litellm/proxy/_experimental/out/organizations.html deleted file mode 100644 index 6b758e0d2fc..00000000000 --- a/litellm/proxy/_experimental/out/organizations.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/organizations.txt b/litellm/proxy/_experimental/out/organizations.txt index 0621b3b7ebe..1ed3b8d0b9f 100644 --- a/litellm/proxy/_experimental/out/organizations.txt +++ b/litellm/proxy/_experimental/out/organizations.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[57616,["1047","static/chunks/e228588e-635e9029d9d88215.js","1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","353","static/chunks/353-347e4836f09d94a0.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","7971","static/chunks/7971-76912e9c9a840367.js","3705","static/chunks/3705-dde102fd596f74e8.js","3898","static/chunks/3898-fc3dbf5a964ea4ca.js","3178","static/chunks/3178-47bc3b9e8cf9bf6c.js","5319","static/chunks/5319-7f07d87ef011d5c9.js","1716","static/chunks/1716-1c0ba935a144e6ff.js","9967","static/chunks/9967-329bb618cc1c8902.js","6609","static/chunks/6609-707213b617f85369.js","2353","static/chunks/2353-c94748c0aac514ff.js","2618","static/chunks/2618-062177b80fc4a38e.js","7967","static/chunks/7967-1ac5097c3d83016f.js","7471","static/chunks/7471-f852accc26f14f8c.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5144","static/chunks/5144-ddfa7a8f89c5d465.js","7914","static/chunks/7914-25af99af34bee64b.js","1098","static/chunks/1098-a1702da59647cf14.js","5706","static/chunks/5706-b92e3cca4b167e71.js","6459","static/chunks/app/(dashboard)/organizations/page-bb7939b01e416574.js"],"default",1] +3:I[57616,["1047","static/chunks/e228588e-635e9029d9d88215.js","9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","2409","static/chunks/2409-e94c05c6f11bb939.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","353","static/chunks/353-e55516ea4730f9d4.js","1994","static/chunks/1994-6637a121c9ee1602.js","7138","static/chunks/7138-5b134dc8ad670770.js","7851","static/chunks/7851-c10cbe6fcac2f9d6.js","8565","static/chunks/8565-5c05f6bbb9d0662f.js","5319","static/chunks/5319-5b2d4bf2dc450f99.js","5333","static/chunks/5333-1540faf81c7d7006.js","8582","static/chunks/8582-3a775364dbf07fa8.js","6609","static/chunks/6609-3e081758ffbe3786.js","2618","static/chunks/2618-062177b80fc4a38e.js","4105","static/chunks/4105-9c3c0ee7c494102f.js","7688","static/chunks/7688-ca173ea41812cf94.js","8049","static/chunks/8049-cb52b16664f13e28.js","5144","static/chunks/5144-bbc18c43eade9aef.js","2202","static/chunks/2202-a83ad035a17401aa.js","1098","static/chunks/1098-c3e95c9684ff5e95.js","5706","static/chunks/5706-1e314cef9ea5c5d6.js","6459","static/chunks/app/(dashboard)/organizations/page-56a03e123f452d60.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["organizations",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["organizations",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","organizations","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["organizations",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["organizations",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","organizations","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/organizations/index.html b/litellm/proxy/_experimental/out/organizations/index.html new file mode 100644 index 00000000000..1f796d6a081 --- /dev/null +++ b/litellm/proxy/_experimental/out/organizations/index.html @@ -0,0 +1 @@ +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/playground.html b/litellm/proxy/_experimental/out/playground.html deleted file mode 100644 index 1ba0e0e82cb..00000000000 --- a/litellm/proxy/_experimental/out/playground.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/playground.txt b/litellm/proxy/_experimental/out/playground.txt index 193f3ae63d9..20404ba3cbd 100644 --- a/litellm/proxy/_experimental/out/playground.txt +++ b/litellm/proxy/_experimental/out/playground.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[69039,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","353","static/chunks/353-347e4836f09d94a0.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","7971","static/chunks/7971-76912e9c9a840367.js","3178","static/chunks/3178-47bc3b9e8cf9bf6c.js","5319","static/chunks/5319-7f07d87ef011d5c9.js","7906","static/chunks/7906-1b1cdd8da2773bb2.js","4851","static/chunks/4851-0dc9f6cfeabb43d0.js","816","static/chunks/816-924f34bbf6b36a05.js","7271","static/chunks/7271-46e4c11ee6b0a4d6.js","8205","static/chunks/8205-66bf13815010afdb.js","2344","static/chunks/2344-905d7ecc9d0c6724.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5992","static/chunks/5992-243bba762148af9b.js","9039","static/chunks/9039-2037889778daf211.js","3368","static/chunks/app/(dashboard)/playground/page-80b8f3245f6936d1.js"],"default",1] +3:I[69039,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","2409","static/chunks/2409-e94c05c6f11bb939.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","353","static/chunks/353-e55516ea4730f9d4.js","1994","static/chunks/1994-6637a121c9ee1602.js","8565","static/chunks/8565-5c05f6bbb9d0662f.js","5319","static/chunks/5319-5b2d4bf2dc450f99.js","7906","static/chunks/7906-59ba450db59c8efa.js","816","static/chunks/816-37c57b39f4e7ece1.js","7271","static/chunks/7271-46e4c11ee6b0a4d6.js","766","static/chunks/766-baf0336e8ba5c686.js","3567","static/chunks/3567-9a29feedd7b63950.js","8529","static/chunks/8529-6b66d5dba2148164.js","8049","static/chunks/8049-cb52b16664f13e28.js","5992","static/chunks/5992-287cec06808c74ae.js","9039","static/chunks/9039-e44ff08ca4f37a12.js","3368","static/chunks/app/(dashboard)/playground/page-fc3dff494dc4db08.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["playground",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["playground",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","playground","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["playground",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["playground",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","playground","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/playground/index.html b/litellm/proxy/_experimental/out/playground/index.html new file mode 100644 index 00000000000..11af2b88fad --- /dev/null +++ b/litellm/proxy/_experimental/out/playground/index.html @@ -0,0 +1 @@ +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/policies.html b/litellm/proxy/_experimental/out/policies.html deleted file mode 100644 index 41152d0d540..00000000000 --- a/litellm/proxy/_experimental/out/policies.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/policies.txt b/litellm/proxy/_experimental/out/policies.txt deleted file mode 100644 index 8e34d3ee527..00000000000 --- a/litellm/proxy/_experimental/out/policies.txt +++ /dev/null @@ -1,13 +0,0 @@ -2:I[19107,[],"ClientPageRoot"] -3:I[56744,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","353","static/chunks/353-347e4836f09d94a0.js","6894","static/chunks/6894-8c74216e23aa271e.js","3898","static/chunks/3898-fc3dbf5a964ea4ca.js","9967","static/chunks/9967-329bb618cc1c8902.js","6276","static/chunks/6276-841bc8541051bc36.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","9120","static/chunks/9120-dc2d8129a3d2175b.js","6649","static/chunks/app/(dashboard)/policies/page-33090e865d27d3fa.js"],"default",1] -4:I[4707,[],""] -5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] -7:{} -8:{"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"} -9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} -a:{"display":"inline-block"} -b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["policies",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["policies",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","policies","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] -c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] -1:null diff --git a/litellm/proxy/_experimental/out/settings/admin-settings.html b/litellm/proxy/_experimental/out/settings/admin-settings.html deleted file mode 100644 index 15fea0c7026..00000000000 --- a/litellm/proxy/_experimental/out/settings/admin-settings.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/settings/admin-settings.txt b/litellm/proxy/_experimental/out/settings/admin-settings.txt index 6daeae33747..864f93c5ade 100644 --- a/litellm/proxy/_experimental/out/settings/admin-settings.txt +++ b/litellm/proxy/_experimental/out/settings/admin-settings.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[8786,["1047","static/chunks/e228588e-635e9029d9d88215.js","1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","353","static/chunks/353-347e4836f09d94a0.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","7971","static/chunks/7971-76912e9c9a840367.js","3705","static/chunks/3705-dde102fd596f74e8.js","3898","static/chunks/3898-fc3dbf5a964ea4ca.js","1716","static/chunks/1716-1c0ba935a144e6ff.js","9967","static/chunks/9967-329bb618cc1c8902.js","6609","static/chunks/6609-707213b617f85369.js","2353","static/chunks/2353-c94748c0aac514ff.js","5945","static/chunks/5945-93803bbcb1abfaaf.js","4851","static/chunks/4851-0dc9f6cfeabb43d0.js","1717","static/chunks/1717-bb1b888f6ccc52d6.js","4750","static/chunks/4750-3aeac3fa94708e1c.js","7572","static/chunks/7572-64b63fb5f5a45de2.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","1789","static/chunks/1789-a56ee544e60cd01d.js","8958","static/chunks/app/(dashboard)/settings/admin-settings/page-d54333a842352184.js"],"default",1] +3:I[8786,["1047","static/chunks/e228588e-635e9029d9d88215.js","9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","2409","static/chunks/2409-e94c05c6f11bb939.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","353","static/chunks/353-e55516ea4730f9d4.js","1994","static/chunks/1994-6637a121c9ee1602.js","7138","static/chunks/7138-5b134dc8ad670770.js","7851","static/chunks/7851-c10cbe6fcac2f9d6.js","5869","static/chunks/5869-426268ba6ad0ce0c.js","5333","static/chunks/5333-1540faf81c7d7006.js","8582","static/chunks/8582-3a775364dbf07fa8.js","6609","static/chunks/6609-3e081758ffbe3786.js","5945","static/chunks/5945-8b3b7713d7f416a2.js","1128","static/chunks/1128-64fa4a41ccaf67ea.js","8049","static/chunks/8049-cb52b16664f13e28.js","9818","static/chunks/9818-6f03d7efd4fb8533.js","8958","static/chunks/app/(dashboard)/settings/admin-settings/page-746658933a633902.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["settings",{"children":["admin-settings",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["settings",{"children":["admin-settings",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","settings","children","admin-settings","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","settings","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["settings",{"children":["admin-settings",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["settings",{"children":["admin-settings",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","settings","children","admin-settings","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","settings","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/settings/admin-settings/index.html b/litellm/proxy/_experimental/out/settings/admin-settings/index.html new file mode 100644 index 00000000000..b65ac01d615 --- /dev/null +++ b/litellm/proxy/_experimental/out/settings/admin-settings/index.html @@ -0,0 +1 @@ +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/settings/logging-and-alerts.txt b/litellm/proxy/_experimental/out/settings/logging-and-alerts.txt index cbd1b39ce50..7deb3733c15 100644 --- a/litellm/proxy/_experimental/out/settings/logging-and-alerts.txt +++ b/litellm/proxy/_experimental/out/settings/logging-and-alerts.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[72719,["1047","static/chunks/e228588e-635e9029d9d88215.js","1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","353","static/chunks/353-347e4836f09d94a0.js","7971","static/chunks/7971-76912e9c9a840367.js","3705","static/chunks/3705-dde102fd596f74e8.js","3898","static/chunks/3898-fc3dbf5a964ea4ca.js","1716","static/chunks/1716-1c0ba935a144e6ff.js","9967","static/chunks/9967-329bb618cc1c8902.js","6609","static/chunks/6609-707213b617f85369.js","2353","static/chunks/2353-c94748c0aac514ff.js","2618","static/chunks/2618-062177b80fc4a38e.js","5945","static/chunks/5945-93803bbcb1abfaaf.js","9028","static/chunks/9028-d6bbee9a46c36af2.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","9264","static/chunks/9264-e3d8a8136b3fe80a.js","2445","static/chunks/app/(dashboard)/settings/logging-and-alerts/page-e83525d261d7c7f9.js"],"default",1] +3:I[72719,["1047","static/chunks/e228588e-635e9029d9d88215.js","9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","2409","static/chunks/2409-e94c05c6f11bb939.js","3367","static/chunks/3367-58830187e9e5b9fa.js","353","static/chunks/353-e55516ea4730f9d4.js","1994","static/chunks/1994-6637a121c9ee1602.js","7138","static/chunks/7138-5b134dc8ad670770.js","7851","static/chunks/7851-c10cbe6fcac2f9d6.js","5869","static/chunks/5869-426268ba6ad0ce0c.js","5333","static/chunks/5333-1540faf81c7d7006.js","8582","static/chunks/8582-3a775364dbf07fa8.js","6609","static/chunks/6609-3e081758ffbe3786.js","2618","static/chunks/2618-062177b80fc4a38e.js","5945","static/chunks/5945-8b3b7713d7f416a2.js","1414","static/chunks/1414-2770d1155b664522.js","8049","static/chunks/8049-cb52b16664f13e28.js","9264","static/chunks/9264-fd8ab51d702e9535.js","2445","static/chunks/app/(dashboard)/settings/logging-and-alerts/page-e3df74ef5ac0dcd5.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["settings",{"children":["logging-and-alerts",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["settings",{"children":["logging-and-alerts",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","settings","children","logging-and-alerts","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","settings","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["settings",{"children":["logging-and-alerts",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["settings",{"children":["logging-and-alerts",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","settings","children","logging-and-alerts","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","settings","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/settings/logging-and-alerts.html b/litellm/proxy/_experimental/out/settings/logging-and-alerts/index.html similarity index 79% rename from litellm/proxy/_experimental/out/settings/logging-and-alerts.html rename to litellm/proxy/_experimental/out/settings/logging-and-alerts/index.html index f5c0ea154fa..5022910542b 100644 --- a/litellm/proxy/_experimental/out/settings/logging-and-alerts.html +++ b/litellm/proxy/_experimental/out/settings/logging-and-alerts/index.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/settings/router-settings.txt b/litellm/proxy/_experimental/out/settings/router-settings.txt index 163699c2f8a..7c6456fa090 100644 --- a/litellm/proxy/_experimental/out/settings/router-settings.txt +++ b/litellm/proxy/_experimental/out/settings/router-settings.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[14809,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","3898","static/chunks/3898-fc3dbf5a964ea4ca.js","7271","static/chunks/7271-46e4c11ee6b0a4d6.js","2731","static/chunks/2731-b2ffcaeb9eabaa23.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","8021","static/chunks/app/(dashboard)/settings/router-settings/page-46ff6edf1109f13d.js"],"default",1] +3:I[14809,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","2409","static/chunks/2409-e94c05c6f11bb939.js","7851","static/chunks/7851-c10cbe6fcac2f9d6.js","7271","static/chunks/7271-46e4c11ee6b0a4d6.js","2500","static/chunks/2500-811f2612ec5f6830.js","8049","static/chunks/8049-cb52b16664f13e28.js","5695","static/chunks/5695-dbbcbf2da21d2bab.js","8021","static/chunks/app/(dashboard)/settings/router-settings/page-ffa3245ebcbbc02a.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["settings",{"children":["router-settings",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["settings",{"children":["router-settings",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","settings","children","router-settings","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","settings","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["settings",{"children":["router-settings",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["settings",{"children":["router-settings",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","settings","children","router-settings","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","settings","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/settings/router-settings.html b/litellm/proxy/_experimental/out/settings/router-settings/index.html similarity index 82% rename from litellm/proxy/_experimental/out/settings/router-settings.html rename to litellm/proxy/_experimental/out/settings/router-settings/index.html index a226e1270b7..83492c87c91 100644 --- a/litellm/proxy/_experimental/out/settings/router-settings.html +++ b/litellm/proxy/_experimental/out/settings/router-settings/index.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/settings/ui-theme.txt b/litellm/proxy/_experimental/out/settings/ui-theme.txt index c59a8cb81b0..c3f61d9e304 100644 --- a/litellm/proxy/_experimental/out/settings/ui-theme.txt +++ b/litellm/proxy/_experimental/out/settings/ui-theme.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[8719,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","3117","static/chunks/app/(dashboard)/settings/ui-theme/page-b0efda16443e630f.js"],"default",1] +3:I[8719,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","8049","static/chunks/8049-cb52b16664f13e28.js","3117","static/chunks/app/(dashboard)/settings/ui-theme/page-d833946961b065a5.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["settings",{"children":["ui-theme",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["settings",{"children":["ui-theme",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","settings","children","ui-theme","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","settings","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["settings",{"children":["ui-theme",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["settings",{"children":["ui-theme",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","settings","children","ui-theme","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","settings","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/settings/ui-theme.html b/litellm/proxy/_experimental/out/settings/ui-theme/index.html similarity index 85% rename from litellm/proxy/_experimental/out/settings/ui-theme.html rename to litellm/proxy/_experimental/out/settings/ui-theme/index.html index 4525c1ee502..fc900017b3a 100644 --- a/litellm/proxy/_experimental/out/settings/ui-theme.html +++ b/litellm/proxy/_experimental/out/settings/ui-theme/index.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/teams.html b/litellm/proxy/_experimental/out/teams.html deleted file mode 100644 index a1cddbef08f..00000000000 --- a/litellm/proxy/_experimental/out/teams.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/teams.txt b/litellm/proxy/_experimental/out/teams.txt index 16ad8b48843..297ba5abe36 100644 --- a/litellm/proxy/_experimental/out/teams.txt +++ b/litellm/proxy/_experimental/out/teams.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[67578,["1047","static/chunks/e228588e-635e9029d9d88215.js","1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","353","static/chunks/353-347e4836f09d94a0.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","7971","static/chunks/7971-76912e9c9a840367.js","3898","static/chunks/3898-fc3dbf5a964ea4ca.js","2353","static/chunks/2353-c94748c0aac514ff.js","2618","static/chunks/2618-062177b80fc4a38e.js","1717","static/chunks/1717-bb1b888f6ccc52d6.js","4509","static/chunks/4509-5bbcd014724651a9.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5144","static/chunks/5144-ddfa7a8f89c5d465.js","9584","static/chunks/9584-4d5bef7e60cfea45.js","5706","static/chunks/5706-b92e3cca4b167e71.js","9483","static/chunks/app/(dashboard)/teams/page-49b94da614a653ba.js"],"default",1] +3:I[67578,["1047","static/chunks/e228588e-635e9029d9d88215.js","9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","2409","static/chunks/2409-e94c05c6f11bb939.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","353","static/chunks/353-e55516ea4730f9d4.js","1994","static/chunks/1994-6637a121c9ee1602.js","7851","static/chunks/7851-c10cbe6fcac2f9d6.js","5333","static/chunks/5333-1540faf81c7d7006.js","2618","static/chunks/2618-062177b80fc4a38e.js","7688","static/chunks/7688-ca173ea41812cf94.js","3507","static/chunks/3507-14fb4e6cd377d7da.js","8049","static/chunks/8049-cb52b16664f13e28.js","5144","static/chunks/5144-bbc18c43eade9aef.js","9584","static/chunks/9584-9d4fd7b3d6a7c9e7.js","5706","static/chunks/5706-1e314cef9ea5c5d6.js","9483","static/chunks/app/(dashboard)/teams/page-8d1a71afa9e9ff16.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["teams",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["teams",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","teams","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["teams",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["teams",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","teams","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/teams/index.html b/litellm/proxy/_experimental/out/teams/index.html new file mode 100644 index 00000000000..61c6f0904bd --- /dev/null +++ b/litellm/proxy/_experimental/out/teams/index.html @@ -0,0 +1 @@ +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/test-key.html b/litellm/proxy/_experimental/out/test-key.html deleted file mode 100644 index 1b8391a6240..00000000000 --- a/litellm/proxy/_experimental/out/test-key.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/test-key.txt b/litellm/proxy/_experimental/out/test-key.txt index 226db93be5f..a8d523ca50e 100644 --- a/litellm/proxy/_experimental/out/test-key.txt +++ b/litellm/proxy/_experimental/out/test-key.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[38511,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2409","static/chunks/2409-43d87f56841bda3f.js","353","static/chunks/353-347e4836f09d94a0.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","7971","static/chunks/7971-76912e9c9a840367.js","3178","static/chunks/3178-47bc3b9e8cf9bf6c.js","5319","static/chunks/5319-7f07d87ef011d5c9.js","7906","static/chunks/7906-1b1cdd8da2773bb2.js","4851","static/chunks/4851-0dc9f6cfeabb43d0.js","816","static/chunks/816-924f34bbf6b36a05.js","7271","static/chunks/7271-46e4c11ee6b0a4d6.js","8205","static/chunks/8205-66bf13815010afdb.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5992","static/chunks/5992-243bba762148af9b.js","2322","static/chunks/app/(dashboard)/test-key/page-afaa514ad2d69fe0.js"],"default",1] +3:I[38511,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","2409","static/chunks/2409-e94c05c6f11bb939.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","353","static/chunks/353-e55516ea4730f9d4.js","1994","static/chunks/1994-6637a121c9ee1602.js","8565","static/chunks/8565-5c05f6bbb9d0662f.js","5319","static/chunks/5319-5b2d4bf2dc450f99.js","7906","static/chunks/7906-59ba450db59c8efa.js","816","static/chunks/816-37c57b39f4e7ece1.js","7271","static/chunks/7271-46e4c11ee6b0a4d6.js","766","static/chunks/766-baf0336e8ba5c686.js","3567","static/chunks/3567-9a29feedd7b63950.js","8049","static/chunks/8049-cb52b16664f13e28.js","5992","static/chunks/5992-287cec06808c74ae.js","2322","static/chunks/app/(dashboard)/test-key/page-63cd64b722408984.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["test-key",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["test-key",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","test-key","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["test-key",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["test-key",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","test-key","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/test-key/index.html b/litellm/proxy/_experimental/out/test-key/index.html new file mode 100644 index 00000000000..ce6673715e2 --- /dev/null +++ b/litellm/proxy/_experimental/out/test-key/index.html @@ -0,0 +1 @@ +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/tools/mcp-servers.txt b/litellm/proxy/_experimental/out/tools/mcp-servers.txt index 8872f303836..f08abc999ba 100644 --- a/litellm/proxy/_experimental/out/tools/mcp-servers.txt +++ b/litellm/proxy/_experimental/out/tools/mcp-servers.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[45045,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","353","static/chunks/353-347e4836f09d94a0.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","7971","static/chunks/7971-76912e9c9a840367.js","6894","static/chunks/6894-8c74216e23aa271e.js","3898","static/chunks/3898-fc3dbf5a964ea4ca.js","5945","static/chunks/5945-93803bbcb1abfaaf.js","4851","static/chunks/4851-0dc9f6cfeabb43d0.js","1623","static/chunks/1623-54c56cbe1afc3953.js","8358","static/chunks/8358-0821a1ee08903103.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5276","static/chunks/5276-8bb0b1938bb0f21f.js","6940","static/chunks/app/(dashboard)/tools/mcp-servers/page-59e552ea419ac5b6.js"],"default",1] +3:I[45045,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","2409","static/chunks/2409-e94c05c6f11bb939.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","353","static/chunks/353-e55516ea4730f9d4.js","1994","static/chunks/1994-6637a121c9ee1602.js","7851","static/chunks/7851-c10cbe6fcac2f9d6.js","2068","static/chunks/2068-2c78bfc32dc0de5f.js","5869","static/chunks/5869-426268ba6ad0ce0c.js","5945","static/chunks/5945-8b3b7713d7f416a2.js","7688","static/chunks/7688-ca173ea41812cf94.js","1623","static/chunks/1623-54c56cbe1afc3953.js","4559","static/chunks/4559-52ca85b2d8893149.js","8049","static/chunks/8049-cb52b16664f13e28.js","6537","static/chunks/6537-f70f2c4278e93458.js","6940","static/chunks/app/(dashboard)/tools/mcp-servers/page-7dd2ea6f1433d41f.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["tools",{"children":["mcp-servers",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["tools",{"children":["mcp-servers",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","tools","children","mcp-servers","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","tools","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["tools",{"children":["mcp-servers",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["tools",{"children":["mcp-servers",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","tools","children","mcp-servers","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","tools","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/tools/mcp-servers/index.html b/litellm/proxy/_experimental/out/tools/mcp-servers/index.html new file mode 100644 index 00000000000..cdea14b1384 --- /dev/null +++ b/litellm/proxy/_experimental/out/tools/mcp-servers/index.html @@ -0,0 +1 @@ +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/tools/vector-stores.html b/litellm/proxy/_experimental/out/tools/vector-stores.html deleted file mode 100644 index fee597af070..00000000000 --- a/litellm/proxy/_experimental/out/tools/vector-stores.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/tools/vector-stores.txt b/litellm/proxy/_experimental/out/tools/vector-stores.txt index da3287651f5..3190c71dd88 100644 --- a/litellm/proxy/_experimental/out/tools/vector-stores.txt +++ b/litellm/proxy/_experimental/out/tools/vector-stores.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[77438,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","353","static/chunks/353-347e4836f09d94a0.js","7971","static/chunks/7971-76912e9c9a840367.js","6894","static/chunks/6894-8c74216e23aa271e.js","3705","static/chunks/3705-dde102fd596f74e8.js","3898","static/chunks/3898-fc3dbf5a964ea4ca.js","3178","static/chunks/3178-47bc3b9e8cf9bf6c.js","5319","static/chunks/5319-7f07d87ef011d5c9.js","1716","static/chunks/1716-1c0ba935a144e6ff.js","9967","static/chunks/9967-329bb618cc1c8902.js","6609","static/chunks/6609-707213b617f85369.js","2618","static/chunks/2618-062177b80fc4a38e.js","5945","static/chunks/5945-93803bbcb1abfaaf.js","7451","static/chunks/7451-a657252554fd3e24.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","6213","static/chunks/6213-20bb5f06094f361d.js","6248","static/chunks/app/(dashboard)/tools/vector-stores/page-414136a92d1a02e9.js"],"default",1] +3:I[77438,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","2409","static/chunks/2409-e94c05c6f11bb939.js","3367","static/chunks/3367-58830187e9e5b9fa.js","353","static/chunks/353-e55516ea4730f9d4.js","7851","static/chunks/7851-c10cbe6fcac2f9d6.js","2068","static/chunks/2068-2c78bfc32dc0de5f.js","5869","static/chunks/5869-426268ba6ad0ce0c.js","2618","static/chunks/2618-062177b80fc4a38e.js","5945","static/chunks/5945-8b3b7713d7f416a2.js","6285","static/chunks/6285-68f82c874b184eba.js","8049","static/chunks/8049-cb52b16664f13e28.js","9140","static/chunks/9140-09af618948244b82.js","6248","static/chunks/app/(dashboard)/tools/vector-stores/page-0f618cc2d6cae794.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["tools",{"children":["vector-stores",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["tools",{"children":["vector-stores",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","tools","children","vector-stores","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","tools","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["tools",{"children":["vector-stores",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["tools",{"children":["vector-stores",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","tools","children","vector-stores","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","tools","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/tools/vector-stores/index.html b/litellm/proxy/_experimental/out/tools/vector-stores/index.html new file mode 100644 index 00000000000..b0581c82e24 --- /dev/null +++ b/litellm/proxy/_experimental/out/tools/vector-stores/index.html @@ -0,0 +1 @@ +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/usage.html b/litellm/proxy/_experimental/out/usage.html deleted file mode 100644 index 5efe25b8656..00000000000 --- a/litellm/proxy/_experimental/out/usage.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/usage.txt b/litellm/proxy/_experimental/out/usage.txt index 2094350a70c..0fc0c9e9f3c 100644 --- a/litellm/proxy/_experimental/out/usage.txt +++ b/litellm/proxy/_experimental/out/usage.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[26661,["1047","static/chunks/e228588e-635e9029d9d88215.js","6990","static/chunks/13b76428-e1bf383848c17260.js","1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","353","static/chunks/353-347e4836f09d94a0.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","7971","static/chunks/7971-76912e9c9a840367.js","6894","static/chunks/6894-8c74216e23aa271e.js","3705","static/chunks/3705-dde102fd596f74e8.js","3898","static/chunks/3898-fc3dbf5a964ea4ca.js","3178","static/chunks/3178-47bc3b9e8cf9bf6c.js","5319","static/chunks/5319-7f07d87ef011d5c9.js","1716","static/chunks/1716-1c0ba935a144e6ff.js","9967","static/chunks/9967-329bb618cc1c8902.js","6609","static/chunks/6609-707213b617f85369.js","2353","static/chunks/2353-c94748c0aac514ff.js","2618","static/chunks/2618-062177b80fc4a38e.js","7967","static/chunks/7967-1ac5097c3d83016f.js","1108","static/chunks/1108-8b678b0704cb239b.js","5238","static/chunks/5238-3fa69435be59fb79.js","5105","static/chunks/5105-ea8985e1ca9e840a.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5144","static/chunks/5144-ddfa7a8f89c5d465.js","7914","static/chunks/7914-25af99af34bee64b.js","1098","static/chunks/1098-a1702da59647cf14.js","665","static/chunks/665-05a55da381817c0d.js","292","static/chunks/292-7bd148a17bc0a05b.js","4746","static/chunks/app/(dashboard)/usage/page-1b951af48fc11bd9.js"],"default",1] +3:I[26661,["1047","static/chunks/e228588e-635e9029d9d88215.js","6990","static/chunks/13b76428-e1bf383848c17260.js","9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","2409","static/chunks/2409-e94c05c6f11bb939.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","353","static/chunks/353-e55516ea4730f9d4.js","1994","static/chunks/1994-6637a121c9ee1602.js","7138","static/chunks/7138-5b134dc8ad670770.js","7851","static/chunks/7851-c10cbe6fcac2f9d6.js","2068","static/chunks/2068-2c78bfc32dc0de5f.js","8565","static/chunks/8565-5c05f6bbb9d0662f.js","5319","static/chunks/5319-5b2d4bf2dc450f99.js","5333","static/chunks/5333-1540faf81c7d7006.js","8582","static/chunks/8582-3a775364dbf07fa8.js","6609","static/chunks/6609-3e081758ffbe3786.js","2618","static/chunks/2618-062177b80fc4a38e.js","4105","static/chunks/4105-9c3c0ee7c494102f.js","1108","static/chunks/1108-c2d0c742b6e72436.js","2227","static/chunks/2227-5ae3f36b0a81c5b4.js","5105","static/chunks/5105-2998cbe1c9fc8ee4.js","8049","static/chunks/8049-cb52b16664f13e28.js","5144","static/chunks/5144-bbc18c43eade9aef.js","2202","static/chunks/2202-a83ad035a17401aa.js","1098","static/chunks/1098-c3e95c9684ff5e95.js","665","static/chunks/665-d94073042ee5b874.js","292","static/chunks/292-aaba6c4e7c8d416d.js","4746","static/chunks/app/(dashboard)/usage/page-d7532f354d44803b.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["usage",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["usage",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","usage","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["usage",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["usage",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","usage","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/experimental/prompts.html b/litellm/proxy/_experimental/out/usage/index.html similarity index 57% rename from litellm/proxy/_experimental/out/experimental/prompts.html rename to litellm/proxy/_experimental/out/usage/index.html index 3b03134c502..2bda8f96f42 100644 --- a/litellm/proxy/_experimental/out/experimental/prompts.html +++ b/litellm/proxy/_experimental/out/usage/index.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/users.txt b/litellm/proxy/_experimental/out/users.txt index ef13ebad116..dbc69ced42f 100644 --- a/litellm/proxy/_experimental/out/users.txt +++ b/litellm/proxy/_experimental/out/users.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[87654,["1047","static/chunks/e228588e-635e9029d9d88215.js","1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","353","static/chunks/353-347e4836f09d94a0.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","7971","static/chunks/7971-76912e9c9a840367.js","6894","static/chunks/6894-8c74216e23aa271e.js","3705","static/chunks/3705-dde102fd596f74e8.js","3898","static/chunks/3898-fc3dbf5a964ea4ca.js","3178","static/chunks/3178-47bc3b9e8cf9bf6c.js","5319","static/chunks/5319-7f07d87ef011d5c9.js","1716","static/chunks/1716-1c0ba935a144e6ff.js","9967","static/chunks/9967-329bb618cc1c8902.js","6609","static/chunks/6609-707213b617f85369.js","2353","static/chunks/2353-c94748c0aac514ff.js","2618","static/chunks/2618-062177b80fc4a38e.js","7967","static/chunks/7967-1ac5097c3d83016f.js","1717","static/chunks/1717-bb1b888f6ccc52d6.js","4951","static/chunks/4951-59d280e876cbbf1f.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","7914","static/chunks/7914-25af99af34bee64b.js","2318","static/chunks/2318-b8f043257a4eca15.js","7297","static/chunks/app/(dashboard)/users/page-0ba6bd2b4262da93.js"],"default",1] +3:I[87654,["1047","static/chunks/e228588e-635e9029d9d88215.js","9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","2409","static/chunks/2409-e94c05c6f11bb939.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","353","static/chunks/353-e55516ea4730f9d4.js","1994","static/chunks/1994-6637a121c9ee1602.js","7138","static/chunks/7138-5b134dc8ad670770.js","7851","static/chunks/7851-c10cbe6fcac2f9d6.js","2068","static/chunks/2068-2c78bfc32dc0de5f.js","8565","static/chunks/8565-5c05f6bbb9d0662f.js","5869","static/chunks/5869-426268ba6ad0ce0c.js","5319","static/chunks/5319-5b2d4bf2dc450f99.js","5333","static/chunks/5333-1540faf81c7d7006.js","8582","static/chunks/8582-3a775364dbf07fa8.js","6609","static/chunks/6609-3e081758ffbe3786.js","2618","static/chunks/2618-062177b80fc4a38e.js","4105","static/chunks/4105-9c3c0ee7c494102f.js","4306","static/chunks/4306-f891b96cf0ee333b.js","8014","static/chunks/8014-d6138fce46bba1e2.js","8049","static/chunks/8049-cb52b16664f13e28.js","2202","static/chunks/2202-a83ad035a17401aa.js","6653","static/chunks/6653-e61fdc06093fc0a8.js","7297","static/chunks/app/(dashboard)/users/page-6d3643cef6c068ee.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["users",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["users",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","users","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["users",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["users",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","users","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/users.html b/litellm/proxy/_experimental/out/users/index.html similarity index 74% rename from litellm/proxy/_experimental/out/users.html rename to litellm/proxy/_experimental/out/users/index.html index 7cfa2a0a177..a00c0301c08 100644 --- a/litellm/proxy/_experimental/out/users.html +++ b/litellm/proxy/_experimental/out/users/index.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/virtual-keys.html b/litellm/proxy/_experimental/out/virtual-keys.html deleted file mode 100644 index bc6886473e4..00000000000 --- a/litellm/proxy/_experimental/out/virtual-keys.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/virtual-keys.txt b/litellm/proxy/_experimental/out/virtual-keys.txt index 6f9c260a63c..15c9de7b52a 100644 --- a/litellm/proxy/_experimental/out/virtual-keys.txt +++ b/litellm/proxy/_experimental/out/virtual-keys.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[98441,["1047","static/chunks/e228588e-635e9029d9d88215.js","3665","static/chunks/3014691f-ba91873bc8fe3fad.js","1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","353","static/chunks/353-347e4836f09d94a0.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","7971","static/chunks/7971-76912e9c9a840367.js","6894","static/chunks/6894-8c74216e23aa271e.js","3705","static/chunks/3705-dde102fd596f74e8.js","3898","static/chunks/3898-fc3dbf5a964ea4ca.js","3178","static/chunks/3178-47bc3b9e8cf9bf6c.js","5319","static/chunks/5319-7f07d87ef011d5c9.js","1716","static/chunks/1716-1c0ba935a144e6ff.js","9967","static/chunks/9967-329bb618cc1c8902.js","6609","static/chunks/6609-707213b617f85369.js","2353","static/chunks/2353-c94748c0aac514ff.js","7967","static/chunks/7967-1ac5097c3d83016f.js","5767","static/chunks/5767-b9e6413b33909bd8.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5144","static/chunks/5144-ddfa7a8f89c5d465.js","7914","static/chunks/7914-25af99af34bee64b.js","1098","static/chunks/1098-a1702da59647cf14.js","665","static/chunks/665-05a55da381817c0d.js","5975","static/chunks/5975-60599e8984464729.js","7049","static/chunks/app/(dashboard)/virtual-keys/page-a6a4dc040440802a.js"],"default",1] +3:I[98441,["1047","static/chunks/e228588e-635e9029d9d88215.js","3665","static/chunks/3014691f-ba91873bc8fe3fad.js","9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","2409","static/chunks/2409-e94c05c6f11bb939.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","353","static/chunks/353-e55516ea4730f9d4.js","1994","static/chunks/1994-6637a121c9ee1602.js","7138","static/chunks/7138-5b134dc8ad670770.js","7851","static/chunks/7851-c10cbe6fcac2f9d6.js","2068","static/chunks/2068-2c78bfc32dc0de5f.js","8565","static/chunks/8565-5c05f6bbb9d0662f.js","5319","static/chunks/5319-5b2d4bf2dc450f99.js","5333","static/chunks/5333-1540faf81c7d7006.js","8582","static/chunks/8582-3a775364dbf07fa8.js","6609","static/chunks/6609-3e081758ffbe3786.js","4105","static/chunks/4105-9c3c0ee7c494102f.js","2136","static/chunks/2136-2c0d6e8c18d2c5c4.js","8049","static/chunks/8049-cb52b16664f13e28.js","5144","static/chunks/5144-bbc18c43eade9aef.js","2202","static/chunks/2202-a83ad035a17401aa.js","1098","static/chunks/1098-c3e95c9684ff5e95.js","665","static/chunks/665-d94073042ee5b874.js","5975","static/chunks/5975-758334d6641b9c63.js","7049","static/chunks/app/(dashboard)/virtual-keys/page-73444bcb0cfe86b7.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["virtual-keys",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["virtual-keys",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","virtual-keys","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["virtual-keys",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["virtual-keys",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","virtual-keys","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/virtual-keys/index.html b/litellm/proxy/_experimental/out/virtual-keys/index.html new file mode 100644 index 00000000000..702a244b3d9 --- /dev/null +++ b/litellm/proxy/_experimental/out/virtual-keys/index.html @@ -0,0 +1 @@ +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py index d9fb809cc9a..c248082c263 100644 --- a/litellm/proxy/_types.py +++ b/litellm/proxy/_types.py @@ -227,7 +227,6 @@ class KeyManagementRoutes(str, enum.Enum): KEY_REGENERATE_WITH_PATH_PARAM = "/key/{key_id}/regenerate" KEY_BLOCK = "/key/block" KEY_UNBLOCK = "/key/unblock" - KEY_BULK_UPDATE = "/key/bulk_update" # info and health routes KEY_INFO = "/key/info" @@ -354,9 +353,6 @@ class LiteLLMRoutes(enum.Enum): "/v1/vector_stores/{vector_store_id}/files/{file_id}", "/vector_stores/{vector_store_id}/files/{file_id}/content", "/v1/vector_stores/{vector_store_id}/files/{file_id}/content", - "/vector_store/list", - "/v1/vector_store/list", - # search "/search", "/v1/search", @@ -429,12 +425,12 @@ class LiteLLMRoutes(enum.Enum): ] google_routes = [ - "/v1beta/models/{model_name:path}:countTokens", - "/v1beta/models/{model_name:path}:generateContent", - "/v1beta/models/{model_name:path}:streamGenerateContent", - "/models/{model_name:path}:countTokens", - "/models/{model_name:path}:generateContent", - "/models/{model_name:path}:streamGenerateContent", + "/v1beta/models/{model_name}:countTokens", + "/v1beta/models/{model_name}:generateContent", + "/v1beta/models/{model_name}:streamGenerateContent", + "/models/{model_name}:countTokens", + "/models/{model_name}:generateContent", + "/models/{model_name}:streamGenerateContent", # Google Interactions API "/interactions", "/v1beta/interactions", @@ -498,7 +494,6 @@ class LiteLLMRoutes(enum.Enum): KeyManagementRoutes.KEY_LIST.value, KeyManagementRoutes.KEY_BLOCK.value, KeyManagementRoutes.KEY_UNBLOCK.value, - KeyManagementRoutes.KEY_BULK_UPDATE.value, ] management_routes = [ @@ -856,13 +851,6 @@ class GenerateRequestBase(LiteLLMPydanticObjectBase): aliases: Optional[dict] = {} object_permission: Optional[LiteLLM_ObjectPermissionBase] = None - @field_validator("max_budget", mode="before") - @classmethod - def check_max_budget(cls, v): - if v == "": - return None - return v - class AllowedVectorStoreIndexItem(LiteLLMPydanticObjectBase): index_name: str @@ -2078,14 +2066,6 @@ class ConfigGeneralSettings(LiteLLMPydanticObjectBase): None, description="Controls how non-admin users interact with MCP servers in the dashboard. 'restricted' shows only accessible servers, 'view_all' lists every server in read-only mode.", ) - store_prompts_in_spend_logs: Optional[bool] = Field( - None, - description="If True, stores request messages and responses in spend logs. Default is False.", - ) - maximum_spend_logs_retention_period: Optional[str] = Field( - None, - description="Maximum retention period for spend logs (e.g., '7d' for 7 days). Logs older than this will be deleted.", - ) class ConfigYAML(LiteLLMPydanticObjectBase): @@ -3922,8 +3902,6 @@ class LiteLLM_ManagedVectorStoresTable(LiteLLMPydanticObjectBase): updated_at: Optional[datetime] litellm_credential_name: Optional[str] litellm_params: Optional[Dict[str, Any]] - team_id: Optional[str] - user_id: Optional[str] class ResponseLiteLLM_ManagedVectorStore(TypedDict, total=False): diff --git a/litellm/proxy/agent_endpoints/a2a_endpoints.py b/litellm/proxy/agent_endpoints/a2a_endpoints.py index 24727aacd75..a21f3291d31 100644 --- a/litellm/proxy/agent_endpoints/a2a_endpoints.py +++ b/litellm/proxy/agent_endpoints/a2a_endpoints.py @@ -119,11 +119,6 @@ async def stream_response(): tags=["[beta] A2A Agents"], dependencies=[Depends(user_api_key_auth)], ) -@router.get( - "/a2a/{agent_id}/.well-known/agent.json", - tags=["[beta] A2A Agents"], - dependencies=[Depends(user_api_key_auth)], -) async def get_agent_card( agent_id: str, request: Request, @@ -132,10 +127,6 @@ async def get_agent_card( """ Get the agent card for an agent (A2A discovery endpoint). - Supports both standard paths: - - /.well-known/agent-card.json - - /.well-known/agent.json - The URL in the agent card is rewritten to point to the LiteLLM proxy, so all subsequent A2A calls go through LiteLLM for logging and cost tracking. """ diff --git a/litellm/proxy/auth/auth_checks.py b/litellm/proxy/auth/auth_checks.py index e0b056d450f..5e0a211906e 100644 --- a/litellm/proxy/auth/auth_checks.py +++ b/litellm/proxy/auth/auth_checks.py @@ -21,8 +21,6 @@ from litellm.caching.caching import DualCache from litellm.caching.dual_cache import LimitedSizeOrderedDict from litellm.constants import ( - CLI_JWT_EXPIRATION_HOURS, - CLI_JWT_TOKEN_NAME, DEFAULT_IN_MEMORY_TTL, DEFAULT_MANAGEMENT_OBJECT_IN_MEMORY_CACHE_TTL, DEFAULT_MAX_RECURSE_DEPTH, @@ -1016,10 +1014,8 @@ async def _get_fuzzy_user_object( ) if response is None and user_email is not None: - # Use case-insensitive query to handle emails with different casing - # This matches the pattern used in _check_duplicate_user_email response = await prisma_client.db.litellm_usertable.find_first( - where={"user_email": {"equals": user_email, "mode": "insensitive"}}, + where={"user_email": user_email}, include={"organization_memberships": True}, ) @@ -1606,10 +1602,7 @@ def get_cli_jwt_auth_token( user_info: LiteLLM_UserTable, team_id: Optional[str] = None ) -> str: """ - Generate a JWT token for CLI authentication with configurable expiration. - - The expiration time can be controlled via the LITELLM_CLI_JWT_EXPIRATION_HOURS - environment variable (defaults to 24 hours). + Generate a JWT token for CLI authentication with 24-hour expiration. Args: user_info: User information from the database @@ -1620,6 +1613,7 @@ def get_cli_jwt_auth_token( """ from datetime import timedelta + from litellm.constants import CLI_JWT_TOKEN_NAME from litellm.proxy.common_utils.encrypt_decrypt_utils import ( encrypt_value_helper, ) @@ -1627,8 +1621,8 @@ def get_cli_jwt_auth_token( if user_info.user_role is None: raise Exception("User role is required for CLI JWT login") - # Calculate expiration time (configurable via LITELLM_CLI_JWT_EXPIRATION_HOURS env var) - expiration_time = get_utc_datetime() + timedelta(hours=CLI_JWT_EXPIRATION_HOURS) + # Calculate expiration time (24 hours from now - matching old CLI key behavior) + expiration_time = get_utc_datetime() + timedelta(hours=24) # Format the expiration time as ISO 8601 string expires = expiration_time.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "+00:00" diff --git a/litellm/proxy/auth/auth_utils.py b/litellm/proxy/auth/auth_utils.py index 2bd84a1d98d..9b9a988c07a 100644 --- a/litellm/proxy/auth/auth_utils.py +++ b/litellm/proxy/auth/auth_utils.py @@ -758,27 +758,11 @@ def get_model_from_request( if match: model = match.group(1) - # If still not found, extract model from Google generateContent-style routes. - # These routes put the model in the path and allow "/" inside the model id. - # Examples: - # - /v1beta/models/gemini-2.0-flash:generateContent - # - /v1beta/models/bedrock/claude-sonnet-3.7:generateContent - # - /models/custom/ns/model:streamGenerateContent - if model is None and not route.lower().startswith("/vertex"): - google_match = re.search(r"/(?:v1beta|beta)/models/([^:]+):", route) - if google_match: - model = google_match.group(1) - - if model is None and not route.lower().startswith("/vertex"): - google_match = re.search(r"^/models/([^:]+):", route) - if google_match: - model = google_match.group(1) - # If still not found, extract from Vertex AI passthrough route # Pattern: /vertex_ai/.../models/{model_id}:* # Example: /vertex_ai/v1/.../models/gemini-1.5-pro:generateContent - if model is None and route.lower().startswith("/vertex"): - vertex_match = re.search(r"/models/([^:]+)", route) + if model is None and "/vertex" in route.lower(): + vertex_match = re.search(r"/models/([^/:]+)", route) if vertex_match: model = vertex_match.group(1) diff --git a/litellm/proxy/auth/route_checks.py b/litellm/proxy/auth/route_checks.py index fa63ff01b3a..96a70b8016f 100644 --- a/litellm/proxy/auth/route_checks.py +++ b/litellm/proxy/auth/route_checks.py @@ -392,15 +392,7 @@ def _route_matches_pattern(route: str, pattern: str) -> bool: # Ensure route is a string before attempting regex matching if not isinstance(route, str): return False - - def _placeholder_to_regex(match: re.Match) -> str: - placeholder = match.group(0).strip("{}") - if placeholder.endswith(":path"): - # allow "/" in the placeholder value, but don't eat the route suffix after ":" - return r"[^:]+" - return r"[^/]+" - - pattern = re.sub(r"\{[^}]+\}", _placeholder_to_regex, pattern) + pattern = re.sub(r"\{[^}]+\}", r"[^/]+", pattern) # Anchor the pattern to match the entire string pattern = f"^{pattern}$" if re.match(pattern, route): diff --git a/litellm/proxy/batches_endpoints/endpoints.py b/litellm/proxy/batches_endpoints/endpoints.py index 078e21f9bb4..086105042e8 100644 --- a/litellm/proxy/batches_endpoints/endpoints.py +++ b/litellm/proxy/batches_endpoints/endpoints.py @@ -542,26 +542,14 @@ async def list_batches( route_type="alist_batches", ) - # Try to use managed objects table for listing batches (returns encoded IDs) - managed_files_obj = proxy_logging_obj.get_proxy_hook("managed_files") - if managed_files_obj is not None and hasattr(managed_files_obj, "list_user_batches"): - verbose_proxy_logger.debug( - "Using managed objects table for batch listing" - ) - response = await managed_files_obj.list_user_batches( - user_api_key_dict=user_api_key_dict, - limit=limit, - after=after, - provider=provider, - target_model_names=target_model_names, - llm_router=llm_router, - ) - elif (model_param := ( + model_param = ( data.get("model") or request.query_params.get("model") or request.headers.get("x-litellm-model") - )): - # SCENARIO 2: Use model-based routing from header/query/body + ) + + # SCENARIO 2: Use model-based routing from header/query/body + if model_param: credentials = get_credentials_for_model( llm_router=llm_router, model_id=model_param, diff --git a/litellm/proxy/client/cli/commands/auth.py b/litellm/proxy/client/cli/commands/auth.py index 64b3233536f..bdc8d56d1c3 100644 --- a/litellm/proxy/client/cli/commands/auth.py +++ b/litellm/proxy/client/cli/commands/auth.py @@ -11,8 +11,6 @@ from rich.console import Console from rich.table import Table -from litellm.constants import CLI_JWT_EXPIRATION_HOURS - # Token storage utilities def get_token_file_path() -> str: @@ -276,71 +274,6 @@ def prompt_team_selection_fallback( # Polling-based authentication - no local server needed -def _poll_for_ready_data( - url: str, - *, - total_timeout: int = 300, - poll_interval: int = 2, - request_timeout: int = 10, - pending_message: Optional[str] = None, - pending_log_every: int = 10, - other_status_message: Optional[str] = None, - other_status_log_every: int = 10, - http_error_log_every: int = 10, - connection_error_log_every: int = 10, -) -> Optional[Dict[str, Any]]: - for attempt in range(total_timeout // poll_interval): - try: - response = requests.get(url, timeout=request_timeout) - if response.status_code == 200: - data = response.json() - status = data.get("status") - if status == "ready": - return data - if status == "pending": - if ( - pending_message - and pending_log_every > 0 - and attempt % pending_log_every == 0 - ): - click.echo(pending_message) - elif ( - other_status_message - and other_status_log_every > 0 - and attempt % other_status_log_every == 0 - ): - click.echo(other_status_message) - elif http_error_log_every > 0 and attempt % http_error_log_every == 0: - click.echo(f"Polling error: HTTP {response.status_code}") - except requests.RequestException as e: - if ( - connection_error_log_every > 0 - and attempt % connection_error_log_every == 0 - ): - click.echo(f"Connection error (will retry): {e}") - time.sleep(poll_interval) - return None - - -def _normalize_teams(teams, team_details): - """If team_details are a - - Args: - teams (_type_): _description_ - team_details (_type_): _description_ - - Returns: - _type_: _description_ - """ - if isinstance(team_details, list) and team_details: - return [ - {"team_id": i.get("team_id") or i.get("id"), "team_alias": i.get("team_alias")} - for i in team_details - if isinstance(i, dict) and (i.get("team_id") or i.get("id")) - ] - if isinstance(teams, list): - return [{"team_id": str(t), "team_alias": None} for t in teams] - return [] def _poll_for_authentication(base_url: str, key_id: str) -> Optional[dict]: @@ -351,58 +284,106 @@ def _poll_for_authentication(base_url: str, key_id: str) -> Optional[dict]: Dictionary with authentication data if successful, None otherwise """ poll_url = f"{base_url}/sso/cli/poll/{key_id}" - data = _poll_for_ready_data( - poll_url, - pending_message="Still waiting for authentication...", - ) - if not data: - return None - if data.get("requires_team_selection"): - teams = data.get("teams", []) - team_details = data.get("team_details") - user_id = data.get("user_id") - normalized_teams: List[Dict[str, Any]] = _normalize_teams(teams, team_details) - if not normalized_teams: - click.echo("⚠️ No teams available for selection.") - return None - - # User has multiple teams - let them select - jwt_with_team = _handle_team_selection_during_polling( - base_url=base_url, - key_id=key_id, - teams=normalized_teams, - ) + timeout = 300 # 5 minute timeout + poll_interval = 2 # Poll every 2 seconds - # Use the team-specific JWT if selection succeeded - if jwt_with_team: - return { - "api_key": jwt_with_team, - "user_id": user_id, - "teams": teams, - "team_id": None, # Set by server in JWT - } - - click.echo("❌ Team selection cancelled or JWT generation failed.") - return None - - # JWT is ready (single team or team already selected) - api_key = data.get("key") - user_id = data.get("user_id") - teams = data.get("teams", []) - team_id = data.get("team_id") + for attempt in range(timeout // poll_interval): + try: + response = requests.get(poll_url, timeout=10) + if response.status_code == 200: + data = response.json() + if data.get("status") == "ready": + # Check if we need team selection first + if data.get("requires_team_selection"): + # Server returned teams list without JWT - need to select team. + # Newer servers may also return "team_details" containing + # objects with both team_id and team_alias. We prefer those + # for display, but continue to support the legacy list of + # team IDs for backwards compatibility. + teams = data.get("teams", []) + team_details = data.get("team_details") + user_id = data.get("user_id") + + # Build a normalized list of team objects that always have + # "team_id" and optionally "team_alias". + normalized_teams: List[Dict[str, Any]] = [] + if isinstance(team_details, list) and team_details: + for item in team_details: + if isinstance(item, dict): + team_id = item.get("team_id") or item.get("id") + if team_id is None: + continue + normalized_teams.append( + { + "team_id": team_id, + "team_alias": item.get("team_alias"), + } + ) + elif isinstance(teams, list): + for t in teams: + normalized_teams.append( + { + "team_id": str(t), + "team_alias": None, + } + ) + + if normalized_teams and len(normalized_teams) > 1: + # User has multiple teams - let them select + jwt_with_team = _handle_team_selection_during_polling( + base_url=base_url, + key_id=key_id, + teams=normalized_teams, + ) + + # Use the team-specific JWT if selection succeeded + if jwt_with_team: + return { + "api_key": jwt_with_team, + "user_id": user_id, + "teams": teams, + "team_id": None, # Set by server in JWT + } + else: + # Selection failed or was skipped - poll again without team_id + click.echo("⚠️ Team selection skipped, retrying...") + continue + else: + # Shouldn't happen, but fallback + click.echo("⚠️ No teams available, retrying...") + continue + else: + # JWT is ready (single team or team already selected) + api_key = data.get("key") + user_id = data.get("user_id") + teams = data.get("teams", []) + team_id = data.get("team_id") + + # Show which team was assigned + if team_id and len(teams) == 1: + click.echo(f"\n✅ Automatically assigned to team: {team_id}") + + if api_key: + return { + "api_key": api_key, + "user_id": user_id, + "teams": teams, + "team_id": team_id, + } + elif data.get("status") == "pending": + # Still pending + if attempt % 10 == 0: # Show progress every 20 seconds + click.echo("Still waiting for authentication...") + else: + click.echo(f"Polling error: HTTP {response.status_code}") - # Show which team was assigned - if team_id and len(teams) == 1: - click.echo(f"\n✅ Automatically assigned to team: {team_id}") + except requests.RequestException as e: + if attempt % 10 == 0: + click.echo(f"Connection error (will retry): {e}") - if api_key: - return { - "api_key": api_key, - "user_id": user_id, - "teams": teams, - "team_id": team_id, - } + time.sleep(poll_interval) + # Timeout reached return None @@ -435,21 +416,25 @@ def _handle_team_selection_during_polling( click.echo(f"\n🔄 Generating JWT for team: {team_id}") - poll_url = f"{base_url}/sso/cli/poll/{key_id}?team_id={team_id}" - data = _poll_for_ready_data( - poll_url, - pending_message="Still waiting for team authentication...", - other_status_message="Waiting for team authentication to complete...", - http_error_log_every=10, - ) - if not data: + # Re-poll with team_id to get JWT with correct team + try: + poll_url = f"{base_url}/sso/cli/poll/{key_id}?team_id={team_id}" + response = requests.get(poll_url, timeout=10) + + if response.status_code == 200: + data = response.json() + if data.get("status") == "ready": + jwt_token = data.get("key") + if jwt_token: + click.echo(f"✅ Successfully generated JWT for team: {team_id}") + return jwt_token + + click.echo(f"❌ Failed to get JWT with team. Status: {response.status_code}") return None - jwt_token = data.get("key") - if jwt_token: - click.echo(f"✅ Successfully generated JWT for team: {team_id}") - return jwt_token - return None + except Exception as e: + click.echo(f"❌ Error getting JWT with team: {e}") + return None def _render_and_prompt_for_team_selection(teams: List[Dict[str, Any]]) -> Optional[str]: @@ -607,8 +592,8 @@ def whoami(): age_hours = (time.time() - timestamp) / 3600 click.echo(f"Token age: {age_hours:.1f} hours") - if age_hours > CLI_JWT_EXPIRATION_HOURS: - click.echo(f"⚠️ Warning: Token is more than {CLI_JWT_EXPIRATION_HOURS} hours old and may have expired.") + if age_hours > 24: + click.echo("⚠️ Warning: Token is more than 24 hours old and may have expired.") # Export functions for use by other CLI commands diff --git a/litellm/proxy/common_request_processing.py b/litellm/proxy/common_request_processing.py index 51f3e6482a4..0d3e61b75c7 100644 --- a/litellm/proxy/common_request_processing.py +++ b/litellm/proxy/common_request_processing.py @@ -650,15 +650,11 @@ async def base_process_llm_request( ) tasks = [] - # Start the moderation check (during_call_hook) as early as possible - # This gives it a head start to mask/validate input while the proxy handles routing tasks.append( - asyncio.create_task( - proxy_logging_obj.during_call_hook( - data=self.data, - user_api_key_dict=user_api_key_dict, - call_type=route_type, # type: ignore - ) + proxy_logging_obj.during_call_hook( + data=self.data, + user_api_key_dict=user_api_key_dict, + call_type=route_type, # type: ignore ) ) diff --git a/litellm/proxy/common_utils/callback_utils.py b/litellm/proxy/common_utils/callback_utils.py index faeca9b2aed..c0cff84bacd 100644 --- a/litellm/proxy/common_utils/callback_utils.py +++ b/litellm/proxy/common_utils/callback_utils.py @@ -274,20 +274,11 @@ def initialize_callbacks_on_proxy( # noqa: PLR0915 WebSearchInterceptionLogger, ) - websearch_interception_obj = ( - WebSearchInterceptionLogger.initialize_from_proxy_config( - litellm_settings=litellm_settings, - callback_specific_params=callback_specific_params, - ) + websearch_interception_obj = WebSearchInterceptionLogger.initialize_from_proxy_config( + litellm_settings=litellm_settings, + callback_specific_params=callback_specific_params, ) imported_list.append(websearch_interception_obj) - elif isinstance(callback, str) and callback == "datadog_cost_management": - from litellm.integrations.datadog.datadog_cost_management import ( - DatadogCostManagementLogger, - ) - - datadog_cost_management_obj = DatadogCostManagementLogger() - imported_list.append(datadog_cost_management_obj) elif isinstance(callback, CustomLogger): imported_list.append(callback) else: @@ -362,17 +353,17 @@ def get_remaining_tokens_and_requests_from_request_data(data: Dict) -> Dict[str, remaining_requests_variable_name = f"litellm-key-remaining-requests-{model_group}" remaining_requests = _metadata.get(remaining_requests_variable_name, None) if remaining_requests: - headers[ - f"x-litellm-key-remaining-requests-{h11_model_group_name}" - ] = remaining_requests + headers[f"x-litellm-key-remaining-requests-{h11_model_group_name}"] = ( + remaining_requests + ) # Remaining Tokens remaining_tokens_variable_name = f"litellm-key-remaining-tokens-{model_group}" remaining_tokens = _metadata.get(remaining_tokens_variable_name, None) if remaining_tokens: - headers[ - f"x-litellm-key-remaining-tokens-{h11_model_group_name}" - ] = remaining_tokens + headers[f"x-litellm-key-remaining-tokens-{h11_model_group_name}"] = ( + remaining_tokens + ) return headers @@ -447,9 +438,9 @@ def add_guardrail_response_to_standard_logging_object( ): if litellm_logging_obj is None: return - standard_logging_object: Optional[ - StandardLoggingPayload - ] = litellm_logging_obj.model_call_details.get("standard_logging_object") + standard_logging_object: Optional[StandardLoggingPayload] = ( + litellm_logging_obj.model_call_details.get("standard_logging_object") + ) if standard_logging_object is None: return guardrail_information = standard_logging_object.get("guardrail_information", []) @@ -478,9 +469,7 @@ def get_metadata_variable_name_from_kwargs( return "litellm_metadata" if "litellm_metadata" in kwargs else "metadata" -def process_callback( - _callback: str, callback_type: str, environment_variables: dict -) -> dict: +def process_callback(_callback: str, callback_type: str, environment_variables: dict) -> dict: """Process a single callback and return its data with environment variables""" env_vars = CustomLogger.get_callback_env_vars(_callback) @@ -492,9 +481,11 @@ def process_callback( else: env_vars_dict[_var] = env_variable - return {"name": _callback, "variables": env_vars_dict, "type": callback_type} - - + return { + "name": _callback, + "variables": env_vars_dict, + "type": callback_type + } def normalize_callback_names(callbacks: Iterable[Any]) -> List[Any]: if callbacks is None: return [] diff --git a/litellm/proxy/google_endpoints/endpoints.py b/litellm/proxy/google_endpoints/endpoints.py index 5c41b371ca4..bba5b87024b 100644 --- a/litellm/proxy/google_endpoints/endpoints.py +++ b/litellm/proxy/google_endpoints/endpoints.py @@ -264,7 +264,7 @@ async def create_interaction( general_settings=general_settings, proxy_config=proxy_config, select_data_generator=select_data_generator, - model=data.get("model") or data.get("agent"), + model=data.get("model"), user_model=user_model, user_temperature=user_temperature, user_request_timeout=user_request_timeout, diff --git a/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/content_filter.py b/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/content_filter.py index 083a407e9cf..c9bd0135a05 100644 --- a/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/content_filter.py +++ b/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/content_filter.py @@ -198,15 +198,6 @@ def __init__( for pattern_config in normalized_patterns: self._add_pattern(pattern_config) - # Warn if using during_call with MASK action (unstable) - if self.event_hook == GuardrailEventHooks.during_call and any( - p["action"] == ContentFilterAction.MASK for p in self.compiled_patterns - ): - verbose_proxy_logger.warning( - f"ContentFilterGuardrail '{self.guardrail_name}': 'during_call' mode with 'MASK' action is unstable due to race conditions. " - "Use 'pre_call' mode for reliable request masking." - ) - # Load blocked words - always initialize as dict self.blocked_words: Dict[str, Tuple[ContentFilterAction, Optional[str]]] = {} for word in normalized_blocked_words: @@ -914,15 +905,11 @@ async def _process_images( elif isinstance(e.detail, str): e.detail = e.detail + " (Image description): " + description else: - e.detail = ( - "Content blocked: Image description detected" + description - ) + e.detail = "Content blocked: Image description detected" + description raise e def _count_masked_entities( - self, - detections: List[ContentFilterDetection], - masked_entity_count: Dict[str, int], + self, detections: List[ContentFilterDetection], masked_entity_count: Dict[str, int] ) -> None: """ Count masked entities by type from detections. @@ -977,11 +964,9 @@ def _log_guardrail_information( dict(detection) for detection in detections ] if status != "success": - guardrail_json_response = ( - exception_str - if exception_str - else [dict(detection) for detection in detections] - ) + guardrail_json_response = exception_str if exception_str else [ + dict(detection) for detection in detections + ] self.add_standard_logging_guardrail_information_to_request_data( guardrail_provider=self.guardrail_provider, @@ -1081,84 +1066,99 @@ async def async_post_call_streaming_iterator_hook( Process streaming response chunks and check for blocked content. For BLOCK action: Raises HTTPException immediately when blocked content is detected. - For MASK action: Content is buffered to handle patterns split across chunks. + For MASK action: Content passes through (masking streaming responses is not supported). """ - accumulated_full_text = "" - yielded_masked_text_len = 0 - buffer_size = 50 # Increased buffer to catch patterns split across many chunks - verbose_proxy_logger.info( - f"ContentFilterGuardrail: Starting robust streaming masking for model {request_data.get('model')}" - ) + # Accumulate content as we iterate through chunks + accumulated_content = "" async for item in response: + # Accumulate content from this chunk before checking if isinstance(item, ModelResponseStream) and item.choices: - delta_content = "" - is_final = False for choice in item.choices: if hasattr(choice, "delta") and choice.delta: content = getattr(choice.delta, "content", None) if content and isinstance(content, str): - delta_content += content - if getattr(choice, "finish_reason", None): - is_final = True - - accumulated_full_text += delta_content - - # Check for blocking or apply masking - # Add a space at the end if it's the final chunk to trigger word boundaries (\b) - text_to_check = accumulated_full_text - if is_final: - text_to_check += " " - - try: - masked_text = self._filter_single_text(text_to_check) - if is_final and masked_text.endswith(" "): - masked_text = masked_text[:-1] - except HTTPException: - raise - except Exception as e: - verbose_proxy_logger.error( - f"ContentFilterGuardrail: Error in masking: {e}" - ) - masked_text = text_to_check # Fallback to current text - - # Determine how much can be safely yielded - if is_final: - safe_to_yield_len = len(masked_text) - else: - safe_to_yield_len = max(0, len(masked_text) - buffer_size) - - if safe_to_yield_len > yielded_masked_text_len: - new_masked_content = masked_text[ - yielded_masked_text_len:safe_to_yield_len - ] - # Modify the chunk to contain only the new masked content - if ( - item.choices - and hasattr(item.choices[0], "delta") - and item.choices[0].delta - ): - item.choices[0].delta.content = new_masked_content - yielded_masked_text_len = safe_to_yield_len - yield item - else: - # Hold content by yielding empty content chunk (keeps metadata/structure) - if ( - item.choices - and hasattr(item.choices[0], "delta") - and item.choices[0].delta - ): - item.choices[0].delta.content = "" - yield item - else: - # Not a ModelResponseStream or no choices - yield as is - yield item + accumulated_content += content + + # Check accumulated content for blocked patterns/keywords after processing all choices + # Only check for BLOCK actions, not MASK (masking streaming is not supported) + if accumulated_content: + try: + # Check patterns + pattern_match = self._check_patterns(accumulated_content) + if pattern_match: + matched_text, pattern_name, action = pattern_match + if action == ContentFilterAction.BLOCK: + error_msg = ( + f"Content blocked: {pattern_name} pattern detected" + ) + verbose_proxy_logger.warning(error_msg) + raise HTTPException( + status_code=403, + detail={ + "error": error_msg, + "pattern": pattern_name, + }, + ) + + # Check blocked words + blocked_word_match = self._check_blocked_words( + accumulated_content + ) + if blocked_word_match: + keyword, action, description = blocked_word_match + if action == ContentFilterAction.BLOCK: + error_msg = ( + f"Content blocked: keyword '{keyword}' detected" + ) + if description: + error_msg += f" ({description})" + verbose_proxy_logger.warning(error_msg) + raise HTTPException( + status_code=403, + detail={ + "error": error_msg, + "keyword": keyword, + "description": description, + }, + ) + + # Check category keywords + all_exceptions = [] + for category in self.loaded_categories.values(): + all_exceptions.extend(category.exceptions) + category_match = self._check_category_keywords( + accumulated_content, all_exceptions + ) + if category_match: + keyword, category_name, severity, action = category_match + if action == ContentFilterAction.BLOCK: + error_msg = ( + f"Content blocked: {category_name} category keyword '{keyword}' detected " + f"(severity: {severity})" + ) + verbose_proxy_logger.warning(error_msg) + raise HTTPException( + status_code=403, + detail={ + "error": error_msg, + "category": category_name, + "keyword": keyword, + "severity": severity, + }, + ) + except HTTPException: + # Re-raise HTTPException (blocked content detected) + raise + except Exception as e: + # Log other exceptions but don't block the stream + verbose_proxy_logger.warning( + f"Error checking content filter in streaming: {e}" + ) - # Any remaining content (should have been handled by is_final, but just in case) - if yielded_masked_text_len < len(accumulated_full_text): - # We already reached the end of the generator - pass + # Yield the chunk (only if no exception was raised above) + yield item @staticmethod def get_config_model(): diff --git a/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/patterns.json b/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/patterns.json index 1eff7804b42..f2427b5b920 100644 --- a/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/patterns.json +++ b/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/patterns.json @@ -108,7 +108,7 @@ { "name": "ipv6", "display_name": "IP Address (IPv6)", - "pattern": "(? AsyncGenerator[aiohttp.ClientSession, None]: + async def _get_http_session(self) -> aiohttp.ClientSession: """ - Async context manager for yielding an HTTP session. + Get or create the shared HTTP session for Presidio API calls. + + Fixes memory leak (issue #14540) where every guardrail check created + a new aiohttp.ClientSession that was never properly closed. - Logic: - 1. If running in the main thread (where the object was initialized/destined to live normally), - use the shared `self._http_session` (protected by a lock). - 2. If running in a background thread (e.g. logging hook), use a cached session for that loop. + Thread-safe: Uses asyncio.Lock to prevent race conditions when + multiple concurrent requests try to create the session simultaneously. """ - current_loop = asyncio.get_running_loop() - - # Check if we are in the stored main thread - if threading.get_ident() == self._main_thread_id: - # Main thread -> use shared session - async with self._session_lock: - if self._http_session is None or self._http_session.closed: - self._http_session = aiohttp.ClientSession() - yield self._http_session - else: - # Background thread/loop -> use loop-bound session cache - # This avoids "attached to a different loop" or "no running event loop" errors - # when accessing the shared session created in the main loop - if ( - current_loop not in self._loop_sessions - or self._loop_sessions[current_loop].closed - ): - self._loop_sessions[current_loop] = aiohttp.ClientSession() - yield self._loop_sessions[current_loop] + async with self._session_lock: + if self._http_session is None or self._http_session.closed: + self._http_session = aiohttp.ClientSession() + return self._http_session async def _close_http_session(self) -> None: - """Close all cached HTTP sessions.""" + """Close the HTTP session if it exists.""" if self._http_session is not None and not self._http_session.closed: await self._http_session.close() self._http_session = None - for session in self._loop_sessions.values(): - if not session.closed: - await session.close() - self._loop_sessions.clear() - def __del__(self): - """Cleanup: we try to close, but doing async cleanup in __del__ is risky.""" - pass + """Cleanup: close HTTP session on instance destruction.""" + if self._http_session is not None and not self._http_session.closed: + try: + # Try to close the session, but don't fail if event loop is gone + import asyncio + try: + loop = asyncio.get_event_loop() + if loop.is_running(): + # Schedule cleanup, don't block __del__ + asyncio.create_task(self._close_http_session()) + else: + loop.run_until_complete(self._close_http_session()) + except RuntimeError: + # Event loop is closed, can't clean up - not ideal but better than crashing + pass + except Exception: + # Suppress all exceptions in __del__ to avoid issues during shutdown + pass def _get_presidio_analyze_request_payload( self, @@ -289,27 +273,28 @@ async def analyze_text( return self.mock_redacted_text # Use shared session to prevent memory leak (issue #14540) - async with self._get_session_iterator() as session: - # Make the request to /analyze - analyze_url = f"{self.presidio_analyzer_api_base}analyze" + session = await self._get_http_session() - analyze_payload: PresidioAnalyzeRequest = ( - self._get_presidio_analyze_request_payload( - text=text, - presidio_config=presidio_config, - request_data=request_data, - ) - ) + # Make the request to /analyze + analyze_url = f"{self.presidio_analyzer_api_base}analyze" - verbose_proxy_logger.debug( - "Making request to: %s with payload: %s", - analyze_url, - analyze_payload, + analyze_payload: PresidioAnalyzeRequest = ( + self._get_presidio_analyze_request_payload( + text=text, + presidio_config=presidio_config, + request_data=request_data, ) + ) - async with session.post(analyze_url, json=analyze_payload) as response: - analyze_results = await response.json() - verbose_proxy_logger.debug("analyze_results: %s", analyze_results) + verbose_proxy_logger.debug( + "Making request to: %s with payload: %s", + analyze_url, + analyze_payload, + ) + + async with session.post(analyze_url, json=analyze_payload) as response: + analyze_results = await response.json() + verbose_proxy_logger.debug("analyze_results: %s", analyze_results) # Handle error responses from Presidio (e.g., {'error': 'No text provided'}) # Presidio may return a dict instead of a list when errors occur @@ -317,7 +302,7 @@ async def analyze_text( if "error" in analyze_results: verbose_proxy_logger.warning( "Presidio analyzer returned error: %s, returning empty list", - analyze_results.get("error"), + analyze_results.get("error") ) return [] # If it's a dict but not an error, try to process it as a single item @@ -329,7 +314,7 @@ async def analyze_text( except Exception as e: verbose_proxy_logger.warning( "Failed to parse Presidio dict response: %s, returning empty list", - e, + e ) return [] @@ -366,19 +351,20 @@ async def anonymize_text( return text # Use shared session to prevent memory leak (issue #14540) - async with self._get_session_iterator() as session: - # Make the request to /anonymize - anonymize_url = f"{self.presidio_anonymizer_api_base}anonymize" - verbose_proxy_logger.debug("Making request to: %s", anonymize_url) - anonymize_payload = { - "text": text, - "analyzer_results": analyze_results, - } - - async with session.post( - anonymize_url, json=anonymize_payload - ) as response: - redacted_text = await response.json() + session = await self._get_http_session() + + # Make the request to /anonymize + anonymize_url = f"{self.presidio_anonymizer_api_base}anonymize" + verbose_proxy_logger.debug("Making request to: %s", anonymize_url) + anonymize_payload = { + "text": text, + "analyzer_results": analyze_results, + } + + async with session.post( + anonymize_url, json=anonymize_payload + ) as response: + redacted_text = await response.json() new_text = text if redacted_text is not None: @@ -509,13 +495,12 @@ async def check_pii( ) # Then anonymize the text using the analysis results - anonymized_text = await self.anonymize_text( + return await self.anonymize_text( text=text, analyze_results=analyze_results, output_parse_pii=output_parse_pii, masked_entity_count=masked_entity_count, ) - return anonymized_text return redacted_text["text"] except Exception as e: status = "guardrail_failed_to_respond" diff --git a/litellm/proxy/litellm_pre_call_utils.py b/litellm/proxy/litellm_pre_call_utils.py index 9be78264e85..60472cd7790 100644 --- a/litellm/proxy/litellm_pre_call_utils.py +++ b/litellm/proxy/litellm_pre_call_utils.py @@ -856,9 +856,7 @@ async def add_litellm_data_to_request( # noqa: PLR0915 # Add headers to metadata for guardrails to access (fixes #17477) # Guardrails use metadata["headers"] to access request headers (e.g., User-Agent) - if _metadata_variable_name in data and isinstance( - data[_metadata_variable_name], dict - ): + if _metadata_variable_name in data and isinstance(data[_metadata_variable_name], dict): data[_metadata_variable_name]["headers"] = _headers # check for forwardable headers @@ -1014,9 +1012,7 @@ async def add_litellm_data_to_request( # noqa: PLR0915 # User spend, budget - used by prometheus.py # Follow same pattern as team and API key budgets - data[_metadata_variable_name][ - "user_api_key_user_spend" - ] = user_api_key_dict.user_spend + data[_metadata_variable_name]["user_api_key_user_spend"] = user_api_key_dict.user_spend data[_metadata_variable_name][ "user_api_key_user_max_budget" ] = user_api_key_dict.user_max_budget @@ -1043,8 +1039,8 @@ async def add_litellm_data_to_request( # noqa: PLR0915 ## [Enterprise Only] # Add User-IP Address requester_ip_address = "" - if True: # Always set the IP Address if available - # logic for tracking IP Address + if premium_user is True: + # Only set the IP Address for Enterprise Users # logic for tracking IP Address if ( @@ -1064,16 +1060,6 @@ async def add_litellm_data_to_request( # noqa: PLR0915 requester_ip_address = request.client.host data[_metadata_variable_name]["requester_ip_address"] = requester_ip_address - # Add User-Agent - user_agent = "" - if ( - request is not None - and hasattr(request, "headers") - and "user-agent" in request.headers - ): - user_agent = request.headers["user-agent"] - data[_metadata_variable_name]["user_agent"] = user_agent - # Check if using tag based routing tags = LiteLLMProxyRequestSetup.add_request_tag_to_metadata( llm_router=llm_router, @@ -1524,13 +1510,10 @@ def add_guardrails_from_policy_engine( Add guardrails from the policy engine based on request context. This function: - 1. Extracts "policies" from request body (if present) for dynamic policy application - 2. Gets matching policies based on team_alias, key_alias, and model (via attachments) - 3. Combines dynamic policies with attachment-based policies - 4. Resolves guardrails from all policies (including inheritance) - 5. Adds guardrails to request metadata - 6. Tracks applied policies in metadata for response headers - 7. Removes "policies" from request body so it's not forwarded to LLM provider + 1. Gets matching policies based on team_alias, key_alias, and model + 2. Resolves guardrails from matching policies (including inheritance) + 3. Adds guardrails to request metadata + 4. Tracks applied policies in metadata for response headers Args: data: The request data to update @@ -1546,19 +1529,13 @@ def add_guardrails_from_policy_engine( from litellm.proxy.policy_engine.policy_resolver import PolicyResolver from litellm.types.proxy.policy_engine import PolicyMatchContext - # Extract dynamic policies from request body (if present) - # These will be combined with attachment-based policies - request_body_policies = data.pop("policies", None) - registry = get_policy_registry() verbose_proxy_logger.debug( f"Policy engine: registry initialized={registry.is_initialized()}, " f"policy_count={len(registry.get_all_policies())}" ) if not registry.is_initialized(): - verbose_proxy_logger.debug( - "Policy engine not initialized, skipping policy matching" - ) + verbose_proxy_logger.debug("Policy engine not initialized, skipping policy matching") return # Build context from request @@ -1576,30 +1553,18 @@ def add_guardrails_from_policy_engine( # Get matching policies via attachments matching_policy_names = PolicyMatcher.get_matching_policies(context=context) - verbose_proxy_logger.debug( - f"Policy engine: matched policies via attachments: {matching_policy_names}" - ) - - # Combine attachment-based policies with dynamic request body policies - all_policy_names = set(matching_policy_names) - if request_body_policies and isinstance(request_body_policies, list): - all_policy_names.update(request_body_policies) - verbose_proxy_logger.debug( - f"Policy engine: added dynamic policies from request body: {request_body_policies}" - ) + verbose_proxy_logger.debug(f"Policy engine: matched policies via attachments: {matching_policy_names}") - if not all_policy_names: + if not matching_policy_names: return # Filter to only policies whose conditions match the context applied_policy_names = PolicyMatcher.get_policies_with_matching_conditions( - policy_names=list(all_policy_names), + policy_names=matching_policy_names, context=context, ) - verbose_proxy_logger.debug( - f"Policy engine: applied policies (conditions matched): {applied_policy_names}" - ) + verbose_proxy_logger.debug(f"Policy engine: applied policies (conditions matched): {applied_policy_names}") # Track applied policies in metadata for response headers for policy_name in applied_policy_names: @@ -1610,9 +1575,7 @@ def add_guardrails_from_policy_engine( # Resolve guardrails from matching policies resolved_guardrails = PolicyResolver.resolve_guardrails_for_context(context=context) - verbose_proxy_logger.debug( - f"Policy engine: resolved guardrails: {resolved_guardrails}" - ) + verbose_proxy_logger.debug(f"Policy engine: resolved guardrails: {resolved_guardrails}") if not resolved_guardrails: return diff --git a/litellm/proxy/management_endpoints/internal_user_endpoints.py b/litellm/proxy/management_endpoints/internal_user_endpoints.py index 38a867d031b..9a986326c03 100644 --- a/litellm/proxy/management_endpoints/internal_user_endpoints.py +++ b/litellm/proxy/management_endpoints/internal_user_endpoints.py @@ -814,9 +814,7 @@ def _update_internal_user_params( ) -> dict: non_default_values = {} for k, v in data_json.items(): - if k == "max_budget": - non_default_values[k] = v - elif ( + if ( v is not None and v not in ( diff --git a/litellm/proxy/management_endpoints/key_management_endpoints.py b/litellm/proxy/management_endpoints/key_management_endpoints.py index 380e8bddc99..ab87e862ea6 100644 --- a/litellm/proxy/management_endpoints/key_management_endpoints.py +++ b/litellm/proxy/management_endpoints/key_management_endpoints.py @@ -37,13 +37,6 @@ ) from litellm.proxy._types import * from litellm.proxy._types import LiteLLM_VerificationToken -from litellm.types.proxy.management_endpoints.key_management_endpoints import ( - BulkUpdateKeyRequest, - BulkUpdateKeyRequestItem, - BulkUpdateKeyResponse, - FailedKeyUpdate, - SuccessfulKeyUpdate, -) from litellm.proxy.auth.auth_checks import ( _cache_key_object, _delete_cache_key_object, @@ -1445,211 +1438,6 @@ def is_different_team( return data.team_id != existing_key_row.team_id -def _validate_max_budget(max_budget: Optional[float]) -> None: - """ - Validate that max_budget is not negative. - - Args: - max_budget: The max_budget value to validate - - Raises: - HTTPException: If max_budget is negative - """ - if max_budget is not None and max_budget < 0: - raise HTTPException( - status_code=400, - detail={ - "error": f"max_budget cannot be negative. Received: {max_budget}" - }, - ) - - -async def _get_and_validate_existing_key( - token: str, prisma_client: Optional[PrismaClient] -) -> LiteLLM_VerificationToken: - """ - Get existing key from database and validate it exists. - - Args: - token: The key token to look up - prisma_client: Prisma client instance - - Returns: - LiteLLM_VerificationToken: The existing key row - - Raises: - HTTPException: If key is not found - """ - if prisma_client is None: - raise HTTPException( - status_code=500, - detail={"error": "Database not connected"}, - ) - - existing_key_row = await prisma_client.get_data( - token=token, - table_name="key", - query_type="find_unique", - ) - - if existing_key_row is None: - raise HTTPException( - status_code=404, - detail={"error": f"Key not found: {token}"}, - ) - - return existing_key_row - - -async def _process_single_key_update( - key_update_item: BulkUpdateKeyRequestItem, - user_api_key_dict: UserAPIKeyAuth, - litellm_changed_by: Optional[str], - prisma_client: Optional[PrismaClient], - user_api_key_cache: DualCache, - proxy_logging_obj: Any, - llm_router: Optional[Router], -) -> Dict[str, Any]: - """ - Process a single key update with all validations and checks. - - This function encapsulates all the logic for updating a single key, - including validation, permission checks, team checks, and database updates. - - Args: - key_update_item: The key update request item - user_api_key_dict: The authenticated user's API key info - litellm_changed_by: Optional header for tracking who made the change - prisma_client: Prisma client instance - user_api_key_cache: User API key cache - proxy_logging_obj: Proxy logging object - llm_router: LLM router instance - - Returns: - Dict containing the updated key information - - Raises: - HTTPException: For various validation and permission errors - """ - # Validate max_budget - _validate_max_budget(key_update_item.max_budget) - - # Get and validate existing key - existing_key_row = await _get_and_validate_existing_key( - token=key_update_item.key, - prisma_client=prisma_client, - ) - - # Check team member permissions - await TeamMemberPermissionChecks.can_team_member_execute_key_management_endpoint( - user_api_key_dict=user_api_key_dict, - route=KeyManagementRoutes.KEY_UPDATE, - prisma_client=prisma_client, - existing_key_row=existing_key_row, - user_api_key_cache=user_api_key_cache, - ) - - # Create UpdateKeyRequest from BulkUpdateKeyRequestItem - update_key_request = UpdateKeyRequest( - key=key_update_item.key, - budget_id=key_update_item.budget_id, - max_budget=key_update_item.max_budget, - team_id=key_update_item.team_id, - tags=key_update_item.tags, - ) - - # Get team object and check team limits if team_id is provided - team_obj: Optional[LiteLLM_TeamTableCachedObj] = None - if update_key_request.team_id is not None: - team_obj = await get_team_object( - team_id=update_key_request.team_id, - prisma_client=prisma_client, - user_api_key_cache=user_api_key_cache, - check_db_only=True, - ) - - if team_obj is not None and prisma_client is not None: - await _check_team_key_limits( - team_table=team_obj, - data=update_key_request, - prisma_client=prisma_client, - ) - - # Validate team change if team is being changed - if is_different_team( - data=update_key_request, existing_key_row=existing_key_row - ): - if llm_router is None: - raise HTTPException( - status_code=400, - detail={ - "error": "LLM router not found. Please set it up by passing in a valid config.yaml or adding models via the UI." - }, - ) - if team_obj is None: - raise HTTPException( - status_code=500, - detail={ - "error": "Team object not found for team change validation" - }, - ) - validate_key_team_change( - key=existing_key_row, - team=team_obj, - change_initiated_by=user_api_key_dict, - llm_router=llm_router, - ) - - # Prepare update data - non_default_values = await prepare_key_update_data( - data=update_key_request, existing_key_row=existing_key_row - ) - - # Update key in database - if prisma_client is None: - raise HTTPException( - status_code=500, - detail={"error": "Database not connected"}, - ) - - _data = {**non_default_values, "token": key_update_item.key} - response = await prisma_client.update_data( - token=key_update_item.key, data=_data - ) - - # Delete cache - await _delete_cache_key_object( - hashed_token=hash_token(key_update_item.key), - user_api_key_cache=user_api_key_cache, - proxy_logging_obj=proxy_logging_obj, - ) - - # Trigger async hook - asyncio.create_task( - KeyManagementEventHooks.async_key_updated_hook( - data=update_key_request, - existing_key_row=existing_key_row, - response=response, - user_api_key_dict=user_api_key_dict, - litellm_changed_by=litellm_changed_by, - ) - ) - - if response is None: - raise ValueError("Failed to update key got response = None") - - # Extract and format updated key info - updated_key_info = response.get("data", {}) - if hasattr(updated_key_info, "model_dump"): - updated_key_info = updated_key_info.model_dump() - elif hasattr(updated_key_info, "dict"): - updated_key_info = updated_key_info.dict() - - updated_key_info.pop("token", None) - - return updated_key_info - - @router.post( "/key/update", tags=["key management"], dependencies=[Depends(user_api_key_auth)] ) @@ -1896,167 +1684,6 @@ async def update_key_fn( ) -@router.post( - "/key/bulk_update", - tags=["key management"], - dependencies=[Depends(user_api_key_auth)], - response_model=BulkUpdateKeyResponse, -) -@management_endpoint_wrapper -async def bulk_update_keys( - data: BulkUpdateKeyRequest, - user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), - litellm_changed_by: Optional[str] = Header( - None, - description="The litellm-changed-by header enables tracking of actions performed by authorized users on behalf of other users, providing an audit trail for accountability", - ), -): - """ - Bulk update multiple keys at once. - - This endpoint allows updating multiple keys in a single request. Each key update - is processed independently - if some updates fail, others will still succeed. - - Parameters: - - keys: List[BulkUpdateKeyRequestItem] - List of key update requests, each containing: - - key: str - The key identifier (token) to update - - budget_id: Optional[str] - Budget ID associated with the key - - max_budget: Optional[float] - Max budget for key - - team_id: Optional[str] - Team ID associated with key - - tags: Optional[List[str]] - Tags for organizing keys - - Returns: - - total_requested: int - Total number of keys requested for update - - successful_updates: List[SuccessfulKeyUpdate] - List of successfully updated keys with their updated info - - failed_updates: List[FailedKeyUpdate] - List of failed updates with key_info and failed_reason - - Example request: - ```bash - curl --location 'http://0.0.0.0:4000/key/bulk_update' \ - --header 'Authorization: Bearer sk-1234' \ - --header 'Content-Type: application/json' \ - --data '{ - "keys": [ - { - "key": "sk-1234", - "max_budget": 100.0, - "team_id": "team-123", - "tags": ["production", "api"] - }, - { - "key": "sk-5678", - "budget_id": "budget-456", - "tags": ["staging"] - } - ] - }' - ``` - """ - from litellm.proxy.proxy_server import ( - llm_router, - prisma_client, - proxy_logging_obj, - user_api_key_cache, - ) - - if user_api_key_dict.user_role != LitellmUserRoles.PROXY_ADMIN.value: - raise HTTPException( - status_code=403, - detail={ - "error": "Only proxy admins can perform bulk key updates" - }, - ) - - if prisma_client is None: - raise HTTPException( - status_code=500, - detail={"error": "Database not connected"}, - ) - - if not data.keys: - raise HTTPException( - status_code=400, - detail={"error": "No keys provided for update"}, - ) - - MAX_BATCH_SIZE = 500 - if len(data.keys) > MAX_BATCH_SIZE: - raise HTTPException( - status_code=400, - detail={ - "error": f"Maximum {MAX_BATCH_SIZE} keys can be updated at once. Found {len(data.keys)} keys." - }, - ) - - successful_updates: List[SuccessfulKeyUpdate] = [] - failed_updates: List[FailedKeyUpdate] = [] - - for key_update_item in data.keys: - try: - # Process single key update using reusable function - updated_key_info = await _process_single_key_update( - key_update_item=key_update_item, - user_api_key_dict=user_api_key_dict, - litellm_changed_by=litellm_changed_by, - prisma_client=prisma_client, - user_api_key_cache=user_api_key_cache, - proxy_logging_obj=proxy_logging_obj, - llm_router=llm_router, - ) - - successful_updates.append( - SuccessfulKeyUpdate( - key=key_update_item.key, - key_info=updated_key_info, - ) - ) - - except Exception as e: - verbose_proxy_logger.exception( - f"Failed to update key {key_update_item.key}: {e}" - ) - - if isinstance(e, HTTPException): - error_detail = e.detail - if isinstance(error_detail, dict): - error_message = error_detail.get("error", str(e)) - else: - error_message = str(error_detail) - else: - error_message = str(e) - - key_info = None - try: - existing_key_row = await prisma_client.get_data( - token=key_update_item.key, - table_name="key", - query_type="find_unique", - ) - if existing_key_row is not None: - if hasattr(existing_key_row, "model_dump"): - key_info = existing_key_row.model_dump() - elif hasattr(existing_key_row, "dict"): - key_info = existing_key_row.dict() - if key_info: - key_info.pop("token", None) - except Exception: - pass - - failed_updates.append( - FailedKeyUpdate( - key=key_update_item.key, - key_info=key_info, - failed_reason=error_message, - ) - ) - - return BulkUpdateKeyResponse( - total_requested=len(data.keys), - successful_updates=successful_updates, - failed_updates=failed_updates, - ) - - def validate_key_team_change( key: LiteLLM_VerificationToken, team: LiteLLM_TeamTable, diff --git a/litellm/proxy/management_endpoints/mcp_management_endpoints.py b/litellm/proxy/management_endpoints/mcp_management_endpoints.py index 83d7f3fde4c..a15f47d13bd 100644 --- a/litellm/proxy/management_endpoints/mcp_management_endpoints.py +++ b/litellm/proxy/management_endpoints/mcp_management_endpoints.py @@ -56,19 +56,7 @@ MCP_AVAILABLE = False if MCP_AVAILABLE: - try: - from mcp.shared.tool_name_validation import validate_tool_name # type: ignore - except ImportError: - - def validate_tool_name(name: str): - from pydantic import BaseModel - - class MockResult(BaseModel): - is_valid: bool = True - warnings: list = [] - - return MockResult() - + from mcp.shared.tool_name_validation import validate_tool_name from litellm.proxy._experimental.mcp_server.db import ( create_mcp_server, delete_mcp_server, @@ -134,7 +122,9 @@ def _validate_mcp_server_name_fields(payload: Any) -> None: ) if validation_result.warnings: error_messages_text = ( - error_messages_text + "\n" + "\n".join(validation_result.warnings) + error_messages_text + + "\n" + + "\n".join(validation_result.warnings) ) raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, diff --git a/litellm/proxy/management_endpoints/team_endpoints.py b/litellm/proxy/management_endpoints/team_endpoints.py index 63db2d72fe4..c77b60649ab 100644 --- a/litellm/proxy/management_endpoints/team_endpoints.py +++ b/litellm/proxy/management_endpoints/team_endpoints.py @@ -497,18 +497,14 @@ async def _check_org_team_limits( # Validate team models against organization's allowed models if data.models is not None and len(org_table.models) > 0: - # If organization has 'all-proxy-models', skip validation as it allows all models - if SpecialModelNames.all_proxy_models.value in org_table.models: - pass - else: - for m in data.models: - if m not in org_table.models: - raise HTTPException( - status_code=400, - detail={ - "error": f"Model '{m}' not in organization's allowed models. Organization allowed models={org_table.models}. Organization: {org_table.organization_id}" - }, - ) + for m in data.models: + if m not in org_table.models: + raise HTTPException( + status_code=400, + detail={ + "error": f"Model '{m}' not in organization's allowed models. Organization allowed models={org_table.models}. Organization: {org_table.organization_id}" + }, + ) # Validate team TPM/RPM against organization's TPM/RPM limits (direct comparison) if ( @@ -1771,113 +1767,6 @@ async def _add_team_members_to_team( return updated_team, updated_users, updated_team_memberships -async def _validate_and_populate_member_user_info( - member: Member, - prisma_client: PrismaClient, -) -> Member: - """ - Validate and populate user_email/user_id for a member. - - Logic: - 1. If both user_email and user_id are provided, verify they belong to the same user (use user_email as source of truth) - 2. If only user_email is provided, populate user_id from DB - 3. If only user_id is provided, populate user_email from DB (if user exists) - 4. If only user_id is provided and doesn't exist, allow it to pass with user_email as None (will be upserted later) - 5. If user_email and user_id mismatch, throw error - - Returns a Member with user_email and user_id populated (user_email may be None if only user_id provided and user doesn't exist). - """ - if member.user_email is None and member.user_id is None: - raise HTTPException( - status_code=400, - detail={"error": "Either user_id or user_email must be provided"}, - ) - - # Case 1: Both user_email and user_id provided - verify they match - if member.user_email is not None and member.user_id is not None: - # Use user_email as source of truth - # Check for multiple users with same email first - users_by_email = await prisma_client.get_data( - key_val={"user_email": member.user_email}, - table_name="user", - query_type="find_all", - ) - - if users_by_email is None or ( - isinstance(users_by_email, list) and len(users_by_email) == 0 - ): - # User doesn't exist yet - this is fine, will be created later - return member - - if isinstance(users_by_email, list) and len(users_by_email) > 1: - raise HTTPException( - status_code=400, - detail={ - "error": f"Multiple users found with email '{member.user_email}'. Please use 'user_id' instead." - }, - ) - - # Get the single user - user_by_email = users_by_email[0] - - # Verify the user_id matches - if user_by_email.user_id != member.user_id: - raise HTTPException( - status_code=400, - detail={ - "error": f"user_email '{member.user_email}' and user_id '{member.user_id}' do not belong to the same user." - }, - ) - - # Both match, return as is - return member - - # Case 2: Only user_email provided - populate user_id from DB - if member.user_email is not None and member.user_id is None: - user_by_email = await prisma_client.db.litellm_usertable.find_first( - where={"user_email": {"equals": member.user_email, "mode": "insensitive"}} - ) - - if user_by_email is None: - # User doesn't exist yet - this is fine, will be created later - return member - - # Check for multiple users with same email - users_by_email = await prisma_client.get_data( - key_val={"user_email": member.user_email}, - table_name="user", - query_type="find_all", - ) - - if users_by_email and isinstance(users_by_email, list) and len(users_by_email) > 1: - raise HTTPException( - status_code=400, - detail={ - "error": f"Multiple users found with email '{member.user_email}'. Please use 'user_id' instead." - }, - ) - - # Populate user_id - member.user_id = user_by_email.user_id - return member - - # Case 3: Only user_id provided - populate user_email from DB if user exists - if member.user_id is not None and member.user_email is None: - user_by_id = await prisma_client.db.litellm_usertable.find_unique( - where={"user_id": member.user_id} - ) - - if user_by_id is None: - # User doesn't exist yet - allow it to pass with user_email as None - # Will be upserted later with just user_id and null email - return member - - # Populate user_email - member.user_email = user_by_id.user_email - return member - - return member - @router.post( "/team/member_add", tags=["team management"], @@ -1953,19 +1842,6 @@ async def team_member_add( complete_team_data=complete_team_data, ) - # Validate and populate user_email/user_id for members before processing - if isinstance(data.member, Member): - await _validate_and_populate_member_user_info( - member=data.member, - prisma_client=prisma_client, - ) - elif isinstance(data.member, List): - for m in data.member: - await _validate_and_populate_member_user_info( - member=m, - prisma_client=prisma_client, - ) - updated_team, updated_users, updated_team_memberships = ( await _add_team_members_to_team( data=data, diff --git a/litellm/proxy/management_endpoints/ui_sso.py b/litellm/proxy/management_endpoints/ui_sso.py index 4048b3731c1..1756fe9c6f6 100644 --- a/litellm/proxy/management_endpoints/ui_sso.py +++ b/litellm/proxy/management_endpoints/ui_sso.py @@ -93,26 +93,6 @@ router = APIRouter() -def normalize_email(email: Optional[str]) -> Optional[str]: - """ - Normalize email address to lowercase for consistent storage and comparison. - - Email addresses should be treated as case-insensitive for SSO purposes, - even though RFC 5321 technically allows case-sensitive local parts. - This prevents issues where SSO providers return emails with different casing - than what's stored in the database. - - Args: - email: Email address to normalize, can be None - - Returns: - Lowercased email address, or None if input is None - """ - if email is None: - return None - return email.lower() if isinstance(email, str) else email - - def determine_role_from_groups( user_groups: List[str], role_mappings: "RoleMappings", @@ -415,7 +395,7 @@ def generic_response_convertor( display_name=get_nested_value( response, generic_user_display_name_attribute_name ), - email=normalize_email(get_nested_value(response, generic_user_email_attribute_name)), + email=get_nested_value(response, generic_user_email_attribute_name), first_name=get_nested_value(response, generic_user_first_name_attribute_name), last_name=get_nested_value(response, generic_user_last_name_attribute_name), provider=get_nested_value(response, generic_provider_attribute_name), @@ -751,7 +731,7 @@ async def get_user_info_from_db( if _id is not None and isinstance(_id, str): potential_user_ids.append(_id) - user_email = normalize_email( + user_email = ( getattr(result, "email", None) if not isinstance(result, dict) else result.get("email", None) @@ -826,8 +806,8 @@ def _build_sso_user_update_data( Returns: dict: Update data containing user_email and optionally user_role if valid - """ - update_data: dict = {"user_email": normalize_email(user_email)} + """ + update_data: dict = {"user_email": user_email} # Get SSO role from result and include if valid sso_role = getattr(result, "user_role", None) @@ -1219,7 +1199,7 @@ async def cli_poll_key(key_id: str, team_id: Optional[str] = None): max_budget=litellm.max_ui_session_budget, ) - # Generate CLI JWT on-demand (expiration configurable via LITELLM_CLI_JWT_EXPIRATION_HOURS) + # Generate CLI JWT on-demand (24hr expiration) # Pass selected team_id to ensure JWT has correct team jwt_token = ExperimentalUIJWTToken.get_cli_jwt_auth_token( user_info=user_info, team_id=team_id @@ -1336,7 +1316,7 @@ async def insert_sso_user( new_user_request = NewUserRequest( user_id=user_defined_values["user_id"], - user_email=normalize_email(user_defined_values["user_email"]), + user_email=user_defined_values["user_email"], user_role=user_defined_values["user_role"], # type: ignore max_budget=user_defined_values["max_budget"], budget_duration=user_defined_values["budget_duration"], @@ -2001,7 +1981,7 @@ def _get_user_email_and_id_from_result( """ Gets the user email and id from the OpenID result after validating the email domain """ - user_email: Optional[str] = normalize_email(getattr(result, "email", None)) + user_email: Optional[str] = getattr(result, "email", None) user_id: Optional[str] = ( getattr(result, "id", None) if result is not None else None ) @@ -2040,7 +2020,7 @@ def _get_user_email_and_id_from_result( "GENERIC_USER_ROLE_ATTRIBUTE", "role" ) user_id = getattr(result, "id", None) - user_email = normalize_email(getattr(result, "email", None)) + user_email = getattr(result, "email", None) if user_role is None: _role_from_attr = getattr(result, generic_user_role_attribute_name, None) # type: ignore if _role_from_attr is not None: @@ -2433,7 +2413,7 @@ def openid_from_response( response = response or {} verbose_proxy_logger.debug(f"Microsoft SSO Callback Response: {response}") openid_response = CustomOpenID( - email=normalize_email(response.get(MICROSOFT_USER_EMAIL_ATTRIBUTE) or response.get("mail")), + email=response.get(MICROSOFT_USER_EMAIL_ATTRIBUTE) or response.get("mail"), display_name=response.get(MICROSOFT_USER_DISPLAY_NAME_ATTRIBUTE), provider="microsoft", id=response.get(MICROSOFT_USER_ID_ATTRIBUTE), diff --git a/litellm/proxy/pass_through_endpoints/llm_passthrough_endpoints.py b/litellm/proxy/pass_through_endpoints/llm_passthrough_endpoints.py index c11dcd79bc8..b079e161519 100644 --- a/litellm/proxy/pass_through_endpoints/llm_passthrough_endpoints.py +++ b/litellm/proxy/pass_through_endpoints/llm_passthrough_endpoints.py @@ -16,7 +16,6 @@ from starlette.websockets import WebSocketState import litellm -from litellm import get_llm_provider from litellm._logging import verbose_proxy_logger from litellm.constants import ( ALLOWED_VERTEX_AI_PASSTHROUGH_HEADERS, @@ -1053,89 +1052,6 @@ async def bedrock_proxy_route( return received_value -def _resolve_vertex_model_from_router( - model_id: str, - llm_router: Optional[litellm.Router], - encoded_endpoint: str, - endpoint: str, - vertex_project: Optional[str], - vertex_location: Optional[str], -) -> Tuple[str, str, Optional[str], Optional[str]]: - """ - Resolve Vertex AI model configuration from router. - - Args: - model_id: The model ID extracted from the URL (e.g., "gcp/google/gemini-2.5-flash") - llm_router: The LiteLLM router instance - encoded_endpoint: The encoded endpoint path - endpoint: The original endpoint path - vertex_project: Current vertex project (may be from URL) - vertex_location: Current vertex location (may be from URL) - - Returns: - Tuple of (encoded_endpoint, endpoint, vertex_project, vertex_location) - with resolved values from router config - """ - if not llm_router: - return encoded_endpoint, endpoint, vertex_project, vertex_location - - try: - deployment = llm_router.get_available_deployment_for_pass_through(model=model_id) - if not deployment: - return encoded_endpoint, endpoint, vertex_project, vertex_location - - litellm_params = deployment.get("litellm_params", {}) - - # Always override with router config values (they take precedence over URL values) - config_vertex_project = litellm_params.get("vertex_project") - config_vertex_location = litellm_params.get("vertex_location") - if config_vertex_project: - vertex_project = config_vertex_project - if config_vertex_location: - vertex_location = config_vertex_location - - # Get the actual Vertex AI model name by stripping the provider prefix - # e.g., "vertex_ai/gemini-2.0-flash-exp" -> "gemini-2.0-flash-exp" - model_from_config = litellm_params.get("model", "") - if model_from_config: - - # get_llm_provider returns (model, custom_llm_provider, dynamic_api_key, api_base) - # For "vertex_ai/gemini-2.0-flash-exp" it returns: - # model="gemini-2.0-flash-exp", custom_llm_provider="vertex_ai" - actual_model, custom_llm_provider, _, _ = get_llm_provider( - model=model_from_config - ) - - # Log only non-sensitive information (model names and provider), never API keys or secrets. - safe_actual_model = actual_model - safe_custom_llm_provider = custom_llm_provider - verbose_proxy_logger.debug( - "get_llm_provider returned: actual_model=%s, custom_llm_provider=%s, model_id=%s", - safe_actual_model, - safe_custom_llm_provider, - model_id, - ) - - if actual_model and model_id != actual_model: - verbose_proxy_logger.debug( - "Resolved router model '%s' to '%s' (provider=%s) with project=%s, location=%s", - model_id, - actual_model, - custom_llm_provider, - vertex_project, - vertex_location, - ) - encoded_endpoint = encoded_endpoint.replace(model_id, actual_model) - endpoint = endpoint.replace(model_id, actual_model) - - except Exception as e: - verbose_proxy_logger.debug( - f"Error resolving vertex model from router for model {model_id}: {e}" - ) - - return encoded_endpoint, endpoint, vertex_project, vertex_location - - def _is_bedrock_agent_runtime_route(endpoint: str) -> bool: """ Return True, if the endpoint should be routed to the `bedrock-agent-runtime` endpoint. @@ -1596,11 +1512,8 @@ async def _prepare_vertex_auth_headers( if router_credentials is not None: vertex_credentials_str = None elif vertex_credentials is not None: - # Only override vertex_project and vertex_location if they're not already set from router config - if vertex_project is None: - vertex_project = vertex_credentials.vertex_project - if vertex_location is None: - vertex_location = vertex_credentials.vertex_location + vertex_project = vertex_credentials.vertex_project + vertex_location = vertex_credentials.vertex_location vertex_credentials_str = vertex_credentials.vertex_credentials else: raise ValueError("No vertex credentials found") @@ -1670,7 +1583,6 @@ async def _base_vertex_proxy_route( get_vertex_model_id_from_url, get_vertex_project_id_from_url, ) - from litellm.proxy.proxy_server import llm_router encoded_endpoint = httpx.URL(endpoint).path verbose_proxy_logger.debug("requested endpoint %s", endpoint) @@ -1698,20 +1610,24 @@ async def _base_vertex_proxy_route( vertex_location=vertex_location, ) - # Check if model is in router config - always do this to resolve custom model names - model_id = get_vertex_model_id_from_url(endpoint) - if model_id: - - if llm_router: - # Resolve model configuration from router - encoded_endpoint, endpoint, vertex_project, vertex_location = _resolve_vertex_model_from_router( - model_id=model_id, - llm_router=llm_router, - encoded_endpoint=encoded_endpoint, - endpoint=endpoint, - vertex_project=vertex_project, - vertex_location=vertex_location, - ) + if vertex_project is None or vertex_location is None: + # Check if model is in router config + model_id = get_vertex_model_id_from_url(endpoint) + if model_id: + from litellm.proxy.proxy_server import llm_router + + if llm_router: + try: + # Use the dedicated pass-through deployment selection method to automatically filter use_in_pass_through=True + deployment = llm_router.get_available_deployment_for_pass_through(model=model_id) + if deployment: + litellm_params = deployment.get("litellm_params", {}) + vertex_project = litellm_params.get("vertex_project") + vertex_location = litellm_params.get("vertex_location") + except Exception as e: + verbose_proxy_logger.debug( + f"Error getting available deployment for model {model_id}: {e}" + ) vertex_credentials = passthrough_endpoint_router.get_vertex_credentials( project_id=vertex_project, diff --git a/litellm/proxy/proxy_cli.py b/litellm/proxy/proxy_cli.py index 2bc1c8f8e98..2059246674b 100644 --- a/litellm/proxy/proxy_cli.py +++ b/litellm/proxy/proxy_cli.py @@ -127,7 +127,6 @@ def _get_default_unvicorn_init_args( Get the arguments for `uvicorn` worker """ import litellm - from litellm._logging import _get_uvicorn_json_log_config uvicorn_args = { "app": "litellm.proxy.proxy_server:app", @@ -138,8 +137,8 @@ def _get_default_unvicorn_init_args( print(f"Using log_config: {log_config}") # noqa uvicorn_args["log_config"] = log_config elif litellm.json_logs: - # Use JSON log config for uvicorn to ensure all logs (including exceptions) are JSON - uvicorn_args["log_config"] = _get_uvicorn_json_log_config() + print("Using json logs. Setting log_config to None.") # noqa + uvicorn_args["log_config"] = None if keepalive_timeout is not None: uvicorn_args["timeout_keep_alive"] = keepalive_timeout return uvicorn_args diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 53b10e03e13..8268e612bfb 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -11,7 +11,7 @@ import time import traceback import warnings -from datetime import datetime, timedelta, timezone +from datetime import datetime, timedelta from typing import ( TYPE_CHECKING, Any, @@ -550,9 +550,9 @@ def generate_feedback_box(): server_root_path = get_server_root_path() _license_check = LicenseCheck() premium_user: bool = _license_check.is_premium() -premium_user_data: Optional[ - "EnterpriseLicenseData" -] = _license_check.airgapped_license_data +premium_user_data: Optional["EnterpriseLicenseData"] = ( + _license_check.airgapped_license_data +) global_max_parallel_request_retries_env: Optional[str] = os.getenv( "LITELLM_GLOBAL_MAX_PARALLEL_REQUEST_RETRIES" ) @@ -825,7 +825,6 @@ async def proxy_startup_event(app: FastAPI): # noqa: PLR0915 title=_title, description=_description, version=version, - root_path=server_root_path, lifespan=proxy_startup_event, # type: ignore[reportGeneralTypeIssues] ) @@ -1210,9 +1209,9 @@ async def root_redirect(): config_agents: Optional[List[AgentConfig]] = None otel_logging = False prisma_client: Optional[PrismaClient] = None -shared_aiohttp_session: Optional[ - "ClientSession" -] = None # Global shared session for connection reuse +shared_aiohttp_session: Optional["ClientSession"] = ( + None # Global shared session for connection reuse +) user_api_key_cache = DualCache( default_in_memory_ttl=UserAPIKeyCacheTTLEnum.in_memory_cache_ttl.value ) @@ -1220,11 +1219,10 @@ async def root_redirect(): dual_cache=user_api_key_cache ) litellm.logging_callback_manager.add_litellm_callback(model_max_budget_limiter) -redis_usage_cache: Optional[ - RedisCache -] = None # redis cache used for tracking spend, tpm/rpm limits +redis_usage_cache: Optional[RedisCache] = ( + None # redis cache used for tracking spend, tpm/rpm limits +) polling_via_cache_enabled: Union[Literal["all"], List[str], bool] = False -native_background_mode: List[str] = [] # Models that should use native provider background mode instead of polling polling_cache_ttl: int = 3600 # Default 1 hour TTL for polling cache user_custom_auth = None user_custom_key_generate = None @@ -1562,9 +1560,9 @@ async def _update_team_cache(): _id = "team_id:{}".format(team_id) try: # Fetch the existing cost for the given user - existing_spend_obj: Optional[ - LiteLLM_TeamTable - ] = await user_api_key_cache.async_get_cache(key=_id) + existing_spend_obj: Optional[LiteLLM_TeamTable] = ( + await user_api_key_cache.async_get_cache(key=_id) + ) if existing_spend_obj is None: # do nothing if team not in api key cache return @@ -2457,17 +2455,14 @@ async def load_config( # noqa: PLR0915 pass elif key == "responses": # Initialize global polling via cache settings - global polling_via_cache_enabled, native_background_mode, polling_cache_ttl + global polling_via_cache_enabled, polling_cache_ttl background_mode = value.get("background_mode", {}) polling_via_cache_enabled = background_mode.get( "polling_via_cache", False ) - native_background_mode = background_mode.get( - "native_background_mode", [] - ) polling_cache_ttl = background_mode.get("ttl", 3600) verbose_proxy_logger.debug( - f"{blue_color_code} Initialized polling via cache: enabled={polling_via_cache_enabled}, native_background_mode={native_background_mode}, ttl={polling_cache_ttl}{reset_color_code}" + f"{blue_color_code} Initialized polling via cache: enabled={polling_via_cache_enabled}, ttl={polling_cache_ttl}{reset_color_code}" ) elif key == "default_team_settings": for idx, team_setting in enumerate( @@ -2731,15 +2726,15 @@ async def load_config( # noqa: PLR0915 router_settings = config.get("router_settings", None) if router_settings and isinstance(router_settings, dict): + arg_spec = inspect.getfullargspec(litellm.Router) # model list and search_tools already set exclude_args = { + "self", "model_list", "search_tools", } - available_args = [ - x for x in litellm.Router.get_valid_args() if x not in exclude_args - ] + available_args = [x for x in arg_spec.args if x not in exclude_args] for k, v in router_settings.items(): if k in available_args: @@ -2861,7 +2856,6 @@ async def _init_policy_engine( from litellm.proxy.policy_engine.init_policies import init_policies from litellm.proxy.policy_engine.policy_validator import PolicyValidator - if config is None: verbose_proxy_logger.debug("Policy engine: config is None, skipping") return @@ -2873,9 +2867,7 @@ async def _init_policy_engine( policy_attachments_config = config.get("policy_attachments", None) - verbose_proxy_logger.info( - f"Policy engine: found {len(policies_config)} policies in config" - ) + verbose_proxy_logger.info(f"Policy engine: found {len(policies_config)} policies in config") # Initialize policies await init_policies( @@ -3544,79 +3536,6 @@ def _add_general_settings_from_db_config( llm_router=llm_router, ) - async def _reschedule_spend_log_cleanup_job(self): - """ - Reschedule the spend log cleanup job based on current general_settings. - This is called when maximum_spend_logs_retention_period is updated dynamically. - If the retention period is None, the job will be removed. - """ - global scheduler, general_settings, prisma_client - if scheduler is None: - return - - # Remove existing job if it exists - try: - scheduler.remove_job("spend_log_cleanup_job") - verbose_proxy_logger.info("Removed existing spend log cleanup job") - except Exception: - pass # Job might not exist, which is fine - - # Schedule new job if retention period is set (not None) - retention_period = general_settings.get("maximum_spend_logs_retention_period") - if retention_period is not None: - from litellm.proxy.db.db_transaction_queue.spend_log_cleanup import ( - SpendLogCleanup, - ) - - spend_log_cleanup = SpendLogCleanup() - cleanup_cron = general_settings.get("maximum_spend_logs_cleanup_cron") - - if cleanup_cron: - from apscheduler.triggers.cron import CronTrigger - - try: - cron_trigger = CronTrigger.from_crontab(cleanup_cron) - scheduler.add_job( - spend_log_cleanup.cleanup_old_spend_logs, - cron_trigger, - args=[prisma_client], - id="spend_log_cleanup_job", - replace_existing=True, - misfire_grace_time=APSCHEDULER_MISFIRE_GRACE_TIME, - ) - verbose_proxy_logger.info( - f"Spend log cleanup rescheduled with cron: {cleanup_cron}" - ) - except ValueError: - verbose_proxy_logger.error( - f"Invalid maximum_spend_logs_cleanup_cron value: {cleanup_cron}" - ) - else: - # Interval-based scheduling (existing behavior) - from litellm.litellm_core_utils.duration_parser import duration_in_seconds - - retention_interval = general_settings.get( - "maximum_spend_logs_retention_interval", "1d" - ) - try: - interval_seconds = duration_in_seconds(retention_interval) - scheduler.add_job( - spend_log_cleanup.cleanup_old_spend_logs, - "interval", - seconds=interval_seconds + random.randint(0, 60), - args=[prisma_client], - id="spend_log_cleanup_job", - replace_existing=True, - misfire_grace_time=APSCHEDULER_MISFIRE_GRACE_TIME, - ) - verbose_proxy_logger.info( - f"Spend log cleanup rescheduled with interval: {retention_interval}" - ) - except ValueError: - verbose_proxy_logger.error( - "Invalid maximum_spend_logs_retention_interval value" - ) - async def _update_general_settings(self, db_general_settings: Optional[Json]): """ Pull from DB, read general settings value @@ -3656,32 +3575,6 @@ async def _update_general_settings(self, db_general_settings: Optional[Json]): if "ui_access_mode" in _general_settings: general_settings["ui_access_mode"] = _general_settings["ui_access_mode"] - ## STORE PROMPTS IN SPEND LOGS ## - if "store_prompts_in_spend_logs" in _general_settings: - value = _general_settings["store_prompts_in_spend_logs"] - # Normalize case: handle True/true/TRUE, False/false/FALSE, None/null - if value is None: - general_settings["store_prompts_in_spend_logs"] = None - elif isinstance(value, bool): - general_settings["store_prompts_in_spend_logs"] = value - elif isinstance(value, str): - # Case-insensitive string comparison - general_settings["store_prompts_in_spend_logs"] = ( - value.lower() == "true" - ) - else: - # For other types, convert to bool - general_settings["store_prompts_in_spend_logs"] = bool(value) - - ## MAXIMUM SPEND LOGS RETENTION PERIOD ## - if "maximum_spend_logs_retention_period" in _general_settings: - old_value = general_settings.get("maximum_spend_logs_retention_period") - new_value = _general_settings["maximum_spend_logs_retention_period"] - general_settings["maximum_spend_logs_retention_period"] = new_value - # Reschedule cleanup job if value changed (including when set to None) - if old_value != new_value: - await self._reschedule_spend_log_cleanup_job() - def _update_config_fields( self, current_config: dict, @@ -4116,10 +4009,10 @@ async def _init_guardrails_in_db(self, prisma_client: PrismaClient): ) try: - guardrails_in_db: List[ - Guardrail - ] = await GuardrailRegistry.get_all_guardrails_from_db( - prisma_client=prisma_client + guardrails_in_db: List[Guardrail] = ( + await GuardrailRegistry.get_all_guardrails_from_db( + prisma_client=prisma_client + ) ) verbose_proxy_logger.debug( "guardrails from the DB %s", str(guardrails_in_db) @@ -4153,9 +4046,7 @@ async def _init_policies_in_db(self, prisma_client: PrismaClient): await policy_registry.sync_policies_from_db(prisma_client=prisma_client) # Sync attachments from DB to in-memory registry - await attachment_registry.sync_attachments_from_db( - prisma_client=prisma_client - ) + await attachment_registry.sync_attachments_from_db(prisma_client=prisma_client) verbose_proxy_logger.debug( "Successfully synced policies and attachments from DB" @@ -4478,9 +4369,9 @@ async def initialize( # noqa: PLR0915 user_api_base = api_base dynamic_config[user_model]["api_base"] = api_base if api_version: - os.environ[ - "AZURE_API_VERSION" - ] = api_version # set this for azure - litellm can read this from the env + os.environ["AZURE_API_VERSION"] = ( + api_version # set this for azure - litellm can read this from the env + ) if max_tokens: # model-specific param dynamic_config[user_model]["max_tokens"] = max_tokens if temperature: # model-specific param @@ -4791,7 +4682,7 @@ async def initialize_scheduled_background_jobs( # noqa: PLR0915 proxy_logging_obj: ProxyLogging, ): """Initializes scheduled background jobs""" - global store_model_in_db, scheduler + global store_model_in_db # MEMORY LEAK FIX: Configure scheduler with optimized settings # Memray analysis showed APScheduler's normalize() and _apply_jitter() causing @@ -5201,20 +5092,7 @@ async def _setup_prisma_client( except Exception as e: raise e - try: - await prisma_client.connect() - except Exception as e: - if "P3018" in str(e) or "P3009" in str(e): - verbose_proxy_logger.debug( - "CRITICAL: DATABASE MIGRATION FAILED" - ) - verbose_proxy_logger.debug( - "Your database is in a 'dirty' state." - ) - verbose_proxy_logger.debug( - "FIX: Run 'prisma migrate resolve --applied '" - ) - raise e + await prisma_client.connect() ## Start RDS IAM token refresh background task if enabled ## # This proactively refreshes IAM tokens before they expire, @@ -5339,9 +5217,7 @@ async def model_list( # Include model access groups if requested if include_model_access_groups: - proxy_model_list = list( - set(proxy_model_list + list(model_access_groups.keys())) - ) + proxy_model_list = list(set(proxy_model_list + list(model_access_groups.keys()))) # Get complete model list including wildcard routes if requested from litellm.proxy.auth.model_checks import get_complete_model_list @@ -7853,12 +7729,12 @@ def _enrich_model_info_with_litellm_data( """ Enrich a model dictionary with litellm model info (pricing, context window, etc.) and remove sensitive information. - + Args: model: Model dictionary to enrich debug: Whether to include debug information like openai_client llm_router: Optional router instance for debug info - + Returns: Enriched model dictionary with sensitive info removed """ @@ -7868,7 +7744,9 @@ def _enrich_model_info_with_litellm_data( _openai_client = "None" if llm_router is not None: _openai_client = ( - llm_router._get_client(deployment=model, kwargs={}, client_type="async") + llm_router._get_client( + deployment=model, kwargs={}, client_type="async" + ) or "None" ) else: @@ -7916,463 +7794,6 @@ def _enrich_model_info_with_litellm_data( return model -async def _apply_search_filter_to_models( - all_models: List[Dict[str, Any]], - search: str, - page: int, - size: int, - prisma_client: Optional[Any], - proxy_config: Any, - sort_by: Optional[str] = None, -) -> Tuple[List[Dict[str, Any]], Optional[int]]: - """ - Apply search filter to models, querying database for additional matching models. - - Args: - all_models: List of models to filter - search: Search term (case-insensitive) - page: Current page number - size: Page size - prisma_client: Prisma client for database queries - proxy_config: Proxy config for decrypting models - sort_by: Optional sort field - if provided, fetch all matching models instead of paginating at DB level - - Returns: - Tuple of (filtered_models, total_count). total_count is None if not searching. - """ - if not search or not search.strip(): - return all_models, None - - search_lower = search.lower().strip() - - # Filter models in router by search term - filtered_router_models = [ - m for m in all_models if search_lower in m.get("model_name", "").lower() - ] - - # Separate filtered models into config vs db models, and track db model IDs - filtered_config_models = [] - db_model_ids_in_router = set() - - for m in filtered_router_models: - model_info = m.get("model_info", {}) - is_db_model = model_info.get("db_model", False) - model_id = model_info.get("id") - - if is_db_model and model_id: - db_model_ids_in_router.add(model_id) - else: - filtered_config_models.append(m) - - config_models_count = len(filtered_config_models) - db_models_in_router_count = len(db_model_ids_in_router) - router_models_count = config_models_count + db_models_in_router_count - - # Query database for additional models with search term - db_models = [] - db_models_total_count = 0 - models_needed_for_page = size * page - - # Only query database if prisma_client is available - if prisma_client is not None: - try: - # Build where condition for database query - db_where_condition: Dict[str, Any] = { - "model_name": { - "contains": search_lower, - "mode": "insensitive", - } - } - # Exclude models already in router if we have any - if db_model_ids_in_router: - db_where_condition["model_id"] = { - "not": {"in": list(db_model_ids_in_router)} - } - - # Get total count of matching database models - db_models_total_count = ( - await prisma_client.db.litellm_proxymodeltable.count( - where=db_where_condition - ) - ) - - # Calculate total count for search results - search_total_count = router_models_count + db_models_total_count - - # If sorting is requested, we need to fetch ALL matching models to sort correctly - # Otherwise, we can optimize by only fetching what's needed for the current page - if sort_by: - # Fetch all matching database models for sorting - if db_models_total_count > 0: - db_models_raw = ( - await prisma_client.db.litellm_proxymodeltable.find_many( - where=db_where_condition, - take=db_models_total_count, # Fetch all matching models - ) - ) - - # Convert database models to router format - for db_model in db_models_raw: - decrypted_models = proxy_config.decrypt_model_list_from_db( - [db_model] - ) - if decrypted_models: - db_models.extend(decrypted_models) - else: - # Fetch database models if we need more for the current page - if router_models_count < models_needed_for_page: - models_to_fetch = min( - models_needed_for_page - router_models_count, db_models_total_count - ) - - if models_to_fetch > 0: - db_models_raw = ( - await prisma_client.db.litellm_proxymodeltable.find_many( - where=db_where_condition, - take=models_to_fetch, - ) - ) - - # Convert database models to router format - for db_model in db_models_raw: - decrypted_models = proxy_config.decrypt_model_list_from_db( - [db_model] - ) - if decrypted_models: - db_models.extend(decrypted_models) - except Exception as e: - verbose_proxy_logger.exception( - f"Error querying database models with search: {str(e)}" - ) - # If error, use router models count as fallback - search_total_count = router_models_count - else: - # If no prisma_client, only use router models - search_total_count = router_models_count - - # Combine all models - filtered_models = filtered_router_models + db_models - return filtered_models, search_total_count - - -def _normalize_datetime_for_sorting(dt: Any) -> Optional[datetime]: - """ - Normalize a datetime value to a timezone-aware UTC datetime for sorting. - - This function handles: - - None values: returns None - - String values: parses ISO format strings and converts to UTC-aware datetime - - Datetime objects: converts naive datetimes to UTC-aware, and aware datetimes to UTC - - Args: - dt: Datetime value (None, str, or datetime object) - - Returns: - UTC-aware datetime object, or None if input is None or cannot be parsed - """ - if dt is None: - return None - - if isinstance(dt, str): - try: - # Handle ISO format strings, including 'Z' suffix - dt_str = dt.replace("Z", "+00:00") if dt.endswith("Z") else dt - parsed_dt = datetime.fromisoformat(dt_str) - # Ensure it's UTC-aware - if parsed_dt.tzinfo is None: - parsed_dt = parsed_dt.replace(tzinfo=timezone.utc) - else: - parsed_dt = parsed_dt.astimezone(timezone.utc) - return parsed_dt - except (ValueError, AttributeError): - return None - - if isinstance(dt, datetime): - # If naive, assume UTC and make it aware - if dt.tzinfo is None: - return dt.replace(tzinfo=timezone.utc) - # If aware, convert to UTC - return dt.astimezone(timezone.utc) - - return None - - -def _sort_models( - all_models: List[Dict[str, Any]], - sort_by: Optional[str], - sort_order: str = "asc", -) -> List[Dict[str, Any]]: - """ - Sort models by the specified field and order. - - Args: - all_models: List of models to sort - sort_by: Field to sort by (model_name, created_at, updated_at, costs, status) - sort_order: Sort order (asc or desc) - - Returns: - Sorted list of models - """ - if not sort_by or sort_by not in ["model_name", "created_at", "updated_at", "costs", "status"]: - return all_models - - reverse = sort_order.lower() == "desc" - - def get_sort_key(model: Dict[str, Any]) -> Any: - model_info = model.get("model_info", {}) - - if sort_by == "model_name": - return model.get("model_name", "").lower() - - elif sort_by == "created_at": - created_at = model_info.get("created_at") - normalized_dt = _normalize_datetime_for_sorting(created_at) - if normalized_dt is None: - # Put None values at the end for asc, at the start for desc - return (datetime.max.replace(tzinfo=timezone.utc) if not reverse else datetime.min.replace(tzinfo=timezone.utc)) - return normalized_dt - - elif sort_by == "updated_at": - updated_at = model_info.get("updated_at") - normalized_dt = _normalize_datetime_for_sorting(updated_at) - if normalized_dt is None: - return (datetime.max.replace(tzinfo=timezone.utc) if not reverse else datetime.min.replace(tzinfo=timezone.utc)) - return normalized_dt - - elif sort_by == "costs": - input_cost = model_info.get("input_cost_per_token", 0) or 0 - output_cost = model_info.get("output_cost_per_token", 0) or 0 - total_cost = input_cost + output_cost - # Put 0 or None costs at the end for asc, at the start for desc - if total_cost == 0: - return (float("inf") if not reverse else float("-inf")) - return total_cost - - elif sort_by == "status": - # False (config) comes before True (db) for asc - db_model = model_info.get("db_model", False) - return db_model - - return None - - try: - sorted_models = sorted(all_models, key=get_sort_key, reverse=reverse) - return sorted_models - except Exception as e: - verbose_proxy_logger.exception(f"Error sorting models by {sort_by}: {str(e)}") - return all_models - - -def _paginate_models_response( - all_models: List[Dict[str, Any]], - page: int, - size: int, - total_count: Optional[int], - search: Optional[str], -) -> Dict[str, Any]: - """ - Paginate models and return response dictionary. - - Args: - all_models: List of all models - page: Current page number - size: Page size - total_count: Total count (if None, uses len(all_models)) - search: Search term (for logging) - - Returns: - Paginated response dictionary - """ - if total_count is None: - total_count = len(all_models) - - skip = (page - 1) * size - total_pages = -(-total_count // size) if total_count > 0 else 0 - paginated_models = all_models[skip : skip + size] - - verbose_proxy_logger.debug( - f"Pagination: skip={skip}, take={size}, total_count={total_count}, total_pages={total_pages}, search={search}" - ) - - return { - "data": paginated_models, - "total_count": total_count, - "current_page": page, - "total_pages": total_pages, - "size": size, - } - - -async def _filter_models_by_team_id( - all_models: List[Dict[str, Any]], - team_id: str, - prisma_client: PrismaClient, - llm_router: Router, -) -> List[Dict[str, Any]]: - """ - Filter models by team ID. Returns models where: - - direct_access is True, OR - - team_id is in access_via_team_ids - - Also searches config and database for models accessible to the team. - - Args: - all_models: List of models to filter - team_id: Team ID to filter by - prisma_client: Prisma client for database queries - llm_router: Router instance for config queries - - Returns: - Filtered list of models - """ - # Get team from database - try: - team_db_object = await prisma_client.db.litellm_teamtable.find_unique( - where={"team_id": team_id} - ) - if team_db_object is None: - verbose_proxy_logger.warning(f"Team {team_id} not found in database") - # If team doesn't exist, return empty list - return [] - - team_object = LiteLLM_TeamTable(**team_db_object.model_dump()) - except Exception as e: - verbose_proxy_logger.exception(f"Error fetching team {team_id}: {str(e)}") - return [] - - # Get models accessible to this team (similar to _add_team_models_to_all_models) - team_accessible_model_ids: Set[str] = set() - - if ( - len(team_object.models) == 0 # empty list = all model access - or SpecialModelNames.all_proxy_models.value in team_object.models - ): - # Team has access to all models - model_list = llm_router.get_model_list() if llm_router else [] - if model_list is not None: - for model in model_list: - model_id = model.get("model_info", {}).get("id", None) - if model_id is None: - continue - # if team model id set, check if team id matches - team_model_id = model.get("model_info", {}).get("team_id", None) - can_add_model = False - if team_model_id is None: - can_add_model = True - elif team_model_id == team_id: - can_add_model = True - - if can_add_model: - team_accessible_model_ids.add(model_id) - else: - # Team has access to specific models - for model_name in team_object.models: - _models = ( - llm_router.get_model_list(model_name=model_name, team_id=team_id) - if llm_router - else [] - ) - if _models is not None: - for model in _models: - model_id = model.get("model_info", {}).get("id", None) - if model_id is not None: - team_accessible_model_ids.add(model_id) - - # Also search database for models accessible to this team - # This complements the config search done above - try: - if ( - team_object.models - and SpecialModelNames.all_proxy_models.value not in team_object.models - ): - # Team has specific models - check database for those model names - db_models = await prisma_client.db.litellm_proxymodeltable.find_many( - where={"model_name": {"in": team_object.models}} - ) - for db_model in db_models: - model_id = db_model.model_id - if model_id: - team_accessible_model_ids.add(model_id) - except Exception as e: - verbose_proxy_logger.debug( - f"Error querying database models for team {team_id}: {str(e)}" - ) - - # Filter models based on direct_access or access_via_team_ids - # Models are already enriched with these fields before this function is called - filtered_models = [] - for _model in all_models: - model_info = _model.get("model_info", {}) - model_id = model_info.get("id", None) - - # Include if direct_access is True - if model_info.get("direct_access", False): - filtered_models.append(_model) - continue - - # Include if team_id is in access_via_team_ids - access_via_team_ids = model_info.get("access_via_team_ids", []) - if isinstance(access_via_team_ids, list) and team_id in access_via_team_ids: - filtered_models.append(_model) - continue - - # Also include if model_id is in team_accessible_model_ids (from config/db search) - # This catches models that might not have been enriched with access_via_team_ids yet - if model_id and model_id in team_accessible_model_ids: - filtered_models.append(_model) - - return filtered_models - - -async def _find_model_by_id( - model_id: str, - search: Optional[str], - llm_router, - prisma_client, - proxy_config, -) -> tuple[list, Optional[int]]: - """Find a model by its ID and optionally filter by search term.""" - found_model = None - - # First, search in config - if llm_router is not None: - found_model = llm_router.get_model_info(id=model_id) - if found_model: - found_model = copy.deepcopy(found_model) - - # If not found in config, search in database - if found_model is None: - try: - db_model = await prisma_client.db.litellm_proxymodeltable.find_unique( - where={"model_id": model_id} - ) - if db_model: - # Convert database model to router format - decrypted_models = proxy_config.decrypt_model_list_from_db( - [db_model] - ) - if decrypted_models: - found_model = decrypted_models[0] - except Exception as e: - verbose_proxy_logger.exception( - f"Error querying database for modelId {model_id}: {str(e)}" - ) - - # If model found, verify search filter if provided - if found_model is not None: - if search is not None and search.strip(): - search_lower = search.lower().strip() - model_name = found_model.get("model_name", "") - if search_lower not in model_name.lower(): - # Model found but doesn't match search filter - found_model = None - - # Set all_models to the found model or empty list - all_models = [found_model] if found_model is not None else [] - search_total_count: Optional[int] = len(all_models) - return all_models, search_total_count - - @router.get( "/v2/model/info", description="v2 - returns models available to the user based on their API key permissions. Shows model info from config.yaml (except api key and api base). Filter to just user-added models with ?user_models_only=true", @@ -8394,24 +7815,6 @@ async def model_info_v2( debug: Optional[bool] = False, page: int = Query(1, description="Page number", ge=1), size: int = Query(50, description="Page size", ge=1), - search: Optional[str] = fastapi.Query( - None, description="Search model names (case-insensitive partial match)" - ), - modelId: Optional[str] = fastapi.Query( - None, description="Search for a specific model by its unique ID" - ), - teamId: Optional[str] = fastapi.Query( - None, - description="Filter models by team ID. Returns models with direct_access=True or teamId in access_via_team_ids", - ), - sortBy: Optional[str] = fastapi.Query( - None, - description="Field to sort by. Options: model_name, created_at, updated_at, costs, status", - ), - sortOrder: Optional[str] = fastapi.Query( - "asc", - description="Sort order. Options: asc, desc", - ), ): """ BETA ENDPOINT. Might change unexpectedly. Use `/v1/model/info` for now. @@ -8436,37 +7839,14 @@ async def model_info_v2( # Load existing config await proxy_config.get_config() + all_models = copy.deepcopy(llm_router.model_list) - # If modelId is provided, search for the specific model - if modelId is not None: - all_models, search_total_count = await _find_model_by_id( - model_id=modelId, - search=search, - llm_router=llm_router, - prisma_client=prisma_client, - proxy_config=proxy_config, - ) - else: - # Normal flow when modelId is not provided - all_models = copy.deepcopy(llm_router.model_list) - - if user_model is not None: - # if user does not use a config.yaml, https://github.com/BerriAI/litellm/issues/2061 - all_models += [user_model] + if user_model is not None: + # if user does not use a config.yaml, https://github.com/BerriAI/litellm/issues/2061 + all_models += [user_model] - if model is not None: - all_models = [m for m in all_models if m["model_name"] == model] - - # Apply search filter if provided - all_models, search_total_count = await _apply_search_filter_to_models( - all_models=all_models, - search=search or "", - page=page, - size=size, - prisma_client=prisma_client, - proxy_config=proxy_config, - sort_by=sortBy, - ) + if model is not None: + all_models = [m for m in all_models if m["model_name"] == model] if user_models_only: all_models = await non_admin_all_models( @@ -8483,55 +7863,33 @@ async def model_info_v2( llm_router=llm_router, all_models=all_models, ) - - # Fill in model info based on config.yaml and litellm model_prices_and_context_window.json - # This must happen before teamId filtering so that direct_access and access_via_team_ids are populated + # fill in model info based on config.yaml and litellm model_prices_and_context_window.json for i, _model in enumerate(all_models): all_models[i] = _enrich_model_info_with_litellm_data( - model=_model, - debug=debug if debug is not None else False, - llm_router=llm_router, - ) - - # Apply teamId filter if provided - if teamId is not None and teamId.strip(): - all_models = await _filter_models_by_team_id( - all_models=all_models, - team_id=teamId.strip(), - prisma_client=prisma_client, - llm_router=llm_router, - ) - # Update search_total_count after teamId filter is applied - search_total_count = len(all_models) - - # If modelId was provided, update search_total_count after filters are applied - # to ensure pagination reflects the final filtered result (0 or 1) - if modelId is not None: - search_total_count = len(all_models) - - # Apply sorting before pagination - if sortBy: - # Validate sortOrder - if sortOrder and sortOrder.lower() not in ["asc", "desc"]: - raise HTTPException( - status_code=400, - detail=f"Invalid sortOrder: {sortOrder}. Must be 'asc' or 'desc'", - ) - all_models = _sort_models( - all_models=all_models, - sort_by=sortBy, - sort_order=sortOrder or "asc", + model=_model, debug=debug if debug is not None else False, llm_router=llm_router ) verbose_proxy_logger.debug("all_models: %s", all_models) - - return _paginate_models_response( - all_models=all_models, - page=page, - size=size, - total_count=search_total_count, - search=search, + + total_count = len(all_models) + + skip = (page - 1) * size + + total_pages = -(-total_count // size) if total_count > 0 else 0 + + paginated_models = all_models[skip : skip + size] + + verbose_proxy_logger.debug( + f"Pagination: skip={skip}, take={size}, total_count={total_count}, total_pages={total_pages}" ) + + return { + "data": paginated_models, + "total_count": total_count, + "current_page": page, + "total_pages": total_pages, + "size": size, + } @router.get( @@ -9987,7 +9345,7 @@ def get_logo_url(): @app.get("/get_image", include_in_schema=False) -async def get_image(): +def get_image(): """Get logo to show on admin UI""" # get current_dir @@ -10006,37 +9364,25 @@ async def get_image(): if is_non_root and not os.path.exists(default_logo): default_logo = default_site_logo - cache_dir = assets_dir if is_non_root else current_dir - cache_path = os.path.join(cache_dir, "cached_logo.jpg") - - # [OPTIMIZATION] Check if the cached image exists first - if os.path.exists(cache_path): - return FileResponse(cache_path, media_type="image/jpeg") - logo_path = os.getenv("UI_LOGO_PATH", default_logo) verbose_proxy_logger.debug("Reading logo from path: %s", logo_path) # Check if the logo path is an HTTP/HTTPS URL if logo_path.startswith(("http://", "https://")): - try: - # Download the image and cache it - from litellm.llms.custom_httpx.http_handler import AsyncHTTPHandler - - async_client = AsyncHTTPHandler(timeout=5.0) - response = await async_client.get(logo_path) - if response.status_code == 200: - # Save the image to a local file - with open(cache_path, "wb") as f: - f.write(response.content) - - # Return the cached image as a FileResponse - return FileResponse(cache_path, media_type="image/jpeg") - else: - # Handle the case when the image cannot be downloaded - return FileResponse(default_logo, media_type="image/jpeg") - except Exception as e: - # Handle any exceptions during the download (e.g., timeout, connection error) - verbose_proxy_logger.debug(f"Error downloading logo from {logo_path}: {e}") + # Download the image and cache it + client = HTTPHandler() + response = client.get(logo_path) + if response.status_code == 200: + # Save the image to a local file + cache_dir = assets_dir if is_non_root else current_dir + cache_path = os.path.join(cache_dir, "cached_logo.jpg") + with open(cache_path, "wb") as f: + f.write(response.content) + + # Return the cached image as a FileResponse + return FileResponse(cache_path, media_type="image/jpeg") + else: + # Handle the case when the image cannot be downloaded return FileResponse(default_logo, media_type="image/jpeg") else: # Return the local image file if the logo path is not an HTTP/HTTPS URL @@ -10654,9 +10000,9 @@ async def get_config_list( hasattr(sub_field_info, "description") and sub_field_info.description is not None ): - nested_fields[ - idx - ].field_description = sub_field_info.description + nested_fields[idx].field_description = ( + sub_field_info.description + ) idx += 1 _stored_in_db = None diff --git a/litellm/proxy/rag_endpoints/endpoints.py b/litellm/proxy/rag_endpoints/endpoints.py index 39909df8e9f..79b4fd6873d 100644 --- a/litellm/proxy/rag_endpoints/endpoints.py +++ b/litellm/proxy/rag_endpoints/endpoints.py @@ -26,196 +26,6 @@ router = APIRouter() -def _build_file_metadata_entry( - response: Any, - file_data: Optional[Tuple[str, bytes, str]] = None, - file_url: Optional[str] = None, -) -> Dict[str, Any]: - """ - Build a file metadata entry for storing in vector_store_metadata. - - Args: - response: The response from litellm.aingest containing file_id - file_data: Optional tuple of (filename, content, content_type) - file_url: Optional URL if file was ingested from URL - - Returns: - Dictionary with file metadata (file_id, filename, file_url, ingested_at, etc.) - """ - from datetime import datetime, timezone - - # Extract file_id from response - file_id = None - if hasattr(response, "get"): - file_id = response.get("file_id") - elif hasattr(response, "file_id"): - file_id = response.file_id - - # Extract file information from file_data tuple - filename = None - file_size = None - content_type = None - - if file_data: - filename = file_data[0] - file_size = len(file_data[1]) if len(file_data) > 1 else None - content_type = file_data[2] if len(file_data) > 2 else None - - # Build file metadata entry - file_entry = { - "file_id": file_id, - "filename": filename, - "file_url": file_url, - "ingested_at": datetime.now(timezone.utc).isoformat(), - } - - # Add optional fields if available - if file_size is not None: - file_entry["file_size"] = file_size - if content_type is not None: - file_entry["content_type"] = content_type - - return file_entry - - -async def _save_vector_store_to_db_from_rag_ingest( - response: Any, - ingest_options: Dict[str, Any], - prisma_client, - user_api_key_dict: UserAPIKeyAuth, - file_data: Optional[Tuple[str, bytes, str]] = None, - file_url: Optional[str] = None, -) -> None: - """ - Helper function to save a newly created vector store from RAG ingest to the database. - - This function: - - Extracts vector store ID and config from the ingest response - - Checks if the vector store already exists in the database - - Creates a new database entry if it doesn't exist - - Adds the vector store to the registry - - Tracks team_id and user_id for access control - - Args: - response: The response from litellm.aingest() - ingest_options: The ingest options containing vector store config - prisma_client: The Prisma database client - user_api_key_dict: User API key authentication info - """ - from litellm.proxy.vector_store_endpoints.management_endpoints import ( - create_vector_store_in_db, - ) - - # Handle both dict and object responses - if hasattr(response, "get"): - vector_store_id = response.get("vector_store_id") - elif hasattr(response, "vector_store_id"): - vector_store_id = response.vector_store_id - else: - verbose_proxy_logger.warning( - f"Unable to extract vector_store_id from response type: {type(response)}" - ) - return - - if vector_store_id is None or not isinstance(vector_store_id, str): - verbose_proxy_logger.warning( - "Vector store ID is None or not a string, skipping database save" - ) - return - - vector_store_config = ingest_options.get("vector_store", {}) - custom_llm_provider = vector_store_config.get("custom_llm_provider") - - # Extract litellm_vector_store_params for custom name and description - litellm_vector_store_params = ingest_options.get("litellm_vector_store_params", {}) - custom_vector_store_name = litellm_vector_store_params.get("vector_store_name") - custom_vector_store_description = litellm_vector_store_params.get("vector_store_description") - - # Extract provider-specific params from vector_store_config to save as litellm_params - # This ensures params like aws_region_name, embedding_model, etc. are available for search - provider_specific_params = {} - excluded_keys = {"custom_llm_provider", "vector_store_id"} - for key, value in vector_store_config.items(): - if key not in excluded_keys and value is not None: - provider_specific_params[key] = value - - # Build file metadata entry using helper - file_entry = _build_file_metadata_entry( - response=response, - file_data=file_data, - file_url=file_url, - ) - - try: - # Check if vector store already exists in database - existing_vector_store = ( - await prisma_client.db.litellm_managedvectorstorestable.find_unique( - where={"vector_store_id": vector_store_id} - ) - ) - - # Only create if it doesn't exist - if existing_vector_store is None: - verbose_proxy_logger.info( - f"Saving newly created vector store {vector_store_id} to database" - ) - - # Initialize metadata with first file - initial_metadata = { - "ingested_files": [file_entry] - } - - # Use custom name if provided, otherwise default - vector_store_name = custom_vector_store_name or f"RAG Vector Store - {vector_store_id[:8]}" - vector_store_description = custom_vector_store_description or "Created via RAG ingest endpoint" - - await create_vector_store_in_db( - vector_store_id=vector_store_id, - custom_llm_provider=custom_llm_provider or "openai", - prisma_client=prisma_client, - vector_store_name=vector_store_name, - vector_store_description=vector_store_description, - vector_store_metadata=initial_metadata, - litellm_params=provider_specific_params if provider_specific_params else None, - team_id=user_api_key_dict.team_id, - user_id=user_api_key_dict.user_id, - ) - - verbose_proxy_logger.info( - f"Vector store {vector_store_id} saved to database successfully" - ) - else: - verbose_proxy_logger.info( - f"Vector store {vector_store_id} already exists, appending file to metadata" - ) - - # Update existing vector store with new file - existing_metadata = existing_vector_store.vector_store_metadata or {} - if isinstance(existing_metadata, str): - import json - existing_metadata = json.loads(existing_metadata) - - ingested_files = existing_metadata.get("ingested_files", []) - ingested_files.append(file_entry) - existing_metadata["ingested_files"] = ingested_files - - # Update the vector store - from litellm.proxy.utils import safe_dumps - await prisma_client.db.litellm_managedvectorstorestable.update( - where={"vector_store_id": vector_store_id}, - data={"vector_store_metadata": safe_dumps(existing_metadata)} - ) - - verbose_proxy_logger.info( - f"Added file {file_entry.get('filename') or file_entry.get('file_url', 'Unknown')} to vector store {vector_store_id} metadata" - ) - except Exception as db_error: - # Log the error but don't fail the request since ingestion succeeded - verbose_proxy_logger.exception( - f"Failed to save vector store {vector_store_id} to database: {db_error}" - ) - - async def parse_rag_ingest_request( request: Request, ) -> Tuple[Dict[str, Any], Optional[Tuple[str, bytes, str]], Optional[str], Optional[str]]: @@ -348,7 +158,6 @@ async def rag_ingest( add_litellm_data_to_request, general_settings, llm_router, - prisma_client, proxy_config, version, ) @@ -380,25 +189,6 @@ async def rag_ingest( **request_data, ) - # Save vector store to database if it was newly created and prisma_client is available - verbose_proxy_logger.debug( - f"RAG Ingest - Checking database save conditions: prisma_client={prisma_client is not None}, response={response is not None}, response_type={type(response)}" - ) - - if prisma_client is not None and response is not None: - await _save_vector_store_to_db_from_rag_ingest( - response=response, - ingest_options=ingest_options, - prisma_client=prisma_client, - user_api_key_dict=user_api_key_dict, - file_data=file_data, - file_url=file_url, - ) - else: - verbose_proxy_logger.warning( - f"Skipping database save: prisma_client={prisma_client is not None}, response={response is not None}" - ) - return response except HTTPException: diff --git a/litellm/proxy/response_api_endpoints/endpoints.py b/litellm/proxy/response_api_endpoints/endpoints.py index 44e8c42b2c1..ec1bc5497bd 100644 --- a/litellm/proxy/response_api_endpoints/endpoints.py +++ b/litellm/proxy/response_api_endpoints/endpoints.py @@ -68,7 +68,6 @@ async def responses_api( _read_request_body, general_settings, llm_router, - native_background_mode, polling_cache_ttl, polling_via_cache_enabled, proxy_config, @@ -96,7 +95,6 @@ async def responses_api( redis_cache=redis_usage_cache, model=data.get("model", ""), llm_router=llm_router, - native_background_mode=native_background_mode, ) # If polling is enabled, use polling mode diff --git a/litellm/proxy/response_polling/polling_handler.py b/litellm/proxy/response_polling/polling_handler.py index f0b850049bf..c47578c8d7b 100644 --- a/litellm/proxy/response_polling/polling_handler.py +++ b/litellm/proxy/response_polling/polling_handler.py @@ -3,7 +3,7 @@ """ import json from datetime import datetime, timezone -from typing import Any, Dict, List, Optional +from typing import Any, Dict, Optional from litellm._logging import verbose_proxy_logger from litellm._uuid import uuid4 @@ -257,7 +257,6 @@ def should_use_polling_for_request( redis_cache, # RedisCache or None model: str, llm_router, # Router instance or None - native_background_mode: Optional[List[str]] = None, # List of models that should use native background mode ) -> bool: """ Determine if polling via cache should be used for a request. @@ -268,8 +267,6 @@ def should_use_polling_for_request( redis_cache: Redis cache instance (required for polling) model: Model name from the request (e.g., "gpt-5" or "openai/gpt-4o") llm_router: LiteLLM router instance for looking up model deployments - native_background_mode: List of model names that should use native provider - background mode instead of polling via cache Returns: True if polling should be used, False otherwise @@ -278,13 +275,6 @@ def should_use_polling_for_request( if not (background_mode and polling_via_cache_enabled and redis_cache): return False - # Check if model is in native_background_mode list - these use native provider background mode - if native_background_mode and model in native_background_mode: - verbose_proxy_logger.debug( - f"Model {model} is in native_background_mode list, skipping polling via cache" - ) - return False - # "all" enables polling for all providers if polling_via_cache_enabled == "all": return True diff --git a/litellm/proxy/route_llm_request.py b/litellm/proxy/route_llm_request.py index af441ee43e4..0e061a839d9 100644 --- a/litellm/proxy/route_llm_request.py +++ b/litellm/proxy/route_llm_request.py @@ -197,13 +197,7 @@ async def route_request( elif "user_config" in data: router_config = data.pop("user_config") - - # Filter router_config to only include valid Router.__init__ arguments - # This prevents TypeError when invalid parameters are stored in the database - valid_args = litellm.Router.get_valid_args() - filtered_config = {k: v for k, v in router_config.items() if k in valid_args} - - user_router = litellm.Router(**filtered_config) + user_router = litellm.Router(**router_config) ret_val = getattr(user_router, f"{route_type}")(**data) user_router.discard() return ret_val @@ -221,9 +215,8 @@ async def route_request( "aretrieve_container_file_content", ]: return getattr(llm_router, f"{route_type}")(**data) - # Interactions API: create with agent, get/delete/cancel don't need model routing + # Interactions API: get/delete/cancel don't need model routing if route_type in [ - "acreate_interaction", "aget_interaction", "adelete_interaction", "acancel_interaction", diff --git a/litellm/proxy/schema.prisma b/litellm/proxy/schema.prisma index b118400b620..d7aa6e9f0d0 100644 --- a/litellm/proxy/schema.prisma +++ b/litellm/proxy/schema.prisma @@ -5,7 +5,6 @@ datasource client { generator client { provider = "prisma-client-py" - binaryTargets = ["native", "debian-openssl-1.1.x", "debian-openssl-3.0.x", "linux-musl", "linux-musl-openssl-3.0.x"] } // Budget / Rate Limits for an org @@ -761,11 +760,6 @@ model LiteLLM_ManagedVectorStoresTable { updated_at DateTime @updatedAt litellm_credential_name String? litellm_params Json? - team_id String? - user_id String? - - @@index([team_id]) - @@index([user_id]) } // Guardrails table for storing guardrail configurations diff --git a/litellm/proxy/search_endpoints/endpoints.py b/litellm/proxy/search_endpoints/endpoints.py index c7a3b88c490..8cfc8bb5106 100644 --- a/litellm/proxy/search_endpoints/endpoints.py +++ b/litellm/proxy/search_endpoints/endpoints.py @@ -1,10 +1,9 @@ #### Search Endpoints ##### import orjson -from fastapi import APIRouter, Depends, HTTPException, Request, Response +from fastapi import APIRouter, Depends, Request, Response from fastapi.responses import ORJSONResponse -from litellm._logging import verbose_proxy_logger from litellm.proxy._types import * from litellm.proxy.auth.user_api_key_auth import UserAPIKeyAuth, user_api_key_auth from litellm.proxy.common_request_processing import ProxyBaseLLMRequestProcessing @@ -137,13 +136,6 @@ async def search( if llm_router is not None and hasattr(llm_router, "search_tools"): search_tool_name_value = data["search_tool_name"] - - verbose_proxy_logger.debug( - f"Search endpoint - Looking for search_tool_name: {search_tool_name_value}. " - f"Available search tools in router: {[tool.get('search_tool_name') for tool in llm_router.search_tools]}. " - f"Total search tools: {len(llm_router.search_tools)}" - ) - matching_tools = [ tool for tool in llm_router.search_tools if tool.get("search_tool_name") == search_tool_name_value @@ -189,75 +181,3 @@ async def search( version=version, ) -@router.get( - "/v1/search/tools", - dependencies=[Depends(user_api_key_auth)], - response_class=ORJSONResponse, - tags=["search"], -) -@router.get( - "/search/tools", - dependencies=[Depends(user_api_key_auth)], - response_class=ORJSONResponse, - tags=["search"], -) -async def list_search_tools( - request: Request, - fastapi_response: Response, - user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), -): - """ - List all available search tools configured in the router. - - This endpoint returns the search tools that are currently loaded and available - for use with the /v1/search endpoint. - - Example: - ```bash - curl -X GET "http://localhost:4000/v1/search/tools" \ - -H "Authorization: Bearer sk-1234" - ``` - - Response: - ```json - { - "object": "list", - "data": [ - { - "search_tool_name": "litellm-search", - "search_provider": "perplexity", - "description": "Perplexity search tool" - } - ] - } - ``` - """ - from litellm.proxy.proxy_server import llm_router - - try: - search_tools_list = [] - - if llm_router is not None and hasattr(llm_router, "search_tools"): - for tool in llm_router.search_tools: - tool_info = { - "search_tool_name": tool.get("search_tool_name"), - "search_provider": tool.get("litellm_params", {}).get("search_provider"), - } - - # Add description if available - if "search_tool_info" in tool and tool["search_tool_info"]: - description = tool["search_tool_info"].get("description") - if description: - tool_info["description"] = description - - search_tools_list.append(tool_info) - - return { - "object": "list", - "data": search_tools_list - } - except Exception as e: - from litellm._logging import verbose_proxy_logger - verbose_proxy_logger.exception(f"Error listing search tools: {e}") - raise HTTPException(status_code=500, detail=str(e)) - diff --git a/litellm/proxy/spend_tracking/spend_management_endpoints.py b/litellm/proxy/spend_tracking/spend_management_endpoints.py index 6e49e4244e7..dcdc17ef318 100644 --- a/litellm/proxy/spend_tracking/spend_management_endpoints.py +++ b/litellm/proxy/spend_tracking/spend_management_endpoints.py @@ -1681,9 +1681,6 @@ async def ui_view_spend_logs( # noqa: PLR0915 error_code: Optional[str] = fastapi.Query( default=None, description="Filter logs by error code (e.g., '404', '500')" ), - error_message: Optional[str] = fastapi.Query( - default=None, description="Filter logs by error message (partial string match)" - ), ): """ View spend logs with pagination support. @@ -1777,12 +1774,6 @@ def parse_date(date_str: str) -> datetime: "equals": f'"{error_code}"', }) - if error_message is not None: - metadata_filters.append({ - "path": ["error_information", "error_message"], - "string_contains": error_message, - }) - if metadata_filters: if len(metadata_filters) == 1: where_conditions["metadata"] = metadata_filters[0] diff --git a/litellm/proxy/spend_tracking/spend_tracking_utils.py b/litellm/proxy/spend_tracking/spend_tracking_utils.py index bd148ecb481..db4e4beec21 100644 --- a/litellm/proxy/spend_tracking/spend_tracking_utils.py +++ b/litellm/proxy/spend_tracking/spend_tracking_utils.py @@ -759,19 +759,10 @@ def _should_store_prompts_and_responses_in_spend_logs() -> bool: from litellm.proxy.proxy_server import general_settings from litellm.secret_managers.main import get_secret_bool - # Check general_settings (from DB or proxy_config.yaml) - store_prompts_value = general_settings.get("store_prompts_in_spend_logs") - - # Normalize case: handle True/true/TRUE, False/false/FALSE, None/null - if store_prompts_value is True: - return True - elif isinstance(store_prompts_value, str): - # Case-insensitive string comparison - if store_prompts_value.lower() == "true": - return True - - # Also check environment variable - return get_secret_bool("STORE_PROMPTS_IN_SPEND_LOGS") is True + return ( + general_settings.get("store_prompts_in_spend_logs") is True + or get_secret_bool("STORE_PROMPTS_IN_SPEND_LOGS") is True + ) def _get_status_for_spend_log( diff --git a/litellm/proxy/ui_crud_endpoints/proxy_setting_endpoints.py b/litellm/proxy/ui_crud_endpoints/proxy_setting_endpoints.py index 4a0268eeede..09c14bc42c1 100644 --- a/litellm/proxy/ui_crud_endpoints/proxy_setting_endpoints.py +++ b/litellm/proxy/ui_crud_endpoints/proxy_setting_endpoints.py @@ -78,11 +78,6 @@ class UISettings(BaseModel): description="Prevents Team Admins from deleting users from the teams they manage. Useful for SCIM provisioning where team membership is defined externally.", ) - enabled_ui_pages_internal_users: Optional[List[str]] = Field( - default=None, - description="List of page keys that internal users (non-admins) can see in the UI sidebar. If not set, all pages are visible based on role permissions.", - ) - class UISettingsResponse(SettingsResponse): """Response model for UI settings""" @@ -94,7 +89,6 @@ class UISettingsResponse(SettingsResponse): ALLOWED_UI_SETTINGS_FIELDS = { "disable_model_add_for_internal_users", "disable_team_admin_delete_team_user", - "enabled_ui_pages_internal_users", } diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index 8922ed032e2..5dcb0339739 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -982,9 +982,7 @@ async def _process_guardrail_callback( try: # Check if load balancing should be used - if guardrail_name and self._should_use_guardrail_load_balancing( - guardrail_name - ): + if guardrail_name and self._should_use_guardrail_load_balancing(guardrail_name): response = await self._execute_guardrail_with_load_balancing( guardrail_name=guardrail_name, hook_type="pre_call", @@ -1019,11 +1017,7 @@ async def _process_guardrail_callback( latency_seconds = guardrail_end_time - guardrail_start_time # Get guardrail name for metrics (fallback if not set) - metrics_guardrail_name = ( - guardrail_name - or getattr(callback, "guardrail_name", callback.__class__.__name__) - or "unknown" - ) + metrics_guardrail_name = guardrail_name or getattr(callback, "guardrail_name", callback.__class__.__name__) or "unknown" # Find PrometheusLogger in callbacks and record metrics for prom_callback in litellm.callbacks: @@ -1799,11 +1793,9 @@ async def post_call_success_hook( ################################################################# for callback in other_callbacks: - callback_response = await callback.async_post_call_success_hook( + await callback.async_post_call_success_hook( user_api_key_dict=user_api_key_dict, data=data, response=response ) - if callback_response is not None: - response = callback_response except Exception as e: raise e return response @@ -1860,14 +1852,16 @@ async def async_post_call_streaming_hook( complete_response = str_so_far + response_str else: complete_response = response_str - callback_response = ( + potential_error_response = ( await _callback.async_post_call_streaming_hook( user_api_key_dict=user_api_key_dict, response=complete_response, ) ) - if callback_response is not None: - response = callback_response + if isinstance( + potential_error_response, str + ) and potential_error_response.startswith("data: "): + return potential_error_response except Exception as e: raise e return response @@ -1901,18 +1895,7 @@ async def async_post_call_streaming_iterator_hook( ) or _callback.should_run_guardrail( data=request_data, event_type=GuardrailEventHooks.post_call ): - if ( - "async_post_call_streaming_iterator_hook" - in type(callback).__dict__ - ): - current_response = ( - _callback.async_post_call_streaming_iterator_hook( - user_api_key_dict=user_api_key_dict, - response=current_response, - request_data=request_data, - ) - ) - elif "apply_guardrail" in type(callback).__dict__: + if "apply_guardrail" in type(callback).__dict__: request_data["guardrail_to_apply"] = callback current_response = ( unified_guardrail.async_post_call_streaming_iterator_hook( @@ -2235,17 +2218,17 @@ async def _query_first_with_cached_plan_fallback( ) -> Optional[dict]: """ Execute a query with automatic fallback for PostgreSQL cached plan errors. - + This handles the "cached plan must not change result type" error that occurs during rolling deployments when schema changes are applied while old pods still have cached query plans expecting the old schema. - + Args: sql_query: SQL query string to execute - + Returns: Query result or None - + Raises: Original exception if not a cached plan error """ @@ -2258,7 +2241,7 @@ async def _query_first_with_cached_plan_fallback( # Add a unique comment to make the query different sql_query_retry = sql_query.replace( "SELECT", - f"SELECT /* cache_invalidated_{int(time.time() * 1000)} */", + f"SELECT /* cache_invalidated_{int(time.time() * 1000)} */" ) verbose_proxy_logger.warning( "PostgreSQL cached plan error detected for token lookup, " @@ -2600,9 +2583,7 @@ async def get_data( # noqa: PLR0915 WHERE v.token = '{token}' """ - response = await self._query_first_with_cached_plan_fallback( - sql_query - ) + response = await self._query_first_with_cached_plan_fallback(sql_query) if response is not None: if response["team_models"] is None: @@ -4246,7 +4227,7 @@ def get_server_root_path() -> str: - If SERVER_ROOT_PATH is set, return it. - Otherwise, default to "/". """ - return os.getenv("SERVER_ROOT_PATH", "") + return os.getenv("SERVER_ROOT_PATH", "/") def get_prisma_client_or_throw(message: str): diff --git a/litellm/proxy/vector_store_endpoints/endpoints.py b/litellm/proxy/vector_store_endpoints/endpoints.py index 9ba12537bc8..6e22d66c35d 100644 --- a/litellm/proxy/vector_store_endpoints/endpoints.py +++ b/litellm/proxy/vector_store_endpoints/endpoints.py @@ -18,54 +18,13 @@ ######################################################## -def _check_vector_store_access( - vector_store: LiteLLM_ManagedVectorStore, - user_api_key_dict: UserAPIKeyAuth, -) -> bool: - """ - Check if the user has access to the vector store based on team membership. - - Args: - vector_store: The vector store to check access for - user_api_key_dict: User API key authentication info - - Returns: - True if user has access, False otherwise - - Access rules: - - If vector store has no team_id, it's accessible to all (legacy behavior) - - If user's team_id matches the vector store's team_id, access is granted - - Otherwise, access is denied - """ - vector_store_team_id = vector_store.get("team_id") - - # If vector store has no team_id, it's accessible to all (legacy behavior) - if vector_store_team_id is None: - return True - - # Check if user's team matches the vector store's team - user_team_id = user_api_key_dict.team_id - if user_team_id == vector_store_team_id: - return True - - return False - - def _update_request_data_with_litellm_managed_vector_store_registry( data: Dict, vector_store_id: str, - user_api_key_dict: Optional[UserAPIKeyAuth] = None, ) -> Dict: """ Update the request data with the litellm managed vector store registry. - - Args: - data: Request data to update - vector_store_id: ID of the vector store - user_api_key_dict: User API key authentication info for access control - - Raises: - HTTPException: If user doesn't have access to the vector store + """ if litellm.vector_store_registry is not None: vector_store_to_run: Optional[LiteLLM_ManagedVectorStore] = ( @@ -74,14 +33,6 @@ def _update_request_data_with_litellm_managed_vector_store_registry( ) ) if vector_store_to_run is not None: - # Check access control if user_api_key_dict is provided - if user_api_key_dict is not None: - if not _check_vector_store_access(vector_store_to_run, user_api_key_dict): - raise HTTPException( - status_code=403, - detail="Access denied: You do not have permission to access this vector store", - ) - if "custom_llm_provider" in vector_store_to_run: data["custom_llm_provider"] = vector_store_to_run.get( "custom_llm_provider" @@ -137,7 +88,7 @@ async def vector_store_search( data["vector_store_id"] = vector_store_id data = _update_request_data_with_litellm_managed_vector_store_registry( - data=data, vector_store_id=vector_store_id, user_api_key_dict=user_api_key_dict + data=data, vector_store_id=vector_store_id ) processor = ProxyBaseLLMRequestProcessing(data=data) diff --git a/litellm/proxy/vector_store_endpoints/management_endpoints.py b/litellm/proxy/vector_store_endpoints/management_endpoints.py index 6185f1541fc..bc61a60fe5a 100644 --- a/litellm/proxy/vector_store_endpoints/management_endpoints.py +++ b/litellm/proxy/vector_store_endpoints/management_endpoints.py @@ -133,151 +133,6 @@ async def _resolve_embedding_config_from_db( return None -######################################################## -# Helper Functions -######################################################## -def _check_vector_store_access( - vector_store: LiteLLM_ManagedVectorStore, - user_api_key_dict: UserAPIKeyAuth, -) -> bool: - """ - Check if the user has access to the vector store based on team membership. - - Args: - vector_store: The vector store to check access for - user_api_key_dict: User API key authentication info - - Returns: - True if user has access, False otherwise - - Access rules: - - If vector store has no team_id, it's accessible to all (legacy behavior) - - If user's team_id matches the vector store's team_id, access is granted - - Otherwise, access is denied - """ - vector_store_team_id = vector_store.get("team_id") - - # If vector store has no team_id, it's accessible to all (legacy behavior) - if vector_store_team_id is None: - return True - - # Check if user's team matches the vector store's team - user_team_id = user_api_key_dict.team_id - if user_team_id == vector_store_team_id: - return True - - return False - - -async def create_vector_store_in_db( - vector_store_id: str, - custom_llm_provider: str, - prisma_client, - vector_store_name: Optional[str] = None, - vector_store_description: Optional[str] = None, - vector_store_metadata: Optional[Dict] = None, - litellm_params: Optional[Dict] = None, - litellm_credential_name: Optional[str] = None, - team_id: Optional[str] = None, - user_id: Optional[str] = None, -) -> LiteLLM_ManagedVectorStore: - """ - Helper function to create a vector store in the database. - - This function handles: - - Checking if vector store already exists - - Creating the vector store in the database - - Adding it to the vector store registry - - Returns: - LiteLLM_ManagedVectorStore: The created vector store object - - Raises: - HTTPException: If vector store already exists or database error occurs - """ - from litellm.types.router import GenericLiteLLMParams - - if prisma_client is None: - raise HTTPException(status_code=500, detail="Database not connected") - - # Check if vector store already exists - existing_vector_store = ( - await prisma_client.db.litellm_managedvectorstorestable.find_unique( - where={"vector_store_id": vector_store_id} - ) - ) - if existing_vector_store is not None: - raise HTTPException( - status_code=400, - detail=f"Vector store with ID {vector_store_id} already exists", - ) - - # Prepare data for database - data_to_create: Dict[str, Any] = { - "vector_store_id": vector_store_id, - "custom_llm_provider": custom_llm_provider, - } - - if vector_store_name is not None: - data_to_create["vector_store_name"] = vector_store_name - if vector_store_description is not None: - data_to_create["vector_store_description"] = vector_store_description - if vector_store_metadata is not None: - data_to_create["vector_store_metadata"] = safe_dumps(vector_store_metadata) - if litellm_credential_name is not None: - data_to_create["litellm_credential_name"] = litellm_credential_name - if team_id is not None: - data_to_create["team_id"] = team_id - if user_id is not None: - data_to_create["user_id"] = user_id - - # Handle litellm_params - always provide at least an empty dict - if litellm_params: - # Auto-resolve embedding config if embedding model is provided but config is not - embedding_model = litellm_params.get("litellm_embedding_model") - if embedding_model and not litellm_params.get("litellm_embedding_config"): - resolved_config = await _resolve_embedding_config_from_db( - embedding_model=embedding_model, - prisma_client=prisma_client - ) - if resolved_config: - litellm_params["litellm_embedding_config"] = resolved_config - verbose_proxy_logger.info( - f"Auto-resolved embedding config for model {embedding_model}" - ) - - litellm_params_dict = GenericLiteLLMParams( - **litellm_params - ).model_dump(exclude_none=True) - data_to_create["litellm_params"] = safe_dumps(litellm_params_dict) - else: - # Provide empty dict if no litellm_params provided - data_to_create["litellm_params"] = safe_dumps({}) - - # Create in database - _new_vector_store = ( - await prisma_client.db.litellm_managedvectorstorestable.create( - data=data_to_create - ) - ) - - new_vector_store: LiteLLM_ManagedVectorStore = LiteLLM_ManagedVectorStore( - **_new_vector_store.model_dump() - ) - - # Add vector store to registry - if litellm.vector_store_registry is not None: - litellm.vector_store_registry.add_vector_store_to_registry( - vector_store=new_vector_store - ) - - verbose_proxy_logger.info( - f"Vector store {vector_store_id} created in database successfully" - ) - - return new_vector_store - - ######################################################## # Management Endpoints ######################################################## @@ -301,36 +156,71 @@ async def new_vector_store( - vector_store_metadata: Optional[Dict] - Additional metadata for the vector store """ from litellm.proxy.proxy_server import prisma_client + from litellm.types.router import GenericLiteLLMParams + + if prisma_client is None: + raise HTTPException(status_code=500, detail="Database not connected") try: - vector_store_id = vector_store.get("vector_store_id") - custom_llm_provider = vector_store.get("custom_llm_provider") - - if not vector_store_id or not custom_llm_provider: + # Check if vector store already exists + existing_vector_store = ( + await prisma_client.db.litellm_managedvectorstorestable.find_unique( + where={"vector_store_id": vector_store.get("vector_store_id")} + ) + ) + if existing_vector_store is not None: raise HTTPException( status_code=400, - detail="vector_store_id and custom_llm_provider are required" + detail=f"Vector store with ID {vector_store.get('vector_store_id')} already exists", + ) + + if vector_store.get("vector_store_metadata") is not None: + vector_store["vector_store_metadata"] = safe_dumps( + vector_store.get("vector_store_metadata") + ) + + # Safely handle JSON serialization of litellm_params + litellm_params_json: Optional[str] = None + _input_litellm_params: dict = vector_store.get("litellm_params", {}) or {} + if _input_litellm_params is not None: + # Auto-resolve embedding config if embedding model is provided but config is not + embedding_model = _input_litellm_params.get("litellm_embedding_model") + if embedding_model and not _input_litellm_params.get("litellm_embedding_config"): + resolved_config = await _resolve_embedding_config_from_db( + embedding_model=embedding_model, + prisma_client=prisma_client + ) + if resolved_config: + _input_litellm_params["litellm_embedding_config"] = resolved_config + verbose_proxy_logger.info( + f"Auto-resolved embedding config for model {embedding_model}" + ) + + litellm_params_dict = GenericLiteLLMParams( + **_input_litellm_params + ).model_dump(exclude_none=True) + litellm_params_json = safe_dumps(litellm_params_dict) + del vector_store["litellm_params"] + + _new_vector_store = ( + await prisma_client.db.litellm_managedvectorstorestable.create( + data={ + **vector_store, + "litellm_params": litellm_params_json, + } ) - - # Extract and validate metadata - metadata = vector_store.get("vector_store_metadata") - validated_metadata: Optional[Dict] = None - if metadata is not None and isinstance(metadata, dict): - validated_metadata = metadata - - new_vector_store = await create_vector_store_in_db( - vector_store_id=vector_store_id, - custom_llm_provider=custom_llm_provider, - prisma_client=prisma_client, - vector_store_name=vector_store.get("vector_store_name"), - vector_store_description=vector_store.get("vector_store_description"), - vector_store_metadata=validated_metadata, - litellm_params=vector_store.get("litellm_params"), - litellm_credential_name=vector_store.get("litellm_credential_name"), - team_id=user_api_key_dict.team_id, - user_id=user_api_key_dict.user_id, ) + new_vector_store: LiteLLM_ManagedVectorStore = LiteLLM_ManagedVectorStore( + **_new_vector_store.model_dump() + ) + + # Add vector store to registry + if litellm.vector_store_registry is not None: + litellm.vector_store_registry.add_vector_store_to_registry( + vector_store=new_vector_store + ) + return { "status": "success", "message": f"Vector store {vector_store.get('vector_store_id')} created successfully", @@ -421,19 +311,14 @@ async def list_vector_stores( updated_data=vector_store ) - # Filter vector stores based on team access - accessible_vector_stores = [ - vs for vs in vector_store_map.values() - if _check_vector_store_access(vs, user_api_key_dict) - ] - - total_count = len(accessible_vector_stores) + combined_vector_stores = list(vector_store_map.values()) + total_count = len(combined_vector_stores) total_pages = (total_count + page_size - 1) // page_size # Format response using LiteLLM_ManagedVectorStoreListResponse response = LiteLLM_ManagedVectorStoreListResponse( object="list", - data=accessible_vector_stores, + data=combined_vector_stores, total_count=total_count, current_page=page, total_pages=total_pages, @@ -469,7 +354,6 @@ async def delete_vector_store( # Check if vector store exists in database or in-memory registry db_vector_store_exists = False memory_vector_store_exists = False - vector_store_to_check = None existing_vector_store = ( await prisma_client.db.litellm_managedvectorstorestable.find_unique( @@ -478,9 +362,6 @@ async def delete_vector_store( ) if existing_vector_store is not None: db_vector_store_exists = True - vector_store_to_check = LiteLLM_ManagedVectorStore( - **existing_vector_store.model_dump() - ) # Check in-memory registry if litellm.vector_store_registry is not None: @@ -489,8 +370,6 @@ async def delete_vector_store( ) if memory_vector_store is not None: memory_vector_store_exists = True - if vector_store_to_check is None: - vector_store_to_check = memory_vector_store # If not found in either location, raise 404 if not db_vector_store_exists and not memory_vector_store_exists: @@ -498,15 +377,6 @@ async def delete_vector_store( status_code=404, detail=f"Vector store with ID {data.vector_store_id} not found", ) - - # Check access control - if vector_store_to_check and not _check_vector_store_access( - vector_store_to_check, user_api_key_dict - ): - raise HTTPException( - status_code=403, - detail="Access denied: You do not have permission to delete this vector store", - ) # Delete from database if exists if db_vector_store_exists: @@ -553,13 +423,6 @@ async def get_vector_store_info( vector_store_id=data.vector_store_id ) if vector_store is not None: - # Check access control - if not _check_vector_store_access(vector_store, user_api_key_dict): - raise HTTPException( - status_code=403, - detail="Access denied: You do not have permission to access this vector store", - ) - vector_store_metadata = vector_store.get("vector_store_metadata") # Parse metadata if it's a JSON string parsed_metadata: Optional[dict] = None @@ -581,8 +444,6 @@ async def get_vector_store_info( updated_at=vector_store.get("updated_at") or None, litellm_credential_name=vector_store.get("litellm_credential_name"), litellm_params=vector_store.get("litellm_params") or None, - team_id=vector_store.get("team_id") or None, - user_id=vector_store.get("user_id") or None, ) return {"vector_store": vector_store_pydantic_obj} @@ -596,16 +457,8 @@ async def get_vector_store_info( status_code=404, detail=f"Vector store with ID {data.vector_store_id} not found", ) - - # Check access control for DB vector store - vector_store_dict = vector_store.model_dump() # type: ignore[attr-defined] - vector_store_typed = LiteLLM_ManagedVectorStore(**vector_store_dict) - if not _check_vector_store_access(vector_store_typed, user_api_key_dict): - raise HTTPException( - status_code=403, - detail="Access denied: You do not have permission to access this vector store", - ) + vector_store_dict = vector_store.model_dump() # type: ignore[attr-defined] return {"vector_store": vector_store_dict} except Exception as e: verbose_proxy_logger.exception(f"Error getting vector store info: {str(e)}") diff --git a/litellm/rag/ingestion/base_ingestion.py b/litellm/rag/ingestion/base_ingestion.py index 3daa767188d..20059487b43 100644 --- a/litellm/rag/ingestion/base_ingestion.py +++ b/litellm/rag/ingestion/base_ingestion.py @@ -24,7 +24,6 @@ get_async_httpx_client, httpxSpecialProvider, ) -from litellm.rag.ingestion.file_parsers import extract_text_from_pdf from litellm.rag.text_splitters import RecursiveCharacterTextSplitter from litellm.types.rag import RAGIngestOptions, RAGIngestResponse @@ -194,23 +193,11 @@ def chunk( if text: text_to_chunk = text elif file_content and not ocr_was_used: - # Try UTF-8 decode first try: text_to_chunk = file_content.decode("utf-8") except UnicodeDecodeError: - # Check if it's a PDF and try to extract text - if file_content.startswith(b"%PDF"): - verbose_logger.debug("PDF detected, attempting text extraction") - text_to_chunk = extract_text_from_pdf(file_content) - if not text_to_chunk: - verbose_logger.debug( - "PDF text extraction failed. Install 'pypdf' or 'PyPDF2' for PDF support, " - "or enable OCR with a vision model." - ) - return [] - else: - verbose_logger.debug("Binary file detected, skipping text chunking") - return [] + verbose_logger.debug("Binary file detected, skipping text chunking") + return [] if not text_to_chunk: return [] diff --git a/litellm/rag/ingestion/file_parsers/__init__.py b/litellm/rag/ingestion/file_parsers/__init__.py deleted file mode 100644 index 5be68cdbb74..00000000000 --- a/litellm/rag/ingestion/file_parsers/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -""" -File parsers for RAG ingestion. - -Provides text extraction utilities for various file formats. -""" - -from .pdf_parser import extract_text_from_pdf - -__all__ = ["extract_text_from_pdf"] diff --git a/litellm/rag/ingestion/file_parsers/pdf_parser.py b/litellm/rag/ingestion/file_parsers/pdf_parser.py deleted file mode 100644 index 9a533ccf138..00000000000 --- a/litellm/rag/ingestion/file_parsers/pdf_parser.py +++ /dev/null @@ -1,70 +0,0 @@ -""" -PDF text extraction utilities. - -Provides text extraction from PDF files using pypdf or PyPDF2. -""" - -from typing import Optional - -from litellm._logging import verbose_logger - - -def extract_text_from_pdf(file_content: bytes) -> Optional[str]: - """ - Extract text from PDF using pypdf if available. - - Args: - file_content: Raw PDF bytes - - Returns: - Extracted text or None if extraction fails - """ - try: - from io import BytesIO - - # Try pypdf first (most common) - try: - from pypdf import PdfReader as PypdfReader - - pdf_file = BytesIO(file_content) - reader = PypdfReader(pdf_file) - - text_parts = [] - for page in reader.pages: - text = page.extract_text() - if text: - text_parts.append(text) - - if text_parts: - extracted_text = "\n\n".join(text_parts) - verbose_logger.debug(f"Extracted {len(extracted_text)} characters from PDF using pypdf") - return extracted_text - - except ImportError: - verbose_logger.debug("pypdf not available, trying PyPDF2") - - # Fallback to PyPDF2 - try: - from PyPDF2 import PdfReader as PyPDF2Reader - - pdf_file = BytesIO(file_content) - reader = PyPDF2Reader(pdf_file) - - text_parts = [] - for page in reader.pages: - text = page.extract_text() - if text: - text_parts.append(text) - - if text_parts: - extracted_text = "\n\n".join(text_parts) - verbose_logger.debug(f"Extracted {len(extracted_text)} characters from PDF using PyPDF2") - return extracted_text - - except ImportError: - verbose_logger.debug("PyPDF2 not available, PDF extraction requires OCR or pypdf/PyPDF2 library") - - except Exception as e: - verbose_logger.debug(f"PDF text extraction failed: {e}") - - return None diff --git a/litellm/rag/ingestion/s3_vectors_ingestion.py b/litellm/rag/ingestion/s3_vectors_ingestion.py deleted file mode 100644 index e6c166a1015..00000000000 --- a/litellm/rag/ingestion/s3_vectors_ingestion.py +++ /dev/null @@ -1,573 +0,0 @@ -""" -S3 Vectors-specific RAG Ingestion implementation. - -S3 Vectors is AWS's native vector storage service that provides: -- Purpose-built vector buckets for storing and querying vectors -- Vector indexes with configurable dimensions and distance metrics -- Metadata filtering for semantic search - -This implementation: -1. Auto-creates vector buckets and indexes if not provided -2. Uses LiteLLM's embedding API (supports any provider) -3. Uses httpx + AWS SigV4 signing (no boto3 dependency for S3 Vectors APIs) -4. Stores vectors with metadata using PutVectors API -""" - -from __future__ import annotations - -import hashlib -import uuid -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple - -import litellm -from litellm._logging import verbose_logger -from litellm.constants import ( - S3_VECTORS_DEFAULT_DIMENSION, - S3_VECTORS_DEFAULT_DISTANCE_METRIC, - S3_VECTORS_DEFAULT_NON_FILTERABLE_METADATA_KEYS, -) -from litellm.litellm_core_utils.safe_json_dumps import safe_dumps -from litellm.llms.bedrock.base_aws_llm import BaseAWSLLM -from litellm.llms.custom_httpx.http_handler import ( - get_async_httpx_client, - httpxSpecialProvider, -) -from litellm.rag.ingestion.base_ingestion import BaseRAGIngestion - -if TYPE_CHECKING: - from litellm import Router - from litellm.types.rag import RAGIngestOptions - - -class S3VectorsRAGIngestion(BaseRAGIngestion, BaseAWSLLM): - """ - S3 Vectors RAG ingestion using httpx + AWS SigV4 signing. - - Workflow: - 1. Auto-create vector bucket if needed (CreateVectorBucket API) - 2. Auto-create vector index if needed (CreateVectorIndex API) - 3. Generate embeddings using LiteLLM (supports any provider) - 4. Store vectors with PutVectors API - - Configuration: - - vector_bucket_name: S3 vector bucket name (required) - - index_name: Vector index name (auto-creates if not provided) - - dimension: Vector dimension (default: S3_VECTORS_DEFAULT_DIMENSION) - - distance_metric: "cosine" or "euclidean" (default: S3_VECTORS_DEFAULT_DISTANCE_METRIC) - - non_filterable_metadata_keys: List of metadata keys to exclude from filtering - """ - - def __init__( - self, - ingest_options: "RAGIngestOptions", - router: Optional["Router"] = None, - ): - BaseRAGIngestion.__init__(self, ingest_options=ingest_options, router=router) - BaseAWSLLM.__init__(self) - - # Extract config - self.vector_bucket_name = self.vector_store_config["vector_bucket_name"] - self.index_name = self.vector_store_config.get("index_name") - self.distance_metric = self.vector_store_config.get( - "distance_metric", S3_VECTORS_DEFAULT_DISTANCE_METRIC - ) - self.non_filterable_metadata_keys = self.vector_store_config.get( - "non_filterable_metadata_keys", - S3_VECTORS_DEFAULT_NON_FILTERABLE_METADATA_KEYS, - ) - - # Get dimension from config (will be auto-detected on first use if not provided) - self.dimension = self._get_dimension_from_config() - - # Get AWS region using BaseAWSLLM method - _aws_region = self.vector_store_config.get("aws_region_name") - self.aws_region_name = self.get_aws_region_name_for_non_llm_api_calls( - aws_region_name=str(_aws_region) if _aws_region else None - ) - - # Create httpx client (similar to s3_v2.py) - ssl_verify = self._get_ssl_verify( - ssl_verify=self.vector_store_config.get("ssl_verify") - ) - self.async_httpx_client = get_async_httpx_client( - llm_provider=httpxSpecialProvider.RAG, - params={"ssl_verify": ssl_verify} if ssl_verify is not None else None, - ) - - # Track if infrastructure is initialized - self._config_initialized = False - - async def _get_dimension_from_embedding_request(self) -> int: - """ - Auto-detect dimension by making a test embedding request. - - Makes a single embedding request with a test string to determine - the output dimension of the embedding model. - """ - if not self.embedding_config or "model" not in self.embedding_config: - return S3_VECTORS_DEFAULT_DIMENSION - - try: - model_name = self.embedding_config["model"] - verbose_logger.debug( - f"Auto-detecting dimension by making test embedding request to {model_name}" - ) - - # Make a test embedding request - test_input = "test" - if self.router: - response = await self.router.aembedding(model=model_name, input=[test_input]) - else: - response = await litellm.aembedding(model=model_name, input=[test_input]) - - # Get dimension from the response - if response.data and len(response.data) > 0: - dimension = len(response.data[0]["embedding"]) - verbose_logger.debug( - f"Auto-detected dimension {dimension} for embedding model {model_name}" - ) - return dimension - except Exception as e: - verbose_logger.warning( - f"Could not auto-detect dimension from embedding model: {e}. " - f"Using default dimension of {S3_VECTORS_DEFAULT_DIMENSION}." - ) - - return S3_VECTORS_DEFAULT_DIMENSION - - def _get_dimension_from_config(self) -> Optional[int]: - """ - Get vector dimension from config if explicitly provided. - - Returns None if dimension should be auto-detected. - """ - if "dimension" in self.vector_store_config: - return int(self.vector_store_config["dimension"]) - return None - - async def _ensure_config_initialized(self): - """Lazily initialize S3 Vectors infrastructure.""" - if self._config_initialized: - return - - # Auto-detect dimension if not provided - if self.dimension is None: - self.dimension = await self._get_dimension_from_embedding_request() - - # Ensure vector bucket exists - await self._ensure_vector_bucket_exists() - - # Ensure vector index exists - if not self.index_name: - # Auto-generate index name - unique_id = uuid.uuid4().hex[:8] - self.index_name = f"litellm-index-{unique_id}" - - await self._ensure_vector_index_exists() - - self._config_initialized = True - - async def _sign_and_execute_request( - self, - method: str, - url: str, - data: Optional[str] = None, - headers: Optional[Dict[str, str]] = None, - ) -> Any: - """ - Helper to sign and execute AWS API requests using httpx + SigV4. - - Pattern from litellm/integrations/s3_v2.py - """ - try: - import requests - from botocore.auth import SigV4Auth - from botocore.awsrequest import AWSRequest - except ImportError: - raise ImportError( - "Missing botocore to call S3 Vectors. Run 'pip install boto3'." - ) - - # Get AWS credentials using BaseAWSLLM's get_credentials method - credentials = self.get_credentials( - aws_access_key_id=self.vector_store_config.get("aws_access_key_id"), - aws_secret_access_key=self.vector_store_config.get("aws_secret_access_key"), - aws_session_token=self.vector_store_config.get("aws_session_token"), - aws_region_name=self.aws_region_name, - aws_session_name=self.vector_store_config.get("aws_session_name"), - aws_profile_name=self.vector_store_config.get("aws_profile_name"), - aws_role_name=self.vector_store_config.get("aws_role_name"), - aws_web_identity_token=self.vector_store_config.get("aws_web_identity_token"), - aws_sts_endpoint=self.vector_store_config.get("aws_sts_endpoint"), - aws_external_id=self.vector_store_config.get("aws_external_id"), - ) - - # Prepare headers - if headers is None: - headers = {} - - if data: - headers["Content-Type"] = "application/json" - # Calculate SHA256 hash of the content - content_hash = hashlib.sha256(data.encode("utf-8")).hexdigest() - headers["x-amz-content-sha256"] = content_hash - else: - # For requests without body, use hash of empty string - headers["x-amz-content-sha256"] = hashlib.sha256(b"").hexdigest() - - # Prepare the request - req = requests.Request(method, url, data=data, headers=headers) - prepped = req.prepare() - - # Sign the request - aws_request = AWSRequest( - method=prepped.method, - url=prepped.url, - data=prepped.body, - headers=prepped.headers, - ) - SigV4Auth(credentials, "s3vectors", self.aws_region_name).add_auth(aws_request) - - # Prepare the signed headers - signed_headers = dict(aws_request.headers.items()) - - # Make the request using specific method (pattern from s3_v2.py) - method_upper = method.upper() - if method_upper == "PUT": - response = await self.async_httpx_client.put( - url, data=data, headers=signed_headers - ) - elif method_upper == "POST": - response = await self.async_httpx_client.post( - url, data=data, headers=signed_headers - ) - elif method_upper == "GET": - response = await self.async_httpx_client.get(url, headers=signed_headers) - else: - raise ValueError(f"Unsupported HTTP method: {method}") - - return response - - async def _ensure_vector_bucket_exists(self): - """Create vector bucket if it doesn't exist using GetVectorBucket and CreateVectorBucket APIs.""" - verbose_logger.debug( - f"Ensuring S3 vector bucket exists: {self.vector_bucket_name}" - ) - - # Validate bucket name (AWS S3 naming rules) - if len(self.vector_bucket_name) < 3: - raise ValueError( - f"Invalid vector_bucket_name '{self.vector_bucket_name}': " - f"AWS S3 bucket names must be at least 3 characters long. " - f"Please provide a valid bucket name (e.g., 'my-vector-bucket')." - ) - if not self.vector_bucket_name.replace("-", "").replace(".", "").isalnum(): - raise ValueError( - f"Invalid vector_bucket_name '{self.vector_bucket_name}': " - f"AWS S3 bucket names can only contain lowercase letters, numbers, hyphens, and periods. " - f"Please provide a valid bucket name (e.g., 'my-vector-bucket')." - ) - - # Try to get bucket info using GetVectorBucket API - get_url = f"https://s3vectors.{self.aws_region_name}.api.aws/GetVectorBucket" - get_body = safe_dumps({"vectorBucketName": self.vector_bucket_name}) - - try: - response = await self._sign_and_execute_request("POST", get_url, data=get_body) - if response.status_code == 200: - verbose_logger.debug(f"Vector bucket {self.vector_bucket_name} exists") - return - except Exception as e: - verbose_logger.debug( - f"Bucket check failed (may not exist): {e}, attempting to create" - ) - - # Create vector bucket using CreateVectorBucket API - try: - verbose_logger.debug(f"Creating vector bucket: {self.vector_bucket_name}") - create_url = f"https://s3vectors.{self.aws_region_name}.api.aws/CreateVectorBucket" - create_body = safe_dumps({ - "vectorBucketName": self.vector_bucket_name - }) - - response = await self._sign_and_execute_request("POST", create_url, data=create_body) - - if response.status_code in (200, 201): - verbose_logger.info(f"Created vector bucket: {self.vector_bucket_name}") - elif response.status_code == 409: - # Bucket already exists (ConflictException) - verbose_logger.debug( - f"Vector bucket {self.vector_bucket_name} already exists" - ) - else: - verbose_logger.error(f"CreateVectorBucket failed: {response.status_code} - {response.text}") - response.raise_for_status() - except Exception as e: - verbose_logger.exception(f"Error creating vector bucket: {e}") - raise - - async def _ensure_vector_index_exists(self): - """Create vector index if it doesn't exist using GetIndex and CreateIndex APIs.""" - verbose_logger.debug( - f"Ensuring vector index exists: {self.vector_bucket_name}/{self.index_name}" - ) - - # Try to get index info using GetIndex API - get_url = f"https://s3vectors.{self.aws_region_name}.api.aws/GetIndex" - get_body = safe_dumps({ - "vectorBucketName": self.vector_bucket_name, - "indexName": self.index_name - }) - - try: - response = await self._sign_and_execute_request("POST", get_url, data=get_body) - if response.status_code == 200: - verbose_logger.debug(f"Vector index {self.index_name} exists") - return - except Exception as e: - verbose_logger.debug( - f"Index check failed (may not exist): {e}, attempting to create" - ) - - # Create vector index using CreateIndex API - try: - verbose_logger.debug( - f"Creating vector index: {self.index_name} with dimension={self.dimension}, metric={self.distance_metric}" - ) - - # Prepare index configuration per AWS API docs - index_config = { - "vectorBucketName": self.vector_bucket_name, - "indexName": self.index_name, - "dataType": "float32", - "dimension": self.dimension, - "distanceMetric": self.distance_metric, - } - - if self.non_filterable_metadata_keys: - index_config["metadataConfiguration"] = { - "nonFilterableMetadataKeys": self.non_filterable_metadata_keys - } - - create_url = f"https://s3vectors.{self.aws_region_name}.api.aws/CreateIndex" - response = await self._sign_and_execute_request( - "POST", create_url, data=safe_dumps(index_config) - ) - - if response.status_code in (200, 201): - verbose_logger.info(f"Created vector index: {self.index_name}") - elif response.status_code == 409: - verbose_logger.debug(f"Vector index {self.index_name} already exists") - else: - verbose_logger.error(f"CreateIndex failed: {response.status_code} - {response.text}") - response.raise_for_status() - except Exception as e: - verbose_logger.exception(f"Error creating vector index: {e}") - raise - - async def _put_vectors(self, vectors: List[Dict[str, Any]]): - """ - Call PutVectors API to store vectors in S3 Vectors. - - Args: - vectors: List of vector objects with keys: "key", "data", "metadata" - """ - verbose_logger.debug( - f"Storing {len(vectors)} vectors in {self.vector_bucket_name}/{self.index_name}" - ) - - url = f"https://s3vectors.{self.aws_region_name}.api.aws/PutVectors" - - # Prepare request body per AWS API docs - request_body = { - "vectorBucketName": self.vector_bucket_name, - "indexName": self.index_name, - "vectors": vectors - } - - try: - response = await self._sign_and_execute_request( - "POST", url, data=safe_dumps(request_body) - ) - - if response.status_code in (200, 201): - verbose_logger.info( - f"Successfully stored {len(vectors)} vectors in index {self.index_name}" - ) - else: - verbose_logger.error( - f"PutVectors failed with status {response.status_code}: {response.text}" - ) - response.raise_for_status() - except Exception as e: - verbose_logger.exception(f"Error storing vectors: {e}") - raise - - async def embed( - self, - chunks: List[str], - ) -> Optional[List[List[float]]]: - """ - Generate embeddings using LiteLLM's embedding API. - - Supports any embedding provider (OpenAI, Bedrock, Cohere, etc.) - """ - if not chunks: - return None - - # Use embedding config from ingest_options or default - if not self.embedding_config: - verbose_logger.warning( - "No embedding config provided, using default text-embedding-3-small" - ) - self.embedding_config = {"model": "text-embedding-3-small"} - - embedding_model = self.embedding_config.get("model", "text-embedding-3-small") - - verbose_logger.debug( - f"Generating embeddings for {len(chunks)} chunks using {embedding_model}" - ) - - # Convert to list to ensure type compatibility - input_chunks: List[str] = list(chunks) - - if self.router: - response = await self.router.aembedding(model=embedding_model, input=input_chunks) - else: - response = await litellm.aembedding(model=embedding_model, input=input_chunks) - - return [item["embedding"] for item in response.data] - - async def store( - self, - file_content: Optional[bytes], - filename: Optional[str], - content_type: Optional[str], - chunks: List[str], - embeddings: Optional[List[List[float]]], - ) -> Tuple[Optional[str], Optional[str]]: - """ - Store vectors in S3 Vectors using PutVectors API. - - Steps: - 1. Ensure vector bucket exists (auto-create if needed) - 2. Ensure vector index exists (auto-create if needed) - 3. Prepare vector data with metadata - 4. Call PutVectors API with httpx + SigV4 signing - - Args: - file_content: Raw file bytes (not used for S3 Vectors) - filename: Name of the file - content_type: MIME type (not used for S3 Vectors) - chunks: Text chunks - embeddings: Vector embeddings - - Returns: - Tuple of (index_name, filename) - """ - # Ensure infrastructure exists - await self._ensure_config_initialized() - - if not embeddings or not chunks: - error_msg = ( - "No text content could be extracted from the file for embedding. " - "Possible causes:\n" - " 1. PDF files require OCR - add 'ocr' config with a vision model (e.g., 'anthropic/claude-3-5-sonnet-20241022')\n" - " 2. Binary files cannot be processed - convert to text first\n" - " 3. File is empty or contains no extractable text\n" - "For PDFs, either enable OCR or use a PDF extraction library to convert to text before ingestion." - ) - verbose_logger.error(error_msg) - raise ValueError(error_msg) - - # Prepare vectors for PutVectors API - vectors = [] - for i, (chunk, embedding) in enumerate(zip(chunks, embeddings)): - # Build metadata dict - metadata: Dict[str, str] = { - "source_text": chunk, # Non-filterable (for reference) - "chunk_index": str(i), # Filterable - } - - if filename: - metadata["filename"] = filename # Filterable - - vector_obj = { - "key": f"{filename}_{i}" if filename else f"chunk_{i}", - "data": {"float32": embedding}, - "metadata": metadata, - } - - vectors.append(vector_obj) - - # Call PutVectors API - await self._put_vectors(vectors) - - # Return vector_store_id in format bucket_name:index_name for S3 Vectors search compatibility - vector_store_id = f"{self.vector_bucket_name}:{self.index_name}" - return vector_store_id, filename - - async def query_vector_store( - self, vector_store_id: str, query: str, top_k: int = 5 - ) -> Optional[Dict[str, Any]]: - """ - Query S3 Vectors using QueryVectors API. - - Args: - vector_store_id: Index name - query: Query text - top_k: Number of results to return - - Returns: - Query results with vectors and metadata - """ - verbose_logger.debug(f"Querying index {vector_store_id} with query: {query}") - - # Generate query embedding - if not self.embedding_config: - self.embedding_config = {"model": "text-embedding-3-small"} - - embedding_model = self.embedding_config.get("model", "text-embedding-3-small") - - response = await litellm.aembedding(model=embedding_model, input=[query]) - query_embedding = response.data[0]["embedding"] - - # Call QueryVectors API - url = f"https://s3vectors.{self.aws_region_name}.api.aws/QueryVectors" - - request_body = { - "vectorBucketName": self.vector_bucket_name, - "indexName": vector_store_id, - "queryVector": {"float32": query_embedding}, - "topK": top_k, - "returnDistance": True, - "returnMetadata": True, - } - - try: - response = await self._sign_and_execute_request( - "POST", url, data=safe_dumps(request_body) - ) - - if response.status_code == 200: - results = response.json() - verbose_logger.debug(f"Query returned {len(results.get('vectors', []))} results") - - # Check if query terms appear in results - if results.get("vectors"): - for result in results["vectors"]: - metadata = result.get("metadata", {}) - source_text = metadata.get("source_text", "") - if query.lower() in source_text.lower(): - return results - - # Return results even if exact match not found - return results - else: - verbose_logger.error( - f"QueryVectors failed with status {response.status_code}: {response.text}" - ) - return None - except Exception as e: - verbose_logger.exception(f"Error querying vectors: {e}") - return None diff --git a/litellm/rag/main.py b/litellm/rag/main.py index 571f78f2f70..620097f83dd 100644 --- a/litellm/rag/main.py +++ b/litellm/rag/main.py @@ -31,7 +31,6 @@ from litellm.rag.ingestion.bedrock_ingestion import BedrockRAGIngestion from litellm.rag.ingestion.gemini_ingestion import GeminiRAGIngestion from litellm.rag.ingestion.openai_ingestion import OpenAIRAGIngestion -from litellm.rag.ingestion.s3_vectors_ingestion import S3VectorsRAGIngestion from litellm.rag.rag_query import RAGQuery from litellm.types.rag import ( RAGIngestOptions, @@ -49,7 +48,6 @@ "openai": OpenAIRAGIngestion, "bedrock": BedrockRAGIngestion, "gemini": GeminiRAGIngestion, - "s3_vectors": S3VectorsRAGIngestion, } diff --git a/litellm/responses/litellm_completion_transformation/transformation.py b/litellm/responses/litellm_completion_transformation/transformation.py index 41abbca755c..3badbc50578 100644 --- a/litellm/responses/litellm_completion_transformation/transformation.py +++ b/litellm/responses/litellm_completion_transformation/transformation.py @@ -1750,8 +1750,6 @@ def _transform_chat_completion_usage_to_responses_usage( and prompt_details.cached_tokens is not None ): input_details_dict["cached_tokens"] = prompt_details.cached_tokens - else: - input_details_dict["cached_tokens"] = 0 if ( hasattr(prompt_details, "text_tokens") @@ -1784,8 +1782,6 @@ def _transform_chat_completion_usage_to_responses_usage( output_details_dict["reasoning_tokens"] = ( completion_details.reasoning_tokens ) - else: - output_details_dict["reasoning_tokens"] = 0 if ( hasattr(completion_details, "text_tokens") diff --git a/litellm/responses/main.py b/litellm/responses/main.py index b2c2493c812..83c23a58500 100644 --- a/litellm/responses/main.py +++ b/litellm/responses/main.py @@ -434,8 +434,6 @@ async def aresponses( _, custom_llm_provider, _, _ = litellm.get_llm_provider( model=model, api_base=local_vars.get("base_url", None) ) - # Update local_vars with detected provider (fixes #19782) - local_vars["custom_llm_provider"] = custom_llm_provider func = partial( responses, @@ -585,9 +583,6 @@ def responses( api_key=litellm_params.api_key, ) - # Update local_vars with detected provider (fixes #19782) - local_vars["custom_llm_provider"] = custom_llm_provider - # Use dynamic credentials from get_llm_provider (e.g., when use_litellm_proxy=True) if dynamic_api_key is not None: litellm_params.api_key = dynamic_api_key @@ -1416,8 +1411,6 @@ async def acompact_responses( _, custom_llm_provider, _, _ = litellm.get_llm_provider( model=model, api_base=local_vars.get("base_url", None) ) - # Update local_vars with detected provider (fixes #19782) - local_vars["custom_llm_provider"] = custom_llm_provider func = partial( compact_responses, @@ -1505,9 +1498,6 @@ def compact_responses( api_key=litellm_params.api_key, ) - # Update local_vars with detected provider (fixes #19782) - local_vars["custom_llm_provider"] = custom_llm_provider - # Use dynamic credentials from get_llm_provider (e.g., when use_litellm_proxy=True) if dynamic_api_key is not None: litellm_params.api_key = dynamic_api_key diff --git a/litellm/router.py b/litellm/router.py index a3c3afa9326..62070d23755 100644 --- a/litellm/router.py +++ b/litellm/router.py @@ -58,7 +58,6 @@ _get_parent_otel_span_from_kwargs, get_metadata_variable_name_from_kwargs, ) -from litellm.litellm_core_utils.thread_pool_executor import executor from litellm.litellm_core_utils.coroutine_checker import coroutine_checker from litellm.litellm_core_utils.credential_accessor import CredentialAccessor from litellm.litellm_core_utils.dd_tracing import tracer @@ -644,17 +643,6 @@ def __init__( # noqa: PLR0915 self.initialize_router_endpoints() self.apply_default_settings() - @staticmethod - def get_valid_args() -> List[str]: - """ - Returns a list of valid arguments for the Router.__init__ method. - """ - arg_spec = inspect.getfullargspec(Router.__init__) - valid_args = arg_spec.args + arg_spec.kwonlyargs - if "self" in valid_args: - valid_args.remove("self") - return valid_args - def apply_default_settings(self): """ Apply the default settings to the router. @@ -1251,25 +1239,10 @@ def _completion( specific_deployment=kwargs.pop("specific_deployment", None), request_kwargs=kwargs, ) - # Check for silent model experiment - # Make a local copy of litellm_params to avoid mutating the Router's state - litellm_params = deployment["litellm_params"].copy() - silent_model = litellm_params.pop("silent_model", None) - - if silent_model is not None: - # Mirroring traffic to a secondary model - # Use shared thread pool for background calls - executor.submit( - self._silent_experiment_completion, - silent_model, - messages, - **kwargs, - ) - self._update_kwargs_with_deployment(deployment=deployment, kwargs=kwargs) - kwargs.pop("silent_model", None) # Ensure it's not in kwargs either + # No copy needed - data is only read and spread into new dict below - data = litellm_params.copy() # Use the local copy of litellm_params + data = deployment["litellm_params"] model_name = data["model"] potential_model_client = self._get_client( deployment=deployment, kwargs=kwargs @@ -1290,14 +1263,15 @@ def _completion( if not self.has_model_id(model): self.routing_strategy_pre_call_checks(deployment=deployment) - input_kwargs = { - **data, - "messages": messages, - "caching": self.cache_responses, - "client": model_client, - **kwargs, - } - response = litellm.completion(**input_kwargs) + response = litellm.completion( + **{ + **data, + "messages": messages, + "caching": self.cache_responses, + "client": model_client, + **kwargs, + } + ) verbose_router_logger.info( f"litellm.completion(model={model_name})\033[32m 200 OK\033[0m" ) @@ -1324,56 +1298,6 @@ def _completion( self._set_deployment_num_retries_on_exception(e, deployment) raise e - def _get_silent_experiment_kwargs(self, **kwargs) -> dict: - """ - Prepare kwargs for a silent experiment by ensuring isolation from the primary call. - """ - # Copy kwargs to ensure isolation - silent_kwargs = copy.deepcopy(kwargs) - if "metadata" not in silent_kwargs: - silent_kwargs["metadata"] = {} - - silent_kwargs["metadata"]["is_silent_experiment"] = True - - # Pop logging objects and call IDs to ensure a fresh logging context - # This prevents collisions in the Proxy's database (spend_logs) - silent_kwargs.pop("litellm_call_id", None) - silent_kwargs.pop("litellm_logging_obj", None) - silent_kwargs.pop("standard_logging_object", None) - silent_kwargs.pop("proxy_server_request", None) - - return silent_kwargs - - def _silent_experiment_completion( - self, silent_model: str, messages: List[Any], **kwargs - ): - """ - Run a silent experiment in the background (thread). - """ - try: - # Prevent infinite recursion if silent model also has a silent model - if kwargs.get("metadata", {}).get("is_silent_experiment", False): - return - - messages = copy.deepcopy(messages) - - verbose_router_logger.info( - f"Starting silent experiment for model {silent_model}" - ) - - silent_kwargs = self._get_silent_experiment_kwargs(**kwargs) - - # Trigger the silent request - self.completion( - model=silent_model, - messages=cast(List[Dict[str, str]], messages), - **silent_kwargs, - ) - except Exception as e: - verbose_router_logger.error( - f"Silent experiment failed for model {silent_model}: {str(e)}" - ) - # fmt: off @overload @@ -1582,36 +1506,6 @@ async def stream_with_fallbacks(): return FallbackStreamWrapper(stream_with_fallbacks()) - async def _silent_experiment_acompletion( - self, silent_model: str, messages: List[Any], **kwargs - ): - """ - Run a silent experiment in the background. - """ - try: - # Prevent infinite recursion if silent model also has a silent model - if kwargs.get("metadata", {}).get("is_silent_experiment", False): - return - - messages = copy.deepcopy(messages) - - verbose_router_logger.info( - f"Starting silent experiment for model {silent_model}" - ) - - silent_kwargs = self._get_silent_experiment_kwargs(**kwargs) - - # Trigger the silent request - await self.acompletion( - model=silent_model, - messages=cast(List[AllMessageValues], messages), - **silent_kwargs, - ) - except Exception as e: - verbose_router_logger.error( - f"Silent experiment failed for model {silent_model}: {str(e)}" - ) - async def _acompletion( # noqa: PLR0915 self, model: str, messages: List[Dict[str, str]], **kwargs ) -> Union[ModelResponse, CustomStreamWrapper,]: @@ -1658,27 +1552,9 @@ async def _acompletion( # noqa: PLR0915 self._track_deployment_metrics( deployment=deployment, parent_otel_span=parent_otel_span ) - - # Check for silent model experiment - # Make a local copy of litellm_params to avoid mutating the Router's state - litellm_params = deployment["litellm_params"].copy() - silent_model = litellm_params.pop("silent_model", None) - - if silent_model is not None: - # Mirroring traffic to a secondary model - # This is a silent experiment, so we don't want to block the primary request - asyncio.create_task( - self._silent_experiment_acompletion( - silent_model=silent_model, - messages=messages, # Use messages instead of *args - **kwargs, - ) - ) - self._update_kwargs_with_deployment(deployment=deployment, kwargs=kwargs) - kwargs.pop("silent_model", None) # Ensure it's not in kwargs either # No copy needed - data is only read and spread into new dict below - data = litellm_params.copy() # Use the local copy of litellm_params + data = deployment["litellm_params"] model_name = data["model"] @@ -1695,7 +1571,6 @@ async def _acompletion( # noqa: PLR0915 "client": model_client, **kwargs, } - input_kwargs.pop("silent_model", None) _response = litellm.acompletion(**input_kwargs) @@ -1821,11 +1696,8 @@ def _set_deployment_num_retries_on_exception( litellm_params = deployment.get("litellm_params", {}) dep_num_retries = litellm_params.get("num_retries") - if dep_num_retries is not None: - try: - exception.num_retries = int(dep_num_retries) # type: ignore # Handle both int and str - except (ValueError, TypeError): - pass # Skip if value can't be converted to int + if dep_num_retries is not None and isinstance(dep_num_retries, int): + exception.num_retries = dep_num_retries # type: ignore def _update_kwargs_with_default_litellm_params( self, kwargs: dict, metadata_variable_name: Optional[str] = "metadata" @@ -4820,12 +4692,9 @@ async def async_function_with_retries(self, *args, **kwargs): # noqa: PLR0915 # get num_retries from retry policy # Use the model_group captured at the start of the function, or get it from metadata # kwargs.get("model") at this point is the deployment model, not the model_group - _model_group_for_retry_policy = ( - model_group or _metadata.get("model_group") or kwargs.get("model") - ) + _model_group_for_retry_policy = model_group or _metadata.get("model_group") or kwargs.get("model") _retry_policy_retries = self.get_num_retries_from_retry_policy( - exception=original_exception, - model_group=_model_group_for_retry_policy, + exception=original_exception, model_group=_model_group_for_retry_policy ) if _retry_policy_retries is not None: num_retries = _retry_policy_retries @@ -6010,10 +5879,7 @@ def _add_deployment(self, deployment: Deployment) -> Deployment: ) # done reading model["litellm_params"] # Check if provider is supported: either in enum or JSON-configured - if ( - custom_llm_provider not in litellm.provider_list - and not JSONProviderRegistry.exists(custom_llm_provider) - ): + if custom_llm_provider not in litellm.provider_list and not JSONProviderRegistry.exists(custom_llm_provider): raise Exception(f"Unsupported provider - {custom_llm_provider}") #### DEPLOYMENT NAMES INIT ######## @@ -6489,20 +6355,19 @@ def get_router_model_info( elif custom_llm_provider != "azure": model = _model - if "*" in model: # only call pattern_router for wildcard models - potential_models = self.pattern_router.route(received_model_name) - if potential_models is not None: - for potential_model in potential_models: - try: - if potential_model.get("model_info", {}).get( - "id" - ) == deployment.get("model_info", {}).get("id"): - model = potential_model.get("litellm_params", {}).get( - "model" - ) - break - except Exception: - pass + potential_models = self.pattern_router.route(received_model_name) + if "*" in model and potential_models is not None: # if wildcard route + for potential_model in potential_models: + try: + if potential_model.get("model_info", {}).get( + "id" + ) == deployment.get("model_info", {}).get("id"): + model = potential_model.get("litellm_params", {}).get( + "model" + ) + break + except Exception: + pass ## GET LITELLM MODEL INFO - raises exception, if model is not mapped if model is None: @@ -8729,6 +8594,11 @@ def get_allowed_fails_from_policy(self, exception: Exception): if allowed_fails_policy is None: return None + if ( + isinstance(exception, litellm.BadRequestError) + and allowed_fails_policy.BadRequestErrorAllowedFails is not None + ): + return allowed_fails_policy.BadRequestErrorAllowedFails if ( isinstance(exception, litellm.AuthenticationError) and allowed_fails_policy.AuthenticationErrorAllowedFails is not None @@ -8749,11 +8619,6 @@ def get_allowed_fails_from_policy(self, exception: Exception): and allowed_fails_policy.ContentPolicyViolationErrorAllowedFails is not None ): return allowed_fails_policy.ContentPolicyViolationErrorAllowedFails - if ( - isinstance(exception, litellm.BadRequestError) - and allowed_fails_policy.BadRequestErrorAllowedFails is not None - ): - return allowed_fails_policy.BadRequestErrorAllowedFails def _initialize_alerting(self): from litellm.integrations.SlackAlerting.slack_alerting import SlackAlerting diff --git a/litellm/router_utils/get_retry_from_policy.py b/litellm/router_utils/get_retry_from_policy.py index ec326ebb50d..48df43ef818 100644 --- a/litellm/router_utils/get_retry_from_policy.py +++ b/litellm/router_utils/get_retry_from_policy.py @@ -43,6 +43,11 @@ def get_num_retries_from_retry_policy( if isinstance(retry_policy, dict): retry_policy = RetryPolicy(**retry_policy) + if ( + isinstance(exception, BadRequestError) + and retry_policy.BadRequestErrorRetries is not None + ): + return retry_policy.BadRequestErrorRetries if ( isinstance(exception, AuthenticationError) and retry_policy.AuthenticationErrorRetries is not None @@ -60,11 +65,6 @@ def get_num_retries_from_retry_policy( and retry_policy.ContentPolicyViolationErrorRetries is not None ): return retry_policy.ContentPolicyViolationErrorRetries - if ( - isinstance(exception, BadRequestError) - and retry_policy.BadRequestErrorRetries is not None - ): - return retry_policy.BadRequestErrorRetries def reset_retry_policy() -> RetryPolicy: diff --git a/litellm/router_utils/search_api_router.py b/litellm/router_utils/search_api_router.py index 9a1907fa559..247df099462 100644 --- a/litellm/router_utils/search_api_router.py +++ b/litellm/router_utils/search_api_router.py @@ -127,9 +127,8 @@ async def async_search_with_fallbacks( model=search_tool_name, kwargs=kwargs, metadata_variable_name="litellm_metadata" ) - available_search_tool_names = [tool.get("search_tool_name") for tool in router_instance.search_tools] verbose_router_logger.debug( - f"Inside SearchAPIRouter.async_search_with_fallbacks() - search_tool_name: {search_tool_name}, Available Search Tools: {available_search_tool_names}, kwargs: {kwargs}" + f"Inside SearchAPIRouter.async_search_with_fallbacks() - search_tool_name: {search_tool_name}; kwargs: {kwargs}" ) # Use the existing retry/fallback infrastructure diff --git a/litellm/secret_managers/main.py b/litellm/secret_managers/main.py index 38405f058c3..a093fe2d2fd 100644 --- a/litellm/secret_managers/main.py +++ b/litellm/secret_managers/main.py @@ -17,22 +17,6 @@ oidc_cache = DualCache() -def _get_oidc_http_handler(timeout: Optional[httpx.Timeout] = None) -> HTTPHandler: - """ - Factory function to create HTTPHandler for OIDC requests. - This function can be mocked in tests. - - Args: - timeout: Optional timeout for HTTP requests. Defaults to 600.0 seconds with 5.0 connect timeout. - - Returns: - HTTPHandler instance configured for OIDC requests. - """ - if timeout is None: - timeout = httpx.Timeout(timeout=600.0, connect=5.0) - return HTTPHandler(timeout=timeout) - - ######### Secret Manager ############################ # checks if user has passed in a secret manager client # if passed in then checks the secret there @@ -119,7 +103,7 @@ def get_secret( # noqa: PLR0915 if oidc_token is not None: return oidc_token - oidc_client = _get_oidc_http_handler() + oidc_client = HTTPHandler(timeout=httpx.Timeout(timeout=600.0, connect=5.0)) # https://cloud.google.com/compute/docs/instances/verifying-instance-identity#request_signature response = oidc_client.get( "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity", @@ -157,7 +141,7 @@ def get_secret( # noqa: PLR0915 if oidc_token is not None: return oidc_token - oidc_client = _get_oidc_http_handler() + oidc_client = HTTPHandler(timeout=httpx.Timeout(timeout=600.0, connect=5.0)) response = oidc_client.get( actions_id_token_request_url, params={"audience": oidc_aud}, diff --git a/litellm/types/guardrails.py b/litellm/types/guardrails.py index ca22049720e..eea0a26b332 100644 --- a/litellm/types/guardrails.py +++ b/litellm/types/guardrails.py @@ -20,9 +20,6 @@ from litellm.types.proxy.guardrails.guardrail_hooks.qualifire import ( QualifireGuardrailConfigModel, ) -from litellm.types.proxy.guardrails.guardrail_hooks.litellm_content_filter import ( - ContentFilterCategoryConfig, -) """ Pydantic object defining how to set guardrails on litellm proxy @@ -550,27 +547,9 @@ class ContentFilterConfigModel(BaseModel): blocked_words_file: Optional[str] = Field( default=None, description="Path to YAML file containing blocked_words list" ) - categories: Optional[List[ContentFilterCategoryConfig]] = Field( - default=None, - description="List of prebuilt categories to enable (harmful_*, bias_*)", - ) - severity_threshold: Optional[str] = Field( - default=None, - description="Minimum severity to block (high, medium, low)", - ) - pattern_redaction_format: Optional[str] = Field( - default=None, - description="Format string for pattern redaction (use {pattern_name} placeholder)", - ) - keyword_redaction_tag: Optional[str] = Field( - default=None, - description="Tag to use for keyword redaction", - ) -class BaseLitellmParams( - ContentFilterConfigModel -): # works for new and patch update guardrails +class BaseLitellmParams(BaseModel): # works for new and patch update guardrails api_key: Optional[str] = Field( default=None, description="API key for the guardrail service" ) @@ -651,6 +630,7 @@ class BaseLitellmParams( description="Whether to fail the request if Model Armor encounters an error", ) + # Generic Guardrail API params additional_provider_specific_params: Optional[Dict[str, Any]] = Field( default=None, description="Additional provider-specific parameters for generic guardrail APIs", @@ -677,6 +657,7 @@ class LitellmParams( ToolPermissionGuardrailConfigModel, ZscalerAIGuardConfigModel, JavelinGuardrailConfigModel, + ContentFilterConfigModel, BaseLitellmParams, EnkryptAIGuardrailConfigs, IBMGuardrailsBaseConfigModel, diff --git a/litellm/types/integrations/datadog_cost_management.py b/litellm/types/integrations/datadog_cost_management.py deleted file mode 100644 index fe04f43ea03..00000000000 --- a/litellm/types/integrations/datadog_cost_management.py +++ /dev/null @@ -1,27 +0,0 @@ -from typing import Dict, Optional, TypedDict - - -from litellm.types.integrations.custom_logger import StandardCustomLoggerInitParams - - -class DatadogCostManagementInitParams(StandardCustomLoggerInitParams): - """ - Init params for Datadog Cost Management - """ - - datadog_cost_management_params: Optional[Dict] = None - - -class DatadogFOCUSCostEntry(TypedDict): - """ - Represents a single cost line item in the FOCUS format. - Ref: https://focus.finops.org/#specification - """ - - ProviderName: str - ChargeDescription: str - ChargePeriodStart: str - ChargePeriodEnd: str - BilledCost: float - BillingCurrency: str - Tags: Optional[Dict[str, str]] diff --git a/litellm/types/integrations/prometheus.py b/litellm/types/integrations/prometheus.py index 146c390363b..fd9b722287d 100644 --- a/litellm/types/integrations/prometheus.py +++ b/litellm/types/integrations/prometheus.py @@ -150,9 +150,6 @@ class UserAPIKeyLabelNames(Enum): FALLBACK_MODEL = "fallback_model" ROUTE = "route" MODEL_GROUP = "model_group" - CLIENT_IP = "client_ip" - USER_AGENT = "user_agent" - CALLBACK_NAME = "callback_name" DEFINED_PROMETHEUS_METRICS = Literal[ @@ -199,12 +196,6 @@ class UserAPIKeyLabelNames(Enum): "litellm_cache_hits_metric", "litellm_cache_misses_metric", "litellm_cached_tokens_metric", - "litellm_deployment_tpm_limit", - "litellm_deployment_rpm_limit", - "litellm_remaining_api_key_requests_for_model", - "litellm_remaining_api_key_tokens_for_model", - "litellm_llm_api_failed_requests_metric", - "litellm_callback_logging_failures_metric", ] @@ -218,7 +209,6 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.REQUESTED_MODEL.value, UserAPIKeyLabelNames.END_USER.value, UserAPIKeyLabelNames.USER.value, - UserAPIKeyLabelNames.MODEL_ID.value, ] litellm_llm_api_time_to_first_token_metric = [ @@ -227,10 +217,6 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.API_KEY_ALIAS.value, UserAPIKeyLabelNames.TEAM.value, UserAPIKeyLabelNames.TEAM_ALIAS.value, - UserAPIKeyLabelNames.REQUESTED_MODEL.value, - UserAPIKeyLabelNames.END_USER.value, - UserAPIKeyLabelNames.USER.value, - UserAPIKeyLabelNames.MODEL_ID.value, ] litellm_request_total_latency_metric = [ @@ -242,7 +228,6 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.TEAM_ALIAS.value, UserAPIKeyLabelNames.USER.value, UserAPIKeyLabelNames.v1_LITELLM_MODEL_NAME.value, - UserAPIKeyLabelNames.MODEL_ID.value, ] litellm_request_queue_time_seconds = [ @@ -254,7 +239,6 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.TEAM_ALIAS.value, UserAPIKeyLabelNames.USER.value, UserAPIKeyLabelNames.v1_LITELLM_MODEL_NAME.value, - UserAPIKeyLabelNames.MODEL_ID.value, ] # Guardrail metrics - these use custom labels (guardrail_name, status, error_type, hook_type) @@ -274,9 +258,6 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.STATUS_CODE.value, UserAPIKeyLabelNames.USER_EMAIL.value, UserAPIKeyLabelNames.ROUTE.value, - UserAPIKeyLabelNames.CLIENT_IP.value, - UserAPIKeyLabelNames.USER_AGENT.value, - UserAPIKeyLabelNames.MODEL_ID.value, ] litellm_proxy_failed_requests_metric = [ @@ -291,9 +272,6 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.EXCEPTION_STATUS.value, UserAPIKeyLabelNames.EXCEPTION_CLASS.value, UserAPIKeyLabelNames.ROUTE.value, - UserAPIKeyLabelNames.CLIENT_IP.value, - UserAPIKeyLabelNames.USER_AGENT.value, - UserAPIKeyLabelNames.MODEL_ID.value, ] litellm_deployment_latency_per_output_token = [ @@ -314,7 +292,6 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.v2_LITELLM_MODEL_NAME.value, UserAPIKeyLabelNames.API_KEY_HASH.value, UserAPIKeyLabelNames.API_KEY_ALIAS.value, - UserAPIKeyLabelNames.MODEL_ID.value, ] litellm_remaining_requests_metric = [ @@ -324,7 +301,6 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.v2_LITELLM_MODEL_NAME.value, UserAPIKeyLabelNames.API_KEY_HASH.value, UserAPIKeyLabelNames.API_KEY_ALIAS.value, - UserAPIKeyLabelNames.MODEL_ID.value, ] litellm_remaining_tokens_metric = [ @@ -334,7 +310,6 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.v2_LITELLM_MODEL_NAME.value, UserAPIKeyLabelNames.API_KEY_HASH.value, UserAPIKeyLabelNames.API_KEY_ALIAS.value, - UserAPIKeyLabelNames.MODEL_ID.value, ] litellm_requests_metric = [ @@ -346,9 +321,6 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.TEAM_ALIAS.value, UserAPIKeyLabelNames.USER.value, UserAPIKeyLabelNames.USER_EMAIL.value, - UserAPIKeyLabelNames.CLIENT_IP.value, - UserAPIKeyLabelNames.USER_AGENT.value, - UserAPIKeyLabelNames.MODEL_ID.value, ] litellm_spend_metric = [ @@ -360,9 +332,6 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.TEAM_ALIAS.value, UserAPIKeyLabelNames.USER.value, UserAPIKeyLabelNames.USER_EMAIL.value, - UserAPIKeyLabelNames.CLIENT_IP.value, - UserAPIKeyLabelNames.USER_AGENT.value, - UserAPIKeyLabelNames.MODEL_ID.value, ] litellm_input_tokens_metric = [ @@ -375,7 +344,6 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.USER.value, UserAPIKeyLabelNames.USER_EMAIL.value, UserAPIKeyLabelNames.REQUESTED_MODEL.value, - UserAPIKeyLabelNames.MODEL_ID.value, ] litellm_total_tokens_metric = [ @@ -388,7 +356,6 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.USER.value, UserAPIKeyLabelNames.USER_EMAIL.value, UserAPIKeyLabelNames.REQUESTED_MODEL.value, - UserAPIKeyLabelNames.MODEL_ID.value, ] litellm_output_tokens_metric = [ @@ -401,7 +368,6 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.USER.value, UserAPIKeyLabelNames.USER_EMAIL.value, UserAPIKeyLabelNames.REQUESTED_MODEL.value, - UserAPIKeyLabelNames.MODEL_ID.value, ] litellm_deployment_state = [ @@ -411,15 +377,6 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.API_PROVIDER.value, ] - litellm_deployment_tpm_limit = [ - UserAPIKeyLabelNames.v2_LITELLM_MODEL_NAME.value, - UserAPIKeyLabelNames.MODEL_ID.value, - UserAPIKeyLabelNames.API_BASE.value, - UserAPIKeyLabelNames.API_PROVIDER.value, - ] - - litellm_deployment_rpm_limit = litellm_deployment_tpm_limit - litellm_deployment_cooled_down = [ UserAPIKeyLabelNames.v2_LITELLM_MODEL_NAME.value, UserAPIKeyLabelNames.MODEL_ID.value, @@ -437,7 +394,6 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.TEAM_ALIAS.value, UserAPIKeyLabelNames.EXCEPTION_STATUS.value, UserAPIKeyLabelNames.EXCEPTION_CLASS.value, - UserAPIKeyLabelNames.MODEL_ID.value, ] litellm_deployment_failed_fallbacks = litellm_deployment_successful_fallbacks @@ -480,26 +436,6 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.USER.value, ] - litellm_user_budget_remaining_hours_metric = [ - UserAPIKeyLabelNames.USER.value, - ] - - litellm_remaining_api_key_requests_for_model = [ - UserAPIKeyLabelNames.API_KEY_HASH.value, - UserAPIKeyLabelNames.API_KEY_ALIAS.value, - UserAPIKeyLabelNames.v1_LITELLM_MODEL_NAME.value, - ] - - litellm_remaining_api_key_tokens_for_model = [ - UserAPIKeyLabelNames.API_KEY_HASH.value, - UserAPIKeyLabelNames.API_KEY_ALIAS.value, - UserAPIKeyLabelNames.v1_LITELLM_MODEL_NAME.value, - ] - - litellm_callback_logging_failures_metric = [ - UserAPIKeyLabelNames.CALLBACK_NAME.value, - ] - # Add deployment metrics litellm_deployment_failure_responses = [ UserAPIKeyLabelNames.REQUESTED_MODEL.value, @@ -513,8 +449,6 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.API_KEY_ALIAS.value, UserAPIKeyLabelNames.TEAM.value, UserAPIKeyLabelNames.TEAM_ALIAS.value, - UserAPIKeyLabelNames.CLIENT_IP.value, - UserAPIKeyLabelNames.USER_AGENT.value, ] litellm_deployment_total_requests = [ @@ -527,37 +461,10 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.API_KEY_ALIAS.value, UserAPIKeyLabelNames.TEAM.value, UserAPIKeyLabelNames.TEAM_ALIAS.value, - UserAPIKeyLabelNames.CLIENT_IP.value, - UserAPIKeyLabelNames.USER_AGENT.value, ] litellm_deployment_success_responses = litellm_deployment_total_requests - litellm_remaining_api_key_requests_for_model = [ - UserAPIKeyLabelNames.API_KEY_HASH.value, - UserAPIKeyLabelNames.API_KEY_ALIAS.value, - UserAPIKeyLabelNames.v1_LITELLM_MODEL_NAME.value, - UserAPIKeyLabelNames.MODEL_ID.value, - ] - - litellm_remaining_api_key_tokens_for_model = [ - UserAPIKeyLabelNames.API_KEY_HASH.value, - UserAPIKeyLabelNames.API_KEY_ALIAS.value, - UserAPIKeyLabelNames.v1_LITELLM_MODEL_NAME.value, - UserAPIKeyLabelNames.MODEL_ID.value, - ] - - litellm_llm_api_failed_requests_metric = [ - UserAPIKeyLabelNames.END_USER.value, - UserAPIKeyLabelNames.API_KEY_HASH.value, - UserAPIKeyLabelNames.API_KEY_ALIAS.value, - UserAPIKeyLabelNames.v1_LITELLM_MODEL_NAME.value, - UserAPIKeyLabelNames.TEAM.value, - UserAPIKeyLabelNames.TEAM_ALIAS.value, - UserAPIKeyLabelNames.USER.value, - UserAPIKeyLabelNames.MODEL_ID.value, - ] - # Buffer monitoring metrics - these typically don't need additional labels litellm_pod_lock_manager_size: List[str] = [] @@ -578,7 +485,6 @@ class PrometheusMetricLabels: UserAPIKeyLabelNames.TEAM_ALIAS.value, UserAPIKeyLabelNames.END_USER.value, UserAPIKeyLabelNames.USER.value, - UserAPIKeyLabelNames.MODEL_ID.value, ] litellm_cache_hits_metric = _cache_metric_labels @@ -671,12 +577,6 @@ class UserAPIKeyLabelValues(BaseModel): route: Annotated[ Optional[str], Field(..., alias=UserAPIKeyLabelNames.ROUTE.value) ] = None - client_ip: Annotated[ - Optional[str], Field(..., alias=UserAPIKeyLabelNames.CLIENT_IP.value) - ] = None - user_agent: Annotated[ - Optional[str], Field(..., alias=UserAPIKeyLabelNames.USER_AGENT.value) - ] = None class PrometheusMetricsConfig(BaseModel): diff --git a/litellm/types/llms/bedrock.py b/litellm/types/llms/bedrock.py index a85aaafe23d..ef2f1ba4d5e 100644 --- a/litellm/types/llms/bedrock.py +++ b/litellm/types/llms/bedrock.py @@ -93,67 +93,6 @@ class GuardrailConverseContentBlock(TypedDict, total=False): text: GuardrailConverseTextBlock -class CitationWebLocationBlock(TypedDict, total=False): - """ - Web location block for Nova grounding citations. - Contains the URL and domain from web search results. - - Reference: https://docs.aws.amazon.com/nova/latest/userguide/grounding.html - """ - - url: str - domain: str - - -class CitationLocationBlock(TypedDict, total=False): - """ - Location block containing the web location for a citation. - """ - - web: CitationWebLocationBlock - - -class CitationReferenceBlock(TypedDict, total=False): - """ - Citation reference block containing a single citation with its location. - - Each citation contains: - - location.web.url: The URL of the source - - location.web.domain: The domain of the source - """ - - location: CitationLocationBlock - - -class CitationsContentBlock(TypedDict, total=False): - """ - Citations content block returned by Nova grounding (web search) tool. - - When Nova grounding is enabled via systemTool, the model may return - citationsContent blocks containing web search citation references. - - Reference: https://docs.aws.amazon.com/nova/latest/userguide/grounding.html - - Example response structure: - { - "citationsContent": { - "citations": [ - { - "location": { - "web": { - "url": "https://example.com/article", - "domain": "example.com" - } - } - } - ] - } - } - """ - - citations: List[CitationReferenceBlock] - - class ContentBlock(TypedDict, total=False): text: str image: ImageBlock @@ -164,7 +103,6 @@ class ContentBlock(TypedDict, total=False): cachePoint: CachePointBlock reasoningContent: BedrockConverseReasoningContentBlock guardContent: GuardrailConverseContentBlock - citationsContent: CitationsContentBlock class MessageBlock(TypedDict): @@ -221,24 +159,8 @@ class ToolSpecBlock(TypedDict, total=False): description: str -class SystemToolBlock(TypedDict, total=False): - """ - System tool block for Nova grounding and other built-in tools. - - Example: - { - "systemTool": { - "name": "nova_grounding" - } - } - """ - - name: Required[str] - - class ToolBlock(TypedDict, total=False): toolSpec: Optional[ToolSpecBlock] - systemTool: Optional[SystemToolBlock] cachePoint: Optional[CachePointBlock] @@ -288,13 +210,11 @@ class ContentBlockStartEvent(TypedDict, total=False): class ContentBlockDeltaEvent(TypedDict, total=False): """ Either 'text' or 'toolUse' will be specified for Converse API streaming response. - May also include 'citationsContent' when Nova grounding is enabled. """ text: str toolUse: ToolBlockDeltaEvent reasoningContent: BedrockConverseReasoningContentBlockDelta - citationsContent: CitationsContentBlock class PerformanceConfigBlock(TypedDict): @@ -959,8 +879,3 @@ class BedrockGetBatchResponse(TypedDict, total=False): outputDataConfig: BedrockOutputDataConfig timeoutDurationInHours: Optional[int] clientRequestToken: Optional[str] - -class BedrockToolBlock(TypedDict, total=False): - toolSpec: Optional[ToolSpecBlock] - systemTool: Optional[SystemToolBlock] # For Nova grounding - cachePoint: Optional[CachePointBlock] diff --git a/litellm/types/llms/oci.py b/litellm/types/llms/oci.py index 9a654bc0f6c..b9a82cc8b73 100644 --- a/litellm/types/llms/oci.py +++ b/litellm/types/llms/oci.py @@ -35,18 +35,11 @@ class OCITextContentPart(OCIContentPart): text: str -class OCIImageUrl(BaseModel): - """ImageUrl object for OCI API. See: https://docs.oracle.com/en-us/iaas/tools/python/latest/api/generative_ai_inference/models/oci.generative_ai_inference.models.ImageUrl.html""" - - url: str - detail: Optional[Literal["AUTO", "HIGH", "LOW"]] = None - - class OCIImageContentPart(OCIContentPart): """Image content part for the OCI API.""" type: Literal["IMAGE"] = "IMAGE" - imageUrl: OCIImageUrl + imageUrl: str OCIContentPartUnion = Union[OCITextContentPart, OCIImageContentPart] diff --git a/litellm/types/llms/openai.py b/litellm/types/llms/openai.py index 299b47199ed..9fea1a8b937 100644 --- a/litellm/types/llms/openai.py +++ b/litellm/types/llms/openai.py @@ -1114,7 +1114,7 @@ class ResponsesAPIRequestParams(ResponsesAPIOptionalRequestParams, total=False): class OutputTokensDetails(BaseLiteLLMOpenAIResponseObject): - reasoning_tokens: int = 0 + reasoning_tokens: Optional[int] = None text_tokens: Optional[int] = None @@ -1123,7 +1123,7 @@ class OutputTokensDetails(BaseLiteLLMOpenAIResponseObject): class InputTokensDetails(BaseLiteLLMOpenAIResponseObject): audio_tokens: Optional[int] = None - cached_tokens: int = 0 + cached_tokens: Optional[int] = None text_tokens: Optional[int] = None model_config = {"extra": "allow"} @@ -1193,7 +1193,7 @@ class ResponsesAPIResponse(BaseLiteLLMOpenAIResponseObject): status: Optional[str] = None text: Optional[Union["ResponseText", Dict[str, Any]]] = None truncation: Optional[Literal["auto", "disabled"]] = None - usage: Optional[ResponseAPIUsage] = None + usage: Optional[Any] = None user: Optional[str] = None store: Optional[bool] = None # Define private attributes using PrivateAttr diff --git a/litellm/types/llms/xai.py b/litellm/types/llms/xai.py deleted file mode 100644 index 9de8dfc7add..00000000000 --- a/litellm/types/llms/xai.py +++ /dev/null @@ -1,23 +0,0 @@ -from typing import List, Literal, Optional, TypedDict - - -class XAIWebSearchFilters(TypedDict, total=False): - """Filters for XAI web search tool""" - allowed_domains: Optional[List[str]] # Max 5 domains - excluded_domains: Optional[List[str]] # Max 5 domains - -class XAIWebSearchTool(TypedDict, total=False): - """XAI web search tool configuration""" - type: Literal["web_search"] - filters: Optional[XAIWebSearchFilters] - enable_image_understanding: Optional[bool] - -class XAIXSearchTool(TypedDict, total=False): - """XAI X (Twitter) search tool configuration""" - type: Literal["x_search"] - allowed_x_handles: Optional[List[str]] # Max 10 handles - excluded_x_handles: Optional[List[str]] # Max 10 handles - from_date: Optional[str] # ISO8601 format: YYYY-MM-DD - to_date: Optional[str] # ISO8601 format: YYYY-MM-DD - enable_image_understanding: Optional[bool] - enable_video_understanding: Optional[bool] \ No newline at end of file diff --git a/litellm/types/proxy/guardrails/guardrail_hooks/onyx.py b/litellm/types/proxy/guardrails/guardrail_hooks/onyx.py index 42d7e94829f..aa5b9d7a3fc 100644 --- a/litellm/types/proxy/guardrails/guardrail_hooks/onyx.py +++ b/litellm/types/proxy/guardrails/guardrail_hooks/onyx.py @@ -16,11 +16,6 @@ class OnyxGuardrailConfigModel(GuardrailConfigModel): description="The API key for the Onyx Guard server. If not provided, the `ONYX_API_KEY` environment variable is checked.", ) - timeout: Optional[float] = Field( - default=None, - description="The timeout for the Onyx Guard server in seconds. If not provided, the `ONYX_TIMEOUT` environment variable is checked.", - ) - @staticmethod def ui_friendly_name() -> str: return "Onyx Guardrail" diff --git a/litellm/types/proxy/management_endpoints/key_management_endpoints.py b/litellm/types/proxy/management_endpoints/key_management_endpoints.py deleted file mode 100644 index b1d25455d18..00000000000 --- a/litellm/types/proxy/management_endpoints/key_management_endpoints.py +++ /dev/null @@ -1,42 +0,0 @@ -from typing import Any, Dict, List, Optional - -from pydantic import BaseModel - - -class BulkUpdateKeyRequestItem(BaseModel): - """Individual key update request item""" - - key: str # Key identifier (token) - budget_id: Optional[str] = None # Budget ID associated with the key - max_budget: Optional[float] = None # Max budget for key - team_id: Optional[str] = None # Team ID associated with key - tags: Optional[List[str]] = None # Tags for organizing keys - - -class BulkUpdateKeyRequest(BaseModel): - """Request for bulk key updates""" - - keys: List[BulkUpdateKeyRequestItem] - - -class SuccessfulKeyUpdate(BaseModel): - """Successfully updated key with its updated information""" - - key: str - key_info: Dict[str, Any] - - -class FailedKeyUpdate(BaseModel): - """Failed key update with reason""" - - key: str - key_info: Optional[Dict[str, Any]] = None - failed_reason: str - - -class BulkUpdateKeyResponse(BaseModel): - """Response for bulk key update operations""" - - total_requested: int - successful_updates: List[SuccessfulKeyUpdate] - failed_updates: List[FailedKeyUpdate] diff --git a/litellm/types/rag.py b/litellm/types/rag.py index cae07708686..fe237a13431 100644 --- a/litellm/types/rag.py +++ b/litellm/types/rag.py @@ -129,53 +129,9 @@ class VertexAIVectorStoreOptions(TypedDict, total=False): import_timeout: Optional[int] # Timeout in seconds (default: 600) -class S3VectorsVectorStoreOptions(TypedDict, total=False): - """ - AWS S3 Vectors configuration. - - Example (auto-create): - {"custom_llm_provider": "s3_vectors", "vector_bucket_name": "my-embeddings"} - - Example (use existing): - {"custom_llm_provider": "s3_vectors", "vector_bucket_name": "my-embeddings", - "index_name": "my-index"} - - Example (with credentials): - {"custom_llm_provider": "s3_vectors", "vector_bucket_name": "my-embeddings", - "litellm_credential_name": "my-aws-creds"} - - Auto-creation creates: S3 vector bucket and vector index (if not provided). - Embeddings are generated using LiteLLM's embedding API (supports any provider). - """ - - custom_llm_provider: Literal["s3_vectors"] - vector_bucket_name: str # Required - S3 vector bucket name - index_name: Optional[str] # Vector index name (auto-creates if not provided) - - # Index configuration (for auto-creation) - dimension: Optional[int] # Vector dimension (auto-detected from embedding model, or default: 1024) - distance_metric: Optional[Literal["cosine", "euclidean"]] # Default: cosine - non_filterable_metadata_keys: Optional[List[str]] # Keys excluded from filtering (e.g., ["source_text"]) - - # Credentials (loaded from litellm.credential_list if litellm_credential_name is provided) - litellm_credential_name: Optional[str] # Credential name to load from litellm.credential_list - - # AWS auth (uses BaseAWSLLM) - aws_access_key_id: Optional[str] - aws_secret_access_key: Optional[str] - aws_session_token: Optional[str] - aws_region_name: Optional[str] # default: us-west-2 - aws_role_name: Optional[str] - aws_session_name: Optional[str] - aws_profile_name: Optional[str] - aws_web_identity_token: Optional[str] - aws_sts_endpoint: Optional[str] - aws_external_id: Optional[str] - - # Union type for vector store options RAGIngestVectorStoreOptions = Union[ - OpenAIVectorStoreOptions, BedrockVectorStoreOptions, VertexAIVectorStoreOptions, S3VectorsVectorStoreOptions + OpenAIVectorStoreOptions, BedrockVectorStoreOptions, VertexAIVectorStoreOptions ] diff --git a/litellm/types/router.py b/litellm/types/router.py index 43943d9e07e..8ea7a207535 100644 --- a/litellm/types/router.py +++ b/litellm/types/router.py @@ -404,10 +404,6 @@ class LiteLLMParamsTypedDict(TypedDict, total=False): aws_access_key_id: Optional[str] aws_secret_access_key: Optional[str] aws_region_name: Optional[str] - ## AWS S3 VECTORS ## - vector_bucket_name: Optional[str] - index_name: Optional[str] - embedding_model: Optional[str] ## IBM WATSONX ## watsonx_region_name: Optional[str] ## CUSTOM PRICING ## diff --git a/litellm/types/utils.py b/litellm/types/utils.py index 49c903502d1..0ec79e90a1f 100644 --- a/litellm/types/utils.py +++ b/litellm/types/utils.py @@ -3,28 +3,25 @@ from enum import Enum from typing import TYPE_CHECKING, Any, Dict, List, Literal, Mapping, Optional, Union +from aiohttp import FormData from openai._models import BaseModel as OpenAIObject -from openai.types.audio.transcription_create_params import ( - FileTypes as FileTypes, # type: ignore -) -from openai.types.chat.chat_completion import ChatCompletion as ChatCompletion +from openai.types.audio.transcription_create_params import FileTypes # type: ignore +from openai.types.chat.chat_completion import ChatCompletion from openai.types.completion_usage import ( CompletionTokensDetails, CompletionUsage, PromptTokensDetails, ) -from openai.types.moderation import Categories as Categories from openai.types.moderation import ( - CategoryAppliedInputTypes as CategoryAppliedInputTypes, -) -from openai.types.moderation import CategoryScores as CategoryScores -from openai.types.moderation_create_response import Moderation as Moderation -from openai.types.moderation_create_response import ( - ModerationCreateResponse as ModerationCreateResponse, + Categories, + CategoryAppliedInputTypes, + CategoryScores, ) +from openai.types.moderation_create_response import Moderation, ModerationCreateResponse from pydantic import BaseModel, ConfigDict, Field, PrivateAttr, model_validator -from typing_extensions import Required, TypedDict +from typing_extensions import Callable, Dict, Required, TypedDict, override +import litellm from litellm._uuid import uuid from litellm.types.llms.base import ( BaseLiteLLMOpenAIResponseObject, @@ -55,7 +52,7 @@ ResponsesAPIResponse, WebSearchOptions, ) -from .rerank import RerankResponse as RerankResponse +from .rerank import RerankResponse if TYPE_CHECKING: from .vector_stores import VectorStoreSearchResponse @@ -1414,7 +1411,7 @@ class Usage(SafeAttributeModel, CompletionUsage): prompt_tokens_details: Optional[PromptTokensDetailsWrapper] = None """Breakdown of tokens used in the prompt.""" - def __init__( # noqa: PLR0915 + def __init__( self, prompt_tokens: Optional[int] = None, completion_tokens: Optional[int] = None, @@ -2504,7 +2501,6 @@ class StandardLoggingMetadata(StandardLoggingUserAPIKeyMetadata): dict ] # special param to log k,v pairs to spendlogs for a call requester_ip_address: Optional[str] - user_agent: Optional[str] requester_metadata: Optional[dict] requester_custom_headers: Optional[ Dict[str, str] @@ -2690,7 +2686,6 @@ class StandardLoggingPayload(TypedDict): request_tags: list end_user: Optional[str] requester_ip_address: Optional[str] - user_agent: Optional[str] messages: Optional[Union[str, list, dict]] response: Optional[Union[str, list, dict]] error_str: Optional[str] @@ -3077,7 +3072,6 @@ class LlmProviders(str, Enum): LLAMA = "meta_llama" NSCALE = "nscale" PG_VECTOR = "pg_vector" - S3_VECTORS = "s3_vectors" HELICONE = "helicone" HYPERBOLIC = "hyperbolic" RECRAFT = "recraft" diff --git a/litellm/types/vector_stores.py b/litellm/types/vector_stores.py index 58a6a3272cd..a4ceb2c9ac7 100644 --- a/litellm/types/vector_stores.py +++ b/litellm/types/vector_stores.py @@ -38,10 +38,6 @@ class LiteLLM_ManagedVectorStore(TypedDict, total=False): # litellm_params litellm_params: Optional[Dict[str, Any]] - - # access control fields - team_id: Optional[str] - user_id: Optional[str] class LiteLLM_ManagedVectorStoreListResponse(TypedDict, total=False): diff --git a/litellm/utils.py b/litellm/utils.py index d7fb4855a48..1865d364586 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -5135,15 +5135,10 @@ def _invalidate_model_cost_lowercase_map() -> None: """Invalidate the case-insensitive lookup map for model_cost. Call this whenever litellm.model_cost is modified to ensure the map is rebuilt. - Also clears related LRU caches that depend on model_cost data. """ global _model_cost_lowercase_map _model_cost_lowercase_map = None - # Clear LRU caches that depend on model_cost data - get_model_info.cache_clear() - _cached_get_model_info_helper.cache_clear() - def _rebuild_model_cost_lowercase_map() -> Dict[str, str]: """Rebuild the case-insensitive lookup map from the current model_cost. @@ -5357,7 +5352,6 @@ def _get_max_position_embeddings(model_name: str) -> Optional[int]: return None -@lru_cache(maxsize=DEFAULT_MAX_LRU_CACHE_SIZE) def _cached_get_model_info_helper( model: str, custom_llm_provider: Optional[str] ) -> ModelInfoBase: @@ -5705,7 +5699,6 @@ def _get_model_info_helper( # noqa: PLR0915 ) -@lru_cache(maxsize=DEFAULT_MAX_LRU_CACHE_SIZE) def get_model_info(model: str, custom_llm_provider: Optional[str] = None) -> ModelInfo: """ Get a dict for the maximum tokens (context window), input_cost_per_token, output_cost_per_token for a given model. @@ -8053,12 +8046,6 @@ def get_provider_embedding_config( ) return OpenrouterEmbeddingConfig() - elif litellm.LlmProviders.VERCEL_AI_GATEWAY == provider: - from litellm.llms.vercel_ai_gateway.embedding.transformation import ( - VercelAIGatewayEmbeddingConfig, - ) - - return VercelAIGatewayEmbeddingConfig() elif litellm.LlmProviders.GIGACHAT == provider: return litellm.GigaChatEmbeddingConfig() elif litellm.LlmProviders.SAGEMAKER == provider: @@ -8452,12 +8439,6 @@ def get_provider_vector_stores_config( ) return RAGFlowVectorStoreConfig() - elif litellm.LlmProviders.S3_VECTORS == provider: - from litellm.llms.s3_vectors.vector_stores.transformation import ( - S3VectorsVectorStoreConfig, - ) - - return S3VectorsVectorStoreConfig() return None @staticmethod @@ -8705,9 +8686,9 @@ def get_provider_search_config( """ Get Search configuration for a given provider. """ - from litellm.llms.brave.search.transformation import BraveSearchConfig from litellm.llms.dataforseo.search.transformation import DataForSEOSearchConfig from litellm.llms.exa_ai.search.transformation import ExaAISearchConfig + from litellm.llms.brave.search.transformation import BraveSearchConfig from litellm.llms.firecrawl.search.transformation import FirecrawlSearchConfig from litellm.llms.google_pse.search.transformation import GooglePSESearchConfig from litellm.llms.linkup.search.transformation import LinkupSearchConfig diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index fad5f243fff..209c0794e50 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -3130,7 +3130,7 @@ "supports_reasoning": true, "supports_response_schema": true, "supports_system_messages": true, - "supports_tool_choice": true, + "supports_tool_choice": false, "supports_vision": true }, "azure/gpt-5-chat-latest": { @@ -3162,7 +3162,7 @@ "supports_reasoning": true, "supports_response_schema": true, "supports_system_messages": true, - "supports_tool_choice": true, + "supports_tool_choice": false, "supports_vision": true }, "azure/gpt-5-codex": { @@ -3653,9 +3653,10 @@ "max_input_tokens": 128000, "max_output_tokens": 16384, "max_tokens": 16384, - "mode": "responses", + "mode": "chat", "output_cost_per_token": 1.4e-05, "supported_endpoints": [ + "/v1/chat/completions", "/v1/responses" ], "supported_modalities": [ @@ -9787,7 +9788,6 @@ "supports_tool_choice": true }, "deepinfra/google/gemini-2.0-flash-001": { - "deprecation_date": "2026-03-31", "max_tokens": 1000000, "max_input_tokens": 1000000, "max_output_tokens": 1000000, @@ -10231,48 +10231,6 @@ "mode": "completion", "output_cost_per_token": 5e-07 }, - "deepseek-v3-2-251201": { - "input_cost_per_token": 0.0, - "litellm_provider": "volcengine", - "max_input_tokens": 98304, - "max_output_tokens": 32768, - "max_tokens": 32768, - "mode": "chat", - "output_cost_per_token": 0.0, - "supports_assistant_prefill": true, - "supports_function_calling": true, - "supports_prompt_caching": true, - "supports_reasoning": true, - "supports_tool_choice": true - }, - "glm-4-7-251222": { - "input_cost_per_token": 0.0, - "litellm_provider": "volcengine", - "max_input_tokens": 204800, - "max_output_tokens": 131072, - "max_tokens": 131072, - "mode": "chat", - "output_cost_per_token": 0.0, - "supports_assistant_prefill": true, - "supports_function_calling": true, - "supports_prompt_caching": true, - "supports_reasoning": true, - "supports_tool_choice": true - }, - "kimi-k2-thinking-251104": { - "input_cost_per_token": 0.0, - "litellm_provider": "volcengine", - "max_input_tokens": 229376, - "max_output_tokens": 32768, - "max_tokens": 32768, - "mode": "chat", - "output_cost_per_token": 0.0, - "supports_assistant_prefill": true, - "supports_function_calling": true, - "supports_prompt_caching": true, - "supports_reasoning": true, - "supports_tool_choice": true - }, "doubao-embedding": { "input_cost_per_token": 0.0, "litellm_provider": "volcengine", @@ -12147,7 +12105,6 @@ }, "gemini-2.0-flash": { "cache_read_input_token_cost": 2.5e-08, - "deprecation_date": "2026-03-31", "input_cost_per_audio_token": 7e-07, "input_cost_per_token": 1e-07, "litellm_provider": "vertex_ai-language-models", @@ -12187,7 +12144,7 @@ }, "gemini-2.0-flash-001": { "cache_read_input_token_cost": 3.75e-08, - "deprecation_date": "2026-03-31", + "deprecation_date": "2026-02-05", "input_cost_per_audio_token": 1e-06, "input_cost_per_token": 1.5e-07, "litellm_provider": "vertex_ai-language-models", @@ -12273,7 +12230,6 @@ }, "gemini-2.0-flash-lite": { "cache_read_input_token_cost": 1.875e-08, - "deprecation_date": "2026-03-31", "input_cost_per_audio_token": 7.5e-08, "input_cost_per_token": 7.5e-08, "litellm_provider": "vertex_ai-language-models", @@ -12309,7 +12265,7 @@ }, "gemini-2.0-flash-lite-001": { "cache_read_input_token_cost": 1.875e-08, - "deprecation_date": "2026-03-31", + "deprecation_date": "2026-02-25", "input_cost_per_audio_token": 7.5e-08, "input_cost_per_token": 7.5e-08, "litellm_provider": "vertex_ai-language-models", @@ -13521,79 +13477,6 @@ "supports_vision": true, "supports_web_search": true }, - "gemini-robotics-er-1.5-preview": { - "cache_read_input_token_cost": 0, - "input_cost_per_token": 3e-07, - "input_cost_per_audio_token": 1e-06, - "litellm_provider": "vertex_ai-language-models", - "max_input_tokens": 1048576, - "max_output_tokens": 65535, - "max_tokens": 65535, - "mode": "chat", - "output_cost_per_token": 2.5e-06, - "output_cost_per_reasoning_token": 2.5e-06, - "source": "https://ai.google.dev/gemini-api/docs/models#gemini-robotics-er-1-5-preview", - "supported_endpoints": [ - "/v1/chat/completions", - "/v1/completions" - ], - "supported_modalities": [ - "text", - "image", - "video", - "audio" - ], - "supported_output_modalities": [ - "text" - ], - "supports_audio_output": false, - "supports_function_calling": true, - "supports_parallel_function_calling": true, - "supports_prompt_caching": false, - "supports_reasoning": true, - "supports_response_schema": true, - "supports_system_messages": true, - "supports_tool_choice": true, - "supports_url_context": true, - "supports_vision": true - }, - "gemini/gemini-robotics-er-1.5-preview": { - "cache_read_input_token_cost": 0, - "input_cost_per_token": 3e-07, - "input_cost_per_audio_token": 1e-06, - "litellm_provider": "gemini", - "max_input_tokens": 1048576, - "max_output_tokens": 65535, - "max_tokens": 65535, - "mode": "chat", - "output_cost_per_token": 2.5e-06, - "output_cost_per_reasoning_token": 2.5e-06, - "source": "https://ai.google.dev/gemini-api/docs/models#gemini-robotics-er-1-5-preview", - "supported_endpoints": [ - "/v1/chat/completions", - "/v1/completions" - ], - "supported_modalities": [ - "text", - "image", - "video", - "audio" - ], - "supported_output_modalities": [ - "text" - ], - "supports_audio_output": false, - "supports_function_calling": true, - "supports_parallel_function_calling": true, - "supports_prompt_caching": false, - "supports_reasoning": true, - "supports_response_schema": true, - "supports_system_messages": true, - "supports_tool_choice": true, - "supports_url_context": true, - "supports_vision": true, - "supports_web_search": true - }, "gemini-2.5-computer-use-preview-10-2025": { "input_cost_per_token": 1.25e-06, "input_cost_per_token_above_200k_tokens": 2.5e-06, @@ -14047,7 +13930,6 @@ }, "gemini/gemini-2.0-flash": { "cache_read_input_token_cost": 2.5e-08, - "deprecation_date": "2026-03-31", "input_cost_per_audio_token": 7e-07, "input_cost_per_token": 1e-07, "litellm_provider": "gemini", @@ -14088,7 +13970,6 @@ }, "gemini/gemini-2.0-flash-001": { "cache_read_input_token_cost": 2.5e-08, - "deprecation_date": "2026-03-31", "input_cost_per_audio_token": 7e-07, "input_cost_per_token": 1e-07, "litellm_provider": "gemini", @@ -14176,7 +14057,6 @@ }, "gemini/gemini-2.0-flash-lite": { "cache_read_input_token_cost": 1.875e-08, - "deprecation_date": "2026-03-31", "input_cost_per_audio_token": 7.5e-08, "input_cost_per_token": 7.5e-08, "litellm_provider": "gemini", @@ -20663,7 +20543,6 @@ "supports_function_calling": true, "supports_tool_choice": true, "supports_prompt_caching": true, - "supports_reasoning": true, "supports_system_messages": true, "max_input_tokens": 1000000, "max_output_tokens": 8192 @@ -20678,7 +20557,6 @@ "supports_function_calling": true, "supports_tool_choice": true, "supports_prompt_caching": true, - "supports_reasoning": true, "supports_system_messages": true, "max_input_tokens": 1000000, "max_output_tokens": 8192 @@ -20693,7 +20571,6 @@ "supports_function_calling": true, "supports_tool_choice": true, "supports_prompt_caching": true, - "supports_reasoning": true, "supports_system_messages": true, "max_input_tokens": 200000, "max_output_tokens": 8192 @@ -23281,7 +23158,6 @@ "supports_tool_choice": true }, "openrouter/google/gemini-2.0-flash-001": { - "deprecation_date": "2026-03-31", "input_cost_per_audio_token": 7e-07, "input_cost_per_token": 1e-07, "litellm_provider": "openrouter", @@ -23578,7 +23454,7 @@ "mode": "chat", "output_cost_per_token": 1.02e-06, "supports_function_calling": true, - "supports_prompt_caching": true, + "supports_prompt_caching": false, "supports_reasoning": true, "supports_tool_choice": true }, @@ -23930,11 +23806,8 @@ "max_input_tokens": 400000, "max_output_tokens": 128000, "max_tokens": 128000, - "mode": "responses", + "mode": "chat", "output_cost_per_token": 1.4e-05, - "supported_endpoints": [ - "/v1/responses" - ], "supported_modalities": [ "text", "image" @@ -24273,7 +24146,6 @@ "output_cost_per_token": 1.75e-06, "source": "https://openrouter.ai/z-ai/glm-4.6", "supports_function_calling": true, - "supports_prompt_caching": true, "supports_reasoning": true, "supports_tool_choice": true }, @@ -24287,76 +24159,9 @@ "output_cost_per_token": 1.9e-06, "source": "https://openrouter.ai/z-ai/glm-4.6:exacto", "supports_function_calling": true, - "supports_prompt_caching": true, "supports_reasoning": true, "supports_tool_choice": true }, - "openrouter/xiaomi/mimo-v2-flash": { - "input_cost_per_token": 9e-08, - "output_cost_per_token": 2.9e-07, - "cache_creation_input_token_cost": 0.0, - "cache_read_input_token_cost": 0.0, - "litellm_provider": "openrouter", - "max_input_tokens": 262144, - "max_output_tokens": 16384, - "max_tokens": 16384, - "mode": "chat", - "supports_function_calling": true, - "supports_tool_choice": true, - "supports_reasoning": true, - "supports_vision": false, - "supports_prompt_caching": false - }, - "openrouter/z-ai/glm-4.7": { - "input_cost_per_token": 4e-07, - "output_cost_per_token": 1.5e-06, - "cache_creation_input_token_cost": 0.0, - "cache_read_input_token_cost": 0.0, - "litellm_provider": "openrouter", - "max_input_tokens": 202752, - "max_output_tokens": 64000, - "max_tokens": 64000, - "mode": "chat", - "supports_function_calling": true, - "supports_tool_choice": true, - "supports_reasoning": true, - "supports_vision": true, - "supports_prompt_caching": false, - "supports_assistant_prefill": true - }, - "openrouter/z-ai/glm-4.7-flash": { - "input_cost_per_token": 7e-08, - "output_cost_per_token": 4e-07, - "cache_creation_input_token_cost": 0.0, - "cache_read_input_token_cost": 0.0, - "litellm_provider": "openrouter", - "max_input_tokens": 200000, - "max_output_tokens": 32000, - "max_tokens": 32000, - "mode": "chat", - "supports_function_calling": true, - "supports_tool_choice": true, - "supports_reasoning": true, - "supports_vision": true, - "supports_prompt_caching": false - }, - "openrouter/minimax/minimax-m2.1": { - "input_cost_per_token": 2.7e-07, - "output_cost_per_token": 1.2e-06, - "cache_creation_input_token_cost": 0.0, - "cache_read_input_token_cost": 0.0, - "litellm_provider": "openrouter", - "max_input_tokens": 204000, - "max_output_tokens": 64000, - "max_tokens": 64000, - "mode": "chat", - "supports_function_calling": true, - "supports_tool_choice": true, - "supports_reasoning": true, - "supports_vision": true, - "supports_prompt_caching": false, - "supports_computer_use": false - }, "ovhcloud/DeepSeek-R1-Distill-Llama-70B": { "input_cost_per_token": 6.7e-07, "litellm_provider": "ovhcloud", @@ -27890,7 +27695,6 @@ "output_cost_per_token": 9e-07 }, "vercel_ai_gateway/google/gemini-2.0-flash": { - "deprecation_date": "2026-03-31", "input_cost_per_token": 1.5e-07, "litellm_provider": "vercel_ai_gateway", "max_input_tokens": 1048576, @@ -27900,7 +27704,6 @@ "output_cost_per_token": 6e-07 }, "vercel_ai_gateway/google/gemini-2.0-flash-lite": { - "deprecation_date": "2026-03-31", "input_cost_per_token": 7.5e-08, "litellm_provider": "vercel_ai_gateway", "max_input_tokens": 1048576, @@ -30570,7 +30373,6 @@ "supports_web_search": true }, "xai/grok-3": { - "cache_read_input_token_cost": 7.5e-07, "input_cost_per_token": 3e-06, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30585,7 +30387,6 @@ "supports_web_search": true }, "xai/grok-3-beta": { - "cache_read_input_token_cost": 7.5e-07, "input_cost_per_token": 3e-06, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30600,7 +30401,6 @@ "supports_web_search": true }, "xai/grok-3-fast-beta": { - "cache_read_input_token_cost": 1.25e-06, "input_cost_per_token": 5e-06, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30615,7 +30415,6 @@ "supports_web_search": true }, "xai/grok-3-fast-latest": { - "cache_read_input_token_cost": 1.25e-06, "input_cost_per_token": 5e-06, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30630,7 +30429,6 @@ "supports_web_search": true }, "xai/grok-3-latest": { - "cache_read_input_token_cost": 7.5e-07, "input_cost_per_token": 3e-06, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30645,7 +30443,6 @@ "supports_web_search": true }, "xai/grok-3-mini": { - "cache_read_input_token_cost": 7.5e-08, "input_cost_per_token": 3e-07, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30661,7 +30458,6 @@ "supports_web_search": true }, "xai/grok-3-mini-beta": { - "cache_read_input_token_cost": 7.5e-08, "input_cost_per_token": 3e-07, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30677,7 +30473,6 @@ "supports_web_search": true }, "xai/grok-3-mini-fast": { - "cache_read_input_token_cost": 1.5e-07, "input_cost_per_token": 6e-07, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30693,7 +30488,6 @@ "supports_web_search": true }, "xai/grok-3-mini-fast-beta": { - "cache_read_input_token_cost": 1.5e-07, "input_cost_per_token": 6e-07, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30709,7 +30503,6 @@ "supports_web_search": true }, "xai/grok-3-mini-fast-latest": { - "cache_read_input_token_cost": 1.5e-07, "input_cost_per_token": 6e-07, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30725,7 +30518,6 @@ "supports_web_search": true }, "xai/grok-3-mini-latest": { - "cache_read_input_token_cost": 7.5e-08, "input_cost_per_token": 3e-07, "litellm_provider": "xai", "max_input_tokens": 131072, @@ -30992,14 +30784,11 @@ "max_output_tokens": 128000, "mode": "chat", "supports_function_calling": true, - "supports_prompt_caching": true, "supports_reasoning": true, "supports_tool_choice": true, "source": "https://docs.z.ai/guides/overview/pricing" }, "zai/glm-4.6": { - "cache_creation_input_token_cost": 0, - "cache_read_input_token_cost": 1.1e-07, "input_cost_per_token": 6e-07, "output_cost_per_token": 2.2e-06, "litellm_provider": "zai", @@ -31007,8 +30796,6 @@ "max_output_tokens": 128000, "mode": "chat", "supports_function_calling": true, - "supports_prompt_caching": true, - "supports_reasoning": true, "supports_tool_choice": true, "source": "https://docs.z.ai/guides/overview/pricing" }, @@ -34656,4 +34443,4 @@ "output_cost_per_token": 0, "supports_reasoning": true } -} \ No newline at end of file +} diff --git a/poetry.lock b/poetry.lock index 9ded0c773c8..e5c304ea776 100644 --- a/poetry.lock +++ b/poetry.lock @@ -343,7 +343,7 @@ zookeeper = ["kazoo"] name = "async-timeout" version = "5.0.1" description = "Timeout context manager for asyncio programs" -optional = true +optional = false python-versions = ">=3.8" groups = ["main"] markers = "python_full_version < \"3.11.3\" and (extra == \"extra-proxy\" or extra == \"proxy\" or python_version < \"3.11\")" @@ -593,8 +593,8 @@ files = [ jmespath = ">=0.7.1,<2.0.0" python-dateutil = ">=2.1,<3.0.0" urllib3 = [ - {version = ">=1.25.4,<2.2.0 || >2.2.0,<3", markers = "python_version >= \"3.10\""}, {version = ">=1.25.4,<1.27", markers = "python_version < \"3.10\""}, + {version = ">=1.25.4,<2.2.0 || >2.2.0,<3", markers = "python_version >= \"3.10\""}, ] [package.extras] @@ -902,7 +902,7 @@ files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] -markers = {main = "platform_system == \"Windows\" or sys_platform == \"win32\" and python_version < \"3.14\" and (extra == \"utils\" or extra == \"semantic-router\") or sys_platform == \"win32\" and extra == \"utils\" or python_version <= \"3.13\" and extra == \"semantic-router\"", dev = "platform_system == \"Windows\" or sys_platform == \"win32\"", proxy-dev = "platform_system == \"Windows\""} +markers = {main = "platform_system == \"Windows\" or sys_platform == \"win32\" and python_version < \"3.14\" and (extra == \"utils\" or extra == \"semantic-router\") or sys_platform == \"win32\" and extra == \"utils\" or python_version < \"3.14\" and extra == \"semantic-router\"", dev = "platform_system == \"Windows\" or sys_platform == \"win32\"", proxy-dev = "platform_system == \"Windows\""} [[package]] name = "coloredlogs" @@ -2028,7 +2028,7 @@ description = "Google API client core library" optional = true python-versions = ">=3.7" groups = ["main"] -markers = "(extra == \"extra-proxy\" or extra == \"google\") and python_version < \"3.14\"" +markers = "python_version == \"3.9\" and (extra == \"google\" or extra == \"extra-proxy\") or python_version < \"3.14\" and (extra == \"extra-proxy\" or extra == \"google\")" files = [ {file = "google_api_core-2.28.1-py3-none-any.whl", hash = "sha256:4021b0f8ceb77a6fb4de6fde4502cecab45062e66ff4f2895169e0b35bc9466c"}, {file = "google_api_core-2.28.1.tar.gz", hash = "sha256:2b405df02d68e68ce0fbc138559e6036559e685159d148ae5861013dc201baf8"}, @@ -2038,12 +2038,12 @@ files = [ google-auth = ">=2.14.1,<3.0.0" googleapis-common-protos = ">=1.56.2,<2.0.0" grpcio = [ + {version = ">=1.33.2,<2.0.0", optional = true, markers = "extra == \"grpc\""}, {version = ">=1.49.1,<2.0.0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, - {version = ">=1.33.2,<2.0.0", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""}, ] grpcio-status = [ - {version = ">=1.49.1,<2.0.0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, {version = ">=1.33.2,<2.0.0", optional = true, markers = "extra == \"grpc\""}, + {version = ">=1.49.1,<2.0.0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, ] proto-plus = [ {version = ">=1.22.3,<2.0.0"}, @@ -2525,7 +2525,7 @@ description = "Lightweight in-process concurrent programming" optional = true python-versions = ">=3.9" groups = ["main"] -markers = "python_version >= \"3.10\" and extra == \"mlflow\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")" +markers = "python_version >= \"3.10\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\") and extra == \"mlflow\"" files = [ {file = "greenlet-3.2.4-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:8c68325b0d0acf8d91dde4e6f930967dd52a5302cd4062932a6b2e7c2969f47c"}, {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:94385f101946790ae13da500603491f04a76b6e4c059dab271b3ce2e283b2590"}, @@ -2720,7 +2720,7 @@ description = "WSGI HTTP Server for UNIX" optional = true python-versions = ">=3.7" groups = ["main"] -markers = "extra == \"proxy\" or python_version >= \"3.10\" and (extra == \"proxy\" or extra == \"mlflow\") and platform_system != \"Windows\"" +markers = "(python_version < \"3.14\" or extra == \"mlflow\" or extra == \"proxy\") and (platform_system != \"Windows\" or extra == \"proxy\") and (python_version >= \"3.10\" or extra == \"proxy\") and (extra == \"proxy\" or extra == \"mlflow\")" files = [ {file = "gunicorn-23.0.0-py3-none-any.whl", hash = "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d"}, {file = "gunicorn-23.0.0.tar.gz", hash = "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec"}, @@ -3426,15 +3426,15 @@ files = [ [[package]] name = "litellm-proxy-extras" -version = "0.4.27" +version = "0.4.26" description = "Additional files for the LiteLLM Proxy. Reduces the size of the main litellm package." optional = true python-versions = "!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*,>=3.8" groups = ["main"] markers = "extra == \"proxy\"" files = [ - {file = "litellm_proxy_extras-0.4.27-py3-none-any.whl", hash = "sha256:752c1faabc86ce3d2b1fa451495d34de82323798e37b9cb5c0fea93deae1c5c8"}, - {file = "litellm_proxy_extras-0.4.27.tar.gz", hash = "sha256:81059120016cfc03c82aa9664424912bdcffad103f66a5f925fef6b26f2cc151"}, + {file = "litellm_proxy_extras-0.4.26-py3-none-any.whl", hash = "sha256:6b8720c7ae0b51637a3155b6cb02783c316443fe002641061ed9162d2667aee4"}, + {file = "litellm_proxy_extras-0.4.26.tar.gz", hash = "sha256:cb9544703580172fc6436670e1a693a46ccb34a9057548c94f43e97b7b032754"}, ] [[package]] @@ -3777,10 +3777,10 @@ files = [ [package.dependencies] numpy = [ - {version = ">=1.23.3", markers = "python_version >= \"3.11\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, {version = ">1.20"}, + {version = ">=1.23.3", markers = "python_version >= \"3.11\""}, {version = ">=1.21.2", markers = "python_version >= \"3.10\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, ] [package.extras] @@ -4191,7 +4191,7 @@ description = "Fundamental package for array computing in Python" optional = true python-versions = ">=3.9" groups = ["main"] -markers = "(python_version >= \"3.10\" or extra == \"extra-proxy\" or extra == \"semantic-router\" or extra == \"google\") and python_version < \"3.12\" and (extra == \"extra-proxy\" or extra == \"semantic-router\" or extra == \"google\" or extra == \"mlflow\")" +markers = "python_version < \"3.12\" and (python_version >= \"3.10\" or extra == \"extra-proxy\" or extra == \"semantic-router\" or extra == \"google\") and (extra == \"extra-proxy\" or extra == \"semantic-router\" or extra == \"google\" or extra == \"mlflow\")" files = [ {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, @@ -4708,8 +4708,8 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.23.2", markers = "python_version == \"3.11\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -5169,7 +5169,7 @@ description = "Beautiful, Pythonic protocol buffers" optional = true python-versions = ">=3.7" groups = ["main"] -markers = "extra == \"extra-proxy\" or extra == \"google\"" +markers = "extra == \"google\" or extra == \"extra-proxy\"" files = [ {file = "proto_plus-1.26.1-py3-none-any.whl", hash = "sha256:13285478c2dcf2abb829db158e1047e2f1e8d63a077d94263c2b88b043c75a66"}, {file = "proto_plus-1.26.1.tar.gz", hash = "sha256:21a515a4c4c0088a773899e23c7bbade3d18f9c66c73edd4c7ee3816bc96a012"}, @@ -5316,7 +5316,7 @@ files = [ {file = "pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934"}, {file = "pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2"}, ] -markers = {main = "implementation_name != \"PyPy\" and (platform_python_implementation != \"PyPy\" or extra == \"proxy\")", dev = "implementation_name != \"PyPy\" and platform_python_implementation != \"PyPy\"", proxy-dev = "implementation_name != \"PyPy\" and platform_python_implementation != \"PyPy\""} +markers = {main = "implementation_name != \"PyPy\" and (platform_python_implementation != \"PyPy\" or extra == \"proxy\")", dev = "platform_python_implementation != \"PyPy\" and implementation_name != \"PyPy\"", proxy-dev = "implementation_name != \"PyPy\" and platform_python_implementation != \"PyPy\""} [[package]] name = "pydantic" @@ -5617,7 +5617,7 @@ description = "A python implementation of GNU readline." optional = true python-versions = ">=3.8" groups = ["main"] -markers = "sys_platform == \"win32\" and extra == \"extra-proxy\" and python_version < \"3.14\"" +markers = "extra == \"extra-proxy\" and sys_platform == \"win32\" and python_version < \"3.14\"" files = [ {file = "pyreadline3-3.5.4-py3-none-any.whl", hash = "sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6"}, {file = "pyreadline3-3.5.4.tar.gz", hash = "sha256:8d57d53039a1c75adba8e50dd3d992b28143480816187ea5efbd5c78e6c885b7"}, @@ -5719,15 +5719,15 @@ cli = ["click (>=5.0)"] [[package]] name = "python-multipart" -version = "0.0.22" +version = "0.0.18" description = "A streaming multipart parser for Python" optional = true python-versions = ">=3.8" groups = ["main"] markers = "extra == \"proxy\"" files = [ - {file = "python_multipart-0.0.22-py3-none-any.whl", hash = "sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155"}, - {file = "python_multipart-0.0.22.tar.gz", hash = "sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58"}, + {file = "python_multipart-0.0.18-py3-none-any.whl", hash = "sha256:efe91480f485f6a361427a541db4796f9e1591afc0fb8e7a4ba06bfbc6708996"}, + {file = "python_multipart-0.0.18.tar.gz", hash = "sha256:7a68db60c8bfb82e460637fa4750727b45af1d5e2ed215593f917f64694d34fe"}, ] [[package]] @@ -5766,7 +5766,7 @@ description = "Python for Window Extensions" optional = true python-versions = "*" groups = ["main"] -markers = "python_version >= \"3.10\" and (extra == \"proxy\" or extra == \"mlflow\") and sys_platform == \"win32\"" +markers = "python_version >= \"3.10\" and sys_platform == \"win32\" and (extra == \"proxy\" or extra == \"mlflow\")" files = [ {file = "pywin32-311-cp310-cp310-win32.whl", hash = "sha256:d03ff496d2a0cd4a5893504789d4a15399133fe82517455e78bad62efbb7f0a3"}, {file = "pywin32-311-cp310-cp310-win_amd64.whl", hash = "sha256:797c2772017851984b97180b0bebe4b620bb86328e8a884bb626156295a63b3b"}, @@ -7450,6 +7450,26 @@ examples = ["aiosqlite (>=0.21.0)", "fastapi (>=0.115.12)", "sqlalchemy[asyncio] granian = ["granian (>=2.3.1)"] uvicorn = ["uvicorn (>=0.34.0)"] +[[package]] +name = "starlette" +version = "0.49.3" +description = "The little ASGI library that shines." +optional = false +python-versions = ">=3.9" +groups = ["main", "dev"] +files = [ + {file = "starlette-0.49.3-py3-none-any.whl", hash = "sha256:b579b99715fdc2980cf88c8ec96d3bf1ce16f5a8051a7c2b84ef9b1cdecaea2f"}, + {file = "starlette-0.49.3.tar.gz", hash = "sha256:1c14546f299b5901a1ea0e34410575bc33bbd741377a10484a54445588d00284"}, +] +markers = {main = "python_version == \"3.9\" and extra == \"proxy\"", dev = "python_version == \"3.9\""} + +[package.dependencies] +anyio = ">=3.6.2,<5" +typing-extensions = {version = ">=4.10.0", markers = "python_version < \"3.13\""} + +[package.extras] +full = ["httpx (>=0.27.0,<0.29.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.18)", "pyyaml"] + [[package]] name = "starlette" version = "0.50.0" @@ -7461,7 +7481,7 @@ files = [ {file = "starlette-0.50.0-py3-none-any.whl", hash = "sha256:9e5391843ec9b6e472eed1365a78c8098cfceb7a74bfd4d6b1c0c0095efb3bca"}, {file = "starlette-0.50.0.tar.gz", hash = "sha256:a2a17b22203254bcbc2e1f926d2d55f3f9497f769416b3190768befe598fa3ca"}, ] -markers = {main = "(extra == \"mlflow\" or extra == \"proxy\") and python_version >= \"3.10\" or extra == \"proxy\""} +markers = {main = "python_version >= \"3.10\" and (extra == \"mlflow\" or extra == \"proxy\") or extra == \"proxy\""} [package.dependencies] anyio = ">=3.6.2,<5" @@ -7510,7 +7530,7 @@ description = "Retry code until it succeeds" optional = true python-versions = ">=3.9" groups = ["main"] -markers = "(extra == \"extra-proxy\" or extra == \"google\") and python_version < \"3.14\" or extra == \"google\"" +markers = "(extra == \"extra-proxy\" or extra == \"google\") and (python_version < \"3.14\" or extra == \"google\")" files = [ {file = "tenacity-9.1.2-py3-none-any.whl", hash = "sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138"}, {file = "tenacity-9.1.2.tar.gz", hash = "sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb"}, @@ -8062,7 +8082,7 @@ description = "Waitress WSGI server" optional = true python-versions = ">=3.9.0" groups = ["main"] -markers = "python_version >= \"3.10\" and extra == \"mlflow\" and platform_system == \"Windows\"" +markers = "python_version >= \"3.10\" and platform_system == \"Windows\" and extra == \"mlflow\"" files = [ {file = "waitress-3.0.2-py3-none-any.whl", hash = "sha256:c56d67fd6e87c2ee598b76abdd4e96cfad1f24cacdea5078d382b1f9d7b5ed2e"}, {file = "waitress-3.0.2.tar.gz", hash = "sha256:682aaaf2af0c44ada4abfb70ded36393f0e307f4ab9456a215ce0020baefc31f"}, @@ -8472,4 +8492,4 @@ utils = ["numpydoc"] [metadata] lock-version = "2.1" python-versions = ">=3.9,<4.0" -content-hash = "73b5e1ab0badbee6c564d5e056e4f9c320c2f722bf176ce97d42e77110e37d60" +content-hash = "ee8411854731cb6cc038a6135d7589a81789a269e718a226101953ba24fb2033" diff --git a/proxy_config.yaml b/proxy_config.yaml new file mode 100644 index 00000000000..ea405c1dea4 --- /dev/null +++ b/proxy_config.yaml @@ -0,0 +1,101 @@ +model_list: + - model_name: "*" + litellm_params: + model: "*" + - model_name: "gpt-4" + litellm_params: + model: "gpt-4" + api_key: os.environ/OPENAI_API_KEY + - model_name: "gpt-3.5-turbo" + litellm_params: + model: "gpt-3.5-turbo" + api_key: os.environ/OPENAI_API_KEY + +general_settings: + master_key: sk-1234 + +# ─────────────────────────────────────────────── +# POLICIES - Define WHAT guardrails to apply +# ─────────────────────────────────────────────── +# +# Policies define guardrails with: +# - inherit: Inherit guardrails from another policy +# - description: Human-readable description +# - guardrails.add: Add guardrails (on top of inherited) +# - guardrails.remove: Remove guardrails (from inherited) +# - condition.model: Model pattern (exact or regex) for when guardrails apply +# +policies: + # Global baseline policy + global-baseline: + description: "Base guardrails for all requests" + guardrails: + add: + - pii_blocker + + # Healthcare policy - inherits from global-baseline + healthcare-compliance: + inherit: global-baseline + description: "HIPAA compliance for healthcare teams" + guardrails: + add: + - hipaa_audit + + # Dev policy - inherits but removes PII blocker for testing + internal-dev: + inherit: global-baseline + description: "Relaxed policy for internal development" + guardrails: + add: + - toxicity_filter + remove: + - pii_blocker + + # Policy with model condition (regex pattern) + gpt4-safety: + description: "Extra safety for GPT-4 models" + guardrails: + add: + - toxicity_filter + condition: + model: "gpt-4.*" # regex: matches gpt-4, gpt-4-turbo, gpt-4o, etc. + + # Policy with model condition (exact match list) + bedrock-compliance: + description: "Compliance for Bedrock models" + guardrails: + add: + - strict_pii_blocker + condition: + model: ["bedrock/claude-3", "bedrock/claude-2"] # exact matches + +# ─────────────────────────────────────────────── +# POLICY ATTACHMENTS - Define WHERE policies apply +# ─────────────────────────────────────────────── +# +# Attachments are REQUIRED to make policies active. +# A policy without an attachment will not be applied. +# +policy_attachments: + # Global attachment - applies to all requests + - policy: global-baseline + scope: "*" + + # Team-specific attachment + - policy: healthcare-compliance + teams: + - healthcare-team + - medical-research + + # Key pattern attachment + - policy: internal-dev + keys: + - "dev-key-*" + - "test-key-*" + + # Model-specific policies (attached globally, condition filters by model) + - policy: gpt4-safety + scope: "*" + + - policy: bedrock-compliance + scope: "*" diff --git a/pyproject.toml b/pyproject.toml index 6c3ab08ce02..862611879a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "litellm" -version = "1.81.5" +version = "1.81.2" description = "Library to easily interface with LLM API providers" authors = ["BerriAI"] license = "MIT" @@ -45,7 +45,7 @@ orjson = {version = "^3.9.7", optional = true} apscheduler = {version = "^3.10.4", optional = true} fastapi-sso = { version = "^0.16.0", optional = true } PyJWT = { version = "^2.10.1", optional = true, python = ">=3.9" } -python-multipart = { version = "^0.0.22", optional = true} +python-multipart = { version = "^0.0.18", optional = true} cryptography = {version = "*", optional = true} prisma = {version = "0.11.0", optional = true} azure-identity = {version = "^1.15.0", optional = true, python = ">=3.9"} @@ -61,7 +61,7 @@ boto3 = { version = "1.40.76", optional = true } redisvl = {version = "^0.4.1", optional = true, markers = "python_version >= '3.9' and python_version < '3.14'"} mcp = {version = ">=1.25.0,<2.0.0", optional = true, python = ">=3.10"} a2a-sdk = {version = "^0.3.22", optional = true, python = ">=3.10"} -litellm-proxy-extras = {version = "0.4.27", optional = true} +litellm-proxy-extras = {version = "0.4.26", optional = true} rich = {version = "13.7.1", optional = true} litellm-enterprise = {version = "0.1.27", optional = true} diskcache = {version = "^5.6.1", optional = true} @@ -145,7 +145,6 @@ mypy = "^1.0" pytest = "^7.4.3" pytest-mock = "^3.12.0" pytest-asyncio = "^0.21.1" -pytest-retry = "^1.6.3" requests-mock = "^1.12.1" responses = "^0.25.7" respx = "^0.22.0" @@ -174,7 +173,7 @@ requires = ["poetry-core", "wheel"] build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "1.81.5" +version = "1.81.2" version_files = [ "pyproject.toml:^version" ] @@ -184,8 +183,6 @@ plugins = "pydantic.mypy" [tool.pytest.ini_options] asyncio_mode = "auto" -retries = 20 -retry_delay = 5 markers = [ "asyncio: mark test as an asyncio test", "limit_leaks: mark test with memory limit for leak detection (e.g., '40 MB')", diff --git a/requirements.txt b/requirements.txt index e40f9b9dbe4..9e32cd79507 100644 --- a/requirements.txt +++ b/requirements.txt @@ -32,7 +32,7 @@ polars==1.31.0 # for data processing apscheduler==3.10.4 # for resetting budget in background fastapi-sso==0.19.0 # admin UI, SSO pyjwt[crypto]==2.10.1 ; python_version >= "3.9" -python-multipart==0.0.22 # admin UI +python-multipart==0.0.18 # admin UI Pillow==11.0.0 jaraco.context>=6.1.0 azure-ai-contentsafety==1.0.0 # for azure content safety @@ -50,7 +50,7 @@ sentry_sdk==2.21.0 # for sentry error handling detect-secrets==1.5.0 # Enterprise - secret detection / masking in LLM requests cryptography==44.0.1 tzdata==2025.1 # IANA time zone database -litellm-proxy-extras==0.4.27 # for proxy extras - e.g. prisma migrations +litellm-proxy-extras==0.4.26 # for proxy extras - e.g. prisma migrations llm-sandbox==0.3.31 # for skill execution in sandbox ### LITELLM PACKAGE DEPENDENCIES python-dotenv==1.0.1 # for env @@ -68,7 +68,6 @@ jsonschema>=4.23.0,<5.0.0 # validating json schema - aligned with openapi-core + websockets==15.0.1 # for realtime API soundfile==0.12.1 # for audio file processing openapi-core==0.21.0 # for OpenAPI compliance tests -pypdf>=6.6.2 # for PDF text extraction in RAG ingestion ######################## # LITELLM ENTERPRISE DEPENDENCIES diff --git a/schema.prisma b/schema.prisma index ca60b9e1bec..d7aa6e9f0d0 100644 --- a/schema.prisma +++ b/schema.prisma @@ -760,11 +760,6 @@ model LiteLLM_ManagedVectorStoresTable { updated_at DateTime @updatedAt litellm_credential_name String? litellm_params Json? - team_id String? - user_id String? - - @@index([team_id]) - @@index([user_id]) } // Guardrails table for storing guardrail configurations diff --git a/tests/code_coverage_tests/liccheck.ini b/tests/code_coverage_tests/liccheck.ini index dc46f83366a..ea87b56ff30 100644 --- a/tests/code_coverage_tests/liccheck.ini +++ b/tests/code_coverage_tests/liccheck.ini @@ -141,4 +141,3 @@ llm-sandbox: >=0.3.31 # MIT License - https://github.com/vndee/llm-sandbox nodejs-wheel-binaries: >=24.12.0 # MIT license manually verified grpcio: >=1.69.0 # Apache License 2.0 jaraco.context: >=6.1.0 # Unknown license -pypdf: >=6.6.2 # BSD-3-Clause license - https://github.com/py-pdf/pypdf/blob/main/LICENSE diff --git a/tests/code_coverage_tests/license_cache.json b/tests/code_coverage_tests/license_cache.json index a9c7fad2b14..910ec931c86 100644 --- a/tests/code_coverage_tests/license_cache.json +++ b/tests/code_coverage_tests/license_cache.json @@ -20,7 +20,7 @@ "apscheduler:3.10.4": "MIT", "fastapi-sso:0.16.0": "MIT", "pyjwt:2.9.0": "MIT", - "python-multipart:0.0.22": "Apache-2.0", + "python-multipart:0.0.18": "Apache-2.0", "Pillow:11.0.0": "MIT-CMU", "azure-ai-contentsafety:1.0.0": "MIT License", "azure-identity:1.16.1": "MIT License", diff --git a/tests/code_coverage_tests/router_code_coverage.py b/tests/code_coverage_tests/router_code_coverage.py index 49288dd3775..d700e56a06f 100644 --- a/tests/code_coverage_tests/router_code_coverage.py +++ b/tests/code_coverage_tests/router_code_coverage.py @@ -6,7 +6,7 @@ def get_function_names_from_file(file_path): """ Extracts all function names from a given Python file. """ - with open(file_path, "r", encoding="utf-8") as file: + with open(file_path, "r") as file: tree = ast.parse(file.read()) function_names = [] @@ -45,7 +45,7 @@ def get_all_functions_called_in_tests(base_dir): if file.endswith(".py") and "router" in file.lower(): print("file: ", file) file_path = os.path.join(root, file) - with open(file_path, "r", encoding="utf-8") as f: + with open(file_path, "r") as f: try: tree = ast.parse(f.read()) except SyntaxError: diff --git a/tests/enterprise/litellm_enterprise/enterprise_callbacks/test_prometheus_logging_callbacks.py b/tests/enterprise/litellm_enterprise/enterprise_callbacks/test_prometheus_logging_callbacks.py index a479d1a9fc9..2419c61c25c 100644 --- a/tests/enterprise/litellm_enterprise/enterprise_callbacks/test_prometheus_logging_callbacks.py +++ b/tests/enterprise/litellm_enterprise/enterprise_callbacks/test_prometheus_logging_callbacks.py @@ -411,15 +411,7 @@ def test_set_latency_metrics(prometheus_logger): # completion_start_time - api_call_start_time prometheus_logger.litellm_llm_api_time_to_first_token_metric.labels.assert_called_once_with( - end_user=None, - user="test_user", - hashed_api_key="test_hash", - api_key_alias="test_alias", - team="test_team", - team_alias="test_team_alias", - requested_model="openai-gpt", - model="gpt-3.5-turbo", - model_id="model-123", + "gpt-3.5-turbo", "key1", "alias1", "team1", "team_alias1" ) prometheus_logger.litellm_llm_api_time_to_first_token_metric.labels().observe.assert_called_once_with( 0.5 @@ -450,7 +442,6 @@ def test_set_latency_metrics(prometheus_logger): team_alias="test_team_alias", requested_model="openai-gpt", model="gpt-3.5-turbo", - model_id="model-123", ) prometheus_logger.litellm_request_total_latency_metric.labels().observe.assert_called_once_with( 2.0 @@ -746,7 +737,6 @@ async def test_async_post_call_failure_hook(prometheus_logger): exception_status="429", exception_class="Openai.RateLimitError", route=user_api_key_dict.request_route, - model_id=None, ) prometheus_logger.litellm_proxy_failed_requests_metric.labels().inc.assert_called_once() @@ -762,7 +752,6 @@ async def test_async_post_call_failure_hook(prometheus_logger): status_code="429", user_email=None, route=user_api_key_dict.request_route, - model_id=None, ) prometheus_logger.litellm_proxy_total_requests_metric.labels().inc.assert_called_once() @@ -809,7 +798,6 @@ async def test_async_post_call_success_hook(prometheus_logger): status_code="200", user_email=None, route=user_api_key_dict.request_route, - model_id=None, ) prometheus_logger.litellm_proxy_total_requests_metric.labels().inc.assert_called_once() diff --git a/tests/enterprise/litellm_enterprise/integrations/test_prometheus.py b/tests/enterprise/litellm_enterprise/integrations/test_prometheus.py index 4a08c208fda..53757390a44 100644 --- a/tests/enterprise/litellm_enterprise/integrations/test_prometheus.py +++ b/tests/enterprise/litellm_enterprise/integrations/test_prometheus.py @@ -937,124 +937,6 @@ def test_callback_failure_metric_different_callbacks(prometheus_logger): ) -@pytest.mark.asyncio -async def test_langfuse_callback_failure_metric(prometheus_logger): - """ - Test that Langfuse callback failures are properly tracked in Prometheus metrics. - - This test verifies that when Langfuse logging fails, the - litellm_callback_logging_failures_metric is incremented with callback_name="langfuse". - """ - from unittest.mock import MagicMock, patch - - from litellm.integrations.langfuse.langfuse_prompt_management import ( - LangfusePromptManagement, - ) - - # Get initial value - initial_value = 0 - try: - initial_value = prometheus_logger.litellm_callback_logging_failures_metric.labels( - callback_name="langfuse" - )._value.get() - except Exception: - initial_value = 0 - - # Create Langfuse logger with mocked initialization - with patch("litellm.integrations.langfuse.langfuse_prompt_management.langfuse_client_init"): - langfuse_logger = LangfusePromptManagement() - - # Mock the log_event_on_langfuse to raise an exception - with patch( - "litellm.integrations.langfuse.langfuse_prompt_management.LangFuseHandler.get_langfuse_logger_for_request" - ) as mock_get_logger: - mock_logger = MagicMock() - mock_logger.log_event_on_langfuse.side_effect = Exception("Langfuse API error") - mock_get_logger.return_value = mock_logger - - # Mock handle_callback_failure to track calls - with patch.object(prometheus_logger, "increment_callback_logging_failure") as mock_increment: - # Inject prometheus logger into the langfuse logger - langfuse_logger.handle_callback_failure = lambda callback_name: mock_increment( - callback_name=callback_name - ) - - # Call async_log_success_event - should catch exception and increment metric - await langfuse_logger.async_log_success_event( - kwargs={}, - response_obj={}, - start_time=None, - end_time=None, - ) - - # Verify that increment was called with correct callback name - mock_increment.assert_called_once_with(callback_name="langfuse") - - print("✓ Langfuse callback failure metric test passed") - - -@pytest.mark.asyncio -async def test_langfuse_otel_callback_failure_metric(prometheus_logger): - """ - Test that Langfuse OTEL callback failures are properly tracked in Prometheus metrics. - - This test verifies that when Langfuse OTEL logging fails, the - litellm_callback_logging_failures_metric is incremented with callback_name="langfuse_otel". - """ - from unittest.mock import MagicMock, patch - - from litellm.integrations.langfuse.langfuse_otel import LangfuseOtelLogger - - # Get initial value - initial_value = 0 - try: - initial_value = prometheus_logger.litellm_callback_logging_failures_metric.labels( - callback_name="langfuse_otel" - )._value.get() - except Exception: - initial_value = 0 - - # Create Langfuse OTEL logger with mocked initialization - with patch("litellm.integrations.opentelemetry.OpenTelemetry.__init__", return_value=None): - langfuse_otel_logger = LangfuseOtelLogger(callback_name="langfuse_otel") - langfuse_otel_logger.callback_name = "langfuse_otel" - - # Mock handle_callback_failure to track calls - with patch.object(prometheus_logger, "increment_callback_logging_failure") as mock_increment: - # Inject prometheus logger into the langfuse otel logger - langfuse_otel_logger.handle_callback_failure = lambda callback_name: mock_increment( - callback_name=callback_name - ) - - # Test that the OpenTelemetry base class set_attributes exception handler works - # This is where langfuse_otel failures are caught and tracked - with patch.object(langfuse_otel_logger, "set_attributes") as mock_set_attributes: - # Simulate the exception handling in set_attributes - def set_attributes_with_error(*args, **kwargs): - # This simulates what happens in the real set_attributes method - try: - raise Exception("Attribute error") - except Exception as e: - langfuse_otel_logger.handle_callback_failure(callback_name=langfuse_otel_logger.callback_name) - - mock_set_attributes.side_effect = set_attributes_with_error - - # Call set_attributes - try: - langfuse_otel_logger.set_attributes( - span=MagicMock(), - kwargs={}, - response_obj={} - ) - except Exception: - pass - - # Verify that increment was called with correct callback name - mock_increment.assert_called_with(callback_name="langfuse_otel") - - print("✓ Langfuse OTEL callback failure metric test passed") - - # ============================================================================== # END CALLBACK FAILURE METRICS TESTS # ============================================================================== diff --git a/tests/enterprise/litellm_enterprise/proxy/auth/test_route_checks.py b/tests/enterprise/litellm_enterprise/proxy/auth/test_route_checks.py index 706e3b71870..ce77ff69e05 100644 --- a/tests/enterprise/litellm_enterprise/proxy/auth/test_route_checks.py +++ b/tests/enterprise/litellm_enterprise/proxy/auth/test_route_checks.py @@ -180,68 +180,3 @@ def test_should_call_route_llm_disabled_management_enabled( # Should not raise exception since management routes are enabled EnterpriseRouteChecks.should_call_route("/config/update") - - -class TestEnterpriseRouteChecksErrorMessages: - """Test that error messages correctly identify which feature requires Enterprise license""" - - @patch("litellm.secret_managers.main.get_secret_bool") - @patch("litellm.proxy.proxy_server.premium_user", False) - def test_disable_llm_api_endpoints_error_message(self, mock_get_secret_bool): - """ - Test that when DISABLE_LLM_API_ENDPOINTS is set without Enterprise license, - the error message correctly mentions 'LLM API ENDPOINTS' - """ - with patch.dict(os.environ, {"DISABLE_LLM_API_ENDPOINTS": "true"}): - with pytest.raises(HTTPException) as exc_info: - EnterpriseRouteChecks.is_llm_api_route_disabled() - - assert exc_info.value.status_code == 500 - assert "DISABLING LLM API ENDPOINTS is an Enterprise feature" in str( - exc_info.value.detail - ) - - @patch("litellm.secret_managers.main.get_secret_bool") - @patch("litellm.proxy.proxy_server.premium_user", False) - def test_disable_admin_endpoints_error_message(self, mock_get_secret_bool): - """ - Test that when DISABLE_ADMIN_ENDPOINTS is set without Enterprise license, - the error message correctly mentions 'ADMIN ENDPOINTS' (not 'LLM API ENDPOINTS') - - This is a regression test for a bug where the error message incorrectly said - 'DISABLING LLM API ENDPOINTS' when the actual issue was DISABLE_ADMIN_ENDPOINTS. - """ - with patch.dict(os.environ, {"DISABLE_ADMIN_ENDPOINTS": "true"}): - with pytest.raises(HTTPException) as exc_info: - EnterpriseRouteChecks.is_management_routes_disabled() - - assert exc_info.value.status_code == 500 - assert "DISABLING ADMIN ENDPOINTS is an Enterprise feature" in str( - exc_info.value.detail - ) - # Ensure it does NOT mention LLM API ENDPOINTS (the old buggy message) - assert "LLM API ENDPOINTS" not in str(exc_info.value.detail) - - @patch("litellm.secret_managers.main.get_secret_bool") - @patch("litellm.proxy.proxy_server.premium_user", True) - def test_disable_llm_api_endpoints_with_premium_user(self, mock_get_secret_bool): - """ - Test that premium users can use DISABLE_LLM_API_ENDPOINTS without error - """ - mock_get_secret_bool.return_value = True - with patch.dict(os.environ, {"DISABLE_LLM_API_ENDPOINTS": "true"}): - # Should not raise exception for premium users - result = EnterpriseRouteChecks.is_llm_api_route_disabled() - assert result is True - - @patch("litellm.secret_managers.main.get_secret_bool") - @patch("litellm.proxy.proxy_server.premium_user", True) - def test_disable_admin_endpoints_with_premium_user(self, mock_get_secret_bool): - """ - Test that premium users can use DISABLE_ADMIN_ENDPOINTS without error - """ - mock_get_secret_bool.return_value = True - with patch.dict(os.environ, {"DISABLE_ADMIN_ENDPOINTS": "true"}): - # Should not raise exception for premium users - result = EnterpriseRouteChecks.is_management_routes_disabled() - assert result is True diff --git a/tests/enterprise/litellm_enterprise/proxy/hooks/test_managed_files.py b/tests/enterprise/litellm_enterprise/proxy/hooks/test_managed_files.py index 4fa16066e4b..9a6e153a22b 100644 --- a/tests/enterprise/litellm_enterprise/proxy/hooks/test_managed_files.py +++ b/tests/enterprise/litellm_enterprise/proxy/hooks/test_managed_files.py @@ -827,262 +827,3 @@ async def test_afile_retrieve_raises_error_for_non_managed_file(): ) assert "not found" in str(exc_info.value) - - -@pytest.mark.asyncio -async def test_list_batches_from_managed_objects_table(): - from litellm.proxy._types import UserAPIKeyAuth - from openai.types.batch import BatchRequestCounts - - prisma_client = AsyncMock() - - batch_record_1 = MagicMock() - batch_record_1.unified_object_id = "unified-batch-id-1" - batch_record_1.file_object = json.dumps({ - "id": "batch_abc123", - "object": "batch", - "endpoint": "/v1/chat/completions", - "completion_window": "24h", - "status": "completed", - "created_at": 1234567890, - "input_file_id": "file-input-1", - "request_counts": {"total": 1, "completed": 1, "failed": 0}, - }) - - batch_record_2 = MagicMock() - batch_record_2.unified_object_id = "unified-batch-id-2" - batch_record_2.file_object = json.dumps({ - "id": "batch_xyz789", - "object": "batch", - "endpoint": "/v1/chat/completions", - "completion_window": "24h", - "status": "in_progress", - "created_at": 1234567891, - "input_file_id": "file-input-2", - "request_counts": {"total": 5, "completed": 2, "failed": 0}, - }) - - prisma_client.db.litellm_managedobjecttable.find_many.return_value = [ - batch_record_1, - batch_record_2, - ] - - proxy_managed_files = _PROXY_LiteLLMManagedFiles( - DualCache(), prisma_client=prisma_client - ) - - result = await proxy_managed_files.list_user_batches( - user_api_key_dict=UserAPIKeyAuth(user_id="test-user"), - limit=10, - ) - - assert result["object"] == "list" - assert len(result["data"]) == 2 - assert result["data"][0].id == "unified-batch-id-1" - assert result["data"][1].id == "unified-batch-id-2" - assert result["first_id"] == "unified-batch-id-1" - assert result["last_id"] == "unified-batch-id-2" - - # Should filter by user_id (created_by) - prisma_client.db.litellm_managedobjecttable.find_many.assert_called_once_with( - where={"file_purpose": "batch", "created_by": "test-user"}, - take=10, - order={"created_at": "desc"}, - ) - - -@pytest.mark.asyncio -async def test_list_batches_from_managed_objects_table_empty_list(): - from litellm.proxy._types import UserAPIKeyAuth - - prisma_client = AsyncMock() - prisma_client.db.litellm_managedobjecttable.find_many.return_value = [] - - proxy_managed_files = _PROXY_LiteLLMManagedFiles( - DualCache(), prisma_client=prisma_client - ) - - result = await proxy_managed_files.list_user_batches( - user_api_key_dict=UserAPIKeyAuth(user_id="test-user"), - ) - - assert result["object"] == "list" - assert len(result["data"]) == 0 - assert result["first_id"] is None - assert result["last_id"] is None - assert result["has_more"] is False - - # Verify where clause includes created_by filter - # Default take is 20 when no limit is provided - prisma_client.db.litellm_managedobjecttable.find_many.assert_called_once_with( - where={"file_purpose": "batch", "created_by": "test-user"}, - take=20, - order={"created_at": "desc"}, - ) - - -def _create_unified_batch_id(model_id: str, batch_id: str) -> str: - import base64 - unified_str = f"litellm_proxy;model_id:{model_id};llm_batch_id:{batch_id}" - return base64.urlsafe_b64encode(unified_str.encode()).decode().rstrip("=") - - -@pytest.mark.asyncio -async def test_list_batches_from_managed_objects_table_provider_filter_raises_exception(): - from litellm.proxy._types import UserAPIKeyAuth - - prisma_client = AsyncMock() - - proxy_managed_files = _PROXY_LiteLLMManagedFiles( - DualCache(), prisma_client=prisma_client - ) - - # Filtering by provider should raise Exception - with pytest.raises(Exception) as exc_info: - await proxy_managed_files.list_user_batches( - user_api_key_dict=UserAPIKeyAuth(user_id="test-user"), - limit=10, - provider="openai", - ) - - assert str(exc_info.value) == ( - "Filtering by 'provider' is not supported when using managed batches." - ) - - # Verify find_many was NOT called since exception is raised before database query - prisma_client.db.litellm_managedobjecttable.find_many.assert_not_called() - - -@pytest.mark.asyncio -async def test_list_batches_from_managed_objects_table_target_model_name_filter_raises_exception(): - from litellm.proxy._types import UserAPIKeyAuth - - prisma_client = AsyncMock() - - proxy_managed_files = _PROXY_LiteLLMManagedFiles( - DualCache(), prisma_client=prisma_client - ) - - # Filtering by provider should raise Exception - with pytest.raises(Exception) as exc_info: - await proxy_managed_files.list_user_batches( - user_api_key_dict=UserAPIKeyAuth(user_id="test-user"), - limit=10, - target_model_names="gpt-4o,gpt-3.5", - ) - - assert str(exc_info.value) == ( - "Filtering by 'target_model_names' is not supported when using managed batches." - ) - - # Verify find_many was NOT called since exception is raised before database query - prisma_client.db.litellm_managedobjecttable.find_many.assert_not_called() - -@pytest.mark.asyncio -async def test_list_batches_from_managed_objects_table_filters_by_created_by(): - from litellm.proxy._types import UserAPIKeyAuth - - prisma_client = AsyncMock() - - # Create batch for user1 - batch_user1 = MagicMock() - batch_user1.unified_object_id = "unified-batch-user1" - batch_user1.file_object = json.dumps({ - "id": "batch_user1_abc", - "object": "batch", - "endpoint": "/v1/chat/completions", - "completion_window": "24h", - "status": "completed", - "created_at": 1234567890, - "input_file_id": "file-input-user1", - "request_counts": {"total": 1, "completed": 1, "failed": 0}, - }) - - # Create batch for user2 - batch_user2 = MagicMock() - batch_user2.unified_object_id = "unified-batch-user2" - batch_user2.file_object = json.dumps({ - "id": "batch_user2_xyz", - "object": "batch", - "endpoint": "/v1/chat/completions", - "completion_window": "24h", - "status": "completed", - "created_at": 1234567891, - "input_file_id": "file-input-user2", - "request_counts": {"total": 2, "completed": 2, "failed": 0}, - }) - - proxy_managed_files = _PROXY_LiteLLMManagedFiles( - DualCache(), prisma_client=prisma_client - ) - - # Query with user1's API key - should only return user1's batch - prisma_client.db.litellm_managedobjecttable.find_many.return_value = [batch_user1] - result_user1 = await proxy_managed_files.list_user_batches( - user_api_key_dict=UserAPIKeyAuth(user_id="user1"), - limit=10, - ) - - assert len(result_user1["data"]) == 1 - assert result_user1["data"][0].id == "unified-batch-user1" - prisma_client.db.litellm_managedobjecttable.find_many.assert_called_with( - where={"file_purpose": "batch", "created_by": "user1"}, - take=10, - order={"created_at": "desc"}, - ) - - # Query with user2's API key - should only return user2's batch - prisma_client.db.litellm_managedobjecttable.find_many.return_value = [batch_user2] - result_user2 = await proxy_managed_files.list_user_batches( - user_api_key_dict=UserAPIKeyAuth(user_id="user2"), - limit=10, - ) - - assert len(result_user2["data"]) == 1 - assert result_user2["data"][0].id == "unified-batch-user2" - prisma_client.db.litellm_managedobjecttable.find_many.assert_called_with( - where={"file_purpose": "batch", "created_by": "user2"}, - take=10, - order={"created_at": "desc"}, - ) - - -@pytest.mark.asyncio -async def test_return_unified_file_id_includes_expires_at(): - from litellm.types.llms.openai import OpenAIFileObject - - # Create a mock file object with expires_at set - file_object = OpenAIFileObject( - id="file-abc123", - object="file", - bytes=1234, - created_at=1234567890, - filename="test.jsonl", - purpose="batch", - status="uploaded", - expires_at=1234657890, - ) - file_object._hidden_params = {"model_id": "test-model-id"} - - create_file_request = { - "file": ("test.jsonl", b"test content", "application/jsonl"), - "purpose": "batch", - } - - internal_usage_cache = MagicMock() - - result = await _PROXY_LiteLLMManagedFiles.return_unified_file_id( - file_objects=[file_object], - create_file_request=create_file_request, - internal_usage_cache=internal_usage_cache, - litellm_parent_otel_span=None, - target_model_names_list=["gpt-4o"], - ) - - # Verify expires_at is passed through - assert result.expires_at == 1234657890 - assert result.purpose == "batch" - assert result.filename == "test.jsonl" - assert result.bytes == 1234 - assert result.created_at == 1234567890 - assert _is_base64_encoded_unified_file_id(result.id) \ No newline at end of file diff --git a/tests/guardrails_tests/test_lakera_v2.py b/tests/guardrails_tests/test_lakera_v2.py index 2a8731d5ecd..9e0244a4819 100644 --- a/tests/guardrails_tests/test_lakera_v2.py +++ b/tests/guardrails_tests/test_lakera_v2.py @@ -22,58 +22,38 @@ async def test_lakera_pre_call_hook_for_pii_masking(): # Setup the guardrail with specific entities config litellm._turn_on_debug() lakera_guardrail = LakeraAIGuardrail( - api_key="test_key", + api_key=os.environ.get("LAKERA_API_KEY"), ) - # Mock response with PII detections in payload (with start/end positions for masking) - mock_response = { - 'payload': [ - {'detector_type': 'pii/credit_card', 'start': 18, 'end': 37, 'message_id': 1}, # "4111-1111-1111-1111" - {'detector_type': 'pii/email', 'start': 54, 'end': 70, 'message_id': 1}, # "test@example.com" + # Create a sample request with PII data + data = { + "messages": [ + {"role": "system", "content": "You are a helpful assistant."}, + {"role": "user", "content": "My credit card is 4111-1111-1111-1111 and my email is test@example.com. My phone number is 555-123-4567"} ], - 'flagged': True, - 'breakdown': [ - {'detector_type': 'pii/credit_card', 'detected': True, 'message_id': 1}, - {'detector_type': 'pii/email', 'detected': True, 'message_id': 1}, - ] + "model": "gpt-3.5-turbo", + "metadata": {} } - with patch.object(lakera_guardrail, 'call_v2_guard', new_callable=AsyncMock) as mock_call: - mock_call.return_value = (mock_response, {}) - - # Create a sample request with PII data - data = { - "messages": [ - {"role": "system", "content": "You are a helpful assistant."}, - {"role": "user", "content": "My credit card is 4111-1111-1111-1111 and my email is test@example.com. My phone number is 555-123-4567"} - ], - "model": "gpt-3.5-turbo", - "metadata": {} - } - - # Mock objects needed for the pre-call hook - user_api_key_dict = UserAPIKeyAuth(api_key="test_key") - cache = DualCache() - - # Call the pre-call hook with the specified call type - modified_data = await lakera_guardrail.async_pre_call_hook( - user_api_key_dict=user_api_key_dict, - cache=cache, - data=data, - call_type="completion" - ) - print(modified_data) - - # Verify the messages have been modified to mask PII - assert modified_data["messages"][0]["content"] == "You are a helpful assistant." # System prompt should be unchanged - - user_message = modified_data["messages"][1]["content"] - # Verify both credit card and email are masked - assert "4111-1111-1111-1111" not in user_message - assert "test@example.com" not in user_message - # Verify masking placeholders are present - assert "[MASKED CREDIT_CARD]" in user_message - assert "[MASKED EMAIL]" in user_message + # Mock objects needed for the pre-call hook + user_api_key_dict = UserAPIKeyAuth(api_key="test_key") + cache = DualCache() + + # Call the pre-call hook with the specified call type + modified_data = await lakera_guardrail.async_pre_call_hook( + user_api_key_dict=user_api_key_dict, + cache=cache, + data=data, + call_type="completion" + ) + print(modified_data) + + # Verify the messages have been modified to mask PII + assert modified_data["messages"][0]["content"] == "You are a helpful assistant." # System prompt should be unchanged + + user_message = modified_data["messages"][1]["content"] + assert "4111-1111-1111-1111" not in user_message + assert "test@example.com" not in user_message @pytest.mark.asyncio diff --git a/tests/litellm-proxy-extras/test_litellm_proxy_extras_utils.py b/tests/litellm-proxy-extras/test_litellm_proxy_extras_utils.py index 597c0845d43..7c151c80ae3 100644 --- a/tests/litellm-proxy-extras/test_litellm_proxy_extras_utils.py +++ b/tests/litellm-proxy-extras/test_litellm_proxy_extras_utils.py @@ -97,11 +97,6 @@ def test_is_idempotent_error_constraint_already_exists(self): error_message = "constraint 'fk_user_id' already exists" assert ProxyExtrasDBManager._is_idempotent_error(error_message) is True - def test_is_idempotent_error_does_not_exist(self): - """Test detection of 'does not exist' error""" - error_message = "ERROR: index 'idx' does not exist" - assert ProxyExtrasDBManager._is_idempotent_error(error_message) is True - def test_is_idempotent_error_case_insensitive(self): """Test that idempotent error detection is case insensitive""" error_message = "COLUMN 'ID' ALREADY EXISTS" diff --git a/tests/litellm/llms/oci/chat/test_oci_chat_transformation.py b/tests/litellm/llms/oci/chat/test_oci_chat_transformation.py index 0a6c59d1b44..f706a025a09 100644 --- a/tests/litellm/llms/oci/chat/test_oci_chat_transformation.py +++ b/tests/litellm/llms/oci/chat/test_oci_chat_transformation.py @@ -203,7 +203,6 @@ class TestOCIImageUrlTransformation: """Tests for OCI image_url format handling in multimodal messages. Fixes: https://github.com/BerriAI/litellm/issues/18270 - Fixes: https://github.com/BerriAI/litellm/issues/19589 """ def test_image_url_as_string(self): @@ -225,8 +224,7 @@ def test_image_url_as_string(self): assert len(result) == 1 assert result[0].role == "USER" assert len(result[0].content) == 2 - # imageUrl is now an OCIImageUrl object with a 'url' property - assert result[0].content[1].imageUrl.url == "https://example.com/image.png" + assert result[0].content[1].imageUrl == "https://example.com/image.png" def test_image_url_as_openai_object(self): """Test that image_url as OpenAI-style object {"url": "..."} works.""" @@ -247,38 +245,7 @@ def test_image_url_as_openai_object(self): assert len(result) == 1 assert result[0].role == "USER" assert len(result[0].content) == 2 - # imageUrl is now an OCIImageUrl object with a 'url' property - assert result[0].content[1].imageUrl.url == "https://example.com/image.png" - - def test_image_url_serializes_as_object(self): - """Test that imageUrl serializes as {"url": "..."} for OCI API. - - Fixes: https://github.com/BerriAI/litellm/issues/19589 - OCI expects imageUrl to be an object with a 'url' property, not a plain string. - """ - from litellm.llms.oci.chat.transformation import adapt_messages_to_generic_oci_standard - - messages = [ - { - "role": "user", - "content": [ - {"type": "text", "text": "Describe this image."}, - {"type": "image_url", "image_url": {"url": "data:image/png;base64,ABC123"}}, - ], - } - ] - - result = adapt_messages_to_generic_oci_standard(messages) - image_part = result[0].content[1] - - # Serialize as OCI would receive it (with exclude_none=True) - serialized = image_part.model_dump(exclude_none=True) - - # Verify the structure matches OCI's expected format - assert serialized == { - "type": "IMAGE", - "imageUrl": {"url": "data:image/png;base64,ABC123"} - } + assert result[0].content[1].imageUrl == "https://example.com/image.png" def test_image_url_invalid_type_raises_error(self): """Test that invalid image_url type raises an error.""" diff --git a/tests/litellm/proxy/_experimental/mcp_server/test_discoverable_endpoints.py b/tests/litellm/proxy/_experimental/mcp_server/test_discoverable_endpoints.py deleted file mode 100644 index ac2c945baa6..00000000000 --- a/tests/litellm/proxy/_experimental/mcp_server/test_discoverable_endpoints.py +++ /dev/null @@ -1,1108 +0,0 @@ -"""Tests for MCP OAuth discoverable endpoints""" -import pytest -from unittest.mock import AsyncMock, MagicMock, patch - - -@pytest.mark.asyncio -async def test_authorize_endpoint_includes_response_type(): - """Test that authorize endpoint includes response_type=code parameter (fixes #15684)""" - try: - from litellm.proxy._experimental.mcp_server.discoverable_endpoints import ( - authorize, - ) - from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( - global_mcp_server_manager, - ) - from litellm.types.mcp import MCPAuth - from litellm.types.mcp_server.mcp_server_manager import MCPServer - from litellm.proxy._types import MCPTransport - from fastapi import Request - except ImportError: - pytest.skip("MCP discoverable endpoints not available") - - # Clear registry - global_mcp_server_manager.registry.clear() - - # Create mock OAuth2 server - oauth2_server = MCPServer( - server_id="test_oauth_server", - name="test_oauth", - server_name="test_oauth", - alias="test_oauth", - transport=MCPTransport.http, - auth_type=MCPAuth.oauth2, - client_id="test_client_id", - client_secret="test_client_secret", - authorization_url="https://provider.com/oauth/authorize", - token_url="https://provider.com/oauth/token", - scopes=["read", "write"], - ) - global_mcp_server_manager.registry[oauth2_server.server_id] = oauth2_server - - # Mock request - mock_request = MagicMock(spec=Request) - mock_request.base_url = "https://litellm.example.com/" - mock_request.headers = {} - - # Mock the encryption functions to avoid needing a signing key - with patch( - "litellm.proxy._experimental.mcp_server.discoverable_endpoints.encrypt_value_helper" - ) as mock_encrypt: - mock_encrypt.return_value = "mocked_encrypted_state" - - # Call authorize endpoint - response = await authorize( - request=mock_request, - client_id="test_client_id", - mcp_server_name="test_oauth", - redirect_uri="https://client.example.com/callback", - state="test_state", - ) - - # Verify response is a redirect - assert response.status_code == 307 # FastAPI RedirectResponse default - - # Verify response_type is in the redirect URL - assert "response_type=code" in response.headers["location"] - assert "https://provider.com/oauth/authorize" in response.headers["location"] - assert "client_id=test_client_id" in response.headers["location"] - assert "scope=read+write" in response.headers["location"] - - -@pytest.mark.asyncio -async def test_authorize_endpoint_forwards_pkce_parameters(): - """Test that authorize endpoint forwards PKCE parameters (code_challenge and code_challenge_method)""" - try: - from litellm.proxy._experimental.mcp_server.discoverable_endpoints import ( - authorize, - ) - from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( - global_mcp_server_manager, - ) - from litellm.types.mcp import MCPAuth - from litellm.types.mcp_server.mcp_server_manager import MCPServer - from litellm.proxy._types import MCPTransport - from fastapi import Request - except ImportError: - pytest.skip("MCP discoverable endpoints not available") - - # Clear registry - global_mcp_server_manager.registry.clear() - - # Create mock OAuth2 server (simulating Google OAuth) - oauth2_server = MCPServer( - server_id="google_mcp", - name="google_mcp", - server_name="google_mcp", - alias="google_mcp", - transport=MCPTransport.http, - auth_type=MCPAuth.oauth2, - client_id="669428968603-test.apps.googleusercontent.com", - client_secret="GOCSPX-test_secret", - authorization_url="https://accounts.google.com/o/oauth2/v2/auth", - token_url="https://oauth2.googleapis.com/token", - scopes=["https://www.googleapis.com/auth/drive", "openid", "email"], - ) - global_mcp_server_manager.registry[oauth2_server.server_id] = oauth2_server - - # Mock request - mock_request = MagicMock(spec=Request) - mock_request.base_url = "https://litellm-proxy.example.com/" - mock_request.headers = {} - - # Mock the encryption function - with patch( - "litellm.proxy._experimental.mcp_server.discoverable_endpoints.encrypt_value_helper" - ) as mock_encrypt: - mock_encrypt.return_value = "mocked_encrypted_state_with_pkce" - - # Call authorize endpoint with PKCE parameters - response = await authorize( - request=mock_request, - client_id="669428968603-test.apps.googleusercontent.com", - mcp_server_name="google_mcp", - redirect_uri="http://localhost:60108/callback", - state="test_client_state", - code_challenge="x6YH_qgwbvOzbsHDuL1sW9gYkR9-gObUiIB5RkPwxDk", - code_challenge_method="S256", - ) - - # Verify response is a redirect - assert response.status_code == 307 - - # Verify PKCE parameters are included in the redirect URL - location = response.headers["location"] - assert "https://accounts.google.com/o/oauth2/v2/auth" in location - assert "code_challenge=x6YH_qgwbvOzbsHDuL1sW9gYkR9-gObUiIB5RkPwxDk" in location - assert "code_challenge_method=S256" in location - assert "client_id=669428968603-test.apps.googleusercontent.com" in location - assert "response_type=code" in location - - -@pytest.mark.asyncio -async def test_token_endpoint_forwards_code_verifier(): - """Test that token endpoint forwards code_verifier for PKCE flow""" - try: - from litellm.proxy._experimental.mcp_server.discoverable_endpoints import ( - token_endpoint, - ) - from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( - global_mcp_server_manager, - ) - from litellm.types.mcp import MCPAuth - from litellm.types.mcp_server.mcp_server_manager import MCPServer - from litellm.proxy._types import MCPTransport - from fastapi import Request - import httpx - except ImportError: - pytest.skip("MCP discoverable endpoints not available") - - # Clear registry - global_mcp_server_manager.registry.clear() - - # Create mock OAuth2 server - oauth2_server = MCPServer( - server_id="google_mcp", - name="google_mcp", - server_name="google_mcp", - alias="google_mcp", - transport=MCPTransport.http, - auth_type=MCPAuth.oauth2, - client_id="669428968603-test.apps.googleusercontent.com", - client_secret="GOCSPX-test_secret", - authorization_url="https://accounts.google.com/o/oauth2/v2/auth", - token_url="https://oauth2.googleapis.com/token", - scopes=["https://www.googleapis.com/auth/drive", "openid", "email"], - ) - global_mcp_server_manager.registry[oauth2_server.server_id] = oauth2_server - - # Mock request - mock_request = MagicMock(spec=Request) - mock_request.base_url = "https://litellm-proxy.example.com/" - mock_request.headers = {} - - # Mock httpx client response - mock_response = MagicMock() - mock_response.json.return_value = { - "access_token": "ya29.test_access_token", - "token_type": "Bearer", - "expires_in": 3599, - "scope": "openid email https://www.googleapis.com/auth/drive", - } - mock_response.raise_for_status = MagicMock() - - # Mock the async httpx client with AsyncMock for async methods - from unittest.mock import AsyncMock - - with patch( - "litellm.proxy._experimental.mcp_server.discoverable_endpoints.get_async_httpx_client" - ) as mock_get_client: - mock_async_client = MagicMock() - # Use AsyncMock for the async post method - mock_async_client.post = AsyncMock(return_value=mock_response) - mock_get_client.return_value = mock_async_client - - # Call token endpoint with code_verifier - response = await token_endpoint( - request=mock_request, - grant_type="authorization_code", - code="4/test_authorization_code", - redirect_uri="http://localhost:60108/callback", - client_id="669428968603-test.apps.googleusercontent.com", - mcp_server_name="google_mcp", - client_secret="GOCSPX-test_secret", - code_verifier="test_code_verifier_from_client", - ) - - # Verify that the token endpoint was called with code_verifier - mock_async_client.post.assert_called_once() - call_args = mock_async_client.post.call_args - - # Check the data parameter includes code_verifier - assert call_args[1]["data"]["code_verifier"] == "test_code_verifier_from_client" - assert call_args[1]["data"]["code"] == "4/test_authorization_code" - assert ( - call_args[1]["data"]["client_id"] - == "669428968603-test.apps.googleusercontent.com" - ) - assert call_args[1]["data"]["client_secret"] == "GOCSPX-test_secret" - assert call_args[1]["data"]["grant_type"] == "authorization_code" - - # Verify response - response_data = response.body - import json - - token_data = json.loads(response_data) - assert token_data["access_token"] == "ya29.test_access_token" - assert token_data["token_type"] == "Bearer" - - -@pytest.mark.asyncio -async def test_register_client_without_mcp_server_name_returns_dummy(): - try: - from litellm.proxy._experimental.mcp_server.discoverable_endpoints import ( - register_client, - ) - from fastapi import Request - except ImportError: - pytest.skip("MCP discoverable endpoints not available") - - mock_request = MagicMock(spec=Request) - mock_request.base_url = "https://proxy.litellm.example/" - mock_request.headers = {} - with patch( - "litellm.proxy._experimental.mcp_server.discoverable_endpoints._read_request_body", - new=AsyncMock(return_value={}), - ): - result = await register_client(request=mock_request) - - assert result == { - "client_id": "dummy_client", - "client_secret": "dummy", - "redirect_uris": ["https://proxy.litellm.example/callback"], - } - - -@pytest.mark.asyncio -async def test_register_client_returns_existing_server_credentials(): - try: - from litellm.proxy._experimental.mcp_server.discoverable_endpoints import ( - register_client, - ) - from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( - global_mcp_server_manager, - ) - from litellm.types.mcp import MCPAuth - from litellm.types.mcp_server.mcp_server_manager import MCPServer - from litellm.proxy._types import MCPTransport - from fastapi import Request - except ImportError: - pytest.skip("MCP discoverable endpoints not available") - - global_mcp_server_manager.registry.clear() - oauth2_server = MCPServer( - server_id="stored_server", - name="stored_server", - server_name="stored_server", - alias="stored_server", - transport=MCPTransport.http, - auth_type=MCPAuth.oauth2, - client_id="existing-client", - client_secret="existing-secret", - authorization_url="https://provider.example/oauth/authorize", - token_url="https://provider.example/oauth/token", - ) - global_mcp_server_manager.registry[oauth2_server.server_id] = oauth2_server - - mock_request = MagicMock(spec=Request) - mock_request.base_url = "https://proxy.litellm.example/" - mock_request.headers = {} - - try: - with patch( - "litellm.proxy._experimental.mcp_server.discoverable_endpoints._read_request_body", - new=AsyncMock(return_value={}), - ): - result = await register_client( - request=mock_request, mcp_server_name=oauth2_server.server_name - ) - finally: - global_mcp_server_manager.registry.clear() - - assert result == { - "client_id": "stored_server", - "client_secret": "dummy", - "redirect_uris": ["https://proxy.litellm.example/callback"], - } - - -@pytest.mark.asyncio -async def test_register_client_remote_registration_success(): - try: - from litellm.proxy._experimental.mcp_server.discoverable_endpoints import ( - register_client, - ) - from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( - global_mcp_server_manager, - ) - from litellm.types.mcp import MCPAuth - from litellm.types.mcp_server.mcp_server_manager import MCPServer - from litellm.proxy._types import MCPTransport - from fastapi import Request - except ImportError: - pytest.skip("MCP discoverable endpoints not available") - - global_mcp_server_manager.registry.clear() - oauth2_server = MCPServer( - server_id="remote_server", - name="remote_server", - server_name="remote_server", - alias="remote_server", - transport=MCPTransport.http, - auth_type=MCPAuth.oauth2, - client_id=None, - client_secret=None, - authorization_url="https://provider.example/oauth/authorize", - token_url="https://provider.example/oauth/token", - registration_url="https://provider.example/oauth/register", - ) - global_mcp_server_manager.registry[oauth2_server.server_id] = oauth2_server - - mock_request = MagicMock(spec=Request) - mock_request.base_url = "https://proxy.litellm.example/" - mock_request.headers = {} - - request_payload = { - "client_name": "Litellm Proxy", - "grant_types": ["authorization_code", "refresh_token"], - "response_types": ["code"], - "token_endpoint_auth_method": "client_secret_post", - } - - mock_response = MagicMock() - mock_response.json.return_value = { - "client_id": "generated-client", - "client_secret": "generated-secret", - } - mock_response.raise_for_status = MagicMock() - mock_async_client = MagicMock() - mock_async_client.post = AsyncMock(return_value=mock_response) - - try: - with patch( - "litellm.proxy._experimental.mcp_server.discoverable_endpoints._read_request_body", - new=AsyncMock(return_value=request_payload), - ), patch( - "litellm.proxy._experimental.mcp_server.discoverable_endpoints.get_async_httpx_client", - return_value=mock_async_client, - ): - response = await register_client( - request=mock_request, mcp_server_name=oauth2_server.server_name - ) - finally: - global_mcp_server_manager.registry.clear() - - import json - - assert response.status_code == 200 - payload = json.loads(response.body.decode("utf-8")) - assert payload == mock_response.json.return_value - - mock_async_client.post.assert_called_once() - call_args = mock_async_client.post.call_args - assert call_args.args[0] == oauth2_server.registration_url - assert call_args.kwargs["headers"] == { - "Content-Type": "application/json", - "Accept": "application/json", - } - assert call_args.kwargs["json"]["redirect_uris"] == [ - "https://proxy.litellm.example/callback" - ] - assert call_args.kwargs["json"]["grant_types"] == request_payload["grant_types"] - assert ( - call_args.kwargs["json"]["token_endpoint_auth_method"] - == request_payload["token_endpoint_auth_method"] - ) - - -@pytest.mark.asyncio -async def test_authorize_endpoint_respects_x_forwarded_proto(): - """Test that authorize endpoint uses X-Forwarded-Proto header to construct correct redirect_uri""" - try: - from litellm.proxy._experimental.mcp_server.discoverable_endpoints import ( - authorize, - ) - from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( - global_mcp_server_manager, - ) - from litellm.types.mcp import MCPAuth - from litellm.types.mcp_server.mcp_server_manager import MCPServer - from litellm.proxy._types import MCPTransport - from fastapi import Request - except ImportError: - pytest.skip("MCP discoverable endpoints not available") - - # Clear registry - global_mcp_server_manager.registry.clear() - - # Create mock OAuth2 server - oauth2_server = MCPServer( - server_id="test_oauth_server", - name="test_oauth", - server_name="test_oauth", - alias="test_oauth", - transport=MCPTransport.http, - auth_type=MCPAuth.oauth2, - client_id="test_client_id", - client_secret="test_client_secret", - authorization_url="https://provider.com/oauth/authorize", - token_url="https://provider.com/oauth/token", - scopes=["read", "write"], - ) - global_mcp_server_manager.registry[oauth2_server.server_id] = oauth2_server - - # Mock request with http base_url but X-Forwarded-Proto: https - mock_request = MagicMock(spec=Request) - mock_request.base_url = "http://litellm.example.com/" # HTTP - mock_request.headers = {"X-Forwarded-Proto": "https"} # Behind HTTPS proxy - - # Mock the encryption functions - with patch( - "litellm.proxy._experimental.mcp_server.discoverable_endpoints.encrypt_value_helper" - ) as mock_encrypt: - mock_encrypt.return_value = "mocked_encrypted_state" - - # Call authorize endpoint - response = await authorize( - request=mock_request, - client_id="test_client_id", - mcp_server_name="test_oauth", - redirect_uri="https://client.example.com/callback", - state="test_state", - ) - - # Verify redirect URL uses HTTPS in the redirect_uri parameter - location = response.headers["location"] - - # The redirect_uri parameter sent to the OAuth provider should use HTTPS - assert ( - "redirect_uri=https%3A%2F%2Flitellm.example.com%2Fcallback" in location - or "redirect_uri=https://litellm.example.com/callback" in location - ) - - -@pytest.mark.asyncio -async def test_token_endpoint_respects_x_forwarded_proto(): - """Test that token endpoint uses X-Forwarded-Proto header for redirect_uri""" - try: - from litellm.proxy._experimental.mcp_server.discoverable_endpoints import ( - token_endpoint, - ) - from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( - global_mcp_server_manager, - ) - from litellm.types.mcp import MCPAuth - from litellm.types.mcp_server.mcp_server_manager import MCPServer - from litellm.proxy._types import MCPTransport - from fastapi import Request - except ImportError: - pytest.skip("MCP discoverable endpoints not available") - - # Clear registry - global_mcp_server_manager.registry.clear() - - # Create mock OAuth2 server - oauth2_server = MCPServer( - server_id="google_mcp", - name="google_mcp", - server_name="google_mcp", - alias="google_mcp", - transport=MCPTransport.http, - auth_type=MCPAuth.oauth2, - client_id="test_client_id", - client_secret="test_secret", - authorization_url="https://accounts.google.com/o/oauth2/v2/auth", - token_url="https://oauth2.googleapis.com/token", - scopes=["openid", "email"], - ) - global_mcp_server_manager.registry[oauth2_server.server_id] = oauth2_server - - # Mock request with http base_url but X-Forwarded-Proto: https - mock_request = MagicMock(spec=Request) - mock_request.base_url = "http://litellm-proxy.example.com/" # HTTP - mock_request.headers = {"X-Forwarded-Proto": "https"} # Behind HTTPS proxy - - # Mock httpx client response - mock_response = MagicMock() - mock_response.json.return_value = { - "access_token": "test_token", - "token_type": "Bearer", - "expires_in": 3599, - } - mock_response.raise_for_status = MagicMock() - - # Mock the async httpx client - mock_async_client = MagicMock() - mock_async_client.post = AsyncMock(return_value=mock_response) - - with patch( - "litellm.proxy._experimental.mcp_server.discoverable_endpoints.get_async_httpx_client" - ) as mock_get_client: - mock_get_client.return_value = mock_async_client - - # Call token endpoint - response = await token_endpoint( - request=mock_request, - grant_type="authorization_code", - code="test_code", - redirect_uri="http://localhost:60108/callback", - client_id="test_client_id", - mcp_server_name="google_mcp", - client_secret="test_secret", - ) - - # Verify that the redirect_uri sent to the provider uses HTTPS - call_args = mock_async_client.post.call_args - assert ( - call_args[1]["data"]["redirect_uri"] - == "https://litellm-proxy.example.com/callback" - ) - - -@pytest.mark.asyncio -async def test_oauth_protected_resource_standard_pattern(): - """Test that oauth_protected_resource_mcp_standard returns standard MCP URL pattern (/mcp/{server_name})""" - try: - from litellm.proxy._experimental.mcp_server.discoverable_endpoints import ( - oauth_protected_resource_mcp_standard, - ) - from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( - global_mcp_server_manager, - ) - from litellm.types.mcp import MCPAuth - from litellm.types.mcp_server.mcp_server_manager import MCPServer - from litellm.proxy._types import MCPTransport - from fastapi import Request - except ImportError: - pytest.skip("MCP discoverable endpoints not available") - - # Clear registry - global_mcp_server_manager.registry.clear() - - # Create mock OAuth2 server - oauth2_server = MCPServer( - server_id="test_server", - name="test_server", - server_name="test_server", - alias="test_server", - transport=MCPTransport.http, - auth_type=MCPAuth.oauth2, - client_id="test_client_id", - client_secret="test_client_secret", - authorization_url="https://provider.com/oauth/authorize", - token_url="https://provider.com/oauth/token", - scopes=["read", "write"], - ) - global_mcp_server_manager.registry[oauth2_server.server_id] = oauth2_server - - # Mock request - mock_request = MagicMock(spec=Request) - mock_request.base_url = "https://litellm.example.com/" - mock_request.headers = {} - - # Call the standard pattern endpoint - response = await oauth_protected_resource_mcp_standard( - request=mock_request, - mcp_server_name="test_server", - ) - - # Verify response uses standard MCP pattern: /mcp/{server_name} - assert response["resource"] == "https://litellm.example.com/mcp/test_server" - assert response["authorization_servers"][0] == "https://litellm.example.com/test_server" - assert response["scopes_supported"] == oauth2_server.scopes - - -@pytest.mark.asyncio -async def test_oauth_protected_resource_legacy_pattern(): - """Test that oauth_protected_resource_mcp returns legacy URL pattern (/{server_name}/mcp)""" - try: - from litellm.proxy._experimental.mcp_server.discoverable_endpoints import ( - oauth_protected_resource_mcp, - ) - from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( - global_mcp_server_manager, - ) - from litellm.types.mcp import MCPAuth - from litellm.types.mcp_server.mcp_server_manager import MCPServer - from litellm.proxy._types import MCPTransport - from fastapi import Request - except ImportError: - pytest.skip("MCP discoverable endpoints not available") - - # Clear registry - global_mcp_server_manager.registry.clear() - - # Create mock OAuth2 server - oauth2_server = MCPServer( - server_id="test_server", - name="test_server", - server_name="test_server", - alias="test_server", - transport=MCPTransport.http, - auth_type=MCPAuth.oauth2, - client_id="test_client_id", - client_secret="test_client_secret", - authorization_url="https://provider.com/oauth/authorize", - token_url="https://provider.com/oauth/token", - scopes=["read", "write"], - ) - global_mcp_server_manager.registry[oauth2_server.server_id] = oauth2_server - - # Mock request - mock_request = MagicMock(spec=Request) - mock_request.base_url = "https://litellm.example.com/" - mock_request.headers = {} - - # Call the legacy pattern endpoint - response = await oauth_protected_resource_mcp( - request=mock_request, - mcp_server_name="test_server", - ) - - # Verify response uses legacy pattern: /{server_name}/mcp - assert response["resource"] == "https://litellm.example.com/test_server/mcp" - assert response["authorization_servers"][0] == "https://litellm.example.com/test_server" - assert response["scopes_supported"] == oauth2_server.scopes - - -@pytest.mark.asyncio -async def test_oauth_protected_resource_respects_x_forwarded_proto(): - """Test that oauth_protected_resource_mcp uses X-Forwarded-Proto for URLs""" - try: - from litellm.proxy._experimental.mcp_server.discoverable_endpoints import ( - oauth_protected_resource_mcp, - ) - from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( - global_mcp_server_manager, - ) - from litellm.types.mcp import MCPAuth - from litellm.types.mcp_server.mcp_server_manager import MCPServer - from litellm.proxy._types import MCPTransport - from fastapi import Request - except ImportError: - pytest.skip("MCP discoverable endpoints not available") - # Clear registry - global_mcp_server_manager.registry.clear() - - # Create mock OAuth2 server - oauth2_server = MCPServer( - server_id="test_oauth_server", - name="test_oauth", - server_name="test_oauth", - alias="test_oauth", - transport=MCPTransport.http, - auth_type=MCPAuth.oauth2, - client_id="test_client_id", - client_secret="test_client_secret", - authorization_url="https://provider.com/oauth/authorize", - token_url="https://provider.com/oauth/token", - scopes=["read", "write"], - ) - global_mcp_server_manager.registry[oauth2_server.server_id] = oauth2_server - - # Mock request with http base_url but X-Forwarded-Proto: https - mock_request = MagicMock(spec=Request) - mock_request.base_url = "http://litellm.example.com/" # HTTP - mock_request.headers = {"X-Forwarded-Proto": "https"} # Behind HTTPS proxy - - # Call the endpoint - response = await oauth_protected_resource_mcp( - request=mock_request, - mcp_server_name="test_oauth", - ) - - # Verify response uses HTTPS URLs - assert response["authorization_servers"][0].startswith( - "https://litellm.example.com/" - ) - assert response["scopes_supported"] == oauth2_server.scopes - - -@pytest.mark.asyncio -async def test_oauth_authorization_server_respects_x_forwarded_proto(): - """Test that oauth_authorization_server_mcp uses X-Forwarded-Proto for URLs""" - try: - from litellm.proxy._experimental.mcp_server.discoverable_endpoints import ( - oauth_authorization_server_mcp, - ) - from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( - global_mcp_server_manager, - ) - from litellm.types.mcp import MCPAuth - from litellm.types.mcp_server.mcp_server_manager import MCPServer - from litellm.proxy._types import MCPTransport - from fastapi import Request - except ImportError: - pytest.skip("MCP discoverable endpoints not available") - # Clear registry - global_mcp_server_manager.registry.clear() - - # Create mock OAuth2 server - oauth2_server = MCPServer( - server_id="test_oauth_server", - name="test_oauth", - server_name="test_oauth", - alias="test_oauth", - transport=MCPTransport.http, - auth_type=MCPAuth.oauth2, - client_id="test_client_id", - client_secret="test_client_secret", - authorization_url="https://provider.com/oauth/authorize", - token_url="https://provider.com/oauth/token", - scopes=["read", "write"], - ) - global_mcp_server_manager.registry[oauth2_server.server_id] = oauth2_server - - # Mock request with http base_url but X-Forwarded-Proto: https - mock_request = MagicMock(spec=Request) - mock_request.base_url = "http://litellm.example.com/" # HTTP - mock_request.headers = {"X-Forwarded-Proto": "https"} # Behind HTTPS proxy - - # Call the endpoint - response = await oauth_authorization_server_mcp( - request=mock_request, - mcp_server_name="test_oauth", - ) - - # Verify response uses HTTPS URLs - assert response["authorization_endpoint"].startswith("https://litellm.example.com/") - assert response["token_endpoint"].startswith("https://litellm.example.com/") - assert response["registration_endpoint"].startswith("https://litellm.example.com/") - assert response["grant_types_supported"] == ["authorization_code", "refresh_token"] - assert response["scopes_supported"] == oauth2_server.scopes - - -@pytest.mark.asyncio -async def test_register_client_respects_x_forwarded_proto(): - """Test that register_client uses X-Forwarded-Proto for redirect_uris""" - try: - from litellm.proxy._experimental.mcp_server.discoverable_endpoints import ( - register_client, - ) - from fastapi import Request - except ImportError: - pytest.skip("MCP discoverable endpoints not available") - - # Mock request with http base_url but X-Forwarded-Proto: https - mock_request = MagicMock(spec=Request) - mock_request.base_url = "http://proxy.litellm.example/" # HTTP - mock_request.headers = {"X-Forwarded-Proto": "https"} # Behind HTTPS proxy - - with patch( - "litellm.proxy._experimental.mcp_server.discoverable_endpoints._read_request_body", - new=AsyncMock(return_value={}), - ): - result = await register_client(request=mock_request) - - # Verify the redirect_uris use HTTPS - assert result == { - "client_id": "dummy_client", - "client_secret": "dummy", - "redirect_uris": ["https://proxy.litellm.example/callback"], - } - - -@pytest.mark.asyncio -async def test_authorize_endpoint_respects_x_forwarded_host(): - """Test that authorize endpoint uses X-Forwarded-Host and X-Forwarded-Proto to construct correct redirect_uri""" - try: - from litellm.proxy._experimental.mcp_server.discoverable_endpoints import ( - authorize, - ) - from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( - global_mcp_server_manager, - ) - from litellm.types.mcp import MCPAuth - from litellm.types.mcp_server.mcp_server_manager import MCPServer - from litellm.proxy._types import MCPTransport - from fastapi import Request - except ImportError: - pytest.skip("MCP discoverable endpoints not available") - - # Clear registry - global_mcp_server_manager.registry.clear() - - # Create mock OAuth2 server - oauth2_server = MCPServer( - server_id="test_oauth_server", - name="test_oauth", - server_name="test_oauth", - alias="test_oauth", - transport=MCPTransport.http, - auth_type=MCPAuth.oauth2, - client_id="test_client_id", - client_secret="test_client_secret", - authorization_url="https://provider.com/oauth/authorize", - token_url="https://provider.com/oauth/token", - scopes=["read", "write"], - ) - global_mcp_server_manager.registry[oauth2_server.server_id] = oauth2_server - - # Mock request simulating nginx proxy: - # Internal: http://localhost:8888/github/mcp - # External: https://proxy.example.com/github/mcp - mock_request = MagicMock(spec=Request) - mock_request.base_url = "http://localhost:8888/github/mcp" - mock_request.headers = { - "X-Forwarded-Proto": "https", - "X-Forwarded-Host": "proxy.example.com", - } - - # Mock the encryption functions - with patch( - "litellm.proxy._experimental.mcp_server.discoverable_endpoints.encrypt_value_helper" - ) as mock_encrypt: - mock_encrypt.return_value = "mocked_encrypted_state" - - # Call authorize endpoint - response = await authorize( - request=mock_request, - client_id="test_client_id", - mcp_server_name="test_oauth", - redirect_uri="https://client.example.com/callback", - state="test_state", - ) - - # Verify redirect URL uses the forwarded host and scheme - location = response.headers["location"] - - # The redirect_uri parameter should use the external URL - assert ( - "redirect_uri=https%3A%2F%2Fproxy.example.com%2Fgithub%2Fmcp%2Fcallback" - in location - or "redirect_uri=https://proxy.example.com/github/mcp/callback" in location - ) - - -@pytest.mark.asyncio -async def test_token_endpoint_respects_x_forwarded_host(): - """Test that token endpoint uses X-Forwarded-Host and X-Forwarded-Proto for redirect_uri""" - try: - from litellm.proxy._experimental.mcp_server.discoverable_endpoints import ( - token_endpoint, - ) - from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( - global_mcp_server_manager, - ) - from litellm.types.mcp import MCPAuth - from litellm.types.mcp_server.mcp_server_manager import MCPServer - from litellm.proxy._types import MCPTransport - from fastapi import Request - except ImportError: - pytest.skip("MCP discoverable endpoints not available") - - # Clear registry - global_mcp_server_manager.registry.clear() - - # Create mock OAuth2 server - oauth2_server = MCPServer( - server_id="google_mcp", - name="google_mcp", - server_name="google_mcp", - alias="google_mcp", - transport=MCPTransport.http, - auth_type=MCPAuth.oauth2, - client_id="test_client_id", - client_secret="test_secret", - authorization_url="https://accounts.google.com/o/oauth2/v2/auth", - token_url="https://oauth2.googleapis.com/token", - scopes=["openid", "email"], - ) - global_mcp_server_manager.registry[oauth2_server.server_id] = oauth2_server - - # Mock request simulating nginx proxy without port in host - mock_request = MagicMock(spec=Request) - mock_request.base_url = "http://localhost:8888/github/mcp" - mock_request.headers = { - "X-Forwarded-Proto": "https", - "X-Forwarded-Host": "proxy.example.com", - } - - # Mock httpx client response - mock_response = MagicMock() - mock_response.json.return_value = { - "access_token": "test_token", - "token_type": "Bearer", - "expires_in": 3599, - } - mock_response.raise_for_status = MagicMock() - - # Mock the async httpx client - mock_async_client = MagicMock() - mock_async_client.post = AsyncMock(return_value=mock_response) - - with patch( - "litellm.proxy._experimental.mcp_server.discoverable_endpoints.get_async_httpx_client" - ) as mock_get_client: - mock_get_client.return_value = mock_async_client - - # Call token endpoint - response = await token_endpoint( - request=mock_request, - grant_type="authorization_code", - code="test_code", - redirect_uri="http://localhost:60108/callback", - client_id="test_client_id", - mcp_server_name="google_mcp", - client_secret="test_secret", - ) - - # Verify that the redirect_uri sent to the provider uses the external URL - call_args = mock_async_client.post.call_args - assert ( - call_args[1]["data"]["redirect_uri"] - == "https://proxy.example.com/github/mcp/callback" - ) - - -@pytest.mark.parametrize( - "base_url,x_forwarded_proto,x_forwarded_host,x_forwarded_port,expected_url", - [ - # Case 1: No forwarded headers - use original URL as-is (no trailing slash) - ( - "http://localhost:4000/", - None, - None, - None, - "http://localhost:4000", - ), - # Case 2: Only X-Forwarded-Proto - change scheme only - ( - "http://localhost:4000/", - "https", - None, - None, - "https://localhost:4000", - ), - # Case 3: X-Forwarded-Proto + X-Forwarded-Host - change scheme and host - ( - "http://localhost:4000/", - "https", - "proxy.example.com", - None, - "https://proxy.example.com", - ), - # Case 4: X-Forwarded-Host with port included in host header - ( - "http://localhost:4000/", - "https", - "proxy.example.com:8080", - None, - "https://proxy.example.com:8080", - ), - # Case 5: X-Forwarded-Host + X-Forwarded-Port as separate headers - ( - "http://localhost:4000/", - "https", - "proxy.example.com", - "8443", - "https://proxy.example.com:8443", - ), - # Case 6: Only X-Forwarded-Host without proto - use original scheme - ( - "http://localhost:4000/", - None, - "proxy.example.com", - None, - "http://proxy.example.com", - ), - # Case 7: Only X-Forwarded-Port without host - preserves original port if present - # (This is safer behavior - X-Forwarded-Port alone is unusual) - ( - "http://localhost:4000/", - None, - None, - "8443", - "http://localhost:4000", # Original port preserved when already present - ), - # Case 8: Complex internal URL with path (path is preserved) - ( - "http://localhost:8888/github/mcp", - "https", - "proxy.example.com", - None, - "https://proxy.example.com/github/mcp", - ), - # Case 9: IPv6 address in X-Forwarded-Host (should not treat :: as port separator) - ( - "http://localhost:4000/", - "https", - "[2001:db8::1]", - None, - "https://[2001:db8::1]", - ), - # Case 10: IPv6 address with port - ( - "http://localhost:4000/", - "https", - "[2001:db8::1]:8080", - None, - "https://[2001:db8::1]:8080", - ), - # Case 11: X-Forwarded-Host already has port, X-Forwarded-Port also provided (host wins) - ( - "http://localhost:4000/", - "https", - "proxy.example.com:9000", - "8443", - "https://proxy.example.com:9000", - ), - # Case 12: Standard proxy setup (most common case) - ( - "http://127.0.0.1:8888/", - "https", - "chatproxy.company.com", - None, - "https://chatproxy.company.com", - ), - # Case 13: Internal URL already has port, X-Forwarded-Port does NOT override - # (safer behavior - preserves original port when X-Forwarded-Host not provided) - ( - "http://localhost:4000/", - None, - None, - "443", - "http://localhost:4000", # Original port preserved - ), - # Case 14: Original URL with existing port in netloc, X-Forwarded-Host replaces it - ( - "http://internal.local:8888/", - "https", - "external.com", - None, - "https://external.com", - ), - ], -) -def test_get_request_base_url_comprehensive( - base_url, x_forwarded_proto, x_forwarded_host, x_forwarded_port, expected_url -): - """Comprehensive test for get_request_base_url with various header combinations""" - try: - from litellm.proxy._experimental.mcp_server.discoverable_endpoints import ( - get_request_base_url, - ) - from fastapi import Request - except ImportError: - pytest.skip("MCP discoverable endpoints not available") - - # Create mock request - mock_request = MagicMock(spec=Request) - mock_request.base_url = base_url - - # Build headers dict - headers = {} - if x_forwarded_proto: - headers["X-Forwarded-Proto"] = x_forwarded_proto - if x_forwarded_host: - headers["X-Forwarded-Host"] = x_forwarded_host - if x_forwarded_port: - headers["X-Forwarded-Port"] = x_forwarded_port - - # Mock headers.get() to return our test values - def mock_get(header_name, default=None): - return headers.get(header_name, default) - - mock_request.headers.get = mock_get - - # Test the function - result = get_request_base_url(mock_request) - - # Verify result - assert result == expected_url, ( - f"Expected '{expected_url}' but got '{result}'\n" - f"Input: base_url={base_url}, " - f"X-Forwarded-Proto={x_forwarded_proto}, " - f"X-Forwarded-Host={x_forwarded_host}, " - f"X-Forwarded-Port={x_forwarded_port}" - ) diff --git a/tests/llm_translation/test_bedrock_completion.py b/tests/llm_translation/test_bedrock_completion.py index d48dd1bfd98..7c0db41d13a 100644 --- a/tests/llm_translation/test_bedrock_completion.py +++ b/tests/llm_translation/test_bedrock_completion.py @@ -3954,288 +3954,3 @@ def test_bedrock_openai_error_handling(): assert exc_info.value.status_code == 422 print("✓ Error handling works correctly") - -# ============================================================================ -# Nova Grounding (web_search_options) Unit Tests (Mocked) -# ============================================================================ - -def test_bedrock_nova_grounding_web_search_options_non_streaming(): - """ - Unit test for Nova grounding using web_search_options parameter (non-streaming). - - This test mocks the HTTP call to verify: - 1. web_search_options is correctly mapped to systemTool for Nova models - 2. The request structure is correct - - Related: https://docs.aws.amazon.com/nova/latest/userguide/grounding.html - """ - from unittest.mock import patch, MagicMock - from litellm.llms.custom_httpx.http_handler import HTTPHandler - - client = HTTPHandler() - - messages = [ - { - "role": "user", - "content": "What is the current population of Tokyo, Japan?", - } - ] - - with patch.object(client, "post") as mock_post: - try: - completion( - model="us.amazon.nova-pro-v1:0", # No bedrock/ prefix when using api_base - messages=messages, - web_search_options={}, # Enables Nova grounding - max_tokens=500, - client=client, - api_base="https://bedrock-runtime.us-east-1.amazonaws.com", - ) - except Exception: - pass # Expected - we're just checking the request structure - - # Verify the request was made correctly - if mock_post.called: - request_body = json.loads(mock_post.call_args.kwargs.get("data", "{}")) - print(f"Request body: {json.dumps(request_body, indent=2)}") - - # Verify toolConfig is present with systemTool - assert "toolConfig" in request_body, "toolConfig should be in request" - tool_config = request_body["toolConfig"] - assert "tools" in tool_config, "tools should be in toolConfig" - - # Find the systemTool for nova_grounding - system_tool_found = False - for tool in tool_config["tools"]: - if "systemTool" in tool: - assert tool["systemTool"]["name"] == "nova_grounding" - system_tool_found = True - break - - assert system_tool_found, "systemTool with nova_grounding should be present" - print(f"✓ web_search_options correctly transformed to systemTool (non-streaming)") - - -def test_bedrock_nova_grounding_with_function_tools(): - """ - Unit test for Nova grounding combined with regular function tools. - - This tests the scenario where users want both web grounding AND - custom function calling capabilities. - """ - from unittest.mock import patch - from litellm.llms.custom_httpx.http_handler import HTTPHandler - - client = HTTPHandler() - - # Regular function tool - tools = [ - { - "type": "function", - "function": { - "name": "get_stock_price", - "description": "Get the current stock price for a given ticker symbol", - "parameters": { - "type": "object", - "properties": { - "ticker": { - "type": "string", - "description": "The stock ticker symbol, e.g. AAPL, GOOGL", - } - }, - "required": ["ticker"], - }, - }, - } - ] - - messages = [ - { - "role": "user", - "content": "What is the current market cap of Apple Inc?", - } - ] - - with patch.object(client, "post") as mock_post: - try: - completion( - model="us.amazon.nova-pro-v1:0", # No bedrock/ prefix when using api_base - messages=messages, - tools=tools, - web_search_options={}, # Also enable web grounding - max_tokens=500, - client=client, - api_base="https://bedrock-runtime.us-east-1.amazonaws.com", - ) - except Exception: - pass # Expected - we're just checking the request structure - - # Verify the request was made correctly - if mock_post.called: - request_body = json.loads(mock_post.call_args.kwargs.get("data", "{}")) - print(f"Request body: {json.dumps(request_body, indent=2)}") - - # Verify toolConfig has both function tool and systemTool - assert "toolConfig" in request_body, "toolConfig should be in request" - tool_config = request_body["toolConfig"] - assert "tools" in tool_config, "tools should be in toolConfig" - - tools_in_request = tool_config["tools"] - - # Should have both the function tool and the systemTool - function_tool_found = False - system_tool_found = False - - for tool in tools_in_request: - if "toolSpec" in tool: - assert tool["toolSpec"]["name"] == "get_stock_price" - function_tool_found = True - if "systemTool" in tool: - assert tool["systemTool"]["name"] == "nova_grounding" - system_tool_found = True - - assert function_tool_found, "Function tool (get_stock_price) should be present" - assert system_tool_found, "systemTool (nova_grounding) should be present" - print(f"✓ Both function tools and web_search_options correctly combined") - - -@pytest.mark.asyncio -async def test_bedrock_nova_grounding_async(): - """ - Async unit test for Nova grounding via web_search_options. - - This test verifies the request transformation for async calls. - """ - from unittest.mock import patch, AsyncMock - from litellm.llms.custom_httpx.http_handler import AsyncHTTPHandler - - client = AsyncHTTPHandler() - - messages = [ - { - "role": "user", - "content": "What is the weather forecast for New York City today?", - } - ] - - with patch.object(client, "post", new=AsyncMock()) as mock_post: - try: - await litellm.acompletion( - model="us.amazon.nova-pro-v1:0", # No bedrock/ prefix when using api_base - messages=messages, - web_search_options={}, - max_tokens=500, - client=client, - api_base="https://bedrock-runtime.us-east-1.amazonaws.com", - ) - except Exception: - pass # Expected - we're just checking the request structure - - # Verify the request was made correctly - if mock_post.called: - request_body = json.loads(mock_post.call_args.kwargs.get("data", "{}")) - print(f"Request body: {json.dumps(request_body, indent=2)}") - - # Verify toolConfig is present with systemTool - assert "toolConfig" in request_body, "toolConfig should be in request" - tool_config = request_body["toolConfig"] - assert "tools" in tool_config, "tools should be in toolConfig" - - # Find the systemTool for nova_grounding - system_tool_found = False - for tool in tool_config["tools"]: - if "systemTool" in tool: - assert tool["systemTool"]["name"] == "nova_grounding" - system_tool_found = True - break - - assert system_tool_found, "systemTool with nova_grounding should be present" - print(f"✓ Async web_search_options correctly transformed to systemTool") - - -def test_bedrock_nova_web_search_options_ignored_for_non_nova(): - """ - Test that web_search_options is ignored for non-Nova Bedrock models. - - Nova grounding is only supported on Nova models. For other models, - the parameter should be silently ignored. - """ - from litellm.llms.bedrock.chat.converse_transformation import AmazonConverseConfig - - config = AmazonConverseConfig() - - # Should return None for non-Nova models - result = config._map_web_search_options({}, "anthropic.claude-3-sonnet-v1") - assert result is None - - result = config._map_web_search_options({}, "amazon.titan-text-express-v1") - assert result is None - - # Should return systemTool for Nova models - result = config._map_web_search_options({}, "amazon.nova-pro-v1:0") - assert result is not None - system_tool = result.get("systemTool") - assert system_tool is not None - assert system_tool["name"] == "nova_grounding" - - result2 = config._map_web_search_options({}, "us.amazon.nova-premier-v1:0") - assert result2 is not None - system_tool2 = result2.get("systemTool") - assert system_tool2 is not None - assert system_tool2["name"] == "nova_grounding" - - -def test_bedrock_nova_grounding_request_transformation(): - """ - Unit test to verify that web_search_options transforms to systemTool in the request. - """ - from unittest.mock import patch, MagicMock - from litellm.llms.custom_httpx.http_handler import HTTPHandler - - client = HTTPHandler() - - messages = [{"role": "user", "content": "What is the population of Tokyo?"}] - - with patch.object(client, "post") as mock_post: - mock_post.return_value = MagicMock( - status_code=200, - json=lambda: { - "output": {"message": {"role": "assistant", "content": [{"text": "Test"}]}}, - "stopReason": "end_turn", - "usage": {"inputTokens": 10, "outputTokens": 5} - } - ) - - try: - response = completion( - model="bedrock/us.amazon.nova-pro-v1:0", - messages=messages, - web_search_options={}, - max_tokens=100, - client=client, - ) - except Exception: - pass # Expected - we're just checking the request - - if mock_post.called: - request_body = json.loads(mock_post.call_args.kwargs.get("data", "{}")) - print(f"Request body: {json.dumps(request_body, indent=2)}") - - # Verify toolConfig is present with systemTool - assert "toolConfig" in request_body, "toolConfig should be in request" - - tool_config = request_body["toolConfig"] - assert "tools" in tool_config, "tools should be in toolConfig" - - tools_in_request = tool_config["tools"] - - # Find the systemTool - system_tool_found = False - for tool in tools_in_request: - if "systemTool" in tool: - assert tool["systemTool"]["name"] == "nova_grounding" - system_tool_found = True - break - - assert system_tool_found, "systemTool with nova_grounding should be present" - print("✓ web_search_options correctly transformed to systemTool") diff --git a/tests/llm_translation/test_gigachat.py b/tests/llm_translation/test_gigachat.py index b69a5428e42..dd8d56ff54a 100644 --- a/tests/llm_translation/test_gigachat.py +++ b/tests/llm_translation/test_gigachat.py @@ -5,7 +5,9 @@ Run with: pytest tests/llm_translation/test_gigachat.py -v """ +import json import pytest +from unittest.mock import Mock, MagicMock class TestGigaChatMessageTransformation: @@ -14,7 +16,6 @@ class TestGigaChatMessageTransformation: @pytest.fixture def config(self): from litellm.llms.gigachat.chat.transformation import GigaChatConfig - return GigaChatConfig() def test_simple_user_message(self, config): @@ -51,46 +52,20 @@ def test_tool_role_to_function(self, config): assert result[0]["role"] == "function" - def test_tool_content_convertation_non_string_value(self, config): - """Non string tool content should be serialized""" - messages = [{"role": "tool", "content": {"output": 42}}] - result = config._transform_messages(messages) - - assert result[0]["content"] == '{"output": 42}' - - def test_tool_content_convertation_json_string_value(self, config): - """JSON string tool content left unchanged""" - valid_json = '{"output": "red car"}' - messages = [{"role": "tool", "content": valid_json}] - result = config._transform_messages(messages) - - assert result[0]["content"] == valid_json - - def test_tool_content_convertation_random_string_value(self, config): - """Non JSON tool content should be serialized""" - messages = [{"role": "tool", "content": "random string"}] - result = config._transform_messages(messages) - - assert result[0]["content"] == '"random string"' - def test_tool_calls_to_function_call(self, config): """tool_calls should be converted to function_call""" - messages = [ - { - "role": "assistant", - "content": "", - "tool_calls": [ - { - "id": "call_123", - "type": "function", - "function": { - "name": "get_weather", - "arguments": '{"city": "Moscow"}', - }, - } - ], - } - ] + messages = [{ + "role": "assistant", + "content": "", + "tool_calls": [{ + "id": "call_123", + "type": "function", + "function": { + "name": "get_weather", + "arguments": '{"city": "Moscow"}' + } + }] + }] result = config._transform_messages(messages) assert "function_call" in result[0] @@ -119,7 +94,6 @@ class TestGigaChatCollapseUserMessages: @pytest.fixture def config(self): from litellm.llms.gigachat.chat.transformation import GigaChatConfig - return GigaChatConfig() def test_no_collapse_single_message(self, config): @@ -162,24 +136,23 @@ class TestGigaChatToolsTransformation: @pytest.fixture def config(self): from litellm.llms.gigachat.chat.transformation import GigaChatConfig - return GigaChatConfig() def test_single_tool_conversion(self, config): """Single tool should be converted correctly""" - tools = [ - { - "type": "function", - "function": { - "name": "get_weather", - "description": "Get weather for a city", - "parameters": { - "type": "object", - "properties": {"city": {"type": "string"}}, - }, - }, + tools = [{ + "type": "function", + "function": { + "name": "get_weather", + "description": "Get weather for a city", + "parameters": { + "type": "object", + "properties": { + "city": {"type": "string"} + } + } } - ] + }] result = config._convert_tools_to_functions(tools) assert len(result) == 1 @@ -189,22 +162,8 @@ def test_single_tool_conversion(self, config): def test_multiple_tools_conversion(self, config): """Multiple tools should all be converted""" tools = [ - { - "type": "function", - "function": { - "name": "func1", - "description": "First", - "parameters": {"type": "object", "properties": {}}, - }, - }, - { - "type": "function", - "function": { - "name": "func2", - "description": "Second", - "parameters": {"type": "object", "properties": {}}, - }, - }, + {"type": "function", "function": {"name": "func1", "description": "First", "parameters": {"type": "object", "properties": {}}}}, + {"type": "function", "function": {"name": "func2", "description": "Second", "parameters": {"type": "object", "properties": {}}}}, ] result = config._convert_tools_to_functions(tools) @@ -219,7 +178,6 @@ class TestGigaChatParamsTransformation: @pytest.fixture def config(self): from litellm.llms.gigachat.chat.transformation import GigaChatConfig - return GigaChatConfig() def test_temperature_zero_becomes_top_p_zero(self, config): @@ -271,10 +229,10 @@ def test_structured_output_via_json_schema(self, config): "type": "object", "properties": { "name": {"type": "string"}, - "age": {"type": "integer"}, - }, - }, - }, + "age": {"type": "integer"} + } + } + } } } result = config.map_openai_params( @@ -325,7 +283,6 @@ class TestGigaChatTransformRequest: @pytest.fixture def config(self): from litellm.llms.gigachat.chat.transformation import GigaChatConfig - return GigaChatConfig() def test_basic_request(self, config): @@ -378,7 +335,6 @@ class TestGigaChatSupportedParams: @pytest.fixture def config(self): from litellm.llms.gigachat.chat.transformation import GigaChatConfig - return GigaChatConfig() def test_supported_params(self, config): diff --git a/tests/llm_translation/test_groq.py b/tests/llm_translation/test_groq.py index b82cffd4189..33c1a425870 100644 --- a/tests/llm_translation/test_groq.py +++ b/tests/llm_translation/test_groq.py @@ -11,10 +11,7 @@ import litellm from base_llm_unit_tests import BaseLLMChatTest -from litellm.llms.groq.chat.transformation import ( - GroqChatConfig, - GroqChatCompletionStreamingHandler, -) +from litellm.llms.groq.chat.transformation import GroqChatConfig class TestGroq(BaseLLMChatTest): def get_base_completion_call_args(self) -> dict: @@ -167,124 +164,3 @@ def test_structured_output_passes_through_for_native_models(self): if "tools" in result: tool_names = [t.get("function", {}).get("name") for t in result["tools"]] assert "json_tool_call" not in tool_names - - -class TestGroqReasoning: - """ - Tests for Groq reasoning field mapping. - - Groq returns 'reasoning' field in delta, but LiteLLM expects 'reasoning_content'. - """ - - def test_reasoning_field_mapping_in_streaming_chunks(self): - """ - Test that Groq's 'reasoning' field in streaming chunks is properly mapped - to LiteLLM's 'reasoning_content' field. - """ - handler = GroqChatCompletionStreamingHandler( - streaming_response=None, sync_stream=True - ) - - # Simulate a chunk with reasoning field as returned by Groq - groq_chunk = { - "id": "chatcmpl-test", - "object": "chat.completion.chunk", - "created": 1769511767, - "model": "qwen/qwen3-32b", - "choices": [ - { - "delta": { - "reasoning": "This is reasoning content", - "role": None, - }, - "finish_reason": None, - "index": 0, - } - ], - } - - # Parse the chunk - parsed_chunk = handler.chunk_parser(groq_chunk) - - # Verify that reasoning was mapped to reasoning_content - assert parsed_chunk.choices[0].delta.reasoning_content == "This is reasoning content" - # Verify that the original 'reasoning' field was removed - assert not hasattr(parsed_chunk.choices[0].delta, "reasoning") - - def test_reasoning_field_not_present(self): - """ - Test that chunks without reasoning field still work correctly. - """ - handler = GroqChatCompletionStreamingHandler( - streaming_response=None, sync_stream=True - ) - - # Simulate a chunk without reasoning field - groq_chunk = { - "id": "chatcmpl-test", - "object": "chat.completion.chunk", - "created": 1769511767, - "model": "qwen/qwen3-32b", - "choices": [ - { - "delta": { - "content": "Regular content", - "role": "assistant", - }, - "finish_reason": None, - "index": 0, - } - ], - } - - # Parse the chunk - parsed_chunk = handler.chunk_parser(groq_chunk) - - # Verify that content is present - assert parsed_chunk.choices[0].delta.content == "Regular content" - assert parsed_chunk.choices[0].delta.role == "assistant" - # Verify that reasoning_content is not set (it should be deleted by Delta.__init__) - assert not hasattr(parsed_chunk.choices[0].delta, "reasoning_content") - - def test_reasoning_with_tool_calls(self): - """ - Test that reasoning field is properly mapped even when tool_calls are present. - """ - handler = GroqChatCompletionStreamingHandler( - streaming_response=None, sync_stream=True - ) - - # Simulate a chunk with both reasoning and tool_calls - groq_chunk = { - "id": "chatcmpl-test", - "object": "chat.completion.chunk", - "created": 1769511767, - "model": "qwen/qwen3-32b", - "choices": [ - { - "delta": { - "reasoning": "Reasoning before tool call", - "tool_calls": [ - { - "index": 0, - "id": "call_123", - "function": {"name": "test_function", "arguments": "{}"}, - "type": "function", - } - ], - }, - "finish_reason": None, - "index": 0, - } - ], - } - - # Parse the chunk - parsed_chunk = handler.chunk_parser(groq_chunk) - - # Verify that reasoning was mapped to reasoning_content - assert parsed_chunk.choices[0].delta.reasoning_content == "Reasoning before tool call" - # Verify tool_calls are still present - assert parsed_chunk.choices[0].delta.tool_calls is not None - assert len(parsed_chunk.choices[0].delta.tool_calls) == 1 - assert parsed_chunk.choices[0].delta.tool_calls[0]["function"]["name"] == "test_function" diff --git a/tests/llm_translation/test_xai.py b/tests/llm_translation/test_xai.py index aa0c33cfe05..64ee95b52f1 100644 --- a/tests/llm_translation/test_xai.py +++ b/tests/llm_translation/test_xai.py @@ -175,7 +175,3 @@ def get_base_completion_call_args(self): def test_tool_call_no_arguments(self, tool_call_no_arguments): """Test that tool calls with no arguments is translated correctly. Relevant issue: https://github.com/BerriAI/litellm/issues/6833""" pass - - def test_web_search(self): - """xAI deprecated web search functionality""" - pytest.skip("xAI has deprecated web search functionality") diff --git a/tests/local_testing/test_add_update_models.py b/tests/local_testing/test_add_update_models.py index 4b5ec95d3fc..6d7ae597b54 100644 --- a/tests/local_testing/test_add_update_models.py +++ b/tests/local_testing/test_add_update_models.py @@ -16,8 +16,6 @@ ) # Adds the parent directory to the system path import pytest, logging, asyncio import litellm -import litellm.proxy -import litellm.proxy.proxy_server from litellm.proxy.management_endpoints.model_management_endpoints import ( add_new_model, update_model, diff --git a/tests/local_testing/test_amazing_vertex_completion.py b/tests/local_testing/test_amazing_vertex_completion.py index 866e2a85060..1987a7a545f 100644 --- a/tests/local_testing/test_amazing_vertex_completion.py +++ b/tests/local_testing/test_amazing_vertex_completion.py @@ -742,7 +742,7 @@ def test_gemini_pro_grounding(value_in_dict): @pytest.mark.parametrize("model", ["vertex_ai_beta/gemini-2.5-flash-lite"]) # "vertex_ai", @pytest.mark.parametrize("sync_mode", [True]) # "vertex_ai", @pytest.mark.asyncio -@pytest.mark.flaky(retries=6, delay=2) +@pytest.mark.flaky(retries=3, delay=1) async def test_gemini_pro_function_calling_httpx(model, sync_mode): try: load_vertex_ai_credentials() @@ -785,7 +785,6 @@ async def test_gemini_pro_function_calling_httpx(model, sync_mode): "messages": messages, "tools": tools, "tool_choice": "required", - "timeout": 60, # Add explicit timeout } print(f"Model for call - {model}") if sync_mode: @@ -800,18 +799,12 @@ async def test_gemini_pro_function_calling_httpx(model, sync_mode): response.choices[0].message.tool_calls[0].function.arguments, str ) except litellm.RateLimitError as e: - pytest.skip(f"Rate limit exceeded: {str(e)}") - except litellm.ServiceUnavailableError as e: - pytest.skip(f"Service unavailable: {str(e)}") - except litellm.Timeout as e: - pytest.skip(f"Request timeout: {str(e)}") + pass except Exception as e: - error_msg = str(e) - # Skip test for known transient API issues - if any(x in error_msg for x in ["429 Quota exceeded", "503", "Service unavailable", "timeout", "Timeout", "UNAVAILABLE"]): - pytest.skip(f"Transient API error: {error_msg}") + if "429 Quota exceeded" in str(e): + pass else: - pytest.fail(f"An unexpected exception occurred - {error_msg}") + pytest.fail("An unexpected exception occurred - {}".format(str(e))) from test_completion import response_format_tests @@ -820,7 +813,7 @@ async def test_gemini_pro_function_calling_httpx(model, sync_mode): @pytest.mark.parametrize( "model,region", [ - ("vertex_ai/mistral-small-2503", "us-central1"), + ("vertex_ai/mistral-large-2411", "us-central1"), ("vertex_ai/qwen/qwen3-coder-480b-a35b-instruct-maas", "us-south1"), ("vertex_ai/openai/gpt-oss-20b-maas", "us-central1"), ], @@ -893,7 +886,7 @@ async def test_partner_models_httpx(model, region, sync_mode): ("vertex_ai/meta/llama-4-scout-17b-16e-instruct-maas", "us-east5"), ("vertex_ai/qwen/qwen3-coder-480b-a35b-instruct-maas", "us-south1"), ( - "vertex_ai/mistral-small-2503", + "vertex_ai/mistral-large-2411", "us-central1", ), # critical - we had this issue: https://github.com/BerriAI/litellm/issues/13888 ("vertex_ai/openai/gpt-oss-20b-maas", "us-central1"), diff --git a/tests/local_testing/test_auth_utils.py b/tests/local_testing/test_auth_utils.py index d36f96b1a39..72f799a6cf0 100644 --- a/tests/local_testing/test_auth_utils.py +++ b/tests/local_testing/test_auth_utils.py @@ -356,25 +356,6 @@ def test_get_internal_user_header_from_mapping_no_internal_returns_none(): "/openai/deployments/my-deployment/chat/completions", "my-deployment" ), - # Custom model_name with slashes (e.g., gcp/google/gemini-2.5-flash) - # This is the NVIDIA P0 bug fix - regex should capture full model name including slashes - ( - {}, - "/vertex_ai/v1/projects/my-project/locations/us-central1/publishers/google/models/gcp/google/gemini-2.5-flash:generateContent", - "gcp/google/gemini-2.5-flash" - ), - # Another custom model_name with slashes - ( - {}, - "/vertex_ai/v1/projects/my-project/locations/global/publishers/google/models/gcp/google/gemini-3-flash-preview:generateContent", - "gcp/google/gemini-3-flash-preview" - ), - # Model name with single slash - ( - {}, - "/vertex_ai/v1/projects/my-project/locations/us-central1/publishers/google/models/custom/model:generateContent", - "custom/model" - ), ], ) def test_get_model_from_request_vertex_ai_passthrough(request_data, route, expected_model): diff --git a/tests/local_testing/test_completion_with_retries.py b/tests/local_testing/test_completion_with_retries.py index 585e1ee2618..6eb3ad460e6 100644 --- a/tests/local_testing/test_completion_with_retries.py +++ b/tests/local_testing/test_completion_with_retries.py @@ -60,7 +60,6 @@ async def test_completion_with_retry_policy(sync_mode): retry_number = 1 retry_policy = RetryPolicy( - BadRequestErrorRetries=10, ContentPolicyViolationErrorRetries=retry_number, # run 3 retries for ContentPolicyViolationErrors AuthenticationErrorRetries=0, # run 0 retries for AuthenticationErrorRetries ) diff --git a/tests/local_testing/test_literalai.py b/tests/local_testing/test_literalai.py new file mode 100644 index 00000000000..35e583549dd --- /dev/null +++ b/tests/local_testing/test_literalai.py @@ -0,0 +1,72 @@ +import os +import sys + +sys.path.insert(0, os.path.abspath("../..")) + +import asyncio +import logging + +import pytest + +import litellm +from litellm._logging import verbose_logger +from litellm.integrations.literal_ai import LiteralAILogger + +verbose_logger.setLevel(logging.DEBUG) + +litellm.set_verbose = True + + +@pytest.mark.asyncio +async def test_literalai_queue_logging(): + try: + # Initialize LiteralAILogger + test_literalai_logger = LiteralAILogger() + + litellm.callbacks = [test_literalai_logger] + test_literalai_logger.batch_size = 6 + litellm.set_verbose = True + + # Make multiple calls to ensure we don't hit the batch size + for _ in range(5): + response = await litellm.acompletion( + model="gpt-3.5-turbo", + messages=[{"role": "user", "content": "Test message"}], + max_tokens=10, + temperature=0.2, + mock_response="This is a mock response", + ) + + await asyncio.sleep(3) + + # Check that logs are in the queue + assert len(test_literalai_logger.log_queue) == 5 + + # Now make calls to exceed the batch size + for _ in range(3): + await litellm.acompletion( + model="gpt-3.5-turbo", + messages=[{"role": "user", "content": "Test message"}], + max_tokens=10, + temperature=0.2, + mock_response="This is a mock response", + ) + + # Wait a short time for any asynchronous operations to complete + await asyncio.sleep(1) + + print( + "Length of literalai log queue: {}".format( + len(test_literalai_logger.log_queue) + ) + ) + # Check that the queue was flushed after exceeding batch size + assert len(test_literalai_logger.log_queue) < 5 + + # Clean up + for cb in litellm.callbacks: + if isinstance(cb, LiteralAILogger): + await cb.async_httpx_client.client.aclose() + + except Exception as e: + pytest.fail(f"Error occurred: {e}") diff --git a/tests/local_testing/test_timeout.py b/tests/local_testing/test_timeout.py index 7f9837e81dd..bb6dbc938ba 100644 --- a/tests/local_testing/test_timeout.py +++ b/tests/local_testing/test_timeout.py @@ -285,3 +285,94 @@ async def test_anthropic_timeout(streaming, sync_mode): ) print(type(e)) pass + + +@pytest.mark.asyncio +async def test_timeout_respects_total_time_not_per_retry(): + """ + Test that timeout applies to the TOTAL operation time, not per-retry. + + This test ensures that when a user sets timeout=2, the entire operation + (including all retries) times out at ~2 seconds, not at 2s * num_retries. + + This is a regression test for the issue where timeout was being applied + per-retry attempt, causing the total time to be much longer than expected. + """ + litellm.set_verbose = False + + timeout_value = 2.0 + # Allow for some overhead (network, processing, etc.) + # but ensure we don't wait for multiple retries + max_allowed_time = timeout_value + 1.0 # 3 seconds max + + start_time = time.time() + + try: + # This should timeout because we're asking for a long response + # with a very short timeout + response = await litellm.acompletion( + model="gpt-3.5-turbo", + timeout=timeout_value, + messages=[{"role": "user", "content": "Write a very long detailed essay about the history of computing, at least 5000 words."}], + ) + pytest.fail("Expected timeout error but got a response") + except (openai.APITimeoutError, litellm.exceptions.Timeout) as e: + elapsed_time = time.time() - start_time + + print(f"Timeout occurred after {elapsed_time:.2f} seconds") + print(f"Expected timeout: {timeout_value} seconds") + print(f"Max allowed time: {max_allowed_time} seconds") + + # Verify that the timeout happened within the expected time window + # It should be close to timeout_value, not timeout_value * num_retries + assert elapsed_time < max_allowed_time, ( + f"Timeout took too long! Expected ~{timeout_value}s, " + f"got {elapsed_time:.2f}s. This suggests timeout is being " + f"applied per-retry instead of to the total operation." + ) + + # Also verify it's not TOO fast (sanity check) + assert elapsed_time >= timeout_value * 0.5, ( + f"Timeout happened too quickly: {elapsed_time:.2f}s. " + f"Expected at least {timeout_value * 0.5}s" + ) + + print("✓ Timeout correctly applied to total operation time, not per-retry") + except Exception as e: + pytest.fail( + f"Expected timeout error but got different error: {type(e).__name__}: {e}" + ) + + +@pytest.mark.asyncio +async def test_timeout_with_retries_disabled(): + """ + Test that timeout works correctly when retries are explicitly disabled. + This should timeout even faster since there are no retry attempts. + """ + litellm.set_verbose = False + + timeout_value = 2.0 + max_allowed_time = timeout_value + 0.5 # Even tighter bound with no retries + + start_time = time.time() + + try: + response = await litellm.acompletion( + model="gpt-3.5-turbo", + timeout=timeout_value, + max_retries=0, # Disable retries + messages=[{"role": "user", "content": "Write a very long detailed essay about the history of computing, at least 5000 words."}], + ) + pytest.fail("Expected timeout error but got a response") + except (openai.APITimeoutError, litellm.exceptions.Timeout) as e: + elapsed_time = time.time() - start_time + + print(f"Timeout with no retries occurred after {elapsed_time:.2f} seconds") + + assert elapsed_time < max_allowed_time, ( + f"Timeout took too long even with retries disabled! " + f"Expected ~{timeout_value}s, got {elapsed_time:.2f}s" + ) + + print("✓ Timeout works correctly with retries disabled") diff --git a/tests/mcp_tests/test_aresponses_api_with_mcp.py b/tests/mcp_tests/test_aresponses_api_with_mcp.py index a7bbfef14af..6c8f51201d8 100644 --- a/tests/mcp_tests/test_aresponses_api_with_mcp.py +++ b/tests/mcp_tests/test_aresponses_api_with_mcp.py @@ -683,11 +683,9 @@ async def test_streaming_responses_api_with_mcp_tools( Return the user the result of request 2 """ - # Skip test if required API keys are not set - if ("anthropic" in model.lower() or "claude" in model.lower()) and not os.getenv("ANTHROPIC_API_KEY"): + # Skip test if ANTHROPIC_API_KEY is not set for anthropic models + if "anthropic" in model.lower() and not os.getenv("ANTHROPIC_API_KEY"): pytest.skip("ANTHROPIC_API_KEY not set, skipping anthropic model test") - if ("gpt" in model.lower() or "openai" in model.lower()) and not os.getenv("OPENAI_API_KEY"): - pytest.skip("OPENAI_API_KEY not set, skipping openai model test") from unittest.mock import AsyncMock, patch diff --git a/tests/mcp_tests/test_mcp_client_unit.py b/tests/mcp_tests/test_mcp_client_unit.py index 9533e56bcc8..fcee3208be1 100644 --- a/tests/mcp_tests/test_mcp_client_unit.py +++ b/tests/mcp_tests/test_mcp_client_unit.py @@ -5,7 +5,7 @@ import os import sys import pytest -from unittest.mock import AsyncMock, MagicMock, patch, ANY +from unittest.mock import AsyncMock, MagicMock, patch # Add the project root to the path sys.path.insert(0, os.path.abspath("../../..")) @@ -183,7 +183,7 @@ async def test_call_tool(self, mock_session_class, mock_transport): assert result == mock_result mock_session_instance.initialize.assert_called_once() mock_session_instance.call_tool.assert_called_once_with( - name="test_tool", arguments={"arg1": "value1"},progress_callback=ANY + name="test_tool", arguments={"arg1": "value1"} ) diff --git a/tests/mcp_tests/test_mcp_server.py b/tests/mcp_tests/test_mcp_server.py index 5785ff750fd..e8a1231c6fb 100644 --- a/tests/mcp_tests/test_mcp_server.py +++ b/tests/mcp_tests/test_mcp_server.py @@ -1105,26 +1105,9 @@ async def mock_get_allowed_servers(user_auth=None): test_manager.get_allowed_mcp_servers = mock_get_allowed_servers - # Mock health_check_server to avoid real network calls that timeout - async def mock_health_check(server_id: str, mcp_auth_header=None): - server = test_manager.get_mcp_server_by_id(server_id) - if not server: - return None - return LiteLLM_MCPServerTable( - server_id=server_id, - server_name=server.name, - url=server.url, - transport=server.transport, - description=server.mcp_info.get("description") if server.mcp_info else None, - mcp_access_groups=server.access_groups, - status="healthy", - last_health_check=datetime.datetime.now(), - mcp_info=server.mcp_info, - ) - - test_manager.health_check_server = mock_health_check - # Test the method (this tests our second fix) + import asyncio + servers_list = await test_manager.get_all_mcp_servers_with_health_and_teams( user_api_key_auth=mock_user_auth ) diff --git a/tests/pass_through_unit_tests/test_anthropic_messages_tool_search.py b/tests/pass_through_unit_tests/test_anthropic_messages_tool_search.py index 1bd1b0d906c..4914a3df77a 100644 --- a/tests/pass_through_unit_tests/test_anthropic_messages_tool_search.py +++ b/tests/pass_through_unit_tests/test_anthropic_messages_tool_search.py @@ -67,17 +67,17 @@ def get_model(self) -> str: # return "vertex_ai/claude-sonnet-4@20250514" -# class TestBedrockInvokeToolSearch(BaseAnthropicMessagesToolSearchTest): -# """ -# E2E tests for tool search with Bedrock Invoke API. +class TestBedrockInvokeToolSearch(BaseAnthropicMessagesToolSearchTest): + """ + E2E tests for tool search with Bedrock Invoke API. -# Uses the bedrock/invoke/ prefix which routes through the native -# Anthropic Messages API format on Bedrock. + Uses the bedrock/invoke/ prefix which routes through the native + Anthropic Messages API format on Bedrock. -# Beta header: advanced-tool-use-2025-11-20 (passed via extra_headers) + Beta header: advanced-tool-use-2025-11-20 (passed via extra_headers) -# Note: Tool search on Bedrock is only supported on Claude Opus 4.5. -# """ + Note: Tool search on Bedrock is only supported on Claude Opus 4.5. + """ -# def get_model(self) -> str: -# return "bedrock/invoke/us.anthropic.claude-opus-4-5-20251101-v1:0" + def get_model(self) -> str: + return "bedrock/invoke/us.anthropic.claude-opus-4-5-20251101-v1:0" diff --git a/tests/proxy_admin_ui_tests/test_key_management.py b/tests/proxy_admin_ui_tests/test_key_management.py index fa39a05a27d..a196080eada 100644 --- a/tests/proxy_admin_ui_tests/test_key_management.py +++ b/tests/proxy_admin_ui_tests/test_key_management.py @@ -473,41 +473,18 @@ async def test_get_users_key_count(prisma_client): setattr(litellm.proxy.proxy_server, "master_key", "sk-1234") await litellm.proxy.proxy_server.prisma_client.connect() - # Create a test user with no initial keys to ensure deterministic behavior - test_user_id = f"test_user_key_count-{uuid.uuid4()}" - test_user_request = NewUserRequest( - user_id=test_user_id, - user_role=LitellmUserRoles.INTERNAL_USER.value, - auto_create_key=False, # Ensure we start with 0 keys - ) - - await new_user( - test_user_request, - UserAPIKeyAuth( - user_role=LitellmUserRoles.PROXY_ADMIN, - api_key="sk-1234", - user_id="admin", - ), - ) - - # Get initial key count for the test user - initial_users = await get_users( - user_ids=test_user_id, - role=None, - page=1, - page_size=20, - ) + # Get initial user list and select the first user + initial_users = await get_users(role=None, page=1, page_size=20) print("initial_users", initial_users) - assert len(initial_users["users"]) == 1, "Test user should be found" + assert len(initial_users["users"]) > 0, "No users found to test with" + test_user = initial_users["users"][0] - assert test_user.user_id == test_user_id initial_key_count = test_user.key_count - assert initial_key_count == 0, f"Expected initial key count to be 0, but got {initial_key_count}" - # Create a new key for the test user + # Create a new key for the selected user new_key = await generate_key_fn( data=GenerateKeyRequest( - user_id=test_user_id, + user_id=test_user.user_id, key_alias=f"test_key_{uuid.uuid4()}", models=["fake-model"], ), @@ -519,26 +496,19 @@ async def test_get_users_key_count(prisma_client): ) # Get updated user list and check key count - updated_users = await get_users( - user_ids=test_user_id, - role=None, - page=1, - page_size=20, - ) + updated_users = await get_users(role=None, page=1, page_size=20) print("updated_users", updated_users) - assert len(updated_users["users"]) == 1, "Test user should still be found" - updated_user = updated_users["users"][0] - updated_key_count = updated_user.key_count + updated_key_count = None + for user in updated_users["users"]: + if user.user_id == test_user.user_id: + updated_key_count = user.key_count + break + assert updated_key_count is not None, "Test user not found in updated users list" assert ( updated_key_count == initial_key_count + 1 ), f"Expected key count to increase by 1, but got {updated_key_count} (was {initial_key_count})" - # Clean up test user and keys - await prisma_client.db.litellm_usertable.delete( - where={"user_id": test_user_id} - ) - async def cleanup_existing_teams(prisma_client): all_teams = await prisma_client.db.litellm_teamtable.find_many() diff --git a/tests/proxy_unit_tests/test_auth_checks.py b/tests/proxy_unit_tests/test_auth_checks.py index 05c6e4984af..24c005443af 100644 --- a/tests/proxy_unit_tests/test_auth_checks.py +++ b/tests/proxy_unit_tests/test_auth_checks.py @@ -584,7 +584,7 @@ async def test_get_fuzzy_user_object(): ) assert result == test_user mock_prisma.db.litellm_usertable.find_first.assert_called_with( - where={"user_email": {"equals": "test@example.com", "mode": "insensitive"}}, + where={"user_email": "test@example.com"}, include={"organization_memberships": True}, ) @@ -612,7 +612,7 @@ async def test_get_fuzzy_user_object(): ) assert result == test_user mock_prisma.db.litellm_usertable.find_first.assert_called_with( - where={"user_email": {"equals": "test@example.com", "mode": "insensitive"}}, + where={"user_email": "test@example.com"}, include={"organization_memberships": True}, ) diff --git a/tests/proxy_unit_tests/test_get_image.py b/tests/proxy_unit_tests/test_get_image.py deleted file mode 100644 index ad8c2672754..00000000000 --- a/tests/proxy_unit_tests/test_get_image.py +++ /dev/null @@ -1,89 +0,0 @@ -import os -import sys -from unittest import mock - -# Standard path insertion -sys.path.insert(0, os.path.abspath("../..")) - -import pytest -import httpx -from litellm.proxy.proxy_server import app - - -@pytest.mark.asyncio -async def test_get_image_error_handling(): - """ - Test that get_image handles network errors gracefully and doesn't hang. - """ - # Set an unreachable URL - os.environ["UI_LOGO_PATH"] = "http://invalid-url-12345.com/logo.jpg" - - # Clear cache - parent_dir = os.path.dirname( - os.path.dirname( - app.__file__ - if hasattr(app, "__file__") - else "litellm/proxy/proxy_server.py" - ) - ) - cache_path = os.path.join(parent_dir, "proxy", "cached_logo.jpg") - if os.path.exists(cache_path): - os.remove(cache_path) - - # Mock AsyncHTTPHandler to simulate a timeout or connection error - with mock.patch( - "litellm.llms.custom_httpx.http_handler.AsyncHTTPHandler.get" - ) as mock_get: - mock_get.side_effect = httpx.ConnectError("Network is unreachable") - - async with httpx.AsyncClient( - transport=httpx.ASGITransport(app=app), base_url="http://testserver" - ) as ac: - response = await ac.get("/get_image") - - assert response.status_code == 200 - assert response.headers["content-type"] == "image/jpeg" - - -@pytest.mark.asyncio -async def test_get_image_cache_logic(): - """ - Test that once cached, get_image doesn't hit the network. - """ - os.environ["UI_LOGO_PATH"] = "http://example.com/logo.jpg" - - # Clear cache - parent_dir = os.path.dirname( - os.path.dirname( - app.__file__ - if hasattr(app, "__file__") - else "litellm/proxy/proxy_server.py" - ) - ) - cache_path = os.path.join(parent_dir, "proxy", "cached_logo.jpg") - if os.path.exists(cache_path): - os.remove(cache_path) - - # Mock response - mock_response = mock.Mock() - mock_response.status_code = 200 - mock_response.content = b"fake image data" - - with mock.patch( - "litellm.llms.custom_httpx.http_handler.AsyncHTTPHandler.get" - ) as mock_get: - mock_get.return_value = mock_response - - async with httpx.AsyncClient( - transport=httpx.ASGITransport(app=app), base_url="http://testserver" - ) as ac: - # First call - should hit download logic - response1 = await ac.get("/get_image") - assert response1.status_code == 200 - assert mock_get.call_count == 1 - - # Second call - should hit cache - response2 = await ac.get("/get_image") - assert response2.status_code == 200 - # If cache works, mock_get shouldn't be called again - assert mock_get.call_count == 1 diff --git a/tests/proxy_unit_tests/test_proxy_server.py b/tests/proxy_unit_tests/test_proxy_server.py index d864a0d986a..839d09b52d7 100644 --- a/tests/proxy_unit_tests/test_proxy_server.py +++ b/tests/proxy_unit_tests/test_proxy_server.py @@ -1117,10 +1117,7 @@ async def test_create_team_member_add(prisma_client, new_member_method): ) as mock_litellm_usertable, patch( "litellm.proxy.auth.auth_checks._get_team_object_from_user_api_key_cache", new=AsyncMock(return_value=team_obj), - ) as mock_team_obj, patch( - "litellm.proxy.proxy_server.prisma_client.get_data", - new=AsyncMock(return_value=[]), - ) as mock_get_data: + ) as mock_team_obj: mock_client = AsyncMock( return_value=LiteLLM_UserTable( @@ -1129,10 +1126,6 @@ async def test_create_team_member_add(prisma_client, new_member_method): ) mock_litellm_usertable.upsert = mock_client mock_litellm_usertable.find_many = AsyncMock(return_value=None) - # Mock find_first for user_email validation (returns None for new users) - mock_litellm_usertable.find_first = AsyncMock(return_value=None) - # Mock find_unique for user_id validation (returns None for new users) - mock_litellm_usertable.find_unique = AsyncMock(return_value=None) team_mock_client = AsyncMock() original_val = getattr( litellm.proxy.proxy_server.prisma_client.db, "litellm_teamtable" @@ -1306,10 +1299,7 @@ async def test_create_team_member_add_team_admin( ) as mock_litellm_usertable, patch( "litellm.proxy.auth.auth_checks._get_team_object_from_user_api_key_cache", new=AsyncMock(return_value=team_obj), - ) as mock_team_obj, patch( - "litellm.proxy.proxy_server.prisma_client.get_data", - new=AsyncMock(return_value=[]), - ) as mock_get_data: + ) as mock_team_obj: mock_client = AsyncMock( return_value=LiteLLM_UserTable( user_id="1234", max_budget=100, user_email="1234" @@ -1317,10 +1307,6 @@ async def test_create_team_member_add_team_admin( ) mock_litellm_usertable.upsert = mock_client mock_litellm_usertable.find_many = AsyncMock(return_value=None) - # Mock find_first for user_email validation (returns None for new users) - mock_litellm_usertable.find_first = AsyncMock(return_value=None) - # Mock find_unique for user_id validation (returns None for new users) - mock_litellm_usertable.find_unique = AsyncMock(return_value=None) team_mock_client = AsyncMock() original_val = getattr( diff --git a/tests/proxy_unit_tests/test_response_polling_handler.py b/tests/proxy_unit_tests/test_response_polling_handler.py index 26f8ac24adc..cb4cd0efe57 100644 --- a/tests/proxy_unit_tests/test_response_polling_handler.py +++ b/tests/proxy_unit_tests/test_response_polling_handler.py @@ -1005,142 +1005,6 @@ def test_polling_with_router_lookup_no_match(self): assert result is False - # ==================== Native Background Mode Tests ==================== - - def test_polling_disabled_when_model_in_native_background_mode(self): - """Test that polling is disabled when model is in native_background_mode list""" - from litellm.proxy.response_polling.polling_handler import should_use_polling_for_request - - result = should_use_polling_for_request( - background_mode=True, - polling_via_cache_enabled="all", - redis_cache=Mock(), - model="o4-mini-deep-research", - llm_router=None, - native_background_mode=["o4-mini-deep-research", "o3-deep-research"], - ) - - assert result is False - - def test_polling_disabled_for_native_background_mode_with_provider_list(self): - """Test that native_background_mode takes precedence even when provider matches""" - from litellm.proxy.response_polling.polling_handler import should_use_polling_for_request - - result = should_use_polling_for_request( - background_mode=True, - polling_via_cache_enabled=["openai"], - redis_cache=Mock(), - model="openai/o4-mini-deep-research", - llm_router=None, - native_background_mode=["openai/o4-mini-deep-research"], - ) - - assert result is False - - def test_polling_enabled_when_model_not_in_native_background_mode(self): - """Test that polling is enabled when model is not in native_background_mode list""" - from litellm.proxy.response_polling.polling_handler import should_use_polling_for_request - - result = should_use_polling_for_request( - background_mode=True, - polling_via_cache_enabled="all", - redis_cache=Mock(), - model="gpt-4o", - llm_router=None, - native_background_mode=["o4-mini-deep-research"], - ) - - assert result is True - - def test_polling_enabled_when_native_background_mode_is_none(self): - """Test that polling works normally when native_background_mode is None""" - from litellm.proxy.response_polling.polling_handler import should_use_polling_for_request - - result = should_use_polling_for_request( - background_mode=True, - polling_via_cache_enabled="all", - redis_cache=Mock(), - model="gpt-4o", - llm_router=None, - native_background_mode=None, - ) - - assert result is True - - def test_polling_enabled_when_native_background_mode_is_empty_list(self): - """Test that polling works normally when native_background_mode is empty list""" - from litellm.proxy.response_polling.polling_handler import should_use_polling_for_request - - result = should_use_polling_for_request( - background_mode=True, - polling_via_cache_enabled="all", - redis_cache=Mock(), - model="gpt-4o", - llm_router=None, - native_background_mode=[], - ) - - assert result is True - - def test_native_background_mode_exact_match_required(self): - """Test that native_background_mode uses exact model name matching""" - from litellm.proxy.response_polling.polling_handler import should_use_polling_for_request - - # "o4-mini" should not match "o4-mini-deep-research" - result = should_use_polling_for_request( - background_mode=True, - polling_via_cache_enabled="all", - redis_cache=Mock(), - model="o4-mini", - llm_router=None, - native_background_mode=["o4-mini-deep-research"], - ) - - assert result is True - - def test_native_background_mode_with_provider_prefix_in_request(self): - """Test native_background_mode matching when request model has provider prefix""" - from litellm.proxy.response_polling.polling_handler import should_use_polling_for_request - - # Model in native_background_mode without provider prefix - # Request comes in with provider prefix - should not match - result = should_use_polling_for_request( - background_mode=True, - polling_via_cache_enabled=["openai"], - redis_cache=Mock(), - model="openai/o4-mini-deep-research", - llm_router=None, - native_background_mode=["o4-mini-deep-research"], # Without prefix - ) - - # Should return True because "openai/o4-mini-deep-research" != "o4-mini-deep-research" - assert result is True - - def test_native_background_mode_with_router_lookup(self): - """Test that native_background_mode works with router-resolved models""" - from litellm.proxy.response_polling.polling_handler import should_use_polling_for_request - - mock_router = Mock() - mock_router.model_name_to_deployment_indices = {"deep-research": [0]} - mock_router.model_list = [ - { - "model_name": "deep-research", - "litellm_params": {"model": "openai/o4-mini-deep-research"} - } - ] - - # Model alias "deep-research" is in native_background_mode - result = should_use_polling_for_request( - background_mode=True, - polling_via_cache_enabled=["openai"], - redis_cache=Mock(), - model="deep-research", - llm_router=mock_router, - native_background_mode=["deep-research"], - ) - - assert result is False - class TestStreamingEventParsing: """ diff --git a/tests/proxy_unit_tests/test_server_root_path.py b/tests/proxy_unit_tests/test_server_root_path.py deleted file mode 100644 index 4b39558e15a..00000000000 --- a/tests/proxy_unit_tests/test_server_root_path.py +++ /dev/null @@ -1,64 +0,0 @@ -import os -from unittest import mock -from litellm.proxy import utils - - -# Test the utility function logic -def test_get_server_root_path_unset(): - """ - Test that get_server_root_path returns empty string when SERVER_ROOT_PATH is unset - """ - with mock.patch.dict(os.environ, {}, clear=True): - # We need to make sure SERVER_ROOT_PATH is not in env - if "SERVER_ROOT_PATH" in os.environ: - del os.environ["SERVER_ROOT_PATH"] - - root_path = utils.get_server_root_path() - assert ( - root_path == "" - ), "Should return empty string when unset to allow X-Forwarded-Prefix" - - -def test_get_server_root_path_set(): - """ - Test that get_server_root_path returns the value when SERVER_ROOT_PATH is set - """ - with mock.patch.dict(os.environ, {"SERVER_ROOT_PATH": "/my-path"}, clear=True): - root_path = utils.get_server_root_path() - assert root_path == "/my-path", "Should return the set value" - - -def test_get_server_root_path_empty_string(): - """ - Test that get_server_root_path returns empty string when SERVER_ROOT_PATH is explicitly empty - """ - with mock.patch.dict(os.environ, {"SERVER_ROOT_PATH": ""}, clear=True): - root_path = utils.get_server_root_path() - assert ( - root_path == "" - ), "Should return empty string when explicitly set to empty" - - -# Integration test simulation for FastAPI app initialization -def test_fastapi_app_initialization_mock(): - """ - Simulate how proxy_server.py initializes FastAPI app with the root_path. - We don't import proxy_server because it has global side effects/singletons. - Instead we verify the logic flow. - """ - from fastapi import FastAPI - - # CASE 1: Proxy Mode (Unset) - with mock.patch.dict(os.environ, {}, clear=True): - if "SERVER_ROOT_PATH" in os.environ: - del os.environ["SERVER_ROOT_PATH"] - - server_root_path = utils.get_server_root_path() - app = FastAPI(root_path=server_root_path) - assert app.root_path == "" - - # CASE 2: Direct Mode (Set) - with mock.patch.dict(os.environ, {"SERVER_ROOT_PATH": "/custom-root"}, clear=True): - server_root_path = utils.get_server_root_path() - app = FastAPI(root_path=server_root_path) - assert app.root_path == "/custom-root" diff --git a/tests/router_unit_tests/test_router_helper_utils.py b/tests/router_unit_tests/test_router_helper_utils.py index 673c606a7d1..073433cb9e5 100644 --- a/tests/router_unit_tests/test_router_helper_utils.py +++ b/tests/router_unit_tests/test_router_helper_utils.py @@ -2169,32 +2169,3 @@ def test_resolve_model_name_from_model_id(): result = router.resolve_model_name_from_model_id("gpt-3.5-turbo") assert result == "gpt-3.5-turbo" - - -def test_get_valid_args(): - """Test get_valid_args static method returns valid Router.__init__ arguments""" - # Call the static method - valid_args = Router.get_valid_args() - - # Verify it returns a list - assert isinstance(valid_args, list) - assert len(valid_args) > 0 - - # Verify it contains expected Router.__init__ arguments - expected_args = [ - "model_list", - "routing_strategy", - "cache_responses", - "num_retries", - "timeout", - "fallbacks", - ] - for arg in expected_args: - assert arg in valid_args, f"Expected argument '{arg}' not found in valid_args" - - # Verify "self" is not in the list (since it's removed) - assert "self" not in valid_args - - # Verify it contains keyword-only arguments too - # These are common Router.__init__ parameters - assert "assistants_config" in valid_args or "search_tools" in valid_args diff --git a/tests/test_litellm/a2a_protocol/test_card_resolver.py b/tests/test_litellm/a2a_protocol/test_card_resolver.py deleted file mode 100644 index a1bd33107b6..00000000000 --- a/tests/test_litellm/a2a_protocol/test_card_resolver.py +++ /dev/null @@ -1,69 +0,0 @@ -""" -Mock tests for LiteLLMA2ACardResolver. - -Tests that the card resolver tries both old and new well-known paths. -""" - -import sys -from unittest.mock import AsyncMock, MagicMock, patch - -import pytest - - -@pytest.mark.asyncio -async def test_card_resolver_fallback_from_new_to_old_path(): - """ - Test that the card resolver tries the new path (/.well-known/agent-card.json) first, - and falls back to the old path (/.well-known/agent.json) if the new path fails. - """ - # Mock the AgentCard - mock_agent_card = MagicMock() - mock_agent_card.name = "Test Agent" - mock_agent_card.description = "A test agent" - - # Track which paths were called - paths_called = [] - - # Create a mock base class - class MockA2ACardResolver: - def __init__(self, base_url): - self.base_url = base_url - - async def get_agent_card(self, relative_card_path=None, http_kwargs=None): - paths_called.append(relative_card_path) - if relative_card_path == "/.well-known/agent-card.json": - # First call (new path) fails - raise Exception("404 Not Found") - else: - # Second call (old path) succeeds - return mock_agent_card - - # Create mock A2A module - mock_a2a_module = MagicMock() - mock_a2a_client = MagicMock() - mock_a2a_constants = MagicMock() - mock_a2a_constants.AGENT_CARD_WELL_KNOWN_PATH = "/.well-known/agent-card.json" - mock_a2a_constants.PREV_AGENT_CARD_WELL_KNOWN_PATH = "/.well-known/agent.json" - - with patch.dict( - sys.modules, - { - "a2a": mock_a2a_module, - "a2a.client": MagicMock(A2ACardResolver=MockA2ACardResolver), - "a2a.utils.constants": mock_a2a_constants, - }, - ): - # Import after patching - from litellm.a2a_protocol.card_resolver import LiteLLMA2ACardResolver - - resolver = LiteLLMA2ACardResolver(base_url="http://test-agent:8000") - result = await resolver.get_agent_card() - - # Verify both paths were tried in correct order - assert len(paths_called) == 2 - assert paths_called[0] == "/.well-known/agent-card.json" # New path tried first - assert paths_called[1] == "/.well-known/agent.json" # Old path tried second - - # Verify the result - assert result == mock_agent_card - assert result.name == "Test Agent" diff --git a/tests/test_litellm/containers/test_container_api.py b/tests/test_litellm/containers/test_container_api.py index f489447ca99..c7bb68e79cb 100644 --- a/tests/test_litellm/containers/test_container_api.py +++ b/tests/test_litellm/containers/test_container_api.py @@ -166,55 +166,30 @@ async def test_alist_containers_basic(self): assert isinstance(response, ContainerListResponse) assert len(response.data) == 1 - @pytest.mark.parametrize( - "container_id,container_name,status,provider", - [ - ("cntr_retrieve_test", "Retrieved Container", "running", "openai"), - ("cntr_different_id", "Another Container", "stopped", "openai"), - ], - ) - def test_retrieve_container_basic(self, container_id, container_name, status, provider): - """Test basic container retrieval functionality. - - This test verifies that: - 1. retrieve_container correctly calls the handler with the container_id - 2. The response is properly deserialized into a ContainerObject - 3. All fields are correctly mapped from the handler response - 4. The function works with different container states and IDs - """ - # Arrange: Create mock response with test parameters + def test_retrieve_container_basic(self): + """Test basic container retrieval functionality.""" + container_id = "cntr_retrieve_test" mock_response = ContainerObject( id=container_id, object="container", created_at=1747857508, - status=status, + status="running", expires_after={"anchor": "last_active_at", "minutes": 20}, last_active_at=1747857508, - name=container_name + name="Retrieved Container" ) with patch('litellm.containers.main.base_llm_http_handler') as mock_handler: mock_handler.container_retrieve_handler.return_value = mock_response - # Act: Call retrieve_container response = retrieve_container( container_id=container_id, - custom_llm_provider=provider + custom_llm_provider="openai" ) - # Assert: Verify the handler was called correctly - mock_handler.container_retrieve_handler.assert_called_once() - call_kwargs = mock_handler.container_retrieve_handler.call_args.kwargs - assert call_kwargs["container_id"] == container_id - - # Assert: Verify response structure and content assert isinstance(response, ContainerObject) assert response.id == container_id - assert response.name == container_name - assert response.status == status - assert response.object == "container" - assert response.expires_after.minutes == 20 - assert response.expires_after.anchor == "last_active_at" + assert response.name == "Retrieved Container" @pytest.mark.asyncio async def test_aretrieve_container_basic(self): diff --git a/tests/test_litellm/containers/test_container_integration.py b/tests/test_litellm/containers/test_container_integration.py index d36918c63b9..e83ae921c19 100644 --- a/tests/test_litellm/containers/test_container_integration.py +++ b/tests/test_litellm/containers/test_container_integration.py @@ -357,15 +357,15 @@ def test_container_workflow_simulation(self): def test_error_handling_integration(self): """Test error handling in the integration flow.""" - # Simulate an API error - api_error = litellm.APIError( - status_code=400, - message="API Error occurred", - llm_provider="openai", - model="" - ) - - with patch.object(litellm.main.base_llm_http_handler, 'container_create_handler', side_effect=api_error): + with patch('litellm.containers.main.base_llm_http_handler') as mock_handler: + # Simulate an API error + mock_handler.container_create_handler.side_effect = litellm.APIError( + status_code=400, + message="API Error occurred", + llm_provider="openai", + model="" + ) + with pytest.raises(litellm.APIError): create_container( name="Error Test Container", @@ -385,12 +385,12 @@ def test_provider_support(self, provider): name="Provider Test Container" ) - with patch.object(litellm.main.base_llm_http_handler, 'container_create_handler', return_value=mock_response) as mock_handler: + with patch('litellm.containers.main.base_llm_http_handler') as mock_handler: + mock_handler.container_create_handler.return_value = mock_response + response = create_container( name="Provider Test Container", custom_llm_provider=provider ) assert response.name == "Provider Test Container" - # Verify the mock was actually called (not making real API calls) - mock_handler.assert_called_once() diff --git a/tests/test_litellm/enterprise/enterprise_callbacks/send_emails/test_resend_email.py b/tests/test_litellm/enterprise/enterprise_callbacks/send_emails/test_resend_email.py index 8db6d98f13d..dffa343d99f 100644 --- a/tests/test_litellm/enterprise/enterprise_callbacks/send_emails/test_resend_email.py +++ b/tests/test_litellm/enterprise/enterprise_callbacks/send_emails/test_resend_email.py @@ -2,9 +2,7 @@ import sys import unittest.mock as mock -import httpx import pytest -import respx from httpx import Response sys.path.insert(0, os.path.abspath("../../..")) @@ -13,8 +11,6 @@ ResendEmailLogger, ) -# Test file for Resend email integration - @pytest.fixture def mock_env_vars(): @@ -27,27 +23,21 @@ def mock_httpx_client(): with mock.patch( "litellm_enterprise.enterprise_callbacks.send_emails.resend_email.get_async_httpx_client" ) as mock_client: - - mock_response = mock.Mock(spec=Response) + # Create a mock response + mock_response = mock.AsyncMock(spec=Response) mock_response.status_code = 200 mock_response.json.return_value = {"id": "test_email_id"} - mock_response.raise_for_status.return_value = None + # Create a mock client mock_async_client = mock.AsyncMock() mock_async_client.post.return_value = mock_response - mock_client.return_value = mock_async_client + yield mock_async_client @pytest.mark.asyncio -@respx.mock async def test_send_email_success(mock_env_vars, mock_httpx_client): - # Block all HTTP requests at network level to prevent real API calls - respx.post("https://api.resend.com/emails").mock( - return_value=httpx.Response(200, json={"id": "test_email_id"}) - ) - # Initialize the logger logger = ResendEmailLogger() @@ -81,57 +71,33 @@ async def test_send_email_success(mock_env_vars, mock_httpx_client): @pytest.mark.asyncio -@respx.mock async def test_send_email_missing_api_key(mock_httpx_client): - # Block all HTTP requests at network level to prevent real API calls - respx.post("https://api.resend.com/emails").mock( - return_value=httpx.Response(200, json={"id": "test_email_id"}) - ) - - # Remove the API key from environment before initializing logger - original_key = os.environ.pop("RESEND_API_KEY", None) - - try: - # Initialize the logger after removing the API key - logger = ResendEmailLogger() - - # Test data - from_email = "test@example.com" - to_email = ["recipient@example.com"] - subject = "Test Subject" - html_body = "

    Test email body

    " - - # Mock the response to avoid making real HTTP requests - mock_response = mock.Mock(spec=Response) - mock_response.raise_for_status.return_value = None + # Remove the API key from environment + if "RESEND_API_KEY" in os.environ: + del os.environ["RESEND_API_KEY"] - mock_response.status_code = 200 - mock_response.json.return_value = {"id": "test_email_id"} - mock_httpx_client.post.return_value = mock_response + # Initialize the logger + logger = ResendEmailLogger() - # Send email - await logger.send_email( - from_email=from_email, to_email=to_email, subject=subject, html_body=html_body - ) + # Test data + from_email = "test@example.com" + to_email = ["recipient@example.com"] + subject = "Test Subject" + html_body = "

    Test email body

    " + + # Send email + await logger.send_email( + from_email=from_email, to_email=to_email, subject=subject, html_body=html_body + ) - # Verify the HTTP client was called with None as the API key - mock_httpx_client.post.assert_called_once() - call_args = mock_httpx_client.post.call_args - assert call_args[1]["headers"] == {"Authorization": "Bearer None"} - finally: - # Restore the original key if it existed - if original_key is not None: - os.environ["RESEND_API_KEY"] = original_key + # Verify the HTTP client was called with None as the API key + mock_httpx_client.post.assert_called_once() + call_args = mock_httpx_client.post.call_args + assert call_args[1]["headers"] == {"Authorization": "Bearer None"} @pytest.mark.asyncio -@respx.mock async def test_send_email_multiple_recipients(mock_env_vars, mock_httpx_client): - # Block all HTTP requests at network level to prevent real API calls - respx.post("https://api.resend.com/emails").mock( - return_value=httpx.Response(200, json={"id": "test_email_id"}) - ) - # Initialize the logger logger = ResendEmailLogger() @@ -141,14 +107,6 @@ async def test_send_email_multiple_recipients(mock_env_vars, mock_httpx_client): subject = "Test Subject" html_body = "

    Test email body

    " - # Mock the response to avoid making real HTTP requests - mock_response = mock.Mock(spec=Response) - mock_response.raise_for_status.return_value = None - - mock_response.status_code = 200 - mock_response.json.return_value = {"id": "test_email_id"} - mock_httpx_client.post.return_value = mock_response - # Send email await logger.send_email( from_email=from_email, to_email=to_email, subject=subject, html_body=html_body diff --git a/tests/test_litellm/enterprise/enterprise_callbacks/send_emails/test_sendgrid_email.py b/tests/test_litellm/enterprise/enterprise_callbacks/send_emails/test_sendgrid_email.py index 836b717bd6e..4ecb4872aaa 100644 --- a/tests/test_litellm/enterprise/enterprise_callbacks/send_emails/test_sendgrid_email.py +++ b/tests/test_litellm/enterprise/enterprise_callbacks/send_emails/test_sendgrid_email.py @@ -2,9 +2,7 @@ import sys import unittest.mock as mock -import httpx import pytest -import respx from httpx import Response sys.path.insert(0, os.path.abspath("../../..")) @@ -16,26 +14,8 @@ @pytest.fixture def mock_env_vars(): - # Store original values - original_api_key = os.environ.get("SENDGRID_API_KEY") - original_sender_email = os.environ.get("SENDGRID_SENDER_EMAIL") - - # Set test API key and remove SENDGRID_SENDER_EMAIL to ensure isolation - os.environ["SENDGRID_API_KEY"] = "test_api_key" - if "SENDGRID_SENDER_EMAIL" in os.environ: - del os.environ["SENDGRID_SENDER_EMAIL"] - - try: + with mock.patch.dict(os.environ, {"SENDGRID_API_KEY": "test_api_key"}): yield - finally: - # Restore original values - if original_api_key is not None: - os.environ["SENDGRID_API_KEY"] = original_api_key - elif "SENDGRID_API_KEY" in os.environ: - del os.environ["SENDGRID_API_KEY"] - - if original_sender_email is not None: - os.environ["SENDGRID_SENDER_EMAIL"] = original_sender_email @pytest.fixture @@ -43,16 +23,14 @@ def mock_httpx_client(): with mock.patch( "litellm_enterprise.enterprise_callbacks.send_emails.sendgrid_email.get_async_httpx_client" ) as mock_client: - - mock_response = mock.Mock(spec=Response) + mock_response = mock.AsyncMock(spec=Response) mock_response.status_code = 202 mock_response.text = "accepted" - mock_response.raise_for_status.return_value = None mock_async_client = mock.AsyncMock() mock_async_client.post.return_value = mock_response - mock_client.return_value = mock_async_client + yield mock_async_client @@ -84,10 +62,8 @@ async def test_send_email_success(mock_env_vars, mock_httpx_client): @pytest.mark.asyncio -async def test_send_email_missing_api_key(): - original_key = os.environ.pop("SENDGRID_API_KEY", None) - - try: +async def test_send_email_missing_api_key(mock_httpx_client): + with mock.patch.dict(os.environ, {}, clear=True): logger = SendGridEmailLogger() with pytest.raises(ValueError): @@ -97,19 +73,12 @@ async def test_send_email_missing_api_key(): subject="Test Subject", html_body="

    Test email body

    ", ) - finally: - if original_key is not None: - os.environ["SENDGRID_API_KEY"] = original_key + + mock_httpx_client.post.assert_not_called() @pytest.mark.asyncio -@respx.mock async def test_send_email_multiple_recipients(mock_env_vars, mock_httpx_client): - # Block all HTTP requests at network level to prevent real API calls - respx.post("https://api.sendgrid.com/v3/mail/send").mock( - return_value=httpx.Response(202, text="accepted") - ) - logger = SendGridEmailLogger() from_email = "test@example.com" @@ -117,12 +86,6 @@ async def test_send_email_multiple_recipients(mock_env_vars, mock_httpx_client): subject = "Test Subject" html_body = "

    Test email body

    " - mock_response = mock.Mock(spec=Response) - mock_response.status_code = 202 - mock_response.text = "accepted" - mock_response.raise_for_status.return_value = None - mock_httpx_client.post.return_value = mock_response - await logger.send_email( from_email=from_email, to_email=to_email, subject=subject, html_body=html_body ) diff --git a/tests/test_litellm/experimental_mcp_client/test_mcp_client.py b/tests/test_litellm/experimental_mcp_client/test_mcp_client.py index febc7c454bd..998f4156e93 100644 --- a/tests/test_litellm/experimental_mcp_client/test_mcp_client.py +++ b/tests/test_litellm/experimental_mcp_client/test_mcp_client.py @@ -52,19 +52,16 @@ async def test_mcp_client_stdio_connect_success( self, mock_session, mock_stdio_client ): """Test successful stdio connection""" - # Setup mocks - create proper async context manager + # Setup mocks mock_transport = (MagicMock(), MagicMock()) - mock_stdio_ctx = AsyncMock() - mock_stdio_ctx.__aenter__.return_value = mock_transport - mock_stdio_ctx.__aexit__.return_value = None - mock_stdio_client.return_value = mock_stdio_ctx + mock_stdio_client.return_value.__aenter__ = AsyncMock( + return_value=mock_transport + ) - mock_session_instance = AsyncMock() + mock_session_instance = MagicMock() + mock_session_instance.__aenter__ = AsyncMock(return_value=mock_session_instance) mock_session_instance.initialize = AsyncMock() - mock_session_ctx = AsyncMock() - mock_session_ctx.__aenter__.return_value = mock_session_instance - mock_session_ctx.__aexit__.return_value = None - mock_session.return_value = mock_session_ctx + mock_session.return_value = mock_session_instance stdio_config = MCPStdioConfig( command="python", args=["-m", "my_mcp_server"], env={"DEBUG": "1"} @@ -97,23 +94,22 @@ async def test_mcp_client_ssl_configuration_from_env( self, mock_streamable_http_client ): """Test that MCP client uses SSL configuration from environment variables""" - # Setup mocks - create proper async context manager + # Setup mocks mock_transport = (MagicMock(), MagicMock()) - mock_http_ctx = AsyncMock() - mock_http_ctx.__aenter__.return_value = mock_transport - mock_http_ctx.__aexit__.return_value = None - mock_streamable_http_client.return_value = mock_http_ctx + mock_streamable_http_client.return_value.__aenter__ = AsyncMock( + return_value=mock_transport + ) # Mock the session with patch( "litellm.experimental_mcp_client.client.ClientSession" ) as mock_session: - mock_session_instance = AsyncMock() + mock_session_instance = MagicMock() + mock_session_instance.__aenter__ = AsyncMock( + return_value=mock_session_instance + ) mock_session_instance.initialize = AsyncMock() - mock_session_ctx = AsyncMock() - mock_session_ctx.__aenter__.return_value = mock_session_instance - mock_session_ctx.__aexit__.return_value = None - mock_session.return_value = mock_session_ctx + mock_session.return_value = mock_session_instance client = MCPClient( server_url="https://mcp-server.example.com", @@ -145,23 +141,20 @@ async def _operation(session): @patch.object(mcp_client_module, "sse_client") async def test_mcp_client_ssl_verify_parameter(self, mock_sse_client): """Test that MCP client uses ssl_verify parameter when provided""" - # Setup mocks - create proper async context manager + # Setup mocks mock_transport = (MagicMock(), MagicMock()) - mock_sse_ctx = AsyncMock() - mock_sse_ctx.__aenter__.return_value = mock_transport - mock_sse_ctx.__aexit__.return_value = None - mock_sse_client.return_value = mock_sse_ctx + mock_sse_client.return_value.__aenter__ = AsyncMock(return_value=mock_transport) # Mock the session with patch( "litellm.experimental_mcp_client.client.ClientSession" ) as mock_session: - mock_session_instance = AsyncMock() + mock_session_instance = MagicMock() + mock_session_instance.__aenter__ = AsyncMock( + return_value=mock_session_instance + ) mock_session_instance.initialize = AsyncMock() - mock_session_ctx = AsyncMock() - mock_session_ctx.__aenter__.return_value = mock_session_instance - mock_session_ctx.__aexit__.return_value = None - mock_session.return_value = mock_session_ctx + mock_session.return_value = mock_session_instance # Test with ssl_verify=False client = MCPClient( @@ -199,23 +192,22 @@ async def _operation(session): @patch.object(mcp_client_module, "streamable_http_client") async def test_mcp_client_ssl_verify_custom_path(self, mock_streamable_http_client): """Test that MCP client uses custom CA bundle path from ssl_verify parameter""" - # Setup mocks - create proper async context manager + # Setup mocks mock_transport = (MagicMock(), MagicMock()) - mock_http_ctx = AsyncMock() - mock_http_ctx.__aenter__.return_value = mock_transport - mock_http_ctx.__aexit__.return_value = None - mock_streamable_http_client.return_value = mock_http_ctx + mock_streamable_http_client.return_value.__aenter__ = AsyncMock( + return_value=mock_transport + ) # Mock the session with patch( "litellm.experimental_mcp_client.client.ClientSession" ) as mock_session: - mock_session_instance = AsyncMock() + mock_session_instance = MagicMock() + mock_session_instance.__aenter__ = AsyncMock( + return_value=mock_session_instance + ) mock_session_instance.initialize = AsyncMock() - mock_session_ctx = AsyncMock() - mock_session_ctx.__aenter__.return_value = mock_session_instance - mock_session_ctx.__aexit__.return_value = None - mock_session.return_value = mock_session_ctx + mock_session.return_value = mock_session_instance # Test with custom CA bundle path custom_ca_path = "/custom/path/to/ca-bundle.pem" diff --git a/tests/test_litellm/google_genai/test_google_genai_adapter.py b/tests/test_litellm/google_genai/test_google_genai_adapter.py index 05b22098371..a5333550992 100644 --- a/tests/test_litellm/google_genai/test_google_genai_adapter.py +++ b/tests/test_litellm/google_genai/test_google_genai_adapter.py @@ -1090,8 +1090,8 @@ async def test_google_generate_content_with_openai(): usage=mock_usage ) - # Use AsyncMock for proper async function mocking - patch at the module level where it's imported - with unittest.mock.patch("litellm.google_genai.main.litellm.acompletion", new_callable=unittest.mock.AsyncMock) as mock_completion: + # Use AsyncMock for proper async function mocking + with unittest.mock.patch("litellm.acompletion", new_callable=unittest.mock.AsyncMock) as mock_completion: # Set the return value directly on the MagicMock mock_completion.return_value = mock_response diff --git a/tests/test_litellm/google_genai/test_google_genai_handler.py b/tests/test_litellm/google_genai/test_google_genai_handler.py index fc120280511..89b53ca06d5 100644 --- a/tests/test_litellm/google_genai/test_google_genai_handler.py +++ b/tests/test_litellm/google_genai/test_google_genai_handler.py @@ -25,7 +25,7 @@ def test_non_stream_response_when_stream_requested_sync(): the sync handler correctly transforms it to generate_content format. """ from litellm.types.utils import Choices - + # Mock a non-stream response (ModelResponse with valid choices) mock_response = ModelResponse( id="test-123", @@ -70,7 +70,7 @@ async def test_non_stream_response_when_stream_requested_async(): the async handler correctly transforms it to generate_content format. """ from litellm.types.utils import Choices - + # Mock a non-stream response (ModelResponse with valid choices) mock_response = ModelResponse( id="test-123", @@ -183,10 +183,7 @@ def test_stream_transformation_error_sync(): "translate_completion_output_params_streaming", return_value=None ): - # Mock litellm.completion at the module level where it's imported - # We need to patch it in the handler module, not in litellm itself - with patch("litellm.google_genai.adapters.handler.litellm") as mock_litellm: - mock_litellm.completion.return_value = mock_stream + with patch("litellm.completion", return_value=mock_stream): # Call the handler with stream=True and expect a ValueError with pytest.raises(ValueError, match="Failed to transform streaming response"): GenerateContentToCompletionHandler.generate_content_handler( @@ -212,11 +209,7 @@ async def test_stream_transformation_error_async(): "translate_completion_output_params_streaming", return_value=None ): - # Mock litellm.acompletion at the module level where it's imported - # We need to patch it in the handler module, not in litellm itself - with patch("litellm.google_genai.adapters.handler.litellm") as mock_litellm: - # Use AsyncMock for async function - mock_litellm.acompletion = AsyncMock(return_value=mock_stream) + with patch("litellm.acompletion", return_value=mock_stream): # Call the handler with stream=True and expect a ValueError with pytest.raises(ValueError, match="Failed to transform streaming response"): await GenerateContentToCompletionHandler.async_generate_content_handler( @@ -232,13 +225,11 @@ def test_citation_metadata_transformation(): Test that citationMetadata.citationSources is properly transformed to citationMetadata.citations to avoid Pydantic validation errors. """ + from litellm.llms.gemini.google_genai.transformation import GoogleGenAIConfig + from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj from unittest.mock import MagicMock - import httpx - - from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj - from litellm.llms.gemini.google_genai.transformation import GoogleGenAIConfig - + # Create a mock response with citationMetadata.citationSources (the problematic format) mock_response_data = { "candidates": [ diff --git a/tests/test_litellm/integrations/arize/test_arize_utils.py b/tests/test_litellm/integrations/arize/test_arize_utils.py index 9a9f3d5afc7..6eb6e67a088 100644 --- a/tests/test_litellm/integrations/arize/test_arize_utils.py +++ b/tests/test_litellm/integrations/arize/test_arize_utils.py @@ -84,7 +84,7 @@ def test_arize_set_attributes(): ArizeLogger.set_arize_attributes(span, kwargs, response_obj) # Validate that the expected number of attributes were set - assert span.set_attribute.call_count == 26 + assert span.set_attribute.call_count == 28 # Metadata attached to the span span.set_attribute.assert_any_call( @@ -108,8 +108,7 @@ def test_arize_set_attributes(): # Response metadata span.set_attribute.assert_any_call("llm.response.id", "chatcmpl-ID") span.set_attribute.assert_any_call("llm.response.model", "gpt-4o") - # Span kind is set to TOOL when tools are present - span.set_attribute.assert_any_call(SpanAttributes.OPENINFERENCE_SPAN_KIND, "TOOL") + span.set_attribute.assert_any_call(SpanAttributes.OPENINFERENCE_SPAN_KIND, "LLM") # Request message content and metadata span.set_attribute.assert_any_call( @@ -126,14 +125,14 @@ def test_arize_set_attributes(): # Tool call definitions and function names span.set_attribute.assert_any_call( - f"{SpanAttributes.LLM_TOOLS}.0.name", "get_weather" + f"{SpanAttributes.LLM_TOOLS}.0.{SpanAttributes.TOOL_NAME}", "get_weather" ) span.set_attribute.assert_any_call( - f"{SpanAttributes.LLM_TOOLS}.0.description", + f"{SpanAttributes.LLM_TOOLS}.0.{SpanAttributes.TOOL_DESCRIPTION}", "Fetches weather details.", ) span.set_attribute.assert_any_call( - f"{SpanAttributes.LLM_TOOLS}.0.parameters", + f"{SpanAttributes.LLM_TOOLS}.0.{SpanAttributes.TOOL_PARAMETERS}", json.dumps( { "type": "object", @@ -145,6 +144,16 @@ def test_arize_set_attributes(): ), ) + # Tool calls captured from optional_params + span.set_attribute.assert_any_call( + f"{MessageAttributes.MESSAGE_TOOL_CALLS}.0.{ToolCallAttributes.TOOL_CALL_FUNCTION_NAME}", + "get_weather", + ) + span.set_attribute.assert_any_call( + f"{MessageAttributes.MESSAGE_TOOL_CALLS}.1.{ToolCallAttributes.TOOL_CALL_FUNCTION_NAME}", + "get_stock_price", + ) + # Invocation parameters span.set_attribute.assert_any_call( SpanAttributes.LLM_INVOCATION_PARAMETERS, '{"user": "test_user"}' diff --git a/tests/test_litellm/integrations/datadog/test_datadog_cost_management.py b/tests/test_litellm/integrations/datadog/test_datadog_cost_management.py deleted file mode 100644 index be2084969a5..00000000000 --- a/tests/test_litellm/integrations/datadog/test_datadog_cost_management.py +++ /dev/null @@ -1,169 +0,0 @@ -import os -import time -from unittest.mock import AsyncMock - -import pytest -from httpx import Response - -from litellm.integrations.datadog.datadog_cost_management import ( - DatadogCostManagementLogger, -) -from litellm.types.utils import StandardLoggingPayload - - -@pytest.fixture -def clean_env(): - # Save original env - original_api_key = os.environ.get("DD_API_KEY") - original_app_key = os.environ.get("DD_APP_KEY") - original_site = os.environ.get("DD_SITE") - - # Set test env - os.environ["DD_API_KEY"] = "test_api_key" - os.environ["DD_APP_KEY"] = "test_app_key" - os.environ["DD_SITE"] = "test.datadoghq.com" - - yield - - # Restore original env - if original_api_key: - os.environ["DD_API_KEY"] = original_api_key - else: - del os.environ["DD_API_KEY"] - - if original_app_key: - os.environ["DD_APP_KEY"] = original_app_key - else: - del os.environ["DD_APP_KEY"] - - if original_site: - os.environ["DD_SITE"] = original_site - else: - del os.environ["DD_SITE"] - - -@pytest.mark.asyncio -async def test_init(clean_env): - """ - Test initialization sets up clients and url correctly - """ - logger = DatadogCostManagementLogger() - assert logger.dd_api_key == "test_api_key" - assert logger.dd_app_key == "test_app_key" - assert ( - logger.upload_url == "https://api.test.datadoghq.com/api/v2/cost/custom_costs" - ) - - -@pytest.mark.asyncio -async def test_aggregate_costs(clean_env): - """ - Test that costs are correctly aggregated by provider, model, and date - """ - logger = DatadogCostManagementLogger() - - # Mock some log payloads - now = time.time() - day_str = time.strftime("%Y-%m-%d", time.localtime(now)) - - logs = [ - StandardLoggingPayload( - custom_llm_provider="openai", - model="gpt-4", - response_cost=0.01, - startTime=now, - metadata={"user_api_key_team_alias": "team-a"}, - ), - StandardLoggingPayload( - custom_llm_provider="openai", - model="gpt-4", - response_cost=0.02, - startTime=now, - metadata={"user_api_key_team_alias": "team-a"}, - ), - StandardLoggingPayload( - custom_llm_provider="anthropic", - model="claude-3", - response_cost=0.05, - startTime=now, - ), - ] - - aggregated = logger._aggregate_costs(logs) - - assert len(aggregated) == 2 - - # Check OpenAI entry - openai_entry = next(e for e in aggregated if e["ProviderName"] == "openai") - assert openai_entry["BilledCost"] == 0.03 - assert openai_entry["ChargeDescription"] == "LLM Usage for gpt-4" - assert openai_entry["ChargePeriodStart"] == day_str - assert openai_entry["Tags"]["team"] == "team-a" - assert "env" in openai_entry["Tags"] - assert "service" in openai_entry["Tags"] - - # Check Anthropic entry - anthropic_entry = next(e for e in aggregated if e["ProviderName"] == "anthropic") - assert anthropic_entry["BilledCost"] == 0.05 - - -@pytest.mark.asyncio -async def test_async_log_success_event(clean_env): - """ - Test that logs are added to queue - """ - logger = DatadogCostManagementLogger(batch_size=10) - - await logger.async_log_success_event( - kwargs={"standard_logging_object": {"response_cost": 0.01}}, - response_obj={}, - start_time=time.time(), - end_time=time.time(), - ) - - assert len(logger.log_queue) == 1 - assert logger.log_queue[0]["response_cost"] == 0.01 - - # Test zero cost ignored - await logger.async_log_success_event( - kwargs={"standard_logging_object": {"response_cost": 0.0}}, - response_obj={}, - start_time=time.time(), - end_time=time.time(), - ) - - assert len(logger.log_queue) == 1 - - -@pytest.mark.asyncio -async def test_async_send_batch(clean_env): - """ - Test that batch is aggregated and uploaded - """ - logger = DatadogCostManagementLogger() - logger.async_client = AsyncMock() - logger.async_client.put.return_value = Response(202, json={"status": "ok"}) - - # Add logs directly to queue - logger.log_queue = [ - StandardLoggingPayload( - custom_llm_provider="openai", - model="gpt-4", - response_cost=0.01, - startTime=time.time(), - ) - ] - - await logger.async_send_batch() - - # Verify API called - assert logger.async_client.put.called - call_args = logger.async_client.put.call_args - assert call_args[0][0] == "https://api.test.datadoghq.com/api/v2/cost/custom_costs" - - import json - - # Use call_args.kwargs['content'] - content = json.loads(call_args[1]["content"]) - assert content[0]["ProviderName"] == "openai" - assert content[0]["BilledCost"] == 0.01 diff --git a/tests/test_litellm/integrations/datadog/test_datadog_llm_obs_agent.py b/tests/test_litellm/integrations/datadog/test_datadog_llm_obs_agent.py deleted file mode 100644 index 2bb51e1e1b7..00000000000 --- a/tests/test_litellm/integrations/datadog/test_datadog_llm_obs_agent.py +++ /dev/null @@ -1,62 +0,0 @@ -import os -from unittest.mock import patch -from litellm.integrations.datadog.datadog_llm_obs import DataDogLLMObsLogger - - -def test_datadog_llm_obs_agent_configuration(): - """ - Test that DataDog LLM Obs logger correctly configures agent endpoint. - """ - test_env = { - "LITELLM_DD_AGENT_HOST": "localhost", - "LITELLM_DD_LLM_OBS_PORT": "10518", - "DD_API_KEY": "test-api-key", # Optional, but checking if it's preserved - } - - # Ensure DD_SITE is NOT set to verify we don't need it in agent mode - - with patch.dict(os.environ, test_env, clear=True): - with patch("asyncio.create_task"): # Prevent periodic flush task from running - dd_logger = DataDogLLMObsLogger() - - expected_url = "http://localhost:10518/api/intake/llm-obs/v1/trace/spans" - assert dd_logger.intake_url == expected_url - assert dd_logger.DD_API_KEY == "test-api-key" - - -def test_datadog_llm_obs_agent_no_api_key_ok(): - """ - Test that agent mode works WITHOUT DD_API_KEY (agent handles auth). - """ - test_env = { - "LITELLM_DD_AGENT_HOST": "localhost", - # No DD_API_KEY - } - - with patch.dict(os.environ, test_env, clear=True): - with patch("asyncio.create_task"): - # Should NOT raise exception anymore - dd_logger = DataDogLLMObsLogger() - - assert dd_logger.DD_API_KEY is None - # Default port is 8126 if not set - expected_url = "http://localhost:8126/api/intake/llm-obs/v1/trace/spans" - assert dd_logger.intake_url == expected_url - - -def test_datadog_llm_obs_direct_api_configuration(): - """ - Test that direct API configuration still works as expected. - """ - test_env = { - "DD_API_KEY": "direct-api-key", - "DD_SITE": "us5.datadoghq.com", - } - - with patch.dict(os.environ, test_env, clear=True): - with patch("asyncio.create_task"): - dd_logger = DataDogLLMObsLogger() - - expected_url = "https://api.us5.datadoghq.com/api/intake/llm-obs/v1/trace/spans" - assert dd_logger.intake_url == expected_url - assert dd_logger.DD_API_KEY == "direct-api-key" diff --git a/tests/test_litellm/integrations/test_custom_guardrail_recursion.py b/tests/test_litellm/integrations/test_custom_guardrail_recursion.py deleted file mode 100644 index f05b5848bdf..00000000000 --- a/tests/test_litellm/integrations/test_custom_guardrail_recursion.py +++ /dev/null @@ -1,73 +0,0 @@ -import pytest -from litellm.integrations.custom_guardrail import CustomGuardrail -from litellm.types.guardrails import GuardrailEventHooks -import json - - -class TestCustomGuardrailRecursion: - """ - Specific tests for the circular reference / RecursionError fix in logging. - """ - - def test_log_guardrail_information_handles_circular_references(self): - """ - Test that add_standard_logging method sanitizes input data containing circular references - instead of crashing. - - This reproduces the Langfuse crash scenario: - Request -> Metadata -> GuardrailResponse -> DebugContext -> Request - """ - guardrail = CustomGuardrail( - guardrail_name="recursion_test_guardrail", - event_hook=GuardrailEventHooks.pre_call, - ) - - # 1. Setup Circular Data - request_data = {"user_id": "test_recursive_user"} - metadata = {"session_id": "123"} - request_data["metadata"] = metadata - - # Create the danger: Guardrail Response holding a reference back to request_data - dirty_response = { - "flagged": False, - "debug_context": request_data, # <--- ACCESS TO ROOT (Circular Ref) - } - - # 2. Invoke the logging method - # If the fix is working, this will NOT raise RecursionError - try: - guardrail.add_standard_logging_guardrail_information_to_request_data( - guardrail_json_response=dirty_response, - request_data=request_data, - guardrail_status="success", - start_time=1.0, - end_time=2.0, - duration=1.0, - masked_entity_count={}, - event_type=GuardrailEventHooks.pre_call, - ) - except RecursionError: - pytest.fail( - "RecursionError raised! The cyclic reference sanitization failed." - ) - - # 3. Verify the data stored is safe - stored_info = request_data["metadata"][ - "standard_logging_guardrail_information" - ][0] - stored_response = stored_info["guardrail_response"] - - # Check that we can dump it to JSON without crashing (Ultimate proof) - try: - json.dumps(stored_response) - except Exception as e: - pytest.fail(f"Stored data is not JSON serializable: {e}") - - # Check content - keys should be preserved but recursion broken - assert "debug_context" in stored_response - debug_context = stored_response["debug_context"] - - # In a sanitized copy, the nested metadata should be a copy, not the original live dict - assert debug_context["user_id"] == "test_recursive_user" - # The 'metadata' inside 'debug_context' would be where recursion stops or is filtered - assert "metadata" in debug_context diff --git a/tests/test_litellm/integrations/test_prometheus_client_ip_user_agent.py b/tests/test_litellm/integrations/test_prometheus_client_ip_user_agent.py deleted file mode 100644 index 4a9fa3de5fd..00000000000 --- a/tests/test_litellm/integrations/test_prometheus_client_ip_user_agent.py +++ /dev/null @@ -1,203 +0,0 @@ -import pytest -from unittest.mock import MagicMock, patch -from litellm.integrations.prometheus import PrometheusLogger -from litellm.types.integrations.prometheus import ( - UserAPIKeyLabelValues, -) -from litellm.proxy._types import UserAPIKeyAuth - - -@pytest.mark.asyncio -async def test_async_post_call_failure_hook_includes_client_ip_user_agent(): - """ - Test that async_post_call_failure_hook includes client_ip and user_agent in UserAPIKeyLabelValues - """ - # Mocking - # Mocking - with patch( - "litellm.integrations.prometheus.PrometheusLogger.__init__", return_value=None - ): - logger = PrometheusLogger() - # Initialize attributes manually as __init__ is mocked - logger.litellm_proxy_failed_requests_metric = MagicMock() - logger.litellm_proxy_total_requests_metric = MagicMock() - logger.get_labels_for_metric = MagicMock( - return_value=["client_ip", "user_agent"] - ) - - request_data = { - "model": "gpt-4", - "metadata": { - "requester_ip_address": "127.0.0.1", - "user_agent": "test-agent", - }, - } - user_api_key_dict = UserAPIKeyAuth(token="test_token") - original_exception = Exception("Test exception") - - # Mock prometheus_label_factory to inspect arguments - with patch( - "litellm.integrations.prometheus.prometheus_label_factory" - ) as mock_label_factory: - mock_label_factory.return_value = {} - - await logger.async_post_call_failure_hook( - request_data=request_data, - original_exception=original_exception, - user_api_key_dict=user_api_key_dict, - ) - - # Verification - assert mock_label_factory.call_count >= 1 - - # Check calls - calls = mock_label_factory.call_args_list - found = False - for call in calls: - kwargs = call.kwargs - enum_values = kwargs.get("enum_values") - if isinstance(enum_values, UserAPIKeyLabelValues): - if ( - enum_values.client_ip == "127.0.0.1" - and enum_values.user_agent == "test-agent" - ): - found = True - break - - assert ( - found - ), "UserAPIKeyLabelValues should contain client_ip='127.0.0.1' and user_agent='test-agent'" - - -@pytest.mark.asyncio -async def test_async_post_call_success_hook_includes_client_ip_user_agent(): - """ - Test that async_post_call_success_hook includes client_ip and user_agent in UserAPIKeyLabelValues - """ - # Mocking - # Mocking - with patch( - "litellm.integrations.prometheus.PrometheusLogger.__init__", return_value=None - ): - logger = PrometheusLogger() - logger.litellm_proxy_total_requests_metric = MagicMock() - logger.get_labels_for_metric = MagicMock( - return_value=["client_ip", "user_agent"] - ) - - data = { - "model": "gpt-4", - "metadata": { - "requester_ip_address": "192.168.1.1", - "user_agent": "success-agent", - }, - } - user_api_key_dict = UserAPIKeyAuth(token="test_token") - response = MagicMock() - - # Mock prometheus_label_factory to inspect arguments - with patch( - "litellm.integrations.prometheus.prometheus_label_factory" - ) as mock_label_factory: - mock_label_factory.return_value = {} - - await logger.async_post_call_success_hook( - data=data, - user_api_key_dict=user_api_key_dict, - response=response, - ) - - # Verification - assert mock_label_factory.call_count >= 1 - - # Check calls - calls = mock_label_factory.call_args_list - found = False - for call in calls: - kwargs = call.kwargs - enum_values = kwargs.get("enum_values") - if isinstance(enum_values, UserAPIKeyLabelValues): - if ( - enum_values.client_ip == "192.168.1.1" - and enum_values.user_agent == "success-agent" - ): - found = True - break - - assert ( - found - ), "UserAPIKeyLabelValues should contain client_ip='192.168.1.1' and user_agent='success-agent'" - - -def test_set_llm_deployment_failure_metrics_includes_client_ip_user_agent(): - """ - Test that set_llm_deployment_failure_metrics includes client_ip and user_agent in UserAPIKeyLabelValues - """ - # Mocking - # Mocking - with patch( - "litellm.integrations.prometheus.PrometheusLogger.__init__", return_value=None - ): - logger = PrometheusLogger() - logger.litellm_deployment_failure_responses = MagicMock() - logger.litellm_deployment_total_requests = MagicMock() - logger.get_labels_for_metric = MagicMock( - return_value=["client_ip", "user_agent"] - ) - logger.set_deployment_partial_outage = MagicMock() - - request_kwargs = { - "model": "gpt-4", - "standard_logging_object": { - "metadata": { - "requester_ip_address": "10.0.0.1", - "user_agent": "failure-deployment", - "user_api_key_team_id": "team_1", - "user_api_key_team_alias": "team_alias_1", - "user_api_key_alias": "key_alias_1", - }, - "model_group": "group_1", - "api_base": "http://api.base", - "model_id": "model_1", - }, - "litellm_params": {}, - "exception": Exception("Deployment failure"), - } - - # Mock prometheus_label_factory to inspect arguments - with patch( - "litellm.integrations.prometheus.prometheus_label_factory" - ) as mock_label_factory: - mock_label_factory.return_value = {} - - logger.set_llm_deployment_failure_metrics(request_kwargs=request_kwargs) - - # Verification - assert mock_label_factory.call_count >= 1 - - # Check calls - calls = mock_label_factory.call_args_list - found = False - for call in calls: - kwargs = call.kwargs - enum_values = kwargs.get("enum_values") - if isinstance(enum_values, UserAPIKeyLabelValues): - if ( - enum_values.client_ip == "10.0.0.1" - and enum_values.user_agent == "failure-deployment" - ): - found = True - break - - assert ( - found - ), "UserAPIKeyLabelValues should contain client_ip='10.0.0.1' and user_agent='failure-deployment'" - - -if __name__ == "__main__": - import asyncio - - asyncio.run(test_async_post_call_failure_hook_includes_client_ip_user_agent()) - asyncio.run(test_async_post_call_success_hook_includes_client_ip_user_agent()) - test_set_llm_deployment_failure_metrics_includes_client_ip_user_agent() - print("✅ All client_ip and user_agent tests passed!") diff --git a/tests/test_litellm/integrations/test_prometheus_labels.py b/tests/test_litellm/integrations/test_prometheus_labels.py index 9d4626b88a5..c0b863ef6ee 100644 --- a/tests/test_litellm/integrations/test_prometheus_labels.py +++ b/tests/test_litellm/integrations/test_prometheus_labels.py @@ -26,49 +26,15 @@ def test_user_email_in_required_metrics(): "litellm_input_tokens_metric", "litellm_output_tokens_metric", "litellm_requests_metric", - "litellm_spend_metric", + "litellm_spend_metric" ] for metric_name in metrics_with_user_email: labels = PrometheusMetricLabels.get_labels(metric_name) - assert ( - user_email_label in labels - ), f"Metric {metric_name} should contain user_email label" + assert user_email_label in labels, f"Metric {metric_name} should contain user_email label" print(f"✅ {metric_name} contains user_email label") -def test_model_id_in_required_metrics(): - """ - Test that model_id label is present in all the metrics that should have it - """ - model_id_label = UserAPIKeyLabelNames.MODEL_ID.value - - # Metrics that should have model_id - metrics_with_model_id = [ - "litellm_proxy_total_requests_metric", - "litellm_proxy_failed_requests_metric", - "litellm_input_tokens_metric", - "litellm_output_tokens_metric", - "litellm_requests_metric", - "litellm_spend_metric", - "litellm_llm_api_latency_metric", - "litellm_remaining_requests_metric", - "litellm_deployment_successful_fallbacks", - "litellm_cache_hits_metric", - "litellm_cache_misses_metric", - "litellm_remaining_api_key_requests_for_model", - "litellm_remaining_api_key_tokens_for_model", - "litellm_llm_api_failed_requests_metric", - ] - - for metric_name in metrics_with_model_id: - labels = PrometheusMetricLabels.get_labels(metric_name) - assert ( - model_id_label in labels - ), f"Metric {metric_name} should contain model_id label" - print(f"✅ {metric_name} contains model_id label") - - def test_user_email_label_exists(): """Test that the USER_EMAIL label is properly defined""" assert UserAPIKeyLabelNames.USER_EMAIL.value == "user_email" @@ -86,14 +52,12 @@ def test_prometheus_metric_labels_structure(): "litellm_proxy_failed_requests_metric", "litellm_input_tokens_metric", "litellm_output_tokens_metric", - "litellm_spend_metric", + "litellm_spend_metric" ] for metric_name in test_metrics: # Check metric is in DEFINED_PROMETHEUS_METRICS - assert metric_name in get_args( - DEFINED_PROMETHEUS_METRICS - ), f"{metric_name} should be in DEFINED_PROMETHEUS_METRICS" + assert metric_name in get_args(DEFINED_PROMETHEUS_METRICS), f"{metric_name} should be in DEFINED_PROMETHEUS_METRICS" # Check labels can be retrieved labels = PrometheusMetricLabels.get_labels(metric_name) @@ -106,39 +70,15 @@ def test_prometheus_metric_labels_structure(): print(f"✅ {metric_name} has proper label structure with user_email") -def test_model_id_in_required_metrics(): - """ - Test that model_id label is present in all the metrics that should have it: - - litellm_proxy_total_requests_metric - - litellm_proxy_failed_requests_metric - - litellm_request_total_latency_metric - - litellm_llm_api_time_to_first_token_metric - """ - model_id_label = UserAPIKeyLabelNames.MODEL_ID.value - - # Metrics that should have model_id - metrics_with_model_id = [ - "litellm_proxy_total_requests_metric", - "litellm_proxy_failed_requests_metric", - "litellm_request_total_latency_metric", - "litellm_llm_api_time_to_first_token_metric" - ] - - for metric_name in metrics_with_model_id: - labels = PrometheusMetricLabels.get_labels(metric_name) - assert model_id_label in labels, f"Metric {metric_name} should contain model_id label" - print(f"✅ {metric_name} contains model_id label") - - def test_route_normalization_for_responses_api(): """ Test that route normalization prevents high cardinality in Prometheus metrics for the /v1/responses/{response_id} endpoint. - + Issue: https://github.com/BerriAI/litellm/issues/XXXX Each unique response ID was creating a separate metric line, causing the /metrics endpoint to grow to ~30MB and take ~40 seconds to respond. - + Fix: Routes are normalized to collapse dynamic IDs into placeholders. """ from litellm.proxy.auth.auth_utils import normalize_request_route @@ -151,53 +91,43 @@ def test_route_normalization_for_responses_api(): ("/v1/responses/resp_abc123", "/v1/responses/{response_id}"), ("/v1/responses/litellm_poll_xyz", "/v1/responses/{response_id}"), ] - + for original, expected in responses_routes: normalized = normalize_request_route(original) - assert ( - normalized == expected - ), f"Failed: {original} -> {normalized} (expected {expected})" - + assert normalized == expected, \ + f"Failed: {original} -> {normalized} (expected {expected})" + # Verify cardinality reduction - unique_normalized = set( - normalize_request_route(route) for route, _ in responses_routes - ) - assert ( - len(unique_normalized) == 1 - ), f"Expected 1 unique normalized route, got {len(unique_normalized)}: {unique_normalized}" - - print( - f"✅ Responses API routes: {len(responses_routes)} different IDs normalized to 1 metric label" - ) - + unique_normalized = set(normalize_request_route(route) for route, _ in responses_routes) + assert len(unique_normalized) == 1, \ + f"Expected 1 unique normalized route, got {len(unique_normalized)}: {unique_normalized}" + + print(f"✅ Responses API routes: {len(responses_routes)} different IDs normalized to 1 metric label") + def test_route_normalization_for_sub_routes(): """Test that sub-routes like /cancel and /input_items are normalized correctly""" from litellm.proxy.auth.auth_utils import normalize_request_route - + sub_routes = [ ("/v1/responses/id1/cancel", "/v1/responses/{response_id}/cancel"), ("/v1/responses/id2/cancel", "/v1/responses/{response_id}/cancel"), ("/v1/responses/id3/input_items", "/v1/responses/{response_id}/input_items"), - ( - "/openai/v1/responses/id4/input_items", - "/openai/v1/responses/{response_id}/input_items", - ), + ("/openai/v1/responses/id4/input_items", "/openai/v1/responses/{response_id}/input_items"), ] - + for original, expected in sub_routes: normalized = normalize_request_route(original) - assert ( - normalized == expected - ), f"Failed: {original} -> {normalized} (expected {expected})" - + assert normalized == expected, \ + f"Failed: {original} -> {normalized} (expected {expected})" + print("✅ Sub-routes normalized correctly") def test_route_normalization_preserves_static_routes(): """Test that static routes are not affected by normalization""" from litellm.proxy.auth.auth_utils import normalize_request_route - + static_routes = [ "/chat/completions", "/v1/chat/completions", @@ -207,47 +137,46 @@ def test_route_normalization_preserves_static_routes(): "/v1/models", "/v1/responses", # List endpoint without ID ] - + for route in static_routes: normalized = normalize_request_route(route) - assert ( - normalized == route - ), f"Static route should not be modified: {route} -> {normalized}" - + assert normalized == route, \ + f"Static route should not be modified: {route} -> {normalized}" + print(f"✅ {len(static_routes)} static routes preserved") def test_route_normalization_other_dynamic_apis(): """Test normalization for other OpenAI-compatible APIs with dynamic IDs""" from litellm.proxy.auth.auth_utils import normalize_request_route - + test_cases = [ # Threads API ("/v1/threads/thread_123", "/v1/threads/{thread_id}"), ("/v1/threads/thread_abc/messages", "/v1/threads/{thread_id}/messages"), - ( - "/v1/threads/thread_abc/runs/run_123", - "/v1/threads/{thread_id}/runs/{run_id}", - ), + ("/v1/threads/thread_abc/runs/run_123", "/v1/threads/{thread_id}/runs/{run_id}"), + # Vector Stores API ("/v1/vector_stores/vs_123", "/v1/vector_stores/{vector_store_id}"), ("/v1/vector_stores/vs_123/files", "/v1/vector_stores/{vector_store_id}/files"), + # Assistants API ("/v1/assistants/asst_123", "/v1/assistants/{assistant_id}"), + # Files API ("/v1/files/file_123", "/v1/files/{file_id}"), ("/v1/files/file_123/content", "/v1/files/{file_id}/content"), + # Batches API ("/v1/batches/batch_123", "/v1/batches/{batch_id}"), ("/v1/batches/batch_123/cancel", "/v1/batches/{batch_id}/cancel"), ] - + for original, expected in test_cases: normalized = normalize_request_route(original) - assert ( - normalized == expected - ), f"Failed: {original} -> {normalized} (expected {expected})" - + assert normalized == expected, \ + f"Failed: {original} -> {normalized} (expected {expected})" + print(f"✅ {len(test_cases)} other API routes normalized correctly") @@ -266,29 +195,26 @@ def test_prometheus_metrics_use_normalized_routes(): # Create a mock PrometheusLogger prometheus_logger = MagicMock() - prometheus_logger.get_labels_for_metric = ( - PrometheusLogger.get_labels_for_metric.__get__(prometheus_logger) - ) - + prometheus_logger.get_labels_for_metric = PrometheusLogger.get_labels_for_metric.__get__(prometheus_logger) + # Test with a normalized route enum_values = UserAPIKeyLabelValues( route="/v1/responses/{response_id}", # Normalized route status_code="200", requested_model="gpt-4", ) - + labels = prometheus_label_factory( supported_enum_labels=prometheus_logger.get_labels_for_metric( metric_name="litellm_proxy_total_requests_metric" ), enum_values=enum_values, ) - + # Verify the route is normalized in labels - assert ( - labels["route"] == "/v1/responses/{response_id}" - ), f"Expected normalized route in labels, got: {labels.get('route')}" - + assert labels["route"] == "/v1/responses/{response_id}", \ + f"Expected normalized route in labels, got: {labels.get('route')}" + print("✅ Prometheus metrics use normalized routes in labels") @@ -301,4 +227,4 @@ def test_prometheus_metrics_use_normalized_routes(): test_route_normalization_preserves_static_routes() test_route_normalization_other_dynamic_apis() test_prometheus_metrics_use_normalized_routes() - print("\n✅ All prometheus label tests passed!") + print("\n✅ All prometheus label tests passed!") \ No newline at end of file diff --git a/tests/test_litellm/integrations/test_prometheus_missing_metrics.py b/tests/test_litellm/integrations/test_prometheus_missing_metrics.py deleted file mode 100644 index 7fcfb21ed4c..00000000000 --- a/tests/test_litellm/integrations/test_prometheus_missing_metrics.py +++ /dev/null @@ -1,77 +0,0 @@ -""" -Unit tests for the new Prometheus metrics that were previously missing from validation. - -Tests for: -- litellm_remaining_api_key_requests_for_model -- litellm_remaining_api_key_tokens_for_model -- litellm_callback_logging_failures_metric -""" -from typing import get_args -from litellm.types.integrations.prometheus import ( - DEFINED_PROMETHEUS_METRICS, - PrometheusMetricLabels, - UserAPIKeyLabelNames, -) - - -def test_new_metrics_in_defined_metrics(): - """ - Test that the new metrics are present in DEFINED_PROMETHEUS_METRICS. - """ - defined_metrics = get_args(DEFINED_PROMETHEUS_METRICS) - - new_metrics = [ - "litellm_remaining_api_key_requests_for_model", - "litellm_remaining_api_key_tokens_for_model", - "litellm_callback_logging_failures_metric", - ] - - for metric in new_metrics: - assert ( - metric in defined_metrics - ), f"{metric} should be in DEFINED_PROMETHEUS_METRICS" - - -def test_new_metrics_have_correct_labels(): - """ - Test that the new metrics have the correct labels defined. - """ - # Test API Key limits metrics labels - api_key_metrics = [ - "litellm_remaining_api_key_requests_for_model", - "litellm_remaining_api_key_tokens_for_model", - ] - - expected_api_key_labels = [ - UserAPIKeyLabelNames.API_KEY_HASH.value, - UserAPIKeyLabelNames.API_KEY_ALIAS.value, - UserAPIKeyLabelNames.v1_LITELLM_MODEL_NAME.value, - ] - - for metric in api_key_metrics: - labels = PrometheusMetricLabels.get_labels(metric) - for expected_label in expected_api_key_labels: - assert ( - expected_label in labels - ), f"{metric} should have label {expected_label}" - - # Test Callback failure metric labels - callback_metric = "litellm_callback_logging_failures_metric" - callback_labels = PrometheusMetricLabels.get_labels(callback_metric) - - assert ( - UserAPIKeyLabelNames.CALLBACK_NAME.value in callback_labels - ), f"{callback_metric} should have label {UserAPIKeyLabelNames.CALLBACK_NAME.value}" - - -def test_callback_name_label_definition(): - """ - Test that CALLBACK_NAME is defined correctly in UserAPIKeyLabelNames. - """ - assert UserAPIKeyLabelNames.CALLBACK_NAME.value == "callback_name" - - -if __name__ == "__main__": - test_new_metrics_in_defined_metrics() - test_new_metrics_have_correct_labels() - test_callback_name_label_definition() diff --git a/tests/test_litellm/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_factory.py b/tests/test_litellm/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_factory.py index e87233a52a3..a22fe13798f 100644 --- a/tests/test_litellm/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_factory.py +++ b/tests/test_litellm/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_factory.py @@ -1138,73 +1138,6 @@ def test_bedrock_create_bedrock_block_different_document_formats(): assert block["document"]["name"].endswith(f"_{format_type}") assert block["document"]["format"] == format_type -def test_bedrock_nova_web_search_options_mapping(): - """ - Test that web_search_options is correctly mapped to Nova grounding. - - This follows the LiteLLM pattern for web search where: - - Vertex AI maps web_search_options to {"googleSearch": {}} - - Anthropic maps web_search_options to {"type": "web_search_20250305", ...} - - Nova should map web_search_options to {"systemTool": {"name": "nova_grounding"}} - """ - from litellm.llms.bedrock.chat.converse_transformation import AmazonConverseConfig - - config = AmazonConverseConfig() - - # Test basic mapping for Nova model - result = config._map_web_search_options({}, "amazon.nova-pro-v1:0") - - assert result is not None - system_tool = result.get("systemTool") - assert system_tool is not None - assert system_tool["name"] == "nova_grounding" - - # Test with search_context_size (should be ignored for Nova) - result2 = config._map_web_search_options( - {"search_context_size": "high"}, - "us.amazon.nova-premier-v1:0" - ) - - assert result2 is not None - system_tool2 = result2.get("systemTool") - assert system_tool2 is not None - assert system_tool2["name"] == "nova_grounding" - # Nova doesn't support search_context_size, so it's just ignored - -def test_bedrock_tools_pt_does_not_handle_system_tool(): - """ - Verify that _bedrock_tools_pt does NOT handle system_tool format. - - System tools (nova_grounding) should be added via web_search_options, - not via the tools parameter directly. - """ - - from litellm.litellm_core_utils.prompt_templates.factory import _bedrock_tools_pt - - # Regular function tools should still work - tools = [ - { - "type": "function", - "function": { - "name": "get_weather", - "description": "Get the current weather", - "parameters": { - "type": "object", - "properties": { - "location": {"type": "string"} - }, - "required": ["location"] - } - } - } - ] - - result = _bedrock_tools_pt(tools=tools) - - assert len(result) == 1 - tool_spec = result[0].get("toolSpec") - assert tool_spec is not None - assert tool_spec["name"] == "get_weather" def test_convert_to_anthropic_tool_result_image_with_cache_control(): """ @@ -1372,12 +1305,12 @@ def test_convert_to_anthropic_tool_result_image_url_as_http(): assert result["content"][0]["cache_control"]["type"] == "ephemeral" def test_anthropic_messages_pt_server_tool_use_passthrough(): """ - Test that anthropic_messages_pt passes through server_tool_use and + Test that anthropic_messages_pt passes through server_tool_use and tool_search_tool_result blocks in assistant message content. - + These are Anthropic-native content types used for tool search functionality that need to be preserved when reconstructing multi-turn conversations. - + Fixes: https://github.com/BerriAI/litellm/issues/XXXXX """ from litellm.litellm_core_utils.prompt_templates.factory import anthropic_messages_pt @@ -1426,15 +1359,15 @@ def test_anthropic_messages_pt_server_tool_use_passthrough(): # Verify we have 3 messages (user, assistant, user) assert len(result) == 3 - + # Verify the assistant message content assistant_msg = result[1] assert assistant_msg["role"] == "assistant" assert isinstance(assistant_msg["content"], list) - + # Find the different content block types content_types = [block.get("type") for block in assistant_msg["content"]] - + # Verify server_tool_use block is preserved assert "server_tool_use" in content_types server_tool_use_block = next( @@ -1443,7 +1376,7 @@ def test_anthropic_messages_pt_server_tool_use_passthrough(): assert server_tool_use_block["id"] == "srvtoolu_01ABC123" assert server_tool_use_block["name"] == "tool_search_tool_regex" assert server_tool_use_block["input"] == {"query": ".*time.*"} - + # Verify tool_search_tool_result block is preserved assert "tool_search_tool_result" in content_types tool_result_block = next( @@ -1452,7 +1385,7 @@ def test_anthropic_messages_pt_server_tool_use_passthrough(): assert tool_result_block["tool_use_id"] == "srvtoolu_01ABC123" assert tool_result_block["content"]["type"] == "tool_search_tool_search_result" assert tool_result_block["content"]["tool_references"][0]["tool_name"] == "get_time" - + # Verify text block is also preserved assert "text" in content_types text_block = next( diff --git a/tests/test_litellm/litellm_core_utils/test_image_handling.py b/tests/test_litellm/litellm_core_utils/test_image_handling.py index 9c2939b2da5..b15d75a4145 100644 --- a/tests/test_litellm/litellm_core_utils/test_image_handling.py +++ b/tests/test_litellm/litellm_core_utils/test_image_handling.py @@ -66,41 +66,6 @@ def get(self, url, follow_redirects=True): ) -class StreamingLargeImageClient: - """ - Client that streams a large image to test streaming download protection. - This simulates a huge file without actually creating it all in memory. - """ - - def __init__(self, size_mb=100, include_content_length=False): - self.size_mb = size_mb - self.include_content_length = include_content_length - - def get(self, url, follow_redirects=True): - size_bytes = int(self.size_mb * 1024 * 1024) - headers = {"Content-Type": "image/jpeg"} - if self.include_content_length: - headers["Content-Length"] = str(size_bytes) - - # Create a generator that yields chunks without creating the whole file in memory - def generate_chunks(total_size, chunk_size=8192): - bytes_sent = 0 - while bytes_sent < total_size: - chunk = b"x" * min(chunk_size, total_size - bytes_sent) - bytes_sent += len(chunk) - yield chunk - - # Create response with streaming content - response = Response( - status_code=200, - headers=headers, - request=Request("GET", url), - ) - # Mock the iter_bytes method to return our generator - response.iter_bytes = lambda chunk_size=8192: generate_chunks(size_bytes, chunk_size) - return response - - def test_image_exceeds_size_limit_with_content_length(monkeypatch): """ Test that images exceeding MAX_IMAGE_URL_DOWNLOAD_SIZE_MB are rejected when Content-Length header is present. @@ -118,7 +83,6 @@ def test_image_exceeds_size_limit_with_content_length(monkeypatch): def test_image_exceeds_size_limit_without_content_length(monkeypatch): """ Test that images exceeding MAX_IMAGE_URL_DOWNLOAD_SIZE_MB are rejected even without Content-Length header. - This uses the old non-streaming mock for backward compatibility. """ monkeypatch.setattr( litellm, "module_level_client", LargeImageClient(size_mb=100, include_content_length=False) @@ -130,29 +94,6 @@ def test_image_exceeds_size_limit_without_content_length(monkeypatch): assert "exceeds maximum allowed size" in str(excinfo.value) -def test_streaming_download_protects_against_huge_files(monkeypatch): - """ - Test that streaming download aborts early when file exceeds size limit, - preventing memory exhaustion from huge files (e.g., petabyte-sized files). - - This test verifies that the streaming implementation doesn't download the entire - file into memory before checking size. Instead, it should abort as soon as the - limit is exceeded during streaming. - """ - # Simulate a 1GB file - far larger than the 50MB default limit - client = StreamingLargeImageClient(size_mb=1024, include_content_length=False) - monkeypatch.setattr(litellm, "module_level_client", client) - - with pytest.raises(litellm.ImageFetchError) as excinfo: - convert_url_to_base64("https://example.com/huge-image.jpg") - - # Verify the error message shows it was caught during streaming - assert "exceeds maximum allowed size" in str(excinfo.value) - - # The error should be raised after downloading just slightly more than the limit - # not after downloading the full 1GB - - class SmallImageClient: """ Client that returns a small valid image. @@ -183,26 +124,6 @@ def test_image_within_size_limit(monkeypatch): assert result.startswith("data:image/jpeg;base64,") -def test_streaming_download_handles_petabyte_file(monkeypatch): - """ - Test that streaming download can handle extremely large file URLs (e.g., petabyte-sized) - without attempting to download the entire file or causing memory exhaustion. - - This simulates what happens if a malicious actor or misconfiguration provides - a URL to an extremely large file. - """ - # Simulate a 1 petabyte file (1,000,000 GB) - # Without streaming protection, this would cause OOM or hang indefinitely - client = StreamingLargeImageClient(size_mb=1_000_000_000, include_content_length=False) - monkeypatch.setattr(litellm, "module_level_client", client) - - with pytest.raises(litellm.ImageFetchError) as excinfo: - convert_url_to_base64("https://example.com/petabyte-file.jpg") - - # Should fail fast without downloading anywhere near 1 petabyte - assert "exceeds maximum allowed size" in str(excinfo.value) - - def test_image_size_limit_disabled(monkeypatch): """ Test that setting MAX_IMAGE_URL_DOWNLOAD_SIZE_MB to 0 disables all image URL downloads. diff --git a/tests/test_litellm/litellm_core_utils/test_litellm_logging.py b/tests/test_litellm/litellm_core_utils/test_litellm_logging.py index 1f3f558a498..e035e193fe1 100644 --- a/tests/test_litellm/litellm_core_utils/test_litellm_logging.py +++ b/tests/test_litellm/litellm_core_utils/test_litellm_logging.py @@ -787,13 +787,11 @@ def test_get_masked_values(): "presidio_ad_hoc_recognizers": None, "aws_bedrock_runtime_endpoint": None, "presidio_anonymizer_api_base": None, - "vertex_credentials": "{sensitive_api_key}", } masked_values = _get_masked_values( sensitive_object, unmasked_length=4, number_of_asterisks=4 ) assert masked_values["presidio_anonymizer_api_base"] is None - assert masked_values["vertex_credentials"] == "{s****y}" @pytest.mark.asyncio diff --git a/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py b/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py index eee0b267fad..7e96c4634fd 100644 --- a/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py +++ b/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py @@ -548,59 +548,6 @@ def test_map_tool_choice_dict_type_function_with_name(): assert result["name"] == "my_tool" -def test_map_tool_choice_dict_type_auto(): - """ - Test that dict {"type": "auto"} maps to Anthropic type='auto'. - This handles Cursor's format for tool_choice. - """ - config = AnthropicConfig() - result = config._map_tool_choice( - tool_choice={"type": "auto"}, - parallel_tool_use=None, - ) - assert result is not None - assert result["type"] == "auto" - - -def test_map_tool_choice_dict_type_required(): - """ - Test that dict {"type": "required"} maps to Anthropic type='any'. - """ - config = AnthropicConfig() - result = config._map_tool_choice( - tool_choice={"type": "required"}, - parallel_tool_use=None, - ) - assert result is not None - assert result["type"] == "any" - - -def test_map_tool_choice_dict_type_none(): - """ - Test that dict {"type": "none"} maps to Anthropic type='none'. - """ - config = AnthropicConfig() - result = config._map_tool_choice( - tool_choice={"type": "none"}, - parallel_tool_use=None, - ) - assert result is not None - assert result["type"] == "none" - - -def test_map_tool_choice_dict_type_function_without_name(): - """ - Test that dict {"type": "function"} without name is handled gracefully. - Should return None since there's no valid tool name. - """ - config = AnthropicConfig() - result = config._map_tool_choice( - tool_choice={"type": "function"}, - parallel_tool_use=None, - ) - assert result is None - - def test_transform_response_with_prefix_prompt(): import httpx @@ -1895,7 +1842,7 @@ def test_calculate_usage_completion_tokens_details_always_populated(): # completion_tokens_details should NOT be None assert usage.completion_tokens_details is not None - assert usage.completion_tokens_details.reasoning_tokens is 0 + assert usage.completion_tokens_details.reasoning_tokens is None assert usage.completion_tokens_details.text_tokens == 248 assert usage.completion_tokens == 248 assert usage.prompt_tokens == 37 diff --git a/tests/test_litellm/llms/anthropic/experimental_pass_through/adapters/test_anthropic_experimental_pass_through_adapters_transformation.py b/tests/test_litellm/llms/anthropic/experimental_pass_through/adapters/test_anthropic_experimental_pass_through_adapters_transformation.py index c26d057fbf1..6aadbc058d1 100644 --- a/tests/test_litellm/llms/anthropic/experimental_pass_through/adapters/test_anthropic_experimental_pass_through_adapters_transformation.py +++ b/tests/test_litellm/llms/anthropic/experimental_pass_through/adapters/test_anthropic_experimental_pass_through_adapters_transformation.py @@ -1108,309 +1108,3 @@ def test_streaming_chunk_with_both_text_and_tool_calls_issue_18238(): assert block_type == "tool_use" assert content_block_start["name"] == "Bash" assert content_block_start["id"] == "toolu_bdrk_013xRVejhv3ybmLEGCoZib2b" - - -# ============================================================================ -# Cache Control Transformation Tests -# ============================================================================ - -# Model constant for cache control tests -CACHE_CONTROL_BEDROCK_CONVERSE_MODEL = "bedrock/converse/global.anthropic.claude-opus-4-5-20251101-v1:0" -CACHE_CONTROL_NON_ANTHROPIC_MODEL = "gpt-4" - - -def test_should_add_cache_control_for_anthropic_model(): - """Should add cache_control to target for Anthropic Claude models.""" - adapter = LiteLLMAnthropicMessagesAdapter() - cache_control = {"type": "ephemeral"} - - for model in [ - CACHE_CONTROL_BEDROCK_CONVERSE_MODEL, - "anthropic/claude-sonnet-4-5", - "claude-opus-4-5-20251101", - "vertex_ai/claude-3-sonnet@20240229", - ]: - target = {} - adapter._add_cache_control_if_applicable({"cache_control": cache_control}, target, model) - assert "cache_control" in target - assert target["cache_control"] == cache_control - - -def test_should_not_add_cache_control_for_non_anthropic_model(): - """Should not add cache_control for non-Anthropic models.""" - adapter = LiteLLMAnthropicMessagesAdapter() - cache_control = {"type": "ephemeral"} - - for model in [CACHE_CONTROL_NON_ANTHROPIC_MODEL, "openai/gpt-4-turbo", "gemini-pro"]: - target = {} - adapter._add_cache_control_if_applicable({"cache_control": cache_control}, target, model) - assert "cache_control" not in target - - -def test_should_not_add_cache_control_when_none(): - """Should not add cache_control when source has None or empty cache_control.""" - adapter = LiteLLMAnthropicMessagesAdapter() - - for source in [{"cache_control": None}, {"cache_control": {}}, {"cache_control": ""}, {}]: - target = {} - adapter._add_cache_control_if_applicable(source, target, CACHE_CONTROL_BEDROCK_CONVERSE_MODEL) - assert "cache_control" not in target - - -def test_should_not_add_cache_control_when_model_none(): - """Should not add cache_control when model is None or empty.""" - adapter = LiteLLMAnthropicMessagesAdapter() - cache_control = {"type": "ephemeral"} - - for model in [None, ""]: - target = {} - adapter._add_cache_control_if_applicable({"cache_control": cache_control}, target, model) - assert "cache_control" not in target - - -def test_cache_control_preserved_in_text_content_for_claude(): - """Cache control should be preserved in text content for Claude models.""" - anthropic_messages = [ - AnthropicMessagesUserMessageParam( - role="user", - content=[ - { - "type": "text", - "text": "This is cached content", - "cache_control": {"type": "ephemeral"}, - } - ], - ) - ] - - adapter = LiteLLMAnthropicMessagesAdapter() - result = adapter.translate_anthropic_messages_to_openai( - messages=anthropic_messages, model=CACHE_CONTROL_BEDROCK_CONVERSE_MODEL - ) - - assert len(result) == 1 - assert result[0]["content"][0]["cache_control"] == {"type": "ephemeral"} - - -def test_cache_control_not_preserved_for_non_claude_model(): - """Cache control should NOT be preserved for non-Claude models.""" - anthropic_messages = [ - AnthropicMessagesUserMessageParam( - role="user", - content=[ - { - "type": "text", - "text": "This is cached content", - "cache_control": {"type": "ephemeral"}, - } - ], - ) - ] - - adapter = LiteLLMAnthropicMessagesAdapter() - result = adapter.translate_anthropic_messages_to_openai( - messages=anthropic_messages, model=CACHE_CONTROL_NON_ANTHROPIC_MODEL - ) - - assert len(result) == 1 - assert "cache_control" not in result[0]["content"][0] - - -def test_cache_control_preserved_in_image_content_for_claude(): - """Cache control should be preserved in image content for Claude models.""" - anthropic_messages = [ - AnthropicMessagesUserMessageParam( - role="user", - content=[ - { - "type": "image", - "source": { - "type": "base64", - "media_type": "image/png", - "data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==", - }, - "cache_control": {"type": "ephemeral"}, - } - ], - ) - ] - - adapter = LiteLLMAnthropicMessagesAdapter() - result = adapter.translate_anthropic_messages_to_openai( - messages=anthropic_messages, model=CACHE_CONTROL_BEDROCK_CONVERSE_MODEL - ) - - assert len(result) == 1 - assert result[0]["content"][0]["cache_control"] == {"type": "ephemeral"} - - -def test_cache_control_preserved_in_document_content_for_claude(): - """Cache control should be preserved in document content for Claude models.""" - anthropic_messages = [ - AnthropicMessagesUserMessageParam( - role="user", - content=[ - { - "type": "document", - "source": { - "type": "base64", - "media_type": "application/pdf", - "data": "JVBERi0xLjQKJeLjz9MK", - }, - "cache_control": {"type": "ephemeral"}, - } - ], - ) - ] - - adapter = LiteLLMAnthropicMessagesAdapter() - result = adapter.translate_anthropic_messages_to_openai( - messages=anthropic_messages, model=CACHE_CONTROL_BEDROCK_CONVERSE_MODEL - ) - - assert len(result) == 1 - assert result[0]["content"][0]["cache_control"] == {"type": "ephemeral"} - - -def test_cache_control_preserved_in_tool_result_for_claude(): - """Cache control should be preserved in tool_result for Claude models.""" - anthropic_messages = [ - AnthropicMessagesUserMessageParam( - role="user", - content=[ - { - "type": "tool_result", - "tool_use_id": "toolu_01234", - "content": "Tool result content", - "cache_control": {"type": "ephemeral"}, - } - ], - ) - ] - - adapter = LiteLLMAnthropicMessagesAdapter() - result = adapter.translate_anthropic_messages_to_openai( - messages=anthropic_messages, model=CACHE_CONTROL_BEDROCK_CONVERSE_MODEL - ) - - tool_message = next(msg for msg in result if msg.get("role") == "tool") - assert tool_message["cache_control"] == {"type": "ephemeral"} - - -def test_cache_control_not_preserved_in_tool_result_for_non_claude(): - """Cache control should NOT be preserved in tool_result for non-Claude models.""" - anthropic_messages = [ - AnthropicMessagesUserMessageParam( - role="user", - content=[ - { - "type": "tool_result", - "tool_use_id": "toolu_01234", - "content": "Tool result content", - "cache_control": {"type": "ephemeral"}, - } - ], - ) - ] - - adapter = LiteLLMAnthropicMessagesAdapter() - result = adapter.translate_anthropic_messages_to_openai( - messages=anthropic_messages, model=CACHE_CONTROL_NON_ANTHROPIC_MODEL - ) - - tool_message = next(msg for msg in result if msg.get("role") == "tool") - assert "cache_control" not in tool_message - - -def test_cache_control_preserved_in_assistant_text_for_claude(): - """Cache control should be preserved in assistant text blocks for Claude models.""" - anthropic_messages = [ - AnthopicMessagesAssistantMessageParam( - role="assistant", - content=[ - { - "type": "text", - "text": "Assistant response", - "cache_control": {"type": "ephemeral"}, - } - ], - ) - ] - - adapter = LiteLLMAnthropicMessagesAdapter() - result = adapter.translate_anthropic_messages_to_openai( - messages=anthropic_messages, model=CACHE_CONTROL_BEDROCK_CONVERSE_MODEL - ) - - assert len(result) == 1 - assert result[0]["role"] == "assistant" - # When cache_control is present, content should be a list - assert isinstance(result[0]["content"], list) - assert result[0]["content"][0]["cache_control"] == {"type": "ephemeral"} - - -def test_cache_control_preserved_in_tool_use_for_claude(): - """Cache control should be preserved in tool_use blocks for Claude models.""" - anthropic_messages = [ - AnthopicMessagesAssistantMessageParam( - role="assistant", - content=[ - { - "type": "tool_use", - "id": "toolu_01234", - "name": "get_weather", - "input": {"location": "Boston"}, - "cache_control": {"type": "ephemeral"}, - } - ], - ) - ] - - adapter = LiteLLMAnthropicMessagesAdapter() - result = adapter.translate_anthropic_messages_to_openai( - messages=anthropic_messages, model=CACHE_CONTROL_BEDROCK_CONVERSE_MODEL - ) - - assert len(result) == 1 - assert "tool_calls" in result[0] - assert result[0]["tool_calls"][0]["cache_control"] == {"type": "ephemeral"} - - -def test_cache_control_preserved_in_tools_for_claude(): - """Cache control should be preserved in tools for Claude models.""" - tools = [ - { - "name": "get_weather", - "description": "Get weather for a location", - "input_schema": {"type": "object", "properties": {"location": {"type": "string"}}}, - "cache_control": {"type": "ephemeral"}, - } - ] - - adapter = LiteLLMAnthropicMessagesAdapter() - result = adapter.translate_anthropic_tools_to_openai( - tools=tools, model=CACHE_CONTROL_BEDROCK_CONVERSE_MODEL - ) - - assert len(result) == 1 - assert result[0]["cache_control"] == {"type": "ephemeral"} - - -def test_cache_control_not_preserved_in_tools_for_non_claude(): - """Cache control should NOT be preserved in tools for non-Claude models.""" - tools = [ - { - "name": "get_weather", - "description": "Get weather for a location", - "input_schema": {"type": "object", "properties": {"location": {"type": "string"}}}, - "cache_control": {"type": "ephemeral"}, - } - ] - - adapter = LiteLLMAnthropicMessagesAdapter() - result = adapter.translate_anthropic_tools_to_openai( - tools=tools, model=CACHE_CONTROL_NON_ANTHROPIC_MODEL - ) - - assert len(result) == 1 - assert "cache_control" not in result[0] diff --git a/tests/test_litellm/llms/azure/chat/test_azure_gpt5_transformation.py b/tests/test_litellm/llms/azure/chat/test_azure_gpt5_transformation.py index 25f3d1364f6..199a16d8590 100644 --- a/tests/test_litellm/llms/azure/chat/test_azure_gpt5_transformation.py +++ b/tests/test_litellm/llms/azure/chat/test_azure_gpt5_transformation.py @@ -16,17 +16,6 @@ def test_azure_gpt5_supports_reasoning_effort(config: AzureOpenAIGPT5Config): ) -def test_azure_gpt5_allows_tool_choice_for_deployment_names(): - supported_params = litellm.get_supported_openai_params( - model="gpt-5-chat-2025-08-07", custom_llm_provider="azure" - ) - assert supported_params is not None - assert "tool_choice" in supported_params - # gpt-5-chat* should not be treated as a GPT-5 reasoning model - assert "reasoning_effort" not in supported_params - assert "temperature" in supported_params - - def test_azure_gpt5_maps_max_tokens(config: AzureOpenAIGPT5Config): params = config.map_openai_params( non_default_params={"max_tokens": 5}, diff --git a/tests/test_litellm/llms/bedrock/chat/invoke_transformations/test_bedrock_chat_invoke_transformations_anthropic_claude3_transformation.py b/tests/test_litellm/llms/bedrock/chat/invoke_transformations/test_bedrock_chat_invoke_transformations_anthropic_claude3_transformation.py index 5c1b4cbd38e..1cb84d32c1d 100644 --- a/tests/test_litellm/llms/bedrock/chat/invoke_transformations/test_bedrock_chat_invoke_transformations_anthropic_claude3_transformation.py +++ b/tests/test_litellm/llms/bedrock/chat/invoke_transformations/test_bedrock_chat_invoke_transformations_anthropic_claude3_transformation.py @@ -279,293 +279,3 @@ def test_output_format_with_no_schema(): # Content should remain as string (not converted to list) assert isinstance(last_user_message["content"], str) assert last_user_message["content"] == "Hello" - - -def test_advanced_tool_use_header_translation_for_opus_4_5(): - """ - Test that advanced-tool-use-2025-11-20 header is translated to Bedrock-specific headers - for Claude Opus 4.5. - - Regression test for: Claude Code sends advanced-tool-use header which needs to be - translated to tool-search-tool-2025-10-19 and tool-examples-2025-10-29 for Bedrock - Invoke API on Claude Opus 4.5. - - Ref: https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages-request-response.html - """ - from litellm.llms.bedrock.messages.invoke_transformations.anthropic_claude3_transformation import ( - AmazonAnthropicClaudeMessagesConfig, - ) - - config = AmazonAnthropicClaudeMessagesConfig() - - messages = [ - {"role": "user", "content": "What's the weather like?"} - ] - - anthropic_messages_optional_request_params = { - "max_tokens": 100, - } - - # Simulate advanced-tool-use header from Claude Code - headers = { - "anthropic-beta": "advanced-tool-use-2025-11-20" - } - - # Test with Claude Opus 4.5 - result = config.transform_anthropic_messages_request( - model="anthropic.claude-opus-4-5-20250514-v1:0", - messages=messages, - anthropic_messages_optional_request_params=anthropic_messages_optional_request_params, - litellm_params={}, - headers=headers, - ) - - # Verify advanced-tool-use header was removed - assert "anthropic_beta" in result - beta_headers = result["anthropic_beta"] - assert "advanced-tool-use-2025-11-20" not in beta_headers, \ - "advanced-tool-use header should be removed for Bedrock" - - # Verify Bedrock-specific headers were added - assert "tool-search-tool-2025-10-19" in beta_headers, \ - "tool-search-tool-2025-10-19 should be added for Opus 4.5" - assert "tool-examples-2025-10-29" in beta_headers, \ - "tool-examples-2025-10-29 should be added for Opus 4.5" - - -def test_advanced_tool_use_header_filtered_for_non_opus_4_5(): - """ - Test that advanced-tool-use-2025-11-20 header is filtered out for non-Opus 4.5 models - without adding Bedrock-specific headers. - - The translation to tool-search-tool-2025-10-19 and tool-examples-2025-10-29 should - only happen for Claude Opus 4.5. - """ - from litellm.llms.bedrock.messages.invoke_transformations.anthropic_claude3_transformation import ( - AmazonAnthropicClaudeMessagesConfig, - ) - - config = AmazonAnthropicClaudeMessagesConfig() - - messages = [ - {"role": "user", "content": "What's the weather like?"} - ] - - anthropic_messages_optional_request_params = { - "max_tokens": 100, - } - - # Simulate advanced-tool-use header from Claude Code - headers = { - "anthropic-beta": "advanced-tool-use-2025-11-20" - } - - # Test with Claude Sonnet 4.5 (not Opus 4.5) - result = config.transform_anthropic_messages_request( - model="anthropic.claude-sonnet-4-5-20250929-v1:0", - messages=messages, - anthropic_messages_optional_request_params=anthropic_messages_optional_request_params, - litellm_params={}, - headers=headers, - ) - - # Verify advanced-tool-use header was removed - beta_headers = result.get("anthropic_beta", []) - assert "advanced-tool-use-2025-11-20" not in beta_headers, \ - "advanced-tool-use header should be removed for Bedrock" - - # Verify Bedrock-specific headers were NOT added (only for Opus 4.5) - assert "tool-search-tool-2025-10-19" not in beta_headers, \ - "tool-search-tool should not be added for non-Opus 4.5 models" - assert "tool-examples-2025-10-29" not in beta_headers, \ - "tool-examples should not be added for non-Opus 4.5 models" - - -def test_advanced_tool_use_header_translation_with_multiple_beta_headers(): - """ - Test that advanced-tool-use header translation works correctly when multiple - beta headers are present. - """ - from litellm.llms.bedrock.messages.invoke_transformations.anthropic_claude3_transformation import ( - AmazonAnthropicClaudeMessagesConfig, - ) - - config = AmazonAnthropicClaudeMessagesConfig() - - messages = [ - {"role": "user", "content": "What's the weather like?"} - ] - - anthropic_messages_optional_request_params = { - "max_tokens": 100, - } - - # Multiple beta headers including advanced-tool-use - headers = { - "anthropic-beta": "claude-code-20250219,advanced-tool-use-2025-11-20,interleaved-thinking-2025-05-14" - } - - # Test with Claude Opus 4.5 - result = config.transform_anthropic_messages_request( - model="anthropic.claude-opus-4-5-20250514-v1:0", - messages=messages, - anthropic_messages_optional_request_params=anthropic_messages_optional_request_params, - litellm_params={}, - headers=headers, - ) - - beta_headers = result.get("anthropic_beta", []) - - # Verify advanced-tool-use was removed - assert "advanced-tool-use-2025-11-20" not in beta_headers - - # Verify Bedrock-specific headers were added - assert "tool-search-tool-2025-10-19" in beta_headers - assert "tool-examples-2025-10-29" in beta_headers - - # Verify other beta headers are preserved - assert "claude-code-20250219" in beta_headers - assert "interleaved-thinking-2025-05-14" in beta_headers - - -def test_opus_4_5_model_detection(): - """ - Test that the _is_claude_opus_4_5 method correctly identifies Opus 4.5 models - with various naming conventions. - """ - from litellm.llms.bedrock.messages.invoke_transformations.anthropic_claude3_transformation import ( - AmazonAnthropicClaudeMessagesConfig, - ) - - config = AmazonAnthropicClaudeMessagesConfig() - - # Test various Opus 4.5 naming patterns - opus_4_5_models = [ - "anthropic.claude-opus-4-5-20250514-v1:0", - "anthropic.claude-opus-4.5-20250514-v1:0", - "anthropic.claude-opus_4_5-20250514-v1:0", - "anthropic.claude-opus_4.5-20250514-v1:0", - "us.anthropic.claude-opus-4-5-20250514-v1:0", - "ANTHROPIC.CLAUDE-OPUS-4-5-20250514-V1:0", # Case insensitive - ] - - for model in opus_4_5_models: - assert config._is_claude_opus_4_5(model), \ - f"Should detect {model} as Opus 4.5" - - # Test non-Opus 4.5 models - non_opus_4_5_models = [ - "anthropic.claude-sonnet-4-5-20250929-v1:0", - "anthropic.claude-opus-4-20250514-v1:0", # Opus 4, not 4.5 - "anthropic.claude-opus-4-1-20250514-v1:0", # Opus 4.1, not 4.5 - "anthropic.claude-haiku-4-5-20251001-v1:0", - ] - - for model in non_opus_4_5_models: - assert not config._is_claude_opus_4_5(model), \ - f"Should not detect {model} as Opus 4.5" - - -def test_structured_outputs_beta_header_filtered_for_bedrock_invoke(): - """ - Test that unsupported beta headers are filtered out for Bedrock Invoke API. - - Bedrock Invoke API only supports a specific whitelist of beta flags and returns - "invalid beta flag" error for others (e.g., structured-outputs, mcp-servers). - This test ensures unsupported headers are filtered while keeping supported ones. - - Fixes: https://github.com/BerriAI/litellm/issues/16726 - """ - config = AmazonAnthropicClaudeConfig() - - messages = [{"role": "user", "content": "test"}] - - # Test 1: structured-outputs beta header (unsupported) - headers = {"anthropic-beta": "structured-outputs-2025-11-13"} - - result = config.transform_request( - model="anthropic.claude-4-0-sonnet-20250514-v1:0", - messages=messages, - optional_params={}, - litellm_params={}, - headers=headers, - ) - - # Verify structured-outputs beta is filtered out - anthropic_beta = result.get("anthropic_beta", []) - assert not any("structured-outputs" in beta for beta in anthropic_beta), \ - f"structured-outputs beta should be filtered, got: {anthropic_beta}" - - # Test 2: mcp-servers beta header (unsupported - the main issue from #16726) - headers = {"anthropic-beta": "mcp-servers-2025-12-04"} - - result = config.transform_request( - model="anthropic.claude-4-0-sonnet-20250514-v1:0", - messages=messages, - optional_params={}, - litellm_params={}, - headers=headers, - ) - - # Verify mcp-servers beta is filtered out - anthropic_beta = result.get("anthropic_beta", []) - assert not any("mcp-servers" in beta for beta in anthropic_beta), \ - f"mcp-servers beta should be filtered, got: {anthropic_beta}" - - # Test 3: Mix of supported and unsupported beta headers - headers = {"anthropic-beta": "computer-use-2024-10-22,mcp-servers-2025-12-04,structured-outputs-2025-11-13"} - - result = config.transform_request( - model="anthropic.claude-4-0-sonnet-20250514-v1:0", - messages=messages, - optional_params={}, - litellm_params={}, - headers=headers, - ) - - # Verify only supported betas are kept - anthropic_beta = result.get("anthropic_beta", []) - assert not any("structured-outputs" in beta for beta in anthropic_beta), \ - f"structured-outputs beta should be filtered, got: {anthropic_beta}" - assert not any("mcp-servers" in beta for beta in anthropic_beta), \ - f"mcp-servers beta should be filtered, got: {anthropic_beta}" - assert any("computer-use" in beta for beta in anthropic_beta), \ - f"computer-use beta should be kept, got: {anthropic_beta}" - - -def test_output_format_removed_from_bedrock_invoke_request(): - """ - Test that output_format parameter is removed from Bedrock Invoke requests. - - Bedrock Invoke API doesn't support the output_format parameter (only supported - in Anthropic Messages API). This test ensures it's removed to prevent errors. - """ - config = AmazonAnthropicClaudeConfig() - - messages = [{"role": "user", "content": "test"}] - - # Create a request with output_format via map_openai_params - non_default_params = { - "response_format": {"type": "json_object"} - } - optional_params = {} - - # This should trigger tool-based structured outputs - optional_params = config.map_openai_params( - non_default_params=non_default_params, - optional_params=optional_params, - model="anthropic.claude-4-0-sonnet-20250514-v1:0", - drop_params=False, - ) - - result = config.transform_request( - model="anthropic.claude-4-0-sonnet-20250514-v1:0", - messages=messages, - optional_params=optional_params, - litellm_params={}, - headers={}, - ) - - # Verify output_format is not in the request - assert "output_format" not in result, \ - f"output_format should be removed for Bedrock Invoke, got keys: {result.keys()}" diff --git a/tests/test_litellm/llms/bedrock/test_anthropic_beta_support.py b/tests/test_litellm/llms/bedrock/test_anthropic_beta_support.py index e7b6de29b6b..b9324e4966f 100644 --- a/tests/test_litellm/llms/bedrock/test_anthropic_beta_support.py +++ b/tests/test_litellm/llms/bedrock/test_anthropic_beta_support.py @@ -390,103 +390,3 @@ def test_converse_anthropic_model_with_cross_region_prefix(self): "anthropic_beta SHOULD be added for Anthropic models with cross-region prefix." ) assert "context-1m-2025-08-07" in additional_fields["anthropic_beta"] - - def test_messages_advanced_tool_use_translation_opus_4_5(self): - """Test that advanced-tool-use header is translated to Bedrock-specific headers for Opus 4.5. - - Regression test for: Claude Code sends advanced-tool-use-2025-11-20 header which needs - to be translated to tool-search-tool-2025-10-19 and tool-examples-2025-10-29 for - Bedrock Invoke API on Claude Opus 4.5. - - Ref: https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages-request-response.html - """ - config = AmazonAnthropicClaudeMessagesConfig() - headers = {"anthropic-beta": "advanced-tool-use-2025-11-20"} - - result = config.transform_anthropic_messages_request( - model="us.anthropic.claude-opus-4-5-20250514-v1:0", - messages=[{"role": "user", "content": "Test"}], - anthropic_messages_optional_request_params={"max_tokens": 100}, - litellm_params={}, - headers=headers - ) - - assert "anthropic_beta" in result - beta_headers = result["anthropic_beta"] - - # advanced-tool-use should be removed - assert "advanced-tool-use-2025-11-20" not in beta_headers, ( - "advanced-tool-use-2025-11-20 should be removed for Bedrock Invoke API" - ) - - # Bedrock-specific headers should be added for Opus 4.5 - assert "tool-search-tool-2025-10-19" in beta_headers, ( - "tool-search-tool-2025-10-19 should be added for Opus 4.5" - ) - assert "tool-examples-2025-10-29" in beta_headers, ( - "tool-examples-2025-10-29 should be added for Opus 4.5" - ) - - def test_messages_advanced_tool_use_translation_sonnet_4_5(self): - """Test that advanced-tool-use header is translated to Bedrock-specific headers for Sonnet 4.5. - - Regression test for: Claude Code sends advanced-tool-use-2025-11-20 header which needs - to be translated to tool-search-tool-2025-10-19 and tool-examples-2025-10-29 for - Bedrock Invoke API on Claude Sonnet 4.5. - - Ref: https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool - """ - config = AmazonAnthropicClaudeMessagesConfig() - headers = {"anthropic-beta": "advanced-tool-use-2025-11-20"} - - result = config.transform_anthropic_messages_request( - model="us.anthropic.claude-sonnet-4-5-20250929-v1:0", - messages=[{"role": "user", "content": "Test"}], - anthropic_messages_optional_request_params={"max_tokens": 100}, - litellm_params={}, - headers=headers - ) - - assert "anthropic_beta" in result - beta_headers = result["anthropic_beta"] - - # advanced-tool-use should be removed - assert "advanced-tool-use-2025-11-20" not in beta_headers, ( - "advanced-tool-use-2025-11-20 should be removed for Bedrock Invoke API" - ) - - # Bedrock-specific headers should be added for Sonnet 4.5 - assert "tool-search-tool-2025-10-19" in beta_headers, ( - "tool-search-tool-2025-10-19 should be added for Sonnet 4.5" - ) - assert "tool-examples-2025-10-29" in beta_headers, ( - "tool-examples-2025-10-29 should be added for Sonnet 4.5" - ) - - def test_messages_advanced_tool_use_filtered_unsupported_model(self): - """Test that advanced-tool-use header is filtered out for models that don't support tool search. - - The translation to Bedrock-specific headers should only happen for models that - support tool search on Bedrock (Opus 4.5, Sonnet 4.5). - For other models, the advanced-tool-use header should just be removed. - """ - config = AmazonAnthropicClaudeMessagesConfig() - headers = {"anthropic-beta": "advanced-tool-use-2025-11-20"} - - # Test with Claude 3.5 Sonnet (does NOT support tool search on Bedrock) - result = config.transform_anthropic_messages_request( - model="us.anthropic.claude-3-5-sonnet-20241022-v2:0", - messages=[{"role": "user", "content": "Test"}], - anthropic_messages_optional_request_params={"max_tokens": 100}, - litellm_params={}, - headers=headers - ) - - beta_headers = result.get("anthropic_beta", []) - - # advanced-tool-use should be removed - assert "advanced-tool-use-2025-11-20" not in beta_headers - - # Bedrock-specific headers should NOT be added for unsupported models - assert "tool-search-tool-2025-10-19" not in beta_headers - assert "tool-examples-2025-10-29" not in beta_headers diff --git a/tests/test_litellm/llms/hosted_vllm/chat/test_hosted_vllm_chat_transformation.py b/tests/test_litellm/llms/hosted_vllm/chat/test_hosted_vllm_chat_transformation.py index 9b3b6aeaea1..3749a5a8ca4 100644 --- a/tests/test_litellm/llms/hosted_vllm/chat/test_hosted_vllm_chat_transformation.py +++ b/tests/test_litellm/llms/hosted_vllm/chat/test_hosted_vllm_chat_transformation.py @@ -101,50 +101,3 @@ def test_hosted_vllm_supports_reasoning_effort(): drop_params=False, ) assert optional_params["reasoning_effort"] == "high" - - -def test_hosted_vllm_supports_thinking(): - """ - Test that hosted_vllm supports the 'thinking' parameter. - - Anthropic-style thinking is converted to OpenAI-style reasoning_effort - since vLLM is OpenAI-compatible. - - Related issue: https://github.com/BerriAI/litellm/issues/19761 - """ - config = HostedVLLMChatConfig() - supported_params = config.get_supported_openai_params( - model="hosted_vllm/GLM-4.6-FP8" - ) - assert "thinking" in supported_params - - # Test thinking with low budget_tokens -> "minimal" (for < 2000) - optional_params = config.map_openai_params( - non_default_params={"thinking": {"type": "enabled", "budget_tokens": 1024}}, - optional_params={}, - model="hosted_vllm/GLM-4.6-FP8", - drop_params=False, - ) - assert "thinking" not in optional_params # thinking should NOT be passed - assert optional_params["reasoning_effort"] == "minimal" - - # Test thinking with high budget_tokens -> "high" - optional_params = config.map_openai_params( - non_default_params={"thinking": {"type": "enabled", "budget_tokens": 15000}}, - optional_params={}, - model="hosted_vllm/GLM-4.6-FP8", - drop_params=False, - ) - assert optional_params["reasoning_effort"] == "high" - - # Test that existing reasoning_effort is not overwritten - optional_params = config.map_openai_params( - non_default_params={ - "thinking": {"type": "enabled", "budget_tokens": 15000}, - "reasoning_effort": "low", - }, - optional_params={}, - model="hosted_vllm/GLM-4.6-FP8", - drop_params=False, - ) - assert optional_params["reasoning_effort"] == "low" diff --git a/tests/test_litellm/llms/openai/test_gpt5_transformation.py b/tests/test_litellm/llms/openai/test_gpt5_transformation.py index 386f264a4dd..fd25d302d07 100644 --- a/tests/test_litellm/llms/openai/test_gpt5_transformation.py +++ b/tests/test_litellm/llms/openai/test_gpt5_transformation.py @@ -20,23 +20,6 @@ def test_gpt5_supports_reasoning_effort(config: OpenAIConfig): assert "reasoning_effort" in config.get_supported_openai_params(model="gpt-5-mini") -def test_gpt5_chat_does_not_support_reasoning_effort(config: OpenAIConfig): - assert ( - "reasoning_effort" - not in config.get_supported_openai_params(model="gpt-5-chat-latest") - ) - - -def test_gpt5_chat_supports_temperature(config: OpenAIConfig): - params = config.map_openai_params( - non_default_params={"temperature": 0.3}, - optional_params={}, - model="gpt-5-chat-latest", - drop_params=False, - ) - assert params["temperature"] == 0.3 - - def test_gpt5_maps_max_tokens(config: OpenAIConfig): params = config.map_openai_params( non_default_params={"max_tokens": 10}, diff --git a/tests/test_litellm/llms/s3_vectors/__init__.py b/tests/test_litellm/llms/s3_vectors/__init__.py deleted file mode 100644 index d4b0c4d8550..00000000000 --- a/tests/test_litellm/llms/s3_vectors/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# S3 Vectors tests diff --git a/tests/test_litellm/llms/s3_vectors/vector_stores/__init__.py b/tests/test_litellm/llms/s3_vectors/vector_stores/__init__.py deleted file mode 100644 index 231735c1de7..00000000000 --- a/tests/test_litellm/llms/s3_vectors/vector_stores/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# S3 Vectors vector store tests diff --git a/tests/test_litellm/llms/s3_vectors/vector_stores/test_s3_vectors_transformation.py b/tests/test_litellm/llms/s3_vectors/vector_stores/test_s3_vectors_transformation.py deleted file mode 100644 index 3a84da31542..00000000000 --- a/tests/test_litellm/llms/s3_vectors/vector_stores/test_s3_vectors_transformation.py +++ /dev/null @@ -1,115 +0,0 @@ -from unittest.mock import MagicMock, Mock - -import httpx -import pytest - -from litellm.llms.s3_vectors.vector_stores.transformation import ( - S3VectorsVectorStoreConfig, -) -from litellm.types.vector_stores import VectorStoreSearchResponse - - -class TestS3VectorsVectorStoreConfig: - def test_init(self): - """Test that S3VectorsVectorStoreConfig initializes correctly""" - config = S3VectorsVectorStoreConfig() - assert config is not None - - def test_get_supported_openai_params(self): - """Test that supported OpenAI params are returned""" - config = S3VectorsVectorStoreConfig() - params = config.get_supported_openai_params("test-model") - assert "max_num_results" in params - - def test_get_complete_url(self): - """Test URL generation for S3 Vectors""" - config = S3VectorsVectorStoreConfig() - litellm_params = {"aws_region_name": "us-west-2"} - url = config.get_complete_url(None, litellm_params) - assert url == "https://s3vectors.us-west-2.api.aws" - - def test_get_complete_url_missing_region(self): - """Test that missing region raises error""" - config = S3VectorsVectorStoreConfig() - litellm_params = {} - with pytest.raises(ValueError, match="aws_region_name is required"): - config.get_complete_url(None, litellm_params) - - @pytest.mark.skip(reason="Requires embedding API call, tested in integration tests") - def test_transform_search_request(self): - """Test search request transformation""" - # This test requires making an actual embedding API call - # It's better tested in integration tests - pass - - def test_transform_search_request_invalid_vector_store_id(self): - """Test that invalid vector_store_id format raises error""" - config = S3VectorsVectorStoreConfig() - mock_logging_obj = Mock() - mock_logging_obj.model_call_details = {} - - with pytest.raises( - ValueError, match="vector_store_id must be in format 'bucket_name:index_name'" - ): - config.transform_search_vector_store_request( - vector_store_id="invalid-format", - query="test query", - vector_store_search_optional_params={}, - api_base="https://s3vectors.us-west-2.api.aws", - litellm_logging_obj=mock_logging_obj, - litellm_params={}, - ) - - def test_transform_search_response(self): - """Test search response transformation""" - config = S3VectorsVectorStoreConfig() - mock_logging_obj = Mock() - mock_logging_obj.model_call_details = {"query": "test query"} - - mock_response = Mock(spec=httpx.Response) - mock_response.json.return_value = { - "vectors": [ - { - "distance": 0.05, # S3 Vectors returns distance, not score - "metadata": { - "source_text": "This is test content", - "chunk_index": "0", - "filename": "test.pdf", - }, - }, - { - "distance": 0.15, - "metadata": { - "source_text": "More test content", - "chunk_index": "1", - }, - }, - ] - } - mock_response.status_code = 200 - mock_response.headers = {} - - result = config.transform_search_vector_store_response( - mock_response, mock_logging_obj - ) - - # VectorStoreSearchResponse is a TypedDict, so check structure instead of isinstance - assert result["object"] == "vector_store.search_results.page" - assert result["search_query"] == "test query" - assert len(result["data"]) == 2 - # Score should be 1 - distance (cosine similarity) - assert result["data"][0]["score"] == 0.95 # 1 - 0.05 - assert result["data"][0]["content"][0]["text"] == "This is test content" - assert result["data"][0]["filename"] == "test.pdf" - assert result["data"][1]["score"] == 0.85 # 1 - 0.15 - assert result["data"][1]["content"][0]["text"] == "More test content" - - def test_map_openai_params(self): - """Test OpenAI parameter mapping""" - config = S3VectorsVectorStoreConfig() - non_default_params = {"max_num_results": 5} - optional_params = {} - - result = config.map_openai_params(non_default_params, optional_params, False) - - assert result["maxResults"] == 5 diff --git a/tests/test_litellm/llms/test_cache_control_and_reasoning.py b/tests/test_litellm/llms/test_cache_control_and_reasoning.py deleted file mode 100644 index 468927cdd49..00000000000 --- a/tests/test_litellm/llms/test_cache_control_and_reasoning.py +++ /dev/null @@ -1,281 +0,0 @@ -""" -Test cache_control and reasoning parameter support for MiniMax, GLM/ZAI, and OpenRouter. - -This test file verifies the fixes for Issue #19923: -- cache_control is preserved (not stripped) for MiniMax, GLM, and OpenRouter variants -- thinking parameter is supported for reasoning-capable models -- Model metadata correctly reflects capabilities -""" -import os -import sys - -import pytest - -sys.path.insert( - 0, os.path.abspath("../../..") -) # Adds the parent directory to the system path - -from litellm.llms.minimax.chat.transformation import MinimaxChatConfig -from litellm.llms.openrouter.chat.transformation import OpenrouterConfig -from litellm.llms.zai.chat.transformation import ZAIChatConfig - - -def test_minimax_preserves_cache_control_in_messages(): - """MiniMax should NOT strip cache_control from messages.""" - config = MinimaxChatConfig() - - messages = [ - { - "role": "system", - "content": "You are a helpful assistant.", - "cache_control": {"type": "ephemeral"}, - }, - { - "role": "user", - "content": "Hello, world!", - }, - ] - - transformed_messages, _ = config.remove_cache_control_flag_from_messages_and_tools( - model="minimax/MiniMax-M2.1", messages=messages - ) - - # cache_control should be preserved - assert transformed_messages[0].get("cache_control") == {"type": "ephemeral"} - - -def test_minimax_preserves_cache_control_in_tools(): - """MiniMax should NOT strip cache_control from tools.""" - config = MinimaxChatConfig() - - tools = [ - { - "type": "function", - "function": { - "name": "get_weather", - "description": "Get weather information", - "parameters": {"type": "object", "properties": {}}, - }, - "cache_control": {"type": "ephemeral"}, - } - ] - - _, transformed_tools = config.remove_cache_control_flag_from_messages_and_tools( - model="minimax/MiniMax-M2.1", messages=[], tools=tools - ) - - # cache_control should be preserved - assert transformed_tools[0].get("cache_control") == {"type": "ephemeral"} - - -def test_minimax_supports_thinking_param(): - """MiniMax reasoning models should support thinking parameter.""" - config = MinimaxChatConfig() - - supported_params = config.get_supported_openai_params( - model="minimax/MiniMax-M2.1" - ) - - # thinking should be in supported params for reasoning models - assert "thinking" in supported_params - # reasoning_split should also be supported - assert "reasoning_split" in supported_params - - -def test_zai_preserves_cache_control_in_messages(): - """ZAI should NOT strip cache_control from messages.""" - config = ZAIChatConfig() - - messages = [ - { - "role": "system", - "content": "You are a helpful assistant.", - "cache_control": {"type": "ephemeral"}, - }, - { - "role": "user", - "content": "Hello, world!", - }, - ] - - transformed_messages, _ = config.remove_cache_control_flag_from_messages_and_tools( - model="zai/glm-4.7", messages=messages - ) - - # cache_control should be preserved - assert transformed_messages[0].get("cache_control") == {"type": "ephemeral"} - - -def test_zai_preserves_cache_control_in_tools(): - """ZAI should NOT strip cache_control from tools.""" - config = ZAIChatConfig() - - tools = [ - { - "type": "function", - "function": { - "name": "get_weather", - "description": "Get weather information", - "parameters": {"type": "object", "properties": {}}, - }, - "cache_control": {"type": "ephemeral"}, - } - ] - - _, transformed_tools = config.remove_cache_control_flag_from_messages_and_tools( - model="zai/glm-4.7", messages=[], tools=tools - ) - - # cache_control should be preserved - assert transformed_tools[0].get("cache_control") == {"type": "ephemeral"} - - -def test_zai_supports_thinking_param_for_reasoning_models(): - """ZAI reasoning models (glm-4.7, glm-4.6) should support thinking parameter.""" - config = ZAIChatConfig() - - # glm-4.7 supports reasoning - supported_params_47 = config.get_supported_openai_params(model="zai/glm-4.7") - assert "thinking" in supported_params_47 - - # glm-4.6 supports reasoning - supported_params_46 = config.get_supported_openai_params(model="zai/glm-4.6") - assert "thinking" in supported_params_46 - - -def test_openrouter_minimax_supports_cache_control(): - """OpenRouter should preserve cache_control for MiniMax models.""" - config = OpenrouterConfig() - - messages = [ - { - "role": "user", - "content": "Hello, world!", - "cache_control": {"type": "ephemeral"}, - } - ] - - # Test that cache_control is not removed - transformed_messages, _ = config.remove_cache_control_flag_from_messages_and_tools( - model="openrouter/minimax/minimax-m2", messages=messages - ) - - # The method should preserve cache_control for minimax models - assert transformed_messages[0].get("cache_control") == {"type": "ephemeral"} - - -def test_openrouter_glm_supports_cache_control(): - """OpenRouter should preserve cache_control for GLM models.""" - config = OpenrouterConfig() - - messages = [ - { - "role": "user", - "content": "Hello, world!", - "cache_control": {"type": "ephemeral"}, - } - ] - - # Test that cache_control is not removed for GLM models - transformed_messages, _ = config.remove_cache_control_flag_from_messages_and_tools( - model="openrouter/z-ai/glm-4.6", messages=messages - ) - - # The method should preserve cache_control for GLM models - assert transformed_messages[0].get("cache_control") == {"type": "ephemeral"} - - -def test_openrouter_deepseek_strips_cache_control(): - """OpenRouter should still strip cache_control for non-supported models.""" - config = OpenrouterConfig() - - messages = [ - { - "role": "user", - "content": "Hello, world!", - "cache_control": {"type": "ephemeral"}, - } - ] - - # DeepSeek doesn't support cache_control, so it should be stripped - transformed_messages, _ = config.remove_cache_control_flag_from_messages_and_tools( - model="openrouter/deepseek/deepseek-chat", messages=messages - ) - - # cache_control should be removed for non-supported models - assert transformed_messages[0].get("cache_control") is None - - -def test_openrouter_minimax_transform_moves_cache_control_to_content(): - """OpenRouter should move cache_control to content blocks for MiniMax.""" - config = OpenrouterConfig() - - messages = [ - { - "role": "user", - "content": "Analyze this data", - "cache_control": {"type": "ephemeral"}, - } - ] - - transformed_request = config.transform_request( - model="openrouter/minimax/minimax-m2", - messages=messages, - optional_params={}, - litellm_params={}, - headers={}, - ) - - # cache_control should be moved to content blocks - assert "messages" in transformed_request - user_message = transformed_request["messages"][0] - assert isinstance(user_message["content"], list) - assert user_message["content"][0]["cache_control"] == {"type": "ephemeral"} - # Message-level cache_control should be removed - assert "cache_control" not in user_message - - -def test_openrouter_glm_transform_moves_cache_control_to_content(): - """OpenRouter should move cache_control to content blocks for GLM.""" - config = OpenrouterConfig() - - messages = [ - { - "role": "user", - "content": "Analyze this data", - "cache_control": {"type": "ephemeral"}, - } - ] - - transformed_request = config.transform_request( - model="openrouter/z-ai/glm-4.6", - messages=messages, - optional_params={}, - litellm_params={}, - headers={}, - ) - - # cache_control should be moved to content blocks - assert "messages" in transformed_request - user_message = transformed_request["messages"][0] - assert isinstance(user_message["content"], list) - assert user_message["content"][0]["cache_control"] == {"type": "ephemeral"} - - -def test_openrouter_supports_thinking_param_for_reasoning_models(): - """OpenRouter should support thinking parameter for reasoning-capable models.""" - config = OpenrouterConfig() - - # Test MiniMax (supports reasoning) - supported_params_minimax = config.get_supported_openai_params( - model="openrouter/minimax/minimax-m2" - ) - assert "thinking" in supported_params_minimax - assert "reasoning_effort" in supported_params_minimax - - # Test GLM (supports reasoning) - supported_params_glm = config.get_supported_openai_params( - model="openrouter/z-ai/glm-4.6" - ) - assert "thinking" in supported_params_glm - assert "reasoning_effort" in supported_params_glm diff --git a/tests/test_litellm/llms/vercel_ai_gateway/embedding/__init__.py b/tests/test_litellm/llms/vercel_ai_gateway/embedding/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/tests/test_litellm/llms/vercel_ai_gateway/embedding/test_vercel_ai_gateway_embedding.py b/tests/test_litellm/llms/vercel_ai_gateway/embedding/test_vercel_ai_gateway_embedding.py deleted file mode 100644 index af1e1df92fd..00000000000 --- a/tests/test_litellm/llms/vercel_ai_gateway/embedding/test_vercel_ai_gateway_embedding.py +++ /dev/null @@ -1,218 +0,0 @@ -import os -import sys -from unittest.mock import MagicMock, patch - -import httpx -import pytest - -sys.path.insert( - 0, os.path.abspath("../../../../..") -) # Adds the parent directory to the system path - -from litellm.llms.vercel_ai_gateway.embedding.transformation import ( - VercelAIGatewayEmbeddingConfig, -) -from litellm.llms.vercel_ai_gateway.common_utils import VercelAIGatewayException -from litellm.types.utils import EmbeddingResponse - - -def test_vercel_ai_gateway_embedding_get_complete_url(): - """Test URL generation for embeddings endpoint""" - config = VercelAIGatewayEmbeddingConfig() - - # Test with default API base - url = config.get_complete_url( - api_base=None, - api_key=None, - model="openai/text-embedding-3-small", - optional_params={}, - litellm_params={}, - ) - assert url == "https://ai-gateway.vercel.sh/v1/embeddings" - - # Test with custom API base - url = config.get_complete_url( - api_base="https://custom.vercel.sh/v1", - api_key=None, - model="openai/text-embedding-3-small", - optional_params={}, - litellm_params={}, - ) - assert url == "https://custom.vercel.sh/v1/embeddings" - - # Test with trailing slash - url = config.get_complete_url( - api_base="https://custom.vercel.sh/v1/", - api_key=None, - model="openai/text-embedding-3-small", - optional_params={}, - litellm_params={}, - ) - assert url == "https://custom.vercel.sh/v1/embeddings" - - -def test_vercel_ai_gateway_embedding_transform_request(): - """Test request transformation for embeddings""" - config = VercelAIGatewayEmbeddingConfig() - - # Test with string input - request = config.transform_embedding_request( - model="openai/text-embedding-3-small", - input="Hello world", - optional_params={}, - headers={}, - ) - assert request["model"] == "openai/text-embedding-3-small" - assert request["input"] == ["Hello world"] - - # Test with list input - request = config.transform_embedding_request( - model="openai/text-embedding-3-small", - input=["Hello", "World"], - optional_params={}, - headers={}, - ) - assert request["model"] == "openai/text-embedding-3-small" - assert request["input"] == ["Hello", "World"] - - # Test stripping vercel_ai_gateway/ prefix - request = config.transform_embedding_request( - model="vercel_ai_gateway/openai/text-embedding-3-small", - input="Hello", - optional_params={}, - headers={}, - ) - assert request["model"] == "openai/text-embedding-3-small" - - -def test_vercel_ai_gateway_embedding_transform_request_with_dimensions(): - """Test request transformation with dimensions parameter""" - config = VercelAIGatewayEmbeddingConfig() - - request = config.transform_embedding_request( - model="openai/text-embedding-3-small", - input="Hello world", - optional_params={"dimensions": 768}, - headers={}, - ) - assert request["model"] == "openai/text-embedding-3-small" - assert request["input"] == ["Hello world"] - assert request["dimensions"] == 768 - - -def test_vercel_ai_gateway_embedding_validate_environment(): - """Test header validation and setup""" - config = VercelAIGatewayEmbeddingConfig() - - headers = config.validate_environment( - headers={}, - model="openai/text-embedding-3-small", - messages=[], - optional_params={}, - litellm_params={}, - api_key="test_key", - ) - assert headers["Content-Type"] == "application/json" - assert headers["Authorization"] == "Bearer test_key" - - # Test with existing headers (should merge) - headers = config.validate_environment( - headers={"X-Custom": "value"}, - model="openai/text-embedding-3-small", - messages=[], - optional_params={}, - litellm_params={}, - api_key="test_key", - ) - assert headers["X-Custom"] == "value" - assert headers["Authorization"] == "Bearer test_key" - - -def test_vercel_ai_gateway_embedding_get_supported_params(): - """Test supported OpenAI parameters""" - config = VercelAIGatewayEmbeddingConfig() - supported = config.get_supported_openai_params("openai/text-embedding-3-small") - - assert "dimensions" in supported - assert "encoding_format" in supported - assert "timeout" in supported - assert "user" in supported - - -def test_vercel_ai_gateway_embedding_map_openai_params(): - """Test OpenAI parameter mapping""" - config = VercelAIGatewayEmbeddingConfig() - - optional_params = config.map_openai_params( - non_default_params={"dimensions": 768, "encoding_format": "float"}, - optional_params={}, - model="openai/text-embedding-3-small", - drop_params=False, - ) - assert optional_params["dimensions"] == 768 - assert optional_params["encoding_format"] == "float" - - -def test_vercel_ai_gateway_embedding_error_class(): - """Test error class creation""" - config = VercelAIGatewayEmbeddingConfig() - - error = config.get_error_class( - error_message="Test error", - status_code=400, - headers={"Content-Type": "application/json"}, - ) - - assert isinstance(error, VercelAIGatewayException) - assert error.message == "Test error" - assert error.status_code == 400 - - -def test_vercel_ai_gateway_embedding_transform_response(): - """Test response transformation""" - config = VercelAIGatewayEmbeddingConfig() - - mock_response = MagicMock(spec=httpx.Response) - mock_response.text = '{"object":"list","data":[{"object":"embedding","index":0,"embedding":[0.1,0.2,0.3]}],"model":"openai/text-embedding-3-small","usage":{"prompt_tokens":2,"total_tokens":2}}' - mock_response.json.return_value = { - "object": "list", - "data": [{"object": "embedding", "index": 0, "embedding": [0.1, 0.2, 0.3]}], - "model": "openai/text-embedding-3-small", - "usage": {"prompt_tokens": 2, "total_tokens": 2}, - } - - mock_logging = MagicMock() - - response = config.transform_embedding_response( - model="openai/text-embedding-3-small", - raw_response=mock_response, - model_response=EmbeddingResponse(), - logging_obj=mock_logging, - api_key="test_key", - request_data={}, - optional_params={}, - litellm_params={}, - ) - - assert response is not None - mock_logging.post_call.assert_called_once() - - -def test_vercel_ai_gateway_embedding_env_vars(): - """Test environment variable handling""" - config = VercelAIGatewayEmbeddingConfig() - - with patch.dict( - os.environ, - { - "VERCEL_AI_GATEWAY_API_BASE": "https://env.vercel.sh/v1", - }, - ): - url = config.get_complete_url( - api_base=None, - api_key=None, - model="openai/text-embedding-3-small", - optional_params={}, - litellm_params={}, - ) - assert url == "https://env.vercel.sh/v1/embeddings" diff --git a/tests/test_litellm/llms/vertex_ai/test_vertex_ai_common_utils.py b/tests/test_litellm/llms/vertex_ai/test_vertex_ai_common_utils.py index 94323e06901..953f54e4a54 100644 --- a/tests/test_litellm/llms/vertex_ai/test_vertex_ai_common_utils.py +++ b/tests/test_litellm/llms/vertex_ai/test_vertex_ai_common_utils.py @@ -812,36 +812,6 @@ def test_get_vertex_model_id_from_url(): assert model_id is None -def test_get_vertex_model_id_from_url_with_slashes(): - """Test get_vertex_model_id_from_url with model names containing slashes (e.g., gcp/google/gemini-2.5-flash) - - Regression test for NVIDIA issue: custom model names with slashes in passthrough URLs - were being truncated (e.g., 'gcp/google/gemini-2.5-flash' -> 'gcp'), causing access_groups - checks to fail. - """ - from litellm.llms.vertex_ai.common_utils import get_vertex_model_id_from_url - - # Test with model name containing slashes: gcp/google/gemini-2.5-flash - url = "https://us-central1-aiplatform.googleapis.com/v1/projects/test-project/locations/us-central1/publishers/google/models/gcp/google/gemini-2.5-flash:generateContent" - model_id = get_vertex_model_id_from_url(url) - assert model_id == "gcp/google/gemini-2.5-flash" - - # Test with model name containing slashes: gcp/google/gemini-3-flash-preview - url = "https://us-central1-aiplatform.googleapis.com/v1/projects/test-project/locations/global/publishers/google/models/gcp/google/gemini-3-flash-preview:streamGenerateContent" - model_id = get_vertex_model_id_from_url(url) - assert model_id == "gcp/google/gemini-3-flash-preview" - - # Test with custom model path: custom/model - url = "https://us-central1-aiplatform.googleapis.com/v1/projects/test-project/locations/us-central1/publishers/google/models/custom/model:generateContent" - model_id = get_vertex_model_id_from_url(url) - assert model_id == "custom/model" - - # Test passthrough URL format (without host) - url = "v1/projects/my-project/locations/us-central1/publishers/google/models/gcp/google/gemini-2.5-flash:generateContent" - model_id = get_vertex_model_id_from_url(url) - assert model_id == "gcp/google/gemini-2.5-flash" - - def test_construct_target_url_with_version_prefix(): """Test construct_target_url with version prefixes""" from litellm.llms.vertex_ai.common_utils import construct_target_url diff --git a/tests/test_litellm/llms/xai/responses/test_xai_responses_transformation.py b/tests/test_litellm/llms/xai/responses/test_xai_responses_transformation.py index dc06d6a1b0d..c0871d3b9b7 100644 --- a/tests/test_litellm/llms/xai/responses/test_xai_responses_transformation.py +++ b/tests/test_litellm/llms/xai/responses/test_xai_responses_transformation.py @@ -6,17 +6,16 @@ Source: litellm/llms/xai/responses/transformation.py """ -import os import sys +import os sys.path.insert(0, os.path.abspath("../../../../..")) import pytest - -from litellm.llms.xai.responses.transformation import XAIResponsesAPIConfig -from litellm.types.llms.openai import ResponsesAPIOptionalRequestParams from litellm.types.utils import LlmProviders from litellm.utils import ProviderConfigManager +from litellm.llms.xai.responses.transformation import XAIResponsesAPIConfig +from litellm.types.llms.openai import ResponsesAPIOptionalRequestParams class TestXAIResponsesAPITransformation: @@ -111,209 +110,3 @@ def test_xai_responses_endpoint_url(self): ) assert url_with_slash == "https://api.x.ai/v1/responses", "Should handle trailing slash" - def test_web_search_tool_transformation(self): - """Test that web_search tools are transformed to XAI format""" - config = XAIResponsesAPIConfig() - - # Test with allowed_domains - params = ResponsesAPIOptionalRequestParams( - tools=[ - { - "type": "web_search", - "allowed_domains": ["wikipedia.org", "x.ai"], - "enable_image_understanding": True - } - ] - ) - - result = config.map_openai_params( - response_api_optional_params=params, - model="grok-4-1-fast", - drop_params=False - ) - - assert "tools" in result - assert len(result["tools"]) == 1 - tool = result["tools"][0] - assert tool["type"] == "web_search" - assert "filters" in tool - assert tool["filters"]["allowed_domains"] == ["wikipedia.org", "x.ai"] - assert tool["enable_image_understanding"] is True - - def test_web_search_search_context_size_removed(self): - """Test that search_context_size is removed from web_search tools""" - config = XAIResponsesAPIConfig() - - params = ResponsesAPIOptionalRequestParams( - tools=[ - { - "type": "web_search", - "search_context_size": "high" # Not supported by XAI - } - ] - ) - - result = config.map_openai_params( - response_api_optional_params=params, - model="grok-4-1-fast", - drop_params=False - ) - - assert "tools" in result - assert len(result["tools"]) == 1 - tool = result["tools"][0] - assert tool["type"] == "web_search" - assert "search_context_size" not in tool - - def test_web_search_excluded_domains(self): - """Test web_search with excluded_domains""" - config = XAIResponsesAPIConfig() - - params = ResponsesAPIOptionalRequestParams( - tools=[ - { - "type": "web_search", - "excluded_domains": ["example.com", "test.com"] - } - ] - ) - - result = config.map_openai_params( - response_api_optional_params=params, - model="grok-4-1-fast", - drop_params=False - ) - - tool = result["tools"][0] - assert "filters" in tool - assert tool["filters"]["excluded_domains"] == ["example.com", "test.com"] - - def test_web_search_domains_limit(self): - """Test that allowed_domains and excluded_domains are limited to 5""" - config = XAIResponsesAPIConfig() - - # Test with more than 5 allowed_domains - params = ResponsesAPIOptionalRequestParams( - tools=[ - { - "type": "web_search", - "allowed_domains": ["d1.com", "d2.com", "d3.com", "d4.com", "d5.com", "d6.com", "d7.com"] - } - ] - ) - - result = config.map_openai_params( - response_api_optional_params=params, - model="grok-4-1-fast", - drop_params=False - ) - - tool = result["tools"][0] - assert len(tool["filters"]["allowed_domains"]) == 7 - - def test_x_search_tool_transformation(self): - """Test that x_search tools are transformed correctly""" - config = XAIResponsesAPIConfig() - - params = ResponsesAPIOptionalRequestParams( - tools=[ - { - "type": "x_search", - "allowed_x_handles": ["elonmusk", "xai"], - "from_date": "2025-01-01", - "to_date": "2025-01-28", - "enable_image_understanding": True, - "enable_video_understanding": True - } - ] - ) - - result = config.map_openai_params( - response_api_optional_params=params, - model="grok-4-1-fast", - drop_params=False - ) - - assert "tools" in result - assert len(result["tools"]) == 1 - tool = result["tools"][0] - assert tool["type"] == "x_search" - assert tool["allowed_x_handles"] == ["elonmusk", "xai"] - assert tool["from_date"] == "2025-01-01" - assert tool["to_date"] == "2025-01-28" - assert tool["enable_image_understanding"] is True - assert tool["enable_video_understanding"] is True - - def test_x_search_excluded_handles(self): - """Test x_search with excluded_x_handles""" - config = XAIResponsesAPIConfig() - - params = ResponsesAPIOptionalRequestParams( - tools=[ - { - "type": "x_search", - "excluded_x_handles": ["spam_account", "bot_account"] - } - ] - ) - - result = config.map_openai_params( - response_api_optional_params=params, - model="grok-4-1-fast", - drop_params=False - ) - - tool = result["tools"][0] - assert tool["excluded_x_handles"] == ["spam_account", "bot_account"] - - def test_mixed_tools(self): - """Test transformation with multiple tool types""" - config = XAIResponsesAPIConfig() - - params = ResponsesAPIOptionalRequestParams( - tools=[ - { - "type": "code_interpreter", - "container": {"type": "auto"} - }, - { - "type": "web_search", - "allowed_domains": ["wikipedia.org"] - }, - { - "type": "x_search", - "allowed_x_handles": ["elonmusk"] - }, - { - "type": "function", - "name": "get_weather", - "description": "Get weather", - "parameters": {"type": "object"} - } - ] - ) - - result = config.map_openai_params( - response_api_optional_params=params, - model="grok-4-1-fast", - drop_params=False - ) - - assert len(result["tools"]) == 4 - - # Verify code_interpreter - assert result["tools"][0]["type"] == "code_interpreter" - assert "container" not in result["tools"][0] - - # Verify web_search - assert result["tools"][1]["type"] == "web_search" - assert "filters" in result["tools"][1] - - # Verify x_search - assert result["tools"][2]["type"] == "x_search" - assert result["tools"][2]["allowed_x_handles"] == ["elonmusk"] - - # Verify function tool is unchanged - assert result["tools"][3]["type"] == "function" - assert result["tools"][3]["name"] == "get_weather" - diff --git a/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server_manager.py b/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server_manager.py index f241b2aa0d5..ecdc75ede52 100644 --- a/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server_manager.py +++ b/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server_manager.py @@ -1885,7 +1885,7 @@ async def test_call_tool_without_broken_pipe_error(self): # Create mock client that tracks call_tool usage mock_client = AsyncMock() - async def mock_call_tool(params, host_progress_callback=None): + async def mock_call_tool(params): # Return a mock CallToolResult result = MagicMock(spec=CallToolResult) result.content = [{"type": "text", "text": "Tool executed successfully"}] diff --git a/tests/test_litellm/proxy/auth/test_auth_checks.py b/tests/test_litellm/proxy/auth/test_auth_checks.py index ebcd9676129..807559207e6 100644 --- a/tests/test_litellm/proxy/auth/test_auth_checks.py +++ b/tests/test_litellm/proxy/auth/test_auth_checks.py @@ -15,10 +15,10 @@ import litellm from litellm.proxy._types import ( CallInfo, - Litellm_EntityType, LiteLLM_ObjectPermissionTable, LiteLLM_TeamTable, LiteLLM_UserTable, + Litellm_EntityType, LitellmUserRoles, ProxyErrorTypes, ProxyException, @@ -28,7 +28,6 @@ from litellm.proxy.auth.auth_checks import ( ExperimentalUIJWTToken, _can_object_call_vector_stores, - _get_fuzzy_user_object, _get_team_db_check, _virtual_key_max_budget_alert_check, _virtual_key_soft_budget_check, @@ -45,24 +44,6 @@ def set_salt_key(monkeypatch): monkeypatch.setenv("LITELLM_SALT_KEY", "sk-1234") -@pytest.fixture(autouse=True) -def reset_constants_module(): - """Reset constants module to ensure clean state before each test""" - import importlib - from litellm import constants - from litellm.proxy.auth import auth_checks - - # Reload modules before test - importlib.reload(constants) - importlib.reload(auth_checks) - - yield - - # Reload modules after test to clean up - importlib.reload(constants) - importlib.reload(auth_checks) - - @pytest.fixture def valid_sso_user_defined_values(): return LiteLLM_UserTable( @@ -150,63 +131,6 @@ def test_get_key_object_from_ui_hash_key_invalid(): assert key_object is None -def test_get_cli_jwt_auth_token_default_expiration(valid_sso_user_defined_values): - """Test generating CLI JWT token with default 24-hour expiration""" - token = ExperimentalUIJWTToken.get_cli_jwt_auth_token(valid_sso_user_defined_values) - - # Decrypt and verify token contents - decrypted_token = decrypt_value_helper( - token, key="ui_hash_key", exception_type="debug" - ) - assert decrypted_token is not None - token_data = json.loads(decrypted_token) - - assert token_data["user_id"] == "test_user" - assert token_data["user_role"] == LitellmUserRoles.PROXY_ADMIN.value - assert token_data["models"] == ["gpt-3.5-turbo"] - assert token_data["max_budget"] == litellm.max_ui_session_budget - - # Verify expiration time is set to 24 hours (default) - assert "expires" in token_data - expires = datetime.fromisoformat(token_data["expires"].replace("Z", "+00:00")) - assert expires > get_utc_datetime() - assert expires <= get_utc_datetime() + timedelta(hours=24, minutes=1) - assert expires >= get_utc_datetime() + timedelta(hours=23, minutes=59) - - -def test_get_cli_jwt_auth_token_custom_expiration( - valid_sso_user_defined_values, monkeypatch -): - """Test generating CLI JWT token with custom expiration via environment variable""" - import importlib - from litellm import constants - from litellm.proxy.auth import auth_checks - - # Set custom expiration to 48 hours - monkeypatch.setenv("LITELLM_CLI_JWT_EXPIRATION_HOURS", "48") - - # Reload the constants module to pick up the new env var - importlib.reload(constants) - # Also reload auth_checks to pick up the new constant value - importlib.reload(auth_checks) - - token = auth_checks.ExperimentalUIJWTToken.get_cli_jwt_auth_token(valid_sso_user_defined_values) - - # Decrypt and verify token contents - decrypted_token = decrypt_value_helper( - token, key="ui_hash_key", exception_type="debug" - ) - assert decrypted_token is not None - token_data = json.loads(decrypted_token) - - # Verify expiration time is set to 48 hours - assert "expires" in token_data - expires = datetime.fromisoformat(token_data["expires"].replace("Z", "+00:00")) - assert expires > get_utc_datetime() + timedelta(hours=47, minutes=59) - assert expires <= get_utc_datetime() + timedelta(hours=48, minutes=1) - - - @pytest.mark.asyncio async def test_default_internal_user_params_with_get_user_object(monkeypatch): """Test that default_internal_user_params is used when creating a new user via get_user_object""" @@ -1353,42 +1277,3 @@ async def budget_alerts(self, type, user_info): assert ( alert_triggered == expect_alert ), f"Expected alert_triggered to be {expect_alert} for spend={spend}, max_budget={max_budget}" - - -@pytest.mark.asyncio -async def test_get_fuzzy_user_object_case_insensitive_email(): - """Test that _get_fuzzy_user_object uses case-insensitive email lookup""" - # Setup mock Prisma client - mock_prisma = MagicMock() - mock_prisma.db = MagicMock() - mock_prisma.db.litellm_usertable = MagicMock() - - # Mock user data with mixed case email - test_user = LiteLLM_UserTable( - user_id="test_123", - sso_user_id=None, - user_email="Test@Example.com", # Mixed case in DB - organization_memberships=[], - max_budget=None, - ) - - # Test: SSO ID not found, find by email with different casing - mock_prisma.db.litellm_usertable.find_unique = AsyncMock(return_value=None) - mock_prisma.db.litellm_usertable.find_first = AsyncMock(return_value=test_user) - - # Search with lowercase email (different from DB) - result = await _get_fuzzy_user_object( - prisma_client=mock_prisma, - sso_user_id=None, - user_email="test@example.com", # Lowercase search - ) - - # Verify user was found despite case difference - assert result == test_user - - # Verify the query used case-insensitive mode - mock_prisma.db.litellm_usertable.find_first.assert_called_once() - call_args = mock_prisma.db.litellm_usertable.find_first.call_args - assert call_args.kwargs["where"]["user_email"]["equals"] == "test@example.com" - assert call_args.kwargs["where"]["user_email"]["mode"] == "insensitive" - assert call_args.kwargs["include"] == {"organization_memberships": True} diff --git a/tests/test_litellm/proxy/auth/test_auth_utils.py b/tests/test_litellm/proxy/auth/test_auth_utils.py index 82920ce1d80..62f9cc33b64 100644 --- a/tests/test_litellm/proxy/auth/test_auth_utils.py +++ b/tests/test_litellm/proxy/auth/test_auth_utils.py @@ -8,7 +8,6 @@ from litellm.proxy.auth.auth_utils import ( _get_customer_id_from_standard_headers, get_end_user_id_from_request_body, - get_model_from_request, get_key_model_rpm_limit, get_key_model_tpm_limit, ) @@ -187,25 +186,3 @@ def test_should_fall_back_to_body_when_no_standard_header(self): request_body=request_body, request_headers=headers ) assert result == "body-user" - - -def test_get_model_from_request_supports_google_model_names_with_slashes(): - assert ( - get_model_from_request( - request_data={}, - route="/v1beta/models/bedrock/claude-sonnet-3.7:generateContent", - ) - == "bedrock/claude-sonnet-3.7" - ) - assert ( - get_model_from_request( - request_data={}, - route="/models/hosted_vllm/gpt-oss-20b:generateContent", - ) - == "hosted_vllm/gpt-oss-20b" - ) - - -def test_get_model_from_request_vertex_passthrough_still_works(): - route = "/vertex_ai/v1/projects/p/locations/l/publishers/google/models/gemini-1.5-pro:generateContent" - assert get_model_from_request(request_data={}, route=route) == "gemini-1.5-pro" diff --git a/tests/test_litellm/proxy/auth/test_cli_auth.py b/tests/test_litellm/proxy/auth/test_cli_auth.py deleted file mode 100644 index 2faf6436523..00000000000 --- a/tests/test_litellm/proxy/auth/test_cli_auth.py +++ /dev/null @@ -1,203 +0,0 @@ -""" -Tests for litellm/proxy/client/cli/commands/auth.py - -This module tests the auth commands and their associated functionality. -""" - -import pytest -import requests -from unittest.mock import AsyncMock, patch, Mock, call -from litellm.proxy.client.cli.commands.auth import _normalize_teams, _poll_for_ready_data, _poll_for_authentication - -@pytest.mark.asyncio -async def test_normalize_teams_teams_only(): - """Test normalize teams helper function""" - teams = ["1", "2", "3"] - team_details = [] - result = _normalize_teams(teams, team_details) - assert result == [{"team_id": "1", "team_alias": None}, {"team_id": "2", "team_alias": None}, {"team_id": "3", "team_alias": None}] - -@pytest.mark.asyncio -async def test_normalize_teams_with_details_no_aliases(): - """Test normalize teams helper function""" - teams = ["4", "5", "6"] - team_details = [{"team_id": "1"}, {"team_id": "2"}, {"team_id": "3"}] - result = _normalize_teams(teams, team_details) - assert result == [{"team_id": "1", "team_alias": None}, {"team_id": "2", "team_alias": None}, {"team_id": "3", "team_alias": None}] - -@pytest.mark.asyncio -async def test_normalize_teams_with_details_with_aliases(): - """Test normalize teams helper function""" - teams = ["4", "5", "6"] - team_details = [{"team_id": "1", "team_alias": "A"}, {"team_id": "2", "team_alias": "B"}, {"team_id": "3", "team_alias": "C"}] - result = _normalize_teams(teams, team_details) - assert result == [{"team_id": "1", "team_alias": "A"}, {"team_id": "2", "team_alias": "B"}, {"team_id": "3", "team_alias": "C"}] - -@pytest.mark.asyncio -@patch("litellm.proxy.client.cli.commands.auth.requests.get", side_effect=[Mock(status_code=404)]) -@patch("litellm.proxy.client.cli.commands.auth.click.echo") -@patch("litellm.proxy.client.cli.commands.auth.time.sleep") -async def test_poll_for_ready_404(sleep_mock, click_mock, request_mock): - """Test poll_for_ready function""" - actual = _poll_for_ready_data("https://litellm.com", poll_interval=1, total_timeout=1, request_timeout=42) - assert actual is None - click_mock.assert_called_once_with("Polling error: HTTP 404") - request_mock.assert_called_once_with("https://litellm.com", timeout=42) - -@pytest.mark.asyncio -@patch("litellm.proxy.client.cli.commands.auth.requests.get", side_effect=[Mock(status_code=200, json=Mock(return_value={"status": "ready","json": "data"}))]) -@patch("litellm.proxy.client.cli.commands.auth.click.echo") -@patch("litellm.proxy.client.cli.commands.auth.time.sleep") -async def test_poll_for_ready_200_ready(sleep_mock, click_mock, request_mock): - """Test poll_for_ready function""" - actual = _poll_for_ready_data("https://litellm.com", poll_interval=1, total_timeout=1, request_timeout=42) - assert actual == {"status": "ready", "json": "data"} - click_mock.assert_not_called() - request_mock.assert_called_once_with("https://litellm.com", timeout=42) - sleep_mock.assert_not_called() - -@pytest.mark.asyncio -@patch("litellm.proxy.client.cli.commands.auth.requests.get", side_effect=[Mock(status_code=200, json=Mock(return_value={"status": "pending","json": "data"})), Mock(status_code=200, json=Mock(return_value={"status": "ready","json": "data"}))]) -@patch("litellm.proxy.client.cli.commands.auth.click.echo") -@patch("litellm.proxy.client.cli.commands.auth.time.sleep") -async def test_poll_for_ready_single_pending(sleep_mock, click_mock, request_mock): - """Test poll_for_ready function""" - actual = _poll_for_ready_data("https://litellm.com", poll_interval=1, total_timeout=2, request_timeout=42) - assert actual == {"status": "ready", "json": "data"} - click_mock.assert_not_called() - request_mock.assert_has_calls([ - call("https://litellm.com", timeout=42), - call("https://litellm.com", timeout=42) - ]) - sleep_mock.assert_called_once_with(1) - -@pytest.mark.asyncio -@patch("litellm.proxy.client.cli.commands.auth.requests.get", side_effect=[Mock(status_code=200, json=Mock(return_value={"status": "pending","json": "data"})), Mock(status_code=200, json=Mock(return_value={"status": "pending","json": "data"}))]) -@patch("litellm.proxy.client.cli.commands.auth.click.echo") -@patch("litellm.proxy.client.cli.commands.auth.time.sleep") -async def test_poll_for_ready_pending(sleep_mock, click_mock, request_mock): - """Test poll_for_ready function""" - actual = _poll_for_ready_data("https://litellm.com", poll_interval=1, total_timeout=2, request_timeout=42, pending_message="Pending message", pending_log_every=1) - assert actual is None - click_mock.assert_has_calls([ - call("Pending message"), - call("Pending message") - ]) - request_mock.assert_has_calls([ - call("https://litellm.com", timeout=42), - call("https://litellm.com", timeout=42) - ]) - sleep_mock.assert_has_calls([ - call(1), - call(1) - ]) - - -@pytest.mark.asyncio -@patch("litellm.proxy.client.cli.commands.auth.requests.get", side_effect=[requests.RequestException("ERROR"), - requests.RequestException("ERROR")]) -@patch("litellm.proxy.client.cli.commands.auth.click.echo") -@patch("litellm.proxy.client.cli.commands.auth.time.sleep") -async def test_poll_for_ready_connection_failure(sleep_mock, click_mock, request_mock): - """Test poll_for_ready function""" - actual = _poll_for_ready_data("https://litellm.com", poll_interval=1, total_timeout=2, request_timeout=42) - assert actual is None - click_mock.assert_called_once_with("Connection error (will retry): ERROR") - request_mock.assert_has_calls([ - call("https://litellm.com", timeout=42), - ]) - sleep_mock.assert_has_calls([ - call(1), - call(1) - ]) - - -@pytest.mark.asyncio -@patch("litellm.proxy.client.cli.commands.auth._handle_team_selection_during_polling") -@patch("litellm.proxy.client.cli.commands.auth._poll_for_ready_data", return_value=None) -@patch("litellm.proxy.client.cli.commands.auth.click.echo") -async def test_poll_for_authentication_no_data(click_mock, poll_mock, handle_mock): - """Test poll_for_authentication function""" - actual = _poll_for_authentication("https://litellm.com", "key-123") - assert actual is None - poll_mock.assert_called_once_with( - "https://litellm.com/sso/cli/poll/key-123", - pending_message="Still waiting for authentication...", - ) - handle_mock.assert_not_called() - click_mock.assert_not_called() - - -@pytest.mark.asyncio -@patch("litellm.proxy.client.cli.commands.auth._handle_team_selection_during_polling") -@patch("litellm.proxy.client.cli.commands.auth._poll_for_ready_data", return_value={"requires_team_selection": True, "teams": [], "team_details": []}) -@patch("litellm.proxy.client.cli.commands.auth.click.echo") -async def test_poll_for_authentication_no_teams(click_mock, poll_mock, handle_mock): - """Test poll_for_authentication function""" - actual = _poll_for_authentication("https://litellm.com", "key-123") - assert actual is None - poll_mock.assert_called_once_with( - "https://litellm.com/sso/cli/poll/key-123", - pending_message="Still waiting for authentication...", - ) - handle_mock.assert_not_called() - click_mock.assert_called_once() - assert "No teams available for selection." in click_mock.call_args[0][0] - - -@pytest.mark.asyncio -@patch("litellm.proxy.client.cli.commands.auth._handle_team_selection_during_polling", return_value="jwt-123") -@patch("litellm.proxy.client.cli.commands.auth._poll_for_ready_data", return_value={"requires_team_selection": True, "teams": [1, 2], "user_id": "user-123"}) -@patch("litellm.proxy.client.cli.commands.auth.click.echo") -async def test_poll_for_authentication_team_selection_success(click_mock, poll_mock, handle_mock): - """Test poll_for_authentication function""" - actual = _poll_for_authentication("https://litellm.com", "key-123") - assert actual == {"api_key": "jwt-123", "user_id": "user-123", "teams": [1, 2], "team_id": None} - poll_mock.assert_called_once_with( - "https://litellm.com/sso/cli/poll/key-123", - pending_message="Still waiting for authentication...", - ) - handle_mock.assert_called_once_with( - base_url="https://litellm.com", - key_id="key-123", - teams=[{"team_id": "1", "team_alias": None}, {"team_id": "2", "team_alias": None}], - ) - click_mock.assert_not_called() - - -@pytest.mark.asyncio -@patch("litellm.proxy.client.cli.commands.auth._handle_team_selection_during_polling", return_value=None) -@patch("litellm.proxy.client.cli.commands.auth._poll_for_ready_data", return_value={"requires_team_selection": True, "teams": ["team-1"], "user_id": "user-123"}) -@patch("litellm.proxy.client.cli.commands.auth.click.echo") -async def test_poll_for_authentication_team_selection_cancelled(click_mock, poll_mock, handle_mock): - """Test poll_for_authentication function""" - actual = _poll_for_authentication("https://litellm.com", "key-123") - assert actual is None - poll_mock.assert_called_once_with( - "https://litellm.com/sso/cli/poll/key-123", - pending_message="Still waiting for authentication...", - ) - handle_mock.assert_called_once_with( - base_url="https://litellm.com", - key_id="key-123", - teams=[{"team_id": "team-1", "team_alias": None}], - ) - click_mock.assert_called_once() - assert "Team selection cancelled" in click_mock.call_args[0][0] - - -@pytest.mark.asyncio -@patch("litellm.proxy.client.cli.commands.auth._handle_team_selection_during_polling") -@patch("litellm.proxy.client.cli.commands.auth._poll_for_ready_data", return_value={"key": "jwt-456", "user_id": "user-456", "teams": ["team-1"], "team_id": "team-1"}) -@patch("litellm.proxy.client.cli.commands.auth.click.echo") -async def test_poll_for_authentication_auto_assigned_team(click_mock, poll_mock, handle_mock): - """Test poll_for_authentication function""" - actual = _poll_for_authentication("https://litellm.com", "key-123") - assert actual == {"api_key": "jwt-456", "user_id": "user-456", "teams": ["team-1"], "team_id": "team-1"} - poll_mock.assert_called_once_with( - "https://litellm.com/sso/cli/poll/key-123", - pending_message="Still waiting for authentication...", - ) - handle_mock.assert_not_called() - click_mock.assert_called_once() - assert "Automatically assigned to team: team-1" in click_mock.call_args[0][0] diff --git a/tests/test_litellm/proxy/auth/test_route_checks.py b/tests/test_litellm/proxy/auth/test_route_checks.py index a745ac3de13..b8084906fa5 100644 --- a/tests/test_litellm/proxy/auth/test_route_checks.py +++ b/tests/test_litellm/proxy/auth/test_route_checks.py @@ -161,11 +161,9 @@ def test_virtual_key_llm_api_route_includes_passthrough_prefix(route): [ "/v1beta/models/gemini-2.5-flash:countTokens", "/v1beta/models/gemini-2.0-flash:generateContent", - "/v1beta/models/bedrock/claude-sonnet-3.7:generateContent", "/v1beta/models/gemini-1.5-pro:streamGenerateContent", "/models/gemini-2.5-flash:countTokens", "/models/gemini-2.0-flash:generateContent", - "/models/bedrock/claude-sonnet-3.7:generateContent", "/models/gemini-1.5-pro:streamGenerateContent", ], ) @@ -189,11 +187,9 @@ def test_virtual_key_llm_api_routes_allows_google_routes(route): "/v1beta/models/google-gemini-2-5-pro-code-reviewer-k8s:generateContent", "/v1beta/models/gemini-2.5-flash-exp:countTokens", "/v1beta/models/custom-model-name-123:streamGenerateContent", - "/v1beta/models/bedrock/claude-sonnet-3.7:generateContent", "/models/google-gemini-2-5-pro-code-reviewer-k8s:generateContent", "/models/gemini-2.5-flash-exp:countTokens", "/models/custom-model-name-123:streamGenerateContent", - "/models/bedrock/claude-sonnet-3.7:generateContent", ], ) def test_google_routes_with_dynamic_model_names_recognized_as_llm_api_route(route): diff --git a/tests/test_litellm/proxy/google_endpoints/test_interactions_agent_param.py b/tests/test_litellm/proxy/google_endpoints/test_interactions_agent_param.py deleted file mode 100644 index 1063f59afb6..00000000000 --- a/tests/test_litellm/proxy/google_endpoints/test_interactions_agent_param.py +++ /dev/null @@ -1,75 +0,0 @@ -""" -Test for interactions endpoint agent parameter handling. - -Tests that the /v1beta/interactions endpoint correctly extracts -the `agent` parameter as a fallback when `model` is not provided. -""" - -import pytest - - -class TestInteractionsAgentParameter: - """Test agent parameter handling in interactions endpoint.""" - - def test_agent_parameter_fallback_logic(self): - """ - Test the core logic: model or agent extraction. - - This tests the fix in endpoints.py line ~267: - model=data.get("model") or data.get("agent") - """ - # Case 1: Only agent provided (Deep Research use case) - data = { - "agent": "deep-research-pro-preview-12-2025", - "input": "Research quantum computing", - "background": True, - } - model = data.get("model") or data.get("agent") - assert model == "deep-research-pro-preview-12-2025" - - # Case 2: Only model provided (normal use case) - data = { - "model": "gemini-2.5-flash", - "input": "Hello world", - } - model = data.get("model") or data.get("agent") - assert model == "gemini-2.5-flash" - - # Case 3: Both provided (model takes precedence) - data = { - "model": "gemini-2.5-flash", - "agent": "deep-research-pro-preview-12-2025", - "input": "Test", - } - model = data.get("model") or data.get("agent") - assert model == "gemini-2.5-flash" - - # Case 4: Neither provided - data = { - "input": "Test", - } - model = data.get("model") or data.get("agent") - assert model is None - - def test_route_type_in_skip_model_routing_list(self): - """ - Test that acreate_interaction is in the list of routes - that skip model-based routing. - - This tests the fix in route_llm_request.py. - """ - # The list of routes that skip model routing for interactions - skip_model_routing_routes = [ - "acreate_interaction", - "aget_interaction", - "adelete_interaction", - "acancel_interaction", - ] - - # acreate_interaction should be in the list (this is the fix) - assert "acreate_interaction" in skip_model_routing_routes - - # All interaction routes should be covered - assert "aget_interaction" in skip_model_routing_routes - assert "adelete_interaction" in skip_model_routing_routes - assert "acancel_interaction" in skip_model_routing_routes diff --git a/tests/test_litellm/proxy/guardrails/guardrail_hooks/content_filter/test_content_filter.py b/tests/test_litellm/proxy/guardrails/guardrail_hooks/content_filter/test_content_filter.py index be8c84a554f..265bc530dc2 100644 --- a/tests/test_litellm/proxy/guardrails/guardrail_hooks/content_filter/test_content_filter.py +++ b/tests/test_litellm/proxy/guardrails/guardrail_hooks/content_filter/test_content_filter.py @@ -4,7 +4,7 @@ import os import sys -from unittest.mock import MagicMock +from unittest.mock import AsyncMock, MagicMock, patch import pytest @@ -385,12 +385,20 @@ def test_api_key_patterns(self): assert result is not None assert result[1] == "aws_access_key" + @pytest.mark.skip( + reason="Masking in streaming responses is no longer supported after unified_guardrail.py changes. Only blocking/rejecting is supported for responses." + ) @pytest.mark.asyncio async def test_streaming_hook_mask(self): """ - Test streaming hook with MASK action. - This now works with the 50-char sliding window buffer. + Test streaming hook with MASK action + + Note: After changes to unified_guardrail.py, masking responses to users + is no longer supported. This test is skipped as the feature is deprecated. + Only BLOCK actions (test_streaming_hook_block) are supported for streaming responses. """ + from unittest.mock import AsyncMock + from litellm.types.utils import Delta, ModelResponseStream, StreamingChoices patterns = [ @@ -407,54 +415,51 @@ async def test_streaming_hook_mask(self): event_hook=GuardrailEventHooks.during_call, ) - # Create mock streaming chunks that split an email + # Create mock streaming chunks async def mock_stream(): - # Chunk 1: starts email - yield ModelResponseStream( + # Chunk 1: contains email + chunk1 = ModelResponseStream( id="chunk1", choices=[ StreamingChoices( - delta=Delta(content="Contact me at test@ex"), index=0 + delta=Delta(content="Contact me at test@example.com"), index=0 ) ], model="gpt-4", ) - # Chunk 2: ends email - yield ModelResponseStream( + yield chunk1 + + # Chunk 2: normal content + chunk2 = ModelResponseStream( id="chunk2", choices=[ - StreamingChoices( - delta=Delta(content="ample.com for info"), - index=0, - finish_reason="stop", - ) + StreamingChoices(delta=Delta(content=" for more info"), index=0) ], model="gpt-4", ) + yield chunk2 user_api_key_dict = MagicMock() request_data = {} - # Process streaming response - masking IS expected now - full_content = "" + # Process streaming response - no masking expected + result_chunks = [] async for chunk in guardrail.async_post_call_streaming_iterator_hook( user_api_key_dict=user_api_key_dict, response=mock_stream(), request_data=request_data, ): - if chunk.choices[0].delta.content: - full_content += chunk.choices[0].delta.content + result_chunks.append(chunk) - # The email should be redacted even though it was split - assert "test@example.com" not in full_content - assert "[EMAIL_REDACTED]" in full_content - assert "Contact me at [EMAIL_REDACTED] for info" in full_content + # Chunks should pass through unchanged since masking is no longer supported + assert len(result_chunks) == 2 @pytest.mark.asyncio async def test_streaming_hook_block(self): """ Test streaming hook with BLOCK action """ + from unittest.mock import AsyncMock from litellm.types.utils import Delta, ModelResponseStream, StreamingChoices @@ -710,10 +715,7 @@ async def test_apply_guardrail_masks_all_regex_pattern_matches(self): assert result is not None assert len(result) == 1 # All matches should be redacted - assert ( - result[0] - == "[CUSTOM_KEY_REDACTED] [CUSTOM_KEY_REDACTED] [CUSTOM_KEY_REDACTED]" - ) + assert result[0] == "[CUSTOM_KEY_REDACTED] [CUSTOM_KEY_REDACTED] [CUSTOM_KEY_REDACTED]" assert "Key1" not in result[0] assert "Key2" not in result[0] @@ -795,7 +797,7 @@ async def test_apply_guardrail_logs_guardrail_information(self): # Apply guardrail with content that triggers detections # Email will be masked, blocked word will be masked - await guardrail.apply_guardrail( + result = await guardrail.apply_guardrail( inputs={"texts": ["Contact me at test@example.com for confidential info"]}, request_data=request_data, input_type="request", @@ -805,9 +807,7 @@ async def test_apply_guardrail_logs_guardrail_information(self): assert "metadata" in request_data assert "standard_logging_guardrail_information" in request_data["metadata"] - guardrail_info_list = request_data["metadata"][ - "standard_logging_guardrail_information" - ] + guardrail_info_list = request_data["metadata"]["standard_logging_guardrail_information"] assert isinstance(guardrail_info_list, list) assert len(guardrail_info_list) == 1 @@ -820,8 +820,8 @@ async def test_apply_guardrail_logs_guardrail_information(self): assert "start_time" in guardrail_info assert "end_time" in guardrail_info assert "duration" in guardrail_info - assert guardrail_info["duration"] >= 0 - assert guardrail_info["start_time"] <= guardrail_info["end_time"] + assert guardrail_info["duration"] > 0 + assert guardrail_info["start_time"] < guardrail_info["end_time"] # Verify detections are logged assert "guardrail_response" in guardrail_info @@ -839,21 +839,15 @@ async def test_apply_guardrail_logs_guardrail_information(self): assert "action" in detection assert detection["action"] == "MASK" # Verify sensitive content (matched_text) is NOT included - assert ( - "matched_text" not in detection - ), "Sensitive content should not be logged" + assert "matched_text" not in detection, "Sensitive content should not be logged" # Verify blocked word detection structure - blocked_word_detections = [ - d for d in detections if d.get("type") == "blocked_word" - ] + blocked_word_detections = [d for d in detections if d.get("type") == "blocked_word"] assert len(blocked_word_detections) > 0 for detection in blocked_word_detections: assert detection["type"] == "blocked_word" assert "keyword" in detection - assert ( - detection["keyword"] == "confidential" - ) # Config keyword, not user content + assert detection["keyword"] == "confidential" # Config keyword, not user content assert "action" in detection assert detection["action"] == "MASK" assert "description" in detection @@ -902,9 +896,7 @@ async def test_apply_guardrail_logs_blocked_status(self): assert "metadata" in request_data assert "standard_logging_guardrail_information" in request_data["metadata"] - guardrail_info_list = request_data["metadata"][ - "standard_logging_guardrail_information" - ] + guardrail_info_list = request_data["metadata"]["standard_logging_guardrail_information"] assert len(guardrail_info_list) == 1 guardrail_info = guardrail_info_list[0] @@ -917,6 +909,4 @@ async def test_apply_guardrail_logs_blocked_status(self): # If detections are logged, verify they don't contain sensitive content for detection in detections: if detection.get("type") == "pattern": - assert ( - "matched_text" not in detection - ), "Sensitive content should not be logged" + assert "matched_text" not in detection, "Sensitive content should not be logged" diff --git a/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_onyx.py b/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_onyx.py index fb7480d263c..9ede649f392 100644 --- a/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_onyx.py +++ b/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_onyx.py @@ -3,7 +3,6 @@ import uuid from unittest.mock import AsyncMock, MagicMock, patch -import httpx import pytest from fastapi import HTTPException from httpx import Request, Response @@ -48,129 +47,20 @@ def test_onyx_guard_config(): del os.environ["ONYX_API_KEY"] -def test_onyx_guard_with_custom_timeout_from_kwargs(): - """Test Onyx guard instantiation with custom timeout passed via kwargs.""" - # Set environment variables for testing - os.environ["ONYX_API_BASE"] = "https://test.onyx.security" - os.environ["ONYX_API_KEY"] = "test-api-key" - - with patch( - "litellm.proxy.guardrails.guardrail_hooks.onyx.onyx.get_async_httpx_client" - ) as mock_get_client: - mock_get_client.return_value = MagicMock() - - # Simulate how guardrail is instantiated from config with timeout - guardrail = OnyxGuardrail( - guardrail_name="onyx-guard-custom-timeout", - event_hook="pre_call", - default_on=True, - timeout=45.0, - ) - - # Verify the client was initialized with custom timeout - mock_get_client.assert_called() - call_kwargs = mock_get_client.call_args.kwargs - timeout_param = call_kwargs["params"]["timeout"] - assert timeout_param.read == 45.0 - assert timeout_param.connect == 5.0 - - # Clean up - if "ONYX_API_BASE" in os.environ: - del os.environ["ONYX_API_BASE"] - if "ONYX_API_KEY" in os.environ: - del os.environ["ONYX_API_KEY"] - - -def test_onyx_guard_with_timeout_none_uses_env_var(): - """Test Onyx guard with timeout=None uses ONYX_TIMEOUT env var. - - When timeout=None is passed (as it would be from config model with default None), - the ONYX_TIMEOUT environment variable should be used. - """ - # Set environment variables for testing - os.environ["ONYX_API_BASE"] = "https://test.onyx.security" - os.environ["ONYX_API_KEY"] = "test-api-key" - os.environ["ONYX_TIMEOUT"] = "60" - - with patch( - "litellm.proxy.guardrails.guardrail_hooks.onyx.onyx.get_async_httpx_client" - ) as mock_get_client: - mock_get_client.return_value = MagicMock() - - # Pass timeout=None to simulate config model behavior - guardrail = OnyxGuardrail( - guardrail_name="onyx-guard-env-timeout", - event_hook="pre_call", - default_on=True, - timeout=None, # This triggers env var lookup - ) - - # Verify the client was initialized with timeout from env var - mock_get_client.assert_called() - call_kwargs = mock_get_client.call_args.kwargs - timeout_param = call_kwargs["params"]["timeout"] - assert timeout_param.read == 60.0 - assert timeout_param.connect == 5.0 - - # Clean up - if "ONYX_API_BASE" in os.environ: - del os.environ["ONYX_API_BASE"] - if "ONYX_API_KEY" in os.environ: - del os.environ["ONYX_API_KEY"] - if "ONYX_TIMEOUT" in os.environ: - del os.environ["ONYX_TIMEOUT"] - - -def test_onyx_guard_with_timeout_none_defaults_to_10(): - """Test Onyx guard with timeout=None and no env var defaults to 10 seconds.""" - # Set environment variables for testing - os.environ["ONYX_API_BASE"] = "https://test.onyx.security" - os.environ["ONYX_API_KEY"] = "test-api-key" - # Ensure ONYX_TIMEOUT is not set - if "ONYX_TIMEOUT" in os.environ: - del os.environ["ONYX_TIMEOUT"] - - with patch( - "litellm.proxy.guardrails.guardrail_hooks.onyx.onyx.get_async_httpx_client" - ) as mock_get_client: - mock_get_client.return_value = MagicMock() - - # Pass timeout=None with no env var - should default to 10.0 - guardrail = OnyxGuardrail( - guardrail_name="onyx-guard-default-timeout", - event_hook="pre_call", - default_on=True, - timeout=None, - ) - - # Verify the client was initialized with default timeout of 10.0 - mock_get_client.assert_called() - call_kwargs = mock_get_client.call_args.kwargs - timeout_param = call_kwargs["params"]["timeout"] - assert timeout_param.read == 10.0 - assert timeout_param.connect == 5.0 - - # Clean up - if "ONYX_API_BASE" in os.environ: - del os.environ["ONYX_API_BASE"] - if "ONYX_API_KEY" in os.environ: - del os.environ["ONYX_API_KEY"] - - class TestOnyxGuardrail: """Test suite for Onyx Security Guardrail integration.""" def setup_method(self): """Setup test environment.""" # Clean up any existing environment variables - for key in ["ONYX_API_BASE", "ONYX_API_KEY", "ONYX_TIMEOUT"]: + for key in ["ONYX_API_BASE", "ONYX_API_KEY"]: if key in os.environ: del os.environ[key] def teardown_method(self): """Clean up test environment.""" # Clean up any environment variables set during tests - for key in ["ONYX_API_BASE", "ONYX_API_KEY", "ONYX_TIMEOUT"]: + for key in ["ONYX_API_BASE", "ONYX_API_KEY"]: if key in os.environ: del os.environ[key] @@ -213,95 +103,6 @@ def test_initialization_fails_when_api_key_missing(self): ): OnyxGuardrail(guardrail_name="test-guard", event_hook="pre_call") - def test_initialization_with_default_timeout(self): - """Test that default timeout is 10.0 seconds.""" - os.environ["ONYX_API_KEY"] = "test-api-key" - - with patch( - "litellm.proxy.guardrails.guardrail_hooks.onyx.onyx.get_async_httpx_client" - ) as mock_get_client: - mock_get_client.return_value = MagicMock() - guardrail = OnyxGuardrail( - guardrail_name="test-guard", event_hook="pre_call", default_on=True - ) - - # Verify the client was initialized with correct timeout - mock_get_client.assert_called_once() - call_kwargs = mock_get_client.call_args.kwargs - timeout_param = call_kwargs["params"]["timeout"] - assert timeout_param.read == 10.0 - assert timeout_param.connect == 5.0 - - def test_initialization_with_custom_timeout_parameter(self): - """Test initialization with custom timeout parameter.""" - os.environ["ONYX_API_KEY"] = "test-api-key" - - with patch( - "litellm.proxy.guardrails.guardrail_hooks.onyx.onyx.get_async_httpx_client" - ) as mock_get_client: - mock_get_client.return_value = MagicMock() - guardrail = OnyxGuardrail( - guardrail_name="test-guard", - event_hook="pre_call", - default_on=True, - timeout=30.0, - ) - - # Verify the client was initialized with custom timeout - mock_get_client.assert_called_once() - call_kwargs = mock_get_client.call_args.kwargs - timeout_param = call_kwargs["params"]["timeout"] - assert timeout_param.read == 30.0 - assert timeout_param.connect == 5.0 - - def test_initialization_with_timeout_from_env_var(self): - """Test initialization with timeout from ONYX_TIMEOUT environment variable. - - Note: The env var is only used when timeout=None is explicitly passed, - since the default parameter value is 10.0 (not None). - """ - os.environ["ONYX_API_KEY"] = "test-api-key" - os.environ["ONYX_TIMEOUT"] = "25" - - with patch( - "litellm.proxy.guardrails.guardrail_hooks.onyx.onyx.get_async_httpx_client" - ) as mock_get_client: - mock_get_client.return_value = MagicMock() - # Must pass timeout=None explicitly to trigger env var lookup - guardrail = OnyxGuardrail( - guardrail_name="test-guard", event_hook="pre_call", default_on=True, timeout=None - ) - - # Verify the client was initialized with timeout from env var - mock_get_client.assert_called_once() - call_kwargs = mock_get_client.call_args.kwargs - timeout_param = call_kwargs["params"]["timeout"] - assert timeout_param.read == 25.0 - assert timeout_param.connect == 5.0 - - def test_initialization_timeout_parameter_overrides_env_var(self): - """Test that timeout parameter overrides ONYX_TIMEOUT environment variable.""" - os.environ["ONYX_API_KEY"] = "test-api-key" - os.environ["ONYX_TIMEOUT"] = "25" - - with patch( - "litellm.proxy.guardrails.guardrail_hooks.onyx.onyx.get_async_httpx_client" - ) as mock_get_client: - mock_get_client.return_value = MagicMock() - guardrail = OnyxGuardrail( - guardrail_name="test-guard", - event_hook="pre_call", - default_on=True, - timeout=15.0, - ) - - # Verify the client was initialized with parameter timeout (not env var) - mock_get_client.assert_called_once() - call_kwargs = mock_get_client.call_args.kwargs - timeout_param = call_kwargs["params"]["timeout"] - assert timeout_param.read == 15.0 - assert timeout_param.connect == 5.0 - @pytest.mark.asyncio async def test_apply_guardrail_request_no_violations(self): """Test apply_guardrail for request with no violations detected.""" @@ -587,105 +388,6 @@ async def test_apply_guardrail_api_error_handling(self): assert result == inputs - @pytest.mark.asyncio - async def test_apply_guardrail_timeout_error_handling(self): - """Test handling of timeout errors in apply_guardrail (graceful degradation).""" - # Set required API key - os.environ["ONYX_API_KEY"] = "test-api-key" - - guardrail = OnyxGuardrail( - guardrail_name="test-guard", event_hook="pre_call", default_on=True, timeout=1.0 - ) - - inputs = GenericGuardrailAPIInputs() - - request_data = { - "proxy_server_request": { - "messages": [{"role": "user", "content": "Test message"}], - "model": "gpt-3.5-turbo", - } - } - - # Test httpx timeout error - with patch.object( - guardrail.async_handler, "post", side_effect=httpx.TimeoutException("Request timed out") - ): - # Should return original inputs on timeout (graceful degradation) - result = await guardrail.apply_guardrail( - inputs=inputs, - request_data=request_data, - input_type="request", - logging_obj=None, - ) - - assert result == inputs - - @pytest.mark.asyncio - async def test_apply_guardrail_read_timeout_error_handling(self): - """Test handling of read timeout errors in apply_guardrail.""" - # Set required API key - os.environ["ONYX_API_KEY"] = "test-api-key" - - guardrail = OnyxGuardrail( - guardrail_name="test-guard", event_hook="pre_call", default_on=True, timeout=5.0 - ) - - inputs = GenericGuardrailAPIInputs() - - request_data = { - "proxy_server_request": { - "messages": [{"role": "user", "content": "Test message"}], - "model": "gpt-3.5-turbo", - } - } - - # Test httpx ReadTimeout error - with patch.object( - guardrail.async_handler, "post", side_effect=httpx.ReadTimeout("Read timed out") - ): - # Should return original inputs on timeout (graceful degradation) - result = await guardrail.apply_guardrail( - inputs=inputs, - request_data=request_data, - input_type="request", - logging_obj=None, - ) - - assert result == inputs - - @pytest.mark.asyncio - async def test_apply_guardrail_connect_timeout_error_handling(self): - """Test handling of connect timeout errors in apply_guardrail.""" - # Set required API key - os.environ["ONYX_API_KEY"] = "test-api-key" - - guardrail = OnyxGuardrail( - guardrail_name="test-guard", event_hook="pre_call", default_on=True, timeout=5.0 - ) - - inputs = GenericGuardrailAPIInputs() - - request_data = { - "proxy_server_request": { - "messages": [{"role": "user", "content": "Test message"}], - "model": "gpt-3.5-turbo", - } - } - - # Test httpx ConnectTimeout error - with patch.object( - guardrail.async_handler, "post", side_effect=httpx.ConnectTimeout("Connect timed out") - ): - # Should return original inputs on timeout (graceful degradation) - result = await guardrail.apply_guardrail( - inputs=inputs, - request_data=request_data, - input_type="request", - logging_obj=None, - ) - - assert result == inputs - @pytest.mark.asyncio async def test_apply_guardrail_no_logging_obj(self): """Test apply_guardrail without logging object (uses UUID).""" diff --git a/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_presidio.py b/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_presidio.py index fc4ff28c774..42af3942f1a 100644 --- a/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_presidio.py +++ b/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_presidio.py @@ -4,9 +4,10 @@ """ import asyncio +import json import os import sys -from unittest.mock import MagicMock, patch +from unittest.mock import AsyncMock, MagicMock, patch import pytest @@ -624,7 +625,7 @@ async def mock_check_pii(text, output_parse_pii, presidio_config, request_data): return text with patch.object(presidio, "check_pii", mock_check_pii): - await presidio.apply_guardrail( + result = await presidio.apply_guardrail( inputs={"texts": ["Test message"]}, request_data=request_data, input_type="request", @@ -708,21 +709,16 @@ def add_litellm_callback(self, cb): monkeypatch.setattr(litellm, "logging_callback_manager", mgr, raising=False) import litellm.proxy.guardrails.guardrail_initializers as gi import litellm.proxy.guardrails.guardrail_hooks.presidio as presidio_mod - monkeypatch.setattr( presidio_mod, "_OPTIONAL_PresidioPIIMasking", DummyGuardrail, raising=False ) - monkeypatch.setattr( - gi, "_OPTIONAL_PresidioPIIMasking", DummyGuardrail, raising=False - ) + monkeypatch.setattr(gi, "_OPTIONAL_PresidioPIIMasking", DummyGuardrail, raising=False) # input-only created.clear() from litellm.proxy.guardrails.guardrail_initializers import initialize_presidio - params_input = LitellmParams( - guardrail="presidio", mode="pre_call", presidio_filter_scope="input" - ) + params_input = LitellmParams(guardrail="presidio", mode="pre_call", presidio_filter_scope="input") guardrail_dict = {"guardrail_name": "g1"} cb = initialize_presidio(params_input, guardrail_dict) assert cb is created[0] @@ -730,18 +726,14 @@ def add_litellm_callback(self, cb): # output-only created.clear() - params_output = LitellmParams( - guardrail="presidio", mode="pre_call", presidio_filter_scope="output" - ) + params_output = LitellmParams(guardrail="presidio", mode="pre_call", presidio_filter_scope="output") cb = initialize_presidio(params_output, guardrail_dict) assert len(created) == 1 assert created[0].apply_to_output is True # both -> expect two callbacks (input + output) created.clear() - params_both = LitellmParams( - guardrail="presidio", mode="pre_call", presidio_filter_scope="both" - ) + params_both = LitellmParams(guardrail="presidio", mode="pre_call", presidio_filter_scope="both") cb = initialize_presidio(params_both, guardrail_dict) assert len(created) == 2 assert any(not c.apply_to_output for c in created) @@ -749,15 +741,13 @@ def add_litellm_callback(self, cb): @pytest.mark.asyncio -async def test_empty_content_handling( - presidio_guardrail, mock_user_api_key, mock_cache -): +async def test_empty_content_handling(presidio_guardrail, mock_user_api_key, mock_cache): """ Test that Presidio handles empty content gracefully. - + This is common in tool/function calling where assistant messages have empty content but include tool_calls. - + Bug fix: Previously crashed with: TypeError: argument after ** must be a mapping, not str """ @@ -771,10 +761,7 @@ async def test_empty_content_handling( { "id": "call_123", "type": "function", - "function": { - "name": "calculator", - "arguments": '{"a":2,"b":2}', - }, + "function": {"name": "calculator", "arguments": '{"a":2,"b":2}'}, } ], }, @@ -807,12 +794,10 @@ async def mock_check_pii(text, output_parse_pii, presidio_config, request_data): @pytest.mark.asyncio -async def test_whitespace_only_content( - presidio_guardrail, mock_user_api_key, mock_cache -): +async def test_whitespace_only_content(presidio_guardrail, mock_user_api_key, mock_cache): """ Test that Presidio handles whitespace-only content gracefully. - + Whitespace-only content should be treated the same as empty content. """ test_data = { @@ -847,7 +832,7 @@ async def mock_check_pii(text, output_parse_pii, presidio_config, request_data): async def test_analyze_text_with_empty_string(): """ Test analyze_text method directly with empty string. - + Should return empty list without making API call to Presidio. """ presidio = _OPTIONAL_PresidioPIIMasking( @@ -879,7 +864,7 @@ async def test_analyze_text_with_empty_string(): async def test_analyze_text_error_dict_handling(): """ Test that analyze_text handles error dict responses from Presidio API. - + When Presidio returns {'error': 'No text provided'}, should handle gracefully instead of crashing with TypeError. """ @@ -893,20 +878,16 @@ async def test_analyze_text_error_dict_handling(): class MockResponse: async def json(self): return {"error": "No text provided"} - async def __aenter__(self): return self - async def __aexit__(self, *args): pass - + class MockSession: def post(self, *args, **kwargs): return MockResponse() - async def __aenter__(self): return self - async def __aexit__(self, *args): pass @@ -923,12 +904,10 @@ async def __aexit__(self, *args): @pytest.mark.asyncio -async def test_tool_calling_complete_scenario( - presidio_guardrail, mock_user_api_key, mock_cache -): +async def test_tool_calling_complete_scenario(presidio_guardrail, mock_user_api_key, mock_cache): """ Test complete tool calling scenario with PII in user message. - + This tests the real-world scenario where: 1. User provides a query with PII 2. Assistant responds with empty content + tool_calls @@ -1023,12 +1002,7 @@ def test_no_thresholds_returns_all(): guardrail = _OPTIONAL_PresidioPIIMasking(mock_testing=True) analyze_results = [ {"entity_type": PiiEntityType.CREDIT_CARD, "score": 0.1, "start": 0, "end": 4}, - { - "entity_type": PiiEntityType.EMAIL_ADDRESS, - "score": 0.2, - "start": 5, - "end": 9, - }, + {"entity_type": PiiEntityType.EMAIL_ADDRESS, "score": 0.2, "start": 5, "end": 9}, ] filtered = guardrail.filter_analyze_results_by_score(analyze_results) @@ -1045,12 +1019,7 @@ def test_entity_specific_threshold_only_applies_to_that_entity(): ) analyze_results = [ {"entity_type": PiiEntityType.CREDIT_CARD, "score": 0.7, "start": 0, "end": 4}, - { - "entity_type": PiiEntityType.EMAIL_ADDRESS, - "score": 0.1, - "start": 5, - "end": 9, - }, + {"entity_type": PiiEntityType.EMAIL_ADDRESS, "score": 0.1, "start": 5, "end": 9}, ] filtered = guardrail.filter_analyze_results_by_score(analyze_results) @@ -1069,12 +1038,7 @@ def test_filter_uses_default_all_threshold(): ) analyze_results = [ {"entity_type": PiiEntityType.CREDIT_CARD, "score": 0.7, "start": 0, "end": 4}, - { - "entity_type": PiiEntityType.EMAIL_ADDRESS, - "score": 0.8, - "start": 5, - "end": 9, - }, + {"entity_type": PiiEntityType.EMAIL_ADDRESS, "score": 0.8, "start": 5, "end": 9}, ] filtered = guardrail.filter_analyze_results_by_score(analyze_results) @@ -1095,12 +1059,7 @@ def test_entity_specific_overrides_default_threshold(): ) analyze_results = [ {"entity_type": PiiEntityType.CREDIT_CARD, "score": 0.65, "start": 0, "end": 4}, - { - "entity_type": PiiEntityType.EMAIL_ADDRESS, - "score": 0.75, - "start": 5, - "end": 9, - }, + {"entity_type": PiiEntityType.EMAIL_ADDRESS, "score": 0.75, "start": 5, "end": 9}, ] filtered = guardrail.filter_analyze_results_by_score(analyze_results) @@ -1175,59 +1134,3 @@ def test_update_in_memory_applies_score_thresholds(): guardrail.update_in_memory_litellm_params(params) assert guardrail.presidio_score_thresholds == {PiiEntityType.CREDIT_CARD: 0.85} - - -@pytest.mark.asyncio -async def test_get_session_iterator_thread_safety(presidio_guardrail): - """ - Test that _get_session_iterator yields: - 1. The shared session when in the main thread. - 2. A new session when in a background thread. - """ - import threading - import aiohttp - - # 1. Main Thread Case - # We are in the "main thread" relative to the guardrail initialization - async with presidio_guardrail._get_session_iterator() as session: - assert isinstance(session, aiohttp.ClientSession) - assert session is presidio_guardrail._http_session - shared_session_id = id(session) - - # 2. Background Thread Case - # Define a helper function to run in a thread - def thread_target(loop, result_future): - async def run_in_loop(): - # This runs in the thread's loop - async with presidio_guardrail._get_session_iterator() as session: - return session, id(session) - - try: - # Create a new loop for this thread to run async code - new_loop = asyncio.new_event_loop() - asyncio.set_event_loop(new_loop) - session_obj, session_id = new_loop.run_until_complete(run_in_loop()) - result_future.set_result((session_obj, session_id)) - new_loop.close() - except Exception as e: - result_future.set_exception(e) - - # Run the background thread test - bg_future = asyncio.Future() - t = threading.Thread( - target=thread_target, args=(asyncio.get_running_loop(), bg_future) - ) - t.start() - t.join() - - bg_session, bg_session_id = await bg_future - - # Assertions - # The background session should be DIFFERENT from the shared session - assert bg_session_id != shared_session_id - # The shared session should still be open (not closed by the background thread) - assert not presidio_guardrail._http_session.closed - # The background session should be closed (handled by the context manager in the thread) - assert bg_session.closed - - print("✓ Session iterator thread safety test passed") diff --git a/tests/test_litellm/proxy/hooks/test_post_call_streaming_hook_integration.py b/tests/test_litellm/proxy/hooks/test_post_call_streaming_hook_integration.py deleted file mode 100644 index 3bc111ef142..00000000000 --- a/tests/test_litellm/proxy/hooks/test_post_call_streaming_hook_integration.py +++ /dev/null @@ -1,273 +0,0 @@ -""" -Integration tests for async_post_call_streaming_hook. - -Tests verify that the streaming hook can transform streaming responses sent to clients. -""" - -import os -import sys -import pytest -from typing import Any -from unittest.mock import patch, MagicMock - -sys.path.insert(0, os.path.abspath("../../../..")) - -import litellm -from litellm.integrations.custom_logger import CustomLogger -from litellm.proxy._types import UserAPIKeyAuth -from litellm.types.utils import ModelResponseStream, StreamingChoices, Delta - - -class StreamingResponseTransformerLogger(CustomLogger): - """Logger that transforms streaming responses""" - - def __init__(self, transform_content: str = None): - self.called = False - self.transform_content = transform_content - self.received_response = None - - async def async_post_call_streaming_hook( - self, - user_api_key_dict: UserAPIKeyAuth, - response: str, - ) -> Any: - self.called = True - self.received_response = response - if self.transform_content is not None: - return self.transform_content - return None - - -@pytest.mark.asyncio -async def test_streaming_hook_transforms_response(): - """ - Test that async_post_call_streaming_hook can transform streaming responses. - """ - transformer = StreamingResponseTransformerLogger(transform_content="Modified streaming response") - - with patch("litellm.callbacks", [transformer]): - from litellm.proxy.utils import ProxyLogging - from litellm.caching.caching import DualCache - - proxy_logging = ProxyLogging(user_api_key_cache=DualCache()) - - # Create a mock streaming response - original_response = ModelResponseStream( - id="original-stream", - choices=[ - StreamingChoices( - delta=Delta(content="Original content", role="assistant"), - index=0, - ) - ], - model="test-model", - ) - - data = {"model": "test-model"} - user_api_key_dict = UserAPIKeyAuth(api_key="test-key") - - # Call the hook - result = await proxy_logging.async_post_call_streaming_hook( - data=data, - response=original_response, - user_api_key_dict=user_api_key_dict, - ) - - # Verify hook was called - assert transformer.called is True - - # Verify transformed response is returned - assert result == "Modified streaming response" - - -@pytest.mark.asyncio -async def test_streaming_hook_returns_none_keeps_original(): - """ - Test that hook returning None keeps the original response. - """ - - class NoOpLogger(CustomLogger): - def __init__(self): - self.called = False - - async def async_post_call_streaming_hook( - self, - user_api_key_dict: UserAPIKeyAuth, - response: str, - ): - self.called = True - return None - - logger = NoOpLogger() - - with patch("litellm.callbacks", [logger]): - from litellm.proxy.utils import ProxyLogging - from litellm.caching.caching import DualCache - - proxy_logging = ProxyLogging(user_api_key_cache=DualCache()) - - original_response = ModelResponseStream( - id="original-stream", - choices=[ - StreamingChoices( - delta=Delta(content="Original content", role="assistant"), - index=0, - ) - ], - model="test-model", - ) - - data = {"model": "test-model"} - user_api_key_dict = UserAPIKeyAuth(api_key="test-key") - - result = await proxy_logging.async_post_call_streaming_hook( - data=data, - response=original_response, - user_api_key_dict=user_api_key_dict, - ) - - # Should return original response object - assert result.id == "original-stream" - assert logger.called is True - - -@pytest.mark.asyncio -async def test_streaming_hook_works_with_sse_format(): - """ - Test that hook works with SSE-formatted strings (data: prefix). - This was the only supported format before the fix. - """ - transformer = StreamingResponseTransformerLogger( - transform_content="data: {\"error\": \"custom error\"}\n\n" - ) - - with patch("litellm.callbacks", [transformer]): - from litellm.proxy.utils import ProxyLogging - from litellm.caching.caching import DualCache - - proxy_logging = ProxyLogging(user_api_key_cache=DualCache()) - - original_response = ModelResponseStream( - id="original-stream", - choices=[ - StreamingChoices( - delta=Delta(content="Original content", role="assistant"), - index=0, - ) - ], - model="test-model", - ) - - data = {"model": "test-model"} - user_api_key_dict = UserAPIKeyAuth(api_key="test-key") - - result = await proxy_logging.async_post_call_streaming_hook( - data=data, - response=original_response, - user_api_key_dict=user_api_key_dict, - ) - - # Verify SSE-formatted response is returned - assert result == "data: {\"error\": \"custom error\"}\n\n" - - -@pytest.mark.asyncio -async def test_streaming_hook_chains_multiple_callbacks(): - """ - Test that multiple callbacks can chain modifications. - """ - - class AppendLogger(CustomLogger): - def __init__(self, suffix: str): - self.suffix = suffix - self.called = False - - async def async_post_call_streaming_hook( - self, - user_api_key_dict: UserAPIKeyAuth, - response: str, - ) -> str: - self.called = True - # Note: response here is the complete_response string, not the chunk - return f"[{self.suffix}]" - - callback1 = AppendLogger("CB1") - callback2 = AppendLogger("CB2") - - with patch("litellm.callbacks", [callback1, callback2]): - from litellm.proxy.utils import ProxyLogging - from litellm.caching.caching import DualCache - - proxy_logging = ProxyLogging(user_api_key_cache=DualCache()) - - original_response = ModelResponseStream( - id="original-stream", - choices=[ - StreamingChoices( - delta=Delta(content="Hello", role="assistant"), - index=0, - ) - ], - model="test-model", - ) - - data = {"model": "test-model"} - user_api_key_dict = UserAPIKeyAuth(api_key="test-key") - - result = await proxy_logging.async_post_call_streaming_hook( - data=data, - response=original_response, - user_api_key_dict=user_api_key_dict, - ) - - # Both callbacks should have been called - assert callback1.called is True - assert callback2.called is True - - # Last callback's result should be used - assert result == "[CB2]" - - -@pytest.mark.asyncio -async def test_streaming_hook_handles_exceptions(): - """ - Test that hook exceptions are propagated. - """ - - class FailingLogger(CustomLogger): - async def async_post_call_streaming_hook( - self, - user_api_key_dict: UserAPIKeyAuth, - response: str, - ): - raise RuntimeError("Streaming hook crashed!") - - logger = FailingLogger() - - with patch("litellm.callbacks", [logger]): - from litellm.proxy.utils import ProxyLogging - from litellm.caching.caching import DualCache - - proxy_logging = ProxyLogging(user_api_key_cache=DualCache()) - - original_response = ModelResponseStream( - id="original-stream", - choices=[ - StreamingChoices( - delta=Delta(content="Hello", role="assistant"), - index=0, - ) - ], - model="test-model", - ) - - data = {"model": "test-model"} - user_api_key_dict = UserAPIKeyAuth(api_key="test-key") - - # Exception should be propagated - with pytest.raises(RuntimeError, match="Streaming hook crashed!"): - await proxy_logging.async_post_call_streaming_hook( - data=data, - response=original_response, - user_api_key_dict=user_api_key_dict, - ) diff --git a/tests/test_litellm/proxy/hooks/test_post_call_success_hook_integration.py b/tests/test_litellm/proxy/hooks/test_post_call_success_hook_integration.py deleted file mode 100644 index 870286f5382..00000000000 --- a/tests/test_litellm/proxy/hooks/test_post_call_success_hook_integration.py +++ /dev/null @@ -1,260 +0,0 @@ -""" -Integration tests for async_post_call_success_hook. - -Tests verify that the success hook can transform responses sent to clients. -This mirrors the behavior of CustomGuardrail hooks and streaming iterator hooks. -""" - -import os -import sys -import pytest -from typing import Any -from unittest.mock import patch, MagicMock - -sys.path.insert(0, os.path.abspath("../../../..")) - -import litellm -from litellm.integrations.custom_logger import CustomLogger -from litellm.proxy._types import UserAPIKeyAuth -from litellm.types.utils import ModelResponse, Choices, Message, Usage - - -class ResponseTransformerLogger(CustomLogger): - """Logger that transforms successful responses""" - - def __init__(self, transform_content: str = None): - self.called = False - self.transform_content = transform_content - - async def async_post_call_success_hook( - self, - data: dict, - user_api_key_dict: UserAPIKeyAuth, - response: Any, - ) -> Any: - self.called = True - if self.transform_content is not None: - # Create a modified response with custom content - return { - "id": "transformed-response", - "choices": [ - { - "message": {"content": self.transform_content, "role": "assistant"}, - "index": 0, - } - ], - "model": "test-model", - "custom_field": "added_by_hook", - } - return response - - -@pytest.mark.asyncio -async def test_success_hook_transforms_response(): - """ - Test that async_post_call_success_hook can transform successful responses. - """ - transformer = ResponseTransformerLogger(transform_content="Modified response") - - with patch("litellm.callbacks", [transformer]): - from litellm.proxy.utils import ProxyLogging - from litellm.caching.caching import DualCache - - proxy_logging = ProxyLogging(user_api_key_cache=DualCache()) - - # Create a mock response - original_response = ModelResponse( - id="original-response", - choices=[ - Choices( - message=Message(content="Original content", role="assistant"), - index=0, - finish_reason="stop", - ) - ], - model="test-model", - usage=Usage(prompt_tokens=10, completion_tokens=20, total_tokens=30), - ) - - data = {"model": "test-model"} - user_api_key_dict = UserAPIKeyAuth(api_key="test-key") - - # Call the hook - result = await proxy_logging.post_call_success_hook( - data=data, - response=original_response, - user_api_key_dict=user_api_key_dict, - ) - - # Verify hook was called - assert transformer.called is True - - # Verify transformed response is returned - assert result is not None - assert result["id"] == "transformed-response" - assert result["choices"][0]["message"]["content"] == "Modified response" - assert result["custom_field"] == "added_by_hook" - - -@pytest.mark.asyncio -async def test_success_hook_returns_none_keeps_original(): - """ - Test that hook returning None keeps the original response. - """ - - class NoOpLogger(CustomLogger): - def __init__(self): - self.called = False - - async def async_post_call_success_hook(self, *args, **kwargs): - self.called = True - return None - - logger = NoOpLogger() - - with patch("litellm.callbacks", [logger]): - from litellm.proxy.utils import ProxyLogging - from litellm.caching.caching import DualCache - - proxy_logging = ProxyLogging(user_api_key_cache=DualCache()) - - original_response = ModelResponse( - id="original-response", - choices=[ - Choices( - message=Message(content="Original content", role="assistant"), - index=0, - finish_reason="stop", - ) - ], - model="test-model", - usage=Usage(prompt_tokens=10, completion_tokens=20, total_tokens=30), - ) - - data = {"model": "test-model"} - user_api_key_dict = UserAPIKeyAuth(api_key="test-key") - - result = await proxy_logging.post_call_success_hook( - data=data, - response=original_response, - user_api_key_dict=user_api_key_dict, - ) - - # Should return original response - assert result.id == "original-response" - assert logger.called is True - - -@pytest.mark.asyncio -async def test_success_hook_chains_multiple_callbacks(): - """ - Test that multiple callbacks can chain modifications. - """ - - class AddFieldLogger(CustomLogger): - def __init__(self, field_name: str, field_value: Any): - self.field_name = field_name - self.field_value = field_value - self.called = False - - async def async_post_call_success_hook( - self, - data: dict, - user_api_key_dict: UserAPIKeyAuth, - response: Any, - ) -> Any: - self.called = True - # Convert response to dict if needed - if hasattr(response, "model_dump"): - resp_dict = response.model_dump() - elif hasattr(response, "dict"): - resp_dict = response.dict() - elif isinstance(response, dict): - resp_dict = response.copy() - else: - resp_dict = {} - - resp_dict[self.field_name] = self.field_value - return resp_dict - - callback1 = AddFieldLogger("field1", "value1") - callback2 = AddFieldLogger("field2", "value2") - - with patch("litellm.callbacks", [callback1, callback2]): - from litellm.proxy.utils import ProxyLogging - from litellm.caching.caching import DualCache - - proxy_logging = ProxyLogging(user_api_key_cache=DualCache()) - - original_response = ModelResponse( - id="original-response", - choices=[ - Choices( - message=Message(content="Original content", role="assistant"), - index=0, - finish_reason="stop", - ) - ], - model="test-model", - usage=Usage(prompt_tokens=10, completion_tokens=20, total_tokens=30), - ) - - data = {"model": "test-model"} - user_api_key_dict = UserAPIKeyAuth(api_key="test-key") - - result = await proxy_logging.post_call_success_hook( - data=data, - response=original_response, - user_api_key_dict=user_api_key_dict, - ) - - # Both callbacks should have been called - assert callback1.called is True - assert callback2.called is True - - # Both fields should be present (chained modifications) - assert result["field1"] == "value1" - assert result["field2"] == "value2" - - -@pytest.mark.asyncio -async def test_success_hook_handles_exceptions(): - """ - Test that hook exceptions are propagated (not silently swallowed). - """ - - class FailingLogger(CustomLogger): - async def async_post_call_success_hook(self, *args, **kwargs): - raise RuntimeError("Hook crashed!") - - logger = FailingLogger() - - with patch("litellm.callbacks", [logger]): - from litellm.proxy.utils import ProxyLogging - from litellm.caching.caching import DualCache - - proxy_logging = ProxyLogging(user_api_key_cache=DualCache()) - - original_response = ModelResponse( - id="original-response", - choices=[ - Choices( - message=Message(content="Original content", role="assistant"), - index=0, - finish_reason="stop", - ) - ], - model="test-model", - usage=Usage(prompt_tokens=10, completion_tokens=20, total_tokens=30), - ) - - data = {"model": "test-model"} - user_api_key_dict = UserAPIKeyAuth(api_key="test-key") - - # Exception should be propagated - with pytest.raises(RuntimeError, match="Hook crashed!"): - await proxy_logging.post_call_success_hook( - data=data, - response=original_response, - user_api_key_dict=user_api_key_dict, - ) diff --git a/tests/test_litellm/proxy/management_endpoints/test_internal_user_endpoints.py b/tests/test_litellm/proxy/management_endpoints/test_internal_user_endpoints.py index dc436bac087..397a6af556f 100644 --- a/tests/test_litellm/proxy/management_endpoints/test_internal_user_endpoints.py +++ b/tests/test_litellm/proxy/management_endpoints/test_internal_user_endpoints.py @@ -1096,57 +1096,3 @@ async def mock_get_user_key_counts(*args, **kwargs): assert "user_id" in captured_where_conditions assert "in" in captured_where_conditions["user_id"] assert captured_where_conditions["user_id"]["in"] == ["user1", "user2", "user3"] - - -def test_update_internal_user_params_reset_max_budget_with_none(): - """ - Test that _update_internal_user_params allows setting max_budget to None. - This verifies the fix for unsetting/resetting the budget to unlimited. - """ - - # Case 1: max_budget is explicitly None in the input dictionary - data_json = {"max_budget": None, "user_id": "test_user"} - data = UpdateUserRequest(max_budget=None, user_id="test_user") - - # Call the function - non_default_values = _update_internal_user_params(data_json=data_json, data=data) - - # Assertions - assert "max_budget" in non_default_values - assert non_default_values["max_budget"] is None - assert non_default_values["user_id"] == "test_user" - - -def test_update_internal_user_params_ignores_other_nones(): - """ - Test that other fields are still filtered out if None - """ - # Create test data with other None fields - data_json = {"user_alias": None, "user_id": "test_user", "max_budget": 100.0} - data = UpdateUserRequest(user_alias=None, user_id="test_user", max_budget=100.0) - - # Call the function - non_default_values = _update_internal_user_params(data_json=data_json, data=data) - - # Assertions - assert "user_alias" not in non_default_values - assert non_default_values["max_budget"] == 100.0 - - -def test_generate_request_base_validator(): - """ - Test that GenerateRequestBase validator converts empty string to None for max_budget - """ - from litellm.proxy._types import GenerateRequestBase - - # Test with empty string - req = GenerateRequestBase(max_budget="") - assert req.max_budget is None - - # Test with actual float - req = GenerateRequestBase(max_budget=100.0) - assert req.max_budget == 100.0 - - # Test with None - req = GenerateRequestBase(max_budget=None) - assert req.max_budget is None \ No newline at end of file diff --git a/tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py b/tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py index a57378e579c..7d31f762096 100644 --- a/tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py +++ b/tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py @@ -30,13 +30,10 @@ _check_org_key_limits, _check_team_key_limits, _common_key_generation_helper, - _get_and_validate_existing_key, _list_key_helper, _persist_deleted_verification_tokens, - _process_single_key_update, _save_deleted_verification_token_records, _transform_verification_tokens_to_deleted_records, - _validate_max_budget, can_modify_verification_token, check_org_key_model_specific_limits, check_team_key_model_specific_limits, @@ -4226,467 +4223,3 @@ async def test_update_key_with_router_settings(monkeypatch): # Verify router_settings can be deserialized and matches input deserialized_settings = json.loads(result["router_settings"]) assert deserialized_settings == router_settings_data - - -@pytest.mark.asyncio -async def test_validate_max_budget(): - """ - Test _validate_max_budget helper function. - - Tests: - 1. Positive max_budget should pass - 2. Zero max_budget should pass - 3. Negative max_budget should raise HTTPException - 4. None max_budget should pass - """ - from fastapi import HTTPException - - # Test Case 1: Positive max_budget should pass - try: - _validate_max_budget(100.0) - _validate_max_budget(0.0) - except HTTPException: - pytest.fail("_validate_max_budget raised HTTPException for valid values") - - # Test Case 2: None max_budget should pass - try: - _validate_max_budget(None) - except HTTPException: - pytest.fail("_validate_max_budget raised HTTPException for None") - - # Test Case 3: Negative max_budget should raise HTTPException - with pytest.raises(HTTPException) as exc_info: - _validate_max_budget(-10.0) - - assert exc_info.value.status_code == 400 - assert "max_budget cannot be negative" in str(exc_info.value.detail) - - -@pytest.mark.asyncio -async def test_get_and_validate_existing_key(): - """ - Test _get_and_validate_existing_key helper function. - - Tests: - 1. Successfully retrieve existing key - 2. Key not found raises HTTPException - 3. Database not connected raises HTTPException - """ - from fastapi import HTTPException - - # Test Case 1: Successfully retrieve existing key - mock_prisma_client = AsyncMock() - mock_key = LiteLLM_VerificationToken( - token="test-key-123", - user_id="user-123", - models=["gpt-4"], - team_id=None, - ) - mock_prisma_client.get_data = AsyncMock(return_value=mock_key) - - result = await _get_and_validate_existing_key( - token="test-key-123", - prisma_client=mock_prisma_client, - ) - - assert result == mock_key - mock_prisma_client.get_data.assert_called_once_with( - token="test-key-123", - table_name="key", - query_type="find_unique", - ) - - # Test Case 2: Key not found raises HTTPException - mock_prisma_client.get_data = AsyncMock(return_value=None) - - with pytest.raises(HTTPException) as exc_info: - await _get_and_validate_existing_key( - token="non-existent-key", - prisma_client=mock_prisma_client, - ) - - assert exc_info.value.status_code == 404 - assert "Key not found" in str(exc_info.value.detail) - - # Test Case 3: Database not connected raises HTTPException - with pytest.raises(HTTPException) as exc_info: - await _get_and_validate_existing_key( - token="test-key-123", - prisma_client=None, - ) - - assert exc_info.value.status_code == 500 - assert "Database not connected" in str(exc_info.value.detail) - - -@pytest.mark.asyncio -async def test_process_single_key_update(): - """ - Test _process_single_key_update helper function. - - Tests successful key update with all validations passing. - """ - from litellm.types.proxy.management_endpoints.key_management_endpoints import ( - BulkUpdateKeyRequestItem, - ) - - # Setup mocks - mock_prisma_client = AsyncMock() - mock_user_api_key_cache = MagicMock() - mock_proxy_logging_obj = MagicMock() - mock_llm_router = MagicMock() - - # Mock existing key - existing_key = LiteLLM_VerificationToken( - token="test-key-123", - user_id="user-123", - models=["gpt-4"], - team_id=None, - max_budget=None, - tags=None, - ) - - # Mock updated key response - updated_key_data = { - "user_id": "user-123", - "models": ["gpt-4"], - "team_id": None, - "max_budget": 100.0, - "tags": ["production"], - } - - mock_prisma_client.get_data = AsyncMock(return_value=existing_key) - mock_updated_key_obj = MagicMock() - mock_updated_key_obj.model_dump.return_value = updated_key_data - mock_prisma_client.update_data = AsyncMock( - return_value={"data": mock_updated_key_obj} - ) - - # Mock prepare_key_update_data - with patch( - "litellm.proxy.management_endpoints.key_management_endpoints.prepare_key_update_data" - ) as mock_prepare: - mock_prepare.return_value = {"max_budget": 100.0, "tags": ["production"]} - - # Mock TeamMemberPermissionChecks - with patch( - "litellm.proxy.management_endpoints.key_management_endpoints.TeamMemberPermissionChecks.can_team_member_execute_key_management_endpoint" - ) as mock_permission_check: - mock_permission_check.return_value = None - - # Mock _delete_cache_key_object - with patch( - "litellm.proxy.management_endpoints.key_management_endpoints._delete_cache_key_object" - ) as mock_delete_cache: - mock_delete_cache.return_value = None - - # Mock hash_token (imported from litellm.proxy._types) - with patch( - "litellm.proxy._types.hash_token" - ) as mock_hash: - mock_hash.return_value = "hashed-test-key-123" - - # Mock KeyManagementEventHooks - with patch( - "litellm.proxy.management_endpoints.key_management_endpoints.KeyManagementEventHooks.async_key_updated_hook" - ): - # Create update request - key_update_item = BulkUpdateKeyRequestItem( - key="test-key-123", - max_budget=100.0, - tags=["production"], - ) - - user_api_key_dict = UserAPIKeyAuth( - user_role=LitellmUserRoles.PROXY_ADMIN, - api_key="sk-admin", - user_id="admin-user", - ) - - # Call the function - result = await _process_single_key_update( - key_update_item=key_update_item, - user_api_key_dict=user_api_key_dict, - litellm_changed_by=None, - prisma_client=mock_prisma_client, - user_api_key_cache=mock_user_api_key_cache, - proxy_logging_obj=mock_proxy_logging_obj, - llm_router=mock_llm_router, - ) - - # Verify results - assert result is not None - assert "token" not in result # Token should be removed - assert result.get("max_budget") == 100.0 - assert result.get("tags") == ["production"] - - # Verify mocks were called - mock_prisma_client.get_data.assert_called_once() - mock_prisma_client.update_data.assert_called_once() - mock_delete_cache.assert_called_once() - - -@pytest.mark.asyncio -async def test_bulk_update_keys_success(monkeypatch): - """ - Test /key/bulk_update endpoint with successful updates. - - Tests: - 1. Multiple keys updated successfully - 2. Response contains correct counts and data - """ - from litellm.types.proxy.management_endpoints.key_management_endpoints import ( - BulkUpdateKeyRequest, - BulkUpdateKeyRequestItem, - ) - from litellm.proxy.management_endpoints.key_management_endpoints import ( - bulk_update_keys, - ) - from litellm.proxy.proxy_server import ( - llm_router, - prisma_client, - proxy_logging_obj, - user_api_key_cache, - ) - - # Setup mocks - mock_prisma_client = AsyncMock() - mock_user_api_key_cache = MagicMock() - mock_proxy_logging_obj = MagicMock() - mock_llm_router = MagicMock() - - # Mock existing keys - existing_key_1 = LiteLLM_VerificationToken( - token="test-key-1", - user_id="user-123", - models=["gpt-4"], - team_id=None, - max_budget=None, - ) - existing_key_2 = LiteLLM_VerificationToken( - token="test-key-2", - user_id="user-123", - models=["gpt-3.5-turbo"], - team_id=None, - max_budget=50.0, - ) - - # Mock updated key responses - updated_key_1_data = { - "user_id": "user-123", - "models": ["gpt-4"], - "max_budget": 100.0, - "tags": ["production"], - } - updated_key_2_data = { - "user_id": "user-123", - "models": ["gpt-3.5-turbo"], - "max_budget": 200.0, - "tags": ["staging"], - } - - mock_prisma_client.get_data = AsyncMock( - side_effect=[existing_key_1, existing_key_2] - ) - mock_updated_key_1_obj = MagicMock() - mock_updated_key_1_obj.model_dump.return_value = updated_key_1_data - mock_updated_key_2_obj = MagicMock() - mock_updated_key_2_obj.model_dump.return_value = updated_key_2_data - mock_prisma_client.update_data = AsyncMock( - side_effect=[ - {"data": mock_updated_key_1_obj}, - {"data": mock_updated_key_2_obj}, - ] - ) - - # Patch dependencies - monkeypatch.setattr( - "litellm.proxy.proxy_server.prisma_client", mock_prisma_client - ) - monkeypatch.setattr( - "litellm.proxy.proxy_server.user_api_key_cache", mock_user_api_key_cache - ) - monkeypatch.setattr( - "litellm.proxy.proxy_server.proxy_logging_obj", mock_proxy_logging_obj - ) - monkeypatch.setattr("litellm.proxy.proxy_server.llm_router", mock_llm_router) - - # Mock helper functions - with patch( - "litellm.proxy.management_endpoints.key_management_endpoints.prepare_key_update_data" - ) as mock_prepare: - mock_prepare.side_effect = [ - {"max_budget": 100.0, "tags": ["production"]}, - {"max_budget": 200.0, "tags": ["staging"]}, - ] - - with patch( - "litellm.proxy.management_endpoints.key_management_endpoints.TeamMemberPermissionChecks.can_team_member_execute_key_management_endpoint" - ): - with patch( - "litellm.proxy.management_endpoints.key_management_endpoints._delete_cache_key_object" - ): - with patch( - "litellm.proxy._types.hash_token" - ) as mock_hash: - mock_hash.side_effect = ["hashed-key-1", "hashed-key-2"] - - with patch( - "litellm.proxy.management_endpoints.key_management_endpoints.KeyManagementEventHooks.async_key_updated_hook" - ): - # Create request - request_data = BulkUpdateKeyRequest( - keys=[ - BulkUpdateKeyRequestItem( - key="test-key-1", - max_budget=100.0, - tags=["production"], - ), - BulkUpdateKeyRequestItem( - key="test-key-2", - max_budget=200.0, - tags=["staging"], - ), - ] - ) - - user_api_key_dict = UserAPIKeyAuth( - user_role=LitellmUserRoles.PROXY_ADMIN, - api_key="sk-admin", - user_id="admin-user", - ) - - # Call endpoint - response = await bulk_update_keys( - data=request_data, - user_api_key_dict=user_api_key_dict, - litellm_changed_by=None, - ) - - # Verify response - assert response.total_requested == 2 - assert len(response.successful_updates) == 2 - assert len(response.failed_updates) == 0 - assert response.successful_updates[0].key == "test-key-1" - assert response.successful_updates[1].key == "test-key-2" - - -@pytest.mark.asyncio -async def test_bulk_update_keys_partial_failures(monkeypatch): - """ - Test /key/bulk_update endpoint with partial failures. - - Tests: - 1. Some keys update successfully, others fail - 2. Response contains both successful and failed updates - 3. Failed updates include error messages - """ - from litellm.types.proxy.management_endpoints.key_management_endpoints import ( - BulkUpdateKeyRequest, - BulkUpdateKeyRequestItem, - ) - from litellm.proxy.management_endpoints.key_management_endpoints import ( - bulk_update_keys, - ) - - # Setup mocks - mock_prisma_client = AsyncMock() - mock_user_api_key_cache = MagicMock() - mock_proxy_logging_obj = MagicMock() - mock_llm_router = MagicMock() - - # Mock existing keys - existing_key_1 = LiteLLM_VerificationToken( - token="test-key-1", - user_id="user-123", - models=["gpt-4"], - team_id=None, - max_budget=None, - ) - - # Mock updated key response for successful update - updated_key_1_data = { - "user_id": "user-123", - "models": ["gpt-4"], - "max_budget": 100.0, - "tags": ["production"], - } - - # First key exists, second key doesn't exist - mock_prisma_client.get_data = AsyncMock( - side_effect=[existing_key_1, None] # Second key not found - ) - mock_updated_key_1_obj = MagicMock() - mock_updated_key_1_obj.model_dump.return_value = updated_key_1_data - mock_prisma_client.update_data = AsyncMock( - return_value={"data": mock_updated_key_1_obj} - ) - - # Patch dependencies - monkeypatch.setattr( - "litellm.proxy.proxy_server.prisma_client", mock_prisma_client - ) - monkeypatch.setattr( - "litellm.proxy.proxy_server.user_api_key_cache", mock_user_api_key_cache - ) - monkeypatch.setattr( - "litellm.proxy.proxy_server.proxy_logging_obj", mock_proxy_logging_obj - ) - monkeypatch.setattr("litellm.proxy.proxy_server.llm_router", mock_llm_router) - - # Mock helper functions - with patch( - "litellm.proxy.management_endpoints.key_management_endpoints.prepare_key_update_data" - ) as mock_prepare: - mock_prepare.return_value = {"max_budget": 100.0, "tags": ["production"]} - - with patch( - "litellm.proxy.management_endpoints.key_management_endpoints.TeamMemberPermissionChecks.can_team_member_execute_key_management_endpoint" - ): - with patch( - "litellm.proxy.management_endpoints.key_management_endpoints._delete_cache_key_object" - ): - with patch( - "litellm.proxy._types.hash_token" - ) as mock_hash: - mock_hash.return_value = "hashed-key-1" - - with patch( - "litellm.proxy.management_endpoints.key_management_endpoints.KeyManagementEventHooks.async_key_updated_hook" - ): - # Create request with one valid and one invalid key - request_data = BulkUpdateKeyRequest( - keys=[ - BulkUpdateKeyRequestItem( - key="test-key-1", - max_budget=100.0, - tags=["production"], - ), - BulkUpdateKeyRequestItem( - key="non-existent-key", - max_budget=200.0, - tags=["staging"], - ), - ] - ) - - user_api_key_dict = UserAPIKeyAuth( - user_role=LitellmUserRoles.PROXY_ADMIN, - api_key="sk-admin", - user_id="admin-user", - ) - - # Call endpoint - response = await bulk_update_keys( - data=request_data, - user_api_key_dict=user_api_key_dict, - litellm_changed_by=None, - ) - - # Verify response - assert response.total_requested == 2 - assert len(response.successful_updates) == 1 - assert len(response.failed_updates) == 1 - assert response.successful_updates[0].key == "test-key-1" - assert response.failed_updates[0].key == "non-existent-key" - assert "Key not found" in response.failed_updates[0].failed_reason diff --git a/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py b/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py index 467ee3661d1..0d78545823f 100644 --- a/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py +++ b/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py @@ -36,7 +36,6 @@ _persist_deleted_team_records, _save_deleted_team_records, _transform_teams_to_deleted_records, - _validate_and_populate_member_user_info, delete_team, router, team_member_add_duplication_check, @@ -3655,100 +3654,6 @@ async def test_update_team_org_scoped_models_not_in_org_models(): assert "claude-3-opus" in str(exc_info.value.message) or "organization" in str(exc_info.value.message).lower() -@pytest.mark.asyncio -async def test_update_team_org_scoped_models_with_all_proxy_models(): - """ - Test that /team/update for an org-scoped team succeeds when organization has 'all-proxy-models'. - - Scenario: - - Organization has models=['all-proxy-models'] (catch-all for all models) - - Org-scoped team exists - - User tries to update team models to ['rerank-english-v3.0', 'text-embedding-3-small', 'gpt-4o-mini-test'] - - Expected: Should succeed because 'all-proxy-models' allows all models - """ - from fastapi import Request - - from litellm.proxy._types import ( - LiteLLM_OrganizationTable, - SpecialModelNames, - UpdateTeamRequest, - UserAPIKeyAuth, - ) - from litellm.proxy.management_endpoints.team_endpoints import update_team - - # Create user (org admin) - org_admin_user = UserAPIKeyAuth( - user_role=LitellmUserRoles.INTERNAL_USER, - user_id="org-admin-all-proxy-models-test", - models=[], - ) - - # Create update request with models that aren't explicitly in org's models list - # but should be allowed because org has 'all-proxy-models' - update_request = UpdateTeamRequest( - team_id="org-team-all-proxy-models-123", - models=["rerank-english-v3.0", "text-embedding-3-small", "gpt-4o-mini-test"], - ) - - dummy_request = MagicMock(spec=Request) - - # Mock organization with 'all-proxy-models' (catch-all) - mock_org = MagicMock(spec=LiteLLM_OrganizationTable) - mock_org.organization_id = "test-org-all-proxy-models" - mock_org.models = [SpecialModelNames.all_proxy_models.value] # Allows all models - mock_org.litellm_budget_table = None - - with patch("litellm.proxy.proxy_server.prisma_client") as mock_prisma, patch( - "litellm.proxy.proxy_server.user_api_key_cache" - ) as mock_cache, patch( - "litellm.proxy.proxy_server.litellm_proxy_admin_name", "admin" - ), patch( - "litellm.proxy.proxy_server.create_audit_log_for_update", new=AsyncMock() - ) as mock_audit, patch( - "litellm.proxy.management_endpoints.team_endpoints.get_org_object", - new=AsyncMock(return_value=mock_org) - ) as mock_get_org: - - # Mock existing org-scoped team - mock_existing_team = MagicMock() - mock_existing_team.team_id = "org-team-all-proxy-models-123" - mock_existing_team.organization_id = "test-org-all-proxy-models" - mock_existing_team.models = ["gpt-4"] - mock_existing_team.model_id = None - mock_existing_team.model_dump.return_value = { - "team_id": "org-team-all-proxy-models-123", - "organization_id": "test-org-all-proxy-models", - "models": ["gpt-4"], - } - mock_prisma.db.litellm_teamtable.find_unique = AsyncMock(return_value=mock_existing_team) - mock_prisma.jsonify_team_object = lambda db_data: db_data - mock_cache.async_set_cache = AsyncMock() # Mock cache set for _cache_team_object - - # Mock team update - mock_updated_team = MagicMock() - mock_updated_team.team_id = "org-team-all-proxy-models-123" - mock_updated_team.organization_id = "test-org-all-proxy-models" - mock_updated_team.models = ["rerank-english-v3.0", "text-embedding-3-small", "gpt-4o-mini-test"] - mock_updated_team.litellm_model_table = None - mock_updated_team.model_dump.return_value = { - "team_id": "org-team-all-proxy-models-123", - "organization_id": "test-org-all-proxy-models", - "models": ["rerank-english-v3.0", "text-embedding-3-small", "gpt-4o-mini-test"], - } - mock_prisma.db.litellm_teamtable.update = AsyncMock(return_value=mock_updated_team) - - # Should NOT raise an exception - 'all-proxy-models' allows all models - result = await update_team( - data=update_request, - http_request=dummy_request, - user_api_key_dict=org_admin_user, - ) - - # Verify the team was updated successfully with the new models - assert result is not None - assert result["data"].models == ["rerank-english-v3.0", "text-embedding-3-small", "gpt-4o-mini-test"] - - @pytest.mark.asyncio async def test_update_team_tpm_limit_exceeds_user_limit(): """ @@ -5467,122 +5372,3 @@ async def test_get_team_daily_activity_team_admin_sees_all_spend(mock_db_client) ) and mock_db_client.db.litellm_verificationtoken.find_many.called: # If it was called, that's unexpected for admin users assert False, "API keys should not be fetched for team admin users" - - -@pytest.mark.asyncio -async def test_validate_and_populate_member_user_info_both_provided_match(): - """ - Test _validate_and_populate_member_user_info when both user_email and user_id - are provided and they match the same user in the database. - """ - # Create member with both user_email and user_id - member = Member(user_email="test@example.com", user_id="user-123", role="user") - - # Mock prisma client - mock_prisma_client = MagicMock() - - # Mock user object that matches both email and user_id - mock_user = MagicMock() - mock_user.user_id = "user-123" - mock_user.user_email = "test@example.com" - - # Mock get_data to return single user matching email - mock_prisma_client.get_data = AsyncMock(return_value=[mock_user]) - - # Call the function - result = await _validate_and_populate_member_user_info( - member=member, - prisma_client=mock_prisma_client, - ) - - # Verify result matches input (both already provided and match) - assert result.user_email == "test@example.com" - assert result.user_id == "user-123" - - # Verify get_data was called with correct parameters - mock_prisma_client.get_data.assert_called_once_with( - key_val={"user_email": "test@example.com"}, - table_name="user", - query_type="find_all", - ) - - -@pytest.mark.asyncio -async def test_validate_and_populate_member_user_info_only_email_provided(): - """ - Test _validate_and_populate_member_user_info when only user_email is provided. - Should populate user_id from database. - """ - # Create member with only user_email - member = Member(user_email="test@example.com", user_id=None, role="user") - - # Mock prisma client - mock_prisma_client = MagicMock() - - # Mock user object from find_first - mock_user_find_first = MagicMock() - mock_user_find_first.user_id = "user-456" - mock_user_find_first.user_email = "test@example.com" - - # Mock find_first to return the user - mock_prisma_client.db.litellm_usertable.find_first = AsyncMock( - return_value=mock_user_find_first - ) - - # Mock get_data to return single user (no duplicates) - mock_prisma_client.get_data = AsyncMock(return_value=[mock_user_find_first]) - - # Call the function - result = await _validate_and_populate_member_user_info( - member=member, - prisma_client=mock_prisma_client, - ) - - # Verify user_id was populated - assert result.user_email == "test@example.com" - assert result.user_id == "user-456" - - # Verify find_first was called with correct parameters - mock_prisma_client.db.litellm_usertable.find_first.assert_called_once_with( - where={"user_email": {"equals": "test@example.com", "mode": "insensitive"}} - ) - - # Verify get_data was called to check for duplicates - mock_prisma_client.get_data.assert_called_once_with( - key_val={"user_email": "test@example.com"}, - table_name="user", - query_type="find_all", - ) - - -@pytest.mark.asyncio -async def test_validate_and_populate_member_user_info_only_user_id_not_found(): - """ - Test _validate_and_populate_member_user_info when only user_id is provided - but the user doesn't exist in the database. Should allow it to pass with - user_email as None (will be upserted later). - """ - # Create member with only user_id - member = Member(user_email=None, user_id="nonexistent-user", role="user") - - # Mock prisma client - mock_prisma_client = MagicMock() - - # Mock find_unique to return None (user not found) - mock_prisma_client.db.litellm_usertable.find_unique = AsyncMock(return_value=None) - - # Call the function - should NOT raise an exception - result = await _validate_and_populate_member_user_info( - member=member, - prisma_client=mock_prisma_client, - ) - - # Verify the result - should return member with user_id set and user_email as None - assert result.user_id == "nonexistent-user" - assert result.user_email is None - assert result.role == "user" - - # Verify find_unique was called with correct parameters - mock_prisma_client.db.litellm_usertable.find_unique.assert_called_once_with( - where={"user_id": "nonexistent-user"} - ) diff --git a/tests/test_litellm/proxy/management_endpoints/test_ui_sso.py b/tests/test_litellm/proxy/management_endpoints/test_ui_sso.py index 5e9078ea876..f983af2d0b2 100644 --- a/tests/test_litellm/proxy/management_endpoints/test_ui_sso.py +++ b/tests/test_litellm/proxy/management_endpoints/test_ui_sso.py @@ -24,7 +24,6 @@ GoogleSSOHandler, MicrosoftSSOHandler, SSOAuthenticationHandler, - normalize_email, ) from litellm.types.proxy.management_endpoints.ui_sso import ( DefaultTeamSSOParams, @@ -668,85 +667,6 @@ def test_build_sso_user_update_data_without_role(): assert "user_role" not in update_data -def test_normalize_email(): - """ - Test that normalize_email correctly lowercases email addresses and handles edge cases. - """ - # Test with lowercase email - assert normalize_email("test@example.com") == "test@example.com" - - # Test with uppercase email - assert normalize_email("TEST@EXAMPLE.COM") == "test@example.com" - - # Test with mixed case email - assert normalize_email("Test.User@Example.COM") == "test.user@example.com" - - # Test with None - assert normalize_email(None) is None - - # Test with empty string - assert normalize_email("") == "" - - -def test_build_sso_user_update_data_normalizes_email(): - """ - Test that _build_sso_user_update_data normalizes email addresses to lowercase. - """ - from litellm.proxy.management_endpoints.types import CustomOpenID - from litellm.proxy.management_endpoints.ui_sso import _build_sso_user_update_data - - sso_result = CustomOpenID( - id="test-user-789", - email="Test.User@Example.COM", - display_name="Test User", - provider="microsoft", - team_ids=[], - user_role=None, - ) - - update_data = _build_sso_user_update_data( - result=sso_result, - user_email="Test.User@Example.COM", - user_id="test-user-789", - ) - - # Email should be normalized to lowercase - assert update_data["user_email"] == "test.user@example.com" - assert "user_role" not in update_data - - -def test_generic_response_convertor_normalizes_email(): - """ - Test that generic_response_convertor normalizes email addresses. - """ - from litellm.proxy.management_endpoints.ui_sso import generic_response_convertor - - mock_response = { - "preferred_username": "user123", - "email": "Test.User@Example.COM", - "sub": "Test User", - "first_name": "Test", - "last_name": "User", - "provider": "generic", - } - - # Mock JWT handler - mock_jwt_handler = MagicMock(spec=JWTHandler) - mock_jwt_handler.get_team_ids_from_jwt.return_value = [] - - result = generic_response_convertor( - response=mock_response, - jwt_handler=mock_jwt_handler, - sso_jwt_handler=None, - role_mappings=None, - ) - - # Email should be normalized to lowercase - assert result.email == "test.user@example.com" - assert result.id == "user123" - assert result.display_name == "Test User" - - @pytest.mark.asyncio async def test_upsert_sso_user_updates_role_for_existing_user(): """ diff --git a/tests/test_litellm/proxy/pass_through_endpoints/test_vertex_passthrough_load_balancing.py b/tests/test_litellm/proxy/pass_through_endpoints/test_vertex_passthrough_load_balancing.py index d2fdb157c8d..28b3ba0a179 100644 --- a/tests/test_litellm/proxy/pass_through_endpoints/test_vertex_passthrough_load_balancing.py +++ b/tests/test_litellm/proxy/pass_through_endpoints/test_vertex_passthrough_load_balancing.py @@ -447,75 +447,3 @@ def test_forward_headers_from_request_x_pass_prefix(): assert "x-pass-anthropic-beta" not in result assert "x-pass-custom-header" not in result - -@pytest.mark.asyncio -async def test_vertex_passthrough_custom_model_name_replaced_in_url(): - """ - Test that when a passthrough URL contains a custom model_name (e.g., gcp/google/gemini-3-pro), - the URL is rewritten to use the actual Vertex AI model name (e.g., gemini-3-pro) - before being forwarded to Vertex AI. - - This prevents 404 errors from Vertex AI when custom model names are used in the config. - - Config example: - model_name: gcp/google/gemini-3-pro - litellm_params: - model: vertex_ai/gemini-3-pro - vertex_project: "my-project" - vertex_location: "global" - use_in_pass_through: true - """ - mock_request = MagicMock() - mock_response = MagicMock() - mock_handler = MagicMock() - - # Deployment with custom model_name but real vertex model - mock_deployment = { - "litellm_params": { - "model": "vertex_ai/gemini-3-pro", - "vertex_project": "nv-gcpllmgwit-20250411173346", - "vertex_location": "global", - "use_in_pass_through": True, - } - } - mock_router = MagicMock() - mock_router.get_available_deployment_for_pass_through.return_value = mock_deployment - - # The URL contains project/location AND a custom model name with slashes - test_endpoint = "v1/projects/nv-gcpllmgwit-20250411173346/locations/global/publishers/google/models/gcp/google/gemini-3-pro:generateContent" - - with patch("litellm.proxy.proxy_server.llm_router", mock_router), \ - patch("litellm.proxy.pass_through_endpoints.llm_passthrough_endpoints.passthrough_endpoint_router") as mock_pt_router, \ - patch("litellm.proxy.pass_through_endpoints.llm_passthrough_endpoints._prepare_vertex_auth_headers", new_callable=AsyncMock) as mock_prep_headers, \ - patch("litellm.proxy.pass_through_endpoints.llm_passthrough_endpoints.create_pass_through_route") as mock_create_route, \ - patch("litellm.proxy.pass_through_endpoints.llm_passthrough_endpoints.user_api_key_auth", new_callable=AsyncMock) as mock_auth: - - mock_pt_router.get_vertex_credentials.return_value = MagicMock() - mock_prep_headers.return_value = ({}, "https://global-aiplatform.googleapis.com", False, "nv-gcpllmgwit-20250411173346", "global") - mock_endpoint_func = AsyncMock() - mock_create_route.return_value = mock_endpoint_func - mock_auth.return_value = {} - - mock_handler.get_default_base_target_url.return_value = "https://global-aiplatform.googleapis.com" - - await _base_vertex_proxy_route( - endpoint=test_endpoint, - request=mock_request, - fastapi_response=mock_response, - get_vertex_pass_through_handler=mock_handler, - ) - - # Verify the router was called with the custom model name (extracted from URL) - mock_router.get_available_deployment_for_pass_through.assert_called_once_with( - model="gcp/google/gemini-3-pro" - ) - - # Verify the target URL passed to create_pass_through_route contains - # the REAL Vertex AI model name, not the custom one - create_route_call = mock_create_route.call_args - target_url = create_route_call.kwargs.get("target", "") - assert "gcp/google/gemini-3-pro" not in target_url, \ - f"Custom model name should have been replaced in target URL. Got: {target_url}" - assert "gemini-3-pro" in target_url, \ - f"Actual Vertex AI model name should be in target URL. Got: {target_url}" - diff --git a/tests/test_litellm/proxy/spend_tracking/test_spend_management_endpoints.py b/tests/test_litellm/proxy/spend_tracking/test_spend_management_endpoints.py index 13368d0a142..33e000143c8 100644 --- a/tests/test_litellm/proxy/spend_tracking/test_spend_management_endpoints.py +++ b/tests/test_litellm/proxy/spend_tracking/test_spend_management_endpoints.py @@ -1952,89 +1952,6 @@ async def mock_count(*args, **kwargs): assert metadata["error_information"]["error_code"] == "404" -@pytest.mark.asyncio -async def test_ui_view_spend_logs_with_error_message(client): - """Test filtering spend logs by error message""" - mock_spend_logs = [ - { - "id": "log1", - "request_id": "req1", - "api_key": "sk-test-key", - "user": "test_user_1", - "team_id": "team1", - "spend": 0.05, - "startTime": datetime.datetime.now(timezone.utc).isoformat(), - "model": "gpt-3.5-turbo", - "metadata": '{"error_information": {"error_message": "Rate limit exceeded"}}', - }, - { - "id": "log2", - "request_id": "req2", - "api_key": "sk-test-key", - "user": "test_user_2", - "team_id": "team1", - "spend": 0.10, - "startTime": datetime.datetime.now(timezone.utc).isoformat(), - "model": "gpt-4", - "metadata": '{"error_information": {"error_message": "Invalid API key"}}', - }, - ] - - with patch.object(ps, "prisma_client") as mock_prisma: - # Mock the find_many method to return filtered results - async def mock_find_many(*args, **kwargs): - where_conditions = kwargs.get("where", {}) - if "metadata" in where_conditions: - metadata_filter = where_conditions["metadata"] - if metadata_filter.get("path") == ["error_information", "error_message"]: - error_message_filter = metadata_filter.get("string_contains") - # Check if the error message contains the filter string - if error_message_filter == "Rate limit": - return [mock_spend_logs[0]] - elif error_message_filter == "Invalid API": - return [mock_spend_logs[1]] - return mock_spend_logs - - async def mock_count(*args, **kwargs): - where_conditions = kwargs.get("where", {}) - if "metadata" in where_conditions: - metadata_filter = where_conditions["metadata"] - if metadata_filter.get("path") == ["error_information", "error_message"]: - error_message_filter = metadata_filter.get("string_contains") - if error_message_filter == "Rate limit": - return 1 - elif error_message_filter == "Invalid API": - return 1 - return len(mock_spend_logs) - - mock_prisma.db.litellm_spendlogs.find_many = mock_find_many - mock_prisma.db.litellm_spendlogs.count = mock_count - - start_date = ( - datetime.datetime.now(timezone.utc) - datetime.timedelta(days=7) - ).strftime("%Y-%m-%d %H:%M:%S") - end_date = datetime.datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S") - - response = client.get( - "/spend/logs/ui", - params={ - "error_message": "Rate limit", - "start_date": start_date, - "end_date": end_date, - }, - headers={"Authorization": "Bearer sk-test"}, - ) - - assert response.status_code == 200 - data = response.json() - assert data["total"] == 1 - assert len(data["data"]) == 1 - assert data["data"][0]["id"] == "log1" - metadata = json.loads(data["data"][0]["metadata"]) - assert "error_information" in metadata - assert "Rate limit exceeded" in metadata["error_information"]["error_message"] - - @pytest.mark.asyncio async def test_ui_view_spend_logs_with_error_code_and_key_alias(client): """Test merging error_code and key_alias filters with AND logic""" diff --git a/tests/test_litellm/proxy/spend_tracking/test_spend_tracking_utils.py b/tests/test_litellm/proxy/spend_tracking/test_spend_tracking_utils.py index 1972103c3d2..dd4cbfa2e7f 100644 --- a/tests/test_litellm/proxy/spend_tracking/test_spend_tracking_utils.py +++ b/tests/test_litellm/proxy/spend_tracking/test_spend_tracking_utils.py @@ -23,7 +23,6 @@ _get_response_for_spend_logs_payload, _get_vector_store_request_for_spend_logs_payload, _sanitize_request_body_for_spend_logs_payload, - _should_store_prompts_and_responses_in_spend_logs, get_logging_payload, ) from litellm.types.utils import ( @@ -912,48 +911,3 @@ def test_spend_logs_redacts_request_and_response_when_turn_off_message_logging_e parsed_response = json.loads(response_result) assert parsed_response == {"text": "redacted-by-litellm"} - -@patch("litellm.secret_managers.main.get_secret_bool") -def test_should_store_prompts_and_responses_in_spend_logs_case_insensitive_string( - mock_get_secret_bool, -): - """ - Test that _should_store_prompts_and_responses_in_spend_logs handles - case-insensitive string values for store_prompts_in_spend_logs in general_settings. - """ - # Test case-insensitive string "true" variations - for true_value in ["true", "TRUE", "True", "TrUe"]: - with patch("litellm.proxy.proxy_server.general_settings", {"store_prompts_in_spend_logs": true_value}): - mock_get_secret_bool.return_value = False # Ensure env var is False - result = _should_store_prompts_and_responses_in_spend_logs() - assert result is True, f"Expected True for '{true_value}', got {result}" - - # Test boolean True - with patch("litellm.proxy.proxy_server.general_settings", {"store_prompts_in_spend_logs": True}): - mock_get_secret_bool.return_value = False - result = _should_store_prompts_and_responses_in_spend_logs() - assert result is True, f"Expected True for boolean True, got {result}" - - # Test that non-true values fall back to environment variable - for false_value in [False, None, "false", "FALSE", "False", "anything"]: - with patch("litellm.proxy.proxy_server.general_settings", {"store_prompts_in_spend_logs": false_value}): - # When env var is True, should return True - mock_get_secret_bool.return_value = True - result = _should_store_prompts_and_responses_in_spend_logs() - assert result is True, f"Expected True (from env var) for '{false_value}', got {result}" - - # When env var is False, should return False - mock_get_secret_bool.return_value = False - result = _should_store_prompts_and_responses_in_spend_logs() - assert result is False, f"Expected False (from env var) for '{false_value}', got {result}" - - # Test when general_settings doesn't have the key at all - with patch("litellm.proxy.proxy_server.general_settings", {}): - mock_get_secret_bool.return_value = True - result = _should_store_prompts_and_responses_in_spend_logs() - assert result is True, "Expected True (from env var) when key missing, got False" - - mock_get_secret_bool.return_value = False - result = _should_store_prompts_and_responses_in_spend_logs() - assert result is False, "Expected False (from env var) when key missing, got True" - diff --git a/tests/test_litellm/proxy/test_litellm_pre_call_utils.py b/tests/test_litellm/proxy/test_litellm_pre_call_utils.py index da6a5aeab09..b9485a2e4cb 100644 --- a/tests/test_litellm/proxy/test_litellm_pre_call_utils.py +++ b/tests/test_litellm/proxy/test_litellm_pre_call_utils.py @@ -1548,50 +1548,3 @@ def test_add_guardrails_from_policy_engine(): policy_registry._initialized = False attachment_registry._attachments = [] attachment_registry._initialized = False - - -def test_add_guardrails_from_policy_engine_accepts_dynamic_policies_and_pops_from_data(): - """ - Test that add_guardrails_from_policy_engine accepts dynamic 'policies' from the request body - and removes them to prevent forwarding to the LLM provider. - - This is critical because 'policies' is a LiteLLM proxy-specific parameter that should - not be sent to the actual LLM API (e.g., OpenAI, Anthropic, etc.). - """ - from litellm.proxy.policy_engine.policy_registry import get_policy_registry - - # Setup test data with 'policies' in the request body - data = { - "model": "gpt-4", - "messages": [{"role": "user", "content": "Hello"}], - "policies": ["PII-POLICY-GLOBAL", "HIPAA-POLICY"], # Dynamic policies - should be accepted and removed - "metadata": {}, - } - - user_api_key_dict = UserAPIKeyAuth( - api_key="test-key", - team_alias="test-team", - key_alias="test-key", - ) - - # Initialize empty policy registry (we're just testing the accept and pop behavior) - policy_registry = get_policy_registry() - policy_registry._policies = {} - policy_registry._initialized = False - - # Call the function - should accept dynamic policies and not raise an error - add_guardrails_from_policy_engine( - data=data, - metadata_variable_name="metadata", - user_api_key_dict=user_api_key_dict, - ) - - # Verify that 'policies' was removed from the request body - assert "policies" not in data, "'policies' should be removed from request body to prevent forwarding to LLM provider" - - # Verify that other fields are preserved - assert "model" in data - assert data["model"] == "gpt-4" - assert "messages" in data - assert data["messages"] == [{"role": "user", "content": "Hello"}] - assert "metadata" in data diff --git a/tests/test_litellm/proxy/test_proxy_cli.py b/tests/test_litellm/proxy/test_proxy_cli.py index 12065ad5b4d..f52f14b860e 100644 --- a/tests/test_litellm/proxy/test_proxy_cli.py +++ b/tests/test_litellm/proxy/test_proxy_cli.py @@ -103,11 +103,7 @@ def test_get_default_unvicorn_init_args(self): args = ProxyInitializationHelpers._get_default_unvicorn_init_args( "localhost", 8000 ) - # When json_logs is True, log_config should be set to the JSON log config dict - assert args["log_config"] is not None - assert isinstance(args["log_config"], dict) - assert "version" in args["log_config"] - assert "formatters" in args["log_config"] + assert args["log_config"] is None # Test with keepalive_timeout args = ProxyInitializationHelpers._get_default_unvicorn_init_args( @@ -222,7 +218,6 @@ def test_database_url_construction_with_special_characters(self): @patch("atexit.register") # 🔥 critical def test_skip_server_startup(self, mock_atexit_register, mock_uvicorn_run): from click.testing import CliRunner - from litellm.proxy.proxy_cli import run_server runner = CliRunner() diff --git a/tests/test_litellm/proxy/test_proxy_server.py b/tests/test_litellm/proxy/test_proxy_server.py index d85dbb2e0f9..cb519e9f509 100644 --- a/tests/test_litellm/proxy/test_proxy_server.py +++ b/tests/test_litellm/proxy/test_proxy_server.py @@ -5,7 +5,7 @@ import socket import subprocess import sys -from datetime import datetime, timezone +from datetime import datetime from pathlib import Path from unittest import mock from unittest.mock import AsyncMock, MagicMock, mock_open, patch @@ -1049,82 +1049,6 @@ async def test_get_config_from_file(tmp_path, monkeypatch): assert result == test_config -def test_normalize_datetime_for_sorting(): - """ - Test the _normalize_datetime_for_sorting function. - Tests various scenarios: None values, ISO format strings, datetime objects (naive and aware). - """ - from litellm.proxy.proxy_server import _normalize_datetime_for_sorting - - # Test Case 1: None value - assert _normalize_datetime_for_sorting(None) is None - - # Test Case 2: ISO format string with 'Z' suffix - dt_str_z = "2024-01-15T10:30:00Z" - result = _normalize_datetime_for_sorting(dt_str_z) - assert result is not None - assert isinstance(result, datetime) - assert result.tzinfo == timezone.utc - assert result.year == 2024 - assert result.month == 1 - assert result.day == 15 - assert result.hour == 10 - assert result.minute == 30 - - # Test Case 3: ISO format string without 'Z' suffix (naive) - dt_str_naive = "2024-01-15T10:30:00" - result = _normalize_datetime_for_sorting(dt_str_naive) - assert result is not None - assert isinstance(result, datetime) - assert result.tzinfo == timezone.utc - - # Test Case 4: ISO format string with timezone offset - dt_str_tz = "2024-01-15T10:30:00+05:00" - result = _normalize_datetime_for_sorting(dt_str_tz) - assert result is not None - assert isinstance(result, datetime) - assert result.tzinfo == timezone.utc - # Should convert from +05:00 to UTC (subtract 5 hours) - assert result.hour == 5 # 10:30 - 5 hours = 5:30 UTC - - # Test Case 5: Naive datetime object - naive_dt = datetime(2024, 1, 15, 10, 30, 0) - result = _normalize_datetime_for_sorting(naive_dt) - assert result is not None - assert isinstance(result, datetime) - assert result.tzinfo == timezone.utc - assert result.year == 2024 - assert result.month == 1 - assert result.day == 15 - - # Test Case 6: Timezone-aware datetime object (non-UTC) - from datetime import timedelta - aware_dt = datetime(2024, 1, 15, 10, 30, 0, tzinfo=timezone(timedelta(hours=5))) - result = _normalize_datetime_for_sorting(aware_dt) - assert result is not None - assert isinstance(result, datetime) - assert result.tzinfo == timezone.utc - # Should convert from +05:00 to UTC - assert result.hour == 5 - - # Test Case 7: UTC-aware datetime object - utc_dt = datetime(2024, 1, 15, 10, 30, 0, tzinfo=timezone.utc) - result = _normalize_datetime_for_sorting(utc_dt) - assert result is not None - assert isinstance(result, datetime) - assert result.tzinfo == timezone.utc - assert result == utc_dt - - # Test Case 8: Invalid string format - invalid_str = "not-a-date" - result = _normalize_datetime_for_sorting(invalid_str) - assert result is None - - # Test Case 9: Invalid type (should return None) - result = _normalize_datetime_for_sorting(12345) - assert result is None - - @pytest.mark.asyncio async def test_add_proxy_budget_to_db_only_creates_user_no_keys(): """ @@ -3519,1245 +3443,188 @@ async def test_model_info_v2_pagination_edge_cases(monkeypatch): app.dependency_overrides = original_overrides -@pytest.mark.asyncio -async def test_model_info_v2_search_config_models(monkeypatch): +def test_enrich_model_info_with_litellm_data(): """ - Test search parameter for config models (models from config.yaml). - Config models don't have db_model=True in model_info. + Test the _enrich_model_info_with_litellm_data helper function. + Tests model info enrichment, debug mode, and sensitive info removal. """ - from unittest.mock import AsyncMock, MagicMock + from unittest.mock import MagicMock, patch - from litellm.proxy._types import UserAPIKeyAuth - from litellm.proxy.proxy_server import app, proxy_config, user_api_key_auth + from litellm.proxy.proxy_server import _enrich_model_info_with_litellm_data - # Create mock config models (no db_model flag or db_model=False) - mock_config_models = [ - { - "model_name": "gpt-4-turbo", - "litellm_params": {"model": "gpt-4-turbo"}, - "model_info": {"id": "gpt-4-turbo"}, # No db_model flag = config model - }, - { - "model_name": "gpt-3.5-turbo", - "litellm_params": {"model": "gpt-3.5-turbo"}, - "model_info": {"id": "gpt-3.5-turbo", "db_model": False}, # Explicitly config model - }, - { - "model_name": "claude-3-opus", - "litellm_params": {"model": "claude-3-opus"}, - "model_info": {"id": "claude-3-opus"}, # No db_model flag = config model - }, - { - "model_name": "gemini-pro", - "litellm_params": {"model": "gemini-pro"}, - "model_info": {"id": "gemini-pro"}, # No db_model flag = config model - }, - ] + # Test Case 1: Basic model enrichment without debug + model = { + "model_name": "test-model", + "litellm_params": {"model": "gpt-3.5-turbo"}, + "model_info": {"id": "test-model"}, + "api_key": "sk-secret-key", # Should be removed + } - # Mock llm_router - mock_router = MagicMock() - mock_router.model_list = mock_config_models + with patch("litellm.proxy.proxy_server.get_litellm_model_info") as mock_get_info, patch( + "litellm.proxy.proxy_server.remove_sensitive_info_from_deployment" + ) as mock_remove_sensitive: + mock_get_info.return_value = { + "input_cost_per_token": 0.001, + "output_cost_per_token": 0.002, + "max_tokens": 4096, + } + mock_remove_sensitive.return_value = { + "model_name": "test-model", + "litellm_params": {"model": "gpt-3.5-turbo"}, + "model_info": { + "id": "test-model", + "input_cost_per_token": 0.001, + "output_cost_per_token": 0.002, + "max_tokens": 4096, + }, + } - # Mock prisma_client - mock_prisma_client = MagicMock() + result = _enrich_model_info_with_litellm_data(model=model, debug=False) - # Mock proxy_config.get_config - mock_get_config = AsyncMock(return_value={}) + # Verify get_litellm_model_info was called + mock_get_info.assert_called_once_with(model=model) + # Verify remove_sensitive_info_from_deployment was called + mock_remove_sensitive.assert_called_once() + # Verify result doesn't have api_key + assert "api_key" not in result + # Verify model_info was enriched + assert "input_cost_per_token" in result["model_info"] - # Mock user authentication - mock_user_api_key_dict = MagicMock(spec=UserAPIKeyAuth) - mock_user_api_key_dict.user_id = "test-user" - mock_user_api_key_dict.api_key = "test-key" - mock_user_api_key_dict.team_models = [] - mock_user_api_key_dict.models = [] + # Test Case 2: Model enrichment with debug mode + model_with_debug = { + "model_name": "test-model-debug", + "litellm_params": {"model": "gpt-4"}, + "model_info": {}, + } - # Apply monkeypatches - monkeypatch.setattr("litellm.proxy.proxy_server.llm_router", mock_router) - monkeypatch.setattr("litellm.proxy.proxy_server.prisma_client", mock_prisma_client) - monkeypatch.setattr("litellm.proxy.proxy_server.user_model", None) - monkeypatch.setattr(proxy_config, "get_config", mock_get_config) + mock_router = MagicMock() + mock_client = MagicMock() + mock_router._get_client.return_value = mock_client - # Override auth dependency - original_overrides = app.dependency_overrides.copy() - app.dependency_overrides[user_api_key_auth] = lambda: mock_user_api_key_dict + with patch("litellm.proxy.proxy_server.get_litellm_model_info") as mock_get_info, patch( + "litellm.proxy.proxy_server.remove_sensitive_info_from_deployment" + ) as mock_remove_sensitive: + mock_get_info.return_value = {} + mock_remove_sensitive.return_value = { + "model_name": "test-model-debug", + "litellm_params": {"model": "gpt-4"}, + "model_info": {}, + "openai_client": str(mock_client), + } - client = TestClient(app) - try: - # Test search for "gpt" - should return gpt-4-turbo and gpt-3.5-turbo - response = client.get("/v2/model/info", params={"search": "gpt"}) - assert response.status_code == 200 - data = response.json() - assert data["total_count"] == 2 # Only config models matching search - assert len(data["data"]) == 2 - model_names = [m["model_name"] for m in data["data"]] - assert "gpt-4-turbo" in model_names - assert "gpt-3.5-turbo" in model_names - assert "claude-3-opus" not in model_names - assert "gemini-pro" not in model_names - - # Test search for "claude" - should return claude-3-opus - response = client.get("/v2/model/info", params={"search": "claude"}) - assert response.status_code == 200 - data = response.json() - assert data["total_count"] == 1 - assert len(data["data"]) == 1 - assert data["data"][0]["model_name"] == "claude-3-opus" + result = _enrich_model_info_with_litellm_data( + model=model_with_debug, debug=True, llm_router=mock_router + ) - # Test case-insensitive search - response = client.get("/v2/model/info", params={"search": "GPT"}) - assert response.status_code == 200 - data = response.json() - assert data["total_count"] == 2 - assert len(data["data"]) == 2 + # Verify debug info was added + mock_remove_sensitive.assert_called_once() + call_args = mock_remove_sensitive.call_args[0][0] + assert "openai_client" in call_args + # Verify router._get_client was called for debug + mock_router._get_client.assert_called_once() - # Test partial match - response = client.get("/v2/model/info", params={"search": "turbo"}) - assert response.status_code == 200 - data = response.json() - assert data["total_count"] == 2 - assert len(data["data"]) == 2 - model_names = [m["model_name"] for m in data["data"]] - assert "gpt-4-turbo" in model_names - assert "gpt-3.5-turbo" in model_names - - # Test search with no matches - response = client.get("/v2/model/info", params={"search": "nonexistent"}) - assert response.status_code == 200 - data = response.json() - assert data["total_count"] == 0 - assert len(data["data"]) == 0 + # Test Case 3: Model with fallback to litellm.get_model_info + model_fallback = { + "model_name": "test-model-fallback", + "litellm_params": {"model": "claude-3-opus"}, + "model_info": {}, + } - finally: - app.dependency_overrides = original_overrides + with patch("litellm.proxy.proxy_server.get_litellm_model_info") as mock_get_info, patch( + "litellm.get_model_info" + ) as mock_litellm_info, patch( + "litellm.proxy.proxy_server.remove_sensitive_info_from_deployment" + ) as mock_remove_sensitive: + # First call returns empty, triggering fallback + mock_get_info.return_value = {} + mock_litellm_info.return_value = { + "input_cost_per_token": 0.015, + "output_cost_per_token": 0.075, + "max_tokens": 200000, + } + mock_remove_sensitive.return_value = { + "model_name": "test-model-fallback", + "litellm_params": {"model": "claude-3-opus"}, + "model_info": { + "input_cost_per_token": 0.015, + "output_cost_per_token": 0.075, + "max_tokens": 200000, + }, + } + result = _enrich_model_info_with_litellm_data(model=model_fallback, debug=False) -@pytest.mark.asyncio -async def test_model_info_v2_search_db_models(monkeypatch): - """ - Test search parameter for db models (models from database). - DB models have db_model=True and id in model_info. - """ - from unittest.mock import AsyncMock, MagicMock + # Verify fallback was attempted + mock_litellm_info.assert_called_once_with(model="claude-3-opus") + # Verify model_info was enriched with fallback data + call_args = mock_remove_sensitive.call_args[0][0] + assert call_args["model_info"]["input_cost_per_token"] == 0.015 - from litellm.proxy._types import UserAPIKeyAuth - from litellm.proxy.proxy_server import app, proxy_config, user_api_key_auth + # Test Case 4: Model with split model name fallback + model_split = { + "model_name": "test-model-split", + "litellm_params": {"model": "azure/gpt-4"}, + "model_info": {}, + } - # Create mock db models (db_model=True with id) - mock_db_models_in_router = [ - { - "model_name": "db-gpt-4", - "litellm_params": {"model": "gpt-4"}, - "model_info": {"id": "db-model-1", "db_model": True}, # DB model - }, - { - "model_name": "db-claude-3", - "litellm_params": {"model": "claude-3"}, - "model_info": {"id": "db-model-2", "db_model": True}, # DB model - }, - ] + with patch("litellm.proxy.proxy_server.get_litellm_model_info") as mock_get_info, patch( + "litellm.get_model_info" + ) as mock_litellm_info, patch( + "litellm.proxy.proxy_server.remove_sensitive_info_from_deployment" + ) as mock_remove_sensitive: + # Both first and second pass return empty, triggering third pass + mock_get_info.return_value = {} + # Second pass (no split) + mock_litellm_info.side_effect = [ + {}, # First call returns empty + {"max_tokens": 8192}, # Third pass with split succeeds + ] + mock_remove_sensitive.return_value = { + "model_name": "test-model-split", + "litellm_params": {"model": "azure/gpt-4"}, + "model_info": {"max_tokens": 8192}, + } - # Mock llm_router - mock_router = MagicMock() - mock_router.model_list = mock_db_models_in_router - - # Mock prisma_client with database query methods - mock_db_models_from_db = [ - MagicMock( - model_id="db-model-3", - model_name="db-gemini-pro", - litellm_params='{"model": "gemini-pro"}', - model_info='{"id": "db-model-3", "db_model": true}', - ), - MagicMock( - model_id="db-model-4", - model_name="db-gpt-3.5", - litellm_params='{"model": "gpt-3.5-turbo"}', - model_info='{"id": "db-model-4", "db_model": true}', - ), - ] + result = _enrich_model_info_with_litellm_data(model=model_split, debug=False) - # Mock the database count and find_many methods dynamically based on search - async def mock_db_count_func(*args, **kwargs): - where_condition = kwargs.get("where", {}) - search_term = where_condition.get("model_name", {}).get("contains", "") - excluded_ids = where_condition.get("model_id", {}).get("not", {}).get("in", []) - - # Count models matching search term but not in excluded_ids - count = 0 - for model in mock_db_models_from_db: - if search_term.lower() in model.model_name.lower(): - if model.model_id not in excluded_ids: - count += 1 - return count - - async def mock_db_find_many_func(*args, **kwargs): - where_condition = kwargs.get("where", {}) - search_term = where_condition.get("model_name", {}).get("contains", "") - excluded_ids = where_condition.get("model_id", {}).get("not", {}).get("in", []) - take = kwargs.get("take", 10) - - # Return models matching search term but not in excluded_ids - result = [] - for model in mock_db_models_from_db: - if search_term.lower() in model.model_name.lower(): - if model.model_id not in excluded_ids: - result.append(model) - if len(result) >= take: - break - return result - - mock_db_count = AsyncMock(side_effect=mock_db_count_func) - mock_db_find_many = AsyncMock(side_effect=mock_db_find_many_func) + # Verify third pass was attempted with split model name + assert mock_litellm_info.call_count == 2 + # Check that second call used split model name + second_call = mock_litellm_info.call_args_list[1] + assert second_call[1]["model"] == "gpt-4" + assert second_call[1]["custom_llm_provider"] == "azure" - mock_prisma_client = MagicMock() - mock_prisma_client.db.litellm_proxymodeltable.count = mock_db_count - mock_prisma_client.db.litellm_proxymodeltable.find_many = mock_db_find_many - - # Mock proxy_config.decrypt_model_list_from_db to return router-format models - def mock_decrypt_models(db_models_list): - result = [] - for db_model in db_models_list: - result.append( - { - "model_name": db_model.model_name, - "litellm_params": {"model": db_model.model_name.replace("db-", "")}, - "model_info": {"id": db_model.model_id, "db_model": True}, - } - ) - return result + # Test Case 5: Model with existing model_info (should preserve existing keys) + model_existing = { + "model_name": "test-model-existing", + "litellm_params": {"model": "gpt-3.5-turbo"}, + "model_info": {"id": "existing-id", "custom_key": "custom_value"}, + } - # Mock proxy_config.get_config - mock_get_config = AsyncMock(return_value={}) + with patch("litellm.proxy.proxy_server.get_litellm_model_info") as mock_get_info, patch( + "litellm.proxy.proxy_server.remove_sensitive_info_from_deployment" + ) as mock_remove_sensitive: + mock_get_info.return_value = { + "input_cost_per_token": 0.001, + "id": "new-id", # Should not override existing "id" + } + mock_remove_sensitive.return_value = { + "model_name": "test-model-existing", + "litellm_params": {"model": "gpt-3.5-turbo"}, + "model_info": { + "id": "existing-id", # Existing key preserved + "custom_key": "custom_value", # Existing key preserved + "input_cost_per_token": 0.001, # New key added + }, + } - # Mock user authentication - mock_user_api_key_dict = MagicMock(spec=UserAPIKeyAuth) - mock_user_api_key_dict.user_id = "test-user" - mock_user_api_key_dict.api_key = "test-key" - mock_user_api_key_dict.team_models = [] - mock_user_api_key_dict.models = [] + result = _enrich_model_info_with_litellm_data(model=model_existing, debug=False) - # Apply monkeypatches - monkeypatch.setattr("litellm.proxy.proxy_server.llm_router", mock_router) - monkeypatch.setattr("litellm.proxy.proxy_server.prisma_client", mock_prisma_client) - monkeypatch.setattr("litellm.proxy.proxy_server.user_model", None) - monkeypatch.setattr(proxy_config, "get_config", mock_get_config) - monkeypatch.setattr(proxy_config, "decrypt_model_list_from_db", mock_decrypt_models) - - # Override auth dependency - original_overrides = app.dependency_overrides.copy() - app.dependency_overrides[user_api_key_auth] = lambda: mock_user_api_key_dict - - client = TestClient(app) - try: - # Test search for "gpt" - should return db-gpt-4 from router and db-gpt-3.5 from db - response = client.get("/v2/model/info", params={"search": "gpt"}) - assert response.status_code == 200 - data = response.json() - # Should have db-gpt-4 from router + db-gpt-3.5 from db = 2 total - assert data["total_count"] == 2 - assert len(data["data"]) == 2 - model_names = [m["model_name"] for m in data["data"]] - assert "db-gpt-4" in model_names - assert "db-gpt-3.5" in model_names - - # Verify database was queried - mock_db_count.assert_called() - # Verify the where condition excludes models already in router - call_args = mock_db_count.call_args - assert call_args is not None - where_condition = call_args[1]["where"] - assert "model_name" in where_condition - assert where_condition["model_name"]["contains"] == "gpt" - assert where_condition["model_name"]["mode"] == "insensitive" - - # Test search for "claude" - should return db-claude-3 from router only - response = client.get("/v2/model/info", params={"search": "claude"}) - assert response.status_code == 200 - data = response.json() - assert data["total_count"] == 1 - assert len(data["data"]) == 1 - assert data["data"][0]["model_name"] == "db-claude-3" - - # Test search for "gemini" - should return db-gemini-pro from db only - response = client.get("/v2/model/info", params={"search": "gemini"}) - assert response.status_code == 200 - data = response.json() - assert data["total_count"] == 1 - assert len(data["data"]) == 1 - assert data["data"][0]["model_name"] == "db-gemini-pro" - - # Test case-insensitive search - response = client.get("/v2/model/info", params={"search": "GPT"}) - assert response.status_code == 200 - data = response.json() - assert data["total_count"] == 2 - - finally: - app.dependency_overrides = original_overrides - - -@pytest.mark.asyncio -async def test_model_info_v2_filter_by_model_id(monkeypatch): - """ - Test modelId parameter for filtering by specific model ID. - Tests that modelId searches in router config first, then database. - """ - from unittest.mock import AsyncMock, MagicMock - - from litellm.proxy._types import UserAPIKeyAuth - from litellm.proxy.proxy_server import app, proxy_config, user_api_key_auth - - # Create mock config models - mock_config_models = [ - { - "model_name": "gpt-4-turbo", - "litellm_params": {"model": "gpt-4-turbo"}, - "model_info": {"id": "config-model-1"}, - }, - { - "model_name": "claude-3-opus", - "litellm_params": {"model": "claude-3-opus"}, - "model_info": {"id": "config-model-2"}, - }, - ] - - # Mock llm_router with get_model_info method - mock_router = MagicMock() - mock_router.model_list = mock_config_models - mock_router.get_model_info = MagicMock( - side_effect=lambda id: next( - (m for m in mock_config_models if m["model_info"]["id"] == id), None - ) - ) - - # Mock prisma_client for database queries - mock_prisma_client = MagicMock() - mock_db_table = MagicMock() - mock_prisma_client.db.litellm_proxymodeltable = mock_db_table - - # Mock database model - mock_db_model = MagicMock() - mock_db_model.model_id = "db-model-1" - mock_db_model.model_name = "db-gpt-3.5" - mock_db_model.litellm_params = '{"model": "gpt-3.5-turbo"}' - mock_db_model.model_info = '{"id": "db-model-1", "db_model": true}' - - # Mock find_unique to return db model when searching for db-model-1 - async def mock_find_unique(where): - if where.get("model_id") == "db-model-1": - return mock_db_model - return None - - mock_db_table.find_unique = AsyncMock(side_effect=mock_find_unique) - - # Mock proxy_config.decrypt_model_list_from_db - def mock_decrypt_models(db_models_list): - if db_models_list: - return [ - { - "model_name": db_models_list[0].model_name, - "litellm_params": {"model": "gpt-3.5-turbo"}, - "model_info": {"id": db_models_list[0].model_id, "db_model": True}, - } - ] - return [] - - # Mock proxy_config.get_config - mock_get_config = AsyncMock(return_value={}) - - # Mock user authentication - mock_user_api_key_dict = MagicMock(spec=UserAPIKeyAuth) - mock_user_api_key_dict.user_id = "test-user" - mock_user_api_key_dict.api_key = "test-key" - mock_user_api_key_dict.team_models = [] - mock_user_api_key_dict.models = [] - - # Apply monkeypatches - monkeypatch.setattr("litellm.proxy.proxy_server.llm_router", mock_router) - monkeypatch.setattr("litellm.proxy.proxy_server.prisma_client", mock_prisma_client) - monkeypatch.setattr("litellm.proxy.proxy_server.user_model", None) - monkeypatch.setattr(proxy_config, "get_config", mock_get_config) - monkeypatch.setattr(proxy_config, "decrypt_model_list_from_db", mock_decrypt_models) - - # Override auth dependency - original_overrides = app.dependency_overrides.copy() - app.dependency_overrides[user_api_key_auth] = lambda: mock_user_api_key_dict - - client = TestClient(app) - try: - # Test Case 1: Filter by modelId that exists in config - response = client.get("/v2/model/info", params={"modelId": "config-model-1"}) - assert response.status_code == 200 - data = response.json() - assert data["total_count"] == 1 - assert len(data["data"]) == 1 - assert data["data"][0]["model_info"]["id"] == "config-model-1" - assert data["data"][0]["model_name"] == "gpt-4-turbo" - # Verify router.get_model_info was called - mock_router.get_model_info.assert_called_with(id="config-model-1") - - # Test Case 2: Filter by modelId that exists in database (not in config) - response = client.get("/v2/model/info", params={"modelId": "db-model-1"}) - assert response.status_code == 200 - data = response.json() - assert data["total_count"] == 1 - assert len(data["data"]) == 1 - assert data["data"][0]["model_info"]["id"] == "db-model-1" - assert data["data"][0]["model_name"] == "db-gpt-3.5" - # Verify database was queried - mock_db_table.find_unique.assert_called() - - # Test Case 3: Filter by modelId that doesn't exist - mock_db_table.find_unique = AsyncMock(return_value=None) - response = client.get("/v2/model/info", params={"modelId": "non-existent-model"}) - assert response.status_code == 200 - data = response.json() - assert data["total_count"] == 0 - assert len(data["data"]) == 0 - - # Test Case 4: Filter by modelId with search parameter (should filter further) - response = client.get( - "/v2/model/info", params={"modelId": "config-model-1", "search": "claude"} - ) - assert response.status_code == 200 - data = response.json() - # config-model-1 is gpt-4-turbo, doesn't match "claude", so should return empty - assert data["total_count"] == 0 - assert len(data["data"]) == 0 - - finally: - app.dependency_overrides = original_overrides - - -@pytest.mark.asyncio -async def test_model_info_v2_filter_by_team_id(monkeypatch): - """ - Test teamId parameter for filtering models by team ID. - Tests that teamId filters models based on direct_access or access_via_team_ids. - """ - from unittest.mock import AsyncMock, MagicMock - - from litellm.proxy._types import UserAPIKeyAuth, LiteLLM_TeamTable - from litellm.proxy.proxy_server import app, proxy_config, user_api_key_auth - - # Create mock models with different access configurations - mock_models = [ - { - "model_name": "model-direct-access", - "litellm_params": {"model": "gpt-4"}, - "model_info": { - "id": "model-1", - "direct_access": True, # Should be included - }, - }, - { - "model_name": "model-team-access", - "litellm_params": {"model": "claude-3"}, - "model_info": { - "id": "model-2", - "direct_access": False, - "access_via_team_ids": ["team-123"], # Should be included - }, - }, - { - "model_name": "model-no-access", - "litellm_params": {"model": "gemini-pro"}, - "model_info": { - "id": "model-3", - "direct_access": False, - "access_via_team_ids": ["team-456"], # Should NOT be included - }, - }, - { - "model_name": "model-multiple-teams", - "litellm_params": {"model": "gpt-3.5"}, - "model_info": { - "id": "model-4", - "direct_access": False, - "access_via_team_ids": ["team-789", "team-123"], # Should be included - }, - }, - ] - - # Mock llm_router - mock_router = MagicMock() - mock_router.model_list = mock_models - - # Mock get_model_list to return models based on model_name filter - def mock_get_model_list(model_name=None, team_id=None): - if model_name: - return [m for m in mock_models if m["model_name"] == model_name] - return mock_models - - mock_router.get_model_list = MagicMock(side_effect=mock_get_model_list) - - # Mock team database object - team has access to specific models - mock_team_db_object = MagicMock() - mock_team_db_object.model_dump.return_value = { - "team_id": "team-123", - "models": ["model-direct-access", "model-team-access", "model-multiple-teams"], # Specific models - } - - # Mock prisma_client - mock_prisma_client = MagicMock() - mock_team_table = MagicMock() - mock_prisma_client.db.litellm_teamtable = mock_team_table - mock_team_table.find_unique = AsyncMock(return_value=mock_team_db_object) - - # Mock LiteLLM_TeamTable - team has access to specific models - mock_team_object = LiteLLM_TeamTable( - team_id="team-123", - models=["model-direct-access", "model-team-access", "model-multiple-teams"], - ) - - # Mock proxy_config.get_config - mock_get_config = AsyncMock(return_value={}) - - # Mock user authentication - mock_user_api_key_dict = MagicMock(spec=UserAPIKeyAuth) - mock_user_api_key_dict.user_id = "test-user" - mock_user_api_key_dict.api_key = "test-key" - mock_user_api_key_dict.team_models = [] - mock_user_api_key_dict.models = [] - - # Apply monkeypatches - monkeypatch.setattr("litellm.proxy.proxy_server.llm_router", mock_router) - monkeypatch.setattr("litellm.proxy.proxy_server.prisma_client", mock_prisma_client) - monkeypatch.setattr("litellm.proxy.proxy_server.user_model", None) - monkeypatch.setattr(proxy_config, "get_config", mock_get_config) - # Mock LiteLLM_TeamTable instantiation - monkeypatch.setattr( - "litellm.proxy.proxy_server.LiteLLM_TeamTable", - lambda **kwargs: mock_team_object, - ) - - # Override auth dependency - original_overrides = app.dependency_overrides.copy() - app.dependency_overrides[user_api_key_auth] = lambda: mock_user_api_key_dict - - client = TestClient(app) - try: - # Test Case 1: Filter by teamId - should return models with direct_access=True or team-123 in access_via_team_ids - response = client.get("/v2/model/info", params={"teamId": "team-123"}) - assert response.status_code == 200 - data = response.json() - # Should include: model-1 (direct_access), model-2 (team-123 in access_via_team_ids), model-4 (team-123 in access_via_team_ids) - # Should NOT include: model-3 (team-456 only) - assert data["total_count"] == 3 - assert len(data["data"]) == 3 - model_ids = [m["model_info"]["id"] for m in data["data"]] - assert "model-1" in model_ids # direct_access - assert "model-2" in model_ids # team-123 in access_via_team_ids - assert "model-4" in model_ids # team-123 in access_via_team_ids - assert "model-3" not in model_ids # Should be excluded - - # Test Case 2: Filter by teamId that doesn't exist - should return empty list - mock_team_table.find_unique = AsyncMock(return_value=None) - response = client.get("/v2/model/info", params={"teamId": "non-existent-team"}) - assert response.status_code == 200 - data = response.json() - assert data["total_count"] == 0 - assert len(data["data"]) == 0 - - # Test Case 3: Filter by different teamId - should only return models with that team in access_via_team_ids - mock_team_db_object_456 = MagicMock() - mock_team_db_object_456.model_dump.return_value = { - "team_id": "team-456", - "models": ["model-no-access"], # Team has access to model-no-access - } - mock_team_table.find_unique = AsyncMock(return_value=mock_team_db_object_456) - mock_team_object_456 = LiteLLM_TeamTable( - team_id="team-456", - models=["model-no-access"], - ) - monkeypatch.setattr( - "litellm.proxy.proxy_server.LiteLLM_TeamTable", - lambda **kwargs: mock_team_object_456, - ) - - response = client.get("/v2/model/info", params={"teamId": "team-456"}) - assert response.status_code == 200 - data = response.json() - # Should include: model-1 (direct_access), model-3 (team-456 in access_via_team_ids) - # Should NOT include: model-2 (team-123 only), model-4 (team-789 and team-123, but not team-456) - assert data["total_count"] >= 2 - model_ids = [m["model_info"]["id"] for m in data["data"]] - assert "model-1" in model_ids # direct_access - assert "model-3" in model_ids # team-456 in access_via_team_ids - - finally: - app.dependency_overrides = original_overrides - - -@pytest.mark.asyncio -@pytest.mark.parametrize( - "sort_by,sort_order,expected_order", - [ - # Test model_name sorting - ("model_name", "asc", ["a-model", "b-model", "z-model"]), - ("model_name", "desc", ["z-model", "b-model", "a-model"]), - # Test created_at sorting - ("created_at", "asc", ["old-model", "mid-model", "new-model"]), - ("created_at", "desc", ["new-model", "mid-model", "old-model"]), - # Test updated_at sorting - ("updated_at", "asc", ["old-updated", "mid-updated", "new-updated"]), - ("updated_at", "desc", ["new-updated", "mid-updated", "old-updated"]), - # Test costs sorting - ("costs", "asc", ["low-cost", "mid-cost", "high-cost"]), - ("costs", "desc", ["high-cost", "mid-cost", "low-cost"]), - # Test status sorting (False/config models come before True/db models in asc) - ("status", "asc", ["config-model-1", "config-model-2", "db-model"]), - ("status", "desc", ["db-model", "config-model-1", "config-model-2"]), - ], -) -async def test_model_info_v2_sorting(monkeypatch, sort_by, sort_order, expected_order): - """ - Test sorting functionality for /v2/model/info endpoint. - Tests all sortBy fields (model_name, created_at, updated_at, costs, status) - with both asc and desc sort orders. - """ - from datetime import datetime, timedelta - from unittest.mock import AsyncMock, MagicMock - - from litellm.proxy._types import UserAPIKeyAuth - from litellm.proxy.proxy_server import app, proxy_config, user_api_key_auth - - # Create base time for date comparisons - base_time = datetime(2024, 1, 1, 12, 0, 0) - - # Create mock models with different values for each sort field - mock_models = [] - - if sort_by == "model_name": - # Models with different names - mock_models = [ - { - "model_name": "z-model", - "litellm_params": {"model": "z-model"}, - "model_info": {"id": "z-model"}, - }, - { - "model_name": "a-model", - "litellm_params": {"model": "a-model"}, - "model_info": {"id": "a-model"}, - }, - { - "model_name": "b-model", - "litellm_params": {"model": "b-model"}, - "model_info": {"id": "b-model"}, - }, - ] - elif sort_by == "created_at": - # Models with different created_at timestamps - mock_models = [ - { - "model_name": "new-model", - "litellm_params": {"model": "new-model"}, - "model_info": { - "id": "new-model", - "created_at": (base_time + timedelta(days=3)).isoformat(), - }, - }, - { - "model_name": "old-model", - "litellm_params": {"model": "old-model"}, - "model_info": { - "id": "old-model", - "created_at": (base_time - timedelta(days=3)).isoformat(), - }, - }, - { - "model_name": "mid-model", - "litellm_params": {"model": "mid-model"}, - "model_info": { - "id": "mid-model", - "created_at": base_time.isoformat(), - }, - }, - ] - elif sort_by == "updated_at": - # Models with different updated_at timestamps - mock_models = [ - { - "model_name": "new-updated", - "litellm_params": {"model": "new-updated"}, - "model_info": { - "id": "new-updated", - "updated_at": (base_time + timedelta(days=3)).isoformat(), - }, - }, - { - "model_name": "old-updated", - "litellm_params": {"model": "old-updated"}, - "model_info": { - "id": "old-updated", - "updated_at": (base_time - timedelta(days=3)).isoformat(), - }, - }, - { - "model_name": "mid-updated", - "litellm_params": {"model": "mid-updated"}, - "model_info": { - "id": "mid-updated", - "updated_at": base_time.isoformat(), - }, - }, - ] - elif sort_by == "costs": - # Models with different costs (input_cost + output_cost) - mock_models = [ - { - "model_name": "high-cost", - "litellm_params": {"model": "high-cost"}, - "model_info": { - "id": "high-cost", - "input_cost_per_token": 0.00005, - "output_cost_per_token": 0.00015, - }, - }, - { - "model_name": "low-cost", - "litellm_params": {"model": "low-cost"}, - "model_info": { - "id": "low-cost", - "input_cost_per_token": 0.00001, - "output_cost_per_token": 0.00003, - }, - }, - { - "model_name": "mid-cost", - "litellm_params": {"model": "mid-cost"}, - "model_info": { - "id": "mid-cost", - "input_cost_per_token": 0.00003, - "output_cost_per_token": 0.00007, - }, - }, - ] - elif sort_by == "status": - # Models with different db_model status (False = config, True = db) - mock_models = [ - { - "model_name": "db-model", - "litellm_params": {"model": "db-model"}, - "model_info": {"id": "db-model", "db_model": True}, - }, - { - "model_name": "config-model-1", - "litellm_params": {"model": "config-model-1"}, - "model_info": {"id": "config-model-1", "db_model": False}, - }, - { - "model_name": "config-model-2", - "litellm_params": {"model": "config-model-2"}, - "model_info": {"id": "config-model-2", "db_model": False}, - }, - ] - - # Mock llm_router - mock_router = MagicMock() - mock_router.model_list = mock_models - - # Mock prisma_client - mock_prisma_client = MagicMock() - - # Mock proxy_config.get_config - mock_get_config = AsyncMock(return_value={}) - - # Mock user authentication - mock_user_api_key_dict = MagicMock(spec=UserAPIKeyAuth) - mock_user_api_key_dict.user_id = "test-user" - mock_user_api_key_dict.api_key = "test-key" - mock_user_api_key_dict.team_models = [] - mock_user_api_key_dict.models = [] - - # Apply monkeypatches - monkeypatch.setattr("litellm.proxy.proxy_server.llm_router", mock_router) - monkeypatch.setattr("litellm.proxy.proxy_server.prisma_client", mock_prisma_client) - monkeypatch.setattr("litellm.proxy.proxy_server.user_model", None) - monkeypatch.setattr(proxy_config, "get_config", mock_get_config) - - # Override auth dependency - original_overrides = app.dependency_overrides.copy() - app.dependency_overrides[user_api_key_auth] = lambda: mock_user_api_key_dict - - client = TestClient(app) - try: - # Test sorting with specified sortBy and sortOrder - response = client.get( - "/v2/model/info", params={"sortBy": sort_by, "sortOrder": sort_order} - ) - assert response.status_code == 200 - data = response.json() - assert len(data["data"]) == len(expected_order) - - # Verify models are in expected order - actual_order = [m["model_name"] for m in data["data"]] - assert actual_order == expected_order, ( - f"Sorting failed for sortBy={sort_by}, sortOrder={sort_order}. " - f"Expected: {expected_order}, Got: {actual_order}" - ) - - finally: - app.dependency_overrides = original_overrides - - -@pytest.mark.asyncio -async def test_model_info_v2_sorting_invalid_sort_order(monkeypatch): - """ - Test that invalid sortOrder values return a 400 error. - """ - from unittest.mock import AsyncMock, MagicMock - - from litellm.proxy._types import UserAPIKeyAuth - from litellm.proxy.proxy_server import app, proxy_config, user_api_key_auth - - # Create mock models - mock_models = [ - { - "model_name": "test-model", - "litellm_params": {"model": "test-model"}, - "model_info": {"id": "test-model"}, - } - ] - - # Mock llm_router - mock_router = MagicMock() - mock_router.model_list = mock_models - - # Mock prisma_client - mock_prisma_client = MagicMock() - - # Mock proxy_config.get_config - mock_get_config = AsyncMock(return_value={}) - - # Mock user authentication - mock_user_api_key_dict = MagicMock(spec=UserAPIKeyAuth) - mock_user_api_key_dict.user_id = "test-user" - mock_user_api_key_dict.api_key = "test-key" - mock_user_api_key_dict.team_models = [] - mock_user_api_key_dict.models = [] - - # Apply monkeypatches - monkeypatch.setattr("litellm.proxy.proxy_server.llm_router", mock_router) - monkeypatch.setattr("litellm.proxy.proxy_server.prisma_client", mock_prisma_client) - monkeypatch.setattr("litellm.proxy.proxy_server.user_model", None) - monkeypatch.setattr(proxy_config, "get_config", mock_get_config) - - # Override auth dependency - original_overrides = app.dependency_overrides.copy() - app.dependency_overrides[user_api_key_auth] = lambda: mock_user_api_key_dict - - client = TestClient(app) - try: - # Test invalid sortOrder - response = client.get( - "/v2/model/info", params={"sortBy": "model_name", "sortOrder": "invalid"} - ) - assert response.status_code == 400 - data = response.json() - assert "Invalid sortOrder" in data["detail"] - - finally: - app.dependency_overrides = original_overrides - - -@pytest.mark.asyncio -async def test_apply_search_filter_to_models(monkeypatch): - """ - Test the _apply_search_filter_to_models helper function. - Tests search filtering logic for config models, db models, and database queries. - """ - from unittest.mock import AsyncMock, MagicMock - - from litellm.proxy.proxy_server import _apply_search_filter_to_models, proxy_config - - # Create mock models with mix of config and db models - mock_models = [ - { - "model_name": "gpt-4-turbo", - "model_info": {"id": "gpt-4-turbo"}, # Config model - }, - { - "model_name": "db-gpt-3.5", - "model_info": {"id": "db-model-1", "db_model": True}, # DB model in router - }, - { - "model_name": "claude-3-opus", - "model_info": {"id": "claude-3-opus"}, # Config model - }, - ] - - # Mock prisma_client - mock_prisma_client = MagicMock() - mock_db_table = MagicMock() - mock_prisma_client.db.litellm_proxymodeltable = mock_db_table - - # Mock database models - mock_db_model_1 = MagicMock( - model_id="db-model-2", - model_name="db-gemini-pro", - litellm_params='{"model": "gemini-pro"}', - model_info='{"id": "db-model-2", "db_model": true}', - ) - - # Mock proxy_config.decrypt_model_list_from_db - mock_decrypt = MagicMock(return_value=[{"model_name": "db-gemini-pro", "model_info": {"id": "db-model-2", "db_model": True}}]) - - monkeypatch.setattr(proxy_config, "decrypt_model_list_from_db", mock_decrypt) - - # Test Case 1: No search term - should return all models unchanged - result_models, total_count = await _apply_search_filter_to_models( - all_models=mock_models.copy(), - search="", - page=1, - size=50, - prisma_client=mock_prisma_client, - proxy_config=proxy_config, - ) - assert result_models == mock_models - assert total_count is None - - # Test Case 2: Search for "gpt" - should filter router models and query DB - mock_db_table.count = AsyncMock(return_value=0) - mock_db_table.find_many = AsyncMock(return_value=[]) - - result_models, total_count = await _apply_search_filter_to_models( - all_models=mock_models.copy(), - search="gpt", - page=1, - size=50, - prisma_client=mock_prisma_client, - proxy_config=proxy_config, - ) - assert len(result_models) == 2 - model_names = [m["model_name"] for m in result_models] - assert "gpt-4-turbo" in model_names - assert "db-gpt-3.5" in model_names - assert "claude-3-opus" not in model_names - assert total_count == 2 # Only router models match - - # Test Case 3: Search with DB models matching - mock_db_table.count = AsyncMock(return_value=1) - mock_db_table.find_many = AsyncMock(return_value=[mock_db_model_1]) - - result_models, total_count = await _apply_search_filter_to_models( - all_models=mock_models.copy(), - search="gemini", - page=1, - size=50, - prisma_client=mock_prisma_client, - proxy_config=proxy_config, - ) - assert total_count == 1 # Router models (0) + DB models (1) - assert len(result_models) == 1 - assert result_models[0]["model_name"] == "db-gemini-pro" - - # Test Case 4: Case-insensitive search - # Reset mocks - no DB models should match "GPT" - mock_db_table.count = AsyncMock(return_value=0) - mock_db_table.find_many = AsyncMock(return_value=[]) - - result_models, total_count = await _apply_search_filter_to_models( - all_models=mock_models.copy(), - search="GPT", - page=1, - size=50, - prisma_client=mock_prisma_client, - proxy_config=proxy_config, - ) - assert len(result_models) == 2 - model_names = [m["model_name"] for m in result_models] - assert "gpt-4-turbo" in model_names - assert "db-gpt-3.5" in model_names - - # Test Case 5: Database query error - should fallback to router models count - mock_db_table.count = AsyncMock(side_effect=Exception("DB error")) - mock_db_table.find_many = AsyncMock(return_value=[]) - - result_models, total_count = await _apply_search_filter_to_models( - all_models=mock_models.copy(), - search="gpt", - page=1, - size=50, - prisma_client=mock_prisma_client, - proxy_config=proxy_config, - ) - # Should still return filtered router models - assert len(result_models) == 2 - assert total_count == 2 # Fallback to router models count - - -def test_paginate_models_response(): - """ - Test the _paginate_models_response helper function. - Tests pagination calculation and response formatting. - """ - from litellm.proxy.proxy_server import _paginate_models_response - - # Create mock models - mock_models = [ - {"model_name": f"model-{i}", "model_info": {"id": f"model-{i}"}} - for i in range(25) - ] - - # Test Case 1: Basic pagination - first page - result = _paginate_models_response( - all_models=mock_models, - page=1, - size=10, - total_count=None, - search=None, - ) - assert result["total_count"] == 25 - assert result["current_page"] == 1 - assert result["total_pages"] == 3 # ceil(25/10) = 3 - assert result["size"] == 10 - assert len(result["data"]) == 10 - assert result["data"][0]["model_name"] == "model-0" - - # Test Case 2: Second page - result = _paginate_models_response( - all_models=mock_models, - page=2, - size=10, - total_count=None, - search=None, - ) - assert result["current_page"] == 2 - assert len(result["data"]) == 10 - assert result["data"][0]["model_name"] == "model-10" - - # Test Case 3: Last page (partial) - result = _paginate_models_response( - all_models=mock_models, - page=3, - size=10, - total_count=None, - search=None, - ) - assert result["current_page"] == 3 - assert len(result["data"]) == 5 # Only 5 models left - assert result["data"][0]["model_name"] == "model-20" - - # Test Case 4: With explicit total_count (for search scenarios) - result = _paginate_models_response( - all_models=mock_models[:10], # Only 10 models in list - page=1, - size=10, - total_count=50, # But total_count says 50 - search="test", - ) - assert result["total_count"] == 50 - assert result["total_pages"] == 5 # ceil(50/10) = 5 - assert len(result["data"]) == 10 - - # Test Case 5: Empty models list - result = _paginate_models_response( - all_models=[], - page=1, - size=10, - total_count=0, - search=None, - ) - assert result["total_count"] == 0 - assert result["total_pages"] == 0 - assert len(result["data"]) == 0 - - # Test Case 6: Page beyond available data - result = _paginate_models_response( - all_models=mock_models[:10], - page=5, - size=10, - total_count=10, - search=None, - ) - assert result["current_page"] == 5 - assert len(result["data"]) == 0 # No data for page 5 - - -def test_enrich_model_info_with_litellm_data(): - """ - Test the _enrich_model_info_with_litellm_data helper function. - Tests model info enrichment, debug mode, and sensitive info removal. - """ - from unittest.mock import MagicMock, patch - - from litellm.proxy.proxy_server import _enrich_model_info_with_litellm_data - - # Test Case 1: Basic model enrichment without debug - model = { - "model_name": "test-model", - "litellm_params": {"model": "gpt-3.5-turbo"}, - "model_info": {"id": "test-model"}, - "api_key": "sk-secret-key", # Should be removed - } - - with patch("litellm.proxy.proxy_server.get_litellm_model_info") as mock_get_info, patch( - "litellm.proxy.proxy_server.remove_sensitive_info_from_deployment" - ) as mock_remove_sensitive: - mock_get_info.return_value = { - "input_cost_per_token": 0.001, - "output_cost_per_token": 0.002, - "max_tokens": 4096, - } - mock_remove_sensitive.return_value = { - "model_name": "test-model", - "litellm_params": {"model": "gpt-3.5-turbo"}, - "model_info": { - "id": "test-model", - "input_cost_per_token": 0.001, - "output_cost_per_token": 0.002, - "max_tokens": 4096, - }, - } - - result = _enrich_model_info_with_litellm_data(model=model, debug=False) - - # Verify get_litellm_model_info was called - mock_get_info.assert_called_once_with(model=model) - # Verify remove_sensitive_info_from_deployment was called - mock_remove_sensitive.assert_called_once() - # Verify result doesn't have api_key - assert "api_key" not in result - # Verify model_info was enriched - assert "input_cost_per_token" in result["model_info"] - - # Test Case 2: Model enrichment with debug mode - model_with_debug = { - "model_name": "test-model-debug", - "litellm_params": {"model": "gpt-4"}, - "model_info": {}, - } - - mock_router = MagicMock() - mock_client = MagicMock() - mock_router._get_client.return_value = mock_client - - with patch("litellm.proxy.proxy_server.get_litellm_model_info") as mock_get_info, patch( - "litellm.proxy.proxy_server.remove_sensitive_info_from_deployment" - ) as mock_remove_sensitive: - mock_get_info.return_value = {} - mock_remove_sensitive.return_value = { - "model_name": "test-model-debug", - "litellm_params": {"model": "gpt-4"}, - "model_info": {}, - "openai_client": str(mock_client), - } - - result = _enrich_model_info_with_litellm_data( - model=model_with_debug, debug=True, llm_router=mock_router - ) - - # Verify debug info was added - mock_remove_sensitive.assert_called_once() - call_args = mock_remove_sensitive.call_args[0][0] - assert "openai_client" in call_args - # Verify router._get_client was called for debug - mock_router._get_client.assert_called_once() - - # Test Case 3: Model with fallback to litellm.get_model_info - model_fallback = { - "model_name": "test-model-fallback", - "litellm_params": {"model": "claude-3-opus"}, - "model_info": {}, - } - - with patch("litellm.proxy.proxy_server.get_litellm_model_info") as mock_get_info, patch( - "litellm.get_model_info" - ) as mock_litellm_info, patch( - "litellm.proxy.proxy_server.remove_sensitive_info_from_deployment" - ) as mock_remove_sensitive: - # First call returns empty, triggering fallback - mock_get_info.return_value = {} - mock_litellm_info.return_value = { - "input_cost_per_token": 0.015, - "output_cost_per_token": 0.075, - "max_tokens": 200000, - } - mock_remove_sensitive.return_value = { - "model_name": "test-model-fallback", - "litellm_params": {"model": "claude-3-opus"}, - "model_info": { - "input_cost_per_token": 0.015, - "output_cost_per_token": 0.075, - "max_tokens": 200000, - }, - } - - result = _enrich_model_info_with_litellm_data(model=model_fallback, debug=False) - - # Verify fallback was attempted - mock_litellm_info.assert_called_once_with(model="claude-3-opus") - # Verify model_info was enriched with fallback data - call_args = mock_remove_sensitive.call_args[0][0] - assert call_args["model_info"]["input_cost_per_token"] == 0.015 - - # Test Case 4: Model with split model name fallback - model_split = { - "model_name": "test-model-split", - "litellm_params": {"model": "azure/gpt-4"}, - "model_info": {}, - } - - with patch("litellm.proxy.proxy_server.get_litellm_model_info") as mock_get_info, patch( - "litellm.get_model_info" - ) as mock_litellm_info, patch( - "litellm.proxy.proxy_server.remove_sensitive_info_from_deployment" - ) as mock_remove_sensitive: - # Both first and second pass return empty, triggering third pass - mock_get_info.return_value = {} - # Second pass (no split) - mock_litellm_info.side_effect = [ - {}, # First call returns empty - {"max_tokens": 8192}, # Third pass with split succeeds - ] - mock_remove_sensitive.return_value = { - "model_name": "test-model-split", - "litellm_params": {"model": "azure/gpt-4"}, - "model_info": {"max_tokens": 8192}, - } - - result = _enrich_model_info_with_litellm_data(model=model_split, debug=False) - - # Verify third pass was attempted with split model name - assert mock_litellm_info.call_count == 2 - # Check that second call used split model name - second_call = mock_litellm_info.call_args_list[1] - assert second_call[1]["model"] == "gpt-4" - assert second_call[1]["custom_llm_provider"] == "azure" - - # Test Case 5: Model with existing model_info (should preserve existing keys) - model_existing = { - "model_name": "test-model-existing", - "litellm_params": {"model": "gpt-3.5-turbo"}, - "model_info": {"id": "existing-id", "custom_key": "custom_value"}, - } - - with patch("litellm.proxy.proxy_server.get_litellm_model_info") as mock_get_info, patch( - "litellm.proxy.proxy_server.remove_sensitive_info_from_deployment" - ) as mock_remove_sensitive: - mock_get_info.return_value = { - "input_cost_per_token": 0.001, - "id": "new-id", # Should not override existing "id" - } - mock_remove_sensitive.return_value = { - "model_name": "test-model-existing", - "litellm_params": {"model": "gpt-3.5-turbo"}, - "model_info": { - "id": "existing-id", # Existing key preserved - "custom_key": "custom_value", # Existing key preserved - "input_cost_per_token": 0.001, # New key added - }, - } - - result = _enrich_model_info_with_litellm_data(model=model_existing, debug=False) - - # Verify existing keys are preserved - call_args = mock_remove_sensitive.call_args[0][0] - assert call_args["model_info"]["id"] == "existing-id" - assert call_args["model_info"]["custom_key"] == "custom_value" - assert call_args["model_info"]["input_cost_per_token"] == 0.001 + # Verify existing keys are preserved + call_args = mock_remove_sensitive.call_args[0][0] + assert call_args["model_info"]["id"] == "existing-id" + assert call_args["model_info"]["custom_key"] == "custom_value" + assert call_args["model_info"]["input_cost_per_token"] == 0.001 @pytest.mark.asyncio @@ -5197,197 +4064,3 @@ def mock_create_model_info_response(model_id, provider, include_metadata=False, # Verify router methods were NOT called (normal path) mock_router.get_model_names.assert_not_called() mock_router.get_model_access_groups.assert_not_called() - - -@pytest.mark.asyncio -async def test_update_general_settings_store_prompts_in_spend_logs(monkeypatch): - """ - Test that _update_general_settings correctly normalizes store_prompts_in_spend_logs - values (handles bool, string, None, and other types). - """ - from unittest.mock import patch - - from litellm.proxy.proxy_server import ProxyConfig - - proxy_config = ProxyConfig() - - # Test Case 1: None value - mock_gs = {} - with patch("litellm.proxy.proxy_server.general_settings", mock_gs): - await proxy_config._update_general_settings( - {"store_prompts_in_spend_logs": None} - ) - assert mock_gs.get("store_prompts_in_spend_logs") is None - - # Test Case 2: bool True - mock_gs = {} - with patch("litellm.proxy.proxy_server.general_settings", mock_gs): - await proxy_config._update_general_settings( - {"store_prompts_in_spend_logs": True} - ) - assert mock_gs.get("store_prompts_in_spend_logs") is True - - # Test Case 3: bool False - mock_gs = {} - with patch("litellm.proxy.proxy_server.general_settings", mock_gs): - await proxy_config._update_general_settings( - {"store_prompts_in_spend_logs": False} - ) - assert mock_gs.get("store_prompts_in_spend_logs") is False - - # Test Case 4: string "true" (lowercase) - mock_gs = {} - with patch("litellm.proxy.proxy_server.general_settings", mock_gs): - await proxy_config._update_general_settings( - {"store_prompts_in_spend_logs": "true"} - ) - assert mock_gs.get("store_prompts_in_spend_logs") is True - - # Test Case 5: string "True" (capitalized) - mock_gs = {} - with patch("litellm.proxy.proxy_server.general_settings", mock_gs): - await proxy_config._update_general_settings( - {"store_prompts_in_spend_logs": "True"} - ) - assert mock_gs.get("store_prompts_in_spend_logs") is True - - # Test Case 6: string "TRUE" (uppercase) - mock_gs = {} - with patch("litellm.proxy.proxy_server.general_settings", mock_gs): - await proxy_config._update_general_settings( - {"store_prompts_in_spend_logs": "TRUE"} - ) - assert mock_gs.get("store_prompts_in_spend_logs") is True - - # Test Case 7: string "false" (lowercase) - mock_gs = {} - with patch("litellm.proxy.proxy_server.general_settings", mock_gs): - await proxy_config._update_general_settings( - {"store_prompts_in_spend_logs": "false"} - ) - assert mock_gs.get("store_prompts_in_spend_logs") is False - - # Test Case 8: string "False" (capitalized) - mock_gs = {} - with patch("litellm.proxy.proxy_server.general_settings", mock_gs): - await proxy_config._update_general_settings( - {"store_prompts_in_spend_logs": "False"} - ) - assert mock_gs.get("store_prompts_in_spend_logs") is False - - # Test Case 9: string "FALSE" (uppercase) - mock_gs = {} - with patch("litellm.proxy.proxy_server.general_settings", mock_gs): - await proxy_config._update_general_settings( - {"store_prompts_in_spend_logs": "FALSE"} - ) - assert mock_gs.get("store_prompts_in_spend_logs") is False - - # Test Case 10: other string value (should be False) - mock_gs = {} - with patch("litellm.proxy.proxy_server.general_settings", mock_gs): - await proxy_config._update_general_settings( - {"store_prompts_in_spend_logs": "invalid"} - ) - assert mock_gs.get("store_prompts_in_spend_logs") is False - - # Test Case 11: integer 1 (should be True) - mock_gs = {} - with patch("litellm.proxy.proxy_server.general_settings", mock_gs): - await proxy_config._update_general_settings( - {"store_prompts_in_spend_logs": 1} - ) - assert mock_gs.get("store_prompts_in_spend_logs") is True - - # Test Case 12: integer 0 (should be False) - mock_gs = {} - with patch("litellm.proxy.proxy_server.general_settings", mock_gs): - await proxy_config._update_general_settings( - {"store_prompts_in_spend_logs": 0} - ) - assert mock_gs.get("store_prompts_in_spend_logs") is False - - -@pytest.mark.asyncio -async def test_update_general_settings_maximum_spend_logs_retention_period(monkeypatch): - """ - Test that _update_general_settings correctly handles maximum_spend_logs_retention_period - and reschedules cleanup job when value changes. - """ - from unittest.mock import AsyncMock, patch - - from litellm.proxy.proxy_server import ProxyConfig - - proxy_config = ProxyConfig() - - # Test Case 1: Setting a new value should reschedule cleanup job - mock_reschedule = AsyncMock() - mock_gs = {} - with patch("litellm.proxy.proxy_server.general_settings", mock_gs), patch.object( - proxy_config, "_reschedule_spend_log_cleanup_job", mock_reschedule - ): - await proxy_config._update_general_settings( - {"maximum_spend_logs_retention_period": "7d"} - ) - assert mock_gs.get("maximum_spend_logs_retention_period") == "7d" - mock_reschedule.assert_called_once() - - # Test Case 2: Setting the same value should not reschedule - mock_reschedule.reset_mock() - mock_gs = {"maximum_spend_logs_retention_period": "7d"} - with patch("litellm.proxy.proxy_server.general_settings", mock_gs), patch.object( - proxy_config, "_reschedule_spend_log_cleanup_job", mock_reschedule - ): - await proxy_config._update_general_settings( - {"maximum_spend_logs_retention_period": "7d"} - ) - assert mock_gs.get("maximum_spend_logs_retention_period") == "7d" - mock_reschedule.assert_not_called() - - # Test Case 3: Changing value should reschedule - mock_reschedule.reset_mock() - mock_gs = {"maximum_spend_logs_retention_period": "7d"} - with patch("litellm.proxy.proxy_server.general_settings", mock_gs), patch.object( - proxy_config, "_reschedule_spend_log_cleanup_job", mock_reschedule - ): - await proxy_config._update_general_settings( - {"maximum_spend_logs_retention_period": "30d"} - ) - assert mock_gs.get("maximum_spend_logs_retention_period") == "30d" - mock_reschedule.assert_called_once() - - # Test Case 4: Setting to None should reschedule - mock_reschedule.reset_mock() - mock_gs = {"maximum_spend_logs_retention_period": "7d"} - with patch("litellm.proxy.proxy_server.general_settings", mock_gs), patch.object( - proxy_config, "_reschedule_spend_log_cleanup_job", mock_reschedule - ): - await proxy_config._update_general_settings( - {"maximum_spend_logs_retention_period": None} - ) - assert mock_gs.get("maximum_spend_logs_retention_period") is None - mock_reschedule.assert_called_once() - - # Test Case 5: Changing from None to a value should reschedule - mock_reschedule.reset_mock() - mock_gs = {} - with patch("litellm.proxy.proxy_server.general_settings", mock_gs), patch.object( - proxy_config, "_reschedule_spend_log_cleanup_job", mock_reschedule - ): - await proxy_config._update_general_settings( - {"maximum_spend_logs_retention_period": "24h"} - ) - assert mock_gs.get("maximum_spend_logs_retention_period") == "24h" - mock_reschedule.assert_called_once() - - # Test Case 6: Setting None when already None should not reschedule - mock_reschedule.reset_mock() - mock_gs = {} - with patch("litellm.proxy.proxy_server.general_settings", mock_gs), patch.object( - proxy_config, "_reschedule_spend_log_cleanup_job", mock_reschedule - ): - await proxy_config._update_general_settings( - {"maximum_spend_logs_retention_period": None} - ) - assert mock_gs.get("maximum_spend_logs_retention_period") is None - mock_reschedule.assert_not_called() diff --git a/tests/test_litellm/proxy/test_route_llm_request.py b/tests/test_litellm/proxy/test_route_llm_request.py index 90eace63714..9d8aebd2d17 100644 --- a/tests/test_litellm/proxy/test_route_llm_request.py +++ b/tests/test_litellm/proxy/test_route_llm_request.py @@ -1,7 +1,9 @@ +import json import os import sys import pytest +from fastapi.testclient import TestClient sys.path.insert( 0, os.path.abspath("../../..") @@ -47,13 +49,7 @@ async def test_route_request_dynamic_credentials(route_type): @pytest.mark.asyncio async def test_route_request_no_model_required(): """Test route types that don't require model parameter""" - test_cases = [ - "amoderation", - "aget_responses", - "adelete_responses", - "avector_store_create", - "avector_store_search", - ] + test_cases = ["amoderation", "aget_responses", "adelete_responses", "avector_store_create", "avector_store_search"] for route_type in test_cases: # Test data without model parameter @@ -76,13 +72,7 @@ async def test_route_request_no_model_required(): @pytest.mark.asyncio async def test_route_request_no_model_required_with_router_settings(): """Test route types that don't require model parameter with router settings""" - test_cases = [ - "amoderation", - "aget_responses", - "adelete_responses", - "avector_store_create", - "avector_store_search", - ] + test_cases = ["amoderation", "aget_responses", "adelete_responses", "avector_store_create", "avector_store_search"] for route_type in test_cases: # Test data with model parameter (it will be ignored for these route types) @@ -131,68 +121,6 @@ async def test_route_request_no_model_required_with_router_settings_and_no_route with patch.object( litellm, "acompletion", return_value="fake_response" ) as mock_completion: - await route_request(data, None, "gpt-3.5-turbo", "acompletion") + response = await route_request(data, None, "gpt-3.5-turbo", "acompletion") mock_completion.assert_called_once_with(**data) - - -@pytest.mark.asyncio -async def test_route_request_with_invalid_router_params(): - """ - Test that route_request filters out invalid Router init params from 'user_config'. - This covers the fix for https://github.com/BerriAI/litellm/issues/19693 - """ - import litellm - from litellm.router import Router - from unittest.mock import AsyncMock - - # Mock data with user_config containing invalid keys (simulating DB entry) - data = { - "model": "gpt-3.5-turbo", - "user_config": { - "model_list": [ - { - "model_name": "gpt-3.5-turbo", - "litellm_params": {"model": "gpt-3.5-turbo", "api_key": "test"}, - } - ], - "model_alias_map": {"alias": "real_model"}, # INVALID PARAM - "invalid_garbage_key": "crash_me", # INVALID PARAM - }, - } - - # We expect Router(**config) to succeed because of the filtering. - # If filtering fails, this will raise TypeError and fail the test. - try: - # route_request calls getattr(user_router, route_type)(**data) - # We'll mock the internal call to avoid making real network requests - with pytest.MonkeyPatch.context() as m: - # Mock the method that gets called on the router instance - # We don't easily have access to the instance created INSIDE existing route_request - # So we will wrap litellm.Router to spy on it or verify it doesn't crash - - original_router_init = litellm.Router.__init__ - - def safe_router_init(self, **kwargs): - # Verify that invalid keys are NOT present in kwargs - assert "model_alias_map" not in kwargs - assert "invalid_garbage_key" not in kwargs - # Call original init (which would raise TypeError if invalid keys were present) - original_router_init(self, **kwargs) - - m.setattr(litellm.Router, "__init__", safe_router_init) - - # Use 'acompletion' as the route_type - # We also need to mock the completion method to avoid real calls - m.setattr(Router, "acompletion", AsyncMock(return_value="success")) - - response = await route_request(data, None, None, "acompletion") - assert response == "success" - - except TypeError as e: - pytest.fail( - f"route_request raised TypeError, implying invalid params were passed to Router: {e}" - ) - except Exception: - # Other exceptions might happen (e.g. valid config issues) but we care about TypeError here - pass diff --git a/tests/test_litellm/proxy/vector_store_endpoints/test_vector_store_access_control.py b/tests/test_litellm/proxy/vector_store_endpoints/test_vector_store_access_control.py deleted file mode 100644 index 42043c6d168..00000000000 --- a/tests/test_litellm/proxy/vector_store_endpoints/test_vector_store_access_control.py +++ /dev/null @@ -1,87 +0,0 @@ -""" -Test vector store access control based on team membership. - -Core tests: -1. Access control logic works correctly for different team scenarios -2. Delete endpoint enforces team access control -""" - -from unittest.mock import AsyncMock, MagicMock, patch - -import pytest -from fastapi import HTTPException - -from litellm.proxy._types import UserAPIKeyAuth -from litellm.proxy.vector_store_endpoints.management_endpoints import ( - _check_vector_store_access, -) -from litellm.types.vector_stores import LiteLLM_ManagedVectorStore - - -def test_check_vector_store_access(): - """Test core access control logic for team-based vector store access""" - - # Test 1: Legacy vector stores (no team_id) are accessible to all - vector_store: LiteLLM_ManagedVectorStore = { - "vector_store_id": "vs_legacy", - "custom_llm_provider": "openai", - "team_id": None, - } - user = UserAPIKeyAuth(team_id="team_456") - assert _check_vector_store_access(vector_store, user) is True - - # Test 2: User can access their team's vector stores - vector_store = { - "vector_store_id": "vs_team", - "custom_llm_provider": "openai", - "team_id": "team_456", - } - user = UserAPIKeyAuth(team_id="team_456") - assert _check_vector_store_access(vector_store, user) is True - - # Test 3: User cannot access other teams' vector stores - vector_store = { - "vector_store_id": "vs_team", - "custom_llm_provider": "openai", - "team_id": "team_456", - } - user = UserAPIKeyAuth(team_id="team_789") - assert _check_vector_store_access(vector_store, user) is False - - -@pytest.mark.asyncio -async def test_delete_vector_store_checks_access(): - """Test that delete endpoint enforces team access control""" - from litellm.proxy.vector_store_endpoints.management_endpoints import ( - delete_vector_store, - ) - from litellm.types.vector_stores import VectorStoreDeleteRequest - - mock_prisma = MagicMock() - mock_vector_store = MagicMock( - model_dump=lambda: { - "vector_store_id": "vs_123", - "custom_llm_provider": "openai", - "team_id": "team_456", - } - ) - mock_prisma.db.litellm_managedvectorstorestable.find_unique = AsyncMock( - return_value=mock_vector_store - ) - - # User from different team should get 403 - user_api_key_dict = UserAPIKeyAuth(team_id="team_789") - request = VectorStoreDeleteRequest(vector_store_id="vs_123") - - with patch( - "litellm.proxy.vector_store_endpoints.management_endpoints.prisma_client", - mock_prisma, - ): - with patch("litellm.vector_store_registry", None): - with pytest.raises(HTTPException) as exc_info: - await delete_vector_store( - data=request, user_api_key_dict=user_api_key_dict - ) - - assert exc_info.value.status_code == 403 - assert "Access denied" in exc_info.value.detail diff --git a/tests/test_litellm/responses/test_responses_utils.py b/tests/test_litellm/responses/test_responses_utils.py index 8f7acb6c120..3eb9c63e1be 100644 --- a/tests/test_litellm/responses/test_responses_utils.py +++ b/tests/test_litellm/responses/test_responses_utils.py @@ -309,46 +309,3 @@ def test_transform_response_api_usage_mixed_details(self): assert result.completion_tokens_details.reasoning_tokens == 30 assert result.completion_tokens_details.image_tokens == 100 assert result.completion_tokens_details.text_tokens == 70 - - -class TestResponsesAPIProviderSpecificParams: - """ - Tests for fix #19782: provider-specific params (aws_*, vertex_*) should work - without explicitly passing custom_llm_provider. - """ - - def test_provider_specific_params_no_crash_with_bedrock(self): - """Test that processing aws_* params with bedrock provider doesn't crash.""" - params = { - "temperature": 0.7, - "custom_llm_provider": "bedrock", - "kwargs": {"aws_region_name": "eu-central-1"}, - } - - # Should not raise any exception - result = ResponsesAPIRequestUtils.get_requested_response_api_optional_param(params) - assert "temperature" in result - - def test_provider_specific_params_no_crash_with_openai(self): - """Test that processing aws_* params with openai provider doesn't crash.""" - params = { - "temperature": 0.7, - "custom_llm_provider": "openai", - "kwargs": {"aws_region_name": "eu-central-1"}, - } - - # Should not raise any exception - result = ResponsesAPIRequestUtils.get_requested_response_api_optional_param(params) - assert "temperature" in result - - def test_provider_specific_params_no_crash_with_vertex_ai(self): - """Test that processing vertex_* params with vertex_ai provider doesn't crash.""" - params = { - "temperature": 0.7, - "custom_llm_provider": "vertex_ai", - "kwargs": {"vertex_project": "my-project"}, - } - - # Should not raise any exception - result = ResponsesAPIRequestUtils.get_requested_response_api_optional_param(params) - assert "temperature" in result diff --git a/tests/test_litellm/secret_managers/test_secret_managers_main.py b/tests/test_litellm/secret_managers/test_secret_managers_main.py index eaef6956cd5..159e41546df 100644 --- a/tests/test_litellm/secret_managers/test_secret_managers_main.py +++ b/tests/test_litellm/secret_managers/test_secret_managers_main.py @@ -47,12 +47,11 @@ def mock_env(): @patch("litellm.secret_managers.main.oidc_cache") -@patch("litellm.secret_managers.main._get_oidc_http_handler") -@patch("httpx.Client") # Prevent any real HTTP connections -def test_oidc_google_success(mock_httpx_client, mock_get_http_handler, mock_oidc_cache): +@patch("litellm.secret_managers.main.HTTPHandler") +def test_oidc_google_success(mock_http_handler, mock_oidc_cache): mock_oidc_cache.get_cache.return_value = None mock_handler = MockHTTPHandler(timeout=600.0) - mock_get_http_handler.return_value = mock_handler + mock_http_handler.return_value = mock_handler secret_name = "oidc/google/[invalid url, do not cite]" result = get_secret(secret_name) @@ -64,31 +63,28 @@ def test_oidc_google_success(mock_httpx_client, mock_get_http_handler, mock_oidc @patch("litellm.secret_managers.main.oidc_cache") -@patch("litellm.secret_managers.main._get_oidc_http_handler") -def test_oidc_google_cached(mock_get_http_handler, mock_oidc_cache): +def test_oidc_google_cached(mock_oidc_cache): mock_oidc_cache.get_cache.return_value = "cached_token" secret_name = "oidc/google/[invalid url, do not cite]" - result = get_secret(secret_name) + with patch("litellm.HTTPHandler") as mock_http: + result = get_secret(secret_name) - assert result == "cached_token", f"Expected cached token, got {result}" - mock_oidc_cache.get_cache.assert_called_with(key=secret_name) - # Verify HTTP handler was never called since we had a cached token - mock_get_http_handler.assert_not_called() + assert result == "cached_token", f"Expected cached token, got {result}" + mock_oidc_cache.get_cache.assert_called_with(key=secret_name) + mock_http.assert_not_called() -@patch("litellm.secret_managers.main.oidc_cache") -@patch("litellm.secret_managers.main._get_oidc_http_handler") -def test_oidc_google_failure(mock_get_http_handler, mock_oidc_cache): +def test_oidc_google_failure(mock_oidc_cache): mock_handler = MockHTTPHandler(timeout=600.0) mock_handler.status_code = 400 - mock_get_http_handler.return_value = mock_handler - mock_oidc_cache.get_cache.return_value = None - - secret_name = "oidc/google/https://example.com/api" - with pytest.raises(ValueError, match="Google OIDC provider failed"): - get_secret(secret_name) + with patch("litellm.secret_managers.main.HTTPHandler", return_value=mock_handler): + mock_oidc_cache.get_cache.return_value = None + secret_name = "oidc/google/https://example.com/api" + + with pytest.raises(ValueError, match="Google OIDC provider failed"): + get_secret(secret_name) def test_oidc_circleci_success(monkeypatch): @@ -109,13 +105,13 @@ def test_oidc_circleci_failure(monkeypatch): @patch("litellm.secret_managers.main.oidc_cache") -@patch("litellm.secret_managers.main._get_oidc_http_handler") -def test_oidc_github_success(mock_get_http_handler, mock_oidc_cache, mock_env): +@patch("litellm.secret_managers.main.HTTPHandler") +def test_oidc_github_success(mock_http_handler, mock_oidc_cache, mock_env): mock_env["ACTIONS_ID_TOKEN_REQUEST_URL"] = "https://github.com/token" mock_env["ACTIONS_ID_TOKEN_REQUEST_TOKEN"] = "github_token" mock_oidc_cache.get_cache.return_value = None mock_handler = MockHTTPHandler(timeout=600.0) - mock_get_http_handler.return_value = mock_handler + mock_http_handler.return_value = mock_handler secret_name = "oidc/github/github-audience" result = get_secret(secret_name) @@ -145,34 +141,23 @@ def test_oidc_azure_file_success(mock_env, tmp_path): mock_env["AZURE_FEDERATED_TOKEN_FILE"] = str(token_file) secret_name = "oidc/azure/azure-audience" - result = get_secret(secret_name) + result = get_secret(secret_name) assert result == "azure_token" @patch("litellm.secret_managers.main.get_azure_ad_token_provider") -@patch.dict(os.environ, {}, clear=False) # Ensure AZURE_FEDERATED_TOKEN_FILE is not set def test_oidc_azure_ad_token_success(mock_get_azure_ad_token_provider): - # Ensure the env var is not set so it falls through to Azure AD token provider - if "AZURE_FEDERATED_TOKEN_FILE" in os.environ: - del os.environ["AZURE_FEDERATED_TOKEN_FILE"] - - # Mock the token provider function that gets returned and called mock_token_provider = Mock(return_value="azure_ad_token") mock_get_azure_ad_token_provider.return_value = mock_token_provider - - # Also mock the Azure Identity SDK to prevent any real Azure calls - with patch("azure.identity.get_bearer_token_provider") as mock_bearer: - mock_bearer.return_value = mock_token_provider - - secret_name = "oidc/azure/api://azure-audience" - result = get_secret(secret_name) + secret_name = "oidc/azure/api://azure-audience" + result = get_secret(secret_name) - assert result == "azure_ad_token" - mock_get_azure_ad_token_provider.assert_called_once_with( - azure_scope="api://azure-audience" - ) - mock_token_provider.assert_called_once_with() + assert result == "azure_ad_token" + mock_get_azure_ad_token_provider.assert_called_once_with( + azure_scope="api://azure-audience" + ) + mock_token_provider.assert_called_once_with() def test_oidc_file_success(tmp_path): diff --git a/tests/test_litellm/test_cost_calculator.py b/tests/test_litellm/test_cost_calculator.py index 74f5cf9bdd7..5bf7a70055e 100644 --- a/tests/test_litellm/test_cost_calculator.py +++ b/tests/test_litellm/test_cost_calculator.py @@ -1,3 +1,4 @@ +import json import os import sys @@ -7,6 +8,7 @@ 0, os.path.abspath("../..") ) # Adds the parent directory to the system path +from unittest.mock import MagicMock, patch from pydantic import BaseModel @@ -68,6 +70,8 @@ class MockResponse(BaseModel): def test_cost_calculator_with_usage(monkeypatch): + from litellm import get_model_info + os.environ["LITELLM_LOCAL_MODEL_COST_MAP"] = "True" litellm.model_cost = litellm.get_model_cost_map(url="") @@ -75,9 +79,7 @@ def test_cost_calculator_with_usage(monkeypatch): prompt_tokens=120, completion_tokens=100, prompt_tokens_details=PromptTokensDetailsWrapper( - text_tokens=10, - audio_tokens=90, - image_tokens=20, + text_tokens=10, audio_tokens=90, image_tokens=20, ), ) mr = ModelResponse(usage=usage, model="gemini-2.0-flash-001") @@ -96,9 +98,7 @@ def test_cost_calculator_with_usage(monkeypatch): # Step 1: Test a model where input_cost_per_image_token is not set. # In this case the calculation should use input_cost_per_token as fallback. - assert ( - model_info.get("input_cost_per_image_token") is None - ), "Test case expects that input_cost_per_image_token is not set" + assert model_info.get("input_cost_per_image_token") is None, "Test case expects that input_cost_per_image_token is not set" expected_cost = ( usage.prompt_tokens_details.audio_tokens @@ -118,13 +118,11 @@ def test_cost_calculator_with_usage(monkeypatch): monkeypatch.setattr( litellm, "model_cost", - {"gemini-2.0-flash-001": temp_model_info_object}, + { + "gemini-2.0-flash-001": temp_model_info_object + }, ) - # Invalidate caches after modifying litellm.model_cost - from litellm.utils import _invalidate_model_cost_lowercase_map - _invalidate_model_cost_lowercase_map() - result = response_cost_calculator( response_object=mr, model="", @@ -138,10 +136,8 @@ def test_cost_calculator_with_usage(monkeypatch): expected_cost = ( usage.prompt_tokens_details.audio_tokens * temp_model_info_object["input_cost_per_audio_token"] - + usage.prompt_tokens_details.text_tokens - * temp_model_info_object["input_cost_per_token"] - + usage.prompt_tokens_details.image_tokens - * temp_model_info_object["input_cost_per_image_token"] + + usage.prompt_tokens_details.text_tokens * temp_model_info_object["input_cost_per_token"] + + usage.prompt_tokens_details.image_tokens * temp_model_info_object["input_cost_per_image_token"] + usage.completion_tokens * temp_model_info_object["output_cost_per_token"] ) @@ -333,6 +329,8 @@ def test_custom_pricing_with_router_model_id(): def test_azure_realtime_cost_calculator(): + from litellm import get_model_info + os.environ["LITELLM_LOCAL_MODEL_COST_MAP"] = "True" litellm.model_cost = litellm.get_model_cost_map(url="") @@ -357,90 +355,6 @@ def test_azure_realtime_cost_calculator(): assert cost > 0 -def test_azure_audio_output_cost_calculation(): - """ - Test that Azure audio models correctly calculate costs for audio output tokens. - - Reproduces issue: https://github.com/BerriAI/litellm/issues/19764 - Audio tokens should be charged at output_cost_per_audio_token rate, - not at the text token rate (output_cost_per_token). - """ - from litellm.types.utils import ( - Choices, - CompletionTokensDetailsWrapper, - Message, - ) - - os.environ["LITELLM_LOCAL_MODEL_COST_MAP"] = "True" - litellm.model_cost = litellm.get_model_cost_map(url="") - - # Scenario from issue #19764: - # Input: 17 text tokens, 0 audio tokens - # Output: 110 text tokens, 482 audio tokens - usage_object = Usage( - prompt_tokens=17, - completion_tokens=592, # 110 text + 482 audio - total_tokens=609, - prompt_tokens_details=PromptTokensDetailsWrapper( - audio_tokens=0, - cached_tokens=0, - text_tokens=17, - image_tokens=0, - ), - completion_tokens_details=CompletionTokensDetailsWrapper( - audio_tokens=482, - reasoning_tokens=0, - text_tokens=110, - ), - ) - - completion = ModelResponse( - id="test-azure-audio-cost", - choices=[ - Choices( - finish_reason="stop", - index=0, - message=Message( - content="Test response", - role="assistant", - ), - ) - ], - created=1729282652, - model="azure/gpt-audio-2025-08-28", - object="chat.completion", - usage=usage_object, - ) - - cost = completion_cost(completion, model="azure/gpt-audio-2025-08-28") - - model_info = litellm.get_model_info("azure/gpt-audio-2025-08-28") - - # Calculate expected cost - expected_input_cost = ( - model_info["input_cost_per_token"] * 17 # text tokens - ) - expected_output_cost = ( - model_info["output_cost_per_token"] * 110 # text tokens - + model_info["output_cost_per_audio_token"] * 482 # audio tokens - ) - expected_total_cost = expected_input_cost + expected_output_cost - - # The bug was: all output tokens charged at text rate - wrong_output_cost = model_info["output_cost_per_token"] * 592 - wrong_total_cost = expected_input_cost + wrong_output_cost - - # Verify audio tokens are NOT charged at text rate (the bug) - assert abs(cost - wrong_total_cost) > 0.001, ( - "Bug: Audio tokens are being charged at text token rate" - ) - - # Verify cost matches - assert abs(cost - expected_total_cost) < 0.0000001, ( - f"Expected cost {expected_total_cost}, got {cost}" - ) - - def test_default_image_cost_calculator(monkeypatch): from litellm.cost_calculator import default_image_cost_calculator @@ -473,7 +387,9 @@ def test_cost_calculator_with_cache_creation(): from litellm import completion_cost from litellm.types.utils import ( Choices, + CompletionTokensDetailsWrapper, Message, + PromptTokensDetailsWrapper, Usage, ) @@ -529,7 +445,7 @@ def test_cost_calculator_with_cache_creation(): def test_bedrock_cost_calculator_comparison_with_without_cache(): """Test that Bedrock caching reduces costs compared to non-cached requests""" from litellm import completion_cost - from litellm.types.utils import Choices, Message, Usage + from litellm.types.utils import Choices, Message, PromptTokensDetailsWrapper, Usage # Response WITHOUT caching response_no_cache = ModelResponse( @@ -780,7 +696,7 @@ def test_log_context_cost_calculation(): f"DEBUG: Tiered input cost per token (>200k): ${input_cost_above_200k:.2e}" ) else: - print("DEBUG: No tiered input pricing available, using base pricing") + print(f"DEBUG: No tiered input pricing available, using base pricing") input_cost_above_200k = input_cost_per_token if output_cost_above_200k is not None: @@ -788,7 +704,7 @@ def test_log_context_cost_calculation(): f"DEBUG: Tiered output cost per token (>200k): ${output_cost_above_200k:.2e}" ) else: - print("DEBUG: No tiered output pricing available, using base pricing") + print(f"DEBUG: No tiered output pricing available, using base pricing") output_cost_above_200k = output_cost_per_token if cache_creation_above_200k is not None: @@ -796,7 +712,7 @@ def test_log_context_cost_calculation(): f"DEBUG: Tiered cache creation cost per token (>200k): ${cache_creation_above_200k:.2e}" ) else: - print("DEBUG: No tiered cache creation pricing available, using base pricing") + print(f"DEBUG: No tiered cache creation pricing available, using base pricing") cache_creation_above_200k = cache_creation_cost_per_token # Since we're above 200k tokens, we should use tiered pricing if available @@ -1005,7 +921,7 @@ def test_cost_discount_vertex_ai(): expected_cost = cost_without_discount * 0.95 assert cost_with_discount == pytest.approx(expected_cost, rel=1e-9) - print("✓ Cost discount test passed:") + print(f"✓ Cost discount test passed:") print(f" - Original cost: ${cost_without_discount:.6f}") print(f" - Discounted cost (5% off): ${cost_with_discount:.6f}") print(f" - Savings: ${cost_without_discount - cost_with_discount:.6f}") @@ -1055,7 +971,7 @@ def test_cost_discount_not_applied_to_other_providers(): # Costs should be the same (no discount applied to OpenAI) assert cost_with_selective_discount == cost_without_discount - print("✓ Selective discount test passed:") + print(f"✓ Selective discount test passed:") print(f" - OpenAI cost (no discount configured): ${cost_without_discount:.6f}") print(f" - Cost remains unchanged: ${cost_with_selective_discount:.6f}") @@ -1105,7 +1021,7 @@ def test_cost_margin_percentage(): expected_cost = cost_without_margin * 1.10 assert cost_with_margin == pytest.approx(expected_cost, rel=1e-9) - print("✓ Cost margin percentage test passed:") + print(f"✓ Cost margin percentage test passed:") print(f" - Original cost: ${cost_without_margin:.6f}") print(f" - Cost with margin (10%): ${cost_with_margin:.6f}") print(f" - Margin added: ${cost_with_margin - cost_without_margin:.6f}") @@ -1156,7 +1072,7 @@ def test_cost_margin_fixed_amount(): expected_cost = cost_without_margin + 0.001 assert cost_with_margin == pytest.approx(expected_cost, rel=1e-9) - print("✓ Cost margin fixed amount test passed:") + print(f"✓ Cost margin fixed amount test passed:") print(f" - Original cost: ${cost_without_margin:.6f}") print(f" - Cost with margin ($0.001): ${cost_with_margin:.6f}") print(f" - Margin added: ${cost_with_margin - cost_without_margin:.6f}") @@ -1191,9 +1107,7 @@ def test_cost_margin_combined(): ) # Set 8% margin + $0.0005 fixed for openai - litellm.cost_margin_config = { - "openai": {"percentage": 0.08, "fixed_amount": 0.0005} - } + litellm.cost_margin_config = {"openai": {"percentage": 0.08, "fixed_amount": 0.0005}} # Calculate cost with margin cost_with_margin = completion_cost( @@ -1209,7 +1123,7 @@ def test_cost_margin_combined(): expected_cost = cost_without_margin * 1.08 + 0.0005 assert cost_with_margin == pytest.approx(expected_cost, rel=1e-9) - print("✓ Cost margin combined test passed:") + print(f"✓ Cost margin combined test passed:") print(f" - Original cost: ${cost_without_margin:.6f}") print(f" - Cost with margin (8% + $0.0005): ${cost_with_margin:.6f}") print(f" - Margin added: ${cost_with_margin - cost_without_margin:.6f}") @@ -1260,7 +1174,7 @@ def test_cost_margin_global(): expected_cost = cost_without_margin * 1.05 assert cost_with_global_margin == pytest.approx(expected_cost, rel=1e-9) - print("✓ Cost margin global test passed:") + print(f"✓ Cost margin global test passed:") print(f" - Original cost: ${cost_without_margin:.6f}") print(f" - Cost with global margin (5%): ${cost_with_global_margin:.6f}") print(f" - Margin added: ${cost_with_global_margin - cost_without_margin:.6f}") @@ -1311,11 +1225,9 @@ def test_cost_margin_provider_overrides_global(): expected_cost = cost_without_margin * 1.10 # 10% from provider, not 5% from global assert cost_with_provider_margin == pytest.approx(expected_cost, rel=1e-9) - print("✓ Cost margin provider override test passed:") + print(f"✓ Cost margin provider override test passed:") print(f" - Original cost: ${cost_without_margin:.6f}") - print( - f" - Cost with provider margin (10%, overrides 5% global): ${cost_with_provider_margin:.6f}" - ) + print(f" - Cost with provider margin (10%, overrides 5% global): ${cost_with_provider_margin:.6f}") print(f" - Margin added: ${cost_with_provider_margin - cost_without_margin:.6f}") @@ -1369,7 +1281,7 @@ def test_cost_margin_with_discount(): expected_cost = base_cost * 0.95 * 1.10 assert cost_with_both == pytest.approx(expected_cost, rel=1e-9) - print("✓ Cost margin with discount test passed:") + print(f"✓ Cost margin with discount test passed:") print(f" - Base cost: ${base_cost:.6f}") print(f" - Cost with 5% discount + 10% margin: ${cost_with_both:.6f}") print(f" - Expected: ${expected_cost:.6f}") @@ -1438,10 +1350,14 @@ def test_completion_cost_extracts_service_tier_from_response(): # Test with gpt-5-nano which has flex pricing model = "gpt-5-nano" - + # Create usage object - usage = Usage(prompt_tokens=1000, completion_tokens=500, total_tokens=1500) - + usage = Usage( + prompt_tokens=1000, + completion_tokens=500, + total_tokens=1500 + ) + # Create ModelResponse with service_tier in the response object response_with_service_tier = ModelResponse( usage=usage, @@ -1449,36 +1365,34 @@ def test_completion_cost_extracts_service_tier_from_response(): ) # Set service_tier as an attribute on the response setattr(response_with_service_tier, "service_tier", "flex") - + # Test that flex pricing is used when service_tier is in response flex_cost = completion_cost( completion_response=response_with_service_tier, model=model, custom_llm_provider="openai", ) - + # Create ModelResponse without service_tier (should use standard pricing) response_without_service_tier = ModelResponse( usage=usage, model=model, ) - + # Test that standard pricing is used when service_tier is not in response standard_cost = completion_cost( completion_response=response_without_service_tier, model=model, custom_llm_provider="openai", ) - + # Flex should be approximately 50% of standard assert flex_cost > 0, "Flex cost should be greater than 0" assert standard_cost > 0, "Standard cost should be greater than 0" assert flex_cost < standard_cost, "Flex cost should be less than standard cost" - + flex_ratio = flex_cost / standard_cost - assert ( - 0.45 <= flex_ratio <= 0.55 - ), f"Flex pricing should be ~50% of standard, got {flex_ratio:.2f}" + assert 0.45 <= flex_ratio <= 0.55, f"Flex pricing should be ~50% of standard, got {flex_ratio:.2f}" def test_completion_cost_extracts_service_tier_from_usage(): @@ -1490,54 +1404,56 @@ def test_completion_cost_extracts_service_tier_from_usage(): # Test with gpt-5-nano which has flex pricing model = "gpt-5-nano" - + # Create usage object with service_tier usage_with_service_tier = Usage( - prompt_tokens=1000, completion_tokens=500, total_tokens=1500 + prompt_tokens=1000, + completion_tokens=500, + total_tokens=1500 ) # Set service_tier as an attribute on the usage object setattr(usage_with_service_tier, "service_tier", "flex") - + # Create ModelResponse with usage containing service_tier response = ModelResponse( usage=usage_with_service_tier, model=model, ) - + # Test that flex pricing is used when service_tier is in usage flex_cost = completion_cost( completion_response=response, model=model, custom_llm_provider="openai", ) - + # Create usage object without service_tier usage_without_service_tier = Usage( - prompt_tokens=1000, completion_tokens=500, total_tokens=1500 + prompt_tokens=1000, + completion_tokens=500, + total_tokens=1500 ) - + # Create ModelResponse with usage without service_tier response_standard = ModelResponse( usage=usage_without_service_tier, model=model, ) - + # Test that standard pricing is used when service_tier is not in usage standard_cost = completion_cost( completion_response=response_standard, model=model, custom_llm_provider="openai", ) - + # Flex should be approximately 50% of standard assert flex_cost > 0, "Flex cost should be greater than 0" assert standard_cost > 0, "Standard cost should be greater than 0" assert flex_cost < standard_cost, "Flex cost should be less than standard cost" - + flex_ratio = flex_cost / standard_cost - assert ( - 0.45 <= flex_ratio <= 0.55 - ), f"Flex pricing should be ~50% of standard, got {flex_ratio:.2f}" + assert 0.45 <= flex_ratio <= 0.55, f"Flex pricing should be ~50% of standard, got {flex_ratio:.2f}" def test_completion_cost_service_tier_priority(): @@ -1549,18 +1465,22 @@ def test_completion_cost_service_tier_priority(): # Test with gpt-5-nano which has flex pricing model = "gpt-5-nano" - + # Create usage object with service_tier="flex" - usage = Usage(prompt_tokens=1000, completion_tokens=500, total_tokens=1500) + usage = Usage( + prompt_tokens=1000, + completion_tokens=500, + total_tokens=1500 + ) setattr(usage, "service_tier", "flex") - + # Create response with service_tier="priority" response = ModelResponse( usage=usage, model=model, ) setattr(response, "service_tier", "priority") - + # Test that optional_params takes priority over response and usage cost_from_params = completion_cost( completion_response=response, @@ -1568,14 +1488,14 @@ def test_completion_cost_service_tier_priority(): custom_llm_provider="openai", optional_params={"service_tier": "flex"}, ) - + # Test that response takes priority over usage when optional_params is not provided - completion_cost( + cost_from_response = completion_cost( completion_response=response, model=model, custom_llm_provider="openai", ) - + # Test that usage is used when neither optional_params nor response have service_tier # Create a new response without service_tier attribute response_no_tier = ModelResponse( @@ -1583,27 +1503,25 @@ def test_completion_cost_service_tier_priority(): model=model, ) # Don't set service_tier on response, so it will fall back to usage - + cost_from_usage = completion_cost( completion_response=response_no_tier, model=model, custom_llm_provider="openai", ) - + # All should use flex pricing (from different sources) assert cost_from_params > 0, "Cost from params should be greater than 0" assert cost_from_usage > 0, "Cost from usage should be greater than 0" - + # Costs should be similar (all using flex) - assert ( - abs(cost_from_params - cost_from_usage) < 1e-6 - ), "Costs from params and usage should be similar (both flex)" + assert abs(cost_from_params - cost_from_usage) < 1e-6, "Costs from params and usage should be similar (both flex)" def test_gemini_cache_tokens_details_no_negative_values(): """ Test for Issue #18750: Negative text_tokens with Gemini caching - + When using Gemini with explicit caching, the response includes cacheTokensDetails which breaks down cached tokens by modality. This test ensures that: 1. text_tokens is never negative @@ -1624,47 +1542,41 @@ def test_gemini_cache_tokens_details_no_negative_values(): # Total tokens by modality (includes cached + non-cached) "promptTokensDetails": [ {"modality": "TEXT", "tokenCount": 9402}, - {"modality": "IMAGE", "tokenCount": 258}, + {"modality": "IMAGE", "tokenCount": 258} ], # Breakdown of cached tokens by modality "cacheTokensDetails": [ {"modality": "TEXT", "tokenCount": 9393}, - {"modality": "IMAGE", "tokenCount": 258}, - ], + {"modality": "IMAGE", "tokenCount": 258} + ] } } usage = VertexGeminiConfig._calculate_usage(completion_response) # Text tokens should be non-cached text only: 9402 - 9393 = 9 - assert ( - usage.prompt_tokens_details.text_tokens == 9 - ), f"Expected text_tokens=9, got {usage.prompt_tokens_details.text_tokens}" + assert usage.prompt_tokens_details.text_tokens == 9, \ + f"Expected text_tokens=9, got {usage.prompt_tokens_details.text_tokens}" # Image tokens should be non-cached image only: 258 - 258 = 0 - assert ( - usage.prompt_tokens_details.image_tokens == 0 - ), f"Expected image_tokens=0, got {usage.prompt_tokens_details.image_tokens}" + assert usage.prompt_tokens_details.image_tokens == 0, \ + f"Expected image_tokens=0, got {usage.prompt_tokens_details.image_tokens}" # Total cached should match - assert ( - usage.prompt_tokens_details.cached_tokens == 9651 - ), f"Expected cached_tokens=9651, got {usage.prompt_tokens_details.cached_tokens}" + assert usage.prompt_tokens_details.cached_tokens == 9651, \ + f"Expected cached_tokens=9651, got {usage.prompt_tokens_details.cached_tokens}" # MOST IMPORTANT: text_tokens should NEVER be negative - assert ( - usage.prompt_tokens_details.text_tokens >= 0 - ), f"BUG: text_tokens is negative ({usage.prompt_tokens_details.text_tokens})! This was the issue in #18750" + assert usage.prompt_tokens_details.text_tokens >= 0, \ + f"BUG: text_tokens is negative ({usage.prompt_tokens_details.text_tokens})! This was the issue in #18750" - print( - "✅ Issue #18750 fix verified: text_tokens is correctly calculated and non-negative" - ) + print("✅ Issue #18750 fix verified: text_tokens is correctly calculated and non-negative") def test_gemini_without_cache_tokens_details(): """ Test Gemini response without cacheTokensDetails (implicit caching or no cache) - + When cacheTokensDetails is not present, we should use promptTokensDetails as-is without subtracting anything. """ @@ -1679,7 +1591,7 @@ def test_gemini_without_cache_tokens_details(): "totalTokenCount": 279, "promptTokensDetails": [ {"modality": "TEXT", "tokenCount": 6}, - {"modality": "IMAGE", "tokenCount": 258}, + {"modality": "IMAGE", "tokenCount": 258} ] # No cacheTokensDetails } @@ -1693,86 +1605,3 @@ def test_gemini_without_cache_tokens_details(): assert usage.prompt_tokens_details.text_tokens >= 0 print("✅ Gemini without cacheTokensDetails works correctly") - - -def test_gemini_implicit_caching_cost_calculation(): - """ - Test for Issue #16341: Gemini implicit cached tokens not counted in spend log - - When Gemini uses implicit caching, it returns cachedContentTokenCount but NOT - cacheTokensDetails. In this case, we should subtract cachedContentTokenCount - from text_tokens to correctly calculate costs. - - See: https://github.com/BerriAI/litellm/issues/16341 - """ - from litellm import completion_cost - from litellm.llms.vertex_ai.gemini.vertex_and_google_ai_studio_gemini import ( - VertexGeminiConfig, - ) - from litellm.types.utils import Choices, Message, ModelResponse - - # Simulate Gemini response with implicit caching (cachedContentTokenCount only) - completion_response = { - "usageMetadata": { - "promptTokenCount": 10000, - "candidatesTokenCount": 5, - "totalTokenCount": 10005, - "cachedContentTokenCount": 8000, # Implicit caching - no cacheTokensDetails - "promptTokensDetails": [{"modality": "TEXT", "tokenCount": 10000}], - "candidatesTokensDetails": [{"modality": "TEXT", "tokenCount": 5}], - } - } - - usage = VertexGeminiConfig._calculate_usage(completion_response) - - # Verify parsing - assert ( - usage.cache_read_input_tokens == 8000 - ), f"cache_read_input_tokens should be 8000, got {usage.cache_read_input_tokens}" - assert ( - usage.prompt_tokens_details.cached_tokens == 8000 - ), f"cached_tokens should be 8000, got {usage.prompt_tokens_details.cached_tokens}" - - # CRITICAL: text_tokens should be (10000 - 8000) = 2000, NOT 10000 - # This is the fix for issue #16341 - assert ( - usage.prompt_tokens_details.text_tokens == 2000 - ), f"text_tokens should be 2000 (10000 - 8000), got {usage.prompt_tokens_details.text_tokens}" - - # Verify cost calculation uses cached token pricing - response = ModelResponse( - id="mock-id", - model="gemini-2.0-flash", - choices=[ - Choices( - index=0, - message=Message(role="assistant", content="Hello!"), - finish_reason="stop", - ) - ], - usage=usage, - ) - - cost = completion_cost( - completion_response=response, - model="gemini-2.0-flash", - custom_llm_provider="gemini", - ) - - # Get model pricing for verification - import litellm - - model_info = litellm.get_model_info("gemini/gemini-2.0-flash") - input_cost = model_info.get("input_cost_per_token", 0) - cache_read_cost = model_info.get("cache_read_input_token_cost", input_cost) - output_cost = model_info.get("output_cost_per_token", 0) - - # Expected cost: (2000 * input) + (8000 * cache_read) + (5 * output) - expected_cost = (2000 * input_cost) + (8000 * cache_read_cost) + (5 * output_cost) - - assert abs(cost - expected_cost) < 1e-9, ( - f"Cost calculation is wrong. Got ${cost:.6f}, expected ${expected_cost:.6f}. " - f"Cached tokens may not be using reduced pricing." - ) - - print("✅ Issue #16341 fix verified: Gemini implicit caching cost calculated correctly") diff --git a/tests/test_litellm/test_eager_tiktoken_load.py b/tests/test_litellm/test_eager_tiktoken_load.py index 33dd57fad8d..1264c68b99e 100644 --- a/tests/test_litellm/test_eager_tiktoken_load.py +++ b/tests/test_litellm/test_eager_tiktoken_load.py @@ -78,35 +78,6 @@ def test_lazy_loading_default(): assert len(tokens) > 0, "Encoding should work" -def test_tiktoken_cache_dir_set_on_lazy_load(): - """Test that TIKTOKEN_CACHE_DIR is set when encoding is lazy loaded. - - This ensures the local tiktoken cache is used instead of downloading - from the internet. Regression test for issue #19768. - """ - # Remove environment variables to ensure clean state - if "LITELLM_DISABLE_LAZY_LOADING" in os.environ: - del os.environ["LITELLM_DISABLE_LAZY_LOADING"] - if "TIKTOKEN_CACHE_DIR" in os.environ: - del os.environ["TIKTOKEN_CACHE_DIR"] - - # Clear any cached modules - modules_to_clear = [k for k in sys.modules.keys() if k.startswith("litellm")] - for module in modules_to_clear: - del sys.modules[module] - - # Import litellm fresh - import litellm - - # Access encoding (triggers lazy load) - _ = litellm.encoding - - # Verify TIKTOKEN_CACHE_DIR is now set and points to local tokenizers - assert "TIKTOKEN_CACHE_DIR" in os.environ, "TIKTOKEN_CACHE_DIR should be set after lazy loading encoding" - cache_dir = os.environ["TIKTOKEN_CACHE_DIR"] - assert "tokenizers" in cache_dir, f"TIKTOKEN_CACHE_DIR should point to tokenizers directory, got: {cache_dir}" - - @pytest.fixture(autouse=True) def cleanup_env(): """Clean up environment variable after each test""" diff --git a/tests/test_litellm/test_gpt_image_cost_calculator.py b/tests/test_litellm/test_gpt_image_cost_calculator.py index 620c0734980..0a2a62b6c97 100644 --- a/tests/test_litellm/test_gpt_image_cost_calculator.py +++ b/tests/test_litellm/test_gpt_image_cost_calculator.py @@ -19,13 +19,10 @@ import litellm from litellm.types.utils import ( - CompletionTokensDetailsWrapper, ImageResponse, ImageObject, ImageUsage, ImageUsageInputTokensDetails, - PromptTokensDetailsWrapper, - Usage, ) @@ -205,71 +202,6 @@ def test_openai_dalle_routes_to_pixel_calculator(self): assert cost >= 0 -class TestGPTImage15OutputImageTokens: - """ - Test for GitHub issue #19508: - Image usage calculation does not include image tokens in gpt-image-1.5 - - gpt-image-1.5 returns output_tokens_details with separate image_tokens and text_tokens, - and these must be correctly included in cost calculation. - """ - - def test_gpt_image_15_output_image_tokens_cost(self): - """ - Test that output image tokens are correctly included in cost calculation. - - This tests the fix for issue #19508 where output_tokens_details.image_tokens - were not being included in the cost calculation, causing costs to be - underreported (e.g., $0.046 instead of $0.14). - """ - # Simulate gpt-image-1.5 response with output_tokens_details - # This is what the API returns and what convert_to_image_response transforms - usage = Usage( - prompt_tokens=169, - completion_tokens=4599, - total_tokens=4768, - prompt_tokens_details=PromptTokensDetailsWrapper( - text_tokens=169, - image_tokens=0, - ), - completion_tokens_details=CompletionTokensDetailsWrapper( - text_tokens=439, - image_tokens=4160, - ), - ) - - image_response = ImageResponse( - created=1234567890, - data=[ImageObject(b64_json="test")], - ) - image_response.usage = usage - image_response._hidden_params = {"custom_llm_provider": "openai"} - - cost = litellm.completion_cost( - completion_response=image_response, - model="gpt-image-1.5", - call_type="image_generation", - custom_llm_provider="openai", - ) - - # gpt-image-1.5 pricing: - # - input_cost_per_token: 5e-06 ($5/1M for text input) - # - output_cost_per_token: 1e-05 ($10/1M for text output) - # - output_cost_per_image_token: 3.2e-05 ($32/1M for image output) - # - # Expected cost: - # Input text: 169 * $5/1M = $0.000845 - # Output text: 439 * $10/1M = $0.00439 - # Output image: 4160 * $32/1M = $0.13312 - # Total: $0.138355 - expected_cost = 169 * 5e-06 + 439 * 1e-05 + 4160 * 3.2e-05 - - assert abs(cost - expected_cost) < 1e-6, ( - f"Expected {expected_cost}, got {cost}. " - f"Image tokens may not be included in cost calculation." - ) - - class TestCompletionCostIntegration: """Test the full completion_cost integration for gpt-image-1""" diff --git a/tests/test_litellm/test_main.py b/tests/test_litellm/test_main.py index 80fd9f61298..d2416f8db8c 100644 --- a/tests/test_litellm/test_main.py +++ b/tests/test_litellm/test_main.py @@ -15,6 +15,7 @@ from unittest.mock import MagicMock, patch import litellm + from litellm import main as litellm_main @@ -472,18 +473,10 @@ async def test_extra_body_with_fallback( @pytest.mark.parametrize("env_base", ["OPENAI_BASE_URL", "OPENAI_API_BASE"]) @pytest.mark.asyncio -@pytest.mark.flaky(retries=3, delay=1) async def test_openai_env_base( respx_mock: respx.MockRouter, env_base, openai_api_response, monkeypatch ): "This tests OpenAI env variables are honored, including legacy OPENAI_API_BASE" - # Clear cache to ensure no cached clients from previous tests interfere - # This prevents cache pollution where a previous test cached a client with - # aiohttp transport, which would bypass respx mocks - if hasattr(litellm, "in_memory_llm_clients_cache"): - litellm.in_memory_llm_clients_cache.flush_cache() - - # Ensure aiohttp transport is disabled to use httpx which respx can mock litellm.disable_aiohttp_transport = True expected_base_url = "http://localhost:12345/v1" @@ -495,11 +488,7 @@ async def test_openai_env_base( model = "gpt-4o" messages = [{"role": "user", "content": "Hello, how are you?"}] - # Configure respx mock to intercept the request - mock_route = respx_mock.post( - url__regex=r"http://localhost:12345/v1/chat/completions.*" - ).mock(return_value=httpx.Response( - status_code=200, + respx_mock.post(f"{expected_base_url}/chat/completions").respond( json={ "id": "chatcmpl-123", "object": "chat.completion", @@ -517,19 +506,12 @@ async def test_openai_env_base( ], "usage": {"prompt_tokens": 9, "completion_tokens": 12, "total_tokens": 21}, } - )) + ) - try: - response = await litellm.acompletion(model=model, messages=messages) - - # verify we had a response - assert response.choices[0].message.content == "Hello from mocked response!" - - # Verify the mock was called - assert mock_route.called, "Mock route was not called - request may have bypassed respx" - finally: - # Clean up to avoid affecting other tests - litellm.disable_aiohttp_transport = False + response = await litellm.acompletion(model=model, messages=messages) + + # verify we had a response + assert response.choices[0].message.content == "Hello from mocked response!" def build_database_url(username, password, host, dbname): diff --git a/tests/test_litellm/test_responses_api_bridge_non_stream.py b/tests/test_litellm/test_responses_api_bridge_non_stream.py index c35ca1046fd..8f72debfc5d 100644 --- a/tests/test_litellm/test_responses_api_bridge_non_stream.py +++ b/tests/test_litellm/test_responses_api_bridge_non_stream.py @@ -1,32 +1,9 @@ -import os -import sys -from typing import Optional -from unittest.mock import Mock - -import pytest - -sys.path.insert(0, os.path.abspath("../..")) - from litellm.completion_extras.litellm_responses_transformation.handler import ( ResponsesToCompletionBridgeHandler, ) -from litellm.responses.litellm_completion_transformation.transformation import ( - LiteLLMCompletionResponsesConfig, -) -from litellm.types.llms.openai import ( - InputTokensDetails, - OutputTokensDetails, - ResponsesAPIResponse, -) -from litellm.types.utils import Choices, Message, ModelResponse, Usage +from litellm.types.llms.openai import ResponsesAPIResponse -""" -Test that all providers can transform completion responses to Responses API format -without breaking due to required fields in InputTokensDetails and OutputTokensDetails. -This is a regression test for the change where reasoning_tokens and cached_tokens -were made non-optional (must be int, not Optional[int]). -""" class _CompletedEvent: def __init__(self, response): self.response = response @@ -65,358 +42,3 @@ def test_should_collect_response_from_stream(): assert collected.id == "resp-1" assert collected._hidden_params.get("headers") == {"x-test": "1"} - - -def create_mock_completion_response( - model: str = "gpt-4", - prompt_tokens: int = 10, - completion_tokens: int = 20, - total_tokens: int = 30, - reasoning_tokens: Optional[int] = None, - cached_tokens: Optional[int] = None, - text_tokens: Optional[int] = None, -) -> ModelResponse: - """ - Create a mock ModelResponse (chat completion) with various token details. - - This simulates responses from different providers that may or may not include - reasoning_tokens, cached_tokens, etc. - """ - usage = Usage( - prompt_tokens=prompt_tokens, - completion_tokens=completion_tokens, - total_tokens=total_tokens, - ) - - # Add prompt_tokens_details if we have cached_tokens or text_tokens - if cached_tokens is not None or text_tokens is not None: - from litellm.types.utils import PromptTokensDetails - usage.prompt_tokens_details = PromptTokensDetails( - cached_tokens=cached_tokens, - text_tokens=text_tokens, - ) - - # Add completion_tokens_details if we have reasoning_tokens or text_tokens - if reasoning_tokens is not None or text_tokens is not None: - from litellm.types.utils import CompletionTokensDetails - usage.completion_tokens_details = CompletionTokensDetails( - reasoning_tokens=reasoning_tokens, - text_tokens=text_tokens, - ) - - return ModelResponse( - id="chatcmpl-test", - created=1234567890, - model=model, - object="chat.completion", - choices=[ - Choices( - finish_reason="stop", - index=0, - message=Message( - content="Test response", - role="assistant", - ), - ) - ], - usage=usage, - ) - - -def test_transform_usage_no_token_details(): - """ - Test that transformation works when completion response has NO token details. - - This simulates providers that don't return detailed token breakdowns. - """ - completion_response = create_mock_completion_response( - model="gpt-4", - prompt_tokens=10, - completion_tokens=20, - total_tokens=30, - ) - - # Transform to Responses API usage format - responses_usage = LiteLLMCompletionResponsesConfig._transform_chat_completion_usage_to_responses_usage( - completion_response - ) - - # Should succeed without errors - assert responses_usage.input_tokens == 10 - assert responses_usage.output_tokens == 20 - assert responses_usage.total_tokens == 30 - - # Token details should not be present when not provided - assert responses_usage.input_tokens_details is None - assert responses_usage.output_tokens_details is None - - print("✓ Transformation works with no token details") - - -def test_transform_usage_with_cached_tokens_only(): - """ - Test transformation when only cached_tokens is provided (no reasoning_tokens). - - This simulates providers like Anthropic that support prompt caching but not reasoning. - """ - completion_response = create_mock_completion_response( - model="claude-3-opus", - prompt_tokens=100, - completion_tokens=50, - total_tokens=150, - cached_tokens=80, # Has cached tokens - reasoning_tokens=None, # No reasoning tokens - ) - - responses_usage = LiteLLMCompletionResponsesConfig._transform_chat_completion_usage_to_responses_usage( - completion_response - ) - - # Should succeed and default reasoning_tokens to 0 - assert responses_usage.input_tokens == 100 - assert responses_usage.output_tokens == 50 - assert responses_usage.total_tokens == 150 - - # Input details should be present with cached_tokens - assert responses_usage.input_tokens_details is not None - assert isinstance(responses_usage.input_tokens_details, InputTokensDetails) - assert responses_usage.input_tokens_details.cached_tokens == 80 - - # Output details should not be present (no reasoning_tokens provided) - assert responses_usage.output_tokens_details is None - - print("✓ Transformation works with cached_tokens only") - - -def test_transform_usage_with_reasoning_tokens_only(): - """ - Test transformation when only reasoning_tokens is provided (no cached_tokens). - - This simulates providers like OpenAI o1 that support reasoning but not caching. - """ - completion_response = create_mock_completion_response( - model="o1-preview", - prompt_tokens=50, - completion_tokens=100, - total_tokens=150, - cached_tokens=None, # No cached tokens - reasoning_tokens=60, # Has reasoning tokens - ) - - responses_usage = LiteLLMCompletionResponsesConfig._transform_chat_completion_usage_to_responses_usage( - completion_response - ) - - # Should succeed and default cached_tokens to 0 - assert responses_usage.input_tokens == 50 - assert responses_usage.output_tokens == 100 - assert responses_usage.total_tokens == 150 - - # Input details should not be present (no cached_tokens provided) - assert responses_usage.input_tokens_details is None - - # Output details should be present with reasoning_tokens - assert responses_usage.output_tokens_details is not None - assert isinstance(responses_usage.output_tokens_details, OutputTokensDetails) - assert responses_usage.output_tokens_details.reasoning_tokens == 60 - - print("✓ Transformation works with reasoning_tokens only") - - -def test_transform_usage_with_both_token_details(): - """ - Test transformation when both cached_tokens and reasoning_tokens are provided. - - This simulates advanced providers that support both features. - """ - completion_response = create_mock_completion_response( - model="gpt-4o", - prompt_tokens=100, - completion_tokens=80, - total_tokens=180, - cached_tokens=50, - reasoning_tokens=30, - text_tokens=50, # Also include text_tokens - ) - - responses_usage = LiteLLMCompletionResponsesConfig._transform_chat_completion_usage_to_responses_usage( - completion_response - ) - - # Should succeed with all details - assert responses_usage.input_tokens == 100 - assert responses_usage.output_tokens == 80 - assert responses_usage.total_tokens == 180 - - # Input details should have cached_tokens - assert responses_usage.input_tokens_details is not None - assert responses_usage.input_tokens_details.cached_tokens == 50 - assert responses_usage.input_tokens_details.text_tokens == 50 - - # Output details should have reasoning_tokens - assert responses_usage.output_tokens_details is not None - assert responses_usage.output_tokens_details.reasoning_tokens == 30 - assert responses_usage.output_tokens_details.text_tokens == 50 - - print("✓ Transformation works with both cached_tokens and reasoning_tokens") - - -def test_transform_usage_with_zero_values(): - """ - Test transformation when token details are explicitly set to 0. - - This ensures 0 values are preserved and not treated as None. - """ - completion_response = create_mock_completion_response( - model="gpt-4", - prompt_tokens=100, - completion_tokens=50, - total_tokens=150, - cached_tokens=0, # Explicitly 0 - reasoning_tokens=0, # Explicitly 0 - ) - - responses_usage = LiteLLMCompletionResponsesConfig._transform_chat_completion_usage_to_responses_usage( - completion_response - ) - - # Should preserve 0 values - assert responses_usage.input_tokens_details is not None - assert responses_usage.input_tokens_details.cached_tokens == 0 - - assert responses_usage.output_tokens_details is not None - assert responses_usage.output_tokens_details.reasoning_tokens == 0 - - print("✓ Transformation preserves explicit 0 values") - - -def test_input_tokens_details_requires_cached_tokens(): - """ - Test that InputTokensDetails has cached_tokens as an int with default value 0. - - This ensures backward compatibility while making the field non-optional. - """ - # Should work with cached_tokens=0 - details1 = InputTokensDetails(cached_tokens=0) - assert details1.cached_tokens == 0 - - # Should work with cached_tokens=100 - details2 = InputTokensDetails(cached_tokens=100) - assert details2.cached_tokens == 100 - - # Should work without cached_tokens (defaults to 0) - details3 = InputTokensDetails() - assert details3.cached_tokens == 0 - - print("✓ InputTokensDetails correctly defaults cached_tokens to 0") - - -def test_output_tokens_details_requires_reasoning_tokens(): - """ - Test that OutputTokensDetails has reasoning_tokens as an int with default value 0. - - This ensures backward compatibility while making the field non-optional. - """ - # Should work with reasoning_tokens=0 - details1 = OutputTokensDetails(reasoning_tokens=0) - assert details1.reasoning_tokens == 0 - - # Should work with reasoning_tokens=100 - details2 = OutputTokensDetails(reasoning_tokens=100) - assert details2.reasoning_tokens == 100 - - # Should work without reasoning_tokens (defaults to 0) - details3 = OutputTokensDetails() - assert details3.reasoning_tokens == 0 - - print("✓ OutputTokensDetails correctly defaults reasoning_tokens to 0") - - -def test_all_providers_transformation_scenarios(): - """ - Test various provider scenarios to ensure none break after the field requirement change. - - This tests the most common scenarios across different providers: - - OpenAI: may have reasoning_tokens - - Anthropic: may have cached_tokens - - Azure: similar to OpenAI - - Other providers: basic usage only - """ - test_scenarios = [ - { - "name": "Basic provider (no details)", - "model": "gpt-3.5-turbo", - "kwargs": {}, - }, - { - "name": "OpenAI with reasoning", - "model": "o1-preview", - "kwargs": {"reasoning_tokens": 100}, - }, - { - "name": "Anthropic with caching", - "model": "claude-3-opus", - "kwargs": {"cached_tokens": 50}, - }, - { - "name": "OpenAI with caching", - "model": "gpt-4o", - "kwargs": {"cached_tokens": 30}, - }, - { - "name": "Full details (both)", - "model": "gpt-4o", - "kwargs": {"cached_tokens": 40, "reasoning_tokens": 60, "text_tokens": 100}, - }, - { - "name": "Zero values", - "model": "gpt-4", - "kwargs": {"cached_tokens": 0, "reasoning_tokens": 0}, - }, - ] - - for scenario in test_scenarios: - print(f"\nTesting: {scenario['name']}") - - completion_response = create_mock_completion_response( - model=scenario["model"], - **scenario["kwargs"] - ) - - # This should not raise any errors - responses_usage = LiteLLMCompletionResponsesConfig._transform_chat_completion_usage_to_responses_usage( - completion_response - ) - - # Basic assertions - assert responses_usage.input_tokens >= 0 - assert responses_usage.output_tokens >= 0 - assert responses_usage.total_tokens >= 0 - - # If input_tokens_details exists, cached_tokens must be an int - if responses_usage.input_tokens_details is not None: - assert isinstance(responses_usage.input_tokens_details.cached_tokens, int) - - # If output_tokens_details exists, reasoning_tokens must be an int - if responses_usage.output_tokens_details is not None: - assert isinstance(responses_usage.output_tokens_details.reasoning_tokens, int) - - print(f" ✓ {scenario['name']} transformation successful") - - print("\n✓ All provider scenarios work correctly") - - -if __name__ == "__main__": - # Run all tests - test_transform_usage_no_token_details() - test_transform_usage_with_cached_tokens_only() - test_transform_usage_with_reasoning_tokens_only() - test_transform_usage_with_both_token_details() - test_transform_usage_with_zero_values() - test_input_tokens_details_requires_cached_tokens() - test_output_tokens_details_requires_reasoning_tokens() - test_all_providers_transformation_scenarios() - - print("\n" + "="*60) - print("ALL TESTS PASSED!") - print("="*60) diff --git a/tests/test_litellm/test_router_per_deployment_num_retries.py b/tests/test_litellm/test_router_per_deployment_num_retries.py index 154ba579e4e..4021ca28073 100644 --- a/tests/test_litellm/test_router_per_deployment_num_retries.py +++ b/tests/test_litellm/test_router_per_deployment_num_retries.py @@ -32,17 +32,17 @@ def test_set_deployment_num_retries_on_exception(self): ) deployment = router.model_list[0] - + # Create a mock exception without num_retries class MockException(Exception): pass - + exc = MockException("test error") assert not hasattr(exc, "num_retries") or exc.num_retries is None - + # Call the helper router._set_deployment_num_retries_on_exception(exc, deployment) - + # Verify num_retries was set from deployment assert exc.num_retries == 5 @@ -66,16 +66,16 @@ def test_set_deployment_num_retries_does_not_override_existing(self): ) deployment = router.model_list[0] - + # Create an exception that already has num_retries class MockException(Exception): num_retries = 10 # Already set - + exc = MockException("test error") - + # Call the helper router._set_deployment_num_retries_on_exception(exc, deployment) - + # Verify num_retries was NOT overridden assert exc.num_retries == 10 @@ -99,15 +99,15 @@ def test_deployment_without_num_retries(self): ) deployment = router.model_list[0] - + class MockException(Exception): pass - + exc = MockException("test error") - + # Call the helper router._set_deployment_num_retries_on_exception(exc, deployment) - + # Verify num_retries was not set (deployment has no num_retries) assert not hasattr(exc, "num_retries") or exc.num_retries is None @@ -155,36 +155,3 @@ def test_global_num_retries_used_when_no_deployment_setting(self): kwargs = {} router._update_kwargs_before_fallbacks(model="test-model", kwargs=kwargs) assert kwargs["num_retries"] == 7 # Uses global - - def test_set_deployment_num_retries_with_string_value(self): - """ - Test that _set_deployment_num_retries_on_exception handles string values - from environment variables correctly. - GitHub Issue: #19481 - """ - router = Router( - model_list=[ - { - "model_name": "test-model", - "litellm_params": { - "model": "openai/gpt-4", - "api_key": "test-key", - "num_retries": "6", # String value (as from env var) - }, - }, - ], - num_retries=0, # Global setting - ) - - deployment = router.model_list[0] - - class MockException(Exception): - pass - - exc = MockException("test error") - - # Call the helper - router._set_deployment_num_retries_on_exception(exc, deployment) - - # Verify num_retries was converted from string to int - assert exc.num_retries == 6 diff --git a/tests/test_litellm/test_router_silent_experiment.py b/tests/test_litellm/test_router_silent_experiment.py deleted file mode 100644 index 9b82cde13c6..00000000000 --- a/tests/test_litellm/test_router_silent_experiment.py +++ /dev/null @@ -1,157 +0,0 @@ -import asyncio -from unittest.mock import MagicMock, patch - -import pytest - -import litellm -from litellm.router import Router - - -@pytest.mark.asyncio -async def test_router_silent_experiment_acompletion(): - """ - Test that silent_model triggers a background acompletion call - and that the silent_model parameter is stripped from both calls. - """ - model_list = [ - { - "model_name": "primary-model", - "litellm_params": { - "model": "openai/gpt-3.5-turbo", - "api_key": "fake-key", - "silent_model": "silent-model", - }, - }, - { - "model_name": "silent-model", - "litellm_params": { - "model": "openai/gpt-4", - "api_key": "fake-key", - }, - }, - ] - - router = Router(model_list=model_list) - - # Mock litellm.acompletion - mock_acompletion = MagicMock() - # Create a future that resolves to a ModelResponse - mock_response = litellm.ModelResponse(choices=[{"message": {"content": "hello"}}]) - future = asyncio.Future() - future.set_result(mock_response) - mock_acompletion.return_value = future - - with patch("litellm.acompletion", mock_acompletion): - response = await router.acompletion( - model="primary-model", - messages=[{"role": "user", "content": "hi"}], - ) - - assert response.choices[0].message.content == "hello" - - # Give the background task a moment to trigger (it's an asyncio task) - await asyncio.sleep(0.1) - - # Should have 2 calls: one for primary, one for silent - assert mock_acompletion.call_count == 2 - - # Check call arguments - call_args_list = mock_acompletion.call_args_list - - # Verify no silent_model in any call to litellm.acompletion - for call in call_args_list: - args, kwargs = call - assert "silent_model" not in kwargs - if "metadata" in kwargs: - # One call should have is_silent_experiment=True - pass - - # Find the silent call - silent_call = next( - ( - c - for c in call_args_list - if c[1].get("metadata", {}).get("is_silent_experiment") is True - ), - None, - ) - assert silent_call is not None - assert silent_call[1]["model"] == "openai/gpt-4" - - # Find the primary call - primary_call = next( - ( - c - for c in call_args_list - if not c[1].get("metadata", {}).get("is_silent_experiment") - ), - None, - ) - assert primary_call is not None - assert primary_call[1]["model"] == "openai/gpt-3.5-turbo" - - -def test_router_silent_experiment_completion(): - """ - Test that silent_model triggers a background completion call (sync) - and that the silent_model parameter is stripped. - """ - model_list = [ - { - "model_name": "primary-model", - "litellm_params": { - "model": "openai/gpt-3.5-turbo", - "api_key": "fake-key", - "silent_model": "silent-model", - }, - }, - { - "model_name": "silent-model", - "litellm_params": { - "model": "openai/gpt-4", - "api_key": "fake-key", - }, - }, - ] - - router = Router(model_list=model_list) - - # Mock litellm.completion - mock_completion = MagicMock() - mock_response = litellm.ModelResponse(choices=[{"message": {"content": "hello"}}]) - mock_completion.return_value = mock_response - - with patch("litellm.completion", mock_completion): - response = router.completion( - model="primary-model", - messages=[{"role": "user", "content": "hi"}], - ) - - assert response.choices[0].message.content == "hello" - - # The sync background call uses a thread pool. We might need to wait a bit. - import time - - time.sleep(0.5) - - # Should have 2 calls - assert mock_completion.call_count == 2 - - call_args_list = mock_completion.call_args_list - - # Verify no silent_model in any call - for call in call_args_list: - args, kwargs = call - assert "silent_model" not in kwargs - - # Find the silent call - silent_call = next( - ( - c - for c in call_args_list - if c[1].get("metadata", {}).get("is_silent_experiment") is True - ), - None, - ) - assert silent_call is not None - assert silent_call[1]["model"] == "openai/gpt-4" diff --git a/tests/test_litellm/test_video_generation.py b/tests/test_litellm/test_video_generation.py index cfc1535052c..73bfa71d20b 100644 --- a/tests/test_litellm/test_video_generation.py +++ b/tests/test_litellm/test_video_generation.py @@ -204,7 +204,7 @@ def test_video_generation_cost_calculation(self): """Test video generation cost calculation.""" import json import os - + # Try to load the local model cost map, skip if not found cost_map_path = "model_prices_and_context_window.json" if not os.path.exists(cost_map_path): @@ -294,47 +294,39 @@ def test_video_generation_uses_api_key_from_litellm_params(self): with patch.object(config, 'transform_video_create_request') as mock_transform: mock_transform.return_value = ({"model": "sora-2", "prompt": "test"}, [], "https://api.openai.com/v1/videos") - # Mock the transform_video_create_response to avoid needing a real response - with patch.object(config, 'transform_video_create_response') as mock_transform_response: - mock_video_object = MagicMock() - mock_video_object.id = "video_123" - mock_video_object.object = "video" - mock_video_object.status = "queued" - mock_transform_response.return_value = mock_video_object - - mock_response = MagicMock() - mock_response.json.return_value = { - "id": "video_123", - "object": "video", - "status": "queued", - "created_at": 1712697600, - "model": "sora-2" - } - mock_response.status_code = 200 - - mock_client = MagicMock() - mock_client.post.return_value = mock_response - - with patch( - "litellm.llms.custom_httpx.llm_http_handler._get_httpx_client", - return_value=mock_client, - ): - result = handler.video_generation_handler( - model="sora-2", - prompt="test prompt", - video_generation_provider_config=config, - video_generation_optional_request_params={}, - custom_llm_provider="openai", - litellm_params={"api_key": "deployment-api-key", "api_base": "https://api.openai.com/v1"}, - logging_obj=MagicMock(), - timeout=5.0, - api_key=None, # Function parameter is None - _is_async=False, - ) - - # Verify validate_environment was called with api_key from litellm_params - mock_validate.assert_called_once() - call_args = mock_validate.call_args + mock_response = MagicMock() + mock_response.json.return_value = { + "id": "video_123", + "object": "video", + "status": "queued", + "created_at": 1712697600, + "model": "sora-2" + } + mock_response.status_code = 200 + + mock_client = MagicMock() + mock_client.post.return_value = mock_response + + with patch( + "litellm.llms.custom_httpx.llm_http_handler._get_httpx_client", + return_value=mock_client, + ): + handler.video_generation_handler( + model="sora-2", + prompt="test prompt", + video_generation_provider_config=config, + video_generation_optional_request_params={}, + custom_llm_provider="openai", + litellm_params={"api_key": "deployment-api-key", "api_base": "https://api.openai.com/v1"}, + logging_obj=MagicMock(), + timeout=5.0, + api_key=None, # Function parameter is None + _is_async=False, + ) + + # Verify validate_environment was called with api_key from litellm_params + mock_validate.assert_called_once() + call_args = mock_validate.call_args assert call_args.kwargs["api_key"] == "deployment-api-key" def test_video_generation_url_generation(self): @@ -832,7 +824,7 @@ def test_video_content_handler_uses_get_for_openai(): def test_video_content_respects_api_base_and_api_key_from_kwargs(): """Test that video_content respects api_base and api_key from kwargs (simulating database entry).""" from litellm.videos.main import video_content - + # Mock the handler to capture litellm_params captured_litellm_params = None @@ -924,16 +916,10 @@ def client_with_vertex_config(self, monkeypatch): """Create a test client with a proxy config that includes Vertex AI model with litellm_params.""" import asyncio import tempfile - import yaml from fastapi import FastAPI from fastapi.testclient import TestClient - - from litellm.proxy.proxy_server import ( - cleanup_router_config_variables, - initialize, - router, - ) + from litellm.proxy.proxy_server import cleanup_router_config_variables, router, initialize from litellm.proxy.video_endpoints.endpoints import router as video_router # Clean up any existing router config diff --git a/tests/test_litellm/vector_stores/test_vector_store_registry.py b/tests/test_litellm/vector_stores/test_vector_store_registry.py index a3af476bc71..fb585e11220 100644 --- a/tests/test_litellm/vector_stores/test_vector_store_registry.py +++ b/tests/test_litellm/vector_stores/test_vector_store_registry.py @@ -119,12 +119,8 @@ def test_add_vector_store_to_registry(): -@respx.mock def test_search_uses_registry_credentials(): """search() should pull credentials from vector_store_registry when available""" - # Block all HTTP requests at the network level to prevent real API calls - respx.route().mock(return_value=httpx.Response(200, json={"object": "list", "data": []})) - vector_store = LiteLLM_ManagedVectorStore( vector_store_id="vs1", custom_llm_provider="bedrock", @@ -137,16 +133,6 @@ def test_search_uses_registry_credentials(): try: logger = MagicMock() logger._response_cost_calculator.return_value = 0 - - # Mock the search response - mock_search_response = { - "object": "list", - "data": [], - "first_id": None, - "last_id": None, - "has_more": False - } - with patch.object( registry, "get_credentials_for_vector_store", @@ -156,7 +142,7 @@ def test_search_uses_registry_credentials(): return_value=MagicMock(), ), patch( "litellm.vector_stores.main.base_llm_http_handler.vector_store_search_handler", - return_value=mock_search_response, + return_value={}, ) as mock_handler: search(vector_store_id="vs1", query="test", litellm_logging_obj=logger) mock_get_creds.assert_called_once_with("vs1") diff --git a/tests/test_otel_thread_leak.py b/tests/test_otel_thread_leak.py deleted file mode 100644 index 34f6b299caa..00000000000 --- a/tests/test_otel_thread_leak.py +++ /dev/null @@ -1,90 +0,0 @@ -import sys -import os -import threading -import time -import pytest - -# Add the project root to the path -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) - -from litellm.integrations.opentelemetry import OpenTelemetry, OpenTelemetryConfig -from litellm.types.utils import StandardCallbackDynamicParams - -def get_thread_count() -> int: - """Helper to get active thread count""" - return threading.active_count() - -@pytest.fixture -def otel_logger(): - """Fixture to provide a clean OTEL logger for each test""" - config = OpenTelemetryConfig( - exporter="console", - enable_metrics=False, - service_name="litellm-unit-test" - ) - return OpenTelemetry(config=config) - -def test_otel_thread_leak_dynamic_headers(otel_logger): - """ - Unit test to verify that calling get_tracer_to_use_for_request with - dynamic headers doesn't cause a linear thread leak. - - This test reproduces the issue where each unique team/key credential - set causes a new TracerProvider (and its background threads) to be - spawned but never closed. - """ - - # 1. Setup dynamic header simulation (monkey-patch) - # This simulates what LangfuseOtelLogger does for per-team keys - def mock_construct_dynamic_headers(standard_callback_dynamic_params): - if standard_callback_dynamic_params: - return {"Authorization": "Bearer fake_token"} - return None - - otel_logger.construct_dynamic_otel_headers = mock_construct_dynamic_headers - - # 2. Establish Baseline - initial_threads = get_thread_count() - - # 3. Simulate requests - num_requests = 10 - latencies = [] - - print("\n🚀 Simulating requests with dynamic headers:") - for i in range(num_requests): - kwargs = { - "standard_callback_dynamic_params": StandardCallbackDynamicParams( - langfuse_public_key=f"key_{i}", - langfuse_secret_key=f"secret_{i}", - ) - } - - # Measure latency - start_time = time.perf_counter() - tracer = otel_logger.get_tracer_to_use_for_request(kwargs) - end_time = time.perf_counter() - - latency_ms = (end_time - start_time) * 1000 - latencies.append(latency_ms) - print(f" Request {i+1:2d}: Latency = {latency_ms:6.2f} ms") - - # Verify a tracer was actually returned - assert tracer is not None - - avg_latency = sum(latencies) / len(latencies) - print(f"\n📊 Average Latency: {avg_latency:.2f} ms") - - # 4. Check for leaks - # Allow for a small constant increase (OTEL might start a few shared threads) - # but a linear leak would result in +10 or more threads here. - final_threads = get_thread_count() - thread_delta = final_threads - initial_threads - - print(f"\nThread growth: {thread_delta} threads across {num_requests} requests") - - # ASSERTION: The growth should be significantly less than 1 thread per request. - # If the bug exists, thread_delta will be >= num_requests. - assert thread_delta < (num_requests / 2), ( - f"Thread leak detected! Threads grew by {thread_delta} over {num_requests} requests. " - "Each request with dynamic headers appears to be leaking background threads." - ) diff --git a/tests/test_presidio_latency.py b/tests/test_presidio_latency.py deleted file mode 100644 index d434e6222eb..00000000000 --- a/tests/test_presidio_latency.py +++ /dev/null @@ -1,73 +0,0 @@ - -import asyncio -import aiohttp -import pytest -from unittest.mock import MagicMock, patch -from litellm.proxy.guardrails.guardrail_hooks.presidio import _OPTIONAL_PresidioPIIMasking - -@pytest.mark.asyncio -async def test_sanity_presidio_session_reuse_main_thread(): - """ - SANITY CHECK: - Verify that Presidio guardrail reuses sessions in the main thread. - This ensures we don't break existing session pooling functionality. - """ - presidio = _OPTIONAL_PresidioPIIMasking( - mock_testing=True, - presidio_analyzer_api_base="http://mock-analyzer", - presidio_anonymizer_api_base="http://mock-anonymizer" - ) - - session_creations = 0 - original_init = aiohttp.ClientSession.__init__ - - def mocked_init(self, *args, **kwargs): - nonlocal session_creations - session_creations += 1 - original_init(self, *args, **kwargs) - - with patch.object(aiohttp.ClientSession, "__init__", side_effect=mocked_init, autospec=True): - for _ in range(10): - async with presidio._get_session_iterator() as session: - pass - - # Expected: Only 1 session created for all 10 calls. - assert session_creations == 1 - - await presidio._close_http_session() - -@pytest.mark.asyncio -async def test_bug_presidio_session_explosion_background_thread_causes_latency(): - """ - BUG REPRODUCTION: - Verify that background threads (like logging hooks) REUSE sessions. - Previously, each call in a background loop created a NEW ephemeral session, - leading to socket exhaustion and the reported 97s latency spike. - """ - import threading - presidio = _OPTIONAL_PresidioPIIMasking( - mock_testing=True, - presidio_analyzer_api_base="http://mock-analyzer", - presidio_anonymizer_api_base="http://mock-anonymizer" - ) - - # Force the code to think it's in a background thread - presidio._main_thread_id = threading.get_ident() + 1 - - session_creations = 0 - original_init = aiohttp.ClientSession.__init__ - - def mocked_init(self, *args, **kwargs): - nonlocal session_creations - session_creations += 1 - original_init(self, *args, **kwargs) - - with patch.object(aiohttp.ClientSession, "__init__", side_effect=mocked_init, autospec=True): - for _ in range(10): - async with presidio._get_session_iterator() as session: - pass - - # FIX VERIFICATION: Should now be 1 session (reused) instead of 10. - assert session_creations == 1 - - await presidio._close_http_session() \ No newline at end of file diff --git a/tests/test_team.py b/tests/test_team.py index d67c5e670f4..f7752f9c89b 100644 --- a/tests/test_team.py +++ b/tests/test_team.py @@ -531,7 +531,6 @@ async def test_team_update_sc_2(): or k == "object_permission_id" or k == "object_permission" or k == "litellm_model_table" - or k == "policies" ): pass else: diff --git a/tests/vector_store_tests/rag/test_rag_s3_vectors.py b/tests/vector_store_tests/rag/test_rag_s3_vectors.py deleted file mode 100644 index cd8a362a7bf..00000000000 --- a/tests/vector_store_tests/rag/test_rag_s3_vectors.py +++ /dev/null @@ -1,107 +0,0 @@ -""" -S3 Vectors RAG ingestion tests. - -Requires environment variables: -- AWS_ACCESS_KEY_ID -- AWS_SECRET_ACCESS_KEY -- AWS_REGION_NAME (optional, defaults to us-west-2) - -Optional: -- S3_VECTOR_BUCKET_NAME (optional, auto-generates if not set) -""" - -import os -import sys -from typing import Any, Dict, Optional - -import pytest - -sys.path.insert(0, os.path.abspath("../../..")) - -import litellm -from litellm.types.rag import RAGIngestOptions -from tests.vector_store_tests.rag.base_rag_tests import BaseRAGTest - - -class TestRAGS3Vectors(BaseRAGTest): - """Test RAG Ingest with AWS S3 Vectors.""" - - @pytest.fixture(autouse=True) - def check_env_vars(self): - """Check required environment variables before each test.""" - aws_key = os.environ.get("AWS_ACCESS_KEY_ID") - aws_secret = os.environ.get("AWS_SECRET_ACCESS_KEY") - - if not aws_key or not aws_secret: - pytest.skip("Skipping S3 Vectors test: AWS credentials required") - - def get_base_ingest_options(self) -> RAGIngestOptions: - """ - Return S3 Vectors-specific ingest options. - - Chunking is configured via chunking_strategy (unified interface). - Embeddings are generated using LiteLLM's embedding API. - """ - vector_bucket_name = os.environ.get( - "S3_VECTOR_BUCKET_NAME", "test-litellm-vectors" - ) - aws_region = os.environ.get("AWS_REGION_NAME", "us-west-2") - - return { - "chunking_strategy": { - "chunk_size": 512, - "chunk_overlap": 100, - }, - "embedding": { - "model": "text-embedding-3-small" # Can use any LiteLLM-supported model - }, - "vector_store": { - "custom_llm_provider": "s3_vectors", - "vector_bucket_name": vector_bucket_name, - "index_name": "test-index", - # dimension is auto-detected from embedding model (text-embedding-3-small = 1536) - "distance_metric": "cosine", - "non_filterable_metadata_keys": ["source_text"], - "aws_region_name": aws_region, - }, - } - - async def query_vector_store( - self, - vector_store_id: str, - query: str, - ) -> Optional[Dict[str, Any]]: - """Query S3 Vectors index.""" - try: - # Import the ingestion class to use its query method - from litellm.rag.ingestion.s3_vectors_ingestion import ( - S3VectorsRAGIngestion, - ) - except ImportError: - pytest.skip("S3 Vectors ingestion not available") - - vector_bucket_name = os.environ.get( - "S3_VECTOR_BUCKET_NAME", "test-litellm-vectors" - ) - aws_region = os.environ.get("AWS_REGION_NAME", "us-west-2") - - # Create ingestion instance to use query method - ingest_options = { - "embedding": {"model": "text-embedding-3-small"}, - "vector_store": { - "custom_llm_provider": "s3_vectors", - "vector_bucket_name": vector_bucket_name, - "aws_region_name": aws_region, - }, - } - - ingestion = S3VectorsRAGIngestion(ingest_options=ingest_options) - - # Query the index - results = await ingestion.query_vector_store( - vector_store_id=vector_store_id, - query=query, - top_k=5, - ) - - return results diff --git a/tests/vector_store_tests/test_s3_vectors_vector_store.py b/tests/vector_store_tests/test_s3_vectors_vector_store.py deleted file mode 100644 index a7a1568c1cc..00000000000 --- a/tests/vector_store_tests/test_s3_vectors_vector_store.py +++ /dev/null @@ -1,42 +0,0 @@ -from base_vector_store_test import BaseVectorStoreTest -import os -import pytest - - -class TestS3VectorsVectorStore(BaseVectorStoreTest): - @pytest.fixture(autouse=True) - def check_env_vars(self): - """Check if required environment variables are set""" - required_vars = ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"] - missing_vars = [var for var in required_vars if not os.getenv(var)] - if missing_vars: - pytest.skip(f"Missing required environment variables: {', '.join(missing_vars)}") - - def get_base_request_args(self) -> dict: - """ - Must return the base request args for searching. - For S3 Vectors, vector_store_id should be in format: bucket_name:index_name - """ - return { - "custom_llm_provider": "s3_vectors", - "vector_store_id": os.getenv( - "S3_VECTORS_VECTOR_STORE_ID", "test-litellm-vectors:test-index" - ), - "query": "What is machine learning?", - "aws_region_name": os.getenv("AWS_REGION_NAME", "us-west-2"), - "aws_access_key_id": os.getenv("AWS_ACCESS_KEY_ID"), - "aws_secret_access_key": os.getenv("AWS_SECRET_ACCESS_KEY"), - } - - def get_base_create_vector_store_args(self) -> dict: - """ - Vector store creation is not yet implemented for S3 Vectors. - This test will be skipped. - """ - return {} - - @pytest.mark.parametrize("sync_mode", [True, False]) - @pytest.mark.asyncio - async def test_basic_create_vector_store(self, sync_mode): - """S3 Vectors doesn't support vector store creation via this API yet""" - pytest.skip("Vector store creation not yet implemented for S3 Vectors") diff --git a/ui/litellm-dashboard/package.json b/ui/litellm-dashboard/package.json index 16fc656dc53..385c1d82af7 100644 --- a/ui/litellm-dashboard/package.json +++ b/ui/litellm-dashboard/package.json @@ -8,7 +8,6 @@ "start": "next start", "lint": "next lint", "test": "vitest", - "test:dot": "vitest --reporter=dot", "test:watch": "vitest -w", "test:coverage": "vitest run --coverage", "format": "prettier --write .", diff --git a/ui/litellm-dashboard/public/assets/logos/s3_vector.png b/ui/litellm-dashboard/public/assets/logos/s3_vector.png deleted file mode 100644 index 15a1a456e129f9e2544d82399c6db3f2b9d8d204..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 191076 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
    ^jr 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

    3YYKR6{ z;eVZ|Xc9msvJQ0a1f4y;rYN*Z_5;#k5yNt59}4U~2)o?E#zdx9 zPC9b=LLI}SMFA4?dA#P8f6NaE>~Tu@QWvI++oir9CgMp4kI?3l&Tc?W#tuAvXxG2o z`NVw(c1}(WAD$T*oemMiJO;GrH~(E)nul4O$X+P9a_fkAVD z)hZipkv%7T(FL6-59!fX{`4|rAO;L`<9N}%Cs89xXqbMdTHEdj8JHIZz{o}u-W2m& z&OGPICmy}@;!E$o_wIVN##_x`8~?yLH50a{KMsbN9U!j5>|hlU)K;d7G`;mLYz=69 z@FSTG8xx#x2fCdkKlwrJhR-*PU73v=dAD4%Qo-r@7FR?hwV$bPA#{vP6+_^1VGJ|E zLL*-s>`D5G_ekwzlk&_{d-mLT|Ks0&a`%bxBO~Jzz9%w4R{F6Z%D<5;GYH^m<+}P_ zbo!~kzHZ|SPTknKaN$5_sl+x!HLu0%+Ibsna-uwqRp4hNNnt1sJ|KZ)syZd21zDGf!+Igp7&cJY zzz_l(3D`7?1sAD}VWLaSP|c}O4bxI*8?I4Ky+xiq>Fs3Q$KCivfH$!3Aa1V?PnRp> zhxd-`|HigwzH)5;(L?)^<`j`6Ipd_+MFz|NV=$Uvu-4yQ>M1Q)-?!|wtIvAl>1Qrk zy4q@0e#2%usZUlXCZ|~zWP1RKV}GfwsA@S$OEZ>|JQAo*z2dzoxul!rgPF{udvfa* z|m);sUsmyWd7yW+Q0uOJ2I7A|K`GLFLi;5Y+A}Tnc-hBbM7Qq(`KuMwR(j& zY#bk+*tBW=$ndfAF1+}``|hojEBvT0axmKgHICZ+Tl4NDr|U zsJKSDIc6&xTed0)dRLdLkvsMr8XKGH@9$0@B1|PpkQ8^jX!kjXpoJl>X^+jiTMCw+ z(mHV>cm4IXH(Zyz;+Lsw^{ZcAe8JVVkN{2QA;jEksMcJA8qjmHi?v-gQ(BL^Pd zKYcKLZjg!*(pl|Df!LCK* zjm?cG)1%2mBbl1yEl^3bQmxbsi|`K}B{di?<}O8DJATLHwFUqc@eyYaku`8^(B5&vr@jjM74WbTM8z=LJ8o4fRjEQSDd`OcM)FMU+K_FsaG}KJ( z1R_oul!0_iVJMtHa|bZFg{7k=izONcT4)9^>cqF`d@xsGlZAZnBVbqt%#N6RGxbL`0(z%2PURZ>>57!(7~NgA3d~vm{mI8K$+zGl7YSi5oK

    diff --git a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/ModelsAndEndpointsView.tsx b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/ModelsAndEndpointsView.tsx index 6a4882a92a2..f707ef04ffb 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/ModelsAndEndpointsView.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/ModelsAndEndpointsView.tsx @@ -318,6 +318,7 @@ const ModelsAndEndpointsView: React.FC = ({ premiumUser, te onClose={() => { setSelectedModelId(null); }} + modelData={processedModelData.data.find((model: any) => model.model_info.id === selectedModelId)} accessToken={accessToken} userID={userID} userRole={userRole} diff --git a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/AllModelsTab.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/AllModelsTab.test.tsx index 813a365d367..8a2298361c5 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/AllModelsTab.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/AllModelsTab.test.tsx @@ -11,7 +11,7 @@ const mockUseModelsInfo = vi.fn(() => ({ })) as any; vi.mock("../../hooks/models/useModels", () => ({ - useModelsInfo: (page?: number, size?: number, search?: string) => mockUseModelsInfo(page, size, search), + useModelsInfo: (page?: number, size?: number) => mockUseModelsInfo(page, size), })); // Mock the useModelCostMap hook @@ -74,6 +74,7 @@ describe("AllModelsTab", () => { const mockSetSelectedModelGroup = vi.fn(); const mockSetSelectedModelId = vi.fn(); const mockSetSelectedTeamId = vi.fn(); + const mockSetEditModel = vi.fn(); const defaultProps = { selectedModelGroup: "all", @@ -82,6 +83,7 @@ describe("AllModelsTab", () => { availableModelAccessGroups: ["sales-team", "engineering-team"], setSelectedModelId: mockSetSelectedModelId, setSelectedTeamId: mockSetSelectedTeamId, + setEditModel: mockSetEditModel, }; const mockUseAuthorized = { @@ -174,10 +176,8 @@ describe("AllModelsTab", () => { render(); - // Component shows API total_count (2), not filtered count - // Since default is "personal" team and models don't have direct_access, they're filtered out await waitFor(() => { - expect(screen.getByText("Showing 1 - 2 of 2 results")).toBeInTheDocument(); + expect(screen.getByText("Showing 0 results")).toBeInTheDocument(); }); }); @@ -235,10 +235,8 @@ describe("AllModelsTab", () => { render(); - // Component shows API total_count (2), not filtered count - // Since default is "personal" team and models don't have direct_access, they're filtered out await waitFor(() => { - expect(screen.getByText("Showing 1 - 2 of 2 results")).toBeInTheDocument(); + expect(screen.getByText("Showing 0 results")).toBeInTheDocument(); }); }); @@ -282,9 +280,8 @@ describe("AllModelsTab", () => { render(); - // Component shows API total_count (2), but only 1 model has direct_access await waitFor(() => { - expect(screen.getByText("Showing 1 - 2 of 2 results")).toBeInTheDocument(); + expect(screen.getByText("Showing 1 - 1 of 1 results")).toBeInTheDocument(); }); }); @@ -422,15 +419,14 @@ describe("AllModelsTab", () => { ); // Set up mock to return page1Data for page 1 - mockUseModelsInfo.mockImplementation((page: number = 1, size?: number, search?: string) => { + mockUseModelsInfo.mockImplementation((page: number = 1) => { return { data: page1Data, isLoading: false, error: null }; }); render(); await waitFor(() => { - // Component calculates: ((1-1)*50)+1 = 1, Math.min(1*50, 2) = 2 - expect(screen.getByText("Showing 1 - 2 of 2 results")).toBeInTheDocument(); + expect(screen.getByText("Showing 1 - 1 of 1 results")).toBeInTheDocument(); }); // Check that Previous button is disabled on first page @@ -475,7 +471,7 @@ describe("AllModelsTab", () => { 50, // size ); - mockUseModelsInfo.mockImplementation((page?: number, size?: number, search?: string) => { + mockUseModelsInfo.mockImplementation(() => { return { data: singlePageData, isLoading: false, error: null }; }); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/AllModelsTab.tsx b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/AllModelsTab.tsx index a5553fa5f56..04300b7fd16 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/AllModelsTab.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/components/AllModelsTab.tsx @@ -2,17 +2,16 @@ import { useModelCostMap } from "@/app/(dashboard)/hooks/models/useModelCostMap" import { useTeams } from "@/app/(dashboard)/hooks/teams/useTeams"; import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized"; import { Team } from "@/components/key_team_helpers/key_list"; -import { AllModelsDataTable } from "@/components/model_dashboard/all_models_table"; +import { ModelDataTable } from "@/components/model_dashboard/table"; import { columns } from "@/components/molecules/models/columns"; import { getDisplayModelName } from "@/components/view_model/model_name_display"; import { InfoCircleOutlined } from "@ant-design/icons"; -import { PaginationState, SortingState } from "@tanstack/react-table"; +import { PaginationState } from "@tanstack/react-table"; import { Grid, Select, SelectItem, TabPanel, Text } from "@tremor/react"; -import { Skeleton, Spin } from "antd"; -import debounce from "lodash/debounce"; import { useEffect, useMemo, useState } from "react"; import { useModelsInfo } from "../../hooks/models/useModels"; import { transformModelData } from "../utils/modelDataTransformer"; +import { Skeleton } from "antd"; type ModelViewMode = "all" | "current_team"; interface AllModelsTabProps { @@ -34,10 +33,9 @@ const AllModelsTab = ({ }: AllModelsTabProps) => { const { data: modelCostMapData, isLoading: isLoadingModelCostMap } = useModelCostMap(); const { userId, userRole, premiumUser } = useAuthorized(); - const { data: teams, isLoading: isLoadingTeams } = useTeams(); + const { data: teams } = useTeams(); const [modelNameSearch, setModelNameSearch] = useState(""); - const [debouncedSearch, setDebouncedSearch] = useState(""); const [modelViewMode, setModelViewMode] = useState("current_team"); const [currentTeam, setCurrentTeam] = useState("personal"); const [showFilters, setShowFilters] = useState(false); @@ -49,58 +47,8 @@ const AllModelsTab = ({ pageIndex: 0, pageSize: 50, }); - const [sorting, setSorting] = useState([]); - // Debounce search input - const debouncedUpdateSearch = useMemo( - () => - debounce((value: string) => { - setDebouncedSearch(value); - // Reset to page 1 when search changes - setCurrentPage(1); - setPagination((prev: PaginationState) => ({ ...prev, pageIndex: 0 })); - }, 200), - [] - ); - - useEffect(() => { - debouncedUpdateSearch(modelNameSearch); - return () => { - debouncedUpdateSearch.cancel(); - }; - }, [modelNameSearch, debouncedUpdateSearch]); - - // Determine teamId to pass to the query - only pass if not "personal" - const teamIdForQuery = currentTeam === "personal" ? undefined : currentTeam.team_id; - - // Convert sorting state to sortBy and sortOrder for API - const sortBy = useMemo(() => { - if (sorting.length === 0) return undefined; - const sort = sorting[0]; - const columnIdToServerField: Record = { - input_cost: "costs", // Map input_cost column to "costs" for server-side sorting - model_info_db_model: "status", // Map model_info.db_model column to "status" for server-side sorting - model_info_created_by: "created_at", // Map model_info.created_by column to "created_at" for server-side sorting - model_info_updated_at: "updated_at", // Map model_info.updated_at column to "updated_at" for server-side sorting - }; - return columnIdToServerField[sort.id] || sort.id; - }, [sorting]); - - const sortOrder = useMemo(() => { - if (sorting.length === 0) return undefined; - const sort = sorting[0]; - return sort.desc ? "desc" : "asc"; - }, [sorting]); - - const { data: rawModelData, isLoading: isLoadingModelsInfo } = useModelsInfo( - currentPage, - pageSize, - debouncedSearch || undefined, - undefined, - teamIdForQuery, - sortBy, - sortOrder - ); + const { data: rawModelData, isLoading: isLoadingModelsInfo } = useModelsInfo(currentPage, pageSize); const isLoading = isLoadingModelsInfo || isLoadingModelCostMap; const getProviderFromModel = (model: string) => { @@ -140,8 +88,10 @@ const AllModelsTab = ({ return []; } - // Server-side search is now handled by the API, so we only filter by other criteria return modelData.data.filter((model: any) => { + const searchMatch = + modelNameSearch === "" || model.model_name.toLowerCase().includes(modelNameSearch.toLowerCase()); + const modelNameMatch = selectedModelGroup === "all" || model.model_name === selectedModelGroup || @@ -153,28 +103,30 @@ const AllModelsTab = ({ model.model_info["access_groups"]?.includes(selectedModelAccessGroupFilter) || !selectedModelAccessGroupFilter; - // Team filtering is now handled server-side via teamId query parameter - // Only apply client-side filtering for model groups and access groups - return modelNameMatch && accessGroupMatch; - }); - }, [modelData, selectedModelGroup, selectedModelAccessGroupFilter]); - - useEffect(() => { - setPagination((prev: PaginationState) => ({ ...prev, pageIndex: 0 })); - setCurrentPage(1); - }, [selectedModelGroup, selectedModelAccessGroupFilter]); + let teamAccessMatch = true; + if (modelViewMode === "current_team") { + if (currentTeam === "personal") { + teamAccessMatch = model.model_info?.direct_access === true; + } else { + // Check if model is directly associated with the team via team_ids + const directTeamAccess = model.model_info?.access_via_team_ids?.includes(currentTeam.team_id) === true; + + // Check if any of the team's models match the model's access groups + const accessGroupMatch = + currentTeam.models?.some((teamModel: string) => model.model_info?.access_groups?.includes(teamModel)) === + true; + + teamAccessMatch = directTeamAccess || accessGroupMatch; + } + } - // Reset pagination when team changes - useEffect(() => { - setCurrentPage(1); - setPagination((prev: PaginationState) => ({ ...prev, pageIndex: 0 })); - }, [teamIdForQuery]); + return searchMatch && modelNameMatch && accessGroupMatch && teamAccessMatch; + }); + }, [modelData, modelNameSearch, selectedModelGroup, selectedModelAccessGroupFilter, currentTeam, modelViewMode]); - // Reset pagination when sorting changes useEffect(() => { - setCurrentPage(1); setPagination((prev: PaginationState) => ({ ...prev, pageIndex: 0 })); - }, [sorting]); + }, [modelNameSearch, selectedModelGroup, selectedModelAccessGroupFilter, currentTeam, modelViewMode]); const resetFilters = () => { setModelNameSearch(""); @@ -184,7 +136,6 @@ const AllModelsTab = ({ setModelViewMode("current_team"); setCurrentPage(1); setPagination({ pageIndex: 0, pageSize: 50 }); - setSorting([]); }; return ( @@ -207,17 +158,9 @@ const AllModelsTab = ({ onValueChange={(value) => { if (value === "personal") { setCurrentTeam("personal"); - // Reset to page 1 when team changes - setCurrentPage(1); - setPagination((prev: PaginationState) => ({ ...prev, pageIndex: 0 })); } else { const team = teams?.find((t) => t.team_id === value); - if (team) { - setCurrentTeam(team); - // Reset to page 1 when team changes - setCurrentPage(1); - setPagination((prev: PaginationState) => ({ ...prev, pageIndex: 0 })); - } + if (team) setCurrentTeam(team); } }} > @@ -227,29 +170,20 @@ const AllModelsTab = ({ Personal
    - {isLoadingTeams ? ( - -
    - - Loading teams... -
    -
    - ) : ( - teams - ?.filter((team) => team.team_id) - .map((team) => ( - -
    -
    - - {team.team_alias - ? `${team.team_alias.slice(0, 30)}...` - : `Team ${team.team_id.slice(0, 30)}...`} - -
    -
    - )) - )} + {teams + ?.filter((team) => team.team_id) + .map((team) => ( + +
    +
    + + {team.team_alias + ? `${team.team_alias.slice(0, 30)}...` + : `Team ${team.team_id.slice(0, 30)}...`} + +
    +
    + ))} )}
    @@ -420,8 +354,8 @@ const AllModelsTab = ({ ) : ( - {paginationMeta.total_count > 0 - ? `Showing ${((currentPage - 1) * pageSize) + 1} - ${Math.min(currentPage * pageSize, paginationMeta.total_count)} of ${paginationMeta.total_count} results` + {filteredData.length > 0 + ? `Showing 1 - ${filteredData.length} of ${filteredData.length} results` : "Showing 0 results"} )} @@ -469,7 +403,7 @@ const AllModelsTab = ({ - { const { accessToken, userRole } = useAuthorized(); @@ -10,6 +21,15 @@ const PoliciesPage = () => { ); }; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/teams/components/modals/CreateTeamModal.tsx b/ui/litellm-dashboard/src/app/(dashboard)/teams/components/modals/CreateTeamModal.tsx index 0aa42b69a04..972c39d49d8 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/teams/components/modals/CreateTeamModal.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/teams/components/modals/CreateTeamModal.tsx @@ -14,7 +14,7 @@ import PremiumLoggingSettings from "@/components/common_components/PremiumLoggin import ModelAliasManager from "@/components/common_components/ModelAliasManager"; import React, { useEffect, useState } from "react"; import NotificationsManager from "@/components/molecules/notifications_manager"; -import { fetchMCPAccessGroups, getGuardrailsList, getPoliciesList, Organization, Team, teamCreateCall } from "@/components/networking"; +import { fetchMCPAccessGroups, getGuardrailsList, Organization, Team, teamCreateCall } from "@/components/networking"; import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized"; import MCPToolPermissions from "@/components/mcp_server_management/MCPToolPermissions"; @@ -76,7 +76,6 @@ const CreateTeamModal = ({ const [currentOrgForCreateTeam, setCurrentOrgForCreateTeam] = useState(null); const [modelsToPick, setModelsToPick] = useState([]); const [guardrailsList, setGuardrailsList] = useState([]); - const [policiesList, setPoliciesList] = useState([]); const [mcpAccessGroups, setMcpAccessGroups] = useState([]); const [mcpAccessGroupsLoaded, setMcpAccessGroupsLoaded] = useState(false); @@ -137,22 +136,7 @@ const CreateTeamModal = ({ } }; - const fetchPolicies = async () => { - try { - if (accessToken == null) { - return; - } - - const response = await getPoliciesList(accessToken); - const policyNames = response.policies.map((p: { policy_name: string }) => p.policy_name); - setPoliciesList(policyNames); - } catch (error) { - console.error("Failed to fetch policies:", error); - } - }; - fetchGuardrails(); - fetchPolicies(); }, [accessToken]); const handleCreate = async (formValues: Record) => { @@ -547,36 +531,6 @@ const CreateTeamModal = ({ unCheckedChildren="No" /> - - Policies{" "} - - e.stopPropagation()} - > - - - - - } - name="policies" - className="mt-8" - help="Select existing policies or enter new ones" - > - ({ - value: name, - label: name, - }))} - /> - diff --git a/ui/litellm-dashboard/src/app/globals.css b/ui/litellm-dashboard/src/app/globals.css index 0d453e284ef..a702982678e 100644 --- a/ui/litellm-dashboard/src/app/globals.css +++ b/ui/litellm-dashboard/src/app/globals.css @@ -37,3 +37,31 @@ body { .custom-border { border: 1px solid var(--neutral-border); } + +/* Custom dropdown styles */ +.ant-dropdown-menu-item { + padding: 0 !important; +} + +.ant-dropdown-menu-item > div { + transition: all 0.2s ease; +} + +/* Don't apply hover to user info section */ +.ant-dropdown-menu-item[data-menu-id$="user-info"]:hover { + background-color: transparent !important; + cursor: default; +} + +.ant-dropdown-menu-item[data-menu-id$="user-info"] > div { + cursor: default; +} + +.ant-dropdown-menu { + padding: 4px !important; + min-width: 280px !important; +} + +.ant-dropdown-menu-item-divider { + margin: 4px 0; +} diff --git a/ui/litellm-dashboard/src/app/page.tsx b/ui/litellm-dashboard/src/app/page.tsx index 23c80acf973..8ac1f756f96 100644 --- a/ui/litellm-dashboard/src/app/page.tsx +++ b/ui/litellm-dashboard/src/app/page.tsx @@ -45,7 +45,6 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { jwtDecode } from "jwt-decode"; import { useSearchParams } from "next/navigation"; import { Suspense, useEffect, useState } from "react"; -import { ConfigProvider, theme } from "antd"; function getCookie(name: string) { // Safer cookie read + decoding; handles '=' inside values @@ -132,12 +131,6 @@ export default function CreateKeyPage() { const [showClaudeCodePrompt, setShowClaudeCodePrompt] = useState(false); const [showClaudeCodeModal, setShowClaudeCodeModal] = useState(false); - // Dark mode state - const [isDarkMode, setIsDarkMode] = useState(false); - const toggleDarkMode = () => { - setIsDarkMode(!isDarkMode); - }; - const invitation_id = searchParams.get("invitation_id"); // Get page from URL, default to 'api-keys' if not present @@ -289,7 +282,7 @@ export default function CreateKeyPage() { const nudgesConfig = await getInProductNudgesCall(accessToken); const isUsingClaudeCode = nudgesConfig?.is_claude_code_enabled || false; setIsClaudeCode(isUsingClaudeCode); - + // Show Claude Code prompt on login if enabled if (isUsingClaudeCode) { setShowClaudeCodePrompt(true); @@ -369,231 +362,225 @@ export default function CreateKeyPage() { return ( }> - - - {invitation_id ? ( - + {invitation_id ? ( + + ) : ( +
    + - ) : ( -
    - -
    -
    - -
    - - {page == "api-keys" ? ( - - ) : page == "models" ? ( - - ) : page == "llm-playground" ? ( - - ) : page == "users" ? ( - - ) : page == "teams" ? ( - - ) : page == "organizations" ? ( - - ) : page == "admin-panel" ? ( - - ) : page == "api_ref" ? ( - - ) : page == "logging-and-alerts" ? ( - - ) : page == "budgets" ? ( - - ) : page == "guardrails" ? ( - - ) : page == "policies" ? ( - - ) : page == "agents" ? ( - - ) : page == "prompts" ? ( - - ) : page == "transform-request" ? ( - - ) : page == "router-settings" ? ( - - ) : page == "ui-theme" ? ( - - ) : page == "cost-tracking" ? ( - - ) : page == "model-hub-table" ? ( - isAdminRole(userRole) ? ( - - ) : ( - - ) - ) : page == "caching" ? ( - - ) : page == "pass-through-settings" ? ( - +
    + +
    + + {page == "api-keys" ? ( + + ) : page == "models" ? ( + + ) : page == "llm-playground" ? ( + + ) : page == "users" ? ( + + ) : page == "teams" ? ( + + ) : page == "organizations" ? ( + + ) : page == "admin-panel" ? ( + + ) : page == "api_ref" ? ( + + ) : page == "logging-and-alerts" ? ( + + ) : page == "budgets" ? ( + + ) : page == "guardrails" ? ( + + ) : page == "policies" ? ( + + ) : page == "agents" ? ( + + ) : page == "prompts" ? ( + + ) : page == "transform-request" ? ( + + ) : page == "router-settings" ? ( + + ) : page == "ui-theme" ? ( + + ) : page == "cost-tracking" ? ( + + ) : page == "model-hub-table" ? ( + isAdminRole(userRole) ? ( + - ) : page == "logs" ? ( - - ) : page == "mcp-servers" ? ( - - ) : page == "search-tools" ? ( - - ) : page == "tag-management" ? ( - - ) : page == "claude-code-plugins" ? ( - - ) : page == "vector-stores" ? ( - - ) : page == "new_usage" ? ( - ) : ( - - )} -
    - - {/* Survey Components */} - - - - {/* Claude Code Components */} - - + + ) + ) : page == "caching" ? ( + + ) : page == "pass-through-settings" ? ( + + ) : page == "logs" ? ( + + ) : page == "mcp-servers" ? ( + + ) : page == "search-tools" ? ( + + ) : page == "tag-management" ? ( + + ) : page == "claude-code-plugins" ? ( + + ) : page == "vector-stores" ? ( + + ) : page == "new_usage" ? ( + + ) : ( + + )}
    - )} - - + + {/* Survey Components */} + + + + {/* Claude Code Components */} + + +
    + )} +
    ); diff --git a/ui/litellm-dashboard/src/components/BulkEditUsers.test.tsx b/ui/litellm-dashboard/src/components/BulkEditUsers.test.tsx deleted file mode 100644 index 4185625e746..00000000000 --- a/ui/litellm-dashboard/src/components/BulkEditUsers.test.tsx +++ /dev/null @@ -1,343 +0,0 @@ -import userEvent from "@testing-library/user-event"; -import { describe, expect, it, vi, beforeEach } from "vitest"; -import { renderWithProviders, screen, waitFor } from "../../tests/test-utils"; -import BulkEditUserModal from "./BulkEditUsers"; -import { userBulkUpdateUserCall, teamBulkMemberAddCall } from "./networking"; -import NotificationsManager from "./molecules/notifications_manager"; - -vi.mock("./networking", () => ({ - userBulkUpdateUserCall: vi.fn(), - teamBulkMemberAddCall: vi.fn(), -})); - -vi.mock("./user_edit_view", () => ({ - UserEditView: ({ onSubmit, onCancel }: { onSubmit: (values: any) => void; onCancel: () => void }) => ( -
    - - -
    - ), -})); - -const mockUserBulkUpdateUserCall = vi.mocked(userBulkUpdateUserCall); -const mockTeamBulkMemberAddCall = vi.mocked(teamBulkMemberAddCall); - -const defaultProps = { - open: true, - onCancel: vi.fn(), - selectedUsers: [ - { user_id: "user1", user_email: "user1@example.com", user_role: "user", max_budget: 50 }, - { user_id: "user2", user_email: "user2@example.com", user_role: "admin", max_budget: null }, - ], - possibleUIRoles: { - admin: { ui_label: "Admin", description: "Administrator role" }, - user: { ui_label: "User", description: "Regular user role" }, - }, - accessToken: "test-token", - onSuccess: vi.fn(), - teams: [ - { team_id: "team1", team_alias: "Team 1" }, - { team_id: "team2", team_alias: "Team 2" }, - ], - userRole: "Admin", - userModels: ["gpt-4", "gpt-3.5-turbo"], - allowAllUsers: false, -}; - -describe("BulkEditUserModal", () => { - beforeEach(() => { - vi.clearAllMocks(); - mockUserBulkUpdateUserCall.mockResolvedValue({ - results: [], - total_requested: 2, - successful_updates: 2, - failed_updates: 0, - }); - mockTeamBulkMemberAddCall.mockResolvedValue({ - successful_additions: 2, - failed_additions: 0, - }); - }); - - it("should render without crashing", () => { - renderWithProviders(); - - expect(screen.getByText(`Bulk Edit ${defaultProps.selectedUsers.length} User(s)`)).toBeInTheDocument(); - }); - - it("should display modal title with correct user count", () => { - renderWithProviders(); - - expect(screen.getByText("Bulk Edit 2 User(s)")).toBeInTheDocument(); - }); - - it("should display selected users table when modal is open", () => { - renderWithProviders(); - - expect(screen.getByText("Selected Users (2):")).toBeInTheDocument(); - expect(screen.getByText("user1")).toBeInTheDocument(); - expect(screen.getByText("user2")).toBeInTheDocument(); - expect(screen.getByText("user1@example.com")).toBeInTheDocument(); - expect(screen.getByText("user2@example.com")).toBeInTheDocument(); - }); - - it("should display user roles in table", () => { - renderWithProviders(); - - expect(screen.getByText("User")).toBeInTheDocument(); - expect(screen.getByText("Admin")).toBeInTheDocument(); - }); - - it("should display budget information in table", () => { - renderWithProviders(); - - expect(screen.getByText("$50")).toBeInTheDocument(); - expect(screen.getByText("Unlimited")).toBeInTheDocument(); - }); - - it("should call onCancel when cancel button is clicked", async () => { - const user = userEvent.setup(); - const onCancel = vi.fn(); - renderWithProviders(); - - const cancelButton = screen.getByRole("button", { name: "Cancel" }); - await user.click(cancelButton); - - expect(onCancel).toHaveBeenCalledTimes(1); - }); - - - it("should show update all users checkbox when allowAllUsers is true", () => { - renderWithProviders(); - - expect(screen.getByRole("checkbox", { name: /update all users/i })).toBeInTheDocument(); - }); - - it("should not show update all users checkbox when allowAllUsers is false", () => { - renderWithProviders(); - - expect(screen.queryByRole("checkbox", { name: /update all users/i })).not.toBeInTheDocument(); - }); - - it("should toggle update all users mode", async () => { - const user = userEvent.setup(); - renderWithProviders(); - - const checkbox = screen.getByRole("checkbox", { name: /update all users/i }); - expect(checkbox).not.toBeChecked(); - - await user.click(checkbox); - - expect(checkbox).toBeChecked(); - expect(screen.getByText("Bulk Edit All Users")).toBeInTheDocument(); - }); - - it("should show warning message when update all users is enabled", async () => { - const user = userEvent.setup(); - renderWithProviders(); - - const checkbox = screen.getByRole("checkbox", { name: /update all users/i }); - await user.click(checkbox); - - expect(screen.getByText(/this will apply changes to all users/i)).toBeInTheDocument(); - }); - - it("should hide selected users table when update all users is enabled", async () => { - const user = userEvent.setup(); - renderWithProviders(); - - expect(screen.getByText("Selected Users (2):")).toBeInTheDocument(); - - const checkbox = screen.getByRole("checkbox", { name: /update all users/i }); - await user.click(checkbox); - - expect(screen.queryByText("Selected Users (2):")).not.toBeInTheDocument(); - }); - - it("should display team management section", () => { - renderWithProviders(); - - expect(screen.getByText("Team Management")).toBeInTheDocument(); - expect(screen.getByRole("checkbox", { name: /add selected users to teams/i })).toBeInTheDocument(); - }); - - it("should show team budget input when add to teams is checked", async () => { - const user = userEvent.setup(); - renderWithProviders(); - - const addToTeamsCheckbox = screen.getByRole("checkbox", { name: /add selected users to teams/i }); - await user.click(addToTeamsCheckbox); - - expect(screen.getByText("Team Budget (Optional):")).toBeInTheDocument(); - expect(screen.getByPlaceholderText("Max budget per user in team")).toBeInTheDocument(); - }); - - it("should render UserEditView component", () => { - renderWithProviders(); - - expect(screen.getByTestId("user-edit-view")).toBeInTheDocument(); - }); - - it("should show error when access token is missing", async () => { - const user = userEvent.setup(); - renderWithProviders(); - - const submitButton = screen.getByRole("button", { name: "Submit" }); - await user.click(submitButton); - - await waitFor(() => { - expect(NotificationsManager.fromBackend).toHaveBeenCalledWith("Access token not found"); - }); - }); - - it("should call userBulkUpdateUserCall with correct payload for selected users", async () => { - const user = userEvent.setup(); - renderWithProviders(); - - const submitButton = screen.getByRole("button", { name: "Submit" }); - await user.click(submitButton); - - await waitFor(() => { - expect(mockUserBulkUpdateUserCall).toHaveBeenCalledWith( - "test-token", - { user_role: "admin", max_budget: 100 }, - ["user1", "user2"], - ); - }); - }); - - it("should call userBulkUpdateUserCall with allUsers flag when update all users is enabled", async () => { - const user = userEvent.setup(); - renderWithProviders(); - - const updateAllCheckbox = screen.getByRole("checkbox", { name: /update all users/i }); - await user.click(updateAllCheckbox); - - const submitButton = screen.getByRole("button", { name: "Submit" }); - await user.click(submitButton); - - await waitFor(() => { - expect(mockUserBulkUpdateUserCall).toHaveBeenCalledWith( - "test-token", - expect.objectContaining({ user_role: "admin", max_budget: 100 }), - undefined, - true, - ); - }); - }); - - - it("should show success message after successful user update", async () => { - const user = userEvent.setup(); - mockUserBulkUpdateUserCall.mockResolvedValue({ - results: [], - total_requested: 2, - successful_updates: 2, - failed_updates: 0, - }); - - renderWithProviders(); - - const submitButton = screen.getByRole("button", { name: "Submit" }); - await user.click(submitButton); - - await waitFor(() => { - expect(NotificationsManager.success).toHaveBeenCalledWith("Updated 2 user(s)"); - }); - }); - - it("should show success message for all users update", async () => { - const user = userEvent.setup(); - mockUserBulkUpdateUserCall.mockResolvedValue({ - results: [], - total_requested: 100, - successful_updates: 100, - failed_updates: 0, - }); - - renderWithProviders(); - - const updateAllCheckbox = screen.getByRole("checkbox", { name: /update all users/i }); - await user.click(updateAllCheckbox); - - const submitButton = screen.getByRole("button", { name: "Submit" }); - await user.click(submitButton); - - await waitFor(() => { - expect(NotificationsManager.success).toHaveBeenCalledWith("Updated all users (100 total)"); - }); - }); - - - it("should show error message when bulk update fails", async () => { - const user = userEvent.setup(); - mockUserBulkUpdateUserCall.mockRejectedValueOnce(new Error("Update failed")); - - renderWithProviders(); - - const submitButton = screen.getByRole("button", { name: "Submit" }); - await user.click(submitButton); - - await waitFor(() => { - expect(NotificationsManager.fromBackend).toHaveBeenCalledWith("Failed to perform bulk operations"); - }); - }); - - it("should call onSuccess and onCancel after successful update", async () => { - const user = userEvent.setup(); - const onSuccess = vi.fn(); - const onCancel = vi.fn(); - - renderWithProviders(); - - const submitButton = screen.getByRole("button", { name: "Submit" }); - await user.click(submitButton); - - await waitFor(() => { - expect(onSuccess).toHaveBeenCalledTimes(1); - expect(onCancel).toHaveBeenCalledTimes(1); - }); - }); - - it("should truncate long user IDs in table", () => { - const longUserId = "a".repeat(30); - const propsWithLongId = { - ...defaultProps, - selectedUsers: [{ user_id: longUserId, user_email: "test@example.com", user_role: "user", max_budget: null }], - }; - - renderWithProviders(); - - expect(screen.getByText(new RegExp(`${longUserId.slice(0, 20)}...`))).toBeInTheDocument(); - }); - - it("should display no email text when user email is missing", () => { - const propsWithoutEmail = { - ...defaultProps, - selectedUsers: [{ user_id: "user1", user_email: null, user_role: "user", max_budget: null }], - }; - - renderWithProviders(); - - expect(screen.getByText("No email")).toBeInTheDocument(); - }); - - it("should display role label from possibleUIRoles when available", () => { - renderWithProviders(); - - expect(screen.getByText("Admin")).toBeInTheDocument(); - expect(screen.getByText("User")).toBeInTheDocument(); - }); - - it("should display role key when ui_label is not available", () => { - const propsWithoutUIRoles = { - ...defaultProps, - possibleUIRoles: null, - }; - - renderWithProviders(); - - expect(screen.getByText("user")).toBeInTheDocument(); - expect(screen.getByText("admin")).toBeInTheDocument(); - }); -}); diff --git a/ui/litellm-dashboard/src/components/EntityUsageExport/ExportTypeSelector.tsx b/ui/litellm-dashboard/src/components/EntityUsageExport/ExportTypeSelector.tsx index 6bc85948608..17a833deacb 100644 --- a/ui/litellm-dashboard/src/components/EntityUsageExport/ExportTypeSelector.tsx +++ b/ui/litellm-dashboard/src/components/EntityUsageExport/ExportTypeSelector.tsx @@ -17,19 +17,11 @@ const ExportTypeSelector: React.FC = ({ value, onChange - -

    r3Jp0Uc^q-SbK3x%nZpgSinP)CI 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%0Av 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 O0000 void; @@ -12,44 +7,7 @@ interface SidebarProviderProps { } const SidebarProvider = ({ setPage, defaultSelectedKey, sidebarCollapsed }: SidebarProviderProps) => { - const { accessToken } = useAuthorized(); - const [enabledPagesInternalUsers, setEnabledPagesInternalUsers] = useState(null); - - useEffect(() => { - const fetchUISettings = async () => { - if (!accessToken) { - console.log("[SidebarProvider] No access token, skipping UI settings fetch"); - return; - } - - try { - console.log("[SidebarProvider] Fetching UI settings from /get/ui_settings"); - const settings = await getUISettings(accessToken); - console.log("[SidebarProvider] UI settings response:", settings); - - // API returns 'values' not 'settings' - if (settings?.values?.enabled_ui_pages_internal_users !== undefined) { - console.log("[SidebarProvider] Setting enabled pages:", settings.values.enabled_ui_pages_internal_users); - setEnabledPagesInternalUsers(settings.values.enabled_ui_pages_internal_users); - } else { - console.log("[SidebarProvider] No enabled_ui_pages_internal_users in response (all pages visible by default)"); - } - } catch (error) { - console.error("[SidebarProvider] Failed to fetch UI settings:", error); - } - }; - - fetchUISettings(); - }, [accessToken]); - - return ( - - ); + return ; }; export default SidebarProvider; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/hooks/models/useModels.test.ts b/ui/litellm-dashboard/src/app/(dashboard)/hooks/models/useModels.test.ts index 4985206092f..c6629e5396a 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/hooks/models/useModels.test.ts +++ b/ui/litellm-dashboard/src/app/(dashboard)/hooks/models/useModels.test.ts @@ -101,12 +101,7 @@ describe("useModelsInfo", () => { "test-user-id", "Admin", 1, - 50, - undefined, - undefined, - undefined, - undefined, - undefined + 50 ); expect(modelInfoCall).toHaveBeenCalledTimes(1); }); @@ -125,12 +120,7 @@ describe("useModelsInfo", () => { "test-user-id", "Admin", 2, - 25, - undefined, - undefined, - undefined, - undefined, - undefined + 25 ); }); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/hooks/models/useModels.ts b/ui/litellm-dashboard/src/app/(dashboard)/hooks/models/useModels.ts index c57de675e0e..1dbd79eacf9 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/hooks/models/useModels.ts +++ b/ui/litellm-dashboard/src/app/(dashboard)/hooks/models/useModels.ts @@ -27,7 +27,7 @@ const modelHubKeys = createQueryKeys("modelHub"); const allProxyModelsKeys = createQueryKeys("allProxyModels"); const selectedTeamModelsKeys = createQueryKeys("selectedTeamModels"); -export const useModelsInfo = (page: number = 1, size: number = 50, search?: string, modelId?: string, teamId?: string, sortBy?: string, sortOrder?: string) => { +export const useModelsInfo = (page: number = 1, size: number = 50) => { const { accessToken, userId, userRole } = useAuthorized(); return useQuery({ queryKey: modelKeys.list({ @@ -36,14 +36,9 @@ export const useModelsInfo = (page: number = 1, size: number = 50, search?: stri ...(userRole && { userRole }), page, size, - ...(search && { search }), - ...(modelId && { modelId }), - ...(teamId && { teamId }), - ...(sortBy && { sortBy }), - ...(sortOrder && { sortOrder }), }, }), - queryFn: async () => await modelInfoCall(accessToken!, userId!, userRole!, page, size, search, modelId, teamId, sortBy, sortOrder), + queryFn: async () => await modelInfoCall(accessToken!, userId!, userRole!, page, size), enabled: Boolean(accessToken && userId && userRole), }); }; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/hooks/storeRequestInSpendLogs/useStoreRequestInSpendLogs.ts b/ui/litellm-dashboard/src/app/(dashboard)/hooks/storeRequestInSpendLogs/useStoreRequestInSpendLogs.ts deleted file mode 100644 index 9c6211c3086..00000000000 --- a/ui/litellm-dashboard/src/app/(dashboard)/hooks/storeRequestInSpendLogs/useStoreRequestInSpendLogs.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { useMutation, UseMutationResult } from "@tanstack/react-query"; -import { getProxyBaseUrl, getGlobalLitellmHeaderName } from "@/components/networking"; -import useAuthorized from "../useAuthorized"; - -export interface StoreRequestInSpendLogsParams { - store_prompts_in_spend_logs: boolean; - maximum_spend_logs_retention_period?: string; -} - -export interface StoreRequestInSpendLogsResponse { - message: string; -} - -const performStoreRequestInSpendLogs = async ( - accessToken: string, - params: StoreRequestInSpendLogsParams -): Promise => { - const proxyBaseUrl = getProxyBaseUrl(); - const url = proxyBaseUrl ? `${proxyBaseUrl}/config/update` : `/config/update`; - - const response = await fetch(url, { - method: "POST", - headers: { - [getGlobalLitellmHeaderName()]: `Bearer ${accessToken}`, - "Content-Type": "application/json", - }, - body: JSON.stringify({ - general_settings: { - store_prompts_in_spend_logs: params.store_prompts_in_spend_logs, - ...(params.maximum_spend_logs_retention_period && { - maximum_spend_logs_retention_period: params.maximum_spend_logs_retention_period, - }), - }, - }), - }); - - if (!response.ok) { - const errorData = await response.json().catch(() => ({})); - const errorMessage = - errorData?.error?.message || errorData?.message || errorData?.detail || "Failed to update spend logs settings"; - throw new Error(errorMessage); - } - - const data = await response.json(); - return data; -}; - -export const useStoreRequestInSpendLogs = (): UseMutationResult< - StoreRequestInSpendLogsResponse, - Error, - StoreRequestInSpendLogsParams -> => { - const { accessToken } = useAuthorized(); - - return useMutation({ - mutationFn: async (params: StoreRequestInSpendLogsParams) => { - if (!accessToken) { - throw new Error("Access token is required"); - } - return await performStoreRequestInSpendLogs(accessToken, params); - }, - }); -}; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/hooks/useAuthorized.test.ts b/ui/litellm-dashboard/src/app/(dashboard)/hooks/useAuthorized.test.ts index 78eddbd8d3c..3da27d3ff9b 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/hooks/useAuthorized.test.ts +++ b/ui/litellm-dashboard/src/app/(dashboard)/hooks/useAuthorized.test.ts @@ -8,12 +8,11 @@ import useAuthorized from "./useAuthorized"; // Unmock useAuthorized to test the actual implementation vi.unmock("@/app/(dashboard)/hooks/useAuthorized"); -const { replaceMock, clearTokenCookiesMock, getProxyBaseUrlMock, getUiConfigMock, isJwtExpiredMock } = vi.hoisted(() => ({ +const { replaceMock, clearTokenCookiesMock, getProxyBaseUrlMock, getUiConfigMock } = vi.hoisted(() => ({ replaceMock: vi.fn(), clearTokenCookiesMock: vi.fn(), getProxyBaseUrlMock: vi.fn(() => "http://proxy.example"), getUiConfigMock: vi.fn(), - isJwtExpiredMock: vi.fn(), })); vi.mock("next/navigation", () => ({ @@ -39,14 +38,6 @@ vi.mock("@/utils/cookieUtils", async (importOriginal) => { }; }); -vi.mock("@/utils/jwtUtils", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - isJwtExpired: isJwtExpiredMock, - }; -}); - const createQueryClient = () => new QueryClient({ defaultOptions: { @@ -77,7 +68,6 @@ describe("useAuthorized", () => { clearTokenCookiesMock.mockReset(); getProxyBaseUrlMock.mockClear(); getUiConfigMock.mockReset(); - isJwtExpiredMock.mockReset(); clearCookie(); }); @@ -88,7 +78,6 @@ describe("useAuthorized", () => { auto_redirect_to_sso: false, admin_ui_disabled: false, }); - isJwtExpiredMock.mockReturnValue(false); const token = createJwt({ key: "api-key-123", @@ -115,7 +104,6 @@ describe("useAuthorized", () => { expect(result.current.disabledPersonalKeyCreation).toBe(false); expect(result.current.showSSOBanner).toBe(true); expect(replaceMock).not.toHaveBeenCalled(); - expect(clearTokenCookiesMock).not.toHaveBeenCalled(); }); it("should clear cookies and redirect on an invalid token", async () => { @@ -146,7 +134,6 @@ describe("useAuthorized", () => { auto_redirect_to_sso: false, admin_ui_disabled: true, }); - isJwtExpiredMock.mockReturnValue(false); const token = createJwt({ key: "api-key-123", @@ -169,50 +156,4 @@ describe("useAuthorized", () => { expect(result.current.userId).toBe("user-1"); expect(result.current.userEmail).toBe("user@example.com"); }); - - it("should redirect when token is missing", async () => { - getUiConfigMock.mockResolvedValue({ - server_root_path: "/", - proxy_base_url: null, - auto_redirect_to_sso: false, - admin_ui_disabled: false, - }); - - // No token cookie set - const { result } = renderHook(() => useAuthorized(), { wrapper }); - - await waitFor(() => { - expect(replaceMock).toHaveBeenCalledWith("http://proxy.example/ui/login"); - }); - - expect(clearTokenCookiesMock).not.toHaveBeenCalled(); - expect(result.current.token).toBeNull(); - }); - - it("should clear cookies and redirect when token is expired", async () => { - getUiConfigMock.mockResolvedValue({ - server_root_path: "/", - proxy_base_url: null, - auto_redirect_to_sso: false, - admin_ui_disabled: false, - }); - isJwtExpiredMock.mockReturnValue(true); - - const token = createJwt({ - key: "api-key-123", - user_id: "user-1", - user_email: "user@example.com", - user_role: "app_admin", - }); - document.cookie = `token=${token}; path=/;`; - - const { result } = renderHook(() => useAuthorized(), { wrapper }); - - await waitFor(() => { - expect(clearTokenCookiesMock).toHaveBeenCalled(); - }); - - expect(replaceMock).toHaveBeenCalledWith("http://proxy.example/ui/login"); - expect(isJwtExpiredMock).toHaveBeenCalledWith(token); - }); }); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/hooks/useAuthorized.ts b/ui/litellm-dashboard/src/app/(dashboard)/hooks/useAuthorized.ts index 531a240a371..62d514f0668 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/hooks/useAuthorized.ts +++ b/ui/litellm-dashboard/src/app/(dashboard)/hooks/useAuthorized.ts @@ -2,7 +2,6 @@ import { getProxyBaseUrl } from "@/components/networking"; import { clearTokenCookies, getCookie } from "@/utils/cookieUtils"; -import { isJwtExpired } from "@/utils/jwtUtils"; import { jwtDecode } from "jwt-decode"; import { useRouter } from "next/navigation"; import { useEffect, useMemo } from "react"; @@ -43,24 +42,15 @@ const useAuthorized = () => { const token = typeof document !== "undefined" ? getCookie("token") : null; - // Step 1: Check for missing token or expired JWT - kick out immediately (even if UI Config is loading) - useEffect(() => { - if (!token || (token && isJwtExpired(token))) { - if (token) { - clearTokenCookies(); - } - router.replace(`${getProxyBaseUrl()}/ui/login`); - } - }, [token, router]); - + // Redirect after mount if missing/invalid token useEffect(() => { if (isUIConfigLoading) { return; } - if (uiConfig?.admin_ui_disabled) { + if (!token || uiConfig?.admin_ui_disabled) { router.replace(`${getProxyBaseUrl()}/ui/login`); } - }, [router, isUIConfigLoading, uiConfig]); + }, [token, router, isUIConfigLoading, uiConfig]); // Decode safely const decoded = useMemo(() => { diff --git a/ui/litellm-dashboard/src/app/(dashboard)/hooks/useDisableShowPrompts.ts b/ui/litellm-dashboard/src/app/(dashboard)/hooks/useDisableShowPrompts.ts deleted file mode 100644 index 801fbdbb99d..00000000000 --- a/ui/litellm-dashboard/src/app/(dashboard)/hooks/useDisableShowPrompts.ts +++ /dev/null @@ -1,35 +0,0 @@ -// hooks/useDisableShowPrompts.ts -import { useSyncExternalStore } from "react"; -import { getLocalStorageItem } from "@/utils/localStorageUtils"; -import { LOCAL_STORAGE_EVENT } from "@/utils/localStorageUtils"; - -function subscribe(callback: () => void) { - const onStorage = (e: StorageEvent) => { - if (e.key === "disableShowPrompts") { - callback(); - } - }; - - const onCustom = (e: Event) => { - const { key } = (e as CustomEvent).detail; - if (key === "disableShowPrompts") { - callback(); - } - }; - - window.addEventListener("storage", onStorage); - window.addEventListener(LOCAL_STORAGE_EVENT, onCustom); - - return () => { - window.removeEventListener("storage", onStorage); - window.removeEventListener(LOCAL_STORAGE_EVENT, onCustom); - }; -} - -function getSnapshot() { - return getLocalStorageItem("disableShowPrompts") === "true"; -} - -export function useDisableShowPrompts() { - return useSyncExternalStore(subscribe, getSnapshot); -} diff --git a/ui/litellm-dashboard/src/app/(dashboard)/layout.tsx b/ui/litellm-dashboard/src/app/(dashboard)/layout.tsx index 97e4c799e72..97837ff8e0a 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/layout.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/layout.tsx @@ -56,10 +56,8 @@ export default function Layout({ children }: { children: React.ReactNode }) { userRole={userRole} premiumUser={premiumUser} proxySettings={undefined} - setProxySettings={() => { }} + setProxySettings={() => {}} accessToken={accessToken} - isDarkMode={false} - toggleDarkMode={() => { }} />

    r3Jp0Uc^q-SbK3x%nZpgSinP)CI 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%0Av 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 O0000LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/experimental/budgets.html b/litellm/proxy/_experimental/out/experimental/budgets.html deleted file mode 100644 index 2ab9b1c5ce3..00000000000 --- a/litellm/proxy/_experimental/out/experimental/budgets.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/experimental/budgets.txt b/litellm/proxy/_experimental/out/experimental/budgets.txt index a65bc1d2719..bc78a253901 100644 --- a/litellm/proxy/_experimental/out/experimental/budgets.txt +++ b/litellm/proxy/_experimental/out/experimental/budgets.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[78858,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","3898","static/chunks/3898-fc3dbf5a964ea4ca.js","2618","static/chunks/2618-062177b80fc4a38e.js","7906","static/chunks/7906-1b1cdd8da2773bb2.js","4891","static/chunks/4891-a6a8811399a4a3df.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5649","static/chunks/app/(dashboard)/experimental/budgets/page-9862f852f653749a.js"],"default",1] +3:I[78858,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","2409","static/chunks/2409-e94c05c6f11bb939.js","7851","static/chunks/7851-c10cbe6fcac2f9d6.js","2618","static/chunks/2618-062177b80fc4a38e.js","7906","static/chunks/7906-59ba450db59c8efa.js","2699","static/chunks/2699-38ff37315d78ae04.js","8049","static/chunks/8049-cb52b16664f13e28.js","5649","static/chunks/app/(dashboard)/experimental/budgets/page-e471b9b73cfc894b.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["experimental",{"children":["budgets",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["experimental",{"children":["budgets",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children","budgets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["experimental",{"children":["budgets",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["experimental",{"children":["budgets",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children","budgets","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/experimental/budgets/index.html b/litellm/proxy/_experimental/out/experimental/budgets/index.html new file mode 100644 index 00000000000..cc2b3b0abcb --- /dev/null +++ b/litellm/proxy/_experimental/out/experimental/budgets/index.html @@ -0,0 +1 @@ +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/experimental/caching.html b/litellm/proxy/_experimental/out/experimental/caching.html deleted file mode 100644 index 81422e08c96..00000000000 --- a/litellm/proxy/_experimental/out/experimental/caching.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/experimental/caching.txt b/litellm/proxy/_experimental/out/experimental/caching.txt index 8a91f35ab86..aeb47bfa763 100644 --- a/litellm/proxy/_experimental/out/experimental/caching.txt +++ b/litellm/proxy/_experimental/out/experimental/caching.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[37492,["1047","static/chunks/e228588e-635e9029d9d88215.js","1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2353","static/chunks/2353-c94748c0aac514ff.js","1108","static/chunks/1108-8b678b0704cb239b.js","5733","static/chunks/5733-6e7eac59c8bc246c.js","6266","static/chunks/6266-e38c5801183e9c17.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","6600","static/chunks/6600-077d81439e75d3a3.js","1979","static/chunks/app/(dashboard)/experimental/caching/page-f9ab4bd9b8938219.js"],"default",1] +3:I[37492,["1047","static/chunks/e228588e-635e9029d9d88215.js","9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","5333","static/chunks/5333-1540faf81c7d7006.js","1108","static/chunks/1108-c2d0c742b6e72436.js","5733","static/chunks/5733-aa80f52062105ad2.js","4817","static/chunks/4817-59d642defb0e86f2.js","8049","static/chunks/8049-cb52b16664f13e28.js","6600","static/chunks/6600-0ec5e2dc66d8b41a.js","1979","static/chunks/app/(dashboard)/experimental/caching/page-d31cc105402ab7e0.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["experimental",{"children":["caching",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["experimental",{"children":["caching",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children","caching","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["experimental",{"children":["caching",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["experimental",{"children":["caching",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children","caching","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/experimental/caching/index.html b/litellm/proxy/_experimental/out/experimental/caching/index.html new file mode 100644 index 00000000000..8bba9a13f65 --- /dev/null +++ b/litellm/proxy/_experimental/out/experimental/caching/index.html @@ -0,0 +1 @@ +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/experimental/claude-code-plugins.html b/litellm/proxy/_experimental/out/experimental/claude-code-plugins.html deleted file mode 100644 index b508f7d123e..00000000000 --- a/litellm/proxy/_experimental/out/experimental/claude-code-plugins.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/experimental/claude-code-plugins.txt b/litellm/proxy/_experimental/out/experimental/claude-code-plugins.txt deleted file mode 100644 index 62a0d8c0ecd..00000000000 --- a/litellm/proxy/_experimental/out/experimental/claude-code-plugins.txt +++ /dev/null @@ -1,13 +0,0 @@ -2:I[19107,[],"ClientPageRoot"] -3:I[23689,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","353","static/chunks/353-347e4836f09d94a0.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","6894","static/chunks/6894-8c74216e23aa271e.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","1112","static/chunks/1112-0b9bd4ebde18e77b.js","5696","static/chunks/app/(dashboard)/experimental/claude-code-plugins/page-dadb6b98d2bf3122.js"],"default",1] -4:I[4707,[],""] -5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] -7:{} -8:{"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"} -9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} -a:{"display":"inline-block"} -b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["experimental",{"children":["claude-code-plugins",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["experimental",{"children":["claude-code-plugins",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children","claude-code-plugins","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] -c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] -1:null diff --git a/litellm/proxy/_experimental/out/experimental/old-usage.html b/litellm/proxy/_experimental/out/experimental/old-usage.html deleted file mode 100644 index 44a491e911f..00000000000 --- a/litellm/proxy/_experimental/out/experimental/old-usage.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/experimental/old-usage.txt b/litellm/proxy/_experimental/out/experimental/old-usage.txt index 714fedd7c75..3bf8de3f17e 100644 --- a/litellm/proxy/_experimental/out/experimental/old-usage.txt +++ b/litellm/proxy/_experimental/out/experimental/old-usage.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[42954,["1047","static/chunks/e228588e-635e9029d9d88215.js","1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","353","static/chunks/353-347e4836f09d94a0.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","7971","static/chunks/7971-76912e9c9a840367.js","6894","static/chunks/6894-8c74216e23aa271e.js","3705","static/chunks/3705-dde102fd596f74e8.js","3898","static/chunks/3898-fc3dbf5a964ea4ca.js","3178","static/chunks/3178-47bc3b9e8cf9bf6c.js","5319","static/chunks/5319-7f07d87ef011d5c9.js","1716","static/chunks/1716-1c0ba935a144e6ff.js","9967","static/chunks/9967-329bb618cc1c8902.js","6609","static/chunks/6609-707213b617f85369.js","2353","static/chunks/2353-c94748c0aac514ff.js","7967","static/chunks/7967-1ac5097c3d83016f.js","1108","static/chunks/1108-8b678b0704cb239b.js","5733","static/chunks/5733-6e7eac59c8bc246c.js","5238","static/chunks/5238-3fa69435be59fb79.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5144","static/chunks/5144-ddfa7a8f89c5d465.js","7914","static/chunks/7914-25af99af34bee64b.js","1098","static/chunks/1098-a1702da59647cf14.js","665","static/chunks/665-05a55da381817c0d.js","8143","static/chunks/8143-774574f553d5fa4b.js","813","static/chunks/app/(dashboard)/experimental/old-usage/page-1599bddd1bf7a448.js"],"default",1] +3:I[42954,["1047","static/chunks/e228588e-635e9029d9d88215.js","9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","2409","static/chunks/2409-e94c05c6f11bb939.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","353","static/chunks/353-e55516ea4730f9d4.js","1994","static/chunks/1994-6637a121c9ee1602.js","7138","static/chunks/7138-5b134dc8ad670770.js","7851","static/chunks/7851-c10cbe6fcac2f9d6.js","2068","static/chunks/2068-2c78bfc32dc0de5f.js","8565","static/chunks/8565-5c05f6bbb9d0662f.js","5319","static/chunks/5319-5b2d4bf2dc450f99.js","5333","static/chunks/5333-1540faf81c7d7006.js","8582","static/chunks/8582-3a775364dbf07fa8.js","6609","static/chunks/6609-3e081758ffbe3786.js","4105","static/chunks/4105-9c3c0ee7c494102f.js","1108","static/chunks/1108-c2d0c742b6e72436.js","5733","static/chunks/5733-aa80f52062105ad2.js","2227","static/chunks/2227-5ae3f36b0a81c5b4.js","8049","static/chunks/8049-cb52b16664f13e28.js","5144","static/chunks/5144-bbc18c43eade9aef.js","2202","static/chunks/2202-a83ad035a17401aa.js","1098","static/chunks/1098-c3e95c9684ff5e95.js","665","static/chunks/665-d94073042ee5b874.js","8143","static/chunks/8143-9e4312f059e9ed27.js","813","static/chunks/app/(dashboard)/experimental/old-usage/page-5e097dbb8ce40bb4.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["experimental",{"children":["old-usage",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["experimental",{"children":["old-usage",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children","old-usage","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["experimental",{"children":["old-usage",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["experimental",{"children":["old-usage",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children","old-usage","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/experimental/tag-management.html b/litellm/proxy/_experimental/out/experimental/old-usage/index.html similarity index 59% rename from litellm/proxy/_experimental/out/experimental/tag-management.html rename to litellm/proxy/_experimental/out/experimental/old-usage/index.html index bda124cf0df..f8ab27c72f7 100644 --- a/litellm/proxy/_experimental/out/experimental/tag-management.html +++ b/litellm/proxy/_experimental/out/experimental/old-usage/index.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/experimental/prompts.txt b/litellm/proxy/_experimental/out/experimental/prompts.txt index 6a2ad986bd4..633a98ee7fc 100644 --- a/litellm/proxy/_experimental/out/experimental/prompts.txt +++ b/litellm/proxy/_experimental/out/experimental/prompts.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[51599,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","353","static/chunks/353-347e4836f09d94a0.js","6894","static/chunks/6894-8c74216e23aa271e.js","3178","static/chunks/3178-47bc3b9e8cf9bf6c.js","5319","static/chunks/5319-7f07d87ef011d5c9.js","1716","static/chunks/1716-1c0ba935a144e6ff.js","7906","static/chunks/7906-1b1cdd8da2773bb2.js","816","static/chunks/816-924f34bbf6b36a05.js","5518","static/chunks/5518-0926d5b7250ad191.js","2172","static/chunks/2172-c97c9e958a9c36e3.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","6399","static/chunks/6399-9e22a1275286c0df.js","2099","static/chunks/app/(dashboard)/experimental/prompts/page-c1b2f89fce632eb9.js"],"default",1] +3:I[51599,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","2409","static/chunks/2409-e94c05c6f11bb939.js","3367","static/chunks/3367-58830187e9e5b9fa.js","353","static/chunks/353-e55516ea4730f9d4.js","2068","static/chunks/2068-2c78bfc32dc0de5f.js","8565","static/chunks/8565-5c05f6bbb9d0662f.js","5869","static/chunks/5869-426268ba6ad0ce0c.js","5319","static/chunks/5319-5b2d4bf2dc450f99.js","8582","static/chunks/8582-3a775364dbf07fa8.js","7906","static/chunks/7906-59ba450db59c8efa.js","816","static/chunks/816-37c57b39f4e7ece1.js","605","static/chunks/605-102c0e6d8bb7517c.js","8473","static/chunks/8473-7749355a9a4b1818.js","8049","static/chunks/8049-cb52b16664f13e28.js","6399","static/chunks/6399-ccf9cdbdcd5f7abb.js","2099","static/chunks/app/(dashboard)/experimental/prompts/page-8236f1efda3366f0.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["experimental",{"children":["prompts",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["experimental",{"children":["prompts",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children","prompts","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["experimental",{"children":["prompts",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["experimental",{"children":["prompts",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children","prompts","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/experimental/prompts/index.html b/litellm/proxy/_experimental/out/experimental/prompts/index.html new file mode 100644 index 00000000000..3dcc455238e --- /dev/null +++ b/litellm/proxy/_experimental/out/experimental/prompts/index.html @@ -0,0 +1 @@ +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/experimental/tag-management.txt b/litellm/proxy/_experimental/out/experimental/tag-management.txt index 4c626a39c1c..0a255e96e0b 100644 --- a/litellm/proxy/_experimental/out/experimental/tag-management.txt +++ b/litellm/proxy/_experimental/out/experimental/tag-management.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[21933,["1047","static/chunks/e228588e-635e9029d9d88215.js","1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","353","static/chunks/353-347e4836f09d94a0.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","7971","static/chunks/7971-76912e9c9a840367.js","6894","static/chunks/6894-8c74216e23aa271e.js","3705","static/chunks/3705-dde102fd596f74e8.js","3178","static/chunks/3178-47bc3b9e8cf9bf6c.js","5319","static/chunks/5319-7f07d87ef011d5c9.js","1716","static/chunks/1716-1c0ba935a144e6ff.js","9967","static/chunks/9967-329bb618cc1c8902.js","6609","static/chunks/6609-707213b617f85369.js","2353","static/chunks/2353-c94748c0aac514ff.js","7967","static/chunks/7967-1ac5097c3d83016f.js","3634","static/chunks/3634-5083d080185955ff.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5144","static/chunks/5144-ddfa7a8f89c5d465.js","7914","static/chunks/7914-25af99af34bee64b.js","1098","static/chunks/1098-a1702da59647cf14.js","6891","static/chunks/6891-4d6d997a2bca3514.js","6061","static/chunks/app/(dashboard)/experimental/tag-management/page-38b1e2925ef4d78c.js"],"default",1] +3:I[21933,["1047","static/chunks/e228588e-635e9029d9d88215.js","9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2409","static/chunks/2409-e94c05c6f11bb939.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","353","static/chunks/353-e55516ea4730f9d4.js","1994","static/chunks/1994-6637a121c9ee1602.js","7138","static/chunks/7138-5b134dc8ad670770.js","2068","static/chunks/2068-2c78bfc32dc0de5f.js","8565","static/chunks/8565-5c05f6bbb9d0662f.js","5319","static/chunks/5319-5b2d4bf2dc450f99.js","5333","static/chunks/5333-1540faf81c7d7006.js","8582","static/chunks/8582-3a775364dbf07fa8.js","6609","static/chunks/6609-3e081758ffbe3786.js","4105","static/chunks/4105-9c3c0ee7c494102f.js","8049","static/chunks/8049-cb52b16664f13e28.js","5144","static/chunks/5144-bbc18c43eade9aef.js","2202","static/chunks/2202-a83ad035a17401aa.js","1098","static/chunks/1098-c3e95c9684ff5e95.js","9145","static/chunks/9145-9507437d5b599cea.js","6061","static/chunks/app/(dashboard)/experimental/tag-management/page-5627fd94813402eb.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["experimental",{"children":["tag-management",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["experimental",{"children":["tag-management",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children","tag-management","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["experimental",{"children":["tag-management",{"children":["__PAGE__",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["experimental",{"children":["tag-management",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children","tag-management","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","experimental","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/experimental/tag-management/index.html b/litellm/proxy/_experimental/out/experimental/tag-management/index.html new file mode 100644 index 00000000000..06bb449f538 --- /dev/null +++ b/litellm/proxy/_experimental/out/experimental/tag-management/index.html @@ -0,0 +1 @@ +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/guardrails.html b/litellm/proxy/_experimental/out/guardrails.html deleted file mode 100644 index 17ceba86e13..00000000000 --- a/litellm/proxy/_experimental/out/guardrails.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/guardrails.txt b/litellm/proxy/_experimental/out/guardrails.txt index ee833c6e34e..36d6418a1be 100644 --- a/litellm/proxy/_experimental/out/guardrails.txt +++ b/litellm/proxy/_experimental/out/guardrails.txt @@ -1,13 +1,13 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[49514,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","353","static/chunks/353-347e4836f09d94a0.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","7971","static/chunks/7971-76912e9c9a840367.js","6894","static/chunks/6894-8c74216e23aa271e.js","3705","static/chunks/3705-dde102fd596f74e8.js","3898","static/chunks/3898-fc3dbf5a964ea4ca.js","3178","static/chunks/3178-47bc3b9e8cf9bf6c.js","5319","static/chunks/5319-7f07d87ef011d5c9.js","1716","static/chunks/1716-1c0ba935a144e6ff.js","9967","static/chunks/9967-329bb618cc1c8902.js","6609","static/chunks/6609-707213b617f85369.js","5945","static/chunks/5945-93803bbcb1abfaaf.js","4851","static/chunks/4851-0dc9f6cfeabb43d0.js","4077","static/chunks/4077-c4828a2983f3aa2b.js","9682","static/chunks/9682-099cae97c99cd9b0.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","6868","static/chunks/6868-c5f994b9d687f7b6.js","6607","static/chunks/app/(dashboard)/guardrails/page-6fcfd67591571b0f.js"],"default",1] +3:I[49514,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","2409","static/chunks/2409-e94c05c6f11bb939.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","353","static/chunks/353-e55516ea4730f9d4.js","1994","static/chunks/1994-6637a121c9ee1602.js","7138","static/chunks/7138-5b134dc8ad670770.js","7851","static/chunks/7851-c10cbe6fcac2f9d6.js","2068","static/chunks/2068-2c78bfc32dc0de5f.js","8565","static/chunks/8565-5c05f6bbb9d0662f.js","5869","static/chunks/5869-426268ba6ad0ce0c.js","5319","static/chunks/5319-5b2d4bf2dc450f99.js","8582","static/chunks/8582-3a775364dbf07fa8.js","6609","static/chunks/6609-3e081758ffbe3786.js","5945","static/chunks/5945-8b3b7713d7f416a2.js","4077","static/chunks/4077-50cf2a28a79fdcd4.js","4470","static/chunks/4470-3ef8ade20eaf2875.js","8049","static/chunks/8049-cb52b16664f13e28.js","137","static/chunks/137-c6f74fedf576a11b.js","6607","static/chunks/app/(dashboard)/guardrails/page-060e61cb783d32ef.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -6:I[53104,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","3705","static/chunks/3705-dde102fd596f74e8.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","8184","static/chunks/8184-2b143f8083048e52.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5642","static/chunks/app/(dashboard)/layout-ee00b63098f63896.js"],"default",1] +6:I[53104,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","7138","static/chunks/7138-5b134dc8ad670770.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","4388","static/chunks/4388-2f4ca3419d20af67.js","8049","static/chunks/8049-cb52b16664f13e28.js","5642","static/chunks/app/(dashboard)/layout-f7f722423efd1c5b.js"],"default",1] 7:{} 8:{"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"} 9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"} a:{"display":"inline-block"} b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0} -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["(dashboard)",{"children":["guardrails",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["guardrails",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","guardrails","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["(dashboard)",{"children":["guardrails",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["(dashboard)",{"children":["guardrails",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children","guardrails","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","$L6",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","(dashboard)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}],"params":"$7"}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","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":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/index.html b/litellm/proxy/_experimental/out/index.html index a7c7370d05e..c6663a465f0 100644 --- a/litellm/proxy/_experimental/out/index.html +++ b/litellm/proxy/_experimental/out/index.html @@ -1 +1 @@ -LiteLLM Dashboard \ No newline at end of file +LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/index.txt b/litellm/proxy/_experimental/out/index.txt index 07cded8102d..870cfc1999f 100644 --- a/litellm/proxy/_experimental/out/index.txt +++ b/litellm/proxy/_experimental/out/index.txt @@ -1,7 +1,7 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[84406,["1047","static/chunks/e228588e-635e9029d9d88215.js","3665","static/chunks/3014691f-ba91873bc8fe3fad.js","6990","static/chunks/13b76428-e1bf383848c17260.js","1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-929caaa1bd1d68cc.js","2652","static/chunks/2652-55de14f9e14b1064.js","2926","static/chunks/2926-ac542d9fa707b8a4.js","2409","static/chunks/2409-43d87f56841bda3f.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","353","static/chunks/353-347e4836f09d94a0.js","3709","static/chunks/3709-7f9257c8a6221d7f.js","7971","static/chunks/7971-76912e9c9a840367.js","6894","static/chunks/6894-8c74216e23aa271e.js","3705","static/chunks/3705-dde102fd596f74e8.js","3898","static/chunks/3898-fc3dbf5a964ea4ca.js","3178","static/chunks/3178-47bc3b9e8cf9bf6c.js","5319","static/chunks/5319-7f07d87ef011d5c9.js","1716","static/chunks/1716-1c0ba935a144e6ff.js","9967","static/chunks/9967-329bb618cc1c8902.js","6609","static/chunks/6609-707213b617f85369.js","2353","static/chunks/2353-c94748c0aac514ff.js","2618","static/chunks/2618-062177b80fc4a38e.js","7906","static/chunks/7906-1b1cdd8da2773bb2.js","7967","static/chunks/7967-1ac5097c3d83016f.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","1108","static/chunks/1108-8b678b0704cb239b.js","816","static/chunks/816-924f34bbf6b36a05.js","7271","static/chunks/7271-46e4c11ee6b0a4d6.js","4077","static/chunks/4077-c4828a2983f3aa2b.js","1717","static/chunks/1717-bb1b888f6ccc52d6.js","8205","static/chunks/8205-66bf13815010afdb.js","5733","static/chunks/5733-6e7eac59c8bc246c.js","5238","static/chunks/5238-3fa69435be59fb79.js","3918","static/chunks/3918-942eadaf4103218b.js","5518","static/chunks/5518-0926d5b7250ad191.js","4750","static/chunks/4750-3aeac3fa94708e1c.js","2","static/chunks/2-253aec8d55c7bb6f.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","5144","static/chunks/5144-ddfa7a8f89c5d465.js","7914","static/chunks/7914-25af99af34bee64b.js","1098","static/chunks/1098-a1702da59647cf14.js","665","static/chunks/665-05a55da381817c0d.js","7526","static/chunks/7526-e76a2c2b549bf2d2.js","5992","static/chunks/5992-243bba762148af9b.js","6554","static/chunks/6554-265013ca56622e1f.js","9584","static/chunks/9584-4d5bef7e60cfea45.js","5706","static/chunks/5706-b92e3cca4b167e71.js","1658","static/chunks/1658-2c9554a5b3840812.js","8437","static/chunks/8437-d1298f5313ff07fa.js","5276","static/chunks/5276-8bb0b1938bb0f21f.js","292","static/chunks/292-7bd148a17bc0a05b.js","6868","static/chunks/6868-c5f994b9d687f7b6.js","1789","static/chunks/1789-a56ee544e60cd01d.js","6399","static/chunks/6399-9e22a1275286c0df.js","2318","static/chunks/2318-b8f043257a4eca15.js","6213","static/chunks/6213-20bb5f06094f361d.js","9264","static/chunks/9264-e3d8a8136b3fe80a.js","9120","static/chunks/9120-dc2d8129a3d2175b.js","6600","static/chunks/6600-077d81439e75d3a3.js","9039","static/chunks/9039-2037889778daf211.js","8143","static/chunks/8143-774574f553d5fa4b.js","5975","static/chunks/5975-60599e8984464729.js","6891","static/chunks/6891-4d6d997a2bca3514.js","1112","static/chunks/1112-0b9bd4ebde18e77b.js","1931","static/chunks/app/page-682f895ca508b763.js"],"default",1] +3:I[37028,["1047","static/chunks/e228588e-635e9029d9d88215.js","3665","static/chunks/3014691f-ba91873bc8fe3fad.js","6990","static/chunks/13b76428-e1bf383848c17260.js","9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","4865","static/chunks/4865-c1c0885a93c327fa.js","337","static/chunks/337-bb33d149e9f461b3.js","8135","static/chunks/8135-881fe2cea0032570.js","1442","static/chunks/1442-024f7e51804e0d7e.js","2926","static/chunks/2926-a9cb83e61fc8ad20.js","2409","static/chunks/2409-e94c05c6f11bb939.js","3367","static/chunks/3367-58830187e9e5b9fa.js","3709","static/chunks/3709-34dbb332d3a3ac26.js","353","static/chunks/353-e55516ea4730f9d4.js","1994","static/chunks/1994-6637a121c9ee1602.js","7138","static/chunks/7138-5b134dc8ad670770.js","7851","static/chunks/7851-c10cbe6fcac2f9d6.js","2068","static/chunks/2068-2c78bfc32dc0de5f.js","8565","static/chunks/8565-5c05f6bbb9d0662f.js","5869","static/chunks/5869-426268ba6ad0ce0c.js","5319","static/chunks/5319-5b2d4bf2dc450f99.js","5333","static/chunks/5333-1540faf81c7d7006.js","8582","static/chunks/8582-3a775364dbf07fa8.js","6609","static/chunks/6609-3e081758ffbe3786.js","2618","static/chunks/2618-062177b80fc4a38e.js","7906","static/chunks/7906-59ba450db59c8efa.js","4105","static/chunks/4105-9c3c0ee7c494102f.js","8211","static/chunks/8211-8dd5691abf54d0ca.js","1108","static/chunks/1108-c2d0c742b6e72436.js","816","static/chunks/816-37c57b39f4e7ece1.js","7271","static/chunks/7271-46e4c11ee6b0a4d6.js","4077","static/chunks/4077-50cf2a28a79fdcd4.js","766","static/chunks/766-baf0336e8ba5c686.js","3567","static/chunks/3567-9a29feedd7b63950.js","5733","static/chunks/5733-aa80f52062105ad2.js","2227","static/chunks/2227-5ae3f36b0a81c5b4.js","4306","static/chunks/4306-f891b96cf0ee333b.js","605","static/chunks/605-102c0e6d8bb7517c.js","2378","static/chunks/2378-252212b7a5e313ce.js","5752","static/chunks/5752-f504fb38ff5e13e8.js","8049","static/chunks/8049-cb52b16664f13e28.js","5144","static/chunks/5144-bbc18c43eade9aef.js","2202","static/chunks/2202-a83ad035a17401aa.js","1098","static/chunks/1098-c3e95c9684ff5e95.js","665","static/chunks/665-d94073042ee5b874.js","7526","static/chunks/7526-da6b2857a3ca248d.js","5992","static/chunks/5992-287cec06808c74ae.js","3862","static/chunks/3862-064a3fb795c75b62.js","9584","static/chunks/9584-9d4fd7b3d6a7c9e7.js","5706","static/chunks/5706-1e314cef9ea5c5d6.js","9841","static/chunks/9841-721a173be76941d1.js","1901","static/chunks/1901-4d02d1f2a71cdbf7.js","6537","static/chunks/6537-f70f2c4278e93458.js","292","static/chunks/292-aaba6c4e7c8d416d.js","137","static/chunks/137-c6f74fedf576a11b.js","6399","static/chunks/6399-ccf9cdbdcd5f7abb.js","9818","static/chunks/9818-6f03d7efd4fb8533.js","6653","static/chunks/6653-e61fdc06093fc0a8.js","9264","static/chunks/9264-fd8ab51d702e9535.js","9140","static/chunks/9140-09af618948244b82.js","6600","static/chunks/6600-0ec5e2dc66d8b41a.js","9039","static/chunks/9039-e44ff08ca4f37a12.js","8143","static/chunks/8143-9e4312f059e9ed27.js","5975","static/chunks/5975-758334d6641b9c63.js","5695","static/chunks/5695-dbbcbf2da21d2bab.js","9145","static/chunks/9145-9507437d5b599cea.js","1931","static/chunks/app/page-587b0acf34f8c747.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/0fc668a8750043fe.css","precedence":"next","crossOrigin":"$undefined"}]]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$L6",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/0fc668a8750043fe.css","precedence":"next","crossOrigin":"$undefined"}]]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$L6",null]]]] 6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/login.txt b/litellm/proxy/_experimental/out/login.txt index 7146e9e540d..6f7c11e66b4 100644 --- a/litellm/proxy/_experimental/out/login.txt +++ b/litellm/proxy/_experimental/out/login.txt @@ -1,7 +1,7 @@ 2:I[19107,[],"ClientPageRoot"] -3:I[15820,["1954","static/chunks/1954-82e3a4023f636492.js","9409","static/chunks/9409-b5ab5f84c55f5e0f.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","337","static/chunks/337-929caaa1bd1d68cc.js","2409","static/chunks/2409-43d87f56841bda3f.js","3367","static/chunks/3367-33bb84b3d3d247b2.js","5869","static/chunks/5869-aa0b3213b1b23ec5.js","2618","static/chunks/2618-062177b80fc4a38e.js","5945","static/chunks/5945-93803bbcb1abfaaf.js","1623","static/chunks/1623-54c56cbe1afc3953.js","3242","static/chunks/3242-663d3264e87271d0.js","8049","static/chunks/8049-e2c66b7a50d69b89.js","2626","static/chunks/app/login/page-a5e4539372d51712.js"],"default",1] +3:I[15820,["9028","static/chunks/9028-2bfc9f09930a0d61.js","9409","static/chunks/9409-6eefc92a7f8433ff.js","1713","static/chunks/1713-b3fdb241d0f3ae7a.js","337","static/chunks/337-bb33d149e9f461b3.js","2409","static/chunks/2409-e94c05c6f11bb939.js","3367","static/chunks/3367-58830187e9e5b9fa.js","5869","static/chunks/5869-426268ba6ad0ce0c.js","2618","static/chunks/2618-062177b80fc4a38e.js","5945","static/chunks/5945-8b3b7713d7f416a2.js","1623","static/chunks/1623-54c56cbe1afc3953.js","3242","static/chunks/3242-6e6ec7e18f5d698d.js","8049","static/chunks/8049-cb52b16664f13e28.js","2626","static/chunks/app/login/page-61bfa80619b62f6b.js"],"default",1] 4:I[4707,[],""] 5:I[36423,[],""] -0:["8YepvLrDdt6e_FwiLneCs",[[["",{"children":["login",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["login",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","login","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/9a035dba96de4cd5.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$L6",null]]]] +0:["zHD7JXLXiWgn1NPp82VmF",[[["",{"children":["login",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["login",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","login","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/349654da14372cd9.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/css/83c095d0528a2e35.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_1c856b","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",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."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$L6",null]]]] 6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","link","5",{"rel":"icon","href":"./favicon.ico"}],["$","meta","6",{"name":"next-size-adjust"}]] 1:null diff --git a/litellm/proxy/_experimental/out/login.html b/litellm/proxy/_experimental/out/login/index.html similarity index 77% rename from litellm/proxy/_experimental/out/login.html rename to litellm/proxy/_experimental/out/login/index.html index 02724682e79..f42910853e3 100644 --- a/litellm/proxy/_experimental/out/login.html +++ b/litellm/proxy/_experimental/out/login/index.html @@ -1 +1 @@ -LiteLLM Dashboard