diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 1301bfb0e60..85291b49880 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -40,6 +40,7 @@ If you're seeing a delay in your PR being merged, ping the LiteLLM Team on [Slac The proof must be completely e2e with no mocks, using, for example, actual LLM calls costing real $. `pytest` commands are not enough For bug fixes: show reproduction before the fix and passing behavior after Include the commit hash each proof was captured at, for both the before and the after runs + If the change applies to all three LLM endpoints (/v1/responses, /v1/chat/completions, /v1/messages), include proof for every single one of them, not just one For new features: show the feature working end-to-end For UI changes: include before/after screenshots --> diff --git a/.github/workflows/_test-unit-base.yml b/.github/workflows/_test-unit-base.yml index 92230fc8892..7fd66e3325e 100644 --- a/.github/workflows/_test-unit-base.yml +++ b/.github/workflows/_test-unit-base.yml @@ -80,7 +80,7 @@ jobs: - name: Install dependencies if: steps.changes.outputs.decision != 'skip' run: | - .github/scripts/uv_sync_with_retries.sh --frozen --group ci --group proxy-dev --extra google --extra proxy --extra semantic-router + .github/scripts/uv_sync_with_retries.sh --frozen --group ci --group proxy-dev --extra google --extra proxy --extra semantic-router --extra saml - name: Generate Prisma client if: steps.changes.outputs.decision != 'skip' diff --git a/.github/workflows/auto_update_price_and_context_window.yml b/.github/workflows/auto_update_price_and_context_window.yml index 1a638a4a331..d391c0bd6ce 100644 --- a/.github/workflows/auto_update_price_and_context_window.yml +++ b/.github/workflows/auto_update_price_and_context_window.yml @@ -24,9 +24,12 @@ jobs: - name: Update JSON Data run: | uv run --frozen --with 'aiohttp==3.13.3' python ".github/workflows/auto_update_price_and_context_window_file.py" + - name: Regenerate JSON Schema + run: | + uv run --frozen python ci_cd/generate_model_prices_schema.py - name: Create Pull Request run: | - git add model_prices_and_context_window.json + git add model_prices_and_context_window.json model_prices_and_context_window.schema.json git commit -m "Update model_prices_and_context_window.json file: $(date +'%Y-%m-%d')" gh pr create --title "Update model_prices_and_context_window.json file" \ --body "Automated update for model_prices_and_context_window.json" \ diff --git a/.github/workflows/mutation-test.yml b/.github/workflows/mutation-test.yml index 6684952b998..da4fe073a6a 100644 --- a/.github/workflows/mutation-test.yml +++ b/.github/workflows/mutation-test.yml @@ -55,7 +55,7 @@ jobs: - name: Install dependencies run: | - .github/scripts/uv_sync_with_retries.sh --frozen --group ci --group proxy-dev --extra google --extra proxy --extra semantic-router + .github/scripts/uv_sync_with_retries.sh --frozen --group ci --group proxy-dev --extra google --extra proxy --extra semantic-router --extra saml - name: Generate Prisma client env: diff --git a/.github/workflows/test-linting.yml b/.github/workflows/test-linting.yml index 09406d77634..8d2b2c2f972 100644 --- a/.github/workflows/test-linting.yml +++ b/.github/workflows/test-linting.yml @@ -104,6 +104,7 @@ jobs: - name: Check basedpyright budget (delta vs base) env: BASE_SHA: ${{ github.event.pull_request.base.sha }} + NODE_OPTIONS: --max-old-space-size=12288 run: | (uv run --no-sync basedpyright --outputjson || true) | uv run --no-sync python scripts/type_check_gate.py --base "$BASE_SHA" diff --git a/.github/workflows/test-litellm-ui-lint.yml b/.github/workflows/test-litellm-ui-lint.yml index 804894b1e50..5173eb6da35 100644 --- a/.github/workflows/test-litellm-ui-lint.yml +++ b/.github/workflows/test-litellm-ui-lint.yml @@ -29,7 +29,15 @@ jobs: id: changed env: BASE_SHA: ${{ github.event.pull_request.base.sha }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} run: | + # base.sha is the base branch tip from when the PR was opened, while + # actions/checkout leaves HEAD on a merge of the PR into the *current* + # base tip. "$BASE_SHA"...HEAD therefore spans every base-branch commit + # landed since, so a PR that touches no UI file still gets linted + # against hundreds of other people's files. Diff the PR head against its + # own merge base instead, which is exactly what this PR changed. + merge_base=$(git merge-base "$BASE_SHA" "$HEAD_SHA") : > "$RUNNER_TEMP/prettier_files.txt" : > "$RUNNER_TEMP/eslint_files.txt" while IFS= read -r f; do @@ -41,7 +49,7 @@ jobs: *.json | *.css | *.scss | *.md | *.mdx | *.yml | *.yaml | *.html) printf '%s\n' "$f" >> "$RUNNER_TEMP/prettier_files.txt" ;; esac - done < <(git diff --name-only --diff-filter=ACMR --relative "$BASE_SHA"...HEAD -- .) + done < <(git diff --name-only --diff-filter=ACMR --relative "$merge_base" "$HEAD_SHA" -- .) if [ -s "$RUNNER_TEMP/prettier_files.txt" ] || [ -s "$RUNNER_TEMP/eslint_files.txt" ]; then echo "has_files=true" >> "$GITHUB_OUTPUT" else diff --git a/.github/workflows/test-model-map.yaml b/.github/workflows/test-model-map.yaml index b2170d9f6a4..cf4b0eb21a1 100644 --- a/.github/workflows/test-model-map.yaml +++ b/.github/workflows/test-model-map.yaml @@ -22,3 +22,12 @@ jobs: - name: Validate model_prices_and_context_window.json run: | jq empty model_prices_and_context_window.json + + - name: Set up uv + uses: ./.github/actions/setup-uv-with-retries + with: + version: "0.10.9" + + - name: Check model_prices_and_context_window.schema.json is in sync + run: | + uv run --frozen python ci_cd/generate_model_prices_schema.py --check diff --git a/.github/workflows/test-unit-misc.yml b/.github/workflows/test-unit-misc.yml index 7c3b195f0ad..9afaaaead93 100644 --- a/.github/workflows/test-unit-misc.yml +++ b/.github/workflows/test-unit-misc.yml @@ -27,6 +27,7 @@ jobs: tests/test_litellm/a2a_protocol tests/test_litellm/anthropic_interface tests/test_litellm/completion_extras + tests/test_litellm/compression tests/test_litellm/containers tests/test_litellm/experimental_mcp_client tests/test_litellm/models diff --git a/.github/workflows/test_server_root_path.yml b/.github/workflows/test_server_root_path.yml deleted file mode 100644 index 01f70511e79..00000000000 --- a/.github/workflows/test_server_root_path.yml +++ /dev/null @@ -1,151 +0,0 @@ -name: Test Proxy SERVER_ROOT_PATH Routing -permissions: - contents: read - -on: - pull_request: - branches: - - main - - litellm_internal_staging - - litellm_oss_staging - - "litellm_**" - -jobs: - test-server-root-path: - runs-on: ubuntu-latest - timeout-minutes: 30 - - strategy: - fail-fast: false - matrix: - root_path: ["/api/v1", "/llmproxy"] - - steps: - - name: Checkout repository - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 - with: - persist-credentials: false - - - name: Free up disk space - run: | - sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc /usr/local/share/boost - sudo apt-get clean - df -h / - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - - - name: Build Docker image - uses: docker/build-push-action@0adf9959216b96bec444f325f1e493d4aa344497 # v6.14.0 - with: - context: . - file: ./docker/Dockerfile.non_root - tags: litellm-test:${{ github.sha }} - load: true - push: false - - - name: Start LiteLLM container with SERVER_ROOT_PATH - run: | - docker run -d \ - --name litellm-test \ - -p 4000:4000 \ - -e SERVER_ROOT_PATH="${{ matrix.root_path }}" \ - -e LITELLM_MASTER_KEY="sk-1234" \ - litellm-test:${{ github.sha }} \ - --detailed_debug - - - name: Wait for container to be healthy - run: | - echo "Waiting for LiteLLM to start..." - max_attempts=30 - attempt=0 - - while [ $attempt -lt $max_attempts ]; do - if docker logs litellm-test 2>&1 | grep -q "Uvicorn running"; then - echo "LiteLLM started successfully" - break - fi - attempt=$((attempt + 1)) - echo "Attempt $attempt/$max_attempts - waiting for server to start..." - sleep 2 - done - - if [ $attempt -eq $max_attempts ]; then - echo "Server failed to start within timeout" - docker logs litellm-test - exit 1 - fi - - sleep 5 - - - name: Show container logs - if: always() - run: docker logs litellm-test - - - name: Test UI endpoint with root path - run: | - ROOT_PATH="${{ matrix.root_path }}" - echo "Testing UI at: http://localhost:4000${ROOT_PATH}/ui/" - - for i in 1 2 3; do - content=$(curl -sL --max-time 5 -H "Authorization: Bearer sk-1234" "http://localhost:4000${ROOT_PATH}/ui/") - if echo "$content" | grep -q -E "(html| Optional[str]: + if key in COST_DESCRIPTIONS: + return COST_DESCRIPTIONS[key] + if key.endswith("_flex"): + return "Flex service-tier rate for the same-named base field." + if key.endswith("_priority"): + return "Priority service-tier rate for the same-named base field." + if "_above_" in key: + return "Rate applied once the prompt exceeds the token threshold in the field name." + return None + + +def cost_schema(key: str) -> JsonSchema: + description = cost_description(key) + return {**NONNEG_NUMBER, "description": description} if description else dict(NONNEG_NUMBER) + + +def string_key_schemas(modes: tuple) -> dict[str, JsonSchema]: + return { + "litellm_provider": { + "type": "string", + "description": "LiteLLM provider slug; one of https://docs.litellm.ai/docs/providers.", + }, + "mode": { + "type": "string", + "description": "Primary API surface / task type of the model.", + "enum": list(modes), + }, + "source": { + "type": "string", + "description": "URL of the provider pricing/model page this entry was taken from.", + }, + "deprecation_date": { + "type": "string", + "description": "Date the provider deprecates the model, YYYY-MM-DD.", + "format": "date", + "pattern": "^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$", + }, + "web_search_billing_unit": { + "type": "string", + "description": "Whether web search is billed per query or per prompt.", + "enum": ["per_query", "per_prompt"], + }, + "bedrock_output_config_effort_ceiling": { + "type": "string", + "description": "Highest reasoning effort the Bedrock output_config accepts for this model.", + "enum": ["low", "medium", "high", "max", "xhigh"], + }, + "comment": STRING, + "audio_transcription_config": STRING, + } + + +def classify(key: str, modes: tuple) -> Optional[JsonSchema]: + curated = {**OBJECT_KEYS, **ARRAY_KEYS, **string_key_schemas(modes), **INTEGER_KEYS, **NUMBER_KEYS} + if key in curated: + return curated[key] + if key.startswith("supports_") or key in EXTRA_BOOLEAN_KEYS: + return BOOLEAN + if "cost" in key: + return cost_schema(key) + return None + + +def build_schema(prices: dict) -> JsonSchema: + entries = {name: entry for name, entry in prices.items() if name not in SPECIAL_ROOT_KEYS} + all_keys = tuple(sorted({key for entry in entries.values() for key in entry})) + modes = tuple(sorted({entry["mode"] for entry in entries.values() if "mode" in entry})) + unclassified = tuple(key for key in all_keys if classify(key, modes) is None) + if unclassified: + raise SystemExit( + f"Unclassified keys in {PRICES_PATH.name}: {', '.join(unclassified)}. " + f"Add them to the key tables in {Path(__file__).name} and rerun it." + ) + entry_properties = {key: classify(key, modes) for key in all_keys} + return { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "LiteLLM model_prices_and_context_window.json", + "description": ( + "Schema for LiteLLM's model price and context window registry " + "(https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json). " + "Every top-level key except 'sample_spec' and 'fallback_generalizations' is a model id, " + "optionally prefixed with its provider (e.g. 'azure/gpt-5.4'), mapping to a model entry. " + "All costs are USD per unit. New optional fields are added regularly, so consumers should " + "ignore unknown fields rather than reject them." + ), + "type": "object", + "properties": { + "sample_spec": { + "type": "object", + "description": ( + "Documentation placeholder illustrating the entry shape; not a real model and not " + "schema-conformant (several values are prose)." + ), + }, + "fallback_generalizations": { + "type": "object", + "description": "Regex rules that generalize unknown model ids to known families; not a model entry.", + "properties": { + "rules": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": STRING, + "pattern": STRING, + "description": STRING, + }, + "required": ["name", "pattern"], + "additionalProperties": True, + }, + } + }, + "additionalProperties": False, + }, + }, + "additionalProperties": {"$ref": "#/$defs/modelEntry"}, + "$defs": { + "modelEntry": { + "type": "object", + "description": ( + "Pricing, limits, and capability flags for one model. Fields other than litellm_provider " + "are optional; boolean capability flags are simply omitted when unknown or false." + ), + "required": ["litellm_provider"], + "properties": entry_properties, + "additionalProperties": True, + } + }, + } + + +def render(schema: JsonSchema) -> str: + return json.dumps(schema, indent=2) + "\n" + + +def validation_errors(prices: dict, schema: JsonSchema) -> tuple: + validator = jsonschema.Draft202012Validator( + schema, format_checker=jsonschema.Draft202012Validator.FORMAT_CHECKER + ) + return tuple( + f"{'.'.join(str(part) for part in error.absolute_path)}: {error.message}" + for error in validator.iter_errors(prices) + ) + + +def main() -> int: + check = "--check" in sys.argv[1:] + prices = json.loads(PRICES_PATH.read_text()) + rendered = render(build_schema(prices)) + errors = validation_errors(prices, json.loads(rendered)) + if errors: + print(f"{PRICES_PATH.name} does not validate against the generated schema:") + print("\n".join(errors[:20])) + return 1 + if not check: + SCHEMA_PATH.write_text(rendered) + print(f"wrote {SCHEMA_PATH}") + return 0 + if not SCHEMA_PATH.exists() or SCHEMA_PATH.read_text() != rendered: + print( + f"{SCHEMA_PATH.name} is out of sync with {PRICES_PATH.name}. " + f"Run `python {Path(__file__).relative_to(REPO_ROOT)}` and commit the result." + ) + return 1 + print(f"{SCHEMA_PATH.name} is in sync and {PRICES_PATH.name} validates against it") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/cookbook/litellm_proxy_server/grafana_dashboard/dashboard_genai_otel/grafana_dashboard.json b/cookbook/litellm_proxy_server/grafana_dashboard/dashboard_genai_otel/grafana_dashboard.json new file mode 100644 index 00000000000..70608a2ffe8 --- /dev/null +++ b/cookbook/litellm_proxy_server/grafana_dashboard/dashboard_genai_otel/grafana_dashboard.json @@ -0,0 +1,523 @@ +{ + "annotations": { + "list": [] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [], + "panels": [ + { + "type": "stat", + "title": "Requests", + "gridPos": { + "h": 4, + "w": 6, + "x": 0, + "y": 0 + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "decimals": 0, + "color": { + "mode": "fixed", + "fixedColor": "blue" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "colorMode": "background", + "graphMode": "none" + }, + "targets": [ + { + "refId": "A", + "editorMode": "code", + "instant": true, + "expr": "sum(increase(gen_ai_client_operation_duration_seconds_count{service_name=~\"$service\", gen_ai_request_model=~\"$model\"}[$__range]))" + } + ], + "id": 1 + }, + { + "type": "stat", + "title": "Spend", + "description": "LiteLLM's computed cost for the selected window, from gen_ai.usage.cost", + "gridPos": { + "h": 4, + "w": 6, + "x": 6, + "y": 0 + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "unit": "currencyUSD", + "decimals": 4, + "color": { + "mode": "fixed", + "fixedColor": "green" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "colorMode": "background", + "graphMode": "none" + }, + "targets": [ + { + "refId": "A", + "editorMode": "code", + "instant": true, + "expr": "sum(increase(gen_ai_usage_cost_USD_sum{service_name=~\"$service\", gen_ai_request_model=~\"$model\"}[$__range]))" + } + ], + "id": 2 + }, + { + "type": "stat", + "title": "Tokens", + "gridPos": { + "h": 4, + "w": 6, + "x": 12, + "y": 0 + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "decimals": 0, + "color": { + "mode": "fixed", + "fixedColor": "purple" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "colorMode": "background", + "graphMode": "none" + }, + "targets": [ + { + "refId": "A", + "editorMode": "code", + "instant": true, + "expr": "sum(increase(gen_ai_client_token_usage_sum{service_name=~\"$service\", gen_ai_request_model=~\"$model\"}[$__range]))" + } + ], + "id": 3 + }, + { + "type": "stat", + "title": "p95 request duration", + "gridPos": { + "h": 4, + "w": 6, + "x": 18, + "y": 0 + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "unit": "s", + "decimals": 2, + "color": { + "mode": "fixed", + "fixedColor": "orange" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "colorMode": "background", + "graphMode": "none" + }, + "targets": [ + { + "refId": "A", + "editorMode": "code", + "instant": true, + "expr": "histogram_quantile(0.95, sum by (le) (rate(gen_ai_client_operation_duration_seconds_bucket{service_name=~\"$service\", gen_ai_request_model=~\"$model\"}[$__range])))" + } + ], + "id": 4 + }, + { + "type": "timeseries", + "title": "Request rate by model", + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 4 + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "unit": "reqpm", + "custom": { + "lineWidth": 2, + "fillOpacity": 8, + "showPoints": "never" + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "editorMode": "code", + "legendFormat": "{{gen_ai_request_model}}", + "expr": "sum by (gen_ai_request_model) (rate(gen_ai_client_operation_duration_seconds_count{service_name=~\"$service\", gen_ai_request_model=~\"$model\"}[$__rate_interval])) * 60" + } + ], + "id": 5 + }, + { + "type": "timeseries", + "title": "Spend rate by model", + "description": "USD per hour, derived from the gen_ai.usage.cost histogram", + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 4 + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "unit": "currencyUSD", + "custom": { + "lineWidth": 2, + "fillOpacity": 8, + "showPoints": "never" + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "editorMode": "code", + "legendFormat": "{{gen_ai_request_model}}", + "expr": "sum by (gen_ai_request_model) (rate(gen_ai_usage_cost_USD_sum{service_name=~\"$service\", gen_ai_request_model=~\"$model\"}[$__rate_interval])) * 3600" + } + ], + "id": 6 + }, + { + "type": "timeseries", + "title": "Tokens per minute by model and type", + "description": "gen_ai.client.token.usage split by the gen_ai.token.type attribute", + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 12 + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "custom": { + "lineWidth": 2, + "fillOpacity": 8, + "showPoints": "never" + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "editorMode": "code", + "legendFormat": "{{gen_ai_request_model}} {{gen_ai_token_type}}", + "expr": "sum by (gen_ai_request_model, gen_ai_token_type) (rate(gen_ai_client_token_usage_sum{service_name=~\"$service\", gen_ai_request_model=~\"$model\"}[$__rate_interval])) * 60" + } + ], + "id": 7 + }, + { + "type": "timeseries", + "title": "p95 request duration by model", + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 12 + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "unit": "s", + "custom": { + "lineWidth": 2, + "fillOpacity": 0, + "showPoints": "never" + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "editorMode": "code", + "legendFormat": "{{gen_ai_request_model}}", + "expr": "histogram_quantile(0.95, sum by (le, gen_ai_request_model) (rate(gen_ai_client_operation_duration_seconds_bucket{service_name=~\"$service\", gen_ai_request_model=~\"$model\"}[$__rate_interval])))" + } + ], + "id": 8 + }, + { + "type": "timeseries", + "title": "p95 time to first token (streaming)", + "description": "gen_ai.server.time_to_first_token, recorded only for streaming requests", + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 20 + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "unit": "s", + "custom": { + "lineWidth": 2, + "fillOpacity": 0, + "showPoints": "never" + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "editorMode": "code", + "legendFormat": "{{gen_ai_request_model}}", + "expr": "histogram_quantile(0.95, sum by (le, gen_ai_request_model) (rate(gen_ai_server_time_to_first_token_seconds_bucket{service_name=~\"$service\", gen_ai_request_model=~\"$model\"}[$__rate_interval])))" + } + ], + "id": 9 + }, + { + "type": "timeseries", + "title": "p95 provider generation time", + "description": "gen_ai.client.response.duration, upstream generation time excluding LiteLLM overhead", + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 20 + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "unit": "s", + "custom": { + "lineWidth": 2, + "fillOpacity": 0, + "showPoints": "never" + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "editorMode": "code", + "legendFormat": "{{gen_ai_request_model}}", + "expr": "histogram_quantile(0.95, sum by (le, gen_ai_request_model) (rate(gen_ai_client_response_duration_seconds_bucket{service_name=~\"$service\", gen_ai_request_model=~\"$model\"}[$__rate_interval])))" + } + ], + "id": 10 + } + ], + "preload": false, + "refresh": "30s", + "schemaVersion": 42, + "tags": [ + "litellm", + "genai", + "opentelemetry" + ], + "templating": { + "list": [ + { + "name": "datasource", + "label": "Prometheus", + "type": "datasource", + "query": "prometheus", + "current": {}, + "hide": 0 + }, + { + "name": "service", + "label": "Service", + "type": "query", + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "query": "label_values(gen_ai_client_operation_duration_seconds_count, service_name)", + "refresh": 2, + "includeAll": true, + "multi": true, + "current": { + "text": "All", + "value": "$__all" + } + }, + { + "name": "model", + "label": "Model", + "type": "query", + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "query": "label_values(gen_ai_client_operation_duration_seconds_count{service_name=~\"$service\"}, gen_ai_request_model)", + "refresh": 2, + "includeAll": true, + "multi": true, + "current": { + "text": "All", + "value": "$__all" + } + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "LiteLLM GenAI (OpenTelemetry)", + "uid": "litellm-genai-otel", + "weekStart": "" +} diff --git a/cookbook/litellm_proxy_server/grafana_dashboard/dashboard_genai_otel/readme.md b/cookbook/litellm_proxy_server/grafana_dashboard/dashboard_genai_otel/readme.md new file mode 100644 index 00000000000..c51f0166462 --- /dev/null +++ b/cookbook/litellm_proxy_server/grafana_dashboard/dashboard_genai_otel/readme.md @@ -0,0 +1,35 @@ +# LiteLLM GenAI dashboard (OpenTelemetry metrics) + +Dashboard for the `gen_ai.*` metrics the OpenTelemetry v2 integration emits, as opposed to the `litellm_*` Prometheus metrics the other dashboards in this folder chart. + +Import `grafana_dashboard.json` from **Dashboards > New > Import** and pick your Prometheus data source. Panels: request count, spend, token count, p95 duration, request rate by model, spend rate per hour by model, tokens per minute split by input and output, p95 duration by model, p95 time to first token, and p95 provider generation time. Template variables for data source, service, and model. + +## Pre-requisites + +Metrics are off by default. In the proxy environment: + +```shell +LITELLM_OTEL_V2=true +LITELLM_OTEL_INTEGRATION_ENABLE_METRICS=true +OTEL_EXPORTER="otlp_http" +OTEL_ENDPOINT="" +``` + +You also need the metric attribute filter, or the panels will plot flat lines at zero. LiteLLM's default attribute set includes per-request fields, so nearly every request lands in its own time series with a single sample, and `rate()` has nothing to compute over: + +```yaml title="config.yaml" +callback_settings: + otel: + attributes: + include_list: + - gen_ai.operation.name + - gen_ai.system + - gen_ai.request.model + - gen_ai.framework +``` + +See [Grafana Cloud](https://docs.litellm.ai/docs/observability/grafana_cloud) for the full setup, and [OpenTelemetry v2](https://docs.litellm.ai/docs/observability/opentelemetry_v2#metrics) for the metric reference. + +## Note on Grafana's AI Observability integration + +Grafana Cloud ships prebuilt GenAI dashboards that query these same metric names, so they look like a drop-in alternative to this one. They are not: twenty of their twenty-two panels filter on `telemetry_sdk_name="openlit"`, a label LiteLLM does not carry and cannot be configured to add, so those panels stay empty. diff --git a/cookbook/litellm_proxy_server/grafana_dashboard/readme.md b/cookbook/litellm_proxy_server/grafana_dashboard/readme.md index 81235c308f2..a1564a406e0 100644 --- a/cookbook/litellm_proxy_server/grafana_dashboard/readme.md +++ b/cookbook/litellm_proxy_server/grafana_dashboard/readme.md @@ -2,6 +2,10 @@ This folder contains the `json` for creating Grafana Dashboards +## [LiteLLM GenAI Dashboard (OpenTelemetry)](./dashboard_genai_otel) + +Charts the `gen_ai.*` metrics from the OpenTelemetry v2 integration: spend, tokens, request rate, and latency percentiles by model. Separate from the dashboards below, which chart the `litellm_*` Prometheus metrics. + ## [LiteLLM v2 Dashboard](./dashboard_v2) grafana_1 diff --git a/db_scripts/backfill_daily_tool_spend.sql b/db_scripts/backfill_daily_tool_spend.sql new file mode 100644 index 00000000000..309b9dbe0ff --- /dev/null +++ b/db_scripts/backfill_daily_tool_spend.sql @@ -0,0 +1,46 @@ +-- One-shot backfill of the LiteLLM_DailyToolSpend rollup from the per-request +-- LiteLLM_SpendLogToolIndex x LiteLLM_SpendLogs tables. +-- +-- This is an opt-in, manual operation. New deployments do not need it: the +-- rollup is written at request time from the moment the release is deployed. +-- Run it only if you want the Cost Optimization "Spend by tool" card to show +-- history from before the deploy, and only once. +-- +-- IMPORTANT caveats before running: +-- +-- 1. Pre-deploy index rows may include tools that were merely DECLARED in a +-- request body but never invoked (the release this ships with stops +-- recording those). For agentic clients that declare many tools per +-- request, backfilled history attributes each request's full spend to +-- every declared tool, overstating per-tool spend. Post-deploy rows do not +-- have this problem. If your traffic is mostly such clients, consider not +-- backfilling. +-- +-- 2. Coverage is bounded by spend-log retention: rows older than +-- maximum_spend_logs_retention_period are already gone. +-- +-- 3. Replace the cutover timestamp below with the time you deployed the +-- release, so backfilled per-request rows cannot double-count on top of +-- rollup rows the new writer already created. ON CONFLICT DO NOTHING is a +-- second guard for (date, tool_name) buckets the writer already touched: +-- such buckets keep the writer's numbers and skip the backfill's. +-- +-- Usage: +-- psql "$DATABASE_URL" -v cutover="'2026-07-25T00:00:00Z'" -f db_scripts/backfill_daily_tool_spend.sql + +SET TIME ZONE 'UTC'; + +INSERT INTO "LiteLLM_DailyToolSpend" (date, tool_name, spend, total_tokens, request_count, created_at, updated_at) +SELECT + to_char(ti.start_time, 'YYYY-MM-DD') AS date, + ti.tool_name, + COALESCE(SUM(sl.spend), 0) AS spend, + COALESCE(SUM(sl.total_tokens), 0) AS total_tokens, + COUNT(*) AS request_count, + now() AS created_at, + now() AS updated_at +FROM "LiteLLM_SpendLogToolIndex" ti +JOIN "LiteLLM_SpendLogs" sl ON sl.request_id = ti.request_id +WHERE ti.start_time < :cutover::timestamptz +GROUP BY 1, 2 +ON CONFLICT (date, tool_name) DO NOTHING; diff --git a/docker/Dockerfile.database b/docker/Dockerfile.database index 34c9c606991..9ee076ce825 100644 --- a/docker/Dockerfile.database +++ b/docker/Dockerfile.database @@ -62,6 +62,7 @@ RUN uv sync --frozen --no-install-project --no-install-workspace --no-default-gr --extra proxy-runtime \ --extra extra_proxy \ --extra semantic-router \ + --extra saml \ --python python3 # Copy full source tree @@ -82,6 +83,7 @@ RUN uv sync --frozen --no-default-groups --no-editable \ --extra proxy-runtime \ --extra extra_proxy \ --extra semantic-router \ + --extra saml \ --python python3 RUN HOME=/opt/prisma XDG_CACHE_HOME=/opt/prisma/.cache PRISMA_BINARY_CACHE_DIR=/opt/prisma/binaries \ diff --git a/docker/Dockerfile.non_root b/docker/Dockerfile.non_root index 8e05f312ba0..946b4de6f5e 100644 --- a/docker/Dockerfile.non_root +++ b/docker/Dockerfile.non_root @@ -68,6 +68,7 @@ RUN --mount=type=cache,target=/app/.cache/uv,id=litellm-uv-cache \ --extra proxy-runtime \ --extra extra_proxy \ --extra semantic-router \ + --extra saml \ --python python3 # Copy full source tree @@ -94,6 +95,7 @@ RUN --mount=type=cache,target=/app/.cache/uv,id=litellm-uv-cache \ --extra proxy-runtime \ --extra extra_proxy \ --extra semantic-router \ + --extra saml \ --python python3 \ --no-sources-package litellm-proxy-extras; \ else \ @@ -102,6 +104,7 @@ RUN --mount=type=cache,target=/app/.cache/uv,id=litellm-uv-cache \ --extra proxy-runtime \ --extra extra_proxy \ --extra semantic-router \ + --extra saml \ --python python3; \ fi diff --git a/enterprise/litellm_enterprise/proxy/hooks/managed_files.py b/enterprise/litellm_enterprise/proxy/hooks/managed_files.py index 3f42867d90e..8821736d0ff 100644 --- a/enterprise/litellm_enterprise/proxy/hooks/managed_files.py +++ b/enterprise/litellm_enterprise/proxy/hooks/managed_files.py @@ -316,26 +316,34 @@ class _PROXY_LiteLLMManagedFiles(CustomLogger, BaseFileEndpoints): where_clause: Dict[str, Any] = {"file_purpose": "batch", **owner_filter} if after: - where_clause["id"] = {"gt": after} + cursor_row = ( + await self.prisma_client.db.litellm_managedobjecttable.find_first( + where={**where_clause, "unified_object_id": after} + ) + ) + if cursor_row is None: + raise HTTPException( + status_code=400, + detail=f"Invalid 'after' cursor: no batch found with id '{after}'.", + ) - fetch_limit = limit or 20 - if target_model_names: - # Oversample so post-fetch model-name filtering still has enough rows. - fetch_limit = max(fetch_limit * 3, 100) + page_size = limit or 20 + cursor_args: Dict[str, Any] = ( + {"cursor": {"unified_object_id": after}, "skip": 1} if after else {} + ) batches = await self.prisma_client.db.litellm_managedobjecttable.find_many( where=where_clause, - take=fetch_limit, - order={"created_at": "desc"}, + take=page_size + 1, + order=[{"created_at": "desc"}, {"unified_object_id": "desc"}], + **cursor_args, ) - batch_objects: List[LiteLLMBatch] = [] - for batch in batches: - try: - # Stop once we have enough after filtering - if len(batch_objects) >= (limit or 20): - break + has_more = len(batches) > page_size + batch_objects: List[LiteLLMBatch] = [] + for batch in batches[:page_size]: + try: batch_data = ( json.loads(batch.file_object) if isinstance(batch.file_object, str) @@ -351,9 +359,7 @@ class _PROXY_LiteLLMManagedFiles(CustomLogger, BaseFileEndpoints): ) continue - return build_list_page( - batch_objects, has_more=len(batch_objects) == (limit or 20) - ) + return build_list_page(batch_objects, has_more=has_more) async def get_user_created_file_ids( self, user_api_key_dict: UserAPIKeyAuth, model_object_ids: List[str] diff --git a/enterprise/litellm_enterprise/proxy/management_endpoints/project_endpoints.py b/enterprise/litellm_enterprise/proxy/management_endpoints/project_endpoints.py index a057df65500..9d668985eb8 100644 --- a/enterprise/litellm_enterprise/proxy/management_endpoints/project_endpoints.py +++ b/enterprise/litellm_enterprise/proxy/management_endpoints/project_endpoints.py @@ -11,7 +11,8 @@ Endpoints for /project operations #### PROJECT MANAGEMENT #### import json -from typing import List, Optional, Union +from collections.abc import Mapping, Sequence +from typing import TYPE_CHECKING from fastapi import APIRouter, Depends, HTTPException, Request @@ -25,15 +26,24 @@ from litellm.proxy.management_helpers.utils import ( ) from litellm.proxy.utils import PrismaClient, handle_exception_on_proxy +if TYPE_CHECKING: + from prisma import models as prisma_models + from prisma.actions import LiteLLM_TeamTableActions + router = APIRouter() +def _team_table(prisma_client: PrismaClient) -> "LiteLLM_TeamTableActions[prisma_models.LiteLLM_TeamTable]": + team_table: LiteLLM_TeamTableActions[prisma_models.LiteLLM_TeamTable] = prisma_client.db.litellm_teamtable + return team_table + + async def _check_user_permission_for_project( user_api_key_dict: UserAPIKeyAuth, - team_id: Optional[str], + team_id: str | None, prisma_client: PrismaClient, require_admin: bool = False, - team_object: Optional[LiteLLM_TeamTable] = None, + team_object: LiteLLM_TeamTable | None = None, ) -> bool: """ Check if user has permission to manage a project. @@ -57,9 +67,7 @@ async def _check_user_permission_for_project( team = team_object if team is None: - team = await prisma_client.db.litellm_teamtable.find_unique( - where={"team_id": team_id} - ) + team = await _team_table(prisma_client).find_unique(where={"team_id": team_id}) if team and team.admins: return user_api_key_dict.user_id in team.admins @@ -70,9 +78,9 @@ async def _check_user_permission_for_project( async def _validate_team_exists( team_id: str, prisma_client: PrismaClient, -): +) -> "prisma_models.LiteLLM_TeamTable": """Validate that a team exists. Returns the team row.""" - team = await prisma_client.db.litellm_teamtable.find_unique( + team = await _team_table(prisma_client).find_unique( where={"team_id": team_id}, ) @@ -89,7 +97,7 @@ async def _validate_team_exists( def _check_team_project_limits( team_object: LiteLLM_TeamTable, - data: Union[NewProjectRequest, UpdateProjectRequest], + data: NewProjectRequest | UpdateProjectRequest, ) -> None: """ Check that project limits respect its parent Team's limits. @@ -108,16 +116,12 @@ def _check_team_project_limits( if data.max_budget is not None and data.max_budget < 0: raise HTTPException( status_code=400, - detail={ - "error": f"max_budget cannot be negative. Received: {data.max_budget}" - }, + detail={"error": f"max_budget cannot be negative. Received: {data.max_budget}"}, ) if data.soft_budget is not None and data.soft_budget < 0: raise HTTPException( status_code=400, - detail={ - "error": f"soft_budget cannot be negative. Received: {data.soft_budget}" - }, + detail={"error": f"soft_budget cannot be negative. Received: {data.soft_budget}"}, ) # --- soft_budget < max_budget --- @@ -131,7 +135,7 @@ def _check_team_project_limits( ) # --- Validate project models are a subset of team models --- - project_models = getattr(data, "models", None) + project_models = data.models team_models = team_object.models or [] if project_models and len(team_models) > 0: # If team has 'all-proxy-models', skip validation as it allows all models @@ -148,11 +152,7 @@ def _check_team_project_limits( # --- Validate project max_budget <= team max_budget --- # Team stores budget fields directly (max_budget, tpm_limit, rpm_limit) # unlike Project which uses a separate LiteLLM_BudgetTable relation - if ( - data.max_budget is not None - and team_object.max_budget is not None - and data.max_budget > team_object.max_budget - ): + if data.max_budget is not None and team_object.max_budget is not None and data.max_budget > team_object.max_budget: raise HTTPException( status_code=400, detail={ @@ -161,11 +161,7 @@ def _check_team_project_limits( ) # --- Validate project tpm_limit <= team tpm_limit --- - if ( - data.tpm_limit is not None - and team_object.tpm_limit is not None - and data.tpm_limit > team_object.tpm_limit - ): + if data.tpm_limit is not None and team_object.tpm_limit is not None and data.tpm_limit > team_object.tpm_limit: raise HTTPException( status_code=400, detail={ @@ -174,11 +170,7 @@ def _check_team_project_limits( ) # --- Validate project rpm_limit <= team rpm_limit --- - if ( - data.rpm_limit is not None - and team_object.rpm_limit is not None - and data.rpm_limit > team_object.rpm_limit - ): + if data.rpm_limit is not None and team_object.rpm_limit is not None and data.rpm_limit > team_object.rpm_limit: raise HTTPException( status_code=400, detail={ @@ -189,19 +181,19 @@ def _check_team_project_limits( async def _create_budget_for_project( data: NewProjectRequest, - user_id: Optional[str], + user_id: str | None, litellm_proxy_admin_name: str, prisma_client: PrismaClient, ) -> str: """Create a budget for the project and return budget_id.""" budget_params = LiteLLM_BudgetTable.model_fields.keys() - _json_data = data.json(exclude_none=True) + _json_data: Mapping[str, object] = data.json(exclude_none=True) _budget_data = {k: v for k, v in _json_data.items() if k in budget_params} - budget_row = LiteLLM_BudgetTable(**_budget_data) + budget_row = LiteLLM_BudgetTable.model_validate(_budget_data) new_budget = prisma_client.jsonify_object(budget_row.json(exclude_none=True)) - _budget = await prisma_client.db.litellm_budgettable.create( + _budget: prisma_models.LiteLLM_BudgetTable = await prisma_client.db.litellm_budgettable.create( data={ **new_budget, "created_by": user_id or litellm_proxy_admin_name, @@ -214,8 +206,8 @@ async def _create_budget_for_project( async def _set_project_object_permission( data: NewProjectRequest, - prisma_client: Optional[PrismaClient], -) -> Optional[str]: + prisma_client: PrismaClient | None, +) -> str | None: """ Creates the LiteLLM_ObjectPermissionTable record for the project. Returns the object_permission_id if created, otherwise None. @@ -224,7 +216,7 @@ async def _set_project_object_permission( return None if data.object_permission is not None: - created_object_permission = ( + created_object_permission: prisma_models.LiteLLM_ObjectPermissionTable = ( await prisma_client.db.litellm_objectpermissiontable.create( data=data.object_permission.model_dump(exclude_none=True), ) @@ -344,8 +336,7 @@ async def new_project( raise HTTPException( status_code=403, detail={ - "error": "Only premium users can add tags to projects. " - + CommonProxyErrors.not_premium_user.value + "error": "Only premium users can add tags to projects. " + CommonProxyErrors.not_premium_user.value }, ) @@ -353,8 +344,7 @@ async def new_project( raise HTTPException( status_code=403, detail={ - "error": "Project management is an enterprise feature. " - + CommonProxyErrors.not_premium_user.value + "error": "Project management is an enterprise feature. " + CommonProxyErrors.not_premium_user.value }, ) @@ -375,13 +365,11 @@ async def new_project( ) # Validate team exists and get team object with budget - team_object = await _validate_team_exists( - team_id=data.team_id, prisma_client=prisma_client - ) + team_object = await _validate_team_exists(team_id=data.team_id, prisma_client=prisma_client) # Validate project limits against team limits _check_team_project_limits( - team_object=LiteLLM_TeamTable(**team_object.model_dump()), + team_object=LiteLLM_TeamTable.model_validate(team_object.model_dump()), data=data, ) @@ -391,7 +379,7 @@ async def new_project( user_api_key_dict=user_api_key_dict, team_id=data.team_id, prisma_client=prisma_client, - team_object=LiteLLM_TeamTable(**team_object.model_dump()), + team_object=LiteLLM_TeamTable.model_validate(team_object.model_dump()), ) if not has_permission: @@ -449,17 +437,13 @@ async def new_project( value=getattr(data, field), ) - new_project_row = prisma_client.jsonify_object( - project_row.json(exclude_none=True) - ) + new_project_row = prisma_client.jsonify_object(project_row.json(exclude_none=True)) # Remove budget fields (following organization_endpoints.py pattern) new_project_row = _remove_budget_fields_from_project_data(new_project_row) - verbose_proxy_logger.info( - f"new_project_row: {json.dumps(new_project_row, indent=2)}" - ) - response = await prisma_client.db.litellm_projecttable.create( + verbose_proxy_logger.info(f"new_project_row: {json.dumps(new_project_row, indent=2)}") + response: prisma_models.LiteLLM_ProjectTable = await prisma_client.db.litellm_projecttable.create( data={ **new_project_row, # type: ignore }, @@ -469,9 +453,7 @@ async def new_project( return response except Exception as e: verbose_proxy_logger.exception( - "litellm.proxy.management_endpoints.project_endpoints.new_project(): Exception occured - {}".format( - str(e) - ) + "litellm.proxy.management_endpoints.project_endpoints.new_project(): Exception occured - {}".format(str(e)) ) raise handle_exception_on_proxy(e) @@ -539,8 +521,7 @@ async def update_project( raise HTTPException( status_code=403, detail={ - "error": "Only premium users can add tags to projects. " - + CommonProxyErrors.not_premium_user.value + "error": "Only premium users can add tags to projects. " + CommonProxyErrors.not_premium_user.value }, ) @@ -548,8 +529,7 @@ async def update_project( raise HTTPException( status_code=403, detail={ - "error": "Project management is an enterprise feature. " - + CommonProxyErrors.not_premium_user.value + "error": "Project management is an enterprise feature. " + CommonProxyErrors.not_premium_user.value }, ) @@ -576,9 +556,9 @@ async def update_project( ) # Fetch existing project - existing_project = await prisma_client.db.litellm_projecttable.find_unique( - where={"project_id": data.project_id} - ) + existing_project: ( + prisma_models.LiteLLM_ProjectTable | None + ) = await prisma_client.db.litellm_projecttable.find_unique(where={"project_id": data.project_id}) if existing_project is None: raise ProxyException( @@ -595,9 +575,7 @@ async def update_project( target_team_id = data.team_id or existing_project.team_id target_team_obj = None if target_team_id is not None: - target_team_obj = await _validate_team_exists( - team_id=target_team_id, prisma_client=prisma_client - ) + target_team_obj = await _validate_team_exists(team_id=target_team_id, prisma_client=prisma_client) has_permission = await _check_user_permission_for_project( user_api_key_dict=user_api_key_dict, @@ -620,32 +598,26 @@ async def update_project( team_id=data.team_id, prisma_client=prisma_client, team_object=( - LiteLLM_TeamTable(**target_team_obj.model_dump()) - if target_team_obj - else None + LiteLLM_TeamTable.model_validate(target_team_obj.model_dump()) if target_team_obj else None ), ) if not can_assign_to_target: raise HTTPException( status_code=403, - detail={ - "error": "Cannot reassign project to a team you are not an admin of" - }, + detail={"error": "Cannot reassign project to a team you are not an admin of"}, ) # Validate project limits against team limits if target_team_obj is not None: _check_team_project_limits( - team_object=LiteLLM_TeamTable(**target_team_obj.model_dump()), + team_object=LiteLLM_TeamTable.model_validate(target_team_obj.model_dump()), data=data, ) # Prepare update data update_data = data.json(exclude_none=True, exclude={"project_id"}) update_data = prisma_client.jsonify_object(update_data) - update_data["updated_by"] = ( - user_api_key_dict.user_id or litellm_proxy_admin_name - ) + update_data["updated_by"] = user_api_key_dict.user_id or litellm_proxy_admin_name # Handle budget updates budget_fields = LiteLLM_BudgetTable.model_fields.keys() @@ -671,21 +643,17 @@ async def update_project( if existing_project.object_permission_id: # Update existing permission await prisma_client.db.litellm_objectpermissiontable.update( - where={ - "object_permission_id": existing_project.object_permission_id - }, + where={"object_permission_id": existing_project.object_permission_id}, data=object_permission_data, ) else: # Create new permission - created_permission = ( + created_permission: prisma_models.LiteLLM_ObjectPermissionTable = ( await prisma_client.db.litellm_objectpermissiontable.create( data=object_permission_data, ) ) - update_data["object_permission_id"] = ( - created_permission.object_permission_id - ) + update_data["object_permission_id"] = created_permission.object_permission_id # Handle metadata fields for field in LiteLLM_ManagementEndpoint_MetadataFields: @@ -698,7 +666,7 @@ async def update_project( update_data = _remove_budget_fields_from_project_data(update_data) # Update project - updated_project = await prisma_client.db.litellm_projecttable.update( + updated_project: prisma_models.LiteLLM_ProjectTable | None = await prisma_client.db.litellm_projecttable.update( where={"project_id": data.project_id}, data=update_data, include={"litellm_budget_table": True, "object_permission": True}, @@ -718,7 +686,7 @@ async def update_project( "/project/delete", tags=["project management"], dependencies=[Depends(user_api_key_auth)], - response_model=List[LiteLLM_ProjectTable], + response_model=list[LiteLLM_ProjectTable], ) @management_endpoint_wrapper async def delete_project( @@ -749,8 +717,7 @@ async def delete_project( raise HTTPException( status_code=403, detail={ - "error": "Project management is an enterprise feature. " - + CommonProxyErrors.not_premium_user.value + "error": "Project management is an enterprise feature. " + CommonProxyErrors.not_premium_user.value }, ) @@ -778,9 +745,7 @@ async def delete_project( for project_id in data.project_ids: # Check if project exists - existing_project = await prisma_client.db.litellm_projecttable.find_unique( - where={"project_id": project_id} - ) + existing_project = await prisma_client.db.litellm_projecttable.find_unique(where={"project_id": project_id}) if existing_project is None: raise ProxyException( @@ -791,11 +756,9 @@ async def delete_project( ) # Check if there are any keys associated with this project - associated_keys = ( - await prisma_client.db.litellm_verificationtoken.find_many( - where={"project_id": project_id} - ) - ) + associated_keys: Sequence[ + prisma_models.LiteLLM_VerificationToken + ] = await prisma_client.db.litellm_verificationtoken.find_many(where={"project_id": project_id}) if len(associated_keys) > 0: raise ProxyException( @@ -806,9 +769,9 @@ async def delete_project( ) # Delete the project - deleted_project = await prisma_client.db.litellm_projecttable.delete( - where={"project_id": project_id} - ) + deleted_project: ( + prisma_models.LiteLLM_ProjectTable | None + ) = await prisma_client.db.litellm_projecttable.delete(where={"project_id": project_id}) deleted_projects.append(deleted_project) @@ -854,7 +817,7 @@ async def project_info( ) # Fetch project - project = await prisma_client.db.litellm_projecttable.find_unique( + project: prisma_models.LiteLLM_ProjectTable | None = await prisma_client.db.litellm_projecttable.find_unique( where={"project_id": project_id}, include={"litellm_budget_table": True, "object_permission": True}, ) @@ -872,17 +835,11 @@ async def project_info( is_team_member = False if project.team_id and user_api_key_dict.user_id: - team = await prisma_client.db.litellm_teamtable.find_unique( - where={"team_id": project.team_id} - ) + team = await _team_table(prisma_client).find_unique(where={"team_id": project.team_id}) if team: caller_user_id = user_api_key_dict.user_id for m in team.members_with_roles or []: - m_user_id = ( - m.get("user_id") - if isinstance(m, dict) - else getattr(m, "user_id", None) - ) + m_user_id = m.get("user_id") if isinstance(m, dict) else getattr(m, "user_id", None) if m_user_id == caller_user_id: is_team_member = True break @@ -896,9 +853,7 @@ async def project_info( return project except Exception as e: verbose_proxy_logger.exception( - "litellm.proxy.management_endpoints.project_endpoints.project_info(): Exception occured - {}".format( - str(e) - ) + "litellm.proxy.management_endpoints.project_endpoints.project_info(): Exception occured - {}".format(str(e)) ) raise handle_exception_on_proxy(e) @@ -907,7 +862,7 @@ async def project_info( "/project/list", tags=["project management"], dependencies=[Depends(user_api_key_auth)], - response_model=List[LiteLLM_ProjectTable], + response_model=list[LiteLLM_ProjectTable], ) async def list_projects( user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), @@ -932,21 +887,19 @@ async def list_projects( # If proxy admin, get all projects if user_api_key_dict.user_role == LitellmUserRoles.PROXY_ADMIN: - projects = await prisma_client.db.litellm_projecttable.find_many( + projects: Sequence[ + prisma_models.LiteLLM_ProjectTable + ] = await prisma_client.db.litellm_projecttable.find_many( include={"litellm_budget_table": True, "object_permission": True} ) else: # Look up the user's team memberships via the reverse-index on # LiteLLM_UserTable.teams (maintained by team_member_add alongside # members_with_roles). This avoids a full scan of all team rows. - user_record = await prisma_client.db.litellm_usertable.find_unique( + user_record: prisma_models.LiteLLM_UserTable | None = await prisma_client.db.litellm_usertable.find_unique( where={"user_id": user_api_key_dict.user_id}, ) - user_team_ids = ( - user_record.teams - if user_record is not None and user_record.teams - else [] - ) + user_team_ids: Sequence[str] = user_record.teams if user_record is not None and user_record.teams else [] projects = await prisma_client.db.litellm_projecttable.find_many( where={"team_id": {"in": user_team_ids}}, diff --git a/enterprise/pyproject.toml b/enterprise/pyproject.toml index 04643b1ec33..fa209e55eb8 100644 --- a/enterprise/pyproject.toml +++ b/enterprise/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "litellm-enterprise" -version = "0.1.51" +version = "0.1.52" description = "Package for LiteLLM Enterprise features" readme = "README.md" requires-python = ">=3.9" @@ -26,7 +26,7 @@ required-version = ">=0.10.9" module-root = "" [tool.commitizen] -version = "0.1.51" +version = "0.1.52" version_files = [ "pyproject.toml:^version", "../pyproject.toml:litellm-enterprise==", diff --git a/gateway/routes/allowlist.py b/gateway/routes/allowlist.py index 792a56a2cd8..a80bbc9ca19 100644 --- a/gateway/routes/allowlist.py +++ b/gateway/routes/allowlist.py @@ -54,6 +54,7 @@ GATEWAY_PATH_PREFIXES: tuple[str, ...] = ( "/messages", "/v1/skills", "/v1/a2a/", + "/a2a/", # LiteLLM-native LLM surface "/v1/rerank", "/v2/rerank", diff --git a/helm/litellm-helm/Chart.lock b/helm/litellm-helm/Chart.lock index f13578d8d35..d626fbb472b 100644 --- a/helm/litellm-helm/Chart.lock +++ b/helm/litellm-helm/Chart.lock @@ -5,5 +5,5 @@ dependencies: - name: redis repository: oci://registry-1.docker.io/bitnamicharts version: 18.19.1 -digest: sha256:8660fe6287f9941d08c0902f3f13731079b8cecd2a5da2fbc54e5b7aae4a6f62 -generated: "2024-03-10T02:28:52.275022+05:30" +digest: sha256:38962e231f6596b93f82a8412bbe4cf5de696caecf5775dfbbd163383eb1c009 +generated: "2026-07-28T10:21:22.511401-07:00" diff --git a/helm/litellm-helm/Chart.yaml b/helm/litellm-helm/Chart.yaml index 0aef2442bfe..8ca217825b8 100644 --- a/helm/litellm-helm/Chart.yaml +++ b/helm/litellm-helm/Chart.yaml @@ -18,7 +18,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.1.0 +version: 1.1.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to @@ -32,10 +32,10 @@ annotations: dependencies: - name: "postgresql" - version: ">=13.3.0" + version: "14.3.1" repository: oci://registry-1.docker.io/bitnamicharts condition: db.deployStandalone - name: redis - version: ">=18.0.0" + version: "18.19.1" repository: oci://registry-1.docker.io/bitnamicharts condition: redis.enabled diff --git a/helm/litellm-helm/README.md b/helm/litellm-helm/README.md index 0edc4d2504b..4e0884dd08c 100644 --- a/helm/litellm-helm/README.md +++ b/helm/litellm-helm/README.md @@ -130,6 +130,16 @@ Set `billingMetrics.caSecretName` only when the collector is a private or test o | `db.deployStandalone` | Deploy a standalone, single instance deployment of Postgres, using the Bitnami postgresql chart. This is useful for getting started but doesn't provide HA or (by default) data backups. | `true` | | `postgresql.*` | If `db.deployStandalone` is `true`, configuration passed to the Bitnami postgresql chart. See the [Bitnami Documentation](https://github.com/bitnami/charts/tree/main/bitnami/postgresql) for full configuration details. See [values.yaml](./values.yaml) for the default configuration. | See [values.yaml](./values.yaml) | | `postgresql.auth.*` | If `db.deployStandalone` is `true`, care should be taken to ensure the default `password` and `postgres-password` values are **NOT** used. | `NoTaGrEaTpAsSwOrD` | +| `postgresql.image.*` | If `db.deployStandalone` is `true`, the image for the bundled Postgres. Pinned to a `docker.io/bitnamilegacy` build because Bitnami retired the versioned tags under `docker.io/bitnami`. | `bitnamilegacy/postgresql:16.2.0-debian-12-r6` | +| `redis.image.*` | If `redis.enabled` is `true`, the image for the bundled Redis. Pinned to a `docker.io/bitnamilegacy` build for the same reason. | `bitnamilegacy/redis:7.2.4-debian-12-r9` | + +#### Bundled Postgres image + +Bitnami removed the versioned tags from `docker.io/bitnami` and republished the archived builds under `docker.io/bitnamilegacy`, so the image defaults that ship inside the `postgresql` and `redis` subcharts no longer pull. The chart pins both to the `bitnamilegacy` copies of the exact builds those subchart versions were released with, which keeps the on-disk data directory layout unchanged for existing installs. + +Keep `postgresql.image.tag` pinned. `docker.io/bitnami/postgresql` still publishes a floating `latest`, and pointing the bundled Postgres at a different major version starts the server against a data directory it cannot read (`database files are incompatible with server`). There is no in-place way back, so crossing a major version means dumping the database with the old image and restoring it into the new one. The chart refuses to render when the tag is empty or `latest`. + +Those images no longer receive updates. For anything beyond getting started, run Postgres outside the chart and point at it with `db.useExisting`. #### Example Postgres `db.useExisting` Secret diff --git a/helm/litellm-helm/templates/_helpers.tpl b/helm/litellm-helm/templates/_helpers.tpl index 387bc3d5dc4..8f2acb20fce 100644 --- a/helm/litellm-helm/templates/_helpers.tpl +++ b/helm/litellm-helm/templates/_helpers.tpl @@ -146,3 +146,18 @@ Get redis service port {{ .Values.redis.master.service.ports.redis }} {{- end -}} {{- end -}} + +{{/* +Reject an unpinned image tag for the bundled PostgreSQL. +A floating tag lets a chart upgrade start a newer PostgreSQL major against the +existing PersistentVolumeClaim. The server then refuses to start on a data +directory written by another major version, and the only way back is a dump +taken before the change, which by that point no longer exists. +*/}} +{{- define "litellm.validateBundledPostgresImageTag" -}} +{{- $tag := .Values.postgresql.image.tag | default "" | toString -}} +{{- $digest := .Values.postgresql.image.digest | default "" | toString -}} +{{- if and (eq $digest "") (or (eq $tag "") (eq $tag "latest")) -}} +{{- fail (printf "postgresql.image.tag must be pinned to an explicit version when db.deployStandalone is true (got %q). An unpinned tag can start a different PostgreSQL major against the existing data directory, which makes the database unreadable and is not recoverable in place. Crossing a major version requires a dump and restore." $tag) -}} +{{- end -}} +{{- end -}} diff --git a/helm/litellm-helm/templates/secret-dbcredentials.yaml b/helm/litellm-helm/templates/secret-dbcredentials.yaml index 8851f5802f2..8ab89a4579e 100644 --- a/helm/litellm-helm/templates/secret-dbcredentials.yaml +++ b/helm/litellm-helm/templates/secret-dbcredentials.yaml @@ -1,4 +1,5 @@ {{- if .Values.db.deployStandalone -}} +{{- include "litellm.validateBundledPostgresImageTag" . -}} apiVersion: v1 kind: Secret metadata: diff --git a/helm/litellm-helm/templates/tests/test-servicemonitor.yaml b/helm/litellm-helm/templates/tests/test-servicemonitor.yaml index c2a4f84ec21..ef8475339c3 100644 --- a/helm/litellm-helm/templates/tests/test-servicemonitor.yaml +++ b/helm/litellm-helm/templates/tests/test-servicemonitor.yaml @@ -10,7 +10,7 @@ metadata: spec: containers: - name: test - image: bitnami/kubectl:latest + image: docker.io/bitnamilegacy/kubectl:1.29.2-debian-12-r3 command: ['sh', '-c'] args: - | diff --git a/helm/litellm-helm/tests/bundled_db_images_tests.yaml b/helm/litellm-helm/tests/bundled_db_images_tests.yaml new file mode 100644 index 00000000000..8f0860c2721 --- /dev/null +++ b/helm/litellm-helm/tests/bundled_db_images_tests.yaml @@ -0,0 +1,94 @@ +suite: test bundled database images +templates: + - charts/postgresql/templates/primary/statefulset.yaml + - charts/redis/templates/master/application.yaml + - charts/redis/templates/configmap.yaml + - charts/redis/templates/health-configmap.yaml + - charts/redis/templates/scripts-configmap.yaml + - charts/redis/templates/secret.yaml + - secret-dbcredentials.yaml + - templates/tests/test-servicemonitor.yaml +tests: + - it: should pull the bundled postgres from a repository that still publishes the pinned tag + template: charts/postgresql/templates/primary/statefulset.yaml + set: + db.deployStandalone: true + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: docker.io/bitnamilegacy/postgresql:16.2.0-debian-12-r6 + + - it: should pull the bundled postgres metrics exporter from the same repository + template: charts/postgresql/templates/primary/statefulset.yaml + set: + db.deployStandalone: true + postgresql.metrics.enabled: true + asserts: + - equal: + path: spec.template.spec.containers[1].image + value: docker.io/bitnamilegacy/postgres-exporter:0.15.0-debian-12-r14 + + - it: should run the bundled postgres init container from the same repository + template: charts/postgresql/templates/primary/statefulset.yaml + set: + db.deployStandalone: true + postgresql.volumePermissions.enabled: true + asserts: + - equal: + path: spec.template.spec.initContainers[0].image + value: docker.io/bitnamilegacy/os-shell:12-debian-12-r16 + + - it: should pull the bundled redis from a repository that still publishes the pinned tag + template: charts/redis/templates/master/application.yaml + set: + redis.enabled: true + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: docker.io/bitnamilegacy/redis:7.2.4-debian-12-r9 + + - it: should reject a floating postgres tag that could cross a major version on an existing volume + template: secret-dbcredentials.yaml + set: + db.deployStandalone: true + postgresql.image.tag: latest + asserts: + - failedTemplate: + errorMessage: 'postgresql.image.tag must be pinned to an explicit version when db.deployStandalone is true (got "latest"). An unpinned tag can start a different PostgreSQL major against the existing data directory, which makes the database unreadable and is not recoverable in place. Crossing a major version requires a dump and restore.' + + - it: should reject an empty postgres tag + template: secret-dbcredentials.yaml + set: + db.deployStandalone: true + postgresql.image.tag: "" + asserts: + - failedTemplate: + errorMessage: 'postgresql.image.tag must be pinned to an explicit version when db.deployStandalone is true (got ""). An unpinned tag can start a different PostgreSQL major against the existing data directory, which makes the database unreadable and is not recoverable in place. Crossing a major version requires a dump and restore.' + + - it: should accept an empty postgres tag when the image is pinned by digest + template: secret-dbcredentials.yaml + set: + db.deployStandalone: true + postgresql.image.tag: "" + postgresql.image.digest: sha256:0d0e2f1a5b3c4d6e7f8091a2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d5e6 + asserts: + - hasDocuments: + count: 1 + + - it: should run the servicemonitor test pod from a pinned image + template: templates/tests/test-servicemonitor.yaml + set: + serviceMonitor.enabled: true + asserts: + - equal: + path: spec.containers[0].image + value: docker.io/bitnamilegacy/kubectl:1.29.2-debian-12-r3 + + - it: should not constrain the postgres tag when the bundled database is not deployed + template: secret-dbcredentials.yaml + set: + db.deployStandalone: false + postgresql.image.tag: latest + asserts: + - hasDocuments: + count: 0 diff --git a/helm/litellm-helm/values.yaml b/helm/litellm-helm/values.yaml index 0529e74d6e4..7235bb0bd78 100644 --- a/helm/litellm-helm/values.yaml +++ b/helm/litellm-helm/values.yaml @@ -328,8 +328,32 @@ lifecycle: {} # Settings for Bitnami postgresql chart (if db.deployStandalone is true, ignored # otherwise) +# +# Bitnami retired the versioned tags under docker.io/bitnami and republished the +# archived builds under docker.io/bitnamilegacy, so the subchart's own image +# defaults no longer resolve. The repository below points at the same build the +# subchart was released with, which keeps the on-disk data directory layout +# identical for existing installs. +# +# Keep the tag pinned. docker.io/bitnami still publishes a floating `latest`, +# and starting a newer PostgreSQL major against an existing data directory +# leaves the server refusing to boot ("database files are incompatible with +# server") with no way back other than a dump taken beforehand. Crossing a major +# version is a dump-and-restore, not an image bump. The chart refuses to render +# an unpinned tag for this reason postgresql: architecture: standalone + image: + repository: bitnamilegacy/postgresql + tag: 16.2.0-debian-12-r6 + volumePermissions: + image: + repository: bitnamilegacy/os-shell + tag: 12-debian-12-r16 + metrics: + image: + repository: bitnamilegacy/postgres-exporter + tag: 0.15.0-debian-12-r14 auth: username: litellm database: litellm @@ -359,9 +383,36 @@ postgresql: # When `redis.sentinel.enabled` is set, the coordination block is rendered with # `sentinel_nodes` and `service_name` (from `redis.sentinel.masterSet`) instead # of host/port, because a plain Redis client cannot talk to the sentinel port +# +# The image repositories carry the same bitnamilegacy repoint as postgresql +# above; the versioned tags the subchart ships with are gone from +# docker.io/bitnami redis: enabled: false architecture: standalone + image: + repository: bitnamilegacy/redis + tag: 7.2.4-debian-12-r9 + sentinel: + image: + repository: bitnamilegacy/redis-sentinel + tag: 7.2.4-debian-12-r7 + metrics: + image: + repository: bitnamilegacy/redis-exporter + tag: 1.58.0-debian-12-r4 + volumePermissions: + image: + repository: bitnamilegacy/os-shell + tag: 12-debian-12-r16 + sysctl: + image: + repository: bitnamilegacy/os-shell + tag: 12-debian-12-r16 + kubectl: + image: + repository: bitnamilegacy/kubectl + tag: 1.29.2-debian-12-r3 coordination: # Set to false to keep the bundled Redis for response caching only and leave # `general_settings.coordination_redis` out of the rendered config. A diff --git a/helm/litellm/templates/ingress.yaml b/helm/litellm/templates/ingress.yaml index 30a8e7c974b..b7c78d3fdad 100644 --- a/helm/litellm/templates/ingress.yaml +++ b/helm/litellm/templates/ingress.yaml @@ -19,7 +19,7 @@ "/v1/fine-tuning" "/fine-tuning" "/v1/responses" "/responses" "/v1/threads" "/threads" "/v1/assistants" "/assistants" "/v1/vector_stores" "/vector_stores" "/v1/indexes" "/v1/models" "/models" "/openai" "/engines" - "/v1/messages" "/messages" "/v1/skills" "/v1/a2a" + "/v1/messages" "/messages" "/v1/skills" "/v1/a2a" "/a2a" "/v1/rerank" "/v2/rerank" "/rerank" "/v1/ocr" "/ocr" "/v1/rag" "/rag" "/v1/video" "/v1/videos" "/video" "/videos" "/v1/search" "/search" "/v1/containers" "/containers" "/v1/evals" "/v1/memory" "/queue/chat" diff --git a/litellm-proxy-extras/litellm_proxy_extras/migrations/20260724000000_add_spend_log_tool_index_start_time_idx/migration.sql b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260724000000_add_spend_log_tool_index_start_time_idx/migration.sql new file mode 100644 index 00000000000..548c3bd5683 --- /dev/null +++ b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260724000000_add_spend_log_tool_index_start_time_idx/migration.sql @@ -0,0 +1,2 @@ +-- CreateIndex +CREATE INDEX IF NOT EXISTS "LiteLLM_SpendLogToolIndex_start_time_idx" ON "LiteLLM_SpendLogToolIndex"("start_time"); diff --git a/litellm-proxy-extras/litellm_proxy_extras/migrations/20260725000000_add_daily_tool_spend/migration.sql b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260725000000_add_daily_tool_spend/migration.sql new file mode 100644 index 00000000000..e02ed01a554 --- /dev/null +++ b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260725000000_add_daily_tool_spend/migration.sql @@ -0,0 +1,12 @@ +-- CreateTable +CREATE TABLE IF NOT EXISTS "LiteLLM_DailyToolSpend" ( + "date" TEXT NOT NULL, + "tool_name" TEXT NOT NULL, + "spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "total_tokens" BIGINT NOT NULL DEFAULT 0, + "request_count" BIGINT NOT NULL DEFAULT 0, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "LiteLLM_DailyToolSpend_pkey" PRIMARY KEY ("date","tool_name") +); diff --git a/litellm-proxy-extras/litellm_proxy_extras/replica_identity.py b/litellm-proxy-extras/litellm_proxy_extras/replica_identity.py new file mode 100644 index 00000000000..dc92e9dca6a --- /dev/null +++ b/litellm-proxy-extras/litellm_proxy_extras/replica_identity.py @@ -0,0 +1,106 @@ +"""Optional post-migration step that raises Postgres REPLICA IDENTITY to FULL. + +Logical-replication consumers (Neon / lakehouse sync and similar) need FULL +replica identity to reconstruct the old row of an UPDATE or DELETE. Prisma +leaves every table it creates at the Postgres default, so the setting has to be +re-applied by hand after each migration run. Setting +``LITELLM_SET_REPLICA_IDENTITY_FULL`` makes every migration run re-assert it. + +The statement goes through the Prisma CLI rather than a Postgres driver because +``litellm-proxy-extras`` has no runtime dependencies, while the CLI is already +required for the migrations themselves. +""" + +import subprocess +import tempfile +from pathlib import Path + +from litellm_proxy_extras._logging import logger + +REPLICA_IDENTITY_FULL_ENV_VAR = "LITELLM_SET_REPLICA_IDENTITY_FULL" + +REPLICA_IDENTITY_FULL_SQL = r""" +DO $$ +DECLARE + target regclass; +BEGIN + SET LOCAL lock_timeout = '5s'; + FOR target IN + SELECT c.oid::regclass + FROM pg_class c + JOIN pg_namespace n ON n.oid = c.relnamespace + WHERE c.relkind = 'r' + AND c.relreplident <> 'f' + AND n.nspname = ANY (current_schemas(false)) + AND c.relname LIKE 'LiteLLM\_%' + LOOP + BEGIN + EXECUTE format('ALTER TABLE %s REPLICA IDENTITY FULL', target); + EXCEPTION WHEN lock_not_available THEN + RAISE WARNING 'REPLICA IDENTITY FULL skipped for %: table busy, retrying next run', target; + END; + END LOOP; +END +$$; +""" + + +def apply_replica_identity_full( + schema_path: str, + prisma_command: str, + prisma_env: dict[str, str], +) -> bool: + """Set REPLICA IDENTITY FULL on every LiteLLM table that is not already FULL. + + Never raises. Replication metadata is not needed to serve requests, so + every failure mode is reported and stepped over rather than taking down a + migration run that already succeeded: a database that refuses the ALTER + (most often because the runtime user does not own the tables), a missing + or unrunnable Prisma CLI, a read-only temp directory, or a timeout. + + Returns True when the statement was applied, False when it failed. + """ + logger.info("Applying REPLICA IDENTITY FULL to LiteLLM tables") + try: + with tempfile.TemporaryDirectory(prefix="litellm_replica_identity_") as tmp_dir: + sql_path = Path(tmp_dir) / "replica_identity_full.sql" + sql_path.write_text(REPLICA_IDENTITY_FULL_SQL) + subprocess.run( + [ + prisma_command, + "db", + "execute", + "--file", + str(sql_path), + "--schema", + schema_path, + ], + timeout=60, + check=True, + capture_output=True, + text=True, + env=prisma_env, + ) + except subprocess.CalledProcessError as e: + logger.error( + "Failed to set REPLICA IDENTITY FULL. Logical replication " + "consumers may reject updates to these tables. Grant table " + "ownership to the migration user, or apply " + "`ALTER TABLE ... REPLICA IDENTITY FULL` by hand. Error: %s", + e.stderr, + ) + return False + except subprocess.TimeoutExpired: + logger.error("Timed out setting REPLICA IDENTITY FULL on LiteLLM tables") + return False + except OSError as e: + logger.error( + "Could not run the REPLICA IDENTITY FULL statement. Logical " + "replication consumers may reject updates to these tables. " + "Error: %s", + e, + ) + return False + + logger.info("REPLICA IDENTITY FULL applied to LiteLLM tables") + return True diff --git a/litellm-proxy-extras/litellm_proxy_extras/schema.prisma b/litellm-proxy-extras/litellm_proxy_extras/schema.prisma index 23a9c086c73..37ea55f8c13 100644 --- a/litellm-proxy-extras/litellm_proxy_extras/schema.prisma +++ b/litellm-proxy-extras/litellm_proxy_extras/schema.prisma @@ -1094,6 +1094,20 @@ model LiteLLM_SpendLogToolIndex { @@id([request_id, tool_name]) @@index([tool_name, start_time]) + @@index([start_time]) +} + +// Daily tool spend rollup (one row per tool per day) – the Cost Optimization card reads this, never SpendLogs +model LiteLLM_DailyToolSpend { + date String + tool_name String + spend Float @default(0.0) + total_tokens BigInt @default(0) + request_count BigInt @default(0) + created_at DateTime @default(now()) + updated_at DateTime @updatedAt + + @@id([date, tool_name]) } // Prompt table for storing prompt configurations diff --git a/litellm-proxy-extras/litellm_proxy_extras/utils.py b/litellm-proxy-extras/litellm_proxy_extras/utils.py index 369b6561931..af822573322 100644 --- a/litellm-proxy-extras/litellm_proxy_extras/utils.py +++ b/litellm-proxy-extras/litellm_proxy_extras/utils.py @@ -10,6 +10,10 @@ from pathlib import Path from typing import Optional from litellm_proxy_extras._logging import logger +from litellm_proxy_extras.replica_identity import ( + REPLICA_IDENTITY_FULL_ENV_VAR, + apply_replica_identity_full, +) def str_to_bool(value: Optional[str]) -> bool: @@ -676,6 +680,39 @@ class ProxyExtrasDBManager: finally: os.chdir(original_dir) + @staticmethod + def apply_replica_identity_full_if_requested() -> bool: + """ + Re-assert REPLICA IDENTITY FULL on LiteLLM's tables when the operator + opted in via LITELLM_SET_REPLICA_IDENTITY_FULL. + + Prisma leaves new tables at the Postgres default, which logical + replication consumers reject, so the setting has to be re-applied after + every migration run rather than once by hand. + + Returns: + bool: True if the setting was applied, False if it was not + requested or could not be applied. + """ + if not str_to_bool(os.getenv(REPLICA_IDENTITY_FULL_ENV_VAR)): + return False + try: + schema_path = ProxyExtrasDBManager._get_prisma_dir() + "/schema.prisma" + prisma_command = _get_prisma_command() + prisma_env = _get_prisma_env() + except OSError as e: + logger.error( + "Could not resolve the migrations directory for the REPLICA " + "IDENTITY FULL step, skipping it. Error: %s", + e, + ) + return False + return apply_replica_identity_full( + schema_path=schema_path, + prisma_command=prisma_command, + prisma_env=prisma_env, + ) + @staticmethod def setup_database( use_migrate: bool = False, use_v2_resolver: bool = False @@ -694,6 +731,15 @@ class ProxyExtrasDBManager: Returns: bool: True if setup was successful, False otherwise """ + migrated = ProxyExtrasDBManager._run_migrations( + use_migrate=use_migrate, use_v2_resolver=use_v2_resolver + ) + if migrated: + ProxyExtrasDBManager.apply_replica_identity_full_if_requested() + return migrated + + @staticmethod + def _run_migrations(use_migrate: bool, use_v2_resolver: bool) -> bool: if use_v2_resolver: logger.info("Using v2 migration resolver (--use_v2_migration_resolver)") return ProxyExtrasDBManager._setup_database_v2(use_migrate=use_migrate) diff --git a/litellm-proxy-extras/pyproject.toml b/litellm-proxy-extras/pyproject.toml index ccca88c9996..79984dcab68 100644 --- a/litellm-proxy-extras/pyproject.toml +++ b/litellm-proxy-extras/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "litellm-proxy-extras" -version = "0.4.80" +version = "0.4.81" description = "Additional files for the LiteLLM Proxy. Reduces the size of the main litellm package." readme = "README.md" requires-python = ">=3.9" @@ -26,7 +26,7 @@ required-version = ">=0.10.9" module-root = "" [tool.commitizen] -version = "0.4.80" +version = "0.4.81" version_files = [ "pyproject.toml:^version", "../pyproject.toml:litellm-proxy-extras==", diff --git a/litellm-rust/ADDING_A_PROVIDER.md b/litellm-rust/ADDING_A_PROVIDER.md index 5f933ec4fa8..857a744e014 100644 --- a/litellm-rust/ADDING_A_PROVIDER.md +++ b/litellm-rust/ADDING_A_PROVIDER.md @@ -1,10 +1,11 @@ # Adding a provider / route to litellm-rust -Three layers, same for every route (see `ocr` and `realtime` as references): +Everything for a route lives in `crates/core/src//`; `crates/core/src/messages` is the reference. A host (the axum gateway, the Python bridge) only calls the route's entrypoint. -1. **Transform contract (pure)** — `crates/core/src//transformation.rs`: a `…ProviderConfig` trait (URL build + request/response transforms) + types in `types.rs`. No network, env, or auth. -2. **Provider config (pure)** — `crates/providers/src///transformation.rs`: implement that trait as a `const __CONFIG`, mirroring the Python provider tree. Add parity unit tests. -3. **HTTP / transport (the host)** — `crates/providers/src/.rs` (e.g. `ocr.rs`, `realtime.rs`): the callable fn (`run_ocr`, `realtime`). It resolves the key, builds the auth header, builds URL + transforms via the config, then does the network call. This is the only layer allowed to do I/O. +1. **Entrypoint** — `mod.rs`: `pub async fn (request) -> CoreResult`, the Rust equivalent of `litellm.()`, plus a `_stream` variant when the route streams. It is the only thing a host touches. +2. **Transform contract** — `transformation.rs`: a `…ProviderConfig` trait (URL build + request/response transforms) with types in `types.rs`. +3. **Provider config** — `crates/core/src/providers///transformation.rs`: implement that trait as a `const __CONFIG`, mirroring the Python provider tree. Add parity unit tests. +4. **Prepare + handler** — `prepare.rs` resolves provider/model, credentials, auth headers, and URL, then transforms the request; `handler.rs` performs the provider call through the shared client in `client.rs` and transforms the response. ## Coding standards @@ -25,4 +26,4 @@ variants of it. The test for a good abstraction is that adding the next provider is a few declarative lines, not a new file of duplicated flow. Only diverge from the base when behavior is genuinely different, and say so explicitly in the PR. -**Calling:** the host invokes the route fn — the Python bridge calls `run_ocr`; the `ai-gateway` server calls `realtime`. Register new modules in `lib.rs` / `mod.rs`, then run `cargo fmt && cargo clippy --workspace -- -D warnings && cargo test --workspace`. +**Calling:** hosts invoke the core entrypoint — the Python bridge and the `ai-gateway` route service both call `litellm_core::messages::messages`. Never add a provider handler to `ai-gateway`. Register new modules in `lib.rs` / `mod.rs`, then run `cargo fmt && cargo clippy --workspace -- -D warnings && cargo test --workspace`. diff --git a/litellm-rust/AGENTS.md b/litellm-rust/AGENTS.md index 398eec4685c..36a5ad5a8f4 100644 --- a/litellm-rust/AGENTS.md +++ b/litellm-rust/AGENTS.md @@ -4,14 +4,30 @@ litellm-rust has exactly THREE crates. A crate is a LAYER, not a route. Routes ( ## Crates -| Crate | Role | Pure / I/O | -|-------|------|------------| -| litellm-core | Translation layer — types, route contracts (traits), provider transforms (modules under providers/), and the router. Builds requests/responses; no network. | Pure | -| litellm-ai-gateway | Routes + host — the only crate that touches the network. HTTP/WebSocket I/O (modules under io/) plus the axum server binary (behind the `server` feature). | I/O | -| litellm-python-bridge | PyO3 cdylib exposing Rust to the litellm Python SDK — a thin adapter over litellm-ai-gateway's I/O. | Binding | +| Crate | Role | +|-------|------| +| litellm-core | The LiteLLM SDK in Rust. One public entrypoint per top-level call (`messages::messages()`), owning types, transforms, provider resolution, auth, and the provider HTTP call. Call it, get a typed response. | +| litellm-ai-gateway | The axum server (behind the `server` feature) plus the WebSocket hosts. Translates HTTP/WS to core entrypoints; owns no provider logic and no handlers. | +| litellm-python-bridge | PyO3 cdylib exposing Rust to the litellm Python SDK — marshals Python objects and calls core entrypoints. | Dependency direction (acyclic): litellm-core ← litellm-ai-gateway ← litellm-python-bridge. +## Where a route lives + +A top-level LiteLLM call is a module under `crates/core/src//`, shaped like `messages`: + +``` +core/src/messages/ + mod.rs # pub async fn messages(..) -> CoreResult<..> (+ messages_stream for SSE) + types.rs # request/response types, MessagesRequest + transformation.rs # the provider template trait + prepare.rs # provider resolution, auth headers, URL + handler.rs # the provider call + client.rs # the shared reqwest client +``` + +Handlers never live in `ai-gateway`. `ocr`, `audio_transcription`, and `realtime` are still hosted there from before this rule; they move to `core` as they are touched. + Adding a crate: default to a MODULE. New crate ONLY on a real trigger — separate artifact (binary/cdylib), proc-macro, shared foundation, or publishable standalone. A new provider or route is none of these. Adding a crate fails crates/core/tests/workspace_crate_allowlist.rs until you update its allowlist and this file — intentional. diff --git a/litellm-rust/CLAUDE.md b/litellm-rust/CLAUDE.md index 0659e63df39..fe6ceedbb86 100644 --- a/litellm-rust/CLAUDE.md +++ b/litellm-rust/CLAUDE.md @@ -23,21 +23,34 @@ the base when behavior is genuinely different, and say so explicitly in the PR. ## Crates (exactly three — see AGENTS.md) -`litellm-core` describes work; `litellm-ai-gateway` executes it; `litellm-python-bridge` -exposes it to the Python SDK. A crate is a **layer**, not a route — add modules, not crates. +`litellm-core` **is** the LiteLLM SDK in Rust: it makes the LLM call. +`litellm-ai-gateway` is an HTTP/WebSocket server in front of it, and +`litellm-python-bridge` exposes it to the Python SDK. A crate is a **layer**, not +a route — add modules, not crates. ## Core Boundary -`litellm-core` is the pure translation layer; the `litellm-ai-gateway` host executes work. +`litellm-core` owns the whole call. The Rust equivalent of `litellm.messages()` +is `litellm_core::messages::messages(request).await`: you call it, it does the +provider call, and you get a typed non-streaming response back. Route-level Rust structure mirrors LiteLLM's Python responsibilities: -- `core/src//` owns the route contract, shared types, and provider - template traits. For OCR, this means `core/src/ocr`. +- `core/src//` owns the route end to end: the public entrypoint fn named + after the route in `mod.rs`, the request/response types (`types.rs`), the + provider template trait (`transformation.rs`), the provider/auth/URL + resolution (`prepare.rs`), the HTTP client (`client.rs`), and the handler that + performs the call (`handler.rs`). `core/src/messages` is the reference. - `core/src/providers///transformation.rs` owns the - provider-specific transform. For Mistral OCR, this means - `core/src/providers/mistral/ocr/transformation.rs`. -- Network execution lives in the host crate `ai-gateway` (`ai-gateway/src/io/`), - never inside `core`. + provider-specific transform. For Anthropic Messages, this means + `core/src/providers/anthropic/messages/transformation.rs`. +- Handlers live in `core`, never in a host. `ai-gateway` must not contain a + route handler that talks to a provider; its axum route reads the HTTP request, + picks a deployment, and calls the `core` entrypoint. `python-bridge` marshals + Python objects and calls the same entrypoint. + +Streaming keeps the same shape: the route entrypoint has a `_stream` +variant in `core` that returns the upstream response so a host can splice it to +its own caller; the host still owns no provider logic. Call-hook and lifecycle instrumentation, including phase timing, usage accumulation, and callback payload construction, always lives in `core`. @@ -45,21 +58,31 @@ Hosts feed observed events into core and dispatch the completed payloads through their I/O logger; hosts must not own callback orchestration. Allowed in `core`: -- Pure request transforms -- Pure response transforms -- Pure stream chunk normalization +- The public entrypoint for a top-level LiteLLM call +- Request/response transforms and stream chunk normalization +- Provider resolution, auth header construction, and URL building +- The provider HTTP call itself, through a shared reused client with connect and + request timeouts - Shared data types and validation errors - Deterministic token/cost helper logic Not allowed in `core`: -- Network calls -- Environment variable or secret reads +- Serving HTTP: axum routes, extractors, and transport concerns stay in the host - Filesystem access -- Database or cache access -- Provider SDK signing or auth flows +- Database access +- Config file reading and rollout state - Logging callbacks, spend writes, or custom callbacks - Global mutable runtime state +Env reads in `core` are limited to credential fallback inside a route's +`prepare.rs` (the `env_lookup` closure), mirroring what the Python SDK does when +no key is passed. Everything else config-shaped is resolved by the host and +passed in. + +Routes still hosted in `ai-gateway` (`ocr`, `audio_transcription`, `realtime`) +predate this rule and are being moved into `core` route modules; do not add new +ones there, and prefer moving one when you touch it. + Python owns rollout state and fallback while Rust is being introduced. Rust paths must be off by default until parity tests prove equivalence with Python. A new provider/route may instead be implemented rust-only with no Python @@ -93,10 +116,10 @@ the first PR: - Preserve Python output shape intentionally. If a field is always serialized as `null` for Python parity, leave a short comment explaining that parity choice. -## Host I/O Rules +## Network I/O Rules -These rules apply when adding future crates or modules that execute network I/O, -such as `ai-gateway`, router hosts, or standalone servers: +These rules apply to every module that executes network I/O, whether it is a +`core` route handler or a host such as `ai-gateway`: - Set connect and full-request timeouts. No unbounded waits. - Reuse HTTP clients; do not construct clients per request. diff --git a/litellm-rust/README.md b/litellm-rust/README.md index 1646c90ad76..bcccf93300b 100644 --- a/litellm-rust/README.md +++ b/litellm-rust/README.md @@ -2,18 +2,31 @@ This workspace contains the staged Rust implementation for LiteLLM. -Rust starts as a pure transform core used by the existing Python host. Python -continues to own auth, configuration, network I/O, retries, routing, logging, +`litellm-core` is the LiteLLM SDK in Rust: one entrypoint per top-level call +that makes the LLM call and hands back a typed response, the same shape as +`litellm.messages()` in Python. + +```rust +let response = litellm_core::messages::messages(MessagesRequest { + model: "claude-sonnet-4-5", + body, + api_key: Some(key), + .. +}) +.await?; +``` + +Python continues to own configuration, retries, routing policy, logging, callbacks, spend tracking, and customer plugins until each Rust path has parity coverage and production evidence. ## Crates -| Crate | Role | Pure / I/O | -|-------|------|------------| -| litellm-core | Translation layer — types, route contracts (traits), provider transforms (modules under providers/), and the router. Builds requests/responses; no network. | Pure | -| litellm-ai-gateway | Routes + host — the only crate that touches the network. HTTP/WebSocket I/O (modules under io/) plus the axum server binary (behind the `server` feature). | I/O | -| litellm-python-bridge | PyO3 cdylib exposing Rust to the litellm Python SDK — a thin adapter over litellm-ai-gateway's I/O. | Binding | +| Crate | Role | +|-------|------| +| litellm-core | The SDK. Per-route entrypoints (`messages::messages()`), types, provider transforms (modules under `providers/`), provider resolution, auth, the provider HTTP call, and the router. | +| litellm-ai-gateway | The axum server (behind the `server` feature) and WebSocket hosts. Translates HTTP/WS to core entrypoints; no provider handlers. | +| litellm-python-bridge | PyO3 cdylib exposing Rust to the litellm Python SDK — marshals Python objects and calls core entrypoints. | Dependency direction (acyclic): litellm-core ← litellm-ai-gateway ← litellm-python-bridge. @@ -21,16 +34,16 @@ Dependency direction (acyclic): litellm-core ← litellm-ai-gateway ← litellm- ```text crates/ - core/ Route contracts, shared pure types, errors, and templates. - src/ocr/ - providers/ Provider-specific pure transforms. - src/mistral/ocr/transformation.rs + core/ The SDK: route modules + provider transforms. + src/messages/ mod.rs (entrypoint), types, transformation, prepare, handler, client + src/providers/anthropic/messages/transformation.rs + ai-gateway/ Axum server + WebSocket hosts; calls core entrypoints. python-bridge/ PyO3 bridge for Python LiteLLM. ``` -The folder shape should follow the Python provider tree: -`providers/src///transformation.rs`. The bridge should expose -one function per top-level route, starting with `ocr(payload)`. +The folder shape follows the Python provider tree: +`core/src/providers///transformation.rs`. The bridge exposes one +function per top-level route, mirroring the core entrypoints. ## Checks diff --git a/litellm-rust/crates/CODING_STANDARDS/PROVIDER_CODING_STANDARDS.md b/litellm-rust/crates/CODING_STANDARDS/PROVIDER_CODING_STANDARDS.md index ed44dc4c729..a1860d8a9c9 100644 --- a/litellm-rust/crates/CODING_STANDARDS/PROVIDER_CODING_STANDARDS.md +++ b/litellm-rust/crates/CODING_STANDARDS/PROVIDER_CODING_STANDARDS.md @@ -1,6 +1,6 @@ # Provider coding standards (litellm-rust) -Rules for adding or changing an LLM provider/route in `litellm-rust`. OCR (`MISTRAL_OCR_CONFIG`) is the reference; `messages` (`ANTHROPIC_MESSAGES_CONFIG`) is the next port. +Rules for adding or changing an LLM provider/route in `litellm-rust`. `messages` (`core/src/messages`, `ANTHROPIC_MESSAGES_CONFIG`) is the reference: a route is a `core` module with a public entrypoint that makes the call and returns a typed response. ## Provider resolution @@ -16,10 +16,10 @@ Rules for adding or changing an LLM provider/route in `litellm-rust`. OCR (`MIST ## Boundaries -7. Layers never cross: `core` = pure transforms/types (no network, env, secrets, auth, logging, global mutable state); `ai-gateway` = all I/O, auth headers, HTTP/SSE, lifecycle hooks; `python-bridge` = thin PyO3 adapter. +7. Layers never cross: `core` = the call itself (entrypoint, types, transforms, provider resolution, auth headers, provider HTTP, lifecycle hooks); `ai-gateway` = serving HTTP/WS (routing, extractors, auth of *our* callers, streaming to the client); `python-bridge` = thin PyO3 adapter. Hosts call the core entrypoint; they never build a provider request. 8. Generic/route files contain zero provider-specific branches. A provider is one module under `core/src/providers///`; a route is a module, never a new crate. -9. Route entry point stays thin: `()` -> `prepare_*` -> `CallLifecycle::run_request`, which owns the pre_call -> during_call -> provider call -> success/failure order and phase timing. Handlers validate and delegate; no business logic in them. -10. Constants (URLs, env-var names, API versions, error messages) live in a crate `constants.rs`, never inline. Env reads happen only at the host/config layer, with the `DEFAULT_*` fallback defined in `constants.rs`. +9. Route entry point stays thin: `core::::()` -> `prepare_*` -> handler (or `CallLifecycle::run_request`, which owns the pre_call -> during_call -> provider call -> success/failure order and phase timing). Axum handlers validate and delegate to a service that calls the entrypoint; no business logic in them. +10. Constants (URLs, env-var names, API versions, error messages) live in a crate `constants.rs`, never inline. Config-shaped env reads happen at the host/config layer with the `DEFAULT_*` fallback defined in `constants.rs`; the only env read in `core` is the credential fallback in a route's `prepare.rs`. ## Types and errors @@ -33,7 +33,7 @@ Rules for adding or changing an LLM provider/route in `litellm-rust`. OCR (`MIST 16. Never log request/response bodies, base64 payloads, document contents, or secrets. Truncate and bound any upstream body before it crosses a host boundary. 17. Treat empty/whitespace credentials, URLs, and config values as absent at the host resolution layer. -18. Host I/O sets connect + request timeouts (no unbounded waits), reuses a shared HTTP client, and prefers rustls TLS. +18. Network I/O sets connect + request timeouts (no unbounded waits), reuses a shared HTTP client, and prefers rustls TLS. ## Tests and rollout diff --git a/litellm-rust/crates/ai-gateway/AGENTS.md b/litellm-rust/crates/ai-gateway/AGENTS.md index d9e6e1adde5..92567091cd3 100644 --- a/litellm-rust/crates/ai-gateway/AGENTS.md +++ b/litellm-rust/crates/ai-gateway/AGENTS.md @@ -1,7 +1,9 @@ # ai-gateway — folder architecture The Axum server that fronts the Rust gateway. It owns transport + config + auth -only; deployment selection lives in `core::router`, transforms in `core`/`providers`. +only; deployment selection lives in `core::router`, and the LLM call itself +(transforms, auth headers, provider HTTP) lives behind a `core` route entrypoint +such as `litellm_core::messages::messages`. No provider handler lives here. ``` src/ @@ -32,6 +34,11 @@ src/ args; it runs during extraction. Never re-implement the check per route. - **Handlers are thin.** A handler validates and delegates to its `service`. No business logic, no provider calls, no transforms in handlers. +- **Services call `core`, they don't reimplement it.** A `service` picks the + deployment and calls the `core` route entrypoint. Provider resolution, auth + headers, URL building, and the HTTP call are `core`'s job; a service that + builds a provider request itself is a bug (`routes/messages/service.rs` is + the reference). - **State is shared and cheap to clone.** Long-lived handles live behind `Arc` in `state.rs`; read env/config only in `main.rs` when building state. diff --git a/litellm-rust/crates/ai-gateway/README.md b/litellm-rust/crates/ai-gateway/README.md index f913beff6d5..7a6c620ee84 100644 --- a/litellm-rust/crates/ai-gateway/README.md +++ b/litellm-rust/crates/ai-gateway/README.md @@ -8,11 +8,11 @@ dials OpenAI upstream, and splices the two sockets frame-by-frame. `litellm-rust` is exactly three crates (a crate is a **layer**, not a route): -| Crate | Role | Pure / I/O | -|-------|------|------------| -| litellm-core | Translation layer — types, route contracts (traits), provider transforms (modules under `providers/`), and the router. Builds requests/responses; no network. | Pure | -| litellm-ai-gateway | Routes + host — the only crate that touches the network. HTTP/WebSocket I/O (modules under `io/`) plus the Axum server binary (behind the `server` feature). | I/O | -| litellm-python-bridge | PyO3 cdylib exposing Rust to the litellm Python SDK — a thin adapter over litellm-ai-gateway's I/O. | Binding | +| Crate | Role | +|-------|------| +| litellm-core | The LiteLLM SDK in Rust — per-route entrypoints (`messages::messages()`) that resolve the provider, transform, and make the call; plus types, provider transforms, and the router. | +| litellm-ai-gateway | The Axum server (behind the `server` feature) and WebSocket hosts. Translates HTTP/WS to core entrypoints; no provider handlers. | +| litellm-python-bridge | PyO3 cdylib exposing Rust to the litellm Python SDK — marshals Python objects and calls core entrypoints. | Dependency direction (acyclic): litellm-core ← litellm-ai-gateway ← litellm-python-bridge. diff --git a/litellm-rust/crates/ai-gateway/src/constants.rs b/litellm-rust/crates/ai-gateway/src/constants.rs index 74808cf1ce6..78af374bf70 100644 --- a/litellm-rust/crates/ai-gateway/src/constants.rs +++ b/litellm-rust/crates/ai-gateway/src/constants.rs @@ -29,18 +29,6 @@ pub(crate) const DEFAULT_FLUSH_INTERVAL_MS: u64 = 500; #[cfg(feature = "server")] pub(crate) const DEFAULT_PROVIDER: &str = "openai"; -/// Full-request timeout ceiling for Anthropic Messages provider calls, in -/// seconds. Mirrors the Python Anthropic Messages default. The per-request -/// timeout from `litellm_params` still overrides this on the request builder. -pub(crate) const MESSAGES_TIMEOUT_SECS: u64 = 600; - -/// Connect timeout for Anthropic Messages provider calls, in seconds. -pub(crate) const MESSAGES_CONNECT_TIMEOUT_SECS: u64 = 10; - -/// Max characters of an upstream error body echoed across the host boundary -/// before truncation, so provider bodies are bounded and data-minimized. -pub(crate) const MESSAGES_ERROR_BODY_MAX_CHARS: usize = 256; - pub(crate) const DEFAULT_RESPONSES_WS_CONNECT_TIMEOUT_SECS: u64 = 10; pub(crate) const DEFAULT_RESPONSES_WS_IDLE_TIMEOUT_SECS: u64 = 300; @@ -48,10 +36,6 @@ pub(crate) const DEFAULT_RESPONSES_WS_IDLE_TIMEOUT_SECS: u64 = 300; #[cfg(feature = "server")] pub(crate) const MESSAGES_ROUTE_PATH: &str = "/v1/messages"; -/// Provider name used by the Anthropic Messages route when a deployment's -/// provider model does not carry an explicit provider prefix. -pub(crate) const ANTHROPIC_MESSAGES_PROVIDER: &str = "anthropic"; - /// Request headers owned by the gateway and never forwarded upstream. #[cfg(feature = "server")] pub(crate) const MESSAGES_HEADERS_NOT_FORWARDED: &[&str] = diff --git a/litellm-rust/crates/ai-gateway/src/io/messages.rs b/litellm-rust/crates/ai-gateway/src/io/messages.rs deleted file mode 100644 index 86170e45678..00000000000 --- a/litellm-rust/crates/ai-gateway/src/io/messages.rs +++ /dev/null @@ -1 +0,0 @@ -pub use crate::messages::{MessagesRequest, messages}; diff --git a/litellm-rust/crates/ai-gateway/src/io/mod.rs b/litellm-rust/crates/ai-gateway/src/io/mod.rs index 6129a808965..cce56dd2121 100644 --- a/litellm-rust/crates/ai-gateway/src/io/mod.rs +++ b/litellm-rust/crates/ai-gateway/src/io/mod.rs @@ -1,5 +1,4 @@ pub mod audio_transcription; -pub mod messages; pub mod ocr; pub mod realtime; pub mod realtime_pool; diff --git a/litellm-rust/crates/ai-gateway/src/lib.rs b/litellm-rust/crates/ai-gateway/src/lib.rs index c44d661c29e..057db6457c4 100644 --- a/litellm-rust/crates/ai-gateway/src/lib.rs +++ b/litellm-rust/crates/ai-gateway/src/lib.rs @@ -4,7 +4,9 @@ //! without pulling in the HTTP server: //! //! - Call-type modules such as [`ocr`]: provider transforms, lifecycle hooks, -//! and provider I/O. Always available — no feature required. +//! and provider I/O. Always available — no feature required. These predate the +//! rule that a route's entrypoint and handler live in `litellm-core` (see +//! `litellm_core::messages`) and move there as they are touched. //! - [`io`]: compatibility exports and realtime WebSocket splice helpers. //! - The server modules ([`auth`], [`routes`], [`state`]) and anything pulling //! `axum` are gated behind the `server` feature, which the `litellm-ai-gateway` @@ -14,7 +16,6 @@ pub mod audio_transcription; mod client; pub mod io; -pub mod messages; pub mod ocr; /// GIL-activity tracking. Pure (atomics only); shared by the `server` routes and diff --git a/litellm-rust/crates/ai-gateway/src/messages/mod.rs b/litellm-rust/crates/ai-gateway/src/messages/mod.rs deleted file mode 100644 index fd2dd546941..00000000000 --- a/litellm-rust/crates/ai-gateway/src/messages/mod.rs +++ /dev/null @@ -1,49 +0,0 @@ -use litellm_core::CoreResult; -use serde_json::Value; - -mod client; -mod common_utils; -mod handler; -mod prepare; -mod types; - -pub use types::MessagesRequest; - -use handler::{execute_messages_provider_call, execute_messages_provider_stream}; -use prepare::prepare_messages_call; - -pub async fn messages(request: MessagesRequest<'_>) -> CoreResult { - match execute_messages(request, false).await? { - MessagesResponse::Json(body) => Ok(body), - MessagesResponse::Stream(response) => { - drop(response); - Err(litellm_core::CoreError::InvalidResponse( - "non-streaming messages execution returned a stream".to_string(), - )) - } - } -} - -pub(crate) enum MessagesResponse { - Json(Value), - Stream(reqwest::Response), -} - -pub(crate) async fn execute_messages( - request: MessagesRequest<'_>, - stream: bool, -) -> CoreResult { - let prepared = prepare_messages_call(request)?; - if stream { - execute_messages_provider_stream(prepared) - .await - .map(MessagesResponse::Stream) - } else { - execute_messages_provider_call(prepared) - .await - .map(MessagesResponse::Json) - } -} - -#[cfg(test)] -mod tests; diff --git a/litellm-rust/crates/ai-gateway/src/messages/types.rs b/litellm-rust/crates/ai-gateway/src/messages/types.rs deleted file mode 100644 index 848fadb4b02..00000000000 --- a/litellm-rust/crates/ai-gateway/src/messages/types.rs +++ /dev/null @@ -1,24 +0,0 @@ -use std::time::Duration; - -use litellm_core::messages::transformation::AnthropicMessagesProviderConfig; -use serde_json::{Map, Value}; - -pub struct MessagesRequest<'a> { - pub model: &'a str, - pub body: Value, - pub api_key: Option<&'a str>, - pub api_base: Option<&'a str>, - pub custom_llm_provider: Option<&'a str>, - pub extra_headers: Option>, - pub timeout: Option, -} - -pub(crate) struct ProviderMessagesRequest { - pub(crate) provider: String, - pub(crate) model: String, - pub(crate) config: &'static dyn AnthropicMessagesProviderConfig, - pub(crate) url: String, - pub(crate) body: Value, - pub(crate) upstream_headers: Vec<(String, String)>, - pub(crate) timeout: Option, -} diff --git a/litellm-rust/crates/ai-gateway/src/routes/AGENTS.md b/litellm-rust/crates/ai-gateway/src/routes/AGENTS.md index 02c5f18c4f3..3eee43e7a2f 100644 --- a/litellm-rust/crates/ai-gateway/src/routes/AGENTS.md +++ b/litellm-rust/crates/ai-gateway/src/routes/AGENTS.md @@ -19,7 +19,10 @@ async fn handle(...) -> impl IntoResponse { ... } When a route has business logic worth testing without axum, put it in a sibling `service` (a file, or a folder if the route grows). The route file stays the **axum surface** (router + handler + any socket/SSE adapter); `service` is plain -Rust with **no axum types**. `realtime/` is the example: +Rust with **no axum types**, and its job is to pick the deployment and call the +`core` route entrypoint (see `messages/service.rs` calling +`litellm_core::messages::messages`). Never build a provider request, resolve a +key, or perform the provider call here. `realtime/` is the older example: ``` realtime/ mod.rs # axum surface: router() + handler + the WS<->events adapter @@ -33,6 +36,8 @@ genuinely gets hard to read. `crate::auth::RequireMasterKey` to its arguments; it runs during extraction. Never re-implement the check per route. - **Handlers contain no business logic; `service` contains no axum types.** +- **No provider handlers in this crate.** Transforms, auth headers, and the + provider HTTP call live in `core/src//`. - A route owns its paths in its own `router()`; `mod.rs` only merges. - Cross-cutting concerns (logging, CORS, timeouts) → Tower layers in `mod.rs`, not duplicated in handlers. diff --git a/litellm-rust/crates/ai-gateway/src/routes/messages/service.rs b/litellm-rust/crates/ai-gateway/src/routes/messages/service.rs index 75ed26e5be8..5f4c5fe8de4 100644 --- a/litellm-rust/crates/ai-gateway/src/routes/messages/service.rs +++ b/litellm-rust/crates/ai-gateway/src/routes/messages/service.rs @@ -1,12 +1,12 @@ use std::sync::Arc; +use litellm_core::constants::ANTHROPIC_MESSAGES_PROVIDER; +use litellm_core::messages::types::MessagesRequest; +use litellm_core::messages::{messages, messages_stream}; use litellm_core::router::Router; use litellm_core::{CoreError, CoreResult}; use serde_json::{Map, Value}; -use crate::constants::ANTHROPIC_MESSAGES_PROVIDER; -use crate::messages::{MessagesRequest, execute_messages}; - pub(crate) enum MessagesResponse { Json(Value), Stream(reqwest::Response), @@ -52,13 +52,14 @@ pub async fn run( extra_headers, timeout: None, }; - let stream = request.body.get("stream").and_then(Value::as_bool) == Some(true); - execute_messages(request, stream) - .await - .map(|response| match response { - crate::messages::MessagesResponse::Json(body) => MessagesResponse::Json(body), - crate::messages::MessagesResponse::Stream(upstream) => { - MessagesResponse::Stream(upstream) - } + if request.body.get("stream").and_then(Value::as_bool) == Some(true) { + return messages_stream(request).await.map(MessagesResponse::Stream); + } + + let response = messages(request).await?; + serde_json::to_value(response) + .map(MessagesResponse::Json) + .map_err(|err| { + CoreError::InvalidResponse(format!("failed to serialize messages response: {err}")) }) } diff --git a/litellm-rust/crates/core/AGENTS.md b/litellm-rust/crates/core/AGENTS.md index 8740dccaf01..aee8b4937ef 100644 --- a/litellm-rust/crates/core/AGENTS.md +++ b/litellm-rust/crates/core/AGENTS.md @@ -1,3 +1,7 @@ -litellm-core is the PURE translation layer — types, route contracts (traits), provider transforms (modules under `providers/`), and the router. No network, no I/O, no env reads. +litellm-core is the LiteLLM SDK in Rust — it makes the LLM call. Each top-level call is a module under `src//` exposing a public entrypoint named after the route (`messages::messages()`, the Rust equivalent of `litellm.messages()`): you call it and get a typed non-streaming response back. -Routes (ocr, realtime) and providers (mistral, openai) are modules, not crates. +A route module owns everything the call needs: types, the provider template trait, provider transforms (under `providers/`), provider/auth/URL resolution, and the handler that performs the HTTP call. Handlers belong here, never in a host crate. + +Not here: serving HTTP (axum routes, extractors), config file reading, rollout state, databases, or callback dispatch. Env reads are limited to credential fallback in a route's `prepare.rs`. + +Routes (messages, ocr, realtime) and providers (anthropic, mistral, openai) are modules, not crates. diff --git a/litellm-rust/crates/core/CLAUDE.md b/litellm-rust/crates/core/CLAUDE.md index 20873878967..5d36305ded5 100644 --- a/litellm-rust/crates/core/CLAUDE.md +++ b/litellm-rust/crates/core/CLAUDE.md @@ -4,20 +4,28 @@ Rules for `litellm-rust/crates/core`. ## Responsibility -`core` owns shared data types, typed errors, and deterministic helper contracts. -It must stay pure and host-independent. +`core` is the LiteLLM SDK in Rust: it makes the LLM call. Every top-level +LiteLLM call has a public entrypoint here, named after the route +(`messages::messages()` is the Rust equivalent of `litellm.messages()`), and +calling it returns a typed non-streaming response. Allowed: +- The public entrypoint for a route, plus its `_stream` variant when the + route supports streaming. +- Provider resolution, auth header construction, URL building, and the provider + HTTP call (shared reused client, connect + request timeouts). - Shared request/response structs. - Typed errors with stable, non-sensitive messages. - Deterministic validation helpers. - Serialization helpers that intentionally mirror Python output shape. - Route templates that match Python base config responsibilities, such as - `ocr::transformation::OcrProviderConfig`. + `messages::transformation::AnthropicMessagesProviderConfig`. Not allowed: -- Network, filesystem, database, cache, or environment access. -- Secret reads or auth/header construction. +- Serving HTTP: axum routers, extractors, and other transport concerns. +- Filesystem, database, or cache access. +- Config file reading or rollout state; the host resolves those and passes them + in. Env reads are limited to credential fallback in a route's `prepare.rs`. - Logging callbacks, tracing spans, spend writes, or customer callbacks. - Provider-specific branching that belongs in `providers`. - Panics for user/provider-controlled input. @@ -33,10 +41,21 @@ typed field on a struct, not a raw string threaded through the API. ## Structure -Use route names directly under `src/`: `ocr`, future `messages`, +Use route names directly under `src/`: `messages`, `ocr`, future `chat_completions`, `embeddings`, and similar top-level LiteLLM calls. Do not invent broad names like `engine` for route contracts. +`src/messages` is the reference shape for a route module: + +``` +mod.rs pub async fn messages(..) (+ messages_stream) +types.rs request/response types +transformation.rs the provider template trait +prepare.rs provider resolution, auth headers, URL +handler.rs the provider call +client.rs the shared reqwest client +``` + ## Parity Rules - Every shared type used by a provider transform needs unit tests for diff --git a/litellm-rust/crates/core/Cargo.toml b/litellm-rust/crates/core/Cargo.toml index 65c6db7412c..ab8050734f2 100644 --- a/litellm-rust/crates/core/Cargo.toml +++ b/litellm-rust/crates/core/Cargo.toml @@ -7,6 +7,7 @@ repository.workspace = true [dependencies] rand.workspace = true +reqwest.workspace = true serde.workspace = true serde_json.workspace = true thiserror.workspace = true @@ -30,5 +31,4 @@ bedrock-auth = [ ] [dev-dependencies] -reqwest.workspace = true tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } diff --git a/litellm-rust/crates/core/src/constants.rs b/litellm-rust/crates/core/src/constants.rs index 5826a5bc9c1..caada1d98b0 100644 --- a/litellm-rust/crates/core/src/constants.rs +++ b/litellm-rust/crates/core/src/constants.rs @@ -1,3 +1,19 @@ pub const OPENAI_DEFAULT_API_BASE: &str = "https://api.openai.com"; pub const OPENAI_RESPONSES_DEFAULT_API_BASE: &str = "https://api.openai.com/v1"; pub const OPENAI_RESPONSES_PATH: &str = "/responses"; + +/// Full-request timeout ceiling for Anthropic Messages provider calls, in +/// seconds. Mirrors the Python Anthropic Messages default. The per-request +/// timeout from the caller still overrides this on the request builder. +pub(crate) const MESSAGES_TIMEOUT_SECS: u64 = 600; + +/// Connect timeout for Anthropic Messages provider calls, in seconds. +pub(crate) const MESSAGES_CONNECT_TIMEOUT_SECS: u64 = 10; + +/// Max characters of an upstream error body echoed across the call boundary +/// before truncation, so provider bodies are bounded and data-minimized. +pub(crate) const MESSAGES_ERROR_BODY_MAX_CHARS: usize = 256; + +/// Provider name used for Anthropic Messages when a deployment's provider model +/// does not carry an explicit provider prefix. +pub const ANTHROPIC_MESSAGES_PROVIDER: &str = "anthropic"; diff --git a/litellm-rust/crates/ai-gateway/src/messages/client.rs b/litellm-rust/crates/core/src/messages/client.rs similarity index 100% rename from litellm-rust/crates/ai-gateway/src/messages/client.rs rename to litellm-rust/crates/core/src/messages/client.rs diff --git a/litellm-rust/crates/ai-gateway/src/messages/common_utils.rs b/litellm-rust/crates/core/src/messages/common_utils.rs similarity index 83% rename from litellm-rust/crates/ai-gateway/src/messages/common_utils.rs rename to litellm-rust/crates/core/src/messages/common_utils.rs index 68ecc3f17c1..9dcfcaa71e3 100644 --- a/litellm-rust/crates/ai-gateway/src/messages/common_utils.rs +++ b/litellm-rust/crates/core/src/messages/common_utils.rs @@ -1,11 +1,11 @@ -use litellm_core::CoreResult; -use litellm_core::error::{CoreError, json_type_name}; -use litellm_core::messages::transformation::AnthropicMessagesProviderConfig; -use litellm_core::providers::anthropic::messages::transformation::ANTHROPIC_MESSAGES_CONFIG; -use litellm_core::providers::azure_ai::messages::transformation::AZURE_ANTHROPIC_MESSAGES_CONFIG; use serde_json::{Map, Value}; use crate::constants::MESSAGES_ERROR_BODY_MAX_CHARS; +use crate::error::{CoreError, CoreResult, json_type_name}; +use crate::providers::anthropic::messages::transformation::ANTHROPIC_MESSAGES_CONFIG; +use crate::providers::azure_ai::messages::transformation::AZURE_ANTHROPIC_MESSAGES_CONFIG; + +use super::transformation::AnthropicMessagesProviderConfig; pub(super) fn truncate_error_body(body: &str) -> String { if body.chars().count() <= MESSAGES_ERROR_BODY_MAX_CHARS { diff --git a/litellm-rust/crates/ai-gateway/src/messages/handler.rs b/litellm-rust/crates/core/src/messages/handler.rs similarity index 84% rename from litellm-rust/crates/ai-gateway/src/messages/handler.rs rename to litellm-rust/crates/core/src/messages/handler.rs index 90c12367f50..1c895f66eba 100644 --- a/litellm-rust/crates/ai-gateway/src/messages/handler.rs +++ b/litellm-rust/crates/core/src/messages/handler.rs @@ -1,15 +1,13 @@ -use litellm_core::CoreResult; -use litellm_core::error::CoreError; -use serde_json::Value; +use crate::constants::ANTHROPIC_MESSAGES_PROVIDER; +use crate::error::{CoreError, CoreResult}; use super::client::http_client; use super::common_utils::truncate_error_body; -use super::types::ProviderMessagesRequest; -use crate::constants::ANTHROPIC_MESSAGES_PROVIDER; +use super::types::{AnthropicMessagesResponse, ProviderMessagesRequest}; pub(super) async fn execute_messages_provider_call( request: ProviderMessagesRequest, -) -> CoreResult { +) -> CoreResult { let mut request_builder = http_client().post(&request.url).json(&request.body); for (key, value) in &request.upstream_headers { request_builder = request_builder.header(key, value); @@ -39,12 +37,7 @@ pub(super) async fn execute_messages_provider_call( let response = serde_json::from_str(&text).map_err(|err| { CoreError::InvalidResponse(format!("invalid messages response JSON: {err}")) })?; - let transformed = request - .config - .transform_response(&request.model, response)?; - serde_json::to_value(transformed).map_err(|err| { - CoreError::InvalidResponse(format!("failed to serialize messages response: {err}")) - }) + request.config.transform_response(&request.model, response) } pub(super) async fn execute_messages_provider_stream( diff --git a/litellm-rust/crates/core/src/messages/mod.rs b/litellm-rust/crates/core/src/messages/mod.rs index ec2fbb969a6..acb36d89daf 100644 --- a/litellm-rust/crates/core/src/messages/mod.rs +++ b/litellm-rust/crates/core/src/messages/mod.rs @@ -1,2 +1,32 @@ +//! The Anthropic Messages call, the Rust equivalent of Python's +//! `litellm.messages()`. +//! +//! [`messages`] is the top-level entrypoint: give it a model, a body, and +//! credentials, and it resolves the provider, transforms the request, calls the +//! provider, and returns a typed non-streaming response. [`messages_stream`] +//! is the streaming variant; it hands the raw upstream response back so a host +//! can splice the event stream to its own caller. + +mod client; +mod common_utils; +mod handler; +mod prepare; pub mod transformation; pub mod types; + +use crate::error::CoreResult; + +use handler::{execute_messages_provider_call, execute_messages_provider_stream}; +use prepare::prepare_messages_call; +use types::{AnthropicMessagesResponse, MessagesRequest}; + +pub async fn messages(request: MessagesRequest<'_>) -> CoreResult { + execute_messages_provider_call(prepare_messages_call(request)?).await +} + +pub async fn messages_stream(request: MessagesRequest<'_>) -> CoreResult { + execute_messages_provider_stream(prepare_messages_call(request)?).await +} + +#[cfg(test)] +mod tests; diff --git a/litellm-rust/crates/ai-gateway/src/messages/prepare.rs b/litellm-rust/crates/core/src/messages/prepare.rs similarity index 92% rename from litellm-rust/crates/ai-gateway/src/messages/prepare.rs rename to litellm-rust/crates/core/src/messages/prepare.rs index 9a027490eb6..94b5b1eaed7 100644 --- a/litellm-rust/crates/ai-gateway/src/messages/prepare.rs +++ b/litellm-rust/crates/core/src/messages/prepare.rs @@ -1,9 +1,8 @@ -use litellm_core::CoreError; -use litellm_core::CoreResult; -use litellm_core::messages::transformation::MessagesAuthStrategy; -use litellm_core::routing_utils::provider::{CustomLlmProvider, get_custom_llm_provider}; +use crate::error::{CoreError, CoreResult}; +use crate::routing_utils::provider::{CustomLlmProvider, get_custom_llm_provider}; use super::common_utils::{has_bearer_auth, has_header, messages_provider_config, string_headers}; +use super::transformation::MessagesAuthStrategy; use super::types::{MessagesRequest, ProviderMessagesRequest}; pub(super) fn prepare_messages_call( diff --git a/litellm-rust/crates/ai-gateway/src/messages/tests.rs b/litellm-rust/crates/core/src/messages/tests.rs similarity index 97% rename from litellm-rust/crates/ai-gateway/src/messages/tests.rs rename to litellm-rust/crates/core/src/messages/tests.rs index 23a53e98045..9fc1763683b 100644 --- a/litellm-rust/crates/ai-gateway/src/messages/tests.rs +++ b/litellm-rust/crates/core/src/messages/tests.rs @@ -1,14 +1,16 @@ use std::time::Duration; -use litellm_core::error::CoreError; use serde_json::{Map, Value, json}; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::{TcpListener, TcpStream}; +use crate::error::CoreError; + use super::common_utils::{ has_bearer_auth, has_header, messages_provider_config, string_headers, truncate_error_body, }; -use super::{MessagesRequest, messages}; +use super::messages; +use super::types::MessagesRequest; async fn read_http_request(socket: &mut TcpStream) -> String { let mut request = Vec::new(); @@ -152,8 +154,8 @@ async fn messages_round_trip_builds_azure_request_and_passes_response_through() .await .expect("messages request succeeds"); - assert_eq!(response["content"][0]["text"], "hi"); - assert_eq!(response["stop_reason"], "end_turn"); + assert_eq!(response.content[0]["text"], "hi"); + assert_eq!(response.stop_reason.as_deref(), Some("end_turn")); let request = server.await.expect("server task completes"); let (head, body) = request.split_once("\r\n\r\n").expect("has body"); @@ -208,8 +210,8 @@ async fn messages_round_trip_builds_native_anthropic_request() { .await .expect("messages request succeeds"); - assert_eq!(response["content"][0]["text"], "hi"); - assert_eq!(response["stop_reason"], "end_turn"); + assert_eq!(response.content[0]["text"], "hi"); + assert_eq!(response.stop_reason.as_deref(), Some("end_turn")); let request = server.await.expect("server task completes"); let (head, _) = request.split_once("\r\n\r\n").expect("has body"); diff --git a/litellm-rust/crates/core/src/messages/types.rs b/litellm-rust/crates/core/src/messages/types.rs index 11fe17ea40f..b9f807c29fd 100644 --- a/litellm-rust/crates/core/src/messages/types.rs +++ b/litellm-rust/crates/core/src/messages/types.rs @@ -1,6 +1,30 @@ +use std::time::Duration; + use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; +use super::transformation::AnthropicMessagesProviderConfig; + +pub struct MessagesRequest<'a> { + pub model: &'a str, + pub body: Value, + pub api_key: Option<&'a str>, + pub api_base: Option<&'a str>, + pub custom_llm_provider: Option<&'a str>, + pub extra_headers: Option>, + pub timeout: Option, +} + +pub(super) struct ProviderMessagesRequest { + pub(super) provider: String, + pub(super) model: String, + pub(super) config: &'static dyn AnthropicMessagesProviderConfig, + pub(super) url: String, + pub(super) body: Value, + pub(super) upstream_headers: Vec<(String, String)>, + pub(super) timeout: Option, +} + #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(untagged)] pub enum SystemPrompt { diff --git a/litellm-rust/crates/python-bridge/AGENTS.md b/litellm-rust/crates/python-bridge/AGENTS.md index d6d3d90e6ab..ad3cddfa5fd 100644 --- a/litellm-rust/crates/python-bridge/AGENTS.md +++ b/litellm-rust/crates/python-bridge/AGENTS.md @@ -1,3 +1,3 @@ -litellm-python-bridge is the PyO3 cdylib that exposes Rust to the litellm Python SDK — a thin adapter (Python objects → Rust calls → Python results) over litellm-ai-gateway. +litellm-python-bridge is the PyO3 cdylib that exposes Rust to the litellm Python SDK — a thin adapter (Python objects → Rust calls → Python results) over the litellm-core route entrypoints (e.g. `litellm_core::messages::messages`). -Keep it thin: no business logic, no transforms, no I/O orchestration — just marshal in/out and call into litellm-ai-gateway. +Keep it thin: no business logic, no transforms, no I/O orchestration — just marshal in/out and call the core entrypoint. diff --git a/litellm-rust/crates/python-bridge/CLAUDE.md b/litellm-rust/crates/python-bridge/CLAUDE.md index e5d021ec25b..3ce8b8c639a 100644 --- a/litellm-rust/crates/python-bridge/CLAUDE.md +++ b/litellm-rust/crates/python-bridge/CLAUDE.md @@ -11,11 +11,11 @@ Python-compatible dictionaries. ## Bridge Shape - Prefer one stable method per top-level LiteLLM route, for example - `ocr(payload)`. + `messages(...)`, calling the matching `litellm-core` entrypoint. - Do not add one exported PyO3 function per provider helper unless there is a measured reason. -- Provider dispatch belongs in Rust route modules such as - `litellm_providers::ocr`, not in this PyO3 crate. +- Provider dispatch belongs in the `litellm-core` route module (e.g. + `litellm_core::messages`), not in this PyO3 crate. - Python owns rollout state and fallback. Rust should return errors; Python decides whether to raise or fall back. For a rust-only provider/route (no Python reference), the Python side is a thin dispatch that calls Rust and diff --git a/litellm-rust/crates/python-bridge/src/lib.rs b/litellm-rust/crates/python-bridge/src/lib.rs index ee9bdd0b81f..f0cc26a0cca 100644 --- a/litellm-rust/crates/python-bridge/src/lib.rs +++ b/litellm-rust/crates/python-bridge/src/lib.rs @@ -4,10 +4,11 @@ use std::time::Duration; use litellm_ai_gateway::io::audio_transcription::{ AudioTranscriptionRequest, audio_transcription as run_audio_transcription, }; -use litellm_ai_gateway::io::messages::{MessagesRequest, messages as run_messages}; use litellm_ai_gateway::io::ocr::{OcrRequest, ocr as run_ocr}; use litellm_ai_gateway::io::responses_ws::ResponsesWebSocketConnection as RustResponsesWebSocketConnection; use litellm_core::error::CoreError; +use litellm_core::messages::messages as run_messages; +use litellm_core::messages::types::{AnthropicMessagesResponse, MessagesRequest}; use pyo3::exceptions::{PyRuntimeError, PyValueError}; use pyo3::prelude::*; use pyo3::types::{PyAny, PyDict}; @@ -35,6 +36,15 @@ fn json_to_py(py: Python<'_>, value: Value) -> PyResult> { Ok(json.call_method1("loads", (encoded,))?.unbind()) } +fn messages_response_to_py( + py: Python<'_>, + response: AnthropicMessagesResponse, +) -> PyResult> { + let value = + serde_json::to_value(response).map_err(|err| PyValueError::new_err(err.to_string()))?; + json_to_py(py, value) +} + fn core_error_to_pyerr(err: CoreError) -> PyErr { match err { CoreError::Auth(message) => PyValueError::new_err(message), @@ -382,7 +392,7 @@ fn messages( }); match result { - Ok(value) => json_to_py(py, value), + Ok(response) => messages_response_to_py(py, response), Err(err) => Err(core_error_to_pyerr(err)), } } @@ -404,7 +414,7 @@ fn amessages( marshal_messages_inputs(py, body, extra_headers, timeout_seconds)?; pyo3_async_runtimes::tokio::future_into_py(py, async move { - let value = run_messages(MessagesRequest { + let response = run_messages(MessagesRequest { model: &model, body, api_key: api_key.as_deref(), @@ -416,7 +426,7 @@ fn amessages( .await .map_err(core_error_to_pyerr)?; - Python::attach(|py| json_to_py(py, value)) + Python::attach(|py| messages_response_to_py(py, response)) }) } diff --git a/litellm/_redis.py b/litellm/_redis.py index fe5c5cdabe9..9e3b247f577 100644 --- a/litellm/_redis.py +++ b/litellm/_redis.py @@ -61,23 +61,51 @@ def _get_redis_kwargs(): return available_args -def _get_redis_url_kwargs(client=None): +def _init_arg_names(cls: type) -> frozenset[str]: + """Every ``__init__`` parameter accepted anywhere in a class's MRO. + + Keyword-only parameters are included, and the MRO is walked because redis-py splits a + connection's parameters between ``AbstractConnection`` and its concrete subclasses. + """ + return frozenset( + name + for klass in inspect.getmro(cls) + if klass is not object + for spec in (inspect.getfullargspec(klass.__init__),) + for name in spec.args + spec.kwonlyargs + ) + + +def _get_redis_url_kwargs(client: Optional[type] = None) -> tuple[str, ...]: + """Connection kwargs that redis-py forwards from ``from_url`` down to the connection. + + ``from_url`` is declared as ``(cls, url, **kwargs)``, so introspecting it yields no + connection kwargs at all. What it really does is hand its kwargs to the connection + class, so that class's signature is the allowlist. + + Taking the client's signature instead would be wrong in both directions: it omits + nothing useful, but it admits client-only parameters such as + ``single_connection_client`` and ``auto_close_connection_pool``, plus the ``ssl_*`` + family that only ``SSLConnection`` accepts. Those reach ``AbstractConnection`` and + raise ``TypeError`` the first time a connection is created. TLS on a url config is + selected by the ``rediss://`` scheme, which picks ``SSLConnection`` on its own. + """ if client is None: - client = redis.Redis.from_url - arg_spec = inspect.getfullargspec(redis.Redis.from_url) + client = redis.Redis + connection_cls = async_redis.Connection if client is async_redis.Redis else redis.Connection + + exclude_args = frozenset( + { + "self", + "connection_pool", + "retry", + } + ) # Only allow primitive arguments - exclude_args = { - "self", - "connection_pool", - "retry", - } + include_args = ("url", "max_connections") - include_args = ["url"] - - available_args = [x for x in arg_spec.args if x not in exclude_args] + include_args - - return available_args + return tuple(x for x in _init_arg_names(connection_cls) if x not in exclude_args) + include_args def _get_redis_cluster_kwargs(client=None): @@ -614,7 +642,7 @@ def get_redis_async_client( if "url" in redis_kwargs and redis_kwargs["url"] is not None: if connection_pool is not None: return async_redis.Redis(connection_pool=connection_pool) - args = _get_redis_url_kwargs(client=async_redis.Redis.from_url) + args = _get_redis_url_kwargs(client=async_redis.Redis) url_kwargs = {} for arg in redis_kwargs: if arg in args: @@ -662,10 +690,10 @@ def get_redis_connection_pool( return None if "url" in redis_kwargs and redis_kwargs["url"] is not None: - pool_kwargs = { - "timeout": REDIS_CONNECTION_POOL_TIMEOUT, - "url": redis_kwargs["url"], - } + allowed_args = _get_redis_url_kwargs(client=async_redis.Redis) + pool_kwargs = {k: v for k, v in redis_kwargs.items() if k in allowed_args and k != "max_connections"} + pool_kwargs["timeout"] = REDIS_CONNECTION_POOL_TIMEOUT + pool_kwargs["url"] = redis_kwargs["url"] if "max_connections" in redis_kwargs: try: pool_kwargs["max_connections"] = int(redis_kwargs["max_connections"]) diff --git a/litellm/a2a_protocol/main.py b/litellm/a2a_protocol/main.py index 4c23ecfed54..f04edf2579b 100644 --- a/litellm/a2a_protocol/main.py +++ b/litellm/a2a_protocol/main.py @@ -568,6 +568,7 @@ def _build_streaming_logging_obj( logging_obj.custom_llm_provider = "a2a_agent" logging_obj.model_call_details["model"] = model logging_obj.model_call_details["custom_llm_provider"] = "a2a_agent" + logging_obj.model_call_details["call_type"] = logging_obj.call_type if agent_id: logging_obj.model_call_details["agent_id"] = agent_id diff --git a/litellm/batches/batch_utils.py b/litellm/batches/batch_utils.py index 2fcb8455e90..eef4cf8d87f 100644 --- a/litellm/batches/batch_utils.py +++ b/litellm/batches/batch_utils.py @@ -1,5 +1,6 @@ import json -from typing import Any, Iterator, List, Literal, Optional, Tuple +from dataclasses import dataclass +from typing import Any, Iterable, Iterator, List, Literal, Optional, Tuple import litellm from litellm._logging import verbose_logger @@ -24,20 +25,20 @@ async def calculate_batch_cost_and_usage( deployment-specific pricing (e.g. input_cost_per_token_batches) is used instead of the global cost map. """ - batch_cost = _batch_cost_calculator( + if ( + custom_llm_provider == "vertex_ai" + and model_name + and getattr(litellm, "disable_vertex_batch_output_transformation", False) + ): + batch_cost, batch_usage = calculate_vertex_ai_batch_cost_and_usage(file_content_dictionary, model_name) + return batch_cost, batch_usage, [model_name] + + return _aggregate_batch_cost_usage_models( + entries=file_content_dictionary, custom_llm_provider=custom_llm_provider, - file_content_dictionary=file_content_dictionary, model_name=model_name, model_info=model_info, ) - batch_usage = _get_batch_job_total_usage_from_file_content( - file_content_dictionary=file_content_dictionary, - custom_llm_provider=custom_llm_provider, - model_name=model_name, - ) - batch_models = _get_batch_models_from_file_content(file_content_dictionary, model_name, custom_llm_provider) - - return batch_cost, batch_usage, batch_models async def _handle_completed_batch( @@ -46,7 +47,9 @@ async def _handle_completed_batch( model_name: Optional[str] = None, litellm_params: Optional[dict] = None, ) -> Tuple[float, Usage, List[str]]: - """Helper function to process a completed batch and handle logging + """Fetch a completed batch's output file and aggregate its cost, usage, and + models in a single pass over the JSONL lines, so the parsed file content is + never materialized in memory. Args: batch: The batch object @@ -54,75 +57,109 @@ async def _handle_completed_batch( model_name: Optional model name litellm_params: Optional litellm parameters containing credentials (api_key, api_base, etc.) """ - # Get batch results - file_content_dictionary = await _get_batch_output_file_content_as_dictionary( - batch, custom_llm_provider, litellm_params=litellm_params - ) + file_content = await _fetch_batch_output_file_content(batch, custom_llm_provider, litellm_params=litellm_params) - # Calculate costs and usage - batch_cost = _batch_cost_calculator( - custom_llm_provider=custom_llm_provider, - file_content_dictionary=file_content_dictionary, - model_name=model_name, - ) - batch_usage = _get_batch_job_total_usage_from_file_content( - file_content_dictionary=file_content_dictionary, - custom_llm_provider=custom_llm_provider, - model_name=model_name, - ) - - batch_models = _get_batch_models_from_file_content(file_content_dictionary, model_name, custom_llm_provider) - - return batch_cost, batch_usage, batch_models - - -def _get_batch_models_from_file_content( - file_content_dictionary: List[dict], - model_name: Optional[str] = None, - custom_llm_provider: str = "openai", -) -> List[str]: - """ - Get the models from the file content - """ - if model_name: - return [model_name] - batch_models = [] - for _item in file_content_dictionary: - if _batch_response_was_successful(_item, custom_llm_provider): - _response_body = _get_response_from_batch_job_output_file(_item, custom_llm_provider) - _model = _response_body.get("model") - if _model: - batch_models.append(_model) - return batch_models - - -def _batch_cost_calculator( - file_content_dictionary: List[dict], - custom_llm_provider: Literal["openai", "azure", "vertex_ai", "hosted_vllm", "anthropic"] = "openai", - model_name: Optional[str] = None, - model_info: Optional[ModelInfo] = None, -) -> float: - """ - Calculate the cost of a batch based on the output file id - """ if ( custom_llm_provider == "vertex_ai" and model_name and getattr(litellm, "disable_vertex_batch_output_transformation", False) ): - batch_cost, _ = calculate_vertex_ai_batch_cost_and_usage(file_content_dictionary, model_name) - verbose_logger.debug("vertex_ai_total_cost=%s", batch_cost) - return batch_cost + batch_cost, batch_usage = calculate_vertex_ai_batch_cost_and_usage( + _get_file_content_as_dictionary(file_content), model_name + ) + return batch_cost, batch_usage, [model_name] - # For other providers, use the existing logic - total_cost = _get_batch_job_cost_from_file_content( - file_content_dictionary=file_content_dictionary, + return _aggregate_batch_cost_usage_models( + entries=_iter_batch_input_entries(file_content), custom_llm_provider=custom_llm_provider, model_name=model_name, - model_info=model_info, ) - verbose_logger.debug("total_cost=%s", total_cost) - return total_cost + + +@dataclass(frozen=True, slots=True) +class _BatchOutputLineStats: + cost: float + prompt_tokens: int + completion_tokens: int + total_tokens: int + cache_read_tokens: int + cache_creation_tokens: int + model: Optional[str] + + +def _iter_successful_output_line_stats( + entries: Iterable[dict], + custom_llm_provider: Literal["openai", "azure", "vertex_ai", "hosted_vllm", "anthropic", "bedrock"], + model_name: Optional[str], + model_info: Optional[ModelInfo], +) -> Iterator[_BatchOutputLineStats]: + from litellm.cost_calculator import batch_cost_calculator + + for entry in entries: + if not _batch_response_was_successful(entry, custom_llm_provider): + continue + response_body = _get_response_from_batch_job_output_file(entry, custom_llm_provider) + usage = _get_batch_job_usage_from_response_body(response_body, custom_llm_provider) + prompt_details = _parse_prompt_tokens_details(usage) + raw_model = response_body.get("model") + response_model = raw_model if isinstance(raw_model, str) and raw_model else None + if model_info is not None or custom_llm_provider in ("anthropic", "bedrock"): + if custom_llm_provider == "bedrock" and model_name: + cost_model = model_name + else: + cost_model = response_model or model_name or "" + prompt_cost, completion_cost = batch_cost_calculator( + usage=usage, + model=cost_model, + custom_llm_provider=custom_llm_provider, + model_info=model_info, + ) + line_cost = prompt_cost + completion_cost + else: + line_cost = litellm.completion_cost( + completion_response=response_body, + custom_llm_provider=custom_llm_provider, + call_type=CallTypes.aretrieve_batch.value, + ) + yield _BatchOutputLineStats( + cost=line_cost, + prompt_tokens=usage.prompt_tokens, + completion_tokens=usage.completion_tokens, + total_tokens=usage.total_tokens, + cache_read_tokens=prompt_details["cache_hit_tokens"], + cache_creation_tokens=prompt_details["cache_creation_tokens"], + model=response_model, + ) + + +def _aggregate_batch_cost_usage_models( + entries: Iterable[dict], + custom_llm_provider: Literal["openai", "azure", "vertex_ai", "hosted_vllm", "anthropic", "bedrock"], + model_name: Optional[str] = None, + model_info: Optional[ModelInfo] = None, +) -> Tuple[float, Usage, List[str]]: + """Aggregate cost, usage, and models from batch output entries in a single + pass, holding one small stats record per line instead of the parsed file.""" + line_stats = tuple(_iter_successful_output_line_stats(entries, custom_llm_provider, model_name, model_info)) + + cache_token_params = { + key: tokens + for key, tokens in ( + ("cache_read_input_tokens", sum(stats.cache_read_tokens for stats in line_stats)), + ("cache_creation_input_tokens", sum(stats.cache_creation_tokens for stats in line_stats)), + ) + if tokens > 0 + } + batch_usage = Usage( + total_tokens=sum(stats.total_tokens for stats in line_stats), + prompt_tokens=sum(stats.prompt_tokens for stats in line_stats), + completion_tokens=sum(stats.completion_tokens for stats in line_stats), + **cache_token_params, + ) + batch_models = [model_name] if model_name else [stats.model for stats in line_stats if stats.model] + total_cost = sum((stats.cost for stats in line_stats), 0.0) + verbose_logger.debug("batch output aggregate: cost=%s usage=%s models=%s", total_cost, batch_usage, batch_models) + return total_cost, batch_usage, batch_models def calculate_vertex_ai_batch_cost_and_usage( @@ -193,13 +230,13 @@ def calculate_vertex_ai_batch_cost_and_usage( ) -async def _get_batch_output_file_content_as_dictionary( +async def _fetch_batch_output_file_content( batch: Batch, custom_llm_provider: Literal["openai", "azure", "vertex_ai", "hosted_vllm", "anthropic"] = "openai", litellm_params: Optional[dict] = None, -) -> List[dict]: +) -> bytes: """ - Get the batch output file content as a list of dictionaries + Fetch the batch output file and return its raw JSONL bytes Args: batch: The batch object @@ -212,9 +249,6 @@ async def _get_batch_output_file_content_as_dictionary( _is_base64_encoded_unified_file_id, ) - if custom_llm_provider == "vertex_ai": - raise ValueError("Vertex AI does not support file content retrieval") - if batch.output_file_id is None: raise ValueError("Output file id is None cannot retrieve file content") @@ -240,7 +274,7 @@ async def _get_batch_output_file_content_as_dictionary( file_content_kwargs.update(credentials) _file_content = await afile_content(**file_content_kwargs) # type: ignore[reportArgumentType] - return _get_file_content_as_dictionary(_file_content.content) + return _file_content.content def _extract_file_access_credentials(litellm_params: Optional[dict]) -> dict: @@ -270,6 +304,8 @@ def _extract_file_access_credentials(litellm_params: Optional[dict]) -> dict: "vertex_project", "vertex_location", "vertex_credentials", + "gcs_bucket_name", + "bucket_name", "timeout", "max_retries", ] @@ -284,17 +320,7 @@ def _get_file_content_as_dictionary(file_content: bytes) -> List[dict]: """ Get the file content as a list of dictionaries from JSON Lines format """ - try: - _file_content_str = file_content.decode("utf-8") - # Split by newlines and parse each line as a separate JSON object - json_objects = [] - for line in _file_content_str.strip().split("\n"): - if line: # Skip empty lines - json_objects.append(json.loads(line)) - verbose_logger.debug("json_objects=%s", json.dumps(json_objects, indent=4)) - return json_objects - except Exception as e: - raise e + return list(_iter_batch_input_entries(file_content)) def _iter_batch_input_lines(file_content: bytes) -> Iterator[bytes]: @@ -361,101 +387,6 @@ def _count_entry_tokens( return 0 -def _get_batch_job_cost_from_file_content( - file_content_dictionary: List[dict], - custom_llm_provider: Literal["openai", "azure", "vertex_ai", "hosted_vllm", "anthropic"] = "openai", - model_name: Optional[str] = None, - model_info: Optional[ModelInfo] = None, -) -> float: - """ - Get the cost of a batch job from the file content - """ - from litellm.cost_calculator import batch_cost_calculator - - try: - total_cost: float = 0.0 - # parse the file content as json - verbose_logger.debug("file_content_dictionary=%s", json.dumps(file_content_dictionary, indent=4)) - for _item in file_content_dictionary: - if _batch_response_was_successful(_item, custom_llm_provider): - _response_body = _get_response_from_batch_job_output_file(_item, custom_llm_provider) - if model_info is not None or custom_llm_provider in ("anthropic", "bedrock"): - usage = _get_batch_job_usage_from_response_body(_response_body, custom_llm_provider) - # Bedrock batch output lines report a short internal model id - # (e.g. "claude-sonnet-4-6") that is not in the cost map; use the - # deployment model name for pricing when available. - if custom_llm_provider == "bedrock" and model_name: - model = model_name - else: - model = _response_body.get("model") or model_name or "" - prompt_cost, completion_cost = batch_cost_calculator( - usage=usage, - model=model, - custom_llm_provider=custom_llm_provider, - model_info=model_info, - ) - total_cost += prompt_cost + completion_cost - else: - total_cost += litellm.completion_cost( - completion_response=_response_body, - custom_llm_provider=custom_llm_provider, - call_type=CallTypes.aretrieve_batch.value, - ) - verbose_logger.debug("total_cost=%s", total_cost) - return total_cost - except Exception as e: - verbose_logger.error("error in _get_batch_job_cost_from_file_content", e) - raise e - - -def _get_batch_job_total_usage_from_file_content( - file_content_dictionary: List[dict], - custom_llm_provider: Literal["openai", "azure", "vertex_ai", "hosted_vllm", "anthropic"] = "openai", - model_name: Optional[str] = None, -) -> Usage: - """ - Get the tokens of a batch job from the file content - """ - if ( - custom_llm_provider == "vertex_ai" - and model_name - and getattr(litellm, "disable_vertex_batch_output_transformation", False) - ): - _, batch_usage = calculate_vertex_ai_batch_cost_and_usage(file_content_dictionary, model_name) - return batch_usage - - # For other providers, use the existing logic - total_tokens: int = 0 - prompt_tokens: int = 0 - completion_tokens: int = 0 - cache_read_tokens: int = 0 - cache_creation_tokens: int = 0 - for _item in file_content_dictionary: - if _batch_response_was_successful(_item, custom_llm_provider): - _response_body = _get_response_from_batch_job_output_file(_item, custom_llm_provider) - usage: Usage = _get_batch_job_usage_from_response_body(_response_body, custom_llm_provider) - total_tokens += usage.total_tokens - prompt_tokens += usage.prompt_tokens - completion_tokens += usage.completion_tokens - prompt_details = _parse_prompt_tokens_details(usage) - cache_read_tokens += prompt_details["cache_hit_tokens"] - cache_creation_tokens += prompt_details["cache_creation_tokens"] - cache_token_params = { - key: tokens - for key, tokens in ( - ("cache_read_input_tokens", cache_read_tokens), - ("cache_creation_input_tokens", cache_creation_tokens), - ) - if tokens > 0 - } - return Usage( - total_tokens=total_tokens, - prompt_tokens=prompt_tokens, - completion_tokens=completion_tokens, - **cache_token_params, - ) - - def _count_prompt_or_input_tokens(model: str, value: Any) -> int: """Token-count a ``prompt`` / ``input`` field that the OpenAI batch schema allows in four shapes: diff --git a/litellm/caching/caching_handler.py b/litellm/caching/caching_handler.py index b17e055c7ea..d8a2d2d76b7 100644 --- a/litellm/caching/caching_handler.py +++ b/litellm/caching/caching_handler.py @@ -517,6 +517,7 @@ class LLMCachingHandler: cached_result=final_embedding_cached_response, is_async=True, is_embedding=True, + custom_llm_provider=custom_llm_provider, ) self._async_log_cache_hit_on_callbacks( logging_obj=logging_obj, diff --git a/litellm/caching/redis_cache.py b/litellm/caching/redis_cache.py index dd1c152a421..9e0f022262b 100644 --- a/litellm/caching/redis_cache.py +++ b/litellm/caching/redis_cache.py @@ -17,7 +17,8 @@ import json import time from collections.abc import Awaitable, Callable, Sequence from datetime import timedelta -from typing import TYPE_CHECKING, Any, List, Optional, Tuple, Union, cast +from contextvars import ContextVar +from typing import TYPE_CHECKING, Any, List, Optional, Tuple, TypeVar, Union, cast import litellm from litellm._logging import print_verbose, verbose_logger @@ -168,24 +169,97 @@ class RedisCircuitBreaker: self._state = self.CLOSED +_RedisCallResult = TypeVar("_RedisCallResult") + + +_swallowed_redis_failures: ContextVar[int] = ContextVar("litellm_swallowed_redis_failures", default=0) + + +@functools.lru_cache(maxsize=1) +def _redis_health_error_types() -> tuple[type, ...]: + """Exception types that mean the Redis backend itself is unhealthy. + + Command and data errors say nothing about connectivity: an INCR against a non-numeric + value or an undecodable cached entry is a request problem, and counting those would let + a caller trip the shared breaker on demand, dropping rate limiting to per-process + counters that spreading traffic across replicas can outrun. + + Imported lazily because this module is reachable from a base ``import litellm`` while + redis is not a base dependency. + """ + from redis.exceptions import BusyLoadingError, ClusterDownError + from redis.exceptions import ConnectionError as RedisConnectionError + from redis.exceptions import TimeoutError as RedisTimeoutError + + return (RedisConnectionError, RedisTimeoutError, BusyLoadingError, ClusterDownError, OSError, asyncio.TimeoutError) + + +def _is_redis_health_failure(exc: BaseException) -> bool: + """True when ``exc`` indicates Redis is unreachable rather than the request being bad.""" + try: + return isinstance(exc, _redis_health_error_types()) + except ImportError: + return True + + +def _record_swallowed_redis_failure(breaker: RedisCircuitBreaker, exc: BaseException) -> None: + """Record a Redis failure that the calling method is about to swallow. + + The marker is a ContextVar rather than a counter on the breaker because breakers are + shared by every concurrent caller. A plain shared counter cannot tell "my call failed" + from "some other in-flight call failed", so a success overlapping someone else's + failure would be discarded and a Redis that is answering would still be evicted. + asyncio gives each task its own copy of the context, so this is per-call. + """ + if not _is_redis_health_failure(exc): + return + breaker.record_failure() + _swallowed_redis_failures.set(_swallowed_redis_failures.get() + 1) + + +async def _run_under_circuit_breaker( + breaker: RedisCircuitBreaker, + name: str, + call: Callable[[], Awaitable[_RedisCallResult]], +) -> _RedisCallResult: + """Run one Redis coroutine under a circuit breaker. + + Shared by the method decorator and the Lua script executor so both feed the same + health signal. Success is recorded only when nothing failed while ``call`` ran, + because several Redis methods catch their own connection errors and return a default. + """ + if breaker.is_open(): + raise Exception(f"Redis circuit breaker is open — skipping {name}") + swallowed_before = _swallowed_redis_failures.get() + try: + result = await call() + except Exception as e: + if _is_redis_health_failure(e): + breaker.record_failure() + raise + if _swallowed_redis_failures.get() == swallowed_before: + breaker.record_success() + return result + + def _redis_circuit_breaker_guard(method): # type: ignore """ Decorator for RedisCache async methods. Checks the circuit breaker before each call; records success/failure after. Does not apply to ping/disconnect/test_connection (health/teardown must always run). + + A returning method is not proof of a healthy Redis: several methods catch their own + connection errors and return a default so callers degrade rather than fail. Counting + those as successes reset the failure streak on every request, so the breaker could + never open and Redis was never taken out of the pool. Success is therefore recorded + only when no failure was registered while the method ran. """ @functools.wraps(method) async def wrapper(self, *args, **kwargs): # type: ignore - if self._circuit_breaker.is_open(): - raise Exception(f"Redis circuit breaker is open — skipping {method.__name__}") - try: - result = await method(self, *args, **kwargs) - self._circuit_breaker.record_success() - return result - except Exception: - self._circuit_breaker.record_failure() - raise + return await _run_under_circuit_breaker( + self._circuit_breaker, method.__name__, lambda: method(self, *args, **kwargs) + ) return wrapper @@ -551,13 +625,16 @@ class RedisCache(BaseCache): ) async def run_script(keys: Sequence[str], args: Sequence[Any], client: Any = None) -> Any: - executor: Optional[Callable[..., Awaitable[Any]]] = litellm.in_memory_llm_clients_cache.get_cache( - key=script_cache_key - ) - if executor is None: - executor = self._register_script_for_current_loop(script) - litellm.in_memory_llm_clients_cache.set_cache(key=script_cache_key, value=executor) - return await executor(keys=keys, args=args, client=client) + async def execute() -> object: + executor: Optional[Callable[..., Awaitable[Any]]] = litellm.in_memory_llm_clients_cache.get_cache( + key=script_cache_key + ) + if executor is None: + executor = self._register_script_for_current_loop(script) + litellm.in_memory_llm_clients_cache.set_cache(key=script_cache_key, value=executor) + return await executor(keys=keys, args=args, client=client) + + return await _run_under_circuit_breaker(self._circuit_breaker, "run_script", execute) return run_script @@ -674,6 +751,7 @@ class RedisCache(BaseCache): str(e), value, ) + _record_swallowed_redis_failure(self._circuit_breaker, e) async def _pipeline_helper( self, @@ -758,6 +836,7 @@ class RedisCache(BaseCache): str(e), cache_value, ) + _record_swallowed_redis_failure(self._circuit_breaker, e) async def _set_cache_sadd_helper( self, @@ -842,6 +921,7 @@ class RedisCache(BaseCache): str(e), value, ) + _record_swallowed_redis_failure(self._circuit_breaker, e) @_redis_circuit_breaker_guard async def batch_cache_write(self, key, value, **kwargs): @@ -1106,6 +1186,7 @@ class RedisCache(BaseCache): ) ) print_verbose(f"litellm.caching.caching: async get() - Got exception from REDIS: {str(e)}") + _record_swallowed_redis_failure(self._circuit_breaker, e) @_redis_circuit_breaker_guard async def async_batch_get_cache( @@ -1177,6 +1258,7 @@ class RedisCache(BaseCache): ) ) verbose_logger.error(f"Error occurred in async batch get cache - {str(e)}") + _record_swallowed_redis_failure(self._circuit_breaker, e) return key_value_dict def sync_ping(self) -> bool: @@ -1432,6 +1514,7 @@ class RedisCache(BaseCache): return ttl except Exception as e: verbose_logger.debug(f"Redis TTL Error: {e}") + _record_swallowed_redis_failure(self._circuit_breaker, e) return None @_redis_circuit_breaker_guard diff --git a/litellm/completion_extras/litellm_responses_transformation/handler.py b/litellm/completion_extras/litellm_responses_transformation/handler.py index 8f12d855880..15f5b28e30e 100644 --- a/litellm/completion_extras/litellm_responses_transformation/handler.py +++ b/litellm/completion_extras/litellm_responses_transformation/handler.py @@ -209,7 +209,15 @@ class ResponsesToCompletionBridgeHandler: json_mode=kwargs.get("json_mode"), ) elif isinstance(result, ModelResponse): - return result + if not stream: + return result + return self._completed_response_as_stream( + response=result, + model=model, + custom_llm_provider=custom_llm_provider, + logging_obj=logging_obj, + json_mode=kwargs.get("json_mode"), + ) elif not stream: responses_api_response = self._collect_response_from_stream(result) return self.transformation_handler.transform_response( @@ -299,7 +307,15 @@ class ResponsesToCompletionBridgeHandler: json_mode=kwargs.get("json_mode"), ) elif isinstance(result, ModelResponse): - return result + if not stream: + return result + return self._completed_response_as_stream( + response=result, + model=model, + custom_llm_provider=custom_llm_provider, + logging_obj=logging_obj, + json_mode=kwargs.get("json_mode"), + ) elif not stream: responses_api_response = await self._collect_response_from_stream_async(result) return self.transformation_handler.transform_response( @@ -331,6 +347,25 @@ class ResponsesToCompletionBridgeHandler: ) return self._apply_post_stream_processing(streamwrapper, model, custom_llm_provider) + def _completed_response_as_stream( + self, + response: "ModelResponse", + model: str, + custom_llm_provider: str, + logging_obj: "LiteLLMLoggingObj", + json_mode: bool | None, + ) -> "CustomStreamWrapper": + from litellm.litellm_core_utils.streaming_handler import CustomStreamWrapper + from litellm.llms.base_llm.base_model_iterator import MockResponseIterator + + streamwrapper = CustomStreamWrapper( + completion_stream=MockResponseIterator(model_response=response, json_mode=json_mode), + model=model, + custom_llm_provider=custom_llm_provider, + logging_obj=logging_obj, + ) + return self._apply_post_stream_processing(streamwrapper, model, custom_llm_provider) + @staticmethod def _apply_post_stream_processing( stream: "CustomStreamWrapper", diff --git a/litellm/completion_extras/litellm_responses_transformation/transformation.py b/litellm/completion_extras/litellm_responses_transformation/transformation.py index aecb2552b53..89a44fcdeef 100644 --- a/litellm/completion_extras/litellm_responses_transformation/transformation.py +++ b/litellm/completion_extras/litellm_responses_transformation/transformation.py @@ -35,6 +35,7 @@ from litellm.responses.sse_output_recovery import ( record_output_item_chunk, record_output_text_chunk, ) +from litellm.responses.utils import normalize_responses_api_stream_options from litellm.types.llms.openai import ( ChatCompletionAnnotation, ChatCompletionReasoningItem, @@ -320,6 +321,10 @@ class LiteLLMResponsesTransformationHandler(CompletionTransformationBridge): responses_api_request["tool_choice"] = ( # type: ignore[assignment] self._normalize_tool_choice_for_responses_api(value) ) + elif key == "stream_options": + stream_options = normalize_responses_api_stream_options(value) + if stream_options is not None: + responses_api_request["stream_options"] = stream_options elif key in ResponsesAPIOptionalRequestParams.__annotations__.keys(): responses_api_request[key] = value # type: ignore elif key == "previous_response_id": @@ -360,8 +365,6 @@ class LiteLLMResponsesTransformationHandler(CompletionTransformationBridge): continue if key == "instructions" and instructions: request_data["instructions"] = instructions - elif key == "stream_options" and isinstance(value, dict): - request_data["stream_options"] = value.get("include_obfuscation") elif key == "user" and isinstance(value, str): # OpenAI API requires user param to be max 64 chars - truncate if longer if len(value) <= 64: @@ -1074,6 +1077,7 @@ class LiteLLMResponsesTransformationHandler(CompletionTransformationBridge): class OpenAiResponsesToChatCompletionStreamIterator(BaseModelResponseIterator): def __init__(self, streaming_response, sync_stream: bool, json_mode: Optional[bool] = False): super().__init__(streaming_response, sync_stream, json_mode) + self._chat_completion_id: str | None = None def _handle_string_chunk( self, str_line: Union[str, "BaseModel"] @@ -1381,4 +1385,13 @@ class OpenAiResponsesToChatCompletionStreamIterator(BaseModelResponseIterator): ModelResponseStream: OpenAI-formatted streaming chunk """ verbose_logger.debug(f"Chat provider: transform_streaming_response called with chunk: {chunk}") - return OpenAiResponsesToChatCompletionStreamIterator.translate_responses_chunk_to_openai_stream(chunk) + return self._with_stream_scoped_id( + OpenAiResponsesToChatCompletionStreamIterator.translate_responses_chunk_to_openai_stream(chunk) + ) + + def _with_stream_scoped_id(self, chunk: "ModelResponseStream") -> "ModelResponseStream": + if self._chat_completion_id is None: + self._chat_completion_id = chunk.id + else: + chunk.id = self._chat_completion_id + return chunk diff --git a/litellm/compression/compress.py b/litellm/compression/compress.py index 004dd82cbaa..9c5f57bc98f 100644 --- a/litellm/compression/compress.py +++ b/litellm/compression/compress.py @@ -3,6 +3,7 @@ Main compress() function — normalizes input messages, orchestrates BM25/embedd scoring, message stubbing, and retrieval tool injection. """ +from collections.abc import Mapping, Sequence from typing import Any, Dict, List, Optional, Set, Tuple, Union, cast from litellm.caching.dual_cache import DualCache @@ -204,33 +205,21 @@ def _extract_anthropic_tool_exchange_spans( return spans, None -def _get_protected_indices(messages: List[dict]) -> List[int]: +def get_protected_indices(messages: Sequence[Mapping[str, object]]) -> tuple[int, ...]: """ Return indices of messages that must never be compressed: - All system messages - The last user message - The last assistant message + + The last user message is what the model is being asked to act on right now, + so compressing it replaces the live instruction with a marker. Compression + guardrails share this policy; see the Headroom guardrail. """ - protected: List[int] = [] - - last_user_idx = None - last_assistant_idx = None - - for i, msg in enumerate(messages): - role = msg.get("role", "") - if role == "system": - protected.append(i) - elif role == "user": - last_user_idx = i - elif role == "assistant": - last_assistant_idx = i - - if last_user_idx is not None: - protected.append(last_user_idx) - if last_assistant_idx is not None: - protected.append(last_assistant_idx) - - return protected + system_indices = tuple(index for index, msg in enumerate(messages) if msg.get("role", "") == "system") + last_user = tuple(index for index, msg in enumerate(messages) if msg.get("role", "") == "user")[-1:] + last_assistant = tuple(index for index, msg in enumerate(messages) if msg.get("role", "") == "assistant")[-1:] + return system_indices + last_user + last_assistant def _combine_scores( @@ -432,7 +421,7 @@ def compress( combined_scores = bm25_scores # Protected messages are never compressed - protected_indices = _get_protected_indices(normalized_messages) + protected_indices = get_protected_indices(normalized_messages) kept_indices: Set[int] = set(protected_indices) tool_exchange_spans: List[Set[int]] = [] diff --git a/litellm/constants.py b/litellm/constants.py index b9b9c0ba604..78bfc6501e8 100644 --- a/litellm/constants.py +++ b/litellm/constants.py @@ -1297,6 +1297,7 @@ X_LITELLM_DISABLE_CALLBACKS = "x-litellm-disable-callbacks" LITELLM_METADATA_FIELD = "litellm_metadata" OLD_LITELLM_METADATA_FIELD = "metadata" RETURN_RAW_MODEL_NAME_METADATA_KEY = "_complexity_router_return_raw_model_name" +INTERNAL_CALL_ORIGIN_METADATA_KEY = "internal_call_origin" LITELLM_TRUNCATED_PAYLOAD_FIELD = "litellm_truncated" LITELLM_TRUNCATION_DB_SAFEGUARD_NOTE = ( "Truncation is a DB storage safeguard. " @@ -1418,6 +1419,8 @@ LITELLM_EXPIRED_UI_SESSION_KEY_CLEANUP_BATCH_SIZE = int( os.getenv("LITELLM_EXPIRED_UI_SESSION_KEY_CLEANUP_BATCH_SIZE", 1000) ) LITELLM_PROXY_ADMIN_NAME = "default_user_id" +LITELLM_PROXY_BUDGET_NAME = "litellm-proxy-budget" +GLOBAL_PROXY_SPEND_CACHE_KEY = f"{LITELLM_PROXY_ADMIN_NAME}:spend" ########################### CLI SSO AUTHENTICATION CONSTANTS ########################### LITELLM_CLI_SOURCE_IDENTIFIER = "litellm-cli" @@ -1455,6 +1458,7 @@ SPEND_LOG_CLEANUP_MAX_CONSECUTIVE_BATCH_FAILURES = int(os.getenv("SPEND_LOG_CLEA SPEND_LOG_CLEANUP_BATCH_FAILURE_BACKOFF_SECONDS = float( os.getenv("SPEND_LOG_CLEANUP_BATCH_FAILURE_BACKOFF_SECONDS", 0.5) ) +TOOL_SPEND_TOP_TOOLS = 100 SPEND_LOG_PARTITION_INTERVAL = os.getenv("SPEND_LOG_PARTITION_INTERVAL", "day") SPEND_LOG_PARTITION_PRECREATE_AHEAD = int(os.getenv("SPEND_LOG_PARTITION_PRECREATE_AHEAD", 7)) SPEND_LOG_QUEUE_SIZE_THRESHOLD = int(os.getenv("SPEND_LOG_QUEUE_SIZE_THRESHOLD", 100)) diff --git a/litellm/integrations/custom_guardrail.py b/litellm/integrations/custom_guardrail.py index cf9dafcb222..fbe70c03d74 100644 --- a/litellm/integrations/custom_guardrail.py +++ b/litellm/integrations/custom_guardrail.py @@ -1,3 +1,4 @@ +import contextvars import hashlib import os import secrets @@ -16,7 +17,11 @@ from typing import ( ) from litellm._logging import verbose_logger -from litellm.litellm_core_utils.core_helpers import redact_nested_match_and_regex_keys +from litellm.litellm_core_utils.core_helpers import ( + get_metadata_variable_name_from_kwargs, + get_or_create_metadata_bucket, + redact_nested_match_and_regex_keys, +) from litellm.caching import DualCache from litellm.integrations.custom_logger import CustomLogger from litellm.secret_managers.main import str_to_bool @@ -64,6 +69,12 @@ from litellm.exceptions import ( # proxy's metadata sanitizer. _PRE_CALL_EXECUTED_TOKEN = secrets.token_hex(16) +_GUARDRAIL_BLOCK_STATUS_CODES = frozenset({400, 403, 422}) + +_guardrail_self_recorded: contextvars.ContextVar[bool] = contextvars.ContextVar( + "litellm_guardrail_self_recorded", default=False +) + def _strict_guardrail_modes_enabled() -> bool: """Whether guardrail-mode validation raises (default) or logs a warning. @@ -102,6 +113,8 @@ class CustomGuardrail(CustomLogger): # If True, during_call runs async_moderation_hook instead of the unified apply_guardrail path. use_native_during_call_hook: ClassVar[bool] = False + records_own_guardrail_information: ClassVar[bool] = False + def __init__( self, guardrail_name: Optional[str] = None, @@ -117,6 +130,7 @@ class CustomGuardrail(CustomLogger): on_sensitive_data: Optional[str] = None, sensitive_data_route_to_model: Optional[str] = None, sticky_session_routing: bool = True, + run_in_parallel: bool = False, only_scan_new_messages: bool = False, **kwargs, ): @@ -136,6 +150,9 @@ class CustomGuardrail(CustomLogger): on_sensitive_data: Action when sensitive data is detected. 'block' (default) or 'route' sensitive_data_route_to_model: Model to route to when on_sensitive_data='route' sticky_session_routing: When True, all subsequent requests in the session use the same model + run_in_parallel: When True, this pre_call or post_call guardrail runs concurrently with + other opted-in guardrails of the same hook. Only safe for block-only guardrails that + do not mutate the request or response. """ self.guardrail_name = guardrail_name self.supported_event_hooks = supported_event_hooks @@ -150,6 +167,7 @@ class CustomGuardrail(CustomLogger): self.on_sensitive_data: Optional[str] = on_sensitive_data self.sensitive_data_route_to_model: Optional[str] = sensitive_data_route_to_model self.sticky_session_routing: bool = sticky_session_routing + self.run_in_parallel: bool = run_in_parallel self.only_scan_new_messages: bool = only_scan_new_messages if supported_event_hooks: @@ -944,17 +962,10 @@ class CustomGuardrail(CustomLogger): # should not happen container[key] = [existing, slg] - if "metadata" in request_data: - if request_data["metadata"] is None: - request_data["metadata"] = {} - _append_guardrail_info(request_data["metadata"]) - elif "litellm_metadata" in request_data: - _append_guardrail_info(request_data["litellm_metadata"]) - else: - # Ensure guardrail info is always logged (e.g. proxy may not have set - # metadata yet). Attach to "metadata" so spend log / standard logging see it. - request_data["metadata"] = {} - _append_guardrail_info(request_data["metadata"]) + _, metadata_bucket = get_or_create_metadata_bucket(request_data) + _append_guardrail_info(metadata_bucket) + + _guardrail_self_recorded.set(True) # Emit the otel guardrail span here, where every guardrail execution lands, # rather than relying on a post-call hook that does not fire on every path @@ -1046,8 +1057,15 @@ class CustomGuardrail(CustomLogger): - GuardrailRaisedException (generic guardrail API, tool permission) - BlockedPiiEntityError (Presidio PII detection) - SensitiveDataRouteException (sensitive-data reroute to on-premise model) - - HTTPException with status 400 (content policy violation) + - HTTPException with a block-signalling status (400, 403, 422) - ModifyResponseException (passthrough mode violation) + + Only the statuses guardrails use in-tree to signal a deliberate rejection + count as an intervention: 400 (content policy), 403 (e.g. akto) and 422 + (e.g. llm_as_a_judge). Other 4xx codes are commonly propagated from an + upstream guardrail provider response (401 bad key, 408 timeout, 429 rate + limit, or a raw upstream status), which are technical failures, not + blocks, so they stay guardrail_failed_to_respond. """ if isinstance(e, ModifyResponseException): return True @@ -1060,7 +1078,11 @@ class CustomGuardrail(CustomLogger): ), ): return True - if HTTPException is not None and isinstance(e, HTTPException) and e.status_code == 400: + if ( + HTTPException is not None + and isinstance(e, HTTPException) + and e.status_code in _GUARDRAIL_BLOCK_STATUS_CODES + ): return True return False @@ -1160,6 +1182,7 @@ class CustomGuardrail(CustomLogger): call_type == CallTypes.completion.value or call_type == CallTypes.acompletion.value or call_type == CallTypes.anthropic_messages.value + or call_type == CallTypes.call_mcp_tool.value ): return data.get("messages") @@ -1211,7 +1234,7 @@ def _sync_guardrail_info_to_logging_obj(request_data: dict, logging_obj: object) """ if logging_obj is None: return - meta_src = request_data.get("metadata") or request_data.get("litellm_metadata") or {} + meta_src = request_data.get(get_metadata_variable_name_from_kwargs(request_data)) or {} slg_info = meta_src.get("standard_logging_guardrail_information") if not slg_info: return @@ -1238,8 +1261,20 @@ def log_guardrail_information(func): (structured detections, tracing detail) than this decorator's "allow"/"mask"/raw-response default. To avoid double-recording in that case (which would emit two spans, two Datadog records, two spend-log - entries, etc.), snapshot the entry count before invocation: if the - wrapped function already appended its own entry, skip the auto-record. + entries, etc.), a context-local flag records whether the wrapped function + appended its own entry; if so, the auto-record is skipped. The flag is a + ``ContextVar`` rather than a count of entries in the shared ``request_data`` + so it stays correct when guardrails run concurrently (asyncio copies the + context into each gathered task): counting shared entries would let one + guardrail's append hide another guardrail's missing record. + + A guardrail that only records an entry when it actually runs (e.g. + ``HeadroomGuardrail``, which returns the inputs untouched on an endpoint + whose payload it cannot act on) sets ``records_own_guardrail_information = + True`` so the auto-record is skipped even on the return paths where it + recorded nothing; otherwise a no-op early return would be logged as an + "allow"/"success" run even though the guardrail did nothing. The exception + branch below still records so a genuine failure is not lost. """ import functools import inspect @@ -1259,16 +1294,6 @@ def log_guardrail_information(func): return GuardrailEventHooks.post_call return None - def _count_recorded_guardrail_entries(request_data: dict) -> int: - total = 0 - for container_key in ("metadata", "litellm_metadata"): - container = request_data.get(container_key) - if isinstance(container, dict): - entries = container.get("standard_logging_guardrail_information") - if isinstance(entries, list): - total += len(entries) - return total - @functools.wraps(func) async def async_wrapper(*args, **kwargs): start_time = datetime.now() # Move start_time inside the wrapper @@ -1282,10 +1307,10 @@ def log_guardrail_information(func): original_inputs = kwargs.get("inputs") logging_obj = kwargs.get("logging_obj") - entries_before = _count_recorded_guardrail_entries(request_data) + self_recorded_token = _guardrail_self_recorded.set(False) try: response = await func(*args, **kwargs) - if _count_recorded_guardrail_entries(request_data) > entries_before: + if self.records_own_guardrail_information or _guardrail_self_recorded.get(): return response return self._process_response( response=response, @@ -1297,7 +1322,7 @@ def log_guardrail_information(func): original_inputs=original_inputs, ) except Exception as e: - if _count_recorded_guardrail_entries(request_data) > entries_before: + if _guardrail_self_recorded.get(): raise return self._process_error( e=e, @@ -1308,6 +1333,7 @@ def log_guardrail_information(func): event_type=event_type, ) finally: + _guardrail_self_recorded.reset(self_recorded_token) _sync_guardrail_info_to_logging_obj(request_data, logging_obj) @functools.wraps(func) @@ -1323,10 +1349,10 @@ def log_guardrail_information(func): original_inputs = kwargs.get("inputs") logging_obj = kwargs.get("logging_obj") - entries_before = _count_recorded_guardrail_entries(request_data) + self_recorded_token = _guardrail_self_recorded.set(False) try: response = func(*args, **kwargs) - if _count_recorded_guardrail_entries(request_data) > entries_before: + if self.records_own_guardrail_information or _guardrail_self_recorded.get(): return response return self._process_response( response=response, @@ -1336,7 +1362,7 @@ def log_guardrail_information(func): original_inputs=original_inputs, ) except Exception as e: - if _count_recorded_guardrail_entries(request_data) > entries_before: + if _guardrail_self_recorded.get(): raise return self._process_error( e=e, @@ -1345,6 +1371,7 @@ def log_guardrail_information(func): event_type=event_type, ) finally: + _guardrail_self_recorded.reset(self_recorded_token) _sync_guardrail_info_to_logging_obj(request_data, logging_obj) @functools.wraps(func) diff --git a/litellm/integrations/custom_logger.py b/litellm/integrations/custom_logger.py index 108928871b0..8b831b55da3 100644 --- a/litellm/integrations/custom_logger.py +++ b/litellm/integrations/custom_logger.py @@ -519,7 +519,13 @@ class CustomLogger: # https://docs.litellm.ai/docs/observability/custom_callbac """ This log gets called after the MCP tool call is made. - Useful if you want to modiy the standard logging payload after the MCP tool call is made. + Useful if you want to modify the standard logging payload after the MCP tool call is made. + + To change what the caller sends back to the MCP client, mutate ``response_obj`` + in place: every call site discards the returned object, because the + dispatcher unwraps it to ``mcp_tool_call_response`` (a raw content list, not + a ``CallToolResult``) which the tool-call paths cannot forward. Guardrails + that mask or reject tool output should use ``post_mcp_call`` instead. """ return None diff --git a/litellm/integrations/langsmith.py b/litellm/integrations/langsmith.py index 18c4baccd51..565ea833768 100644 --- a/litellm/integrations/langsmith.py +++ b/litellm/integrations/langsmith.py @@ -133,6 +133,15 @@ class LangsmithLogger(CustomBatchLogger): "dotted_order": metadata.get("dotted_order", None), } + def _redact_metadata(self, metadata: dict) -> dict: + # helper is shallow; also scrub nested requester_metadata since + # LangSmith forwards the whole dict into the run + redacted = redact_user_api_key_info(metadata=dict(metadata)) + nested = redacted.get("requester_metadata") + if isinstance(nested, dict): + redacted["requester_metadata"] = redact_user_api_key_info(metadata=nested) + return redacted + def _build_extra_metadata(self, metadata: Dict): extra_metadata = dict(metadata) requester_metadata = extra_metadata.get("requester_metadata") @@ -141,13 +150,7 @@ class LangsmithLogger(CustomBatchLogger): if key in requester_metadata and key not in extra_metadata: extra_metadata[key] = requester_metadata[key] - # helper is shallow; also scrub nested requester_metadata since - # LangSmith forwards the whole dict into `extra` - extra_metadata = redact_user_api_key_info(metadata=extra_metadata) - nested = extra_metadata.get("requester_metadata") - if isinstance(nested, dict): - extra_metadata["requester_metadata"] = redact_user_api_key_info(metadata=nested) - return extra_metadata + return self._redact_metadata(extra_metadata) def _build_outputs_with_usage(self, payload: StandardLoggingPayload) -> Dict[str, Any]: response = payload["response"] @@ -200,12 +203,13 @@ class LangsmithLogger(CustomBatchLogger): metadata = payload["metadata"] extra_metadata = self._build_extra_metadata(dict(metadata)) + inputs = {**payload, "metadata": self._redact_metadata(dict(metadata))} outputs = self._build_outputs_with_usage(payload) data = { "name": fields["run_name"], "run_type": "llm", - "inputs": payload, + "inputs": inputs, "outputs": outputs, "session_name": fields["project_name"], "start_time": payload["startTime"], diff --git a/litellm/integrations/opentelemetry.py b/litellm/integrations/opentelemetry.py index fea55cd1db4..60eb960be4e 100644 --- a/litellm/integrations/opentelemetry.py +++ b/litellm/integrations/opentelemetry.py @@ -27,6 +27,7 @@ from litellm.integrations.opentelemetry_utils.gen_ai_semconv import ( OTELSemconvCategory, parse_semconv_opt_in, ) +from litellm.integrations.otel.model.semconv import Metric from litellm.litellm_core_utils.safe_json_dumps import safe_dumps from litellm.litellm_core_utils.secret_redaction import redact_string from litellm.secret_managers.main import get_secret_bool, str_to_bool @@ -117,6 +118,7 @@ TOKEN_TYPE_ATTRIBUTE: str = "gen_ai.token.type" VALID_METRIC_ATTRIBUTE_NAMES: FrozenSet[str] = frozenset( ( "gen_ai.operation.name", + "gen_ai.provider.name", "gen_ai.system", "gen_ai.request.model", "gen_ai.framework", @@ -597,32 +599,32 @@ class OpenTelemetry(OTELGenAISemconvMixin, CustomLogger): meter = meter_provider.get_meter(__name__) self._operation_duration_histogram = meter.create_histogram( - name="gen_ai.client.operation.duration", # Replace with semconv constant in otel 1.38 + name=Metric.OPERATION_DURATION, description="GenAI operation duration", unit="s", ) self._token_usage_histogram = meter.create_histogram( - name="gen_ai.client.token.usage", # Replace with semconv constant in otel 1.38 + name=Metric.TOKEN_USAGE, description="GenAI token usage", unit="{token}", ) self._cost_histogram = meter.create_histogram( - name="gen_ai.client.token.cost", + name=Metric.TOKEN_COST, description="GenAI request cost", unit="USD", ) self._time_to_first_token_histogram = meter.create_histogram( - name="gen_ai.client.response.time_to_first_token", + name=Metric.TIME_TO_FIRST_TOKEN, description="Time to first token for streaming requests", unit="s", ) self._time_per_output_token_histogram = meter.create_histogram( - name="gen_ai.client.response.time_per_output_token", + name=Metric.TIME_PER_OUTPUT_TOKEN, description="Average time per output token (generation time / completion tokens)", unit="s", ) self._response_duration_histogram = meter.create_histogram( - name="gen_ai.client.response.duration", + name=Metric.RESPONSE_DURATION, description="Total LLM API generation time (excludes LiteLLM overhead)", unit="s", ) @@ -883,8 +885,8 @@ class OpenTelemetry(OTELGenAISemconvMixin, CustomLogger): request_data: dict, parent_span: Optional[Any], ) -> None: - """Emit ``guardrail`` spans from ``request_data["metadata"] - ["standard_logging_guardrail_information"]``. + """Emit ``guardrail`` spans from the request's proxy-internal metadata bucket + (``standard_logging_guardrail_information``). Routed through ``_create_guardrail_span`` so the dedupe state in ``_otel_internal`` is honoured — if ``_handle_failure`` already @@ -892,7 +894,12 @@ class OpenTelemetry(OTELGenAISemconvMixin, CustomLogger): """ from opentelemetry import trace as _trace - metadata = (request_data or {}).get("metadata") or {} + from litellm.litellm_core_utils.core_helpers import ( + get_metadata_variable_name_from_kwargs, + ) + + request_data = request_data or {} + metadata = request_data.get(get_metadata_variable_name_from_kwargs(request_data)) or {} guardrail_information = metadata.get("standard_logging_guardrail_information") if not guardrail_information: return @@ -2975,10 +2982,12 @@ class OpenTelemetry(OTELGenAISemconvMixin, CustomLogger): def _get_metric_reader(self): """ Get the appropriate metric reader based on the configuration. + + Histograms keep the SDK's default cumulative temporality: Prometheus-backed + OTLP receivers reject delta histograms and drop the whole batch, while + backends that prefer delta still accept cumulative. """ - from opentelemetry.sdk.metrics import Histogram from opentelemetry.sdk.metrics.export import ( - AggregationTemporality, ConsoleMetricExporter, PeriodicExportingMetricReader, ) @@ -3009,7 +3018,6 @@ class OpenTelemetry(OTELGenAISemconvMixin, CustomLogger): exporter = OTLPMetricExporter( endpoint=normalized_endpoint, headers=_split_otel_headers, - preferred_temporality={Histogram: AggregationTemporality.DELTA}, ) return PeriodicExportingMetricReader(exporter, export_interval_millis=5000) @@ -3027,7 +3035,6 @@ class OpenTelemetry(OTELGenAISemconvMixin, CustomLogger): exporter = OTLPMetricExporter( endpoint=normalized_endpoint, headers=_split_otel_headers, - preferred_temporality={Histogram: AggregationTemporality.DELTA}, ) return PeriodicExportingMetricReader(exporter, export_interval_millis=5000) diff --git a/litellm/integrations/otel/README.md b/litellm/integrations/otel/README.md index 3038bdb90b2..338afe04e5e 100644 --- a/litellm/integrations/otel/README.md +++ b/litellm/integrations/otel/README.md @@ -222,7 +222,29 @@ lives in [`plumbing/`](./plumbing): otherwise the operator's globally configured `MeterProvider` is reused so its readers/exporters receive them alongside the server metrics, and one is built and registered as the global only when none is set (mirroring how V2 owns trace - export). + export). A **failed** call records `gen_ai.client.operation.duration` too, + carrying the semconv `error.type` (the mapped provider exception's class name), + so the histogram covers the whole traffic and failure-rate panels are buildable; + the other five instruments describe a completed generation and are skipped + rather than filled with a fabricated zero. `error.type` is stamped after the + cardinality filter, so an `otel.attributes` list cannot merge the failure series + back into the success series. A proxy-gate rejection (auth / rate limit) records + nothing, for the same reason it gets no span: no upstream call happened. + Both paths cap their attributes at `METRIC_ATTRIBUTE_CEILING` before the + operator's own `otel.attributes` filter runs, so the filter can narrow the set + but never widen it. The ceiling is what keeps series count bounded by the + deployment's own key/team/user/deployment count instead of by its traffic: a + label value that moves per request mints a time series per request, which both + bills per request on a hosted backend and leaves a histogram that cannot be + aggregated. So client-supplied and per-request metadata (`requester_metadata`, + `spend_logs_metadata`, `user_api_key_end_user_id`, `requester_ip_address`) is + metric-ineligible and stays on the span, where cardinality is free, and the + `hidden_params` label carries only `model_id`, the deployment identity a + per-deployment panel joins on. `api_base` is excluded despite naming the same + deployment, because it is a documented per-call parameter and so is caller-chosen + in SDK use. Because the shared validator accepts every span attribute name, a + filter that names a metric-ineligible one logs a warning once when the filter + resolves rather than silently emitting nothing for it. - [`events.py`](./plumbing/events.py) — GenAI client events. Gated on `enable_events` (`LITELLM_OTEL_INTEGRATION_ENABLE_EVENTS`), a failed LLM call records the semconv `gen_ai.client.operation.exception` log event at severity @@ -267,7 +289,10 @@ lives in [`plumbing/`](./plumbing): - **A new attribute vocabulary for a backend**: add a mapper in `mappers/` (a class with a `map(data) -> AttributeMap` method, typically built from - `key -> extractor` tables) and register it in `mappers/__init__._MAPPER_BY_NAME`. + `key -> extractor` tables) and register it in `mappers/__init__._PLAIN_MAPPERS`. + If it spells declared tool definitions out per index, register it in + `_TOOL_DEFINITION_MAPPERS` instead and take the shared attribute budget in its + constructor, so the family stays bounded span-wide rather than per vocabulary. - **A new integration**: add a preset in `presets/` that returns an `OpenTelemetryV2Config`, and register it in `presets/__init__.PRESET_BY_CALLBACK`. If it supports dynamic credentials, add a header builder to diff --git a/litellm/integrations/otel/logger.py b/litellm/integrations/otel/logger.py index 778f5342e90..b8908696547 100644 --- a/litellm/integrations/otel/logger.py +++ b/litellm/integrations/otel/logger.py @@ -17,6 +17,7 @@ from litellm.integrations.otel.model.baggage import promoted_baggage from litellm.integrations.otel.model.config import OpenTelemetryV2Config from litellm.integrations.otel.plumbing.context import ( is_recordable_span, + mcp_message_transport_span, request_root_span, resolve_mcp_span_context, resolve_parent_context, @@ -280,13 +281,29 @@ class OpenTelemetryV2(CustomLogger): self._record_metrics(kwargs, response_obj, start_time, end_time) def _record_metrics(self, kwargs, response_obj, start_time, end_time) -> None: - """Record the GenAI metrics for a successful LLM call. Best-effort: a - recording failure (e.g. a malformed payload) must never break the span - close or the request itself.""" + """Record the GenAI metrics for a successful LLM call.""" + self._guarded_record(lambda recorder: recorder.record(kwargs, response_obj, start_time, end_time)) + + def _record_failure_metrics(self, kwargs, start_time, end_time) -> None: + """Record the GenAI metrics for a failed LLM call, so the duration + histogram covers the whole traffic rather than only what survived. + + A synthetic proxy-gate log (auth / rate-limit rejection) is skipped for the + same reason it gets no span: no upstream call happened, so its duration is + not a GenAI operation's duration and would pull the histogram down.""" + if LLMCallEvent.from_dict(kwargs).is_no_upstream_call: + return + self._guarded_record(lambda recorder: recorder.record_failure(kwargs, start_time, end_time)) + + def _guarded_record(self, record: "Callable[[GenAIMetricRecorder], None]") -> None: + """Run one metric recording. Best-effort: a recording failure (e.g. a + malformed payload) must never break the span close or the request itself. A + misconfigured attribute filter is operator-fixable, so it is surfaced once + at ERROR instead of being swallowed.""" if self._metrics_recorder is None: return try: - self._metrics_recorder.record(kwargs, response_obj, start_time, end_time) + record(self._metrics_recorder) except ValueError as exc: if not self._metric_filter_error_logged: verbose_logger.error( @@ -303,6 +320,7 @@ class OpenTelemetryV2(CustomLogger): if self._emit_mcp_list_tools(kwargs, start_time, end_time): return self._close_llm_call(kwargs, start_time, end_time) + self._record_failure_metrics(kwargs, start_time, end_time) def _seed_identity_baggage(self, identity: RequestIdentity, model: str | None, context: Context) -> Context: """Seed authenticated request-identity Baggage onto ``context`` so the Baggage @@ -641,8 +659,14 @@ class OpenTelemetryV2(CustomLogger): endpoint, auth failure), so the failed request carries the same error keys a failed LLM call does. v1's ``OpenTelemetry`` implemented this same hook; v2 lost it when it stopped subclassing ``OpenTelemetry``, which is the - LIT-4179 regression for pre-call failures.""" - span = request_root_span() or user_api_key_dict.parent_otel_span + LIT-4179 regression for pre-call failures. + + An MCP message is handled on the session's task, where the request-root + anchor is whatever request opened the session, so prefer the transport the + gateway published for this specific message. Without that, a failed tool + call aimed its error at the ``initialize`` request's finished span and the + SDK dropped it, leaving the POST that actually failed unmarked.""" + span = mcp_message_transport_span() or request_root_span() or user_api_key_dict.parent_otel_span if span is None or not is_recordable_span(span): return None stamp_error(span, _span_error_from_exception(original_exception, traceback_str=traceback_str)) diff --git a/litellm/integrations/otel/mappers/__init__.py b/litellm/integrations/otel/mappers/__init__.py index b0c1d7019db..55504c5e8bf 100644 --- a/litellm/integrations/otel/mappers/__init__.py +++ b/litellm/integrations/otel/mappers/__init__.py @@ -18,13 +18,19 @@ from litellm.integrations.otel.mappers.langfuse import LangfuseMapper from litellm.integrations.otel.mappers.langtrace import LangtraceMapper from litellm.integrations.otel.mappers.legacy import LegacyMapper from litellm.integrations.otel.mappers.openinference import OpenInferenceMapper +from litellm.integrations.otel.mappers.utils import tool_attr_budget from litellm.integrations.otel.mappers.weave import WeaveMapper -# Registry keyed by ``config.mapper_names`` entries. -_MAPPER_BY_NAME: dict[str, Callable[[], AttributeMapper]] = { +# Registries keyed by ``config.mapper_names`` entries, split by whether the +# vocabulary spells declared tool definitions out per index. Those share one +# span-wide attribute ceiling, so resolution has to know how many of them are +# active before it can build them. +_TOOL_DEFINITION_MAPPERS: dict[str, Callable[[int], AttributeMapper]] = { "genai": GenAIMapper, "legacy": LegacyMapper, "openinference": OpenInferenceMapper, +} +_PLAIN_MAPPERS: dict[str, Callable[[], AttributeMapper]] = { "langfuse": LangfuseMapper, "weave": WeaveMapper, "langtrace": LangtraceMapper, @@ -33,13 +39,19 @@ _MAPPER_BY_NAME: dict[str, Callable[[], AttributeMapper]] = { def resolve_mappers(names: Iterable[str]) -> list[AttributeMapper]: """Resolve mapper names to instances. Unknown names raise ``ValueError``.""" - out: list[AttributeMapper] = [] - for name in names: - factory = _MAPPER_BY_NAME.get(name) - if factory is None: - raise ValueError(f"unknown mapper name {name!r}; known: {sorted(_MAPPER_BY_NAME)}") - out.append(factory()) - return out + ordered = tuple(names) + for name in ordered: + if name not in _TOOL_DEFINITION_MAPPERS and name not in _PLAIN_MAPPERS: + known = sorted((*_TOOL_DEFINITION_MAPPERS, *_PLAIN_MAPPERS)) + raise ValueError(f"unknown mapper name {name!r}; known: {known}") + # Distinct vocabularies each write the tool family under their own keys, so + # the ceiling is split by how many of them are configured. Repeating a name + # rewrites the same keys, so only distinct ones count. + budget = tool_attr_budget(len({*ordered} & _TOOL_DEFINITION_MAPPERS.keys())) + return [ + _TOOL_DEFINITION_MAPPERS[name](budget) if name in _TOOL_DEFINITION_MAPPERS else _PLAIN_MAPPERS[name]() + for name in ordered + ] __all__ = [ diff --git a/litellm/integrations/otel/mappers/genai.py b/litellm/integrations/otel/mappers/genai.py index f568afa9e3e..70414734b72 100644 --- a/litellm/integrations/otel/mappers/genai.py +++ b/litellm/integrations/otel/mappers/genai.py @@ -11,10 +11,11 @@ from typing import Callable from litellm.integrations.otel.mappers.base import AttributeMap, AttrValue, SpanData from litellm.integrations.otel.mappers.utils import ( + MAX_TOOL_DEFINITION_ATTRS_PER_SPAN, collect, - drop_none, output_messages, serialize_messages, + tool_definition_attrs, ) from litellm.integrations.otel.model.payloads import ( GuardrailSpanData, @@ -135,6 +136,9 @@ class GenAIMapper: LiteLLM.SERVICE_CALL_TYPE: lambda d: d.call_type, } + def __init__(self, tool_attr_budget: int = MAX_TOOL_DEFINITION_ATTRS_PER_SPAN) -> None: + self._tool_attr_budget = tool_attr_budget + def map(self, data: SpanData) -> AttributeMap: match data: case LLMCallSpanData(): @@ -150,18 +154,18 @@ class GenAIMapper: case _: return {} - @classmethod - def _llm_call(cls, data: LLMCallSpanData) -> AttributeMap: - attrs = collect(cls._LLM_CALL_ATTRS, data) - attrs.update( - drop_none( - { - f"gen_ai.tool.{idx}.{suffix}": extract(tool) - for idx, tool in enumerate(data.tools) - for suffix, extract in cls._TOOL_ATTRS.items() - } + def _llm_call(self, data: LLMCallSpanData) -> AttributeMap: + attrs = collect(self._LLM_CALL_ATTRS, data) + if data.tools: + attrs[LiteLLM.TOOLS_DECLARED] = len(data.tools) + attrs.update( + tool_definition_attrs( + lambda idx, suffix: f"gen_ai.tool.{idx}.{suffix}", + data.tools, + self._TOOL_ATTRS, + self._tool_attr_budget, + ) ) - ) return attrs @classmethod diff --git a/litellm/integrations/otel/mappers/legacy.py b/litellm/integrations/otel/mappers/legacy.py index 57dc7ed3632..f17a62828e7 100644 --- a/litellm/integrations/otel/mappers/legacy.py +++ b/litellm/integrations/otel/mappers/legacy.py @@ -12,7 +12,11 @@ Like ``GenAIMapper``, each span kind declares its schema as a flat from typing import Callable, Final from litellm.integrations.otel.mappers.base import AttributeMap, AttrValue, SpanData -from litellm.integrations.otel.mappers.utils import collect, drop_none +from litellm.integrations.otel.mappers.utils import ( + MAX_TOOL_DEFINITION_ATTRS_PER_SPAN, + collect, + tool_definition_attrs, +) from litellm.integrations.otel.model.payloads import ( LLMCallSpanData, ServiceSpanData, @@ -63,6 +67,9 @@ class LegacyMapper: _LEGACY_ERROR: lambda d: d.error.message if d.error is not None and d.error.message else None, } + def __init__(self, tool_attr_budget: int = MAX_TOOL_DEFINITION_ATTRS_PER_SPAN) -> None: + self._tool_attr_budget = tool_attr_budget + def map(self, data: SpanData) -> AttributeMap: match data: case LLMCallSpanData(): @@ -72,16 +79,14 @@ class LegacyMapper: case _: return {} - @classmethod - def _llm_call(cls, data: LLMCallSpanData) -> AttributeMap: - attrs = collect(cls._LLM_CALL_ATTRS, data) + def _llm_call(self, data: LLMCallSpanData) -> AttributeMap: + attrs = collect(self._LLM_CALL_ATTRS, data) attrs.update( - drop_none( - { - f"llm.request.functions.{idx}.{suffix}": extract(tool) - for idx, tool in enumerate(data.tools) - for suffix, extract in cls._TOOL_ATTRS.items() - } + tool_definition_attrs( + lambda idx, suffix: f"llm.request.functions.{idx}.{suffix}", + data.tools, + self._TOOL_ATTRS, + self._tool_attr_budget, ) ) return attrs diff --git a/litellm/integrations/otel/mappers/openinference.py b/litellm/integrations/otel/mappers/openinference.py index dab9a616979..87c4d0d6484 100644 --- a/litellm/integrations/otel/mappers/openinference.py +++ b/litellm/integrations/otel/mappers/openinference.py @@ -13,9 +13,11 @@ from litellm.integrations.otel.mappers.base import AttributeMap, AttrValue, Span from litellm.integrations.otel.mappers.utils import ( collect, drop_none, + MAX_TOOL_DEFINITION_ATTRS_PER_SPAN, json_if, message_content, output_messages, + tool_definition_attrs, ) from litellm.integrations.otel.model.payloads import ( LLMCallSpanData, @@ -70,6 +72,9 @@ class OpenInferenceMapper: ), } + def __init__(self, tool_attr_budget: int = MAX_TOOL_DEFINITION_ATTRS_PER_SPAN) -> None: + self._tool_attr_budget = tool_attr_budget + def map(self, data: SpanData) -> AttributeMap: match data: case LLMCallSpanData(): @@ -77,14 +82,13 @@ class OpenInferenceMapper: case _: return {} - @classmethod - def _llm_call(cls, data: LLMCallSpanData) -> AttributeMap: + def _llm_call(self, data: LLMCallSpanData) -> AttributeMap: return { - **collect(cls._LLM_CALL_ATTRS, data), - **collect(cls._BLOB_ATTRS, data), - **cls._messages("llm.input_messages", "input.value", data.messages_in), - **cls._messages("llm.output_messages", "output.value", output_messages(data)), - **cls._tools(data), + **collect(self._LLM_CALL_ATTRS, data), + **collect(self._BLOB_ATTRS, data), + **self._messages("llm.input_messages", "input.value", data.messages_in), + **self._messages("llm.output_messages", "output.value", output_messages(data)), + **self._tools(data), } @staticmethod @@ -108,12 +112,10 @@ class OpenInferenceMapper: attrs[value_key] = json.dumps([{"role": role, "content": content} for role, content in parsed]) return attrs - @classmethod - def _tools(cls, data: LLMCallSpanData) -> AttributeMap: - return drop_none( - { - f"llm.tools.{idx}.{suffix}": extract(tool) - for idx, tool in enumerate(data.tools) - for suffix, extract in cls._TOOL_ATTRS.items() - } + def _tools(self, data: LLMCallSpanData) -> AttributeMap: + return tool_definition_attrs( + lambda idx, suffix: f"llm.tools.{idx}.{suffix}", + data.tools, + self._TOOL_ATTRS, + self._tool_attr_budget, ) diff --git a/litellm/integrations/otel/mappers/utils.py b/litellm/integrations/otel/mappers/utils.py index a91e59e4ab8..cbdb60f42c9 100644 --- a/litellm/integrations/otel/mappers/utils.py +++ b/litellm/integrations/otel/mappers/utils.py @@ -6,10 +6,34 @@ they live in one place. """ import json -from typing import Callable, Mapping, Sequence +from typing import Callable, Final, Mapping, Sequence from litellm.integrations.otel.mappers.base import AttributeMap, AttrValue -from litellm.integrations.otel.model.payloads import LLMCallSpanData +from litellm.integrations.otel.model.payloads import LLMCallSpanData, ToolDefinition + +DEFAULT_SPAN_ATTRIBUTE_LIMIT: Final = 128 +"""The OTel SDK's default per-span attribute count limit.""" + +MAX_TOOL_DEFINITION_ATTRS_PER_SPAN: Final = DEFAULT_SPAN_ATTRIBUTE_LIMIT // 4 +"""Span-wide ceiling on attributes spent spelling out declared tool definitions. + +Tool definitions are an unbounded attribute family: one entry per declared +tool, per field, per active vocabulary. Agentic clients declare hundreds, which +overruns the span attribute limit. That limit evicts oldest-first, so an +uncapped family silently destroys the core ``gen_ai.*`` attributes written +before it. + +The ceiling is span-wide rather than per-mapper because several vocabularies +can be active at once and each spells the same tools out under its own keys, so +a per-mapper allowance multiplies by the number of vocabularies and reaches the +limit again. Reserving a quarter of the span for tool detail leaves the rest to +core telemetry no matter how many vocabularies are configured. +""" + + +def tool_attr_budget(vocabularies: int) -> int: + """Split the span-wide tool-definition ceiling across active vocabularies.""" + return MAX_TOOL_DEFINITION_ATTRS_PER_SPAN // max(vocabularies, 1) def drop_none(values: Mapping[str, AttrValue | None]) -> AttributeMap: @@ -17,6 +41,29 @@ def drop_none(values: Mapping[str, AttrValue | None]) -> AttributeMap: return {k: v for k, v in values.items() if v is not None} +def tool_definition_attrs( + key_for: Callable[[int, str], str], + tools: Sequence[ToolDefinition], + extractors: Mapping[str, Callable[[ToolDefinition], AttrValue | None]], + attr_budget: int, +) -> AttributeMap: + """Per-index attributes for as many tools as ``attr_budget`` affords. + + ``key_for`` builds a vocabulary's key from the tool's index and the field + name, so each mapper keeps its own naming while sharing the budget. One tool + always keeps its detail, so the family stays legible even when many + vocabularies split the ceiling. + """ + max_tools = max(attr_budget // max(len(extractors), 1), 1) + return drop_none( + { + key_for(idx, suffix): extract(tool) + for idx, tool in enumerate(tools[:max_tools]) + for suffix, extract in extractors.items() + } + ) + + def collect(table: Mapping[str, Callable], source: object) -> AttributeMap: """Apply an extractor table to ``source``, dropping ``None`` results.""" return drop_none({key: extract(source) for key, extract in table.items()}) diff --git a/litellm/integrations/otel/model/semconv.py b/litellm/integrations/otel/model/semconv.py index 44b2f7e0488..3b38b3d3655 100644 --- a/litellm/integrations/otel/model/semconv.py +++ b/litellm/integrations/otel/model/semconv.py @@ -6,17 +6,30 @@ without a semconv equivalent lives under the ``litellm.*`` vendor namespace. from enum import Enum from typing import Final +from litellm._logging import verbose_logger + class GenAIOperation(str, Enum): - """Values for ``gen_ai.operation.name``.""" + """Values for ``gen_ai.operation.name``. + + The first block is the convention's own vocabulary. The ``LITELLM_`` members + are vendor values for operations the convention names nothing for; its note + on this attribute directs instrumentation to use a system-specific name in + exactly that case, the same allowance :func:`resolve_provider` relies on for + unmapped providers. They stay under the ``litellm.`` prefix so a value the + convention adds later can never collide with one of ours. + """ CHAT = "chat" TEXT_COMPLETION = "text_completion" EMBEDDINGS = "embeddings" GENERATE_CONTENT = "generate_content" + RETRIEVAL = "retrieval" # vector-store search / RAG query spans CREATE_AGENT = "create_agent" # reserved for future agent spans - INVOKE_AGENT = "invoke_agent" # reserved for future agent spans + INVOKE_AGENT = "invoke_agent" # agent (A2A) message spans EXECUTE_TOOL = "execute_tool" # MCP tool-call spans + LITELLM_VECTOR_STORE_MANAGEMENT = "litellm.vector_store_management" + LITELLM_VECTOR_STORE_FILE_MANAGEMENT = "litellm.vector_store_file_management" class GenAIProvider(str, Enum): @@ -49,11 +62,17 @@ class MCPMethod(str, Enum): class GenAI: - """Canonical OTel GenAI span-attribute keys.""" + """Canonical OTel GenAI attribute keys. + + ``SYSTEM`` is the one exception: the convention deprecated it in favor of + ``PROVIDER_NAME``, and it survives here only so already-shipped series keep + resolving for consumers that query it. Nothing new should use it. + """ # request OPERATION_NAME: Final = "gen_ai.operation.name" PROVIDER_NAME: Final = "gen_ai.provider.name" + SYSTEM: Final = "gen_ai.system" REQUEST_MODEL: Final = "gen_ai.request.model" REQUEST_TEMPERATURE: Final = "gen_ai.request.temperature" REQUEST_TOP_P: Final = "gen_ai.request.top_p" @@ -233,6 +252,7 @@ class LiteLLM: # ``litellm_params.model``), distinct from the user-facing ``gen_ai.request.model``. PROVIDER_MODEL: Final = "litellm.provider.model" REQUEST_STREAMING: Final = "litellm.request.streaming" + TOOLS_DECLARED: Final = "litellm.request.tools.declared" GUARDRAIL_NAME: Final = "litellm.guardrail.name" GUARDRAIL_MODE: Final = "litellm.guardrail.mode" GUARDRAIL_STATUS: Final = "litellm.guardrail.status" @@ -257,13 +277,27 @@ class LiteLLM: class Metric: - """GenAI metric instrument names.""" + """GenAI metric instrument names. + + Every name here that a convention or a backend defines uses that name, so a + consumer charting GenAI telemetry finds litellm's series where it looks for + them. ``TOKEN_USAGE``, ``OPERATION_DURATION``, ``TIME_TO_FIRST_TOKEN`` and + ``TIME_PER_OUTPUT_TOKEN`` are semconv instruments, defined in the GenAI + conventions; the ``gen_ai.client.response.*`` spellings litellm used for the + latter two are not conventions at all, so nothing downstream could chart + them. Cost has no semconv instrument, so it takes ``gen_ai.usage.cost``, the + name backends already query for spend. + + ``RESPONSE_DURATION`` keeps its vendor spelling deliberately: the closest + convention, ``gen_ai.server.request.duration``, would collide in meaning with + ``OPERATION_DURATION``, which litellm already emits for the whole operation. + """ TOKEN_USAGE: Final = "gen_ai.client.token.usage" OPERATION_DURATION: Final = "gen_ai.client.operation.duration" - TOKEN_COST: Final = "gen_ai.client.token.cost" - TIME_TO_FIRST_TOKEN: Final = "gen_ai.client.response.time_to_first_token" - TIME_PER_OUTPUT_TOKEN: Final = "gen_ai.client.response.time_per_output_token" + TOKEN_COST: Final = "gen_ai.usage.cost" + TIME_TO_FIRST_TOKEN: Final = "gen_ai.server.time_to_first_token" + TIME_PER_OUTPUT_TOKEN: Final = "gen_ai.server.time_per_output_token" RESPONSE_DURATION: Final = "gen_ai.client.response.duration" @@ -301,6 +335,35 @@ _OPERATION_BY_CALL_TYPE: dict[str, GenAIOperation] = { "responses": GenAIOperation.CHAT, "aresponses": GenAIOperation.CHAT, "call_mcp_tool": GenAIOperation.EXECUTE_TOOL, + "vector_store_search": GenAIOperation.RETRIEVAL, + "avector_store_search": GenAIOperation.RETRIEVAL, + "query": GenAIOperation.RETRIEVAL, + "aquery": GenAIOperation.RETRIEVAL, + "send_message": GenAIOperation.INVOKE_AGENT, + "asend_message": GenAIOperation.INVOKE_AGENT, + "asend_message_streaming": GenAIOperation.INVOKE_AGENT, + "vector_store_create": GenAIOperation.LITELLM_VECTOR_STORE_MANAGEMENT, + "avector_store_create": GenAIOperation.LITELLM_VECTOR_STORE_MANAGEMENT, + "vector_store_retrieve": GenAIOperation.LITELLM_VECTOR_STORE_MANAGEMENT, + "avector_store_retrieve": GenAIOperation.LITELLM_VECTOR_STORE_MANAGEMENT, + "vector_store_list": GenAIOperation.LITELLM_VECTOR_STORE_MANAGEMENT, + "avector_store_list": GenAIOperation.LITELLM_VECTOR_STORE_MANAGEMENT, + "vector_store_update": GenAIOperation.LITELLM_VECTOR_STORE_MANAGEMENT, + "avector_store_update": GenAIOperation.LITELLM_VECTOR_STORE_MANAGEMENT, + "vector_store_delete": GenAIOperation.LITELLM_VECTOR_STORE_MANAGEMENT, + "avector_store_delete": GenAIOperation.LITELLM_VECTOR_STORE_MANAGEMENT, + "vector_store_file_create": GenAIOperation.LITELLM_VECTOR_STORE_FILE_MANAGEMENT, + "avector_store_file_create": GenAIOperation.LITELLM_VECTOR_STORE_FILE_MANAGEMENT, + "vector_store_file_list": GenAIOperation.LITELLM_VECTOR_STORE_FILE_MANAGEMENT, + "avector_store_file_list": GenAIOperation.LITELLM_VECTOR_STORE_FILE_MANAGEMENT, + "vector_store_file_retrieve": GenAIOperation.LITELLM_VECTOR_STORE_FILE_MANAGEMENT, + "avector_store_file_retrieve": GenAIOperation.LITELLM_VECTOR_STORE_FILE_MANAGEMENT, + "vector_store_file_content": GenAIOperation.LITELLM_VECTOR_STORE_FILE_MANAGEMENT, + "avector_store_file_content": GenAIOperation.LITELLM_VECTOR_STORE_FILE_MANAGEMENT, + "vector_store_file_update": GenAIOperation.LITELLM_VECTOR_STORE_FILE_MANAGEMENT, + "avector_store_file_update": GenAIOperation.LITELLM_VECTOR_STORE_FILE_MANAGEMENT, + "vector_store_file_delete": GenAIOperation.LITELLM_VECTOR_STORE_FILE_MANAGEMENT, + "avector_store_file_delete": GenAIOperation.LITELLM_VECTOR_STORE_FILE_MANAGEMENT, } @@ -317,7 +380,21 @@ def resolve_provider(custom_llm_provider: str | None) -> str: def resolve_operation(call_type: str | None) -> GenAIOperation: - """Map a litellm ``call_type`` to a ``gen_ai.operation.name`` value.""" + """Map a litellm ``call_type`` to a ``gen_ai.operation.name`` value. + + An unmapped call type still falls back to ``chat`` so every series keeps an + operation label, but it logs at debug rather than falling through silently: + a new call type mislabelled as ``chat`` mixes its latency and cost into + everyone's chat charts, which is invisible until someone reads the numbers. + """ if not call_type: return GenAIOperation.CHAT - return _OPERATION_BY_CALL_TYPE.get(call_type.lower(), GenAIOperation.CHAT) + mapped = _OPERATION_BY_CALL_TYPE.get(call_type.lower()) + if mapped is not None: + return mapped + verbose_logger.debug( + "otel: call_type %r has no gen_ai.operation.name mapping; labelling it %r. Add it to _OPERATION_BY_CALL_TYPE.", + call_type, + GenAIOperation.CHAT.value, + ) + return GenAIOperation.CHAT diff --git a/litellm/integrations/otel/model/spans.py b/litellm/integrations/otel/model/spans.py index c93f95ec97d..fa41070a8de 100644 --- a/litellm/integrations/otel/model/spans.py +++ b/litellm/integrations/otel/model/spans.py @@ -18,12 +18,14 @@ before the LLM call even starts), so a guardrail is a sibling of the LLM call, not a child of it. The emitter parents every span to the ambient OTel context (the active server span), which matches this. -MCP spans (``MCP_TOOL_CALL``, ``MCP_LIST_TOOLS``) are intentionally NOT in this -tree. Per the OTel GenAI MCP semconv, MCP and the HTTP transport are independent -contexts, so an MCP span parents to the trace context the client propagated in -``params._meta`` (or starts its own root when none is propagated) and records the -``PROXY_REQUEST`` transport span as a span *link*, never a parent. The registry -encodes this as ``parent=None, links=PROXY_REQUEST``. +MCP spans (``MCP_TOOL_CALL``, ``MCP_LIST_TOOLS``) have two shapes, chosen at emit +time by :func:`resolve_mcp_span_context`. When the client propagates trace context +in ``params._meta`` MCP and the HTTP transport are independent contexts per the +OTel GenAI MCP semconv, so the span parents to that propagated context and records +the ``PROXY_REQUEST`` transport span as a span *link*, never a parent — the shape +this registry's ``parent=None, links=PROXY_REQUEST`` entry encodes. When nothing is +propagated (the common case) the span nests under the transport span of the request +carrying that message, so the tool call stays in one trace. Not every service call becomes a span — :func:`span_role_for_service` decides: @@ -89,12 +91,13 @@ class SpanSpec: SPAN_REGISTRY: dict[SpanRole, SpanSpec] = { SpanRole.PROXY_REQUEST: SpanSpec(SpanRole.PROXY_REQUEST, LiteLLMSpanKind.SERVER, parent=None), SpanRole.LLM_CALL: SpanSpec(SpanRole.LLM_CALL, LiteLLMSpanKind.CLIENT, parent=SpanRole.PROXY_REQUEST), - # MCP and the HTTP transport are independent contexts (OTel GenAI MCP semconv), - # so an MCP span does not nest under the transport span. The proxy is an MCP - # client to the upstream server, so it's a CLIENT span; it parents to the trace - # context the client propagated in ``params._meta`` (or starts its own root when - # none is propagated) and records the PROXY_REQUEST transport span as a span - # *link*, never a parent — hence ``parent=None, links=PROXY_REQUEST``. + # The proxy is an MCP client to the upstream server, so MCP spans are CLIENT + # spans. With trace context propagated in ``params._meta``, MCP and the HTTP + # transport are independent contexts (OTel GenAI MCP semconv): the span parents + # to the propagated context and records the PROXY_REQUEST transport span as a + # span *link*, never a parent — the shape ``parent=None, links=PROXY_REQUEST`` + # encodes. With nothing propagated, ``resolve_mcp_span_context`` nests the span + # under that message's transport span instead, keeping the call in one trace. SpanRole.MCP_TOOL_CALL: SpanSpec( SpanRole.MCP_TOOL_CALL, LiteLLMSpanKind.CLIENT, parent=None, links=SpanRole.PROXY_REQUEST ), diff --git a/litellm/integrations/otel/model/utils.py b/litellm/integrations/otel/model/utils.py index f37afc97879..ab54a558a9a 100644 --- a/litellm/integrations/otel/model/utils.py +++ b/litellm/integrations/otel/model/utils.py @@ -1,9 +1,11 @@ """Shared, OpenTelemetry-free helpers for the otel integration. -Generic value coercion (for reading heterogeneous logging-payload dicts), time -conversion, and header parsing — pulled out of the individual modules so they -live in one place. Deliberately free of any ``opentelemetry`` import so the -OTel-free sources of truth (payloads, semconv, spans, config) can use it too. +Generic value coercion (for reading heterogeneous logging-payload dicts) and +time conversion — pulled out of the individual modules so they live in one +place. Deliberately free of any ``opentelemetry`` import so the OTel-free +sources of truth (payloads, semconv, spans, config) can use it too. OTLP header +parsing lives in :mod:`litellm.integrations.otel.plumbing.providers` instead, +because it delegates to the OTel SDK's own W3C Baggage parser. """ from datetime import datetime @@ -89,15 +91,3 @@ def to_seconds(value: datetime | float | int | str | None) -> float | None: except ValueError: continue return None - - -def parse_headers(raw: str | None) -> dict[str, str]: - """Parse an OTLP ``"k=v,k=v"`` header string into a dict.""" - headers: dict[str, str] = {} - if not raw: - return headers - for pair in raw.split(","): - if "=" in pair: - key, _, value = pair.partition("=") - headers[key.strip()] = value.strip() - return headers diff --git a/litellm/integrations/otel/plumbing/context.py b/litellm/integrations/otel/plumbing/context.py index 8acac112c3d..c03ef8d6d63 100644 --- a/litellm/integrations/otel/plumbing/context.py +++ b/litellm/integrations/otel/plumbing/context.py @@ -5,7 +5,14 @@ from typing import Mapping from opentelemetry import baggage from opentelemetry.context import Context, get_current -from opentelemetry.trace import Link, Span, get_current_span, set_span_in_context +from opentelemetry.trace import ( + Link, + NonRecordingSpan, + Span, + SpanContext, + get_current_span, + set_span_in_context, +) from opentelemetry.trace.propagation.tracecontext import ( TraceContextTextMapPropagator, ) @@ -72,6 +79,86 @@ def reset_mcp_message_trace_carrier(token: "Token[Mapping[str, str] | None]") -> _mcp_message_trace_carrier.reset(token) +# The transport span of the HTTP request carrying the CURRENT MCP message. +# +# ``_request_root_span`` above cannot be used for MCP: a *stateful* streamable-HTTP +# session runs every message on the single task spawned by that session's +# ``initialize`` POST, so the ContextVar the ASGI request task writes at auth time +# is frozen at ``initialize`` there and never sees the later ``tools/call`` POSTs. +# Reading it from the message handler parents every tool call in the session to the +# first request's server span and aims that call's ``error.*`` at it — a span that +# ended long ago, so the SDK drops the write and the failure reaches no request at +# all. The gateway instead resolves the current message's transport span on the +# request task and hands it over the same way it hands over per-request auth, and +# the handler publishes it here for the span emitter and the failure hook. +_mcp_message_transport_span: "ContextVar[Span | None]" = ContextVar( + "litellm_otel_mcp_message_transport_span", default=None +) + + +def set_mcp_message_transport_span(span: object) -> "Token[Span | None]": + """Publish the transport span of the request carrying the current MCP message. + + Also re-anchors the request root, so everything else the message emits or stamps + — the identity attributes seeded onto the server span, a guardrail span, a + proxy-level failure — lands on this request instead of on the one that opened + the session. The MCP SDK dispatches each message on its own task, so the anchor + is scoped to this message; the handler re-publishes it for the next one either + way. Only a transport still open for writes is anchored: replacing the anchor + with a request that already answered would just move the dropped writes from one + finished span to another. + + Takes ``object`` because the gateway reads it back out of the ASGI scope, whose + values are untyped; anything that is not a usable span is stored as ``None`` + rather than trusted. + + Returns the reset token; the caller must reset it once the message is handled + so the transport never leaks to the next message on the same session task. + """ + transport = span if isinstance(span, Span) and is_recordable_span(span) else None + if transport is not None and transport.is_recording(): + set_request_root_span(transport) + return _mcp_message_transport_span.set(transport) + + +def reset_mcp_message_transport_span(token: "Token[Span | None]") -> None: + _mcp_message_transport_span.reset(token) + + +def mcp_message_transport_span() -> "Span | None": + """The published transport span, only while it is still open for writes. + + Recording — not merely valid — is the bar here because this span is the target + of ``error.*`` stamping from another task, and the publisher's validity check + cannot speak for a span that has since ended. A finished span keeps a valid + context forever, so it would otherwise be handed back for a write the SDK then + refuses. The POST carrying a ``tools/call`` stays open until the result is + written, so it is recording for the life of the call; a notification POST can + answer first, and this returns ``None`` for it rather than writing into the void. + """ + span = _mcp_message_transport_span.get() + if span is None or not span.is_recording(): + return None + return span + + +def _mcp_transport_span_context() -> "SpanContext | None": + """The transport span an MCP message span should attach to. + + Prefers the transport the gateway published for this specific message; falls + back to the ambient request anchor for paths that emit an MCP span on the + request task itself (the REST MCP endpoints, the SDK). Parenting and linking + only need the immutable context, and unlike ``mcp_message_transport_span`` they + stay correct against a transport that has already finished, so this does not + require the span to still be recording. + """ + published = _mcp_message_transport_span.get() + if published is not None: + return published.get_span_context() + span = request_root_span() + return span.get_span_context() if span is not None else None + + def set_request_baggage(values: Mapping[str, str], context: Context | None = None) -> Context: """Return a context with ``values`` written into Baggage.""" ctx = context @@ -132,33 +219,44 @@ def resolve_request_span_context() -> Context: def resolve_mcp_span_context( carrier: "Mapping[str, str] | None" = None, ) -> "tuple[Context, tuple[Link, ...]]": - """Parent context + links for an MCP message span, per the OTel GenAI MCP semconv. + """Parent context + links for an MCP message span. - MCP and the underlying transport (HTTP) are independent lifecycles — one - streamable-HTTP session multiplexes many messages, so nesting the message span - under the HTTP/session span is wrong (it renders the message at the session's - start, skewed by however long the session has been open). Instead: + When the client propagates W3C trace context in the request's ``params._meta`` + (SEP-414), MCP and the underlying transport are independent lifecycles — one + streamable-HTTP session multiplexes many messages, and the client's own span is + the truthful parent. So, per the OTel GenAI MCP semconv: - * parent to the trace context the client propagated in the request's - ``params._meta`` (a *remote* parent), and - * record the transport/session span as a *link*, never the parent. + * parent to the trace context the client propagated (a *remote* parent), and + * record the transport span as a *link*, never the parent. + + Almost no client implements SEP-414 yet, so in practice nothing is propagated. + Rooting the span there splits a single tool call into two disconnected traces + joined only by a link, which is how it surfaces in APM: the ``POST`` transaction + and the ``tools/call`` span share no trace. With no remote parent to honor, + parent to the transport span of the request carrying this message instead, so + the call stays in one trace; no link is added since the transport is now the + real parent. The transport comes from :func:`_mcp_transport_span_context`, which + is the *current message's* POST rather than whatever request happened to open + the session, so a long-lived session does not glue every message under its + first request. With neither a remote parent nor a transport the returned context + carries no span and the span legitimately starts its own root trace. Only trace context (``traceparent``/``tracestate``) is extracted, never the client's W3C Baggage: ``params._meta`` is caller-controlled, and the otel baggage processor stamps allowlisted baggage keys (``litellm.team.id``, ``litellm.metadata.*``, ...) onto the span as attributes, so honoring remote - baggage would let a client spoof a span's identity attribution. - - With no propagated context the returned context carries no span, so the span - starts its own root trace (still linked to the transport). The base context is - explicitly empty so an absent ``traceparent`` can never fall through to the - ambient (stale session) span. + baggage would let a client spoof a span's identity attribution. The base context + for extraction is explicitly empty so an absent or malformed ``traceparent`` can + never fall through to the ambient (stale session) span. """ source = carrier if carrier is not None else _mcp_message_trace_carrier.get() parent = _PROPAGATOR.extract(dict(source or {}), context=Context()) - transport = request_root_span() - links = (Link(transport.get_span_context()),) if transport is not None else () - return parent, links + transport = _mcp_transport_span_context() + if is_recordable_span(get_current_span(parent)): + return parent, (Link(transport),) if transport is not None else () + if transport is not None: + return context_from_span(NonRecordingSpan(transport)), () + return parent, () def is_recordable_span(obj: object) -> bool: diff --git a/litellm/integrations/otel/plumbing/metrics.py b/litellm/integrations/otel/plumbing/metrics.py index 50d0fb75962..6ebaacafdc4 100644 --- a/litellm/integrations/otel/plumbing/metrics.py +++ b/litellm/integrations/otel/plumbing/metrics.py @@ -1,6 +1,6 @@ """GenAI client metrics: the six ``gen_ai.client.*`` histograms plus the recorder that builds attributes, applies the shared cardinality filter, and -records a request's metrics in the success path. +records a request's metrics on both the success and the failure path. The instrument names/units/descriptions and the recording + timing math mirror the v1 :mod:`litellm.integrations.opentelemetry` integration so both engines emit @@ -10,11 +10,12 @@ identical metrics. The attribute cardinality filter is reused from v1 by import from dataclasses import dataclass from datetime import datetime -from typing import Any, FrozenSet, Mapping, Optional +from typing import Any, Final, FrozenSet, Mapping, Optional, TypeAlias from opentelemetry.metrics import Histogram, Meter import litellm +from litellm._logging import verbose_logger from litellm.integrations.opentelemetry import ( METRIC_METADATA_KEYS, TOKEN_TYPE_ATTRIBUTE, @@ -22,11 +23,34 @@ from litellm.integrations.opentelemetry import ( _resolve_metric_attribute_filter, ) from litellm.integrations.otel.model.metadata import time_to_first_chunk_seconds -from litellm.integrations.otel.model.semconv import Metric, resolve_operation +from litellm.integrations.otel.model.semconv import ( + Error, + GenAI, + Metric, + resolve_operation, + resolve_provider, +) from litellm.integrations.otel.model.utils import to_seconds from litellm.litellm_core_utils.safe_json_dumps import safe_dumps +def _provider_attributes(custom_llm_provider: object) -> Mapping[str, str]: + """The provider labels for one call's metrics. + + ``gen_ai.provider.name`` carries the semconv-mapped value; the deprecated + ``gen_ai.system`` spelling is dual-emitted with the raw litellm provider + string it has always carried, so a dashboard already querying it keeps + matching. A call with no provider gets neither label: a placeholder value + would mint a permanent series that no operator can act on. + """ + if not isinstance(custom_llm_provider, str) or not custom_llm_provider: + return {} + return { + GenAI.PROVIDER_NAME: resolve_provider(custom_llm_provider), + GenAI.SYSTEM: custom_llm_provider, + } + + @dataclass(frozen=True) class GenAIMetrics: operation_duration: Histogram @@ -72,8 +96,83 @@ def create_genai_metrics(meter: Meter) -> GenAIMetrics: ) +# A metric datapoint's attributes. Values are the strings the recorder builds, except +# the request model, which is whatever the caller passed and may be absent. +MetricAttributes: TypeAlias = Mapping[str, "str | None"] + +ERROR_TYPE_FALLBACK: Final = "_OTHER" + +# Every attribute a metric datapoint may carry, on either path. A label value that +# is unique per request is a new time series that will never be written to again, so +# this set is what keeps the series count bounded by the deployment's own +# key/team/user/deployment count rather than by its traffic. Each entry is a fixed +# enum or an operator-provisioned identifier. +# +# Deliberately excluded is everything the *client* supplies or that moves per +# request: ``metadata.requester_metadata`` and ``metadata.spend_logs_metadata`` (both +# free-form from the request body), ``metadata.user_api_key_end_user_id`` (the body's +# ``user`` field), and ``metadata.requester_ip_address``. Those stay on the span, +# where cardinality is free and where they already are. +# ``metadata.user_api_key_user_email`` is left out too: it is bounded, but it is PII +# duplicating the user id already here. +# +# This is a CEILING, applied before the operator's own include/exclude filter, so an +# operator can narrow it but never widen it back to an unbounded attribute. +METRIC_ATTRIBUTE_CEILING: Final[frozenset[str]] = frozenset( + ( + "gen_ai.operation.name", + "gen_ai.provider.name", + "gen_ai.system", + "gen_ai.request.model", + "gen_ai.framework", + "metadata.user_api_key_hash", + "metadata.user_api_key_alias", + "metadata.user_api_key_team_id", + "metadata.user_api_key_team_alias", + "metadata.user_api_key_org_id", + "metadata.user_api_key_user_id", + "hidden_params", + ) +) + +# The only ``hidden_params`` field that becomes part of the ``hidden_params`` label. +# The object as a whole is per-request by construction -- ``response_cost``, +# ``litellm_overhead_time_ms``, ``cache_key``, ``usage_object`` and the provider's +# ``additional_headers`` rate-limit counters all move on every call -- so dumping it +# whole made one series per request out of every instrument. +# +# ``model_id`` is the router's own deployment id, so it is bounded by the deployment +# list and is what a per-deployment panel joins on. ``api_base`` is deliberately NOT +# here even though it names the same thing: it is a documented per-call parameter, so +# in SDK use it is chosen by the caller rather than provisioned by the operator, and a +# caller varying it would put the per-request cardinality straight back. +BOUNDED_HIDDEN_PARAM_KEYS: Final[tuple[str, ...]] = ("model_id",) + + +def resolve_error_type(kwargs: Mapping[str, Any]) -> str: + """The ``error.type`` value for a failed request. + + Bounded by construction: the mapped provider exception's class name (the same + ``error_information.error_class`` the failure span stamps), else the provider + status code, else the raw exception's class name, else ``_OTHER`` — the value + the convention reserves for a failure the instrumentation cannot classify. The + exception *message* is unbounded and never becomes a label; it stays on the + span and its exception event, where high cardinality is free. + """ + std_log = kwargs.get("standard_logging_object") + info = getattr(std_log, "error_information", None) or (std_log or {}).get("error_information") or {} + error_class = info.get("error_class") or info.get("error_code") + if error_class: + return str(error_class) + exception = kwargs.get("exception") + if exception is not None: + return type(exception).__name__ + return ERROR_TYPE_FALLBACK + + class GenAIMetricRecorder: - """Records the six GenAI histograms for one successful LLM call. + """Records the six GenAI histograms for one successful LLM call, and the + duration histogram alone for one failed LLM call (see :meth:`record_failure`). The cardinality filter is resolved lazily on the first record: the proxy populates ``callback_settings.otel.attributes`` after the logger is built, so @@ -96,7 +195,7 @@ class GenAIMetricRecorder: start_time: datetime, end_time: datetime, ) -> None: - common_attrs = self._filter_attributes(self._common_attributes(kwargs)) + common_attrs = self._filter_attributes(self._bounded_attributes(kwargs)) duration_s = (end_time - start_time).total_seconds() self._metrics.operation_duration.record(duration_s, attributes=common_attrs) @@ -110,17 +209,48 @@ class GenAIMetricRecorder: self._record_time_per_output_token(kwargs, response_obj, end_time, duration_s, common_attrs) self._record_response_duration(kwargs, end_time, common_attrs) + def record_failure( + self, + kwargs: Mapping[str, Any], + start_time: datetime, + end_time: datetime, + ) -> None: + """Record the one metric a failed request can honestly report: the + operation's duration, tagged with ``error.type``. + + The other five instruments all describe a completed generation and have + nothing to measure here. litellm hands the failure callback no + ``response_obj`` at all, so there is no usage to split into input/output + tokens and no completion-token count to divide generation time by; it also + zeroes ``response_cost`` on failure. Recording them anyway would put a + fabricated zero into series that dashboards average. + + The attribute set is :data:`METRIC_ATTRIBUTE_CEILING`, the same cap the + success path uses. A failure needs no provider spend, so a caller who can put + a unique value into a client-supplied attribute could mint one histogram + series per request for free; the cap is what makes that impossible on either + path. + + ``error.type`` is stamped after both filters, exactly like + ``gen_ai.token.type``, so an operator's include/exclude list cannot strip + the discriminator and silently merge failures back into the success series. + """ + attributes = { + **self._filter_attributes(self._bounded_attributes(kwargs)), + Error.TYPE: resolve_error_type(kwargs), + } + self._metrics.operation_duration.record((end_time - start_time).total_seconds(), attributes=attributes) + # ------------------------------------------------------------------ # # Attribute building + cardinality filter # ------------------------------------------------------------------ # def _common_attributes(self, kwargs: Mapping[str, Any]) -> dict: params = kwargs.get("litellm_params") or {} - provider = params.get("custom_llm_provider", "Unknown") common_attrs: dict = { - "gen_ai.operation.name": resolve_operation(kwargs.get("call_type")).value, - "gen_ai.system": provider, - "gen_ai.request.model": kwargs.get("model"), + GenAI.OPERATION_NAME: resolve_operation(kwargs.get("call_type")).value, + **_provider_attributes(params.get("custom_llm_provider")), + GenAI.REQUEST_MODEL: kwargs.get("model"), "gen_ai.framework": "litellm", } @@ -136,11 +266,25 @@ class GenAIMetricRecorder: common_attrs[f"metadata.{key}"] = str(value) hidden_params = getattr(std_log, "hidden_params", None) or (std_log or {}).get("hidden_params", {}) - if hidden_params: - common_attrs["hidden_params"] = safe_dumps(hidden_params) + bounded_hidden_params = { + key: hidden_params[key] + for key in BOUNDED_HIDDEN_PARAM_KEYS + if isinstance(hidden_params, Mapping) and hidden_params.get(key) is not None + } + if bounded_hidden_params: + common_attrs["hidden_params"] = safe_dumps(bounded_hidden_params) return common_attrs + def _bounded_attributes(self, kwargs: Mapping[str, Any]) -> MetricAttributes: + """The datapoint attributes, capped at :data:`METRIC_ATTRIBUTE_CEILING`. + + The cap runs BEFORE the operator's include/exclude filter so the filter can + only narrow it. An operator who names an excluded attribute in an include + list gets nothing for it rather than reintroducing an unbounded label. + """ + return {k: v for k, v in self._common_attributes(kwargs).items() if k in METRIC_ATTRIBUTE_CEILING} + def _ensure_filter(self) -> None: if self._filter_resolved: return @@ -157,8 +301,29 @@ class GenAIMetricRecorder: # without reconstructing the recorder. self._include, self._exclude = _resolve_metric_attribute_filter(attributes) self._filter_resolved = True + self._warn_about_metric_ineligible_names() - def _filter_attributes(self, attrs: dict) -> dict: + def _warn_about_metric_ineligible_names(self) -> None: + """Say so when the operator's filter names an attribute the ceiling removes. + + The shared validator accepts every span attribute name, so a name that is + legal on a span but metric-ineligible would otherwise be a silent no-op: an + ``include_list`` naming it emits nothing for it and an ``exclude_list`` naming + it looks like it worked. Logged once, when the filter resolves, rather than + per request. + """ + named = (self._include or frozenset()) | (self._exclude or frozenset()) + ineligible = sorted(named - METRIC_ATTRIBUTE_CEILING - {TOKEN_TYPE_ATTRIBUTE}) + if ineligible: + verbose_logger.warning( + "OTel metrics: %s cannot be a metric attribute and is being ignored; it varies " + "per request or is client-supplied, so it would make one time series per request. " + "It is still on the span. Metric attributes are limited to: %s", + ", ".join(ineligible), + ", ".join(sorted(METRIC_ATTRIBUTE_CEILING)), + ) + + def _filter_attributes(self, attrs: MetricAttributes) -> MetricAttributes: self._ensure_filter() if self._include is not None: return {k: v for k, v in attrs.items() if k in self._include} diff --git a/litellm/integrations/otel/plumbing/providers.py b/litellm/integrations/otel/plumbing/providers.py index ced65aa1ec3..ede9acc6d8f 100644 --- a/litellm/integrations/otel/plumbing/providers.py +++ b/litellm/integrations/otel/plumbing/providers.py @@ -29,15 +29,13 @@ from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( InMemorySpanExporter, ) from opentelemetry.trace import Span, SpanKind, Tracer +from opentelemetry.util.re import parse_env_headers from litellm._version import version as litellm_version from litellm.integrations.otel.model.config import ExporterSpec, OpenTelemetryV2Config from litellm.integrations.otel.model.semconv import LiteLLM from litellm.integrations.otel.model.spans import LiteLLMSpanKind -# Re-exported so ``providers.parse_headers`` remains a stable entry point. -from litellm.integrations.otel.model.utils import parse_headers as parse_headers - if TYPE_CHECKING: from opentelemetry.metrics import Meter from opentelemetry.sdk.metrics.export import MetricReader @@ -119,6 +117,23 @@ def _otlp_traces_endpoint(endpoint: str | None) -> str | None: return endpoint + "/v1/traces" +def parse_headers(raw: str | None) -> dict[str, str]: + """Parse an OTLP ``"k=v,k=v"`` header string into a dict. + + ``OTEL_EXPORTER_OTLP_HEADERS`` is W3C Baggage encoded per the OTLP spec, so + values are percent-decoded: a vendor that documents + ``Authorization=Basic%20`` (Grafana Cloud does, because a bare space + is not representable there) has to reach the exporter as ``Basic ``, + not with a literal ``%20`` that the backend rejects as malformed. The SDK's + own parser is used so litellm decodes exactly what the OTLP exporters do + when they read the env var themselves; ``liberal`` keeps values that are not + percent-encoded (``Authorization=Bearer ``) working unchanged. + """ + if not raw: + return {} + return dict(parse_env_headers(raw, liberal=True)) + + def _exporter_from_spec(spec: ExporterSpec) -> SpanExporter: kind = (spec.kind or "console").lower() factory = _EXPORTER_FACTORIES.get(kind) @@ -191,6 +206,13 @@ def build_metric_reader(config: OpenTelemetryV2Config) -> "MetricReader": ``console`` (and any unrecognized kind) exports to the console; ``otlp_http`` and ``otlp_grpc`` export over OTLP with the configured endpoint/headers. The reader exports on a 5s period, matching v1. + + Histograms keep the SDK's default cumulative temporality. Prometheus-backed + OTLP receivers (Grafana Cloud / Mimir, and the Prometheus OTLP endpoint) + reject delta histograms outright with ``invalid temporality and type + combination``, which drops the whole metric batch, while backends that + prefer delta still accept cumulative. The enterprise billing exporter + already relies on the same default. """ from opentelemetry.sdk.metrics.export import ( ConsoleMetricExporter, @@ -202,18 +224,12 @@ def build_metric_reader(config: OpenTelemetryV2Config) -> "MetricReader": from opentelemetry.exporter.otlp.proto.http.metric_exporter import ( OTLPMetricExporter as HTTPMetricExporter, ) - from opentelemetry.sdk.metrics import Histogram - from opentelemetry.sdk.metrics.export import AggregationTemporality exporter: Any = HTTPMetricExporter( endpoint=_otlp_metrics_endpoint(config.endpoint), headers=parse_headers(config.headers), - preferred_temporality={Histogram: AggregationTemporality.DELTA}, ) elif kind in ("otlp_grpc", "grpc"): - from opentelemetry.sdk.metrics import Histogram - from opentelemetry.sdk.metrics.export import AggregationTemporality - try: from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import ( OTLPMetricExporter as GRPCMetricExporter, @@ -227,7 +243,6 @@ def build_metric_reader(config: OpenTelemetryV2Config) -> "MetricReader": exporter = GRPCMetricExporter( endpoint=config.endpoint, headers=parse_headers(config.headers), - preferred_temporality={Histogram: AggregationTemporality.DELTA}, ) else: exporter = ConsoleMetricExporter() diff --git a/litellm/integrations/prometheus.py b/litellm/integrations/prometheus.py index 64d4dd578b2..41a4d026fe1 100644 --- a/litellm/integrations/prometheus.py +++ b/litellm/integrations/prometheus.py @@ -16,6 +16,7 @@ from typing import ( Dict, List, Literal, + Mapping, Optional, Sequence, Tuple, @@ -68,6 +69,15 @@ else: _DEFAULT_BUDGET_METRICS_PER_REQUEST_TIMEOUT = 5.0 +# Tiers a caller may name in a request, across the providers that accept the +# parameter: OpenAI ("auto", "default", "flex", "priority", "scale"), Bedrock and +# Groq (subsets of those), Anthropic ("auto", "standard_only") and Vertex, which +# maps "default" to "standard". Used to bound the caller-controlled fallback in +# ``get_service_tier_from_standard_logging_payload``. +KNOWN_REQUEST_SERVICE_TIERS = frozenset( + {"auto", "batch", "default", "flex", "priority", "scale", "standard", "standard_only"} +) + def _get_budget_metrics_per_request_timeout() -> float: raw = os.getenv("PROMETHEUS_BUDGET_METRICS_PER_REQUEST_TIMEOUT") @@ -1244,6 +1254,7 @@ class PrometheusLogger(CustomLogger): client_ip=standard_logging_payload["metadata"].get("requester_ip_address"), user_agent=standard_logging_payload["metadata"].get("user_agent"), stream=(str(standard_logging_payload.get("stream")) if litellm.prometheus_emit_stream_label else None), + service_tier=get_service_tier_from_standard_logging_payload(standard_logging_payload), ) if user_api_key is not None and isinstance(user_api_key, str) and user_api_key.startswith("sk-"): @@ -1449,6 +1460,8 @@ class PrometheusLogger(CustomLogger): prompt_details = usage_object.get("prompt_tokens_details") or {} completion_details = usage_object.get("completion_tokens_details") or {} + cache_creation_detail_tokens = PrometheusLogger._resolve_cache_write_tokens(prompt_details) + detail_metrics: List[Tuple[Any, DEFINED_PROMETHEUS_METRICS, Any]] = [ ( self.litellm_input_cached_tokens_metric, @@ -1458,7 +1471,7 @@ class PrometheusLogger(CustomLogger): ( self.litellm_input_cache_creation_tokens_metric, "litellm_input_cache_creation_tokens_metric", - (prompt_details.get("cache_creation_tokens") if isinstance(prompt_details, dict) else None), + cache_creation_detail_tokens, ), ( self.litellm_input_audio_tokens_metric, @@ -1597,27 +1610,12 @@ class PrometheusLogger(CustomLogger): ) # Provider prompt caching metrics are independent of LiteLLM cache_hit. - provider_cache_read_tokens = 0 - provider_cache_creation_tokens = 0 usage_obj = (standard_logging_payload.get("metadata", {}) or {}).get("usage_object") if isinstance(usage_obj, dict): - # Prefer explicit provider cache fields when available. - _read = usage_obj.get("cache_read_input_tokens") - _write = usage_obj.get("cache_creation_input_tokens") - - if isinstance(_read, int): - provider_cache_read_tokens = _read - if isinstance(_write, int): - provider_cache_creation_tokens = _write - - # Fallback to prompt_tokens_details.cached_tokens (common normalization point). - # Only fallback when the explicit field is genuinely absent (None). - if _read is None: - prompt_details = usage_obj.get("prompt_tokens_details") - if isinstance(prompt_details, dict): - cached_tokens = prompt_details.get("cached_tokens") - if isinstance(cached_tokens, int): - provider_cache_read_tokens = cached_tokens + ( + provider_cache_read_tokens, + provider_cache_creation_tokens, + ) = PrometheusLogger._resolve_provider_cache_tokens(usage_obj) if provider_cache_read_tokens > 0: PrometheusLogger._inc_labeled_counter( @@ -1639,6 +1637,40 @@ class PrometheusLogger(CustomLogger): amount=float(provider_cache_creation_tokens), ) + @staticmethod + def _resolve_provider_cache_tokens(usage_obj: Mapping[str, object]) -> tuple[int, int]: + # Prefer explicit provider cache fields when available. + _read = usage_obj.get("cache_read_input_tokens") + _write = usage_obj.get("cache_creation_input_tokens") + + provider_cache_read_tokens = _read if isinstance(_read, int) else 0 + provider_cache_creation_tokens = _write if isinstance(_write, int) else 0 + + # Fallback to prompt_tokens_details (common normalization point). + # Only fallback when the explicit field is genuinely absent (None). + prompt_details = usage_obj.get("prompt_tokens_details") + if _read is None and isinstance(prompt_details, dict): + cached_tokens = prompt_details.get("cached_tokens") + if isinstance(cached_tokens, int): + provider_cache_read_tokens = cached_tokens + + if _write is None: + write_tokens = PrometheusLogger._resolve_cache_write_tokens(prompt_details) + if write_tokens is not None: + provider_cache_creation_tokens = write_tokens + + return provider_cache_read_tokens, provider_cache_creation_tokens + + @staticmethod + def _resolve_cache_write_tokens(prompt_details: object) -> int | None: + if not isinstance(prompt_details, dict): + return None + for key in ("cache_write_tokens", "cache_creation_tokens"): + value = prompt_details.get(key) + if isinstance(value, int) and not isinstance(value, bool): + return value + return None + def _increment_mcp_tool_call_metrics( self, standard_logging_payload: StandardLoggingPayload, @@ -4076,6 +4108,44 @@ def get_custom_labels_from_metadata(metadata: dict) -> Dict[str, str]: return result +def get_service_tier_from_standard_logging_payload( + standard_logging_payload: StandardLoggingPayload, +) -> str | None: + """ + Resolve the service tier a request ran on, for the ``service_tier`` label. + + The tier the provider actually served wins over the tier the caller asked for, + so latency and spend stay segmentable when the request said ``auto`` and the + provider picked the concrete tier. Providers report the served tier either at + the top level of the response (OpenAI, Bedrock, Groq) or on the usage object + (Anthropic). + + Streaming responses carry no served tier, so the requested tier is the + fallback. That value is caller-controlled and survives param mapping even + where the provider then ignores it (Bedrock and Groq accept the request and + drop an unrecognized tier), so it is only labelled when it names a known + tier; otherwise one caller could mint a Prometheus series per string. Values + the provider itself reports are not caller-controlled and stay unrestricted, + so a tier a provider adds later is still labelled correctly. + """ + response = standard_logging_payload.get("response") + usage_object = standard_logging_payload.get("metadata", {}).get("usage_object") + + served_candidates: tuple[object, ...] = ( + response.get("service_tier") if isinstance(response, dict) else None, + usage_object.get("service_tier") if isinstance(usage_object, dict) else None, + ) + served_tier = next((tier for tier in served_candidates if isinstance(tier, str) and tier), None) + if served_tier is not None: + return served_tier + + model_parameters = standard_logging_payload.get("model_parameters") + requested_tier = model_parameters.get("service_tier") if isinstance(model_parameters, dict) else None + if isinstance(requested_tier, str) and requested_tier in KNOWN_REQUEST_SERVICE_TIERS: + return requested_tier + return None + + def _get_combined_custom_metadata_from_standard_logging_payload( standard_logging_payload: Optional[dict], ) -> Dict[str, Any]: diff --git a/litellm/integrations/s3.py b/litellm/integrations/s3.py index e8252d87572..07bd957b5a3 100644 --- a/litellm/integrations/s3.py +++ b/litellm/integrations/s3.py @@ -24,6 +24,8 @@ class S3Logger: s3_aws_secret_access_key=None, s3_aws_session_token=None, s3_config=None, + s3_server_side_encryption: str | None = None, + s3_sse_kms_key_id: str | None = None, **kwargs, ): import boto3 @@ -50,11 +52,16 @@ class S3Logger: s3_aws_session_token = litellm.s3_callback_params.get("s3_aws_session_token") s3_config = litellm.s3_callback_params.get("s3_config") s3_path = litellm.s3_callback_params.get("s3_path") + s3_server_side_encryption = litellm.s3_callback_params.get("s3_server_side_encryption") + s3_sse_kms_key_id = litellm.s3_callback_params.get("s3_sse_kms_key_id") # done reading litellm.s3_callback_params s3_use_team_prefix = bool(litellm.s3_callback_params.get("s3_use_team_prefix", False)) self.s3_use_team_prefix = s3_use_team_prefix self.bucket_name = s3_bucket_name self.s3_path = s3_path + self.s3_server_side_encryption, self.s3_sse_kms_key_id = resolve_sse_params( + s3_server_side_encryption, s3_sse_kms_key_id + ) verbose_logger.debug(f"s3 logger using endpoint url {s3_endpoint_url}") # Create an S3 client with custom endpoint URL self.s3_client = boto3.client( @@ -136,6 +143,15 @@ class S3Logger: print_verbose(f"\ns3 Logger - Logging payload = {payload_str}") + sse_params = { + key: value + for key, value in { + "ServerSideEncryption": self.s3_server_side_encryption, + "SSEKMSKeyId": self.s3_sse_kms_key_id, + }.items() + if value + } + response = self.s3_client.put_object( Bucket=self.bucket_name, Key=s3_object_key, @@ -144,6 +160,7 @@ class S3Logger: ContentLanguage="en", ContentDisposition=f'inline; filename="{s3_object_download_filename}"', CacheControl="private, immutable, max-age=31536000, s-maxage=0", + **sse_params, ) print_verbose(f"Response from s3:{str(response)}") @@ -155,6 +172,33 @@ class S3Logger: pass +def _validated_sse_value(name: str, value: str | None) -> str | None: + if value is None or isinstance(value, str): + return value + verbose_logger.warning( + f"s3 logging: ignoring {name} because it has invalid type {type(value).__name__}; expected a string" + ) + return None + + +def resolve_sse_params( + server_side_encryption: str | None, + sse_kms_key_id: str | None, +) -> tuple[str | None, str | None]: + valid_sse = _validated_sse_value("s3_server_side_encryption", server_side_encryption) + valid_key_id = _validated_sse_value("s3_sse_kms_key_id", sse_kms_key_id) + algorithm = valid_sse or ("aws:kms" if valid_key_id else None) + if algorithm is None: + return None, None + if valid_key_id and not algorithm.startswith("aws:kms"): + verbose_logger.warning( + f"s3 logging: ignoring s3_sse_kms_key_id because s3_server_side_encryption is {algorithm}; " + "set it to aws:kms to encrypt with the KMS key" + ) + return algorithm, None + return algorithm, valid_key_id + + def get_s3_object_key( s3_path: str, prefix: str, diff --git a/litellm/integrations/s3_v2.py b/litellm/integrations/s3_v2.py index 5b953035cfd..7fa78f39460 100644 --- a/litellm/integrations/s3_v2.py +++ b/litellm/integrations/s3_v2.py @@ -8,13 +8,14 @@ NOTE 1: S3 does not provide a BATCH PUT API endpoint, so we create tasks to uplo import asyncio import time +from collections.abc import Mapping from datetime import datetime from typing import List, Optional, cast import litellm from litellm._logging import print_verbose, verbose_logger from litellm.constants import DEFAULT_S3_BATCH_SIZE, DEFAULT_S3_FLUSH_INTERVAL_SECONDS -from litellm.integrations.s3 import get_s3_object_key +from litellm.integrations.s3 import get_s3_object_key, resolve_sse_params from litellm.litellm_core_utils.safe_json_dumps import safe_dumps from litellm.litellm_core_utils.sensitive_data_masker import SensitiveDataMasker from litellm.llms.bedrock.base_aws_llm import BaseAWSLLM @@ -55,6 +56,7 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM): s3_use_key_prefix: bool = False, s3_use_virtual_hosted_style: bool = False, s3_server_side_encryption: Optional[str] = None, + s3_sse_kms_key_id: str | None = None, s3_callback_params_override: Optional[dict] = None, **kwargs, ): @@ -94,6 +96,7 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM): s3_use_key_prefix=s3_use_key_prefix, s3_use_virtual_hosted_style=s3_use_virtual_hosted_style, s3_server_side_encryption=s3_server_side_encryption, + s3_sse_kms_key_id=s3_sse_kms_key_id, ) verbose_logger.debug(f"s3 logger using endpoint url {s3_endpoint_url}") @@ -148,6 +151,7 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM): s3_use_key_prefix: bool = False, s3_use_virtual_hosted_style: bool = False, s3_server_side_encryption: Optional[str] = None, + s3_sse_kms_key_id: str | None = None, params_source: Optional[dict] = None, ): """ @@ -197,10 +201,20 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM): bool(params.get("s3_use_virtual_hosted_style", False)) or s3_use_virtual_hosted_style ) - self.s3_server_side_encryption = params.get("s3_server_side_encryption") or s3_server_side_encryption + self.s3_server_side_encryption, self.s3_sse_kms_key_id = resolve_sse_params( + params.get("s3_server_side_encryption") or s3_server_side_encryption, + params.get("s3_sse_kms_key_id") or s3_sse_kms_key_id, + ) return + def _sse_headers(self) -> Mapping[str, str]: + candidates = { + "x-amz-server-side-encryption": self.s3_server_side_encryption, + "x-amz-server-side-encryption-aws-kms-key-id": self.s3_sse_kms_key_id, + } + return {key: value for key, value in candidates.items() if value} + async def async_log_success_event(self, kwargs, response_obj, start_time, end_time): await self._async_log_event_base( kwargs=kwargs, @@ -335,11 +349,7 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM): "Content-Language": "en", "Content-Disposition": f'inline; filename="{batch_logging_element.s3_object_download_filename}"', "Cache-Control": "private, immutable, max-age=31536000, s-maxage=0", - **( - {"x-amz-server-side-encryption": self.s3_server_side_encryption} - if self.s3_server_side_encryption - else {} - ), + **self._sse_headers(), } req = requests.Request("PUT", url, data=json_string, headers=headers) prepped = req.prepare() @@ -510,11 +520,7 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM): "Content-Language": "en", "Content-Disposition": f'inline; filename="{batch_logging_element.s3_object_download_filename}"', "Cache-Control": "private, immutable, max-age=31536000, s-maxage=0", - **( - {"x-amz-server-side-encryption": self.s3_server_side_encryption} - if self.s3_server_side_encryption - else {} - ), + **self._sse_headers(), } req = requests.Request("PUT", url, data=json_string, headers=headers) prepped = req.prepare() diff --git a/litellm/litellm_core_utils/core_helpers.py b/litellm/litellm_core_utils/core_helpers.py index 88dddb59cc7..cecc35ee1c1 100644 --- a/litellm/litellm_core_utils/core_helpers.py +++ b/litellm/litellm_core_utils/core_helpers.py @@ -195,6 +195,25 @@ def get_metadata_variable_name_from_kwargs( return "litellm_metadata" if "litellm_metadata" in kwargs else "metadata" +def get_or_create_metadata_bucket( + request_data: dict, +) -> tuple[Literal["metadata", "litellm_metadata"], dict]: + """ + Return the proxy-internal metadata bucket for this request, creating it if absent. + + Batch/file routes store proxy state in ``litellm_metadata`` so the OpenAI + ``metadata`` field can remain provider-safe (string values only). Every writer and + reader of proxy-internal metadata resolves the bucket through here, so a caller that + supplies its own ``metadata`` field cannot split them across two dicts. + """ + metadata_key = get_metadata_variable_name_from_kwargs(request_data) + metadata_bucket = request_data.get(metadata_key) + if not isinstance(metadata_bucket, dict): + metadata_bucket = {} + request_data[metadata_key] = metadata_bucket + return metadata_key, metadata_bucket + + def get_litellm_metadata_from_kwargs(kwargs: dict): """ Helper to get litellm metadata from all litellm request kwargs diff --git a/litellm/litellm_core_utils/litellm_logging.py b/litellm/litellm_core_utils/litellm_logging.py index c9e70b7db73..c2dc7189934 100644 --- a/litellm/litellm_core_utils/litellm_logging.py +++ b/litellm/litellm_core_utils/litellm_logging.py @@ -1878,7 +1878,14 @@ class Logging(LiteLLMLoggingBaseClass): elif standard_logging_object is not None: self.model_call_details["standard_logging_object"] = standard_logging_object else: - self.model_call_details["response_cost"] = None + # Streaming reaches here before its cost is known, so the cost + # is seeded to None, but only when nothing has already + # established one. A stream that assembles into a response + # object recomputes the cost right after this; a pass-through + # stream cannot (its body is opaque) and carries the cost its + # upstream reported in the response headers, which an + # unconditional reset would discard. + self.model_call_details.setdefault("response_cost", None) result = self._transform_usage_objects(result=result) @@ -4673,6 +4680,7 @@ class StandardLoggingPayloadSetup: applied_guardrails=applied_guardrails, mcp_tool_call_metadata=mcp_tool_call_metadata, vector_store_request_metadata=vector_store_request_metadata, + routing_decision=None, usage_object=usage_object, requester_custom_headers=None, cold_storage_object_key=None, @@ -5512,6 +5520,7 @@ def get_standard_logging_metadata( applied_guardrails=None, mcp_tool_call_metadata=None, vector_store_request_metadata=None, + routing_decision=None, usage_object=None, requester_custom_headers=None, user_api_key_request_route=None, @@ -5547,18 +5556,6 @@ def scrub_sensitive_keys_in_metadata(litellm_params: Optional[dict]): litellm_params["_langfuse_masking_function"] = masking_fn litellm_params["metadata"] = metadata - ## check user_api_key_metadata for sensitive logging keys - cleaned_user_api_key_metadata = {} - if "user_api_key_metadata" in metadata and isinstance(metadata["user_api_key_metadata"], dict): - for k, v in metadata["user_api_key_metadata"].items(): - if k == "logging": # prevent logging user logging keys - cleaned_user_api_key_metadata[k] = "scrubbed_by_litellm_for_sensitive_keys" - else: - cleaned_user_api_key_metadata[k] = v - - metadata["user_api_key_metadata"] = cleaned_user_api_key_metadata - litellm_params["metadata"] = metadata - return litellm_params diff --git a/litellm/litellm_core_utils/llm_cost_calc/utils.py b/litellm/litellm_core_utils/llm_cost_calc/utils.py index 85ed0665ebf..fbc06b76c72 100644 --- a/litellm/litellm_core_utils/llm_cost_calc/utils.py +++ b/litellm/litellm_core_utils/llm_cost_calc/utils.py @@ -2,7 +2,8 @@ ## Helper utilities for cost_per_token() from dataclasses import dataclass -from typing import Any, Literal, Optional, Tuple, TypedDict, cast +from types import MappingProxyType +from typing import Any, Literal, Mapping, Optional, Tuple, TypedDict, cast import litellm from litellm._logging import verbose_logger @@ -39,6 +40,14 @@ _VALID_DATA_RESIDENCIES = frozenset(r.value for r in DataResidency) # of being rebuilt for every model_info key on every call. _SERVICE_TIER_SUFFIXES: tuple[str, ...] = tuple(f"_{st.value}" for st in ServiceTier) +_SERVICE_TIER_TO_COST_KEY_SUFFIX: Mapping[str, str] = MappingProxyType( + { + ServiceTier.FLEX.value: ServiceTier.FLEX.value, + ServiceTier.PRIORITY.value: ServiceTier.PRIORITY.value, + ServiceTier.FAST.value: ServiceTier.PRIORITY.value, + } +) + def _get_token_detail_value(details: object, key: str) -> Optional[int]: if isinstance(details, dict): @@ -177,7 +186,7 @@ def _get_service_tier_cost_key(base_key: str, service_tier: Optional[str]) -> st Args: base_key: The base cost key (e.g., "input_cost_per_token") - service_tier: The service tier ("flex", "priority", or None for standard) + service_tier: The service tier ("flex", "priority", "fast", or None for standard) Returns: str: The cost key to use (e.g., "input_cost_per_token_flex" or "input_cost_per_token") @@ -185,12 +194,11 @@ def _get_service_tier_cost_key(base_key: str, service_tier: Optional[str]) -> st if service_tier is None: return base_key - # Only use service tier specific keys for "flex" and "priority" - if service_tier.lower() in [ServiceTier.FLEX.value, ServiceTier.PRIORITY.value]: - return f"{base_key}_{service_tier.lower()}" + suffix = _SERVICE_TIER_TO_COST_KEY_SUFFIX.get(service_tier.lower()) + if suffix is None: + return base_key - # For any other service tier, use standard pricing - return base_key + return f"{base_key}_{suffix}" def _parse_above_token_threshold(key: str) -> float: diff --git a/litellm/litellm_core_utils/prompt_templates/factory.py b/litellm/litellm_core_utils/prompt_templates/factory.py index f7ff4d6b16f..0752bf2d771 100644 --- a/litellm/litellm_core_utils/prompt_templates/factory.py +++ b/litellm/litellm_core_utils/prompt_templates/factory.py @@ -6,6 +6,7 @@ import mimetypes import re import xml.etree.ElementTree as ET from enum import Enum +from collections.abc import Iterator, Mapping, Sequence from typing import Any, Dict, List, Optional, Set, Tuple, TypedDict, Union, cast, overload from jinja2.sandbox import ImmutableSandboxedEnvironment @@ -1266,7 +1267,7 @@ def _get_dummy_thought_signature() -> str: def convert_to_gemini_tool_call_invoke( message: ChatCompletionAssistantMessage, model: Optional[str] = None, - custom_llm_provider: Optional[str] = None, + forward_function_call_id: bool = False, ) -> List[VertexPartType]: """ OpenAI tool invokes: @@ -1316,16 +1317,12 @@ def convert_to_gemini_tool_call_invoke( VertexGeminiConfig, ) - forward_tool_call_id = bool( - model and VertexGeminiConfig._forward_gemini_function_call_id(model, custom_llm_provider) - ) - if tool_calls is not None: for idx, tool in enumerate(tool_calls): if "function" in tool: gemini_function_call: Optional[VertexFunctionCall] = _gemini_tool_call_invoke_helper( function_call_params=tool["function"], - tool_call_id=(tool.get("id") if forward_tool_call_id else None), + tool_call_id=(tool.get("id") if forward_function_call_id else None), ) if gemini_function_call is not None: part_dict: VertexPartType = {"function_call": gemini_function_call} @@ -1377,8 +1374,7 @@ def convert_to_gemini_tool_call_invoke( def convert_to_gemini_tool_call_result( message: Union[ChatCompletionToolMessage, ChatCompletionFunctionMessage], last_message_with_tool_calls: Optional[dict], - model: Optional[str] = None, - custom_llm_provider: Optional[str] = None, + forward_function_call_id: bool = False, ) -> Union[VertexPartType, List[VertexPartType]]: """ OpenAI message with a tool result looks like: @@ -1500,14 +1496,8 @@ def convert_to_gemini_tool_call_result( name = tool.get("function", {}).get("name", "") # Echo the OpenAI tool_call_id on functionResponse (strip thought-signature suffix). - # Only Google AI Studio Gemini 3+ accepts `id` on function_response parts. - # Vertex AI and older Gemini models reject the field with HTTP 400. - from litellm.llms.vertex_ai.gemini.vertex_and_google_ai_studio_gemini import ( - VertexGeminiConfig, - ) - gemini_call_id: Optional[str] = None - if model and VertexGeminiConfig._forward_gemini_function_call_id(model, custom_llm_provider): + if forward_function_call_id: raw_tool_call_id = message.get("tool_call_id") if raw_tool_call_id and isinstance(raw_tool_call_id, str): stripped_id = raw_tool_call_id.split(THOUGHT_SIGNATURE_SEPARATOR, 1)[0] @@ -2220,6 +2210,49 @@ def _is_orphaned_tool_result( return False +def _declared_tool_call_ids(message: Mapping[str, Any]) -> frozenset[str]: + tool_calls = message.get("tool_calls") + if not isinstance(tool_calls, list): + return frozenset() + return frozenset( + str(tool_call["id"]) for tool_call in tool_calls if isinstance(tool_call, Mapping) and tool_call.get("id") + ) + + +def group_tool_exchanges(messages: Sequence[Mapping[str, Any]]) -> tuple[tuple[int, ...], ...]: + """Group message indices into tool exchanges: an assistant row that made + tool calls, together with the tool rows answering the ids it declared. + + Membership is by ``tool_call_id`` ownership rather than adjacency, so a tool + row belonging to some other call opens its own group instead of being swept + into the exchange it happens to sit next to. Every other row is its own + group. Groups stay contiguous and in order, so a caller can convert or + protect them without reordering the conversation. + + Callers need this because an assistant row and the tool rows answering it + are only well-formed together: ``sanitize_messages_for_tool_calling`` reads + an assistant row whose results are missing as an orphaned tool call, and + a tool row whose call is missing as an orphaned result. + """ + return tuple(_iter_tool_exchange_groups(messages)) + + +def _iter_tool_exchange_groups(messages: Sequence[Mapping[str, Any]]) -> Iterator[tuple[int, ...]]: + index = 0 + while index < len(messages): + declared = _declared_tool_call_ids(messages[index]) + end = index + 1 + while ( + declared + and end < len(messages) + and messages[end].get("role") in ("tool", "function") + and str(messages[end].get("tool_call_id")) in declared + ): + end += 1 + yield tuple(range(index, end)) + index = end + + def sanitize_messages_for_tool_calling( messages: List[AllMessageValues], ) -> List[AllMessageValues]: @@ -5350,7 +5383,9 @@ def prompt_factory( def get_attribute_or_key(tool_or_function, attribute, default=None): if hasattr(tool_or_function, attribute): return getattr(tool_or_function, attribute) - return tool_or_function.get(attribute, default) + if isinstance(tool_or_function, Mapping): + return tool_or_function.get(attribute, default) + return default class NormalizedToolCall(TypedDict): @@ -5379,14 +5414,18 @@ def _parse_tool_call_arguments(raw: Any, tool_name: Optional[str], context: str) return parsed if isinstance(parsed, dict) else {} -def _tool_calls_from_chat_completion_response(response: Any) -> list[NormalizedToolCall]: +def _tool_calls_from_chat_completion_response( + response: Any, include_all_choices: bool = False +) -> list[NormalizedToolCall]: choices = get_attribute_or_key(response, "choices", None) if not (isinstance(choices, list) and choices): return [] - message = get_attribute_or_key(choices[0], "message", None) - tool_calls = get_attribute_or_key(message, "tool_calls", None) if message else None - if not isinstance(tool_calls, list): - return [] + tool_calls: list[Any] = [] + for choice in choices if include_all_choices else choices[:1]: + message = get_attribute_or_key(choice, "message", None) + choice_tool_calls = get_attribute_or_key(message, "tool_calls", None) if message else None + if isinstance(choice_tool_calls, list): + tool_calls.extend(choice_tool_calls) result: list[NormalizedToolCall] = [] for tc in tool_calls: fn = get_attribute_or_key(tc, "function", None) @@ -5449,7 +5488,7 @@ def _tool_calls_from_anthropic_messages_response(response: Any) -> list[Normaliz return result -def get_tool_calls_from_response(response: Any) -> list[NormalizedToolCall]: +def get_tool_calls_from_response(response: Any, include_all_choices: bool = False) -> list[NormalizedToolCall]: """ Extract tool/function calls from a response object into a normalized ``{"id", "name", "arguments"}`` shape, regardless of which API surface @@ -5457,11 +5496,20 @@ def get_tool_calls_from_response(response: Any) -> list[NormalizedToolCall]: the Responses API (``output`` items of type ``function_call``), or the Anthropic Messages API (``content`` blocks of type ``tool_use``). + ``include_all_choices`` decides the chat-completions scope: the default + reads only ``choices[0]``, which is what consumers that act on THE reply + (e.g. guardrails rebuilding the primary assistant message) want; usage + accounting passes True because every choice of an ``n>1`` request costs + money and its tool calls really ran. The other surfaces have a single + output, so the flag has no effect on them. + Callers that only care about a specific tool should filter the result by ``name`` themselves -- this returns every tool call found. """ + chat_tool_calls = _tool_calls_from_chat_completion_response(response, include_all_choices=include_all_choices) + if chat_tool_calls: + return chat_tool_calls for extractor in ( - _tool_calls_from_chat_completion_response, _tool_calls_from_responses_api_response, _tool_calls_from_anthropic_messages_response, ): diff --git a/litellm/llms/anthropic/chat/guardrail_translation/handler.py b/litellm/llms/anthropic/chat/guardrail_translation/handler.py index 7000c20d9c4..a549db94224 100644 --- a/litellm/llms/anthropic/chat/guardrail_translation/handler.py +++ b/litellm/llms/anthropic/chat/guardrail_translation/handler.py @@ -361,14 +361,34 @@ class AnthropicMessagesHandler(BaseTranslation): @staticmethod def _write_back_structured_messages(data: dict, structured_messages: list) -> None: - """Convert compressed structured_messages back to Anthropic format and write to data.""" + """Convert compressed structured_messages back to Anthropic format and write to data. + + ``anthropic_messages_pt`` merges every run of consecutive user/tool rows + into a single message, so a turn carrying only tool results and the user + turn that follows it come back fused, and the request the model sees no + longer has the boundaries the client sent. Converting a row at a time + would keep them apart but breaks tool pairing: an assistant row whose + tool results sit outside its own call reads as an orphaned tool call, + and under ``modify_params`` the sanitizer answers it with a synthetic + "tool execution skipped" result and drops the real one. Converting each + assistant row together with the tool rows that answer it, and every + other row on its own, satisfies both. + """ from litellm.litellm_core_utils.prompt_templates.factory import ( anthropic_messages_pt, + group_tool_exchanges, ) model = str(data.get("model") or "") non_system = [m for m in structured_messages if m.get("role") != "system"] - converted = anthropic_messages_pt(messages=non_system, model=model, llm_provider="anthropic") + groups = tuple([non_system[index] for index in group] for group in group_tool_exchanges(non_system)) or ( + non_system, + ) + converted = [ + message + for group in groups + for message in anthropic_messages_pt(messages=group, model=model, llm_provider="anthropic") + ] for msg in converted: content = msg.get("content") if isinstance(content, list): @@ -600,9 +620,15 @@ class AnthropicMessagesHandler(BaseTranslation): guardrail_inputs["tool_calls"] = tool_calls_list try: + prepared_request_data = self._prepare_request_data( + request_data, + model_response, + user_api_key_dict, + key="response", + ) _guardrailed_inputs = await guardrail_to_apply.apply_guardrail( inputs=guardrail_inputs, - request_data=request_data if request_data is not None else {}, + request_data=prepared_request_data, input_type="response", logging_obj=litellm_logging_obj, ) @@ -618,9 +644,15 @@ class AnthropicMessagesHandler(BaseTranslation): string_so_far = self.get_streaming_string_so_far(responses_so_far) try: + prepared_request_data = self._prepare_request_data( + request_data, + responses_so_far, + user_api_key_dict, + key="responses", + ) _guardrailed_inputs = await guardrail_to_apply.apply_guardrail( inputs={"texts": [string_so_far]}, - request_data=request_data if request_data is not None else {}, + request_data=prepared_request_data, input_type="response", logging_obj=litellm_logging_obj, ) diff --git a/litellm/llms/anthropic/experimental_pass_through/adapters/streaming_iterator.py b/litellm/llms/anthropic/experimental_pass_through/adapters/streaming_iterator.py index f02333c34c8..d9bcfa19a7f 100644 --- a/litellm/llms/anthropic/experimental_pass_through/adapters/streaming_iterator.py +++ b/litellm/llms/anthropic/experimental_pass_through/adapters/streaming_iterator.py @@ -28,7 +28,7 @@ from litellm.types.llms.anthropic import ( UsageDelta, UsageIteration, ) -from litellm.types.utils import AdapterCompletionStreamWrapper +from litellm.types.utils import AdapterCompletionStreamWrapper, Delta if TYPE_CHECKING: from litellm.types.utils import ModelResponseStream @@ -96,6 +96,90 @@ class _CombinedChunkSplitter: or getattr(delta, "thinking_blocks", None) ) + _PAYLOAD_FIELD_GROUPS: "tuple[tuple[str, ...], ...]" = ( + ("reasoning_content", "thinking_blocks"), + ("content",), + ("tool_calls",), + ) + + @staticmethod + def _clear_usage(chunk: "ModelResponseStream") -> None: + if hasattr(chunk, "usage"): + chunk.usage = None + hidden_params = getattr(chunk, "_hidden_params", None) + if isinstance(hidden_params, dict) and "usage" in hidden_params: + chunk._hidden_params = {key: value for key, value in hidden_params.items() if key != "usage"} + + @staticmethod + def _split_by_payload_kind(chunk: "ModelResponseStream") -> "tuple[ModelResponseStream, ...]": + """Return ``(chunk,)``, or one piece per payload kind it carries. + + Each piece's delta is rebuilt as a fresh ``Delta`` carrying exactly one + payload kind (reasoning, text, tool calls), in native Anthropic block + order: thinking, then text, then tool_use. Runs downstream of + ``_split``, which has already peeled ``finish_reason`` and usage onto + their own finish chunk. + + Chunks that must not be split pass through unchanged: multi-choice + chunks (the translators read every choice, so slicing one would drop + or repeat payload) and tool-argument continuations (splitting one + would close the in-flight ``tool_use`` block mid-arguments). A + reasoning piece whose ``thinking_blocks`` carry no signature is + normalized to ``reasoning_content`` so the synthesized block start + stays empty and the thinking text is emitted exactly once. + """ + choices = getattr(chunk, "choices", None) + if not choices or len(choices) != 1: + return (chunk,) + delta = getattr(choices[0], "delta", None) + if delta is None: + return (chunk,) + tool_calls = getattr(delta, "tool_calls", None) + if tool_calls and not any( + getattr(getattr(tool_call, "function", None), "name", None) for tool_call in tool_calls + ): + return (chunk,) + present_groups = tuple( + group + for group in _CombinedChunkSplitter._PAYLOAD_FIELD_GROUPS + if any(getattr(delta, field, None) for field in group) + ) + if len(present_groups) <= 1: + return (chunk,) + + pieces = tuple(copy.deepcopy(chunk) for _ in present_groups) + for index, (piece, group) in enumerate(zip(pieces, present_groups)): + copied_delta = piece.choices[0].delta + fields = {field: value for field in group if (value := getattr(copied_delta, field, None))} + fields = _CombinedChunkSplitter._normalize_reasoning_fields(fields) + role = getattr(copied_delta, "role", None) if index == 0 else None + piece.choices[0].delta = Delta(role=role, **fields) + return pieces + + @staticmethod + def _normalize_reasoning_fields(fields: "dict[str, Any]") -> "dict[str, Any]": + """Collapse signature-less ``thinking_blocks`` into ``reasoning_content``. + + The block opener seeds a ``thinking_blocks`` start body with the full + thinking text while the delta re-emits it, so SSE accumulators would + collect it twice; the ``reasoning_content`` branch opens an empty body. + Signature-carrying blocks are kept intact so ``signature_delta`` + suppression of the full-text snapshot still applies. + """ + thinking_blocks = fields.get("thinking_blocks") + if not thinking_blocks: + return fields + if any(block.get("signature") for block in thinking_blocks if isinstance(block, dict)): + return fields + thinking_text = "".join( + block.get("thinking") or "" + for block in thinking_blocks + if isinstance(block, dict) and block.get("type") == "thinking" + ) + if not thinking_text: + return fields + return {"reasoning_content": thinking_text} + @staticmethod def _split(chunk: Any) -> List[Any]: """Return ``[chunk]``, or ``[content_chunk, finish_chunk]`` if combined.""" @@ -105,6 +189,7 @@ class _CombinedChunkSplitter: # Content chunk: keep the delta payload, clear the finish_reason. content_chunk = copy.deepcopy(chunk) content_chunk.choices[0].finish_reason = None + _CombinedChunkSplitter._clear_usage(content_chunk) # Finish chunk: keep finish_reason (and usage), clear the delta payload. finish_chunk = copy.deepcopy(chunk) @@ -127,7 +212,11 @@ class _CombinedChunkSplitter: if self._sync_iter is None: self._sync_iter = iter(self._stream) chunk = next(self._sync_iter) # propagates StopIteration when exhausted - self._buffer.extend(self._split(chunk)) + self._buffer.extend( + split_chunk + for combined_chunk in self._split(chunk) + for split_chunk in self._split_by_payload_kind(combined_chunk) + ) return self._buffer.popleft() def __aiter__(self) -> "AsyncIterator[Any]": @@ -139,7 +228,11 @@ class _CombinedChunkSplitter: if self._async_iter is None: self._async_iter = self._stream.__aiter__() chunk = await self._async_iter.__anext__() # propagates StopAsyncIteration - self._buffer.extend(self._split(chunk)) + self._buffer.extend( + split_chunk + for combined_chunk in self._split(chunk) + for split_chunk in self._split_by_payload_kind(combined_chunk) + ) return self._buffer.popleft() @@ -393,24 +486,25 @@ class AnthropicStreamWrapper(AdapterCompletionStreamWrapper): if compaction_event is not None: return compaction_event - if self.sent_content_block_start is False: - self.sent_content_block_start = True - self.sent_content_block_finish = False - self.chunk_queue.append( - { - "type": "content_block_start", - "index": self.current_content_block_index, - "content_block": {"type": "text", "text": ""}, - } - ) - return self.chunk_queue.popleft() - for chunk in self.completion_stream: if chunk == "None" or chunk is None: raise Exception should_start_new_block = self._should_start_new_content_block(chunk) - if should_start_new_block: + is_opening_first_block = self.sent_content_block_start is False + if is_opening_first_block and self._is_blank_delta(chunk): + continue + if is_opening_first_block: + self.sent_content_block_start = True + self.sent_content_block_finish = False + self.chunk_queue.append( + { + "type": "content_block_start", + "index": self.current_content_block_index, + "content_block": self.current_content_block_start, + } + ) + elif should_start_new_block: self._increment_content_block_index() # applied_edits only needs to flow to the final message_delta @@ -447,7 +541,7 @@ class AnthropicStreamWrapper(AdapterCompletionStreamWrapper): # ``not self.queued_usage_chunk``. continue - if should_start_new_block and not self.sent_content_block_finish: + if should_start_new_block and not is_opening_first_block and not self.sent_content_block_finish: # Queue the sequence: content_block_stop -> content_block_start # -> (optionally) the trigger chunk's delta. # @@ -615,25 +709,25 @@ class AnthropicStreamWrapper(AdapterCompletionStreamWrapper): if compaction_event is not None: return compaction_event - if self.sent_content_block_start is False: - self.sent_content_block_start = True - self.sent_content_block_finish = False - self.chunk_queue.append( - { - "type": "content_block_start", - "index": self.current_content_block_index, - "content_block": {"type": "text", "text": ""}, - } - ) - return self.chunk_queue.popleft() - async for chunk in self.completion_stream: if chunk == "None" or chunk is None: raise Exception - # Check if we need to start a new content block should_start_new_block = self._should_start_new_content_block(chunk) - if should_start_new_block: + is_opening_first_block = self.sent_content_block_start is False + if is_opening_first_block and self._is_blank_delta(chunk): + continue + if is_opening_first_block: + self.sent_content_block_start = True + self.sent_content_block_finish = False + self.chunk_queue.append( + { + "type": "content_block_start", + "index": self.current_content_block_index, + "content_block": self.current_content_block_start, + } + ) + elif should_start_new_block: self._increment_content_block_index() # applied_edits only needs to flow to the final message_delta @@ -664,7 +758,7 @@ class AnthropicStreamWrapper(AdapterCompletionStreamWrapper): # Check if this processed chunk has a stop_reason - hold it for next chunk if not self.queued_usage_chunk: - if should_start_new_block and not self.sent_content_block_finish: + if should_start_new_block and not is_opening_first_block and not self.sent_content_block_finish: # Queue the sequence: content_block_stop -> content_block_start # -> (optionally) the trigger chunk's delta. # @@ -875,6 +969,22 @@ class AnthropicStreamWrapper(AdapterCompletionStreamWrapper): return False return bool(delta.get(_delta_payload_field(delta_type))) + @staticmethod + def _is_blank_delta(chunk: "ModelResponseStream") -> bool: + choice = chunk.choices[0] + if choice.finish_reason is not None: + return False + delta = choice.delta + if getattr(delta, "tool_calls", None): + return False + if getattr(delta, "content", None): + return False + if getattr(delta, "reasoning_content", None): + return False + if getattr(delta, "thinking_blocks", None): + return False + return True + def _should_start_new_content_block(self, chunk: "ModelResponseStream") -> bool: """ Determine if we should start a new content block based on the processed chunk. diff --git a/litellm/llms/anthropic/experimental_pass_through/adapters/transformation.py b/litellm/llms/anthropic/experimental_pass_through/adapters/transformation.py index 4b6617fbeac..86c9c1db481 100644 --- a/litellm/llms/anthropic/experimental_pass_through/adapters/transformation.py +++ b/litellm/llms/anthropic/experimental_pass_through/adapters/transformation.py @@ -331,6 +331,7 @@ class LiteLLMAnthropicMessagesAdapter: "thinking", "output_format", "output_config", + "stop_sequences", ] def _is_web_search_tool(self, tool: Dict[str, Any]) -> bool: @@ -615,7 +616,7 @@ class LiteLLMAnthropicMessagesAdapter: thinking_type = thinking.get("type", "disabled") if thinking_type == "disabled": - return None + return "none" elif thinking_type == "enabled": return reasoning_effort_from_thinking_budget(thinking.get("budget_tokens", 0)) elif thinking_type == "adaptive": @@ -683,25 +684,37 @@ class LiteLLMAnthropicMessagesAdapter: thinking ) if reasoning_effort: - summary = thinking.get("summary") if isinstance(thinking, dict) else None - auto_summary = is_reasoning_auto_summary_enabled() - if summary: - return { - "reasoning_effort": { - "effort": reasoning_effort, - "summary": summary, - } - } - elif auto_summary: - return { - "reasoning_effort": { - "effort": reasoning_effort, - "summary": "detailed", - } - } - return {"reasoning_effort": reasoning_effort} + return { + "reasoning_effort": LiteLLMAnthropicMessagesAdapter._apply_reasoning_summary_wrapping( + reasoning_effort, thinking + ) + } return {} + @staticmethod + def _apply_reasoning_summary_wrapping( + reasoning_effort: str, + thinking: Dict[str, Any], + ) -> Any: + """ + Apply the reasoning_effort/summary wrapping rules shared by every + thinking->reasoning_effort translation path. + + Disabled thinking always stays a plain string - there's no reasoning + trace to summarize, and non-Claude providers (e.g. Fireworks) expect + reasoning_effort as a plain string, not a summary dict. + """ + thinking_type = thinking.get("type") if isinstance(thinking, dict) else None + if thinking_type == "disabled": + return reasoning_effort + + summary = thinking.get("summary") if isinstance(thinking, dict) else None + if summary: + return {"effort": reasoning_effort, "summary": summary} + if is_reasoning_auto_summary_enabled(): + return {"effort": reasoning_effort, "summary": "detailed"} + return reasoning_effort + def translate_anthropic_tool_choice_to_openai( self, tool_choice: AnthropicMessagesToolChoice ) -> ChatCompletionToolChoiceValues: @@ -919,6 +932,18 @@ class LiteLLMAnthropicMessagesAdapter: tool_choice=cast(AnthropicMessagesToolChoice, tool_choice) ) + def _translate_stop_sequences_to_openai( + self, + anthropic_message_request: AnthropicMessagesRequest, + new_kwargs: ChatCompletionRequest, + ) -> None: + if "stop_sequences" not in anthropic_message_request: + return + stop_sequences = anthropic_message_request["stop_sequences"] + if not stop_sequences: + return + new_kwargs["stop"] = stop_sequences + def _translate_tools_to_openai( self, anthropic_message_request: AnthropicMessagesRequest, @@ -976,32 +1001,17 @@ class LiteLLMAnthropicMessagesAdapter: if not reasoning_effort: return + thinking_type = thinking.get("type") if isinstance(thinking, dict) else None + # For adaptive thinking, override with output_config.effort if available - if isinstance(thinking, dict) and thinking.get("type") == "adaptive": + if thinking_type == "adaptive": output_config = anthropic_message_request.get("output_config") if isinstance(output_config, dict) and output_config.get("effort"): reasoning_effort = output_config["effort"] - summary = thinking.get("summary") if isinstance(thinking, dict) else None - auto_summary = is_reasoning_auto_summary_enabled() - if summary: - new_kwargs["reasoning_effort"] = cast( - Any, - { - "effort": reasoning_effort, - "summary": summary, - }, - ) - elif auto_summary: - new_kwargs["reasoning_effort"] = cast( - Any, - { - "effort": reasoning_effort, - "summary": "detailed", - }, - ) - else: - new_kwargs["reasoning_effort"] = reasoning_effort + new_kwargs["reasoning_effort"] = self._apply_reasoning_summary_wrapping( + reasoning_effort, cast(Dict[str, Any], thinking) + ) def _translate_output_format_to_openai( self, @@ -1098,6 +1108,11 @@ class LiteLLMAnthropicMessagesAdapter: anthropic_message_request=anthropic_message_request, new_kwargs=new_kwargs, ) + ## CONVERT STOP_SEQUENCES + self._translate_stop_sequences_to_openai( + anthropic_message_request=anthropic_message_request, + new_kwargs=new_kwargs, + ) ## CONVERT OUTPUT_FORMAT to RESPONSE_FORMAT self._translate_output_format_to_openai( anthropic_message_request=anthropic_message_request, diff --git a/litellm/llms/anthropic/experimental_pass_through/messages/interceptors/advisor.py b/litellm/llms/anthropic/experimental_pass_through/messages/interceptors/advisor.py index 79faa39c7a2..a36f825951a 100644 --- a/litellm/llms/anthropic/experimental_pass_through/messages/interceptors/advisor.py +++ b/litellm/llms/anthropic/experimental_pass_through/messages/interceptors/advisor.py @@ -21,6 +21,7 @@ import litellm import litellm.constants as _c from litellm.litellm_core_utils.url_utils import validate_url from litellm.llms.anthropic.common_utils import strip_advisor_blocks_from_messages +from litellm.router_utils.cooldown_handlers import mark_advisor_orchestration_failure from litellm.types.llms.anthropic_messages.anthropic_response import ( AnthropicMessagesResponse, ) @@ -124,30 +125,36 @@ class AdvisorOrchestrationHandler(MessagesInterceptor): iteration += 1 if iteration > max_uses: - raise AdvisorMaxIterationsError( + max_iterations_error = AdvisorMaxIterationsError( f"Advisor orchestration loop exceeded max_uses={max_uses}. " "Increase max_uses in the advisor tool definition or cap the request." ) + mark_advisor_orchestration_failure(max_iterations_error) + raise max_iterations_error # --- Build advisor context --- advisor_messages = _build_advisor_context(current_messages, executor_response, advisor_use_block) # --- Advisor sub-call (always non-streaming, no tools) --- - advisor_response: AnthropicMessagesResponse = await _call_messages_handler( - model=advisor_model, - messages=advisor_messages, - tools=None, - stream=False, - max_tokens=max_tokens, - custom_llm_provider=None, # let litellm resolve from model name - metadata={ - **metadata_base, - "advisor_sub_call": True, - "parent_request_id": parent_request_id, - }, - api_key=advisor_api_key, - api_base=advisor_api_base, - ) + try: + advisor_response: AnthropicMessagesResponse = await _call_messages_handler( + model=advisor_model, + messages=advisor_messages, + tools=None, + stream=False, + max_tokens=max_tokens, + custom_llm_provider=None, # let litellm resolve from model name + metadata={ + **metadata_base, + "advisor_sub_call": True, + "parent_request_id": parent_request_id, + }, + api_key=advisor_api_key, + api_base=advisor_api_base, + ) + except Exception as advisor_sub_call_exception: + mark_advisor_orchestration_failure(advisor_sub_call_exception) + raise advisor_text = _extract_response_text(advisor_response) diff --git a/litellm/llms/azure/batches/handler.py b/litellm/llms/azure/batches/handler.py index 808fb3d9600..4a064756295 100644 --- a/litellm/llms/azure/batches/handler.py +++ b/litellm/llms/azure/batches/handler.py @@ -2,7 +2,8 @@ Azure Batches API Handler """ -from typing import Any, Coroutine, Optional, Union, cast +from collections.abc import Coroutine +from typing import cast import httpx from openai import AsyncOpenAI, OpenAI @@ -33,32 +34,30 @@ class AzureBatchesAPI(BaseAzureLLM): async def acreate_batch( self, create_batch_data: CreateBatchRequest, - azure_client: Union[AsyncAzureOpenAI, AsyncOpenAI], + azure_client: AsyncAzureOpenAI | AsyncOpenAI, ) -> LiteLLMBatch: response = await azure_client.batches.create(**create_batch_data) # type: ignore[arg-type] - return LiteLLMBatch(**response.model_dump()) + return LiteLLMBatch.model_validate(response.model_dump()) def create_batch( self, _is_async: bool, create_batch_data: CreateBatchRequest, - api_key: Optional[str], - api_base: Optional[str], - api_version: Optional[str], - timeout: Union[float, httpx.Timeout], - max_retries: Optional[int], - client: Optional[Union[AzureOpenAI, AsyncAzureOpenAI, OpenAI, AsyncOpenAI]] = None, - litellm_params: Optional[dict] = None, - ) -> Union[LiteLLMBatch, Coroutine[Any, Any, LiteLLMBatch]]: - azure_client: Optional[Union[AzureOpenAI, AsyncAzureOpenAI, OpenAI, AsyncOpenAI]] = ( - self.get_azure_openai_client( - api_key=api_key, - api_base=api_base, - api_version=api_version, - client=client, - _is_async=_is_async, - litellm_params=litellm_params or {}, - ) + api_key: str | None, + api_base: str | None, + api_version: str | None, + timeout: float | httpx.Timeout, + max_retries: int | None, + client: AzureOpenAI | AsyncAzureOpenAI | OpenAI | AsyncOpenAI | None = None, + litellm_params: dict | None = None, + ) -> LiteLLMBatch | Coroutine[object, object, LiteLLMBatch]: + azure_client: AzureOpenAI | AsyncAzureOpenAI | OpenAI | AsyncOpenAI | None = self.get_azure_openai_client( + api_key=api_key, + api_base=api_base, + api_version=api_version, + client=client, + _is_async=_is_async, + litellm_params=litellm_params or {}, ) if azure_client is None: raise ValueError( @@ -73,38 +72,36 @@ class AzureBatchesAPI(BaseAzureLLM): return self.acreate_batch( # type: ignore create_batch_data=create_batch_data, azure_client=azure_client ) - response = cast(Union[AzureOpenAI, OpenAI], azure_client).batches.create(**create_batch_data) # type: ignore[arg-type] - return LiteLLMBatch(**response.model_dump()) + response = cast(AzureOpenAI | OpenAI, azure_client).batches.create(**create_batch_data) # type: ignore[arg-type] + return LiteLLMBatch.model_validate(response.model_dump()) async def aretrieve_batch( self, retrieve_batch_data: RetrieveBatchRequest, - client: Union[AsyncAzureOpenAI, AsyncOpenAI], + client: AsyncAzureOpenAI | AsyncOpenAI, ) -> LiteLLMBatch: response = await client.batches.retrieve(**retrieve_batch_data) # type: ignore[arg-type] - return LiteLLMBatch(**response.model_dump()) + return LiteLLMBatch.model_validate(response.model_dump()) def retrieve_batch( self, _is_async: bool, retrieve_batch_data: RetrieveBatchRequest, - api_key: Optional[str], - api_base: Optional[str], - api_version: Optional[str], - timeout: Union[float, httpx.Timeout], - max_retries: Optional[int], - client: Optional[Union[AzureOpenAI, AsyncAzureOpenAI, OpenAI, AsyncOpenAI]] = None, - litellm_params: Optional[dict] = None, + api_key: str | None, + api_base: str | None, + api_version: str | None, + timeout: float | httpx.Timeout, + max_retries: int | None, + client: AzureOpenAI | AsyncAzureOpenAI | OpenAI | AsyncOpenAI | None = None, + litellm_params: dict | None = None, ): - azure_client: Optional[Union[AzureOpenAI, AsyncAzureOpenAI, OpenAI, AsyncOpenAI]] = ( - self.get_azure_openai_client( - api_key=api_key, - api_base=api_base, - api_version=api_version, - client=client, - _is_async=_is_async, - litellm_params=litellm_params or {}, - ) + azure_client: AzureOpenAI | AsyncAzureOpenAI | OpenAI | AsyncOpenAI | None = self.get_azure_openai_client( + api_key=api_key, + api_base=api_base, + api_version=api_version, + client=client, + _is_async=_is_async, + litellm_params=litellm_params or {}, ) if azure_client is None: raise ValueError( @@ -119,38 +116,36 @@ class AzureBatchesAPI(BaseAzureLLM): return self.aretrieve_batch( # type: ignore retrieve_batch_data=retrieve_batch_data, client=azure_client ) - response = cast(Union[AzureOpenAI, OpenAI], azure_client).batches.retrieve(**retrieve_batch_data) - return LiteLLMBatch(**response.model_dump()) + response = cast(AzureOpenAI | OpenAI, azure_client).batches.retrieve(**retrieve_batch_data) + return LiteLLMBatch.model_validate(response.model_dump()) async def acancel_batch( self, cancel_batch_data: CancelBatchRequest, - client: Union[AsyncAzureOpenAI, AsyncOpenAI], + client: AsyncAzureOpenAI | AsyncOpenAI, ) -> LiteLLMBatch: response = await client.batches.cancel(**cancel_batch_data) - return LiteLLMBatch(**response.model_dump()) + return LiteLLMBatch.model_validate(response.model_dump()) def cancel_batch( self, _is_async: bool, cancel_batch_data: CancelBatchRequest, - api_key: Optional[str], - api_base: Optional[str], - api_version: Optional[str], - timeout: Union[float, httpx.Timeout], - max_retries: Optional[int], - client: Optional[Union[AzureOpenAI, AsyncAzureOpenAI, OpenAI, AsyncOpenAI]] = None, - litellm_params: Optional[dict] = None, + api_key: str | None, + api_base: str | None, + api_version: str | None, + timeout: float | httpx.Timeout, + max_retries: int | None, + client: AzureOpenAI | AsyncAzureOpenAI | OpenAI | AsyncOpenAI | None = None, + litellm_params: dict | None = None, ): - azure_client: Optional[Union[AzureOpenAI, AsyncAzureOpenAI, OpenAI, AsyncOpenAI]] = ( - self.get_azure_openai_client( - api_key=api_key, - api_base=api_base, - api_version=api_version, - client=client, - _is_async=_is_async, - litellm_params=litellm_params or {}, - ) + azure_client: AzureOpenAI | AsyncAzureOpenAI | OpenAI | AsyncOpenAI | None = self.get_azure_openai_client( + api_key=api_key, + api_base=api_base, + api_version=api_version, + client=client, + _is_async=_is_async, + litellm_params=litellm_params or {}, ) if azure_client is None: raise ValueError( @@ -172,13 +167,13 @@ class AzureBatchesAPI(BaseAzureLLM): "Azure client is not an instance of AzureOpenAI or OpenAI. Make sure you passed a sync client." ) response = azure_client.batches.cancel(**cancel_batch_data) - return LiteLLMBatch(**response.model_dump()) + return LiteLLMBatch.model_validate(response.model_dump()) async def alist_batches( self, - client: Union[AsyncAzureOpenAI, AsyncOpenAI], - after: Optional[str] = None, - limit: Optional[int] = None, + client: AsyncAzureOpenAI | AsyncOpenAI, + after: str | None = None, + limit: int | None = None, ): response = await client.batches.list(after=after, limit=limit) # type: ignore return response @@ -186,25 +181,23 @@ class AzureBatchesAPI(BaseAzureLLM): def list_batches( self, _is_async: bool, - api_key: Optional[str], - api_base: Optional[str], - api_version: Optional[str], - timeout: Union[float, httpx.Timeout], - max_retries: Optional[int], - after: Optional[str] = None, - limit: Optional[int] = None, - client: Optional[Union[AzureOpenAI, AsyncAzureOpenAI, OpenAI, AsyncOpenAI]] = None, - litellm_params: Optional[dict] = None, + api_key: str | None, + api_base: str | None, + api_version: str | None, + timeout: float | httpx.Timeout, + max_retries: int | None, + after: str | None = None, + limit: int | None = None, + client: AzureOpenAI | AsyncAzureOpenAI | OpenAI | AsyncOpenAI | None = None, + litellm_params: dict | None = None, ): - azure_client: Optional[Union[AzureOpenAI, AsyncAzureOpenAI, OpenAI, AsyncOpenAI]] = ( - self.get_azure_openai_client( - api_key=api_key, - api_base=api_base, - api_version=api_version, - client=client, - _is_async=_is_async, - litellm_params=litellm_params or {}, - ) + azure_client: AzureOpenAI | AsyncAzureOpenAI | OpenAI | AsyncOpenAI | None = self.get_azure_openai_client( + api_key=api_key, + api_base=api_base, + api_version=api_version, + client=client, + _is_async=_is_async, + litellm_params=litellm_params or {}, ) if azure_client is None: raise ValueError( diff --git a/litellm/llms/azure_ai/anthropic/count_tokens/transformation.py b/litellm/llms/azure_ai/anthropic/count_tokens/transformation.py index 5e1fb69f40d..ba930f40059 100644 --- a/litellm/llms/azure_ai/anthropic/count_tokens/transformation.py +++ b/litellm/llms/azure_ai/anthropic/count_tokens/transformation.py @@ -4,8 +4,6 @@ Azure AI Anthropic CountTokens API transformation logic. Extends the base Anthropic CountTokens transformation with Azure authentication. """ -from typing import Any, Dict, Optional - from litellm.constants import ANTHROPIC_TOKEN_COUNTING_BETA_VERSION from litellm.llms.anthropic.count_tokens.transformation import ( AnthropicCountTokensConfig, @@ -25,8 +23,8 @@ class AzureAIAnthropicCountTokensConfig(AnthropicCountTokensConfig): def get_required_headers( self, api_key: str, - litellm_params: Optional[Dict[str, Any]] = None, - ) -> Dict[str, str]: + litellm_params: dict[str, object] | None = None, + ) -> dict[str, str]: """ Get the required headers for the Azure AI Anthropic CountTokens API. @@ -53,7 +51,7 @@ class AzureAIAnthropicCountTokensConfig(AnthropicCountTokensConfig): if "api_key" not in litellm_params: litellm_params["api_key"] = api_key - litellm_params_obj = GenericLiteLLMParams(**litellm_params) + litellm_params_obj = GenericLiteLLMParams.model_validate(litellm_params) # Get Azure auth headers (api-key or Authorization) azure_headers = BaseAzureLLM._base_validate_azure_environment(headers={}, litellm_params=litellm_params_obj) diff --git a/litellm/llms/bedrock/base_aws_llm.py b/litellm/llms/bedrock/base_aws_llm.py index df811f8d262..6b89fb69739 100644 --- a/litellm/llms/bedrock/base_aws_llm.py +++ b/litellm/llms/bedrock/base_aws_llm.py @@ -78,8 +78,10 @@ class BaseAWSLLM: # Storage is in-process memory only: default ``DualCache()`` has no Redis backend unless attached # elsewhere. Entry TTL: static access-key + secret + region use ``_get_default_ttl_for_boto3_credentials`` # (~59 minutes); ambient env (``_auth_with_env_vars`` returns ``ttl=None``) uses ``InMemoryCache``'s - # ``default_ttl`` (600 seconds / 10 minutes). AssumeRole, web identity, profiles, and explicit - # session-token tuples are not cached — see ``get_credentials`` and ``_get_or_set_cached_credentials``. + # ``default_ttl`` (600 seconds / 10 minutes); web identity STS credentials use + # ``_get_default_ttl_for_boto3_credentials`` (~59 minutes), keyed on all aws_* credential args + # plus ssl_verify. AssumeRole, profiles, and explicit session-token tuples are not cached — see + # ``get_credentials`` and ``_get_or_set_cached_credentials``. _shared_iam_cache: ClassVar[DualCache] = DualCache() def __init__(self) -> None: @@ -136,11 +138,12 @@ class BaseAWSLLM: which ``InMemoryCache.set_cache`` resolves to ``default_ttl`` (600 seconds / 10 minutes by default). - Used only for static access-key credentials and ambient credentials from + Used for static access-key credentials, ambient credentials from ``_auth_with_env_vars`` (including when skipping AssumeRole because the runtime identity - already matches ``aws_role_name``). + already matches ``aws_role_name``), and web identity STS credentials (plain + non-refreshable ``Credentials`` cached ~59 min, inside the 3600s STS session). - AssumeRole, web identity exchange, profiles, and explicit session-token tuples are not + AssumeRole, profiles, and explicit session-token tuples are not cached here — shared ``Credentials`` / refresh state must not span logical sessions. """ cache_key = self.get_cache_key(credential_args) @@ -266,23 +269,26 @@ class BaseAWSLLM: # Credentials - boto3.Credentials # cache ttl - Optional[int]. If None, the credentials are not cached. Some auth flows have no expiry time. # - # iam_cache: static keys and ambient env only (including skip-AssumeRole path). - # Do not cache AssumeRole / web identity / profile / explicit session-token paths here. + # iam_cache: static keys, ambient env (including skip-AssumeRole path), and web identity. + # Do not cache AssumeRole / profile / explicit session-token paths here. ######################################################### if self._is_auth_with_web_identity_token( aws_web_identity_token, aws_role_name, aws_session_name, ): - credentials, _cache_ttl = self._auth_with_web_identity_token( - aws_web_identity_token=cast(str, aws_web_identity_token), - aws_role_name=cast(str, aws_role_name), - aws_session_name=cast(str, aws_session_name), - aws_region_name=aws_region_name, - aws_sts_endpoint=aws_sts_endpoint, - aws_external_id=aws_external_id, + return self._get_or_set_cached_credentials( + args, + lambda: self._auth_with_web_identity_token( + aws_web_identity_token=cast(str, aws_web_identity_token), + aws_role_name=cast(str, aws_role_name), + aws_session_name=cast(str, aws_session_name), + aws_region_name=aws_region_name, + aws_sts_endpoint=aws_sts_endpoint, + aws_external_id=aws_external_id, + ssl_verify=ssl_verify, + ), ) - return credentials elif self._is_auth_with_aws_role(aws_role_name): # Same role (IRSA/ECS/EC2): ambient creds via _get_or_set_cached_credentials like the # default env branch; never pre-read cache (must run _is_already_running_as_role first). diff --git a/litellm/llms/bedrock/chat/__init__.py b/litellm/llms/bedrock/chat/__init__.py index c1323b9192a..37dcb270743 100644 --- a/litellm/llms/bedrock/chat/__init__.py +++ b/litellm/llms/bedrock/chat/__init__.py @@ -5,7 +5,6 @@ from .invoke_handler import ( AmazonAnthropicClaudeStreamDecoder, AmazonDeepSeekR1StreamDecoder, AWSEventStreamDecoder, - BedrockLLM, ) diff --git a/litellm/llms/bedrock/chat/invoke_handler.py b/litellm/llms/bedrock/chat/invoke_handler.py index 4c256be1ab8..c28627d5aec 100644 --- a/litellm/llms/bedrock/chat/invoke_handler.py +++ b/litellm/llms/bedrock/chat/invoke_handler.py @@ -1,19 +1,10 @@ -""" -TODO: DELETE FILE. Bedrock LLM is no longer used. Goto `litellm/llms/bedrock/chat/invoke_transformations/base_invoke_transformation.py` -""" - -import copy -import time import types -from functools import partial from typing import ( AsyncIterator, - Callable, Iterator, Optional, Tuple, cast, - get_args, ) import httpx # type: ignore @@ -25,16 +16,6 @@ from litellm.caching.caching import InMemoryCache from litellm.constants import RESPONSE_FORMAT_TOOL_NAME from litellm.litellm_core_utils.core_helpers import map_finish_reason from litellm.litellm_core_utils.litellm_logging import Logging -from litellm.litellm_core_utils.logging_utils import track_llm_api_timing -from litellm.litellm_core_utils.prompt_templates.factory import ( - cohere_message_pt, - construct_tool_use_system_prompt, - contains_tag, - custom_prompt, - extract_between_tags, - parse_xml_params, - prompt_factory, -) from litellm.llms.anthropic.chat.handler import ( ModelResponseIterator as AnthropicModelResponseIterator, ) @@ -64,12 +45,9 @@ from litellm.types.utils import ( StreamingChoices, Usage, ) -from litellm.utils import CustomStreamWrapper, get_secret -from ..base_aws_llm import BaseAWSLLM from ..common_utils import ( BedrockError, - ModelResponseIterator, build_bedrock_stream_error, get_bedrock_response_stream_shape, get_bedrock_tool_name, @@ -77,9 +55,6 @@ from ..common_utils import ( bedrock_tool_name_mappings: InMemoryCache = InMemoryCache(max_size_in_memory=50, default_ttl=600) from litellm.llms.bedrock.chat.converse_transformation import AmazonConverseConfig -from litellm.llms.bedrock.chat.invoke_transformations.amazon_openai_transformation import ( - AmazonBedrockOpenAIConfig, -) converse_config = AmazonConverseConfig() @@ -351,932 +326,6 @@ def make_sync_call( raise BedrockError(status_code=500, message=str(e)) -class BedrockLLM(BaseAWSLLM): - """ - Example call - - ``` - curl --location --request POST 'https://bedrock-runtime.{aws_region_name}.amazonaws.com/model/{bedrock_model_name}/invoke' \ - --header 'Content-Type: application/json' \ - --header 'Accept: application/json' \ - --user "$AWS_ACCESS_KEY_ID":"$AWS_SECRET_ACCESS_KEY" \ - --aws-sigv4 "aws:amz:us-east-1:bedrock" \ - --data-raw '{ - "prompt": "Hi", - "temperature": 0, - "p": 0.9, - "max_tokens": 4096 - }' - ``` - """ - - def __init__(self) -> None: - super().__init__() - - @staticmethod - def is_claude_messages_api_model(model: str) -> bool: - """ - Check if the model uses the Claude Messages API (Claude 3+). - - Handles: - - Regional prefixes: eu.anthropic.claude-*, us.anthropic.claude-* - - Claude 3 models: claude-3-haiku, claude-3-sonnet, claude-3-opus, claude-3-5-*, claude-3-7-* - - Claude 4 models: claude-opus-4, claude-sonnet-4, claude-haiku-4 - """ - # Normalize model string to lowercase for matching - model_lower = model.lower() - - # Claude 3+ indicators (all use Messages API) - messages_api_indicators = [ - "claude-3", # Claude 3.x models - "claude-opus-4", # Claude Opus 4 - "claude-sonnet-4", # Claude Sonnet 4 - "claude-haiku-4", # Claude Haiku 4 - ] - - return any(indicator in model_lower for indicator in messages_api_indicators) - - def convert_messages_to_prompt(self, model, messages, provider, custom_prompt_dict) -> Tuple[str, Optional[list]]: - # handle anthropic prompts and amazon titan prompts - prompt = "" - chat_history: Optional[list] = None - ## CUSTOM PROMPT - if model in custom_prompt_dict: - # check if the model has a registered custom prompt - model_prompt_details = custom_prompt_dict[model] - prompt = custom_prompt( - role_dict=model_prompt_details["roles"], - initial_prompt_value=model_prompt_details.get("initial_prompt_value", ""), - final_prompt_value=model_prompt_details.get("final_prompt_value", ""), - messages=messages, - ) - return prompt, None - ## ELSE - if provider == "anthropic" or provider == "amazon": - prompt = prompt_factory(model=model, messages=messages, custom_llm_provider="bedrock") - elif provider == "mistral": - prompt = prompt_factory(model=model, messages=messages, custom_llm_provider="bedrock") - elif provider == "meta" or provider == "llama": - prompt = prompt_factory(model=model, messages=messages, custom_llm_provider="bedrock") - elif provider == "openai": - # OpenAI uses messages directly, no prompt conversion needed - # Return empty prompt as it won't be used - prompt = "" - elif provider == "cohere": - prompt, chat_history = cohere_message_pt(messages=messages) - else: - prompt = "" - for message in messages: - if "role" in message: - if message["role"] == "user": - prompt += f"{message['content']}" - else: - prompt += f"{message['content']}" - else: - prompt += f"{message['content']}" - return prompt, chat_history # type: ignore - - def process_response( - self, - model: str, - response: httpx.Response, - model_response: ModelResponse, - stream: Optional[bool], - logging_obj: Logging, - optional_params: dict, - api_key: str, - data: Union[dict, str], - messages: List, - print_verbose, - encoding, - ) -> Union[ModelResponse, CustomStreamWrapper]: - provider = self.get_bedrock_invoke_provider(model) - ## LOGGING - logging_obj.post_call( - input=messages, - api_key=api_key, - original_response=response.text, - additional_args={"complete_input_dict": data}, - ) - print_verbose(f"raw model_response: {response.text}") - - ## RESPONSE OBJECT - try: - completion_response = response.json() - except Exception: - raise BedrockError(message=response.text, status_code=422) - - outputText: Optional[str] = None - try: - if provider == "cohere": - if "text" in completion_response: - outputText = completion_response["text"] # type: ignore - elif "generations" in completion_response: - outputText = completion_response["generations"][0]["text"] - model_response.choices[0].finish_reason = map_finish_reason( - completion_response["generations"][0]["finish_reason"] - ) - elif provider == "anthropic": - if self.is_claude_messages_api_model(model): - json_schemas: dict = {} - _is_function_call = False - ## Handle Tool Calling - if "tools" in optional_params: - _is_function_call = True - for tool in optional_params["tools"]: - json_schemas[tool["function"]["name"]] = tool["function"].get("parameters", None) - outputText = completion_response.get("content")[0].get("text", None) - if outputText is not None and contains_tag("invoke", outputText): # OUTPUT PARSE FUNCTION CALL - function_name = extract_between_tags("tool_name", outputText)[0] - function_arguments_str = extract_between_tags("invoke", outputText)[0].strip() - function_arguments_str = f"{function_arguments_str}" - function_arguments = parse_xml_params( - function_arguments_str, - json_schema=json_schemas.get( - function_name, None - ), # check if we have a json schema for this function name) - ) - _message = litellm.Message( - tool_calls=[ - { - "id": f"call_{uuid.uuid4()}", - "type": "function", - "function": { - "name": function_name, - "arguments": json.dumps(function_arguments), - }, - } - ], - content=None, - ) - model_response.choices[0].message = _message # type: ignore - model_response._hidden_params["original_response"] = ( - outputText # allow user to access raw anthropic tool calling response - ) - if _is_function_call is True and stream is not None and stream is True: - print_verbose("INSIDE BEDROCK STREAMING TOOL CALLING CONDITION BLOCK") - # return an iterator - streaming_model_response = ModelResponseStream() - streaming_model_response.choices[0].finish_reason = getattr( - model_response.choices[0], "finish_reason", "stop" - ) - # streaming_model_response.choices = [litellm.utils.StreamingChoices()] - streaming_choice = litellm.utils.StreamingChoices() - streaming_choice.index = model_response.choices[0].index - _tool_calls = [] - print_verbose(f"type of model_response.choices[0]: {type(model_response.choices[0])}") - print_verbose(f"type of streaming_choice: {type(streaming_choice)}") - if isinstance(model_response.choices[0], litellm.Choices): - if getattr( - model_response.choices[0].message, "tool_calls", None - ) is not None and isinstance(model_response.choices[0].message.tool_calls, list): - for tool_call in model_response.choices[0].message.tool_calls: - _tool_call = {**tool_call.dict(), "index": 0} - _tool_calls.append(_tool_call) - delta_obj = Delta( - content=getattr(model_response.choices[0].message, "content", None), - role=model_response.choices[0].message.role, - tool_calls=_tool_calls, - ) - streaming_choice.delta = delta_obj - streaming_model_response.choices = [streaming_choice] - completion_stream = ModelResponseIterator(model_response=streaming_model_response) - print_verbose( - "Returns anthropic CustomStreamWrapper with 'cached_response' streaming object" - ) - return litellm.CustomStreamWrapper( - completion_stream=completion_stream, - model=model, - custom_llm_provider="cached_response", - logging_obj=logging_obj, - ) - - model_response.choices[0].finish_reason = map_finish_reason( - completion_response.get("stop_reason", "") - ) - _usage = litellm.Usage( - prompt_tokens=completion_response["usage"]["input_tokens"], - completion_tokens=completion_response["usage"]["output_tokens"], - total_tokens=completion_response["usage"]["input_tokens"] - + completion_response["usage"]["output_tokens"], - ) - setattr(model_response, "usage", _usage) - else: - outputText = completion_response["completion"] - - model_response.choices[0].finish_reason = completion_response["stop_reason"] - elif provider == "ai21": - outputText = completion_response.get("completions")[0].get("data").get("text") - elif provider == "meta" or provider == "llama": - outputText = completion_response["generation"] - elif provider == "openai": - # OpenAI imported models use OpenAI Chat Completions format - if "choices" in completion_response and len(completion_response["choices"]) > 0: - choice = completion_response["choices"][0] - if "message" in choice: - outputText = choice["message"].get("content") - elif "text" in choice: # fallback for completion format - outputText = choice["text"] - - # Set finish reason - if "finish_reason" in choice: - model_response.choices[0].finish_reason = map_finish_reason(choice["finish_reason"]) - - # Set usage if available - if "usage" in completion_response: - usage = completion_response["usage"] - _usage = litellm.Usage( - prompt_tokens=usage.get("prompt_tokens", 0), - completion_tokens=usage.get("completion_tokens", 0), - total_tokens=usage.get("total_tokens", 0), - ) - setattr(model_response, "usage", _usage) - elif provider == "mistral": - outputText = completion_response["outputs"][0]["text"] - model_response.choices[0].finish_reason = completion_response["outputs"][0]["stop_reason"] - else: # amazon titan - outputText = completion_response.get("results")[0].get("outputText") - except Exception as e: - raise BedrockError( - message="Error processing={}, Received error={}".format(response.text, str(e)), - status_code=422, - ) - - try: - if ( - outputText is not None - and len(outputText) > 0 - and hasattr(model_response.choices[0], "message") - and getattr(model_response.choices[0].message, "tool_calls", None) # type: ignore - is None - ): - model_response.choices[0].message.content = outputText # type: ignore - elif ( - hasattr(model_response.choices[0], "message") - and getattr(model_response.choices[0].message, "tool_calls", None) # type: ignore - is not None - ): - pass - else: - raise Exception() - except Exception as e: - raise BedrockError( - message="Error parsing received text={}.\nError-{}".format(outputText, str(e)), - status_code=response.status_code, - ) - - if stream and provider == "ai21": - streaming_model_response = ModelResponseStream() - streaming_model_response.choices[0].finish_reason = model_response.choices[ # type: ignore - 0 - ].finish_reason - # streaming_model_response.choices = [litellm.utils.StreamingChoices()] - streaming_choice = litellm.utils.StreamingChoices() - streaming_choice.index = model_response.choices[0].index - delta_obj = litellm.utils.Delta( - content=getattr(model_response.choices[0].message, "content", None), # type: ignore - role=model_response.choices[0].message.role, # type: ignore - ) - streaming_choice.delta = delta_obj - streaming_model_response.choices = [streaming_choice] - mri = ModelResponseIterator(model_response=streaming_model_response) - return CustomStreamWrapper( - completion_stream=mri, - model=model, - custom_llm_provider="cached_response", - logging_obj=logging_obj, - ) - - ## CALCULATING USAGE - bedrock returns usage in the headers - # Skip if usage was already set (e.g., from JSON response for OpenAI provider) - if not hasattr(model_response, "usage") or getattr(model_response, "usage", None) is None: - bedrock_input_tokens = response.headers.get("x-amzn-bedrock-input-token-count", None) - bedrock_output_tokens = response.headers.get("x-amzn-bedrock-output-token-count", None) - - prompt_tokens = int(bedrock_input_tokens or litellm.token_counter(messages=messages)) - - completion_tokens = int( - bedrock_output_tokens - or litellm.token_counter( - text=model_response.choices[0].message.content, # type: ignore - count_response_tokens=True, - ) - ) - - model_response.created = int(time.time()) - model_response.model = model - usage = Usage( - prompt_tokens=prompt_tokens, - completion_tokens=completion_tokens, - total_tokens=prompt_tokens + completion_tokens, - ) - setattr(model_response, "usage", usage) - else: - # Ensure created and model are set even if usage was already set - model_response.created = int(time.time()) - model_response.model = model - - return model_response - - def completion( - self, - model: str, - messages: list, - api_base: Optional[str], - custom_prompt_dict: dict, - model_response: ModelResponse, - print_verbose: Callable, - encoding, - logging_obj: Logging, - optional_params: dict, - acompletion: bool, - timeout: Optional[Union[float, httpx.Timeout]], - litellm_params=None, - logger_fn=None, - extra_headers: Optional[dict] = None, - client: Optional[Union[AsyncHTTPHandler, HTTPHandler]] = None, - ) -> Union[ModelResponse, CustomStreamWrapper]: - try: - from botocore.credentials import Credentials - except ImportError: - raise ImportError("Missing boto3 to call bedrock. Run 'pip install boto3'.") - - ## SETUP ## - stream = optional_params.pop("stream", None) - stream_chunk_size = optional_params.pop("stream_chunk_size", None) - - provider = self.get_bedrock_invoke_provider(model) - modelId = self.get_bedrock_model_id( - model=model, - provider=provider, - optional_params=optional_params, - ) - - ## CREDENTIALS ## - # pop aws_secret_access_key, aws_access_key_id, aws_session_token, aws_region_name from kwargs, since completion calls fail with them - aws_secret_access_key = optional_params.pop("aws_secret_access_key", None) - aws_access_key_id = optional_params.pop("aws_access_key_id", None) - aws_session_token = optional_params.pop("aws_session_token", None) - aws_region_name = optional_params.pop("aws_region_name", None) - aws_role_name = optional_params.pop("aws_role_name", None) - aws_session_name = optional_params.pop("aws_session_name", None) - aws_profile_name = optional_params.pop("aws_profile_name", None) - aws_bedrock_runtime_endpoint = optional_params.pop( - "aws_bedrock_runtime_endpoint", None - ) # https://bedrock-runtime.{region_name}.amazonaws.com - aws_web_identity_token = optional_params.pop("aws_web_identity_token", None) - aws_sts_endpoint = optional_params.pop("aws_sts_endpoint", None) - ssl_verify = optional_params.pop("ssl_verify", None) - - ### SET REGION NAME ### - if aws_region_name is None: - # check env # - litellm_aws_region_name = get_secret("AWS_REGION_NAME", None) - - if litellm_aws_region_name is not None and isinstance(litellm_aws_region_name, str): - aws_region_name = litellm_aws_region_name - - standard_aws_region_name = get_secret("AWS_REGION", None) - if standard_aws_region_name is not None and isinstance(standard_aws_region_name, str): - aws_region_name = standard_aws_region_name - - if aws_region_name is None: - aws_region_name = "us-west-2" - - credentials: Credentials = self.get_credentials( - aws_access_key_id=aws_access_key_id, - aws_secret_access_key=aws_secret_access_key, - aws_session_token=aws_session_token, - aws_region_name=aws_region_name, - aws_session_name=aws_session_name, - aws_profile_name=aws_profile_name, - aws_role_name=aws_role_name, - aws_web_identity_token=aws_web_identity_token, - aws_sts_endpoint=aws_sts_endpoint, - ssl_verify=ssl_verify, - ) - - ### SET RUNTIME ENDPOINT ### - endpoint_url, proxy_endpoint_url = self.get_runtime_endpoint( - api_base=api_base, - aws_bedrock_runtime_endpoint=aws_bedrock_runtime_endpoint, - aws_region_name=aws_region_name, - ) - - if (stream is not None and stream is True) and provider != "ai21": - endpoint_url = f"{endpoint_url}/model/{modelId}/invoke-with-response-stream" - proxy_endpoint_url = f"{proxy_endpoint_url}/model/{modelId}/invoke-with-response-stream" - else: - endpoint_url = f"{endpoint_url}/model/{modelId}/invoke" - proxy_endpoint_url = f"{proxy_endpoint_url}/model/{modelId}/invoke" - - if acompletion and provider == "anthropic" and self.is_claude_messages_api_model(model): - if isinstance(client, HTTPHandler): - client = None - return self._async_anthropic_messages_completion( - model=model, - messages=messages, - endpoint_url=endpoint_url, - proxy_endpoint_url=proxy_endpoint_url, - credentials=credentials, - aws_region_name=aws_region_name, - model_response=model_response, - print_verbose=print_verbose, - encoding=encoding, - logging_obj=logging_obj, - optional_params=optional_params, - stream=stream, - litellm_params=litellm_params, - logger_fn=logger_fn, - extra_headers=extra_headers, - timeout=timeout, - client=client, - stream_chunk_size=stream_chunk_size, - ) # type: ignore[return-value] - - prompt, chat_history = self.convert_messages_to_prompt(model, messages, provider, custom_prompt_dict) - inference_params = copy.deepcopy(optional_params) - json_schemas: dict = {} - if provider == "cohere": - if model.startswith("cohere.command-r"): - ## LOAD CONFIG - config = litellm.AmazonCohereChatConfig().get_config() - for k, v in config.items(): - if ( - k not in inference_params - ): # completion(top_k=3) > anthropic_config(top_k=3) <- allows for dynamic variables to be passed in - inference_params[k] = v - _data = {"message": prompt, **inference_params} - if chat_history is not None: - _data["chat_history"] = chat_history - data = json.dumps(_data) - else: - ## LOAD CONFIG - config = litellm.AmazonCohereConfig.get_config() - for k, v in config.items(): - if ( - k not in inference_params - ): # completion(top_k=3) > anthropic_config(top_k=3) <- allows for dynamic variables to be passed in - inference_params[k] = v - if stream is True: - inference_params["stream"] = True # cohere requires stream = True in inference params - data = json.dumps({"prompt": prompt, **inference_params}) - elif provider == "anthropic": - if self.is_claude_messages_api_model(model): - # Separate system prompt from rest of message - system_prompt_idx: list[int] = [] - system_messages: list[str] = [] - for idx, message in enumerate(messages): - if message["role"] == "system": - system_messages.append(message["content"]) - system_prompt_idx.append(idx) - if len(system_prompt_idx) > 0: - inference_params["system"] = "\n".join(system_messages) - messages = [i for j, i in enumerate(messages) if j not in system_prompt_idx] - # Format rest of message according to anthropic guidelines - messages = prompt_factory(model=model, messages=messages, custom_llm_provider="anthropic_xml") # type: ignore - ## LOAD CONFIG - config = litellm.AmazonAnthropicClaudeConfig.get_config() - for k, v in config.items(): - if ( - k not in inference_params - ): # completion(top_k=3) > anthropic_config(top_k=3) <- allows for dynamic variables to be passed in - inference_params[k] = v - ## Handle Tool Calling - if "tools" in inference_params: - _is_function_call = True - for tool in inference_params["tools"]: - json_schemas[tool["function"]["name"]] = tool["function"].get("parameters", None) - tool_calling_system_prompt = construct_tool_use_system_prompt(tools=inference_params["tools"]) - inference_params["system"] = ( - inference_params.get("system", "\n") + tool_calling_system_prompt - ) # add the anthropic tool calling prompt to the system prompt - inference_params.pop("tools") - data = json.dumps({"messages": messages, **inference_params}) - else: - ## LOAD CONFIG - config = litellm.AmazonAnthropicConfig.get_config() - for k, v in config.items(): - if ( - k not in inference_params - ): # completion(top_k=3) > anthropic_config(top_k=3) <- allows for dynamic variables to be passed in - inference_params[k] = v - data = json.dumps({"prompt": prompt, **inference_params}) - elif provider == "ai21": - ## LOAD CONFIG - config = litellm.AmazonAI21Config.get_config() - for k, v in config.items(): - if ( - k not in inference_params - ): # completion(top_k=3) > anthropic_config(top_k=3) <- allows for dynamic variables to be passed in - inference_params[k] = v - - data = json.dumps({"prompt": prompt, **inference_params}) - elif provider == "mistral": - ## LOAD CONFIG - config = litellm.AmazonMistralConfig.get_config() - for k, v in config.items(): - if ( - k not in inference_params - ): # completion(top_k=3) > amazon_config(top_k=3) <- allows for dynamic variables to be passed in - inference_params[k] = v - - data = json.dumps({"prompt": prompt, **inference_params}) - elif provider == "amazon": # amazon titan - ## LOAD CONFIG - config = litellm.AmazonTitanConfig.get_config() - for k, v in config.items(): - if ( - k not in inference_params - ): # completion(top_k=3) > amazon_config(top_k=3) <- allows for dynamic variables to be passed in - inference_params[k] = v - - data = json.dumps( - { - "inputText": prompt, - "textGenerationConfig": inference_params, - } - ) - elif provider == "meta" or provider == "llama": - ## LOAD CONFIG - config = litellm.AmazonLlamaConfig.get_config() - for k, v in config.items(): - if ( - k not in inference_params - ): # completion(top_k=3) > anthropic_config(top_k=3) <- allows for dynamic variables to be passed in - inference_params[k] = v - data = json.dumps({"prompt": prompt, **inference_params}) - elif provider == "openai": - ## OpenAI imported models use OpenAI Chat Completions format (messages-based) - # Use AmazonBedrockOpenAIConfig for proper OpenAI transformation - openai_config = AmazonBedrockOpenAIConfig() - supported_params = openai_config.get_supported_openai_params(model=model) - - # Filter to only supported OpenAI params - filtered_params = {k: v for k, v in inference_params.items() if k in supported_params} - - # OpenAI uses messages format, not prompt - data = json.dumps({"messages": messages, **filtered_params}) - else: - ## LOGGING - logging_obj.pre_call( - input=messages, - api_key="", - additional_args={ - "complete_input_dict": inference_params, - }, - ) - raise BedrockError( - status_code=404, - message="Bedrock Invoke HTTPX: Unknown provider={}, model={}. Try calling via converse route - `bedrock/converse/`.".format( - provider, model - ), - ) - - ## COMPLETION CALL - - headers = {"Content-Type": "application/json"} - if extra_headers is not None: - headers = {"Content-Type": "application/json", **extra_headers} - prepped = self.get_request_headers( - credentials=credentials, - aws_region_name=aws_region_name, - extra_headers=extra_headers, - endpoint_url=endpoint_url, - data=data, - headers=headers, - ) - - ## LOGGING - logging_obj.pre_call( - input=messages, - api_key="", - additional_args={ - "complete_input_dict": data, - "api_base": proxy_endpoint_url, - "headers": prepped.headers, - }, - ) - - ### ROUTING (ASYNC, STREAMING, SYNC) - if acompletion: - if isinstance(client, HTTPHandler): - client = None - if stream is True and provider != "ai21": - return self.async_streaming( - model=model, - messages=messages, - data=data, - api_base=proxy_endpoint_url, - model_response=model_response, - print_verbose=print_verbose, - encoding=encoding, - logging_obj=logging_obj, - optional_params=optional_params, - stream=True, - litellm_params=litellm_params, - logger_fn=logger_fn, - headers=prepped.headers, - timeout=timeout, - client=client, - stream_chunk_size=stream_chunk_size, - ) # type: ignore - ### ASYNC COMPLETION - return self.async_completion( - model=model, - messages=messages, - data=data, - api_base=proxy_endpoint_url, - model_response=model_response, - print_verbose=print_verbose, - encoding=encoding, - logging_obj=logging_obj, - optional_params=optional_params, - stream=stream, # type: ignore - litellm_params=litellm_params, - logger_fn=logger_fn, - headers=prepped.headers, - timeout=timeout, - client=client, - ) # type: ignore - - if client is None or isinstance(client, AsyncHTTPHandler): - _params = {} - if timeout is not None: - if isinstance(timeout, float) or isinstance(timeout, int): - timeout = httpx.Timeout(timeout) - _params["timeout"] = timeout - self.client = _get_httpx_client(_params) # type: ignore - else: - self.client = client - if (stream is not None and stream is True) and provider != "ai21": - response = self.client.post( - url=proxy_endpoint_url, - headers=prepped.headers, # type: ignore - data=data, - stream=stream, - logging_obj=logging_obj, - ) - - if response.status_code != 200: - raise BedrockError(status_code=response.status_code, message=str(response.read())) - - decoder = AWSEventStreamDecoder(model=model) - - completion_stream = decoder.iter_bytes(response.iter_bytes(chunk_size=stream_chunk_size)) - streaming_response = CustomStreamWrapper( - completion_stream=completion_stream, - model=model, - custom_llm_provider="bedrock", - logging_obj=logging_obj, - ) - - ## LOGGING - logging_obj.post_call( - input=messages, - api_key="", - original_response=streaming_response, - additional_args={"complete_input_dict": data}, - ) - return streaming_response - - try: - response = self.client.post( - url=proxy_endpoint_url, - headers=dict(prepped.headers), - data=data, - logging_obj=logging_obj, - ) - response.raise_for_status() - except httpx.HTTPStatusError as err: - error_code = err.response.status_code - raise BedrockError(status_code=error_code, message=err.response.text) - except httpx.TimeoutException: - raise BedrockError(status_code=408, message="Timeout error occurred.") - - return self.process_response( - model=model, - response=response, - model_response=model_response, - stream=stream, - logging_obj=logging_obj, - optional_params=optional_params, - api_key="", - data=data, - messages=messages, - print_verbose=print_verbose, - encoding=encoding, - ) - - async def _async_anthropic_messages_completion( - self, - model: str, - messages: list, - endpoint_url: str, - proxy_endpoint_url: str, - credentials, - aws_region_name: str, - model_response: ModelResponse, - print_verbose: Callable, - encoding, - logging_obj: Logging, - optional_params: dict, - stream, - litellm_params=None, - logger_fn=None, - extra_headers: Optional[dict] = None, - timeout: Optional[Union[float, httpx.Timeout]] = None, - client: Optional[AsyncHTTPHandler] = None, - stream_chunk_size: Optional[int] = None, - ) -> Union[ModelResponse, CustomStreamWrapper]: - transformed_request = await litellm.AmazonAnthropicClaudeConfig().async_transform_request( - model=model, - messages=messages, - optional_params=optional_params, - litellm_params=litellm_params or {}, - headers=extra_headers or {}, - ) - data = json.dumps(transformed_request) - - headers = {"Content-Type": "application/json"} - if extra_headers is not None: - headers = {"Content-Type": "application/json", **extra_headers} - prepped = self.get_request_headers( - credentials=credentials, - aws_region_name=aws_region_name, - extra_headers=extra_headers, - endpoint_url=endpoint_url, - data=data, - headers=headers, - ) - - logging_obj.pre_call( - input=messages, - api_key="", - additional_args={ - "complete_input_dict": data, - "api_base": proxy_endpoint_url, - "headers": prepped.headers, - }, - ) - - if stream is True: - return await self.async_streaming( - model=model, - messages=messages, - data=data, - api_base=proxy_endpoint_url, - model_response=model_response, - print_verbose=print_verbose, - encoding=encoding, - logging_obj=logging_obj, - optional_params=optional_params, - stream=True, - litellm_params=litellm_params, - logger_fn=logger_fn, - headers=prepped.headers, - timeout=timeout, - client=client, - stream_chunk_size=stream_chunk_size, - ) - return await self.async_completion( - model=model, - messages=messages, - data=data, - api_base=proxy_endpoint_url, - model_response=model_response, - print_verbose=print_verbose, - encoding=encoding, - logging_obj=logging_obj, - optional_params=optional_params, - stream=stream, # type: ignore - litellm_params=litellm_params, - logger_fn=logger_fn, - headers=prepped.headers, - timeout=timeout, - client=client, - ) - - async def async_completion( - self, - model: str, - messages: list, - api_base: str, - model_response: ModelResponse, - print_verbose: Callable, - data: str, - timeout: Optional[Union[float, httpx.Timeout]], - encoding, - logging_obj: Logging, - stream, - optional_params: dict, - litellm_params=None, - logger_fn=None, - headers={}, - client: Optional[AsyncHTTPHandler] = None, - ) -> Union[ModelResponse, CustomStreamWrapper]: - if client is None: - _params = {} - if timeout is not None: - if isinstance(timeout, float) or isinstance(timeout, int): - timeout = httpx.Timeout(timeout) - _params["timeout"] = timeout - client = get_async_httpx_client(params=_params, llm_provider=litellm.LlmProviders.BEDROCK) # type: ignore - else: - client = client # type: ignore - - try: - response = await client.post( - api_base, - headers=headers, - data=data, - timeout=timeout, - logging_obj=logging_obj, - ) - response.raise_for_status() - except httpx.HTTPStatusError as err: - error_code = err.response.status_code - raise BedrockError(status_code=error_code, message=err.response.text) - except httpx.TimeoutException: - raise BedrockError(status_code=408, message="Timeout error occurred.") - - return self.process_response( - model=model, - response=response, - model_response=model_response, - stream=stream if isinstance(stream, bool) else False, - logging_obj=logging_obj, - api_key="", - data=data, - messages=messages, - print_verbose=print_verbose, - optional_params=optional_params, - encoding=encoding, - ) - - @track_llm_api_timing() # for streaming, we need to instrument the function calling the wrapper - async def async_streaming( - self, - model: str, - messages: list, - api_base: str, - model_response: ModelResponse, - print_verbose: Callable, - data: str, - timeout: Optional[Union[float, httpx.Timeout]], - encoding, - logging_obj: Logging, - stream, - optional_params: dict, - litellm_params=None, - logger_fn=None, - headers={}, - client: Optional[AsyncHTTPHandler] = None, - stream_chunk_size: Optional[int] = None, - ) -> CustomStreamWrapper: - # The call is not made here; instead, we prepare the necessary objects for the stream. - - streaming_response = CustomStreamWrapper( - completion_stream=None, - make_call=partial( - make_call, - client=client, - api_base=api_base, - headers=headers, - data=data, # type: ignore - model=model, - messages=messages, - logging_obj=logging_obj, - fake_stream=True if "ai21" in api_base else False, - stream_chunk_size=stream_chunk_size, - ), - model=model, - custom_llm_provider="bedrock", - logging_obj=logging_obj, - ) - return streaming_response - - @staticmethod - def _get_provider_from_model_path( - model_path: str, - ) -> Optional[litellm.BEDROCK_INVOKE_PROVIDERS_LITERAL]: - """ - Helper function to get the provider from a model path with format: provider/model-name - - Args: - model_path (str): The model path (e.g., 'llama/arn:aws:bedrock:us-east-1:086734376398:imported-model/r4c4kewx2s0n' or 'anthropic/model-name') - - Returns: - Optional[str]: The provider name, or None if no valid provider found - """ - parts = model_path.split("/") - if len(parts) >= 1: - provider = parts[0] - if provider in get_args(litellm.BEDROCK_INVOKE_PROVIDERS_LITERAL): - return cast(litellm.BEDROCK_INVOKE_PROVIDERS_LITERAL, provider) - return None - - class AWSEventStreamDecoder: def __init__(self, model: str, json_mode: Optional[bool] = False) -> None: from botocore.parsers import EventStreamJSONParser diff --git a/litellm/llms/bedrock/common_utils.py b/litellm/llms/bedrock/common_utils.py index 5114677ffc0..93998f0610e 100644 --- a/litellm/llms/bedrock/common_utils.py +++ b/litellm/llms/bedrock/common_utils.py @@ -1109,8 +1109,10 @@ def get_bedrock_chat_config(model: str): Returns: The appropriate Bedrock config class instance """ + from litellm.llms.bedrock.base_aws_llm import BaseAWSLLM + bedrock_route = BedrockModelInfo.get_bedrock_route(model) - bedrock_invoke_provider = litellm.BedrockLLM.get_bedrock_invoke_provider(model=model) + bedrock_invoke_provider = BaseAWSLLM.get_bedrock_invoke_provider(model=model) base_model = BedrockModelInfo.get_base_model(model) # Handle explicit routes first diff --git a/litellm/llms/bedrock/messages/mantle_transformation.py b/litellm/llms/bedrock/messages/mantle_transformation.py index da7b8697a6b..65a2ab3b9a7 100644 --- a/litellm/llms/bedrock/messages/mantle_transformation.py +++ b/litellm/llms/bedrock/messages/mantle_transformation.py @@ -17,6 +17,10 @@ from litellm.llms.bedrock.common_utils import build_mantle_messages_url from litellm.llms.bedrock.messages.invoke_transformations.anthropic_claude3_transformation import ( AmazonAnthropicClaudeMessagesConfig, ) +from litellm.types.llms.anthropic_messages.anthropic_response import ( + AnthropicMessagesResponse, + AnthropicUsage, +) from litellm.types.router import GenericLiteLLMParams if TYPE_CHECKING: @@ -103,6 +107,25 @@ class AmazonMantleMessagesConfig(AmazonAnthropicClaudeMessagesConfig): ) return {**request, "model": model_id, **stream_fields} + def transform_anthropic_messages_response( + self, + model: str, + raw_response: httpx.Response, + logging_obj: LiteLLMLoggingObj, + ) -> AnthropicMessagesResponse: + response = super().transform_anthropic_messages_response( + model=model, + raw_response=raw_response, + logging_obj=logging_obj, + ) + existing_usage: AnthropicUsage = response.get("usage") or AnthropicUsage() + normalized_usage: AnthropicUsage = { + "input_tokens": 0, + "output_tokens": 0, + **existing_usage, + } + return {**response, "usage": normalized_usage} + def get_async_streaming_response_iterator( self, model: str, diff --git a/litellm/llms/custom_httpx/aiohttp_transport.py b/litellm/llms/custom_httpx/aiohttp_transport.py index adac6a1b276..2c5f455692c 100644 --- a/litellm/llms/custom_httpx/aiohttp_transport.py +++ b/litellm/llms/custom_httpx/aiohttp_transport.py @@ -1,10 +1,11 @@ import asyncio +import concurrent.futures import contextlib import os import ssl import typing import urllib.request -from typing import Any, Callable, Dict, Optional, Union +from typing import Any, Callable, ClassVar, Dict, Optional, Union import aiohttp import aiohttp.client_exceptions @@ -138,18 +139,122 @@ class LiteLLMAiohttpTransport(AiohttpTransport): Credit to: https://github.com/karpetrosyan/httpx-aiohttp for this implementation """ + # Strong references to scheduled session-close tasks. A bare + # asyncio.create_task() result may be garbage-collected before it runs, + # leaving the recycled session unclosed ("Unclosed client session"). + _background_close_tasks: ClassVar[set["asyncio.Task[None]"]] = set() # mutable-ok: strong refs for pending closes + def __init__( self, client: Union[ClientSession, Callable[[], ClientSession]], ssl_verify: Optional[Union[bool, ssl.SSLContext]] = None, owns_session: bool = True, + session_factory: Callable[[], ClientSession] | None = None, ): self.client = client self._ssl_verify = ssl_verify # Store for per-request SSL override super().__init__(client=client, owns_session=owns_session) # Store the client factory for recreating sessions when needed - if callable(client): - self._client_factory = client + default_factory: Callable[[], ClientSession] = client if callable(client) else ClientSession + self._client_factory: Callable[[], ClientSession] = session_factory or default_factory + + def _rebuild_session(self) -> ClientSession: + """ + Build a replacement session from the configured factory. + + The replacement is reachable only from this transport, so the transport + owns it from here on even when it was originally handed a session it did + not own (the proxy's shared session). + """ + session = self._client_factory() + self._owns_session = True + return session + + @classmethod + def _on_close_task_done(cls, task: "asyncio.Task[None]") -> None: + cls._background_close_tasks.discard(task) + if task.cancelled(): + return + exc = task.exception() + if exc is not None: + verbose_logger.debug("Error closing recycled aiohttp session: %s", exc) + + @staticmethod + def _on_threadsafe_close_done(future: "concurrent.futures.Future[None]") -> None: + if future.cancelled(): + return + exc = future.exception() + if exc is not None: + verbose_logger.debug("Error closing recycled aiohttp session on its own loop: %s", exc) + + @staticmethod + def _mark_connector_closed(session: ClientSession) -> None: + """Synchronously dispose a session whose event loop is gone. + + An async close can no longer run on a closed loop. BaseConnector._close + is the same synchronous teardown aiohttp's own finalizer (__del__) + uses: it is guarded for closed loops, releases pooled connections, and + flips the flags that ClientSession.closed / BaseConnector.closed read - + so no "Unclosed client session" / "Unclosed connector" warnings reach + the event-loop exception handler at garbage collection. + """ + connector = getattr(session, "_connector", None) + close_sync = getattr(connector, "_close", None) + if not callable(close_sync): + return + try: + close_sync() + except (RuntimeError, AttributeError, OSError) as e: + verbose_logger.debug("Best-effort connector close failed: %s", e) + + def _close_recycled_session(self, session: ClientSession) -> None: + """Deterministically dispose a ClientSession this transport is replacing. + + Covers the three lifecycles a recycled session can be in: + - its loop is the current running loop: schedule an async close and keep + a strong reference to the task until it completes; + - its loop is still running elsewhere (e.g. another thread): hand the + close to that loop thread-safely; + - its loop is stopped or closed, or there is no running loop: fall + back to the synchronous finalizer-safe teardown. + """ + if session.closed: + return + + session_loop = getattr(session, "_loop", None) + try: + current_loop: Optional[asyncio.AbstractEventLoop] = asyncio.get_running_loop() + except RuntimeError: + current_loop = None + + if session_loop is not None and session_loop is not current_loop: + if not session_loop.is_closed() and session_loop.is_running(): + # The session's loop is running somewhere else (e.g. another + # thread): closing from here would touch that loop's internals + # unsafely; hand the close to its own loop. + try: + future = asyncio.run_coroutine_threadsafe(session.close(), session_loop) + except RuntimeError as e: # loop shut down between the checks + verbose_logger.debug("Threadsafe session close failed: %s", e) + self._mark_connector_closed(session) + else: + future.add_done_callback(self._on_threadsafe_close_done) + return + + # Foreign loop that is stopped or closed: an async close can no + # longer run there, and running it on the current loop would touch + # another loop's internals. Dispose synchronously instead. + self._mark_connector_closed(session) + return + + if current_loop is None: + self._mark_connector_closed(session) + return + + task = current_loop.create_task(session.close()) + cls = type(self) + cls._background_close_tasks.add(task) + task.add_done_callback(cls._on_close_task_done) def _get_valid_client_session(self) -> ClientSession: """ @@ -158,24 +263,16 @@ class LiteLLMAiohttpTransport(AiohttpTransport): This handles the case where the session was created in a different event loop that may have been closed (common in CI/CD environments). """ - from aiohttp.client import ClientSession - # If we don't have a client or it's not a ClientSession, create one if not isinstance(self.client, ClientSession): - if hasattr(self, "_client_factory") and callable(self._client_factory): - self.client = self._client_factory() - else: - self.client = ClientSession() + self.client = self._rebuild_session() # Don't return yet - check if the newly created session is valid # Check if the session itself is closed if self.client.closed: verbose_logger.debug("Session is closed, creating new session") # Create a new session - if hasattr(self, "_client_factory") and callable(self._client_factory): - self.client = self._client_factory() - else: - self.client = ClientSession() + self.client = self._rebuild_session() return self.client # Check if the existing session is still valid for the current event loop @@ -188,27 +285,25 @@ class LiteLLMAiohttpTransport(AiohttpTransport): # Close old session to prevent leaks old_session = self.client try: - if not old_session.closed: - try: - asyncio.create_task(old_session.close()) - except RuntimeError: - # Different event loop - can't schedule task, rely on GC - verbose_logger.debug("Old session from different loop, relying on GC") + if self._owns_session: + self._close_recycled_session(old_session) except Exception as e: verbose_logger.debug(f"Error closing old session: {e}") # Create a new session in the current event loop - if hasattr(self, "_client_factory") and callable(self._client_factory): - self.client = self._client_factory() - else: - self.client = ClientSession() + self.client = self._rebuild_session() - except (RuntimeError, AttributeError): - # If we can't check the loop or session is invalid, recreate it - if hasattr(self, "_client_factory") and callable(self._client_factory): - self.client = self._client_factory() - else: - self.client = ClientSession() + except (RuntimeError, AttributeError) as e: + # If we can't check the loop or session is invalid, recreate it, + # but still dispose of the session being replaced. + old_session = self.client + if self._owns_session: + try: + self._close_recycled_session(old_session) + except (RuntimeError, AttributeError, OSError) as close_error: + verbose_logger.debug(f"Error closing old session: {close_error}") + self.client = self._rebuild_session() + verbose_logger.debug(f"Error checking session loop, created new session: {e}") return self.client @@ -302,11 +397,15 @@ class LiteLLMAiohttpTransport(AiohttpTransport): # Handle the case where session was closed between our check and actual use if "Session is closed" in str(e): verbose_logger.debug(f"Session closed during request, retrying with new session: {e}") - # Force creation of a new session - if hasattr(self, "_client_factory") and callable(self._client_factory): - self.client = self._client_factory() - else: - self.client = ClientSession() + # Dispose of the session that actually faulted. Do NOT read + # self.client here: a concurrent task may already have + # replaced it with a healthy session that must stay open. + # Guarded by isinstance: factory-injected sessions may be + # duck-typed test doubles without a close() coroutine. + # Read _owns_session before _rebuild_session() claims ownership. + if self._owns_session and isinstance(client_session, ClientSession): + self._close_recycled_session(client_session) + self.client = self._rebuild_session() client_session = self.client # Retry the request with the new session diff --git a/litellm/llms/custom_httpx/http_handler.py b/litellm/llms/custom_httpx/http_handler.py index 5cec763bb5d..c92f8bcc937 100644 --- a/litellm/llms/custom_httpx/http_handler.py +++ b/litellm/llms/custom_httpx/http_handler.py @@ -1013,17 +1013,6 @@ class AsyncHTTPHandler: verbose_logger.debug("Creating AiohttpTransport...") - # Use shared session if provided and valid - if shared_session is not None and not shared_session.closed: - verbose_logger.debug(f"SHARED SESSION: Reusing existing ClientSession (ID: {id(shared_session)})") - return LiteLLMAiohttpTransport( - client=shared_session, - ssl_verify=ssl_for_transport, - owns_session=False, - ) - - # Create new session only if none provided or existing one is invalid - verbose_logger.debug("NEW SESSION: Creating new ClientSession (no shared session provided)") transport_connector_kwargs = { "keepalive_timeout": AIOHTTP_KEEPALIVE_TIMEOUT, "ttl_dns_cache": AIOHTTP_TTL_DNS_CACHE, @@ -1041,11 +1030,26 @@ class AsyncHTTPHandler: if socket_factory is not None: transport_connector_kwargs["socket_factory"] = socket_factory - return LiteLLMAiohttpTransport( - client=lambda: ClientSession( + def session_factory() -> ClientSession: + return ClientSession( connector=TCPConnector(**transport_connector_kwargs), trust_env=trust_env, - ), + ) + + # Use shared session if provided and valid + if shared_session is not None and not shared_session.closed: + verbose_logger.debug(f"SHARED SESSION: Reusing existing ClientSession (ID: {id(shared_session)})") + return LiteLLMAiohttpTransport( + client=shared_session, + ssl_verify=ssl_for_transport, + owns_session=False, + session_factory=session_factory, + ) + + # Create new session only if none provided or existing one is invalid + verbose_logger.debug("NEW SESSION: Creating new ClientSession (no shared session provided)") + return LiteLLMAiohttpTransport( + client=session_factory, ssl_verify=ssl_for_transport, ) diff --git a/litellm/llms/openai/evals/transformation.py b/litellm/llms/openai/evals/transformation.py index 8a55fec58a6..1ccaed72f26 100644 --- a/litellm/llms/openai/evals/transformation.py +++ b/litellm/llms/openai/evals/transformation.py @@ -2,7 +2,7 @@ OpenAI Evals API configuration and transformations """ -from typing import Any, Dict, Optional, Tuple +from collections.abc import Mapping import httpx @@ -31,6 +31,10 @@ from litellm.types.router import GenericLiteLLMParams from litellm.types.utils import LlmProviders +def _parsed_response_json(raw_response: httpx.Response) -> Mapping[str, object]: + return raw_response.json() + + class OpenAIEvalsConfig(BaseEvalsAPIConfig): """OpenAI-specific Evals API configuration""" @@ -38,7 +42,7 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): def custom_llm_provider(self) -> LlmProviders: return LlmProviders.OPENAI - def validate_environment(self, headers: dict, litellm_params: Optional[GenericLiteLLMParams]) -> dict: + def validate_environment(self, headers: dict, litellm_params: GenericLiteLLMParams | None) -> dict: """Add OpenAI-specific headers""" import litellm from litellm.secret_managers.main import get_secret_str @@ -61,9 +65,9 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): def get_complete_url( self, - api_base: Optional[str], + api_base: str | None, endpoint: str, - eval_id: Optional[str] = None, + eval_id: str | None = None, ) -> str: """Get complete URL for OpenAI Evals API""" if api_base is None: @@ -79,7 +83,7 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): create_request: CreateEvalRequest, litellm_params: GenericLiteLLMParams, headers: dict, - ) -> Dict: + ) -> dict: """Transform create eval request for OpenAI""" verbose_logger.debug("Transforming create eval request: %s", create_request) @@ -94,17 +98,17 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): logging_obj: LiteLLMLoggingObj, ) -> Eval: """Transform OpenAI response to Eval object""" - response_json = raw_response.json() + response_json = _parsed_response_json(raw_response) verbose_logger.debug("Transforming create eval response: %s", response_json) - return Eval(**response_json) + return Eval.model_validate(response_json) def transform_list_evals_request( self, list_params: ListEvalsParams, litellm_params: GenericLiteLLMParams, headers: dict, - ) -> Tuple[str, Dict]: + ) -> tuple[str, dict]: """Transform list evals request for OpenAI""" api_base = "https://api.openai.com" if litellm_params and litellm_params.api_base: @@ -113,7 +117,7 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): url = self.get_complete_url(api_base=api_base, endpoint="evals") # Build query parameters - query_params: Dict[str, Any] = {} + query_params: dict[str, object] = {} if "limit" in list_params and list_params["limit"]: query_params["limit"] = list_params["limit"] if "after" in list_params and list_params["after"]: @@ -138,10 +142,10 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): logging_obj: LiteLLMLoggingObj, ) -> ListEvalsResponse: """Transform OpenAI response to ListEvalsResponse""" - response_json = raw_response.json() + response_json = _parsed_response_json(raw_response) verbose_logger.debug("Transforming list evals response: %s", response_json) - return ListEvalsResponse(**response_json) + return ListEvalsResponse.model_validate(response_json) def transform_get_eval_request( self, @@ -149,7 +153,7 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, - ) -> Tuple[str, Dict]: + ) -> tuple[str, dict]: """Transform get eval request for OpenAI""" url = self.get_complete_url(api_base=api_base, endpoint="evals", eval_id=eval_id) @@ -163,10 +167,10 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): logging_obj: LiteLLMLoggingObj, ) -> Eval: """Transform OpenAI response to Eval object""" - response_json = raw_response.json() + response_json = _parsed_response_json(raw_response) verbose_logger.debug("Transforming get eval response: %s", response_json) - return Eval(**response_json) + return Eval.model_validate(response_json) def transform_update_eval_request( self, @@ -175,7 +179,7 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, - ) -> Tuple[str, Dict, Dict]: + ) -> tuple[str, dict, dict]: """Transform update eval request for OpenAI""" url = self.get_complete_url(api_base=api_base, endpoint="evals", eval_id=eval_id) @@ -192,10 +196,10 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): logging_obj: LiteLLMLoggingObj, ) -> Eval: """Transform OpenAI response to Eval object""" - response_json = raw_response.json() + response_json = _parsed_response_json(raw_response) verbose_logger.debug("Transforming update eval response: %s", response_json) - return Eval(**response_json) + return Eval.model_validate(response_json) def transform_delete_eval_request( self, @@ -203,7 +207,7 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, - ) -> Tuple[str, Dict]: + ) -> tuple[str, dict]: """Transform delete eval request for OpenAI""" url = self.get_complete_url(api_base=api_base, endpoint="evals", eval_id=eval_id) @@ -217,10 +221,10 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): logging_obj: LiteLLMLoggingObj, ) -> DeleteEvalResponse: """Transform OpenAI response to DeleteEvalResponse""" - response_json = raw_response.json() + response_json = _parsed_response_json(raw_response) verbose_logger.debug("Transforming delete eval response: %s", response_json) - return DeleteEvalResponse(**response_json) + return DeleteEvalResponse.model_validate(response_json) def transform_cancel_eval_request( self, @@ -228,12 +232,12 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, - ) -> Tuple[str, Dict, Dict]: + ) -> tuple[str, dict, dict]: """Transform cancel eval request for OpenAI""" url = f"{self.get_complete_url(api_base=api_base, endpoint='evals', eval_id=eval_id)}/cancel" # Empty body for cancel request - request_body: Dict[str, Any] = {} + request_body: dict[str, object] = {} verbose_logger.debug("Cancel eval request - URL: %s", url) @@ -245,10 +249,10 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): logging_obj: LiteLLMLoggingObj, ) -> CancelEvalResponse: """Transform OpenAI response to CancelEvalResponse""" - response_json = raw_response.json() + response_json = _parsed_response_json(raw_response) verbose_logger.debug("Transforming cancel eval response: %s", response_json) - return CancelEvalResponse(**response_json) + return CancelEvalResponse.model_validate(response_json) # Run API Transformations def transform_create_run_request( @@ -257,7 +261,7 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): create_request: CreateRunRequest, litellm_params: GenericLiteLLMParams, headers: dict, - ) -> Tuple[str, Dict]: + ) -> tuple[str, dict]: """Transform create run request for OpenAI""" api_base = "https://api.openai.com" if litellm_params and litellm_params.api_base: @@ -279,10 +283,10 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): logging_obj: LiteLLMLoggingObj, ) -> Run: """Transform OpenAI response to Run object""" - response_json = raw_response.json() + response_json = _parsed_response_json(raw_response) verbose_logger.debug("Transforming create run response: %s", response_json) - return Run(**response_json) + return Run.model_validate(response_json) def transform_list_runs_request( self, @@ -290,7 +294,7 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): list_params: ListRunsParams, litellm_params: GenericLiteLLMParams, headers: dict, - ) -> Tuple[str, Dict]: + ) -> tuple[str, dict]: """Transform list runs request for OpenAI""" api_base = "https://api.openai.com" if litellm_params and litellm_params.api_base: @@ -300,7 +304,7 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): url = f"{api_base}/v1/evals/{encoded_eval_id}/runs" # Build query parameters - query_params: Dict[str, Any] = {} + query_params: dict[str, object] = {} if "limit" in list_params and list_params["limit"]: query_params["limit"] = list_params["limit"] if "after" in list_params and list_params["after"]: @@ -323,10 +327,10 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): logging_obj: LiteLLMLoggingObj, ) -> ListRunsResponse: """Transform OpenAI response to ListRunsResponse""" - response_json = raw_response.json() + response_json = _parsed_response_json(raw_response) verbose_logger.debug("Transforming list runs response: %s", response_json) - return ListRunsResponse(**response_json) + return ListRunsResponse.model_validate(response_json) def transform_get_run_request( self, @@ -335,7 +339,7 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, - ) -> Tuple[str, Dict]: + ) -> tuple[str, dict]: """Transform get run request for OpenAI""" encoded_eval_id = encode_url_path_segment(eval_id, field_name="eval_id") encoded_run_id = encode_url_path_segment(run_id, field_name="run_id") @@ -351,10 +355,10 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): logging_obj: LiteLLMLoggingObj, ) -> Run: """Transform OpenAI response to Run object""" - response_json = raw_response.json() + response_json = _parsed_response_json(raw_response) verbose_logger.debug("Transforming get run response: %s", response_json) - return Run(**response_json) + return Run.model_validate(response_json) def transform_cancel_run_request( self, @@ -363,14 +367,14 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, - ) -> Tuple[str, Dict, Dict]: + ) -> tuple[str, dict, dict]: """Transform cancel run request for OpenAI""" encoded_eval_id = encode_url_path_segment(eval_id, field_name="eval_id") encoded_run_id = encode_url_path_segment(run_id, field_name="run_id") url = f"{api_base}/v1/evals/{encoded_eval_id}/runs/{encoded_run_id}/cancel" # Empty body for cancel request - request_body: Dict[str, Any] = {} + request_body: dict[str, object] = {} verbose_logger.debug("Cancel run request - URL: %s", url) @@ -382,10 +386,10 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): logging_obj: LiteLLMLoggingObj, ) -> CancelRunResponse: """Transform OpenAI response to CancelRunResponse""" - response_json = raw_response.json() + response_json = _parsed_response_json(raw_response) verbose_logger.debug("Transforming cancel run response: %s", response_json) - return CancelRunResponse(**response_json) + return CancelRunResponse.model_validate(response_json) def transform_delete_run_request( self, @@ -394,14 +398,14 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, - ) -> Tuple[str, Dict, Dict]: + ) -> tuple[str, dict, dict]: """Transform delete run request for OpenAI""" encoded_eval_id = encode_url_path_segment(eval_id, field_name="eval_id") encoded_run_id = encode_url_path_segment(run_id, field_name="run_id") url = f"{api_base}/v1/evals/{encoded_eval_id}/runs/{encoded_run_id}" # Empty body for delete request - request_body: Dict[str, Any] = {} + request_body: dict[str, object] = {} verbose_logger.debug("Delete run request - URL: %s", url) @@ -413,7 +417,7 @@ class OpenAIEvalsConfig(BaseEvalsAPIConfig): logging_obj: LiteLLMLoggingObj, ) -> RunDeleteResponse: """Transform OpenAI response to RunDeleteResponse""" - response_json = raw_response.json() + response_json = _parsed_response_json(raw_response) verbose_logger.debug("Transforming delete run response: %s", response_json) - return RunDeleteResponse(**response_json) + return RunDeleteResponse.model_validate(response_json) diff --git a/litellm/llms/openai/openai.py b/litellm/llms/openai/openai.py index 6b191144a11..8fc7e6d0ebd 100644 --- a/litellm/llms/openai/openai.py +++ b/litellm/llms/openai/openai.py @@ -1626,7 +1626,7 @@ class OpenAIFilesAPI(BaseLLM): openai_client: AsyncOpenAI, ) -> OpenAIFileObject: response = await openai_client.files.create(**create_file_data) # type: ignore[arg-type] - return OpenAIFileObject(**response.model_dump()) + return OpenAIFileObject.model_validate(response.model_dump()) def create_file( self, @@ -1662,7 +1662,7 @@ class OpenAIFilesAPI(BaseLLM): create_file_data=create_file_data, openai_client=openai_client ) response = cast(OpenAI, openai_client).files.create(**create_file_data) # type: ignore[arg-type] - return OpenAIFileObject(**response.model_dump()) + return OpenAIFileObject.model_validate(response.model_dump()) async def afile_content( self, @@ -1986,7 +1986,7 @@ class OpenAIBatchesAPI(BaseLLM): openai_client: AsyncOpenAI, ) -> LiteLLMBatch: response = await openai_client.batches.create(**create_batch_data) # type: ignore[arg-type] - return LiteLLMBatch(**response.model_dump()) + return LiteLLMBatch.model_validate(response.model_dump()) def create_batch( self, @@ -2023,7 +2023,7 @@ class OpenAIBatchesAPI(BaseLLM): ) response = cast(OpenAI, openai_client).batches.create(**create_batch_data) # type: ignore[arg-type] - return LiteLLMBatch(**response.model_dump()) + return LiteLLMBatch.model_validate(response.model_dump()) async def aretrieve_batch( self, @@ -2032,7 +2032,7 @@ class OpenAIBatchesAPI(BaseLLM): ) -> LiteLLMBatch: verbose_logger.debug("retrieving batch, args= %s", retrieve_batch_data) response = await openai_client.batches.retrieve(**retrieve_batch_data) # type: ignore[arg-type] - return LiteLLMBatch(**response.model_dump()) + return LiteLLMBatch.model_validate(response.model_dump()) def retrieve_batch( self, @@ -2068,7 +2068,7 @@ class OpenAIBatchesAPI(BaseLLM): retrieve_batch_data=retrieve_batch_data, openai_client=openai_client ) response = cast(OpenAI, openai_client).batches.retrieve(**retrieve_batch_data) # type: ignore[arg-type] - return LiteLLMBatch(**response.model_dump()) + return LiteLLMBatch.model_validate(response.model_dump()) async def acancel_batch( self, @@ -2077,7 +2077,7 @@ class OpenAIBatchesAPI(BaseLLM): ) -> LiteLLMBatch: verbose_logger.debug("async cancelling batch, args= %s", cancel_batch_data) response = await openai_client.batches.cancel(**cancel_batch_data) - return LiteLLMBatch(**response.model_dump()) + return LiteLLMBatch.model_validate(response.model_dump()) def cancel_batch( self, @@ -2117,7 +2117,7 @@ class OpenAIBatchesAPI(BaseLLM): if not isinstance(openai_client, OpenAI): raise ValueError("OpenAI client is not an instance of OpenAI. Make sure you passed a sync OpenAI client.") response = openai_client.batches.cancel(**cancel_batch_data) - return LiteLLMBatch(**response.model_dump()) + return LiteLLMBatch.model_validate(response.model_dump()) async def alist_batches( self, @@ -2477,9 +2477,9 @@ class OpenAIAssistantsAPI(BaseLLM): response_obj: Optional[OpenAIMessage] = None if getattr(thread_message, "status", None) is None: thread_message.status = "completed" - response_obj = OpenAIMessage(**thread_message.dict()) + response_obj = OpenAIMessage.model_validate(thread_message.dict()) else: - response_obj = OpenAIMessage(**thread_message.dict()) + response_obj = OpenAIMessage.model_validate(thread_message.dict()) return response_obj # fmt: off @@ -2556,9 +2556,9 @@ class OpenAIAssistantsAPI(BaseLLM): response_obj: Optional[OpenAIMessage] = None if getattr(thread_message, "status", None) is None: thread_message.status = "completed" - response_obj = OpenAIMessage(**thread_message.dict()) + response_obj = OpenAIMessage.model_validate(thread_message.dict()) else: - response_obj = OpenAIMessage(**thread_message.dict()) + response_obj = OpenAIMessage.model_validate(thread_message.dict()) return response_obj async def async_get_messages( diff --git a/litellm/llms/openai/responses/transformation.py b/litellm/llms/openai/responses/transformation.py index 3c2ae238a0b..dc4e98e6216 100644 --- a/litellm/llms/openai/responses/transformation.py +++ b/litellm/llms/openai/responses/transformation.py @@ -280,7 +280,7 @@ class OpenAIResponsesAPIConfig(BaseResponsesAPIConfig): raw_response_headers = dict(raw_response.headers) processed_headers = process_response_headers(raw_response_headers) try: - response = ResponsesAPIResponse(**raw_response_json) + response = ResponsesAPIResponse.model_validate(raw_response_json) except Exception: verbose_logger.debug(f"Error constructing ResponsesAPIResponse: {raw_response_json}, using model_construct") response = ResponsesAPIResponse.model_construct(**raw_response_json) @@ -506,7 +506,7 @@ class OpenAIResponsesAPIConfig(BaseResponsesAPIConfig): raise OpenAIError(message=raw_response.text, status_code=raw_response.status_code) raw_response_headers = dict(raw_response.headers) processed_headers = process_response_headers(raw_response_headers) - response = ResponsesAPIResponse(**raw_response_json) + response = ResponsesAPIResponse.model_validate(raw_response_json) response._hidden_params["additional_headers"] = processed_headers response._hidden_params["headers"] = raw_response_headers @@ -588,7 +588,7 @@ class OpenAIResponsesAPIConfig(BaseResponsesAPIConfig): raw_response_headers = dict(raw_response.headers) processed_headers = process_response_headers(raw_response_headers) - response = ResponsesAPIResponse(**raw_response_json) + response = ResponsesAPIResponse.model_validate(raw_response_json) response._hidden_params["additional_headers"] = processed_headers response._hidden_params["headers"] = raw_response_headers @@ -647,7 +647,7 @@ class OpenAIResponsesAPIConfig(BaseResponsesAPIConfig): processed_headers = process_response_headers(raw_response_headers) try: - response = ResponsesAPIResponse(**raw_response_json) + response = ResponsesAPIResponse.model_validate(raw_response_json) except Exception: verbose_logger.debug(f"Error constructing ResponsesAPIResponse: {raw_response_json}, using model_construct") response = ResponsesAPIResponse.model_construct(**raw_response_json) diff --git a/litellm/llms/vertex_ai/batches/transformation.py b/litellm/llms/vertex_ai/batches/transformation.py index 6bbe8f75701..df903ba7ef0 100644 --- a/litellm/llms/vertex_ai/batches/transformation.py +++ b/litellm/llms/vertex_ai/batches/transformation.py @@ -123,7 +123,8 @@ class VertexAIBatchTransformation: Gets the output file id from the Vertex AI Batch response """ - output_file_id: str = response.get("outputInfo", OutputInfo()).get("gcsOutputDirectory", "") + output_info = response.get("outputInfo") or OutputInfo() + output_file_id: str = output_info.get("gcsOutputDirectory", "") if output_file_id: output_file_id = output_file_id.rstrip("/") + "/predictions.jsonl" if output_file_id and output_file_id != "/predictions.jsonl": diff --git a/litellm/llms/vertex_ai/context_caching/transformation.py b/litellm/llms/vertex_ai/context_caching/transformation.py index f0ce3323ef6..36c78974aca 100644 --- a/litellm/llms/vertex_ai/context_caching/transformation.py +++ b/litellm/llms/vertex_ai/context_caching/transformation.py @@ -5,7 +5,7 @@ Why separate file? Make it easy to see how transformation works """ import re -from typing import List, Optional, Tuple, Literal +from typing import List, Optional, Sequence, Tuple, Literal from litellm.types.llms.openai import AllMessageValues from litellm.types.llms.vertex_ai import CachedContentRequestBody @@ -152,6 +152,20 @@ def separate_cached_messages( return cached_messages, non_cached_messages +def cached_messages_end_on_supported_turn(cached_messages: Sequence[AllMessageValues]) -> bool: + """ + The cachedContents API rejects contents ending on a model turn, which is how it + classifies both assistant messages and tool results, with HTTP 400 + "Requests ending with a model turn are not supported". System messages are + extracted into system_instruction before contents are built, so the terminal + turn is the last non-system message. + """ + non_system_messages = tuple(message for message in cached_messages if message.get("role") != "system") + if not non_system_messages: + return bool(cached_messages) + return non_system_messages[-1].get("role") not in ("assistant", "tool", "function") + + def transform_openai_messages_to_gemini_context_caching( model: str, messages: List[AllMessageValues], diff --git a/litellm/llms/vertex_ai/context_caching/vertex_ai_context_caching.py b/litellm/llms/vertex_ai/context_caching/vertex_ai_context_caching.py index 0bf3715f798..f8774e33ca4 100644 --- a/litellm/llms/vertex_ai/context_caching/vertex_ai_context_caching.py +++ b/litellm/llms/vertex_ai/context_caching/vertex_ai_context_caching.py @@ -22,6 +22,7 @@ from litellm.types.llms.vertex_ai import ( from ..common_utils import VertexAIError, get_vertex_base_url from ..vertex_llm_base import VertexBase from .transformation import ( + cached_messages_end_on_supported_turn, separate_cached_messages, transform_openai_messages_to_gemini_context_caching, ) @@ -308,6 +309,14 @@ class ContextCachingEndpoints(VertexBase): if len(cached_messages) == 0: return messages, optional_params, None + if not cached_messages_end_on_supported_turn(cached_messages): + verbose_logger.debug( + "Vertex AI context caching: cached message block ends on a model turn once " + "system messages are extracted, which the cachedContents API rejects. " + "Skipping context caching." + ) + return messages, optional_params, None + # Gemini requires a minimum of 1024 tokens for context caching. # Skip caching if the cached content is too small to avoid API errors. if not is_prompt_caching_valid_prompt( @@ -459,6 +468,14 @@ class ContextCachingEndpoints(VertexBase): if len(cached_messages) == 0: return messages, optional_params, None + if not cached_messages_end_on_supported_turn(cached_messages): + verbose_logger.debug( + "Vertex AI context caching: cached message block ends on a model turn once " + "system messages are extracted, which the cachedContents API rejects. " + "Skipping context caching." + ) + return messages, optional_params, None + # Gemini requires a minimum of 1024 tokens for context caching. # Skip caching if the cached content is too small to avoid API errors. if not is_prompt_caching_valid_prompt( diff --git a/litellm/llms/vertex_ai/files/handler.py b/litellm/llms/vertex_ai/files/handler.py index 3bc09139f8f..4d2a1e18eb5 100644 --- a/litellm/llms/vertex_ai/files/handler.py +++ b/litellm/llms/vertex_ai/files/handler.py @@ -1,7 +1,9 @@ import asyncio +import json +import os import time from urllib.parse import unquote -from typing import Any, Coroutine, Optional, Tuple, Union +from typing import Any, Coroutine, Mapping, Optional, Tuple, Union import httpx @@ -10,6 +12,7 @@ from litellm.integrations.gcs_bucket.gcs_bucket_base import ( GCSBucketBase, GCSLoggingConfig, ) +from litellm.types.utils import StandardCallbackDynamicParams from litellm.litellm_core_utils.cloud_storage_security import ( VERTEX_AI_MANAGED_GCS_PREFIX, should_allow_legacy_cloud_file_ids, @@ -39,6 +42,35 @@ class VertexAIFilesHandler(GCSBucketBase): llm_provider=LlmProviders.VERTEX_AI, ) + def _resolve_read_gcs_config( + self, + litellm_params: Mapping[str, object] | None, + vertex_credentials: VERTEX_CREDENTIALS_TYPES | None, + ) -> tuple[str | None, str | None]: + """ + Resolve the GCS bucket and service-account credentials for the read/content path. + + Sources them from the deployment's ``litellm_params`` (``gcs_bucket_name`` / + ``bucket_name`` and ``vertex_credentials``), mirroring the write path in + ``VertexAIFilesConfig._get_configured_bucket_name``, and falls back to the global + ``GCS_BUCKET_NAME`` / ``GCS_PATH_SERVICE_ACCOUNT`` env vars. This lets Vertex batch + run entirely at the model-group level, so output written to a per-model bucket is + readable without setting the global env vars. + """ + params: Mapping[str, object] = litellm_params or {} + bucket_candidate = params.get("gcs_bucket_name") or params.get("bucket_name") + configured_bucket_name = bucket_candidate if isinstance(bucket_candidate, str) else os.getenv("GCS_BUCKET_NAME") + + credentials = params.get("vertex_credentials") or vertex_credentials + if isinstance(credentials, dict): + path_service_account: str | None = json.dumps(credentials) + elif isinstance(credentials, str): + path_service_account = credentials + else: + path_service_account = os.getenv("GCS_PATH_SERVICE_ACCOUNT") + + return configured_bucket_name, path_service_account + def _extract_bucket_and_object_from_file_id( self, file_id: str, @@ -91,7 +123,17 @@ class VertexAIFilesHandler(GCSBucketBase): if not file_id: raise ValueError("file_id is required in file_content_request") - gcs_logging_config: GCSLoggingConfig = await self.get_gcs_logging_config(kwargs={}) + configured_bucket_name, path_service_account = self._resolve_read_gcs_config( + litellm_params=litellm_params, + vertex_credentials=vertex_credentials, + ) + dynamic_params = StandardCallbackDynamicParams( + gcs_bucket_name=configured_bucket_name, + gcs_path_service_account=path_service_account, + ) + gcs_logging_config: GCSLoggingConfig = await self.get_gcs_logging_config( + kwargs={"standard_callback_dynamic_params": dynamic_params} + ) bucket_name, object_path = self._extract_bucket_and_object_from_file_id( file_id=file_id, configured_bucket_name=gcs_logging_config["bucket_name"], diff --git a/litellm/llms/vertex_ai/gemini/transformation.py b/litellm/llms/vertex_ai/gemini/transformation.py index 0db1118a7b4..c0da1536c42 100644 --- a/litellm/llms/vertex_ai/gemini/transformation.py +++ b/litellm/llms/vertex_ai/gemini/transformation.py @@ -20,6 +20,7 @@ from litellm.litellm_core_utils.prompt_templates.common_utils import ( _get_image_mime_type_from_url, ) from litellm.litellm_core_utils.prompt_templates.factory import ( + _get_thought_signature_from_tool, convert_generic_image_chunk_to_openai_image_obj, convert_to_anthropic_image_obj, convert_to_gemini_tool_call_invoke, @@ -635,6 +636,58 @@ def check_if_part_exists_in_parts(parts: List[PartType], part: PartType, exclude return False +def _collect_tool_call_thought_signatures( + assistant_msg: ChatCompletionAssistantMessage, +) -> frozenset[str]: + """Thought signatures already carried by this message's tool-call parts. + + Gemini returns each thoughtSignature on exactly one part. When the signed + part is a function call, the signature is replayed on that tool-call part + by convert_to_gemini_tool_call_invoke, so attaching the same signature to + the text part as well would send two copies and double-bill the previous + turn's reasoning tokens on gemini-3 and newer models. + + Detection deliberately calls _get_thought_signature_from_tool without the + model argument: with a gemini-3 model that helper synthesizes a dummy + signature for unsigned tool calls, which must not suppress a real + text-part signature (e.g. replaying gemini-2.5 history to a newer model). + """ + signatures: tuple[str, ...] = () + + tool_calls = assistant_msg.get("tool_calls") + if isinstance(tool_calls, list): + for tool in tool_calls: + if not isinstance(tool, dict): + continue + signature = _get_thought_signature_from_tool(tool) + if signature: + signatures += (signature,) + + function_call = assistant_msg.get("function_call") + if isinstance(function_call, dict): + signature = _get_thought_signature_from_tool({"function": function_call}) + if signature: + signatures += (signature,) + + provider_specific_fields = assistant_msg.get("provider_specific_fields") + if not isinstance(provider_specific_fields, dict): + return frozenset(signatures) + + invocations = provider_specific_fields.get("server_side_tool_invocations") + if not isinstance(invocations, list): + return frozenset(signatures) + + for invocation in invocations: + if not isinstance(invocation, dict): + continue + for key in ("thought_signature", "response_thought_signature"): + invocation_signature = invocation.get(key) + if isinstance(invocation_signature, str) and invocation_signature: + signatures += (invocation_signature,) + + return frozenset(signatures) + + def _gemini_convert_messages_with_history( messages: List[AllMessageValues], model: Optional[str] = None, @@ -661,6 +714,10 @@ def _gemini_convert_messages_with_history( vertex_project = litellm_params.get("vertex_project") or litellm_params.get("vertex_ai_project") vertex_credentials = litellm_params.get("vertex_credentials") or litellm_params.get("vertex_ai_credentials") + from .vertex_and_google_ai_studio_gemini import VertexGeminiConfig + + forward_function_call_id = VertexGeminiConfig._forward_gemini_function_call_id(model or "") + try: while msg_i < len(messages): user_content: List[PartType] = [] @@ -864,8 +921,18 @@ def _gemini_convert_messages_with_history( if provider_specific_fields and isinstance(provider_specific_fields, dict): thought_signatures = provider_specific_fields.get("thought_signatures") - # If we have thought signatures, add them to the part - if thought_signatures and isinstance(thought_signatures, list) and len(thought_signatures) > 0: + # A signature that is already carried by one of this message's + # tool-call parts must not be attached to the text part too: + # Gemini bills every replayed copy as the previous turn's full + # reasoning token count on gemini-3 and newer models + tool_call_signatures = _collect_tool_call_thought_signatures(assistant_msg) + + if ( + thought_signatures + and isinstance(thought_signatures, list) + and len(thought_signatures) > 0 + and thought_signatures[0] not in tool_call_signatures + ): # Use the first signature for the text part (Gemini expects one signature per part) assistant_content.append( PartType( @@ -910,7 +977,7 @@ def _gemini_convert_messages_with_history( gemini_tool_call_parts = convert_to_gemini_tool_call_invoke( assistant_msg, model=model, - custom_llm_provider=custom_llm_provider, + forward_function_call_id=forward_function_call_id, ) ## check if gemini_tool_call already exists in assistant_content for gemini_tool_call_part in gemini_tool_call_parts: @@ -973,8 +1040,7 @@ def _gemini_convert_messages_with_history( _part = convert_to_gemini_tool_call_result( messages[msg_i], # type: ignore last_message_with_tool_calls, # type: ignore - model=model, - custom_llm_provider=custom_llm_provider, + forward_function_call_id=forward_function_call_id, ) msg_i += 1 # Handle both single part and list of parts (for Computer Use with images) 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 8dd0dc19b81..126f82436e8 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 @@ -289,15 +289,13 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig): return False @staticmethod - def _forward_gemini_function_call_id(model: str, custom_llm_provider: Optional[str] = None) -> bool: + def _forward_gemini_function_call_id(model: str) -> bool: """ Whether to include `id` on function_call / function_response parts. - Gemini 3+ on Google AI Studio accepts (and returns) `id` for strict - tool-call matching. Vertex AI rejects the field with HTTP 400. + Gemini 3+ accepts (and returns) `id` for strict tool-call matching, on Vertex AI and + Google AI Studio alike. Older Gemini models reject the field with HTTP 400. """ - if custom_llm_provider != "gemini": - return False return VertexGeminiConfig._is_gemini_3_or_newer(model) def _supports_penalty_parameters(self, model: str) -> bool: diff --git a/litellm/llms/volcengine/responses/transformation.py b/litellm/llms/volcengine/responses/transformation.py index 56950151969..4b20962e100 100644 --- a/litellm/llms/volcengine/responses/transformation.py +++ b/litellm/llms/volcengine/responses/transformation.py @@ -1,11 +1,9 @@ +from collections.abc import Callable, Mapping, Sequence from typing import ( TYPE_CHECKING, Any, - Dict, - List, Literal, - Optional, - Tuple, + Protocol, Union, get_args, get_origin, @@ -17,10 +15,10 @@ from pydantic import fields as pyd_fields import litellm from litellm._logging import verbose_logger from litellm.litellm_core_utils.core_helpers import process_response_headers -from litellm.litellm_core_utils.url_utils import encode_url_path_segment from litellm.litellm_core_utils.llm_response_utils.convert_dict_to_response import ( _safe_convert_created_field, ) +from litellm.litellm_core_utils.url_utils import encode_url_path_segment from litellm.llms.openai.responses.transformation import OpenAIResponsesAPIConfig from litellm.secret_managers.main import get_secret_str from litellm.types.llms.openai import ( @@ -47,8 +45,15 @@ else: LiteLLMLoggingObj = Any +class _EventModelClass(Protocol): + @property + def model_fields(self) -> Mapping[str, pyd_fields.FieldInfo]: ... + + def model_validate(self, obj: Mapping[str, object]) -> ResponsesAPIStreamingResponse: ... + + class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): - _SUPPORTED_OPTIONAL_PARAMS: List[str] = [ + _SUPPORTED_OPTIONAL_PARAMS: list[str] = [ # Doc-listed knobs "instructions", "max_output_tokens", @@ -89,9 +94,7 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): supported.remove("metadata") return supported - def get_error_class( - self, error_message: str, status_code: int, headers: Union[dict, httpx.Headers] - ) -> VolcEngineError: + def get_error_class(self, error_message: str, status_code: int, headers: dict | httpx.Headers) -> VolcEngineError: typed_headers: httpx.Headers = headers if isinstance(headers, httpx.Headers) else httpx.Headers(headers or {}) return VolcEngineError( status_code=status_code, @@ -99,14 +102,14 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): headers=typed_headers, ) - def validate_environment(self, headers: dict, model: str, litellm_params: Optional[GenericLiteLLMParams]) -> dict: + def validate_environment(self, headers: dict, model: str, litellm_params: GenericLiteLLMParams | None) -> dict: """ Build auth headers for Volcengine Responses API. """ if litellm_params is None: litellm_params = GenericLiteLLMParams() elif isinstance(litellm_params, dict): - litellm_params = GenericLiteLLMParams(**litellm_params) + litellm_params = GenericLiteLLMParams.model_validate(litellm_params) api_key = ( litellm_params.api_key @@ -122,7 +125,7 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): def get_complete_url( self, - api_base: Optional[str], + api_base: str | None, litellm_params: dict, ) -> str: """ @@ -149,7 +152,7 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): response_api_optional_params: ResponsesAPIOptionalRequestParams, model: str, drop_params: bool, - ) -> Dict: + ) -> dict: """ Volcengine Responses API aligns with OpenAI parameters. Remove parameters not supported by the public docs. @@ -173,11 +176,11 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): def transform_responses_api_request( self, model: str, - input: Union[str, ResponseInputParam], - response_api_optional_request_params: Dict, + input: str | ResponseInputParam, + response_api_optional_request_params: dict, litellm_params: GenericLiteLLMParams, headers: dict, - ) -> Dict: + ) -> dict: """ Volcengine rejects any undocumented fields (including extra_body). Fail fast with clear errors and re-filter with the documented whitelist before delegating @@ -210,7 +213,7 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): def transform_streaming_response( self, model: str, - parsed_chunk: dict, + parsed_chunk: Mapping[str, object], logging_obj: LiteLLMLoggingObj, ) -> ResponsesAPIStreamingResponse: """ @@ -222,18 +225,19 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): if isinstance(chunk, dict): resp = chunk.get("response") if isinstance(resp, dict) and "output" not in resp: + resp_items: Mapping[str, object] = resp patched_chunk = dict(chunk) - patched_resp = dict(resp) + patched_resp = dict(resp_items) patched_resp["output"] = [] patched_chunk["response"] = patched_resp chunk = patched_chunk event_type = str(chunk.get("type")) if isinstance(chunk, dict) else None - event_pydantic_model = OpenAIResponsesAPIConfig.get_event_model_class(event_type=event_type) + event_pydantic_model: _EventModelClass = OpenAIResponsesAPIConfig.get_event_model_class(event_type=event_type) patched_chunk = self._fill_missing_fields(chunk, event_pydantic_model) - return event_pydantic_model(**patched_chunk) + return event_pydantic_model.model_validate(patched_chunk) def transform_response_api_response( self, @@ -246,7 +250,7 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): original_response=raw_response.text, additional_args={"complete_input_dict": {}}, ) - raw_response_json = raw_response.json() + raw_response_json = self._parsed_response_body(raw_response) if "created_at" in raw_response_json: raw_response_json["created_at"] = _safe_convert_created_field(raw_response_json["created_at"]) except Exception: @@ -256,10 +260,11 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): processed_headers = process_response_headers(raw_response_headers) try: - response = ResponsesAPIResponse(**raw_response_json) + response = ResponsesAPIResponse.model_validate(raw_response_json) except Exception: verbose_logger.debug("Volcengine Responses API: falling back to model_construct for response parsing.") - response = ResponsesAPIResponse.model_construct(**raw_response_json) + construct_response: Callable[..., ResponsesAPIResponse] = ResponsesAPIResponse.model_construct + response = construct_response(**raw_response_json) response._hidden_params["additional_headers"] = processed_headers response._hidden_params["headers"] = raw_response_headers @@ -274,10 +279,10 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, - ) -> Tuple[str, Dict]: + ) -> tuple[str, dict]: encoded_response_id = encode_url_path_segment(response_id, field_name="response_id") url = f"{api_base}/{encoded_response_id}" - data: Dict = {} + data: dict = {} return url, data def transform_delete_response_api_response( @@ -286,16 +291,17 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): logging_obj: LiteLLMLoggingObj, ) -> DeleteResponseResult: try: - raw_response_json = raw_response.json() + raw_response_json = self._parsed_response_body(raw_response) except Exception: raise VolcEngineError(message=raw_response.text, status_code=raw_response.status_code) try: - return DeleteResponseResult(**raw_response_json) + return DeleteResponseResult.model_validate(raw_response_json) except Exception: verbose_logger.debug( "Volcengine Responses API: falling back to model_construct for delete response parsing." ) - return DeleteResponseResult.model_construct(**raw_response_json) + construct_delete_result: Callable[..., DeleteResponseResult] = DeleteResponseResult.model_construct + return construct_delete_result(**raw_response_json) ######################################################### ########## GET RESPONSE API TRANSFORMATION ############### @@ -306,10 +312,10 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, - ) -> Tuple[str, Dict]: + ) -> tuple[str, dict]: encoded_response_id = encode_url_path_segment(response_id, field_name="response_id") url = f"{api_base}/{encoded_response_id}" - data: Dict = {} + data: dict = {} return url, data def transform_get_response_api_response( @@ -318,14 +324,14 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): logging_obj: LiteLLMLoggingObj, ) -> ResponsesAPIResponse: try: - raw_response_json = raw_response.json() + raw_response_json = self._parsed_response_body(raw_response) except Exception: raise VolcEngineError(message=raw_response.text, status_code=raw_response.status_code) raw_response_headers = dict(raw_response.headers) processed_headers = process_response_headers(raw_response_headers) - response = ResponsesAPIResponse(**raw_response_json) + response = ResponsesAPIResponse.model_validate(raw_response_json) response._hidden_params["additional_headers"] = processed_headers response._hidden_params["headers"] = raw_response_headers return response @@ -339,15 +345,15 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, - after: Optional[str] = None, - before: Optional[str] = None, - include: Optional[List[str]] = None, + after: str | None = None, + before: str | None = None, + include: list[str] | None = None, limit: int = 20, order: Literal["asc", "desc"] = "desc", - ) -> Tuple[str, Dict]: + ) -> tuple[str, dict]: encoded_response_id = encode_url_path_segment(response_id, field_name="response_id") url = f"{api_base}/{encoded_response_id}/input_items" - params: Dict[str, Any] = {} + params: dict[str, str | int] = {} if after is not None: params["after"] = after if before is not None: @@ -364,9 +370,9 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): self, raw_response: httpx.Response, logging_obj: LiteLLMLoggingObj, - ) -> Dict: + ) -> dict: try: - return raw_response.json() + return self._parsed_response_body(raw_response) except Exception: raise VolcEngineError(message=raw_response.text, status_code=raw_response.status_code) @@ -379,10 +385,10 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, - ) -> Tuple[str, Dict]: + ) -> tuple[str, dict]: encoded_response_id = encode_url_path_segment(response_id, field_name="response_id") url = f"{api_base}/{encoded_response_id}/cancel" - data: Dict = {} + data: dict = {} return url, data def transform_cancel_response_api_response( @@ -391,23 +397,23 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): logging_obj: LiteLLMLoggingObj, ) -> ResponsesAPIResponse: try: - raw_response_json = raw_response.json() + raw_response_json = self._parsed_response_body(raw_response) except Exception: raise VolcEngineError(message=raw_response.text, status_code=raw_response.status_code) raw_response_headers = dict(raw_response.headers) processed_headers = process_response_headers(raw_response_headers) - response = ResponsesAPIResponse(**raw_response_json) + response = ResponsesAPIResponse.model_validate(raw_response_json) response._hidden_params["additional_headers"] = processed_headers response._hidden_params["headers"] = raw_response_headers return response def should_fake_stream( self, - model: Optional[str], - stream: Optional[bool], - custom_llm_provider: Optional[str] = None, + model: str | None, + stream: bool | None, + custom_llm_provider: str | None = None, ) -> bool: """ Volcengine Responses API supports native streaming; never fall back to fake stream. @@ -415,7 +421,24 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): return False @staticmethod - def _fill_missing_fields(chunk: Any, event_model: Any) -> Dict[str, Any]: + def _parsed_response_body(raw_response: httpx.Response) -> dict[str, object]: + return raw_response.json() + + @staticmethod + def _annotation_origin(annotation: object) -> object: + return get_origin(annotation) + + @staticmethod + def _annotation_args(annotation: object) -> tuple[object, ...]: + return get_args(annotation) + + @staticmethod + def _field_annotation(field: pyd_fields.FieldInfo) -> object: + annotation: object = field.annotation + return annotation + + @staticmethod + def _fill_missing_fields(chunk: Mapping[str, object], event_model: object | None) -> Mapping[str, object]: """ Heuristically fill missing required fields with safe defaults based on the event model's field annotations. This keeps parsing tolerant of providers that @@ -424,31 +447,37 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): if not isinstance(chunk, dict) or event_model is None: return chunk - patched: Dict[str, Any] = dict(chunk) - fields_map = getattr(event_model, "model_fields", {}) or {} + patched = dict(chunk) + fields_map: Mapping[str, pyd_fields.FieldInfo] = getattr(event_model, "model_fields", {}) or {} for name, field in fields_map.items(): if name in patched: - patched[name] = VolcEngineResponsesAPIConfig._maybe_fill_nested(patched[name], field.annotation) + patched[name] = VolcEngineResponsesAPIConfig._maybe_fill_nested( + patched[name], VolcEngineResponsesAPIConfig._field_annotation(field) + ) continue # Explicit default or factory - if field.default is not pyd_fields.PydanticUndefined and field.default is not None: - patched[name] = field.default + field_default: object = field.default + if field_default is not pyd_fields.PydanticUndefined and field_default is not None: + patched[name] = field_default continue - if field.default_factory is not None and field.default_factory is not pyd_fields.PydanticUndefined: - patched[name] = field.default_factory() + default_factory: Callable[..., object] | None = field.default_factory + if default_factory is not None and default_factory is not pyd_fields.PydanticUndefined: + patched[name] = default_factory() continue # Heuristic defaults for missing required fields - patched[name] = VolcEngineResponsesAPIConfig._default_for_annotation(field.annotation) + patched[name] = VolcEngineResponsesAPIConfig._default_for_annotation( + VolcEngineResponsesAPIConfig._field_annotation(field) + ) return patched @staticmethod - def _default_for_annotation(annotation: Any) -> Any: - origin = get_origin(annotation) - args = get_args(annotation) + def _default_for_annotation(annotation: object) -> object: + origin = VolcEngineResponsesAPIConfig._annotation_origin(annotation) + args = VolcEngineResponsesAPIConfig._annotation_args(annotation) if annotation is int: return 0 @@ -456,7 +485,7 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): return [] if origin is Union: # Prefer empty list when any option is a list - if any((arg is list or get_origin(arg) is list) for arg in args): + if any((arg is list or VolcEngineResponsesAPIConfig._annotation_origin(arg) is list) for arg in args): return [] if type(None) in args: return None @@ -467,53 +496,51 @@ class VolcEngineResponsesAPIConfig(OpenAIResponsesAPIConfig): return None @staticmethod - def _maybe_fill_nested(value: Any, annotation: Any) -> Any: + def _maybe_fill_nested(value: object, annotation: object) -> object: """ Recursively fill nested dict/list structures based on the annotated model. """ model_cls = VolcEngineResponsesAPIConfig._pick_model_class(annotation, value) - args = get_args(annotation) + args = VolcEngineResponsesAPIConfig._annotation_args(annotation) if isinstance(value, dict) and model_cls is not None: - return VolcEngineResponsesAPIConfig._fill_missing_fields(value, model_cls) + nested_items: Mapping[str, object] = value + return VolcEngineResponsesAPIConfig._fill_missing_fields(nested_items, model_cls) if isinstance(value, list): # Attempt to fill list elements if we know the element annotation - elem_ann: Any = args[0] if args else None + elem_ann: object = args[0] if args else None if elem_ann is not None: - return [VolcEngineResponsesAPIConfig._maybe_fill_nested(v, elem_ann) for v in value] + nested_elements: Sequence[object] = value + return [VolcEngineResponsesAPIConfig._maybe_fill_nested(v, elem_ann) for v in nested_elements] return value @staticmethod - def _pick_model_class(annotation: Any, value: Any) -> Optional[Any]: + def _pick_model_class(annotation: object, value: object) -> object | None: """ Choose the best-matching Pydantic model class for a nested dict. """ - candidates: List[Any] = [] - origin = get_origin(annotation) - - if hasattr(annotation, "model_fields"): - candidates.append(annotation) - if origin is Union: - for arg in get_args(annotation): - if hasattr(arg, "model_fields"): - candidates.append(arg) + origin = VolcEngineResponsesAPIConfig._annotation_origin(annotation) + union_args = VolcEngineResponsesAPIConfig._annotation_args(annotation) if origin is Union else () + candidates = tuple(candidate for candidate in (annotation, *union_args) if hasattr(candidate, "model_fields")) if not candidates: return None # Try to match by literal "type" field when available if isinstance(value, dict): - v_type = value.get("type") + value_items: Mapping[str, object] = value + v_type = value_items.get("type") for candidate in candidates: try: - type_field = candidate.model_fields.get("type") + candidate_fields: Mapping[str, pyd_fields.FieldInfo] = getattr(candidate, "model_fields") + type_field = candidate_fields.get("type") if type_field is None: continue - literal_ann = type_field.annotation - if get_origin(literal_ann) is Literal: - literal_values = get_args(literal_ann) + literal_ann = VolcEngineResponsesAPIConfig._field_annotation(type_field) + if VolcEngineResponsesAPIConfig._annotation_origin(literal_ann) is Literal: + literal_values = VolcEngineResponsesAPIConfig._annotation_args(literal_ann) if v_type in literal_values: return candidate except Exception: diff --git a/litellm/main.py b/litellm/main.py index dc3ec469a1b..acdec7385da 100644 --- a/litellm/main.py +++ b/litellm/main.py @@ -207,7 +207,7 @@ from .llms.azure.chat.o_series_handler import AzureOpenAIO1ChatCompletion from .llms.azure.completion.handler import AzureTextCompletion from .llms.azure_ai.anthropic.handler import AzureAnthropicChatCompletion from .llms.azure_ai.embed import AzureAIEmbedding -from .llms.bedrock.chat import BedrockConverseLLM, BedrockLLM +from .llms.bedrock.chat import BedrockConverseLLM from .llms.bedrock.embed.embedding import BedrockEmbedding from .llms.bedrock.image_edit.handler import BedrockImageEdit from .llms.bedrock.image_generation.image_handler import BedrockImageGeneration diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index d43eda39b1f..07f04136bd0 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -2887,7 +2887,7 @@ "input_cost_per_token": 5e-06, "output_cost_per_token": 2.5e-05, "litellm_provider": "azure_ai", - "max_input_tokens": 200000, + "max_input_tokens": 1000000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -2916,7 +2916,7 @@ "input_cost_per_token": 5e-06, "output_cost_per_token": 2.5e-05, "litellm_provider": "azure_ai", - "max_input_tokens": 200000, + "max_input_tokens": 1000000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -3010,7 +3010,7 @@ "input_cost_per_token": 5e-06, "output_cost_per_token": 2.5e-05, "litellm_provider": "azure_ai", - "max_input_tokens": 200000, + "max_input_tokens": 1000000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -3454,22 +3454,16 @@ }, "azure_ai/gpt-5.4-mini": { "cache_read_input_token_cost": 7.5e-08, - "cache_read_input_token_cost_above_272k_tokens": 1.5e-07, "cache_read_input_token_cost_priority": 1.5e-07, - "cache_read_input_token_cost_above_272k_tokens_priority": 3e-07, "input_cost_per_token": 7.5e-07, - "input_cost_per_token_above_272k_tokens": 1.5e-06, "input_cost_per_token_priority": 1.5e-06, - "input_cost_per_token_above_272k_tokens_priority": 3e-06, "litellm_provider": "azure_ai", - "max_input_tokens": 400000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", "output_cost_per_token": 4.5e-06, - "output_cost_per_token_above_272k_tokens": 6.75e-06, "output_cost_per_token_priority": 9e-06, - "output_cost_per_token_above_272k_tokens_priority": 1.35e-05, "source": "https://ai.azure.com/catalog/models/gpt-5.4-mini", "supported_endpoints": [ "/v1/chat/completions", @@ -3500,22 +3494,16 @@ }, "azure_ai/gpt-5.4-mini-2026-03-17": { "cache_read_input_token_cost": 7.5e-08, - "cache_read_input_token_cost_above_272k_tokens": 1.5e-07, "cache_read_input_token_cost_priority": 1.5e-07, - "cache_read_input_token_cost_above_272k_tokens_priority": 3e-07, "input_cost_per_token": 7.5e-07, - "input_cost_per_token_above_272k_tokens": 1.5e-06, "input_cost_per_token_priority": 1.5e-06, - "input_cost_per_token_above_272k_tokens_priority": 3e-06, "litellm_provider": "azure_ai", - "max_input_tokens": 400000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", "output_cost_per_token": 4.5e-06, - "output_cost_per_token_above_272k_tokens": 6.75e-06, "output_cost_per_token_priority": 9e-06, - "output_cost_per_token_above_272k_tokens_priority": 1.35e-05, "source": "https://ai.azure.com/catalog/models/gpt-5.4-mini", "supported_endpoints": [ "/v1/chat/completions", @@ -3546,22 +3534,16 @@ }, "azure_ai/gpt-5.4-nano": { "cache_read_input_token_cost": 2e-08, - "cache_read_input_token_cost_above_272k_tokens": 4e-08, "cache_read_input_token_cost_priority": 4e-08, - "cache_read_input_token_cost_above_272k_tokens_priority": 8e-08, "input_cost_per_token": 2e-07, - "input_cost_per_token_above_272k_tokens": 4e-07, "input_cost_per_token_priority": 4e-07, - "input_cost_per_token_above_272k_tokens_priority": 8e-07, "litellm_provider": "azure_ai", - "max_input_tokens": 400000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", "output_cost_per_token": 1.25e-06, - "output_cost_per_token_above_272k_tokens": 1.875e-06, "output_cost_per_token_priority": 2.5e-06, - "output_cost_per_token_above_272k_tokens_priority": 3.75e-06, "source": "https://ai.azure.com/catalog/models/gpt-5.4-nano", "supported_endpoints": [ "/v1/chat/completions", @@ -3592,22 +3574,16 @@ }, "azure_ai/gpt-5.4-nano-2026-03-17": { "cache_read_input_token_cost": 2e-08, - "cache_read_input_token_cost_above_272k_tokens": 4e-08, "cache_read_input_token_cost_priority": 4e-08, - "cache_read_input_token_cost_above_272k_tokens_priority": 8e-08, "input_cost_per_token": 2e-07, - "input_cost_per_token_above_272k_tokens": 4e-07, "input_cost_per_token_priority": 4e-07, - "input_cost_per_token_above_272k_tokens_priority": 8e-07, "litellm_provider": "azure_ai", - "max_input_tokens": 400000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", "output_cost_per_token": 1.25e-06, - "output_cost_per_token_above_272k_tokens": 1.875e-06, "output_cost_per_token_priority": 2.5e-06, - "output_cost_per_token_above_272k_tokens_priority": 3.75e-06, "source": "https://ai.azure.com/catalog/models/gpt-5.4-nano", "supported_endpoints": [ "/v1/chat/completions", @@ -7201,7 +7177,7 @@ "cache_read_input_token_cost": 7.5e-08, "input_cost_per_token": 7.5e-07, "litellm_provider": "azure", - "max_input_tokens": 1050000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -7236,7 +7212,7 @@ "cache_read_input_token_cost": 7.5e-08, "input_cost_per_token": 7.5e-07, "litellm_provider": "azure", - "max_input_tokens": 1050000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -7271,7 +7247,7 @@ "cache_read_input_token_cost": 2e-08, "input_cost_per_token": 2e-07, "litellm_provider": "azure", - "max_input_tokens": 1050000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -7306,7 +7282,7 @@ "cache_read_input_token_cost": 2e-08, "input_cost_per_token": 2e-07, "litellm_provider": "azure", - "max_input_tokens": 1050000, + "max_input_tokens": 272000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", @@ -13567,6 +13543,56 @@ } ] }, + "dashscope/qwen3.7-max": { + "cache_read_input_token_cost": 5e-07, + "input_cost_per_token": 2.5e-06, + "litellm_provider": "dashscope", + "max_input_tokens": 991808, + "max_output_tokens": 65536, + "max_tokens": 65536, + "mode": "chat", + "output_cost_per_token": 7.5e-06, + "source": "https://www.alibabacloud.com/help/en/model-studio/models", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true + }, + "dashscope/qwen3.7-plus": { + "litellm_provider": "dashscope", + "max_input_tokens": 991808, + "max_output_tokens": 65536, + "max_tokens": 65536, + "mode": "chat", + "source": "https://www.alibabacloud.com/help/en/model-studio/models", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true, + "tiered_pricing": [ + { + "cache_read_input_token_cost": 8e-08, + "input_cost_per_token": 4e-07, + "output_cost_per_token": 1.6e-06, + "range": [ + 0, + 256000.0 + ] + }, + { + "cache_read_input_token_cost": 2.4e-07, + "input_cost_per_token": 1.2e-06, + "output_cost_per_token": 4.8e-06, + "range": [ + 256000.0, + 1000000.0 + ] + } + ] + }, "dashscope/qwq-plus": { "input_cost_per_token": 8e-07, "litellm_provider": "dashscope", @@ -16653,8 +16679,8 @@ "input_cost_per_token": 6e-07, "litellm_provider": "fireworks_ai", "max_input_tokens": 262144, - "max_output_tokens": 262144, - "max_tokens": 262144, + "max_output_tokens": 32768, + "max_tokens": 32768, "mode": "chat", "output_cost_per_token": 3e-06, "source": "https://fireworks.ai/pricing", @@ -16667,8 +16693,8 @@ "input_cost_per_token": 9.5e-07, "litellm_provider": "fireworks_ai", "max_input_tokens": 262144, - "max_output_tokens": 262144, - "max_tokens": 262144, + "max_output_tokens": 32768, + "max_tokens": 32768, "mode": "chat", "output_cost_per_token": 4e-06, "source": "https://docs.fireworks.ai/serverless/pricing", @@ -16683,8 +16709,8 @@ "input_cost_per_token": 9.5e-07, "litellm_provider": "fireworks_ai", "max_input_tokens": 262144, - "max_output_tokens": 262144, - "max_tokens": 262144, + "max_output_tokens": 32768, + "max_tokens": 32768, "mode": "chat", "output_cost_per_token": 4e-06, "source": "https://docs.fireworks.ai/serverless/pricing", @@ -17027,8 +17053,8 @@ "input_cost_per_token": 6e-07, "litellm_provider": "fireworks_ai", "max_input_tokens": 262144, - "max_output_tokens": 262144, - "max_tokens": 262144, + "max_output_tokens": 32768, + "max_tokens": 32768, "mode": "chat", "output_cost_per_token": 3e-06, "source": "https://fireworks.ai/pricing", @@ -17041,8 +17067,8 @@ "input_cost_per_token": 9.5e-07, "litellm_provider": "fireworks_ai", "max_input_tokens": 262144, - "max_output_tokens": 262144, - "max_tokens": 262144, + "max_output_tokens": 32768, + "max_tokens": 32768, "mode": "chat", "output_cost_per_token": 4e-06, "source": "https://docs.fireworks.ai/serverless/pricing", @@ -17057,8 +17083,8 @@ "input_cost_per_token": 2e-06, "litellm_provider": "fireworks_ai", "max_input_tokens": 262144, - "max_output_tokens": 262144, - "max_tokens": 262144, + "max_output_tokens": 32768, + "max_tokens": 32768, "mode": "chat", "output_cost_per_token": 8e-06, "source": "https://docs.fireworks.ai/serverless/pricing", @@ -17073,8 +17099,8 @@ "input_cost_per_token": 9.5e-07, "litellm_provider": "fireworks_ai", "max_input_tokens": 262144, - "max_output_tokens": 262144, - "max_tokens": 262144, + "max_output_tokens": 32768, + "max_tokens": 32768, "mode": "chat", "output_cost_per_token": 4e-06, "source": "https://docs.fireworks.ai/serverless/pricing", @@ -17089,8 +17115,8 @@ "input_cost_per_token": 1.9e-06, "litellm_provider": "fireworks_ai", "max_input_tokens": 262144, - "max_output_tokens": 262144, - "max_tokens": 262144, + "max_output_tokens": 32768, + "max_tokens": 32768, "mode": "chat", "output_cost_per_token": 8e-06, "source": "https://docs.fireworks.ai/serverless/pricing", @@ -23652,14 +23678,17 @@ "gpt-5.6": { "cache_creation_input_token_cost": 6.25e-06, "cache_creation_input_token_cost_above_272k_tokens": 1.25e-05, + "cache_creation_input_token_cost_above_272k_tokens_flex": 6.25e-06, "cache_creation_input_token_cost_flex": 3.125e-06, "cache_creation_input_token_cost_priority": 1.25e-05, "cache_read_input_token_cost": 5e-07, "cache_read_input_token_cost_above_272k_tokens": 1e-06, + "cache_read_input_token_cost_above_272k_tokens_flex": 5e-07, "cache_read_input_token_cost_flex": 2.5e-07, "cache_read_input_token_cost_priority": 1e-06, "input_cost_per_token": 5e-06, "input_cost_per_token_above_272k_tokens": 1e-05, + "input_cost_per_token_above_272k_tokens_flex": 5e-06, "input_cost_per_token_batches": 2.5e-06, "input_cost_per_token_flex": 2.5e-06, "input_cost_per_token_priority": 1e-05, @@ -23670,6 +23699,7 @@ "mode": "chat", "output_cost_per_token": 3e-05, "output_cost_per_token_above_272k_tokens": 4.5e-05, + "output_cost_per_token_above_272k_tokens_flex": 2.25e-05, "output_cost_per_token_batches": 1.5e-05, "output_cost_per_token_flex": 1.5e-05, "output_cost_per_token_priority": 6e-05, @@ -23705,14 +23735,17 @@ "gpt-5.6-sol": { "cache_creation_input_token_cost": 6.25e-06, "cache_creation_input_token_cost_above_272k_tokens": 1.25e-05, + "cache_creation_input_token_cost_above_272k_tokens_flex": 6.25e-06, "cache_creation_input_token_cost_flex": 3.125e-06, "cache_creation_input_token_cost_priority": 1.25e-05, "cache_read_input_token_cost": 5e-07, "cache_read_input_token_cost_above_272k_tokens": 1e-06, + "cache_read_input_token_cost_above_272k_tokens_flex": 5e-07, "cache_read_input_token_cost_flex": 2.5e-07, "cache_read_input_token_cost_priority": 1e-06, "input_cost_per_token": 5e-06, "input_cost_per_token_above_272k_tokens": 1e-05, + "input_cost_per_token_above_272k_tokens_flex": 5e-06, "input_cost_per_token_batches": 2.5e-06, "input_cost_per_token_flex": 2.5e-06, "input_cost_per_token_priority": 1e-05, @@ -23723,6 +23756,7 @@ "mode": "chat", "output_cost_per_token": 3e-05, "output_cost_per_token_above_272k_tokens": 4.5e-05, + "output_cost_per_token_above_272k_tokens_flex": 2.25e-05, "output_cost_per_token_batches": 1.5e-05, "output_cost_per_token_flex": 1.5e-05, "output_cost_per_token_priority": 6e-05, @@ -23756,29 +23790,33 @@ "supports_xhigh_reasoning_effort": true }, "gpt-5.6-terra": { - "cache_creation_input_token_cost": 3.125e-06, - "cache_creation_input_token_cost_above_272k_tokens": 6.25e-06, - "cache_creation_input_token_cost_flex": 1.5625e-06, - "cache_creation_input_token_cost_priority": 6.25e-06, - "cache_read_input_token_cost": 2.5e-07, - "cache_read_input_token_cost_above_272k_tokens": 5e-07, - "cache_read_input_token_cost_flex": 1.25e-07, - "cache_read_input_token_cost_priority": 5e-07, - "input_cost_per_token": 2.5e-06, - "input_cost_per_token_above_272k_tokens": 5e-06, - "input_cost_per_token_batches": 1.25e-06, - "input_cost_per_token_flex": 1.25e-06, - "input_cost_per_token_priority": 5e-06, + "cache_creation_input_token_cost": 2.5e-06, + "cache_creation_input_token_cost_above_272k_tokens": 5e-06, + "cache_creation_input_token_cost_above_272k_tokens_flex": 2.5e-06, + "cache_creation_input_token_cost_flex": 1.25e-06, + "cache_creation_input_token_cost_priority": 5e-06, + "cache_read_input_token_cost": 2e-07, + "cache_read_input_token_cost_above_272k_tokens": 4e-07, + "cache_read_input_token_cost_above_272k_tokens_flex": 2e-07, + "cache_read_input_token_cost_flex": 1e-07, + "cache_read_input_token_cost_priority": 4e-07, + "input_cost_per_token": 2e-06, + "input_cost_per_token_above_272k_tokens": 4e-06, + "input_cost_per_token_above_272k_tokens_flex": 2e-06, + "input_cost_per_token_batches": 1e-06, + "input_cost_per_token_flex": 1e-06, + "input_cost_per_token_priority": 4e-06, "litellm_provider": "openai", "max_input_tokens": 1050000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", - "output_cost_per_token": 1.5e-05, - "output_cost_per_token_above_272k_tokens": 2.25e-05, - "output_cost_per_token_batches": 7.5e-06, - "output_cost_per_token_flex": 7.5e-06, - "output_cost_per_token_priority": 3e-05, + "output_cost_per_token": 1.2e-05, + "output_cost_per_token_above_272k_tokens": 1.8e-05, + "output_cost_per_token_above_272k_tokens_flex": 9e-06, + "output_cost_per_token_batches": 6e-06, + "output_cost_per_token_flex": 6e-06, + "output_cost_per_token_priority": 2.4e-05, "regional_processing_uplift_multiplier_eu": 1.1, "regional_processing_uplift_multiplier_us": 1.1, "supported_endpoints": [ @@ -23809,29 +23847,33 @@ "supports_xhigh_reasoning_effort": true }, "gpt-5.6-luna": { - "cache_creation_input_token_cost": 1.25e-06, - "cache_creation_input_token_cost_above_272k_tokens": 2.5e-06, - "cache_creation_input_token_cost_flex": 6.25e-07, - "cache_creation_input_token_cost_priority": 2.5e-06, - "cache_read_input_token_cost": 1e-07, - "cache_read_input_token_cost_above_272k_tokens": 2e-07, - "cache_read_input_token_cost_flex": 5e-08, - "cache_read_input_token_cost_priority": 2e-07, - "input_cost_per_token": 1e-06, - "input_cost_per_token_above_272k_tokens": 2e-06, - "input_cost_per_token_batches": 5e-07, - "input_cost_per_token_flex": 5e-07, - "input_cost_per_token_priority": 2e-06, + "cache_creation_input_token_cost": 2.5e-07, + "cache_creation_input_token_cost_above_272k_tokens": 5e-07, + "cache_creation_input_token_cost_above_272k_tokens_flex": 2.5e-07, + "cache_creation_input_token_cost_flex": 1.25e-07, + "cache_creation_input_token_cost_priority": 5e-07, + "cache_read_input_token_cost": 2e-08, + "cache_read_input_token_cost_above_272k_tokens": 4e-08, + "cache_read_input_token_cost_above_272k_tokens_flex": 2e-08, + "cache_read_input_token_cost_flex": 1e-08, + "cache_read_input_token_cost_priority": 4e-08, + "input_cost_per_token": 2e-07, + "input_cost_per_token_above_272k_tokens": 4e-07, + "input_cost_per_token_above_272k_tokens_flex": 2e-07, + "input_cost_per_token_batches": 1e-07, + "input_cost_per_token_flex": 1e-07, + "input_cost_per_token_priority": 4e-07, "litellm_provider": "openai", "max_input_tokens": 1050000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", - "output_cost_per_token": 6e-06, - "output_cost_per_token_above_272k_tokens": 9e-06, - "output_cost_per_token_batches": 3e-06, - "output_cost_per_token_flex": 3e-06, - "output_cost_per_token_priority": 1.2e-05, + "output_cost_per_token": 1.2e-06, + "output_cost_per_token_above_272k_tokens": 1.8e-06, + "output_cost_per_token_above_272k_tokens_flex": 9e-07, + "output_cost_per_token_batches": 6e-07, + "output_cost_per_token_flex": 6e-07, + "output_cost_per_token_priority": 2.4e-06, "regional_processing_uplift_multiplier_eu": 1.1, "regional_processing_uplift_multiplier_us": 1.1, "supported_endpoints": [ @@ -42451,8 +42493,8 @@ "input_cost_per_token": 2e-06, "litellm_provider": "fireworks_ai", "max_input_tokens": 262144, - "max_output_tokens": 262144, - "max_tokens": 262144, + "max_output_tokens": 32768, + "max_tokens": 32768, "mode": "chat", "output_cost_per_token": 8e-06, "source": "https://docs.fireworks.ai/serverless/pricing", @@ -42467,8 +42509,8 @@ "input_cost_per_token": 1.9e-06, "litellm_provider": "fireworks_ai", "max_input_tokens": 262144, - "max_output_tokens": 262144, - "max_tokens": 262144, + "max_output_tokens": 32768, + "max_tokens": 32768, "mode": "chat", "output_cost_per_token": 8e-06, "source": "https://docs.fireworks.ai/serverless/pricing", @@ -45094,10 +45136,10 @@ "supports_vision": true }, "bedrock_mantle/openai.gpt-5.6-terra": { - "input_cost_per_token": 2.75e-06, - "cache_creation_input_token_cost": 3.4375e-06, - "cache_read_input_token_cost": 2.75e-07, - "output_cost_per_token": 1.65e-05, + "input_cost_per_token": 2.2e-06, + "cache_creation_input_token_cost": 2.75e-06, + "cache_read_input_token_cost": 2.2e-07, + "output_cost_per_token": 1.32e-05, "litellm_provider": "bedrock_mantle", "max_input_tokens": 272000, "max_output_tokens": 128000, @@ -45122,10 +45164,10 @@ "supports_vision": true }, "bedrock_mantle/openai.gpt-5.6-luna": { - "input_cost_per_token": 1.1e-06, - "cache_creation_input_token_cost": 1.375e-06, - "cache_read_input_token_cost": 1.1e-07, - "output_cost_per_token": 6.6e-06, + "input_cost_per_token": 2.2e-07, + "cache_creation_input_token_cost": 2.75e-07, + "cache_read_input_token_cost": 2.2e-08, + "output_cost_per_token": 1.32e-06, "litellm_provider": "bedrock_mantle", "max_input_tokens": 272000, "max_output_tokens": 128000, @@ -45890,6 +45932,7 @@ "supports_native_streaming": true, "supports_parallel_function_calling": true, "supports_prompt_caching": true, + "supports_reasoning": true, "supports_response_schema": true, "supports_system_messages": true, "supports_tool_choice": true, @@ -45915,6 +45958,7 @@ "supports_native_streaming": true, "supports_parallel_function_calling": true, "supports_prompt_caching": true, + "supports_reasoning": true, "supports_response_schema": true, "supports_system_messages": true, "supports_tool_choice": true, @@ -45940,6 +45984,7 @@ "supports_native_streaming": true, "supports_parallel_function_calling": true, "supports_prompt_caching": true, + "supports_reasoning": true, "supports_response_schema": true, "supports_system_messages": true, "supports_tool_choice": true, @@ -45999,6 +46044,7 @@ "supports_native_streaming": true, "supports_parallel_function_calling": true, "supports_prompt_caching": true, + "supports_reasoning": true, "supports_response_schema": true, "supports_system_messages": true, "supports_tool_choice": true, diff --git a/litellm/models/mcp_server.py b/litellm/models/mcp_server.py index 23b26bd8e89..e428d20f99d 100644 --- a/litellm/models/mcp_server.py +++ b/litellm/models/mcp_server.py @@ -102,6 +102,7 @@ class LiteLLM_MCPServerTable(LiteLLMPydanticObjectBase): byok_description: List[str] = Field(default_factory=list) byok_api_key_help_url: Optional[str] = None has_user_credential: Optional[bool] = None + connected_app_reachable: bool | None = None source_url: Optional[str] = None timeout: Optional[float] = None max_concurrent_requests: Optional[int] = None diff --git a/litellm/ocr/main.py b/litellm/ocr/main.py index 38f3f804e10..f53f32eecfa 100644 --- a/litellm/ocr/main.py +++ b/litellm/ocr/main.py @@ -7,9 +7,10 @@ import base64 import mimetypes import os import re +from collections.abc import Callable, Coroutine, Mapping from dataclasses import dataclass from io import IOBase -from typing import Any, Callable, Coroutine, Union, cast +from typing import Any, cast import httpx @@ -42,7 +43,7 @@ class _PreparedOCRRequest: provider_config: BaseOCRConfig optional_params: dict[str, object] litellm_params: dict[str, object] - effective_timeout: Union[float, httpx.Timeout] + effective_timeout: float | httpx.Timeout litellm_logging_obj: LiteLLMLoggingObj @@ -63,13 +64,13 @@ _RUST_OCR_PROVIDERS = { def _prepare_ocr_request( model: str, - document: dict[str, Any], + document: Mapping[str, object], api_key: str | None, api_base: str | None, - timeout: Union[float, httpx.Timeout] | None, + timeout: float | httpx.Timeout | None, custom_llm_provider: str | None, - extra_headers: dict[str, Any] | None, - kwargs: dict[str, Any], + extra_headers: dict[str, object] | None, + kwargs: dict[str, object], ) -> _PreparedOCRRequest: litellm_logging_obj = cast(LiteLLMLoggingObj, kwargs.pop("litellm_logging_obj")) litellm_call_id = cast(str | None, kwargs.get("litellm_call_id", None)) @@ -120,7 +121,7 @@ def _prepare_ocr_request( verbose_logger.debug(f"OCR call - model: {model}, provider: {custom_llm_provider}") - litellm_params = GenericLiteLLMParams(**kwargs) + litellm_params = GenericLiteLLMParams.model_validate(kwargs) supported_params = ocr_provider_config.get_supported_ocr_params(model=model) non_default_params = {} @@ -155,7 +156,7 @@ def _prepare_ocr_request( api_key=api_key, api_base=api_base, custom_llm_provider=custom_llm_provider, - extra_headers=cast(dict[str, object] | None, extra_headers), + extra_headers=extra_headers, provider_config=ocr_provider_config, optional_params=cast(dict[str, object], optional_params), litellm_params=dict(litellm_params), @@ -305,13 +306,13 @@ async def _run_rust_aocr( @client async def aocr( model: str, - document: dict[str, Any], + document: Mapping[str, object], api_key: str | None = None, api_base: str | None = None, - timeout: Union[float, httpx.Timeout] | None = None, + timeout: float | httpx.Timeout | None = None, custom_llm_provider: str | None = None, - extra_headers: dict[str, Any] | None = None, - **kwargs, + extra_headers: dict[str, object] | None = None, + **kwargs: object, ) -> OCRResponse: """ Async OCR function. @@ -567,14 +568,14 @@ def convert_file_document_to_url_document(document: dict[str, Any]) -> dict[str, @client def ocr( model: str, - document: dict[str, Any], + document: Mapping[str, object], api_key: str | None = None, api_base: str | None = None, - timeout: Union[float, httpx.Timeout] | None = None, + timeout: float | httpx.Timeout | None = None, custom_llm_provider: str | None = None, - extra_headers: dict[str, Any] | None = None, - **kwargs, -) -> Union[OCRResponse, Coroutine[Any, Any, OCRResponse]]: + extra_headers: dict[str, object] | None = None, + **kwargs: object, +) -> OCRResponse | Coroutine[object, object, OCRResponse]: """ Synchronous OCR function. diff --git a/litellm/proxy/_experimental/mcp_server/auth/user_api_key_auth_mcp.py b/litellm/proxy/_experimental/mcp_server/auth/user_api_key_auth_mcp.py index a27d6b92843..81983cc62fd 100644 --- a/litellm/proxy/_experimental/mcp_server/auth/user_api_key_auth_mcp.py +++ b/litellm/proxy/_experimental/mcp_server/auth/user_api_key_auth_mcp.py @@ -1,6 +1,6 @@ import re from datetime import datetime, timezone -from typing import Dict, List, Optional, Set, Tuple, cast +from typing import TYPE_CHECKING, Dict, List, Optional, Sequence, Set, Tuple, cast from fastapi import HTTPException from starlette.datastructures import Headers @@ -11,6 +11,7 @@ from typing_extensions import assert_never import litellm from litellm._logging import verbose_logger from litellm.proxy._experimental.mcp_server.oauth_utils import ( + get_passthrough_resource_metadata_url, get_request_base_url, well_known_root_suffix, ) @@ -30,6 +31,7 @@ from litellm.proxy._experimental.mcp_server.outbound_credentials.session_credent ) from litellm.proxy._types import ( UI_TEAM_ID, + LiteLLM_ObjectPermissionTable, LiteLLM_TeamTable, ProxyException, SpecialHeaders, @@ -43,13 +45,39 @@ from litellm.proxy.auth.user_api_key_auth import ( user_api_key_auth, ) from litellm.proxy.common_utils.http_parsing_utils import _read_request_body -from litellm.proxy.common_utils.user_api_key_cache import get_management_object_ttl +from litellm.proxy.common_utils.user_api_key_cache import ( + USER_NO_MCP_PERMISSION_SENTINEL, + get_management_object_ttl, + user_object_permission_id_cache_key, +) from litellm.repositories.table_repositories import ( AgentsRepository, MCPServerRepository, ) +from litellm.repositories.user_repository import UserRepository from litellm.types.mcp_server.mcp_server_manager import MCPServer +if TYPE_CHECKING: + from litellm.proxy.utils import PrismaClient + + +def _as_list(values: Sequence[str] | None) -> list[str] | None: # mutable-ok: resolver returns a list + """Widen a read-only allowlist back to the mutable list the resolver's own contract returns, + preserving the ``None`` that means "no restriction".""" + return None if values is None else list(values) + + +class UnloadableEntitlementError(Exception): + """A principal's row NAMES an ``object_permission_id`` whose contents could not be read. + + Raised only where there is POSITIVE evidence an entitlement exists, so every caller must DENY + rather than fall back to "this level places no restriction": a ceiling we know exists but cannot + read would otherwise silently widen the caller for as long as the fault lasts. + + Deliberately distinct from a lookup that fails before the principal's entitlement is known at + all. Not knowing whether someone is entitled is the state that existed before the level did, so + it places no ceiling; denying there would refuse MCP to every caller during a cold-cache fault.""" + def _parse_mcp_server_names_from_path(path: str, mcp_servers_header: Optional[List[str]] = None) -> Optional[List[str]]: """Resolve the single MCP server name a cold-start passthrough bypass may @@ -137,52 +165,83 @@ def _is_mcp_admitted_user_subject(user_api_key_auth: UserAPIKeyAuth | None) -> b return user_api_key_auth is not None and user_api_key_auth.mcp_admitted_user_subject is True -def _is_aggregate_mcp_scope(route: str, mcp_servers: list[str] | None) -> bool: - """True when a request targets the aggregate ``/mcp`` endpoint rather than any named - server. Named targets arrive either through ``x-mcp-servers`` (``mcp_servers``) or a - path segment (``/mcp/{server}`` / ``/{server}/mcp``); the aggregate scope has neither. - The gateway-DCR session arm and challenge fire only here, so a per-server flow is never - affected.""" - if mcp_servers: - return False - return len(MCPRequestHandler._extract_target_server_names_from_path(route)) == 0 +def _gateway_dcr_challenge_target( + route: str, + mcp_servers: list[str] | None, + client_ip: str | None, +) -> str | None: + """The single path-named server this request targets, iff it resolves to a + gateway-managed oauth2 server — the one per-server shape the gateway's own keyless + DCR flow serves end to end, so the 401 challenge may advertise the per-server + protected-resource metadata (whose ``authorization_servers`` names the gateway). + + Multi-server CSV paths, header/path mismatches, unknown names, and every + client-forwarded or delegated mode return ``None``: those cells keep their existing + challenge (or absence of one), and a challenge is never emitted for a name the + public discovery routes would 404, so this reveals exactly the server set the + per-server protected-resource metadata already reveals.""" + from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( + global_mcp_server_manager, + ) + + targets = _parse_mcp_server_names_from_path(route, mcp_servers) + if targets is None: + return None + server = global_mcp_server_manager.get_mcp_server_by_name(targets[0], client_ip=client_ip) + if server is None or not server.is_gateway_managed_oauth2: + return None + return targets[0] -def _is_aggregate_gateway_dcr_challenge_scope( +def _is_gateway_dcr_challenge_scope( route: str, mcp_servers: list[str] | None, mcp_auth_header: str | None, mcp_server_auth_headers: dict[str, dict[str, str]] | None, exc: Exception, + client_ip: str | None, ) -> bool: - """True when an unauthenticated request to the aggregate ``/mcp`` endpoint - should receive the RFC 9728 401 challenge that advertises the gateway as - the authorization server. + """True when an unauthenticated MCP request should receive the RFC 9728 401 + challenge that advertises the gateway as the authorization server. - Fires only for a genuine 401 on the aggregate scope: any named target - (path or ``x-mcp-servers``) belongs to the per-server challenge paths, and - client-supplied MCP auth headers mean the caller is not a cold-start DCR - client. Fails closed to the original admission error otherwise.""" + Fires only for a genuine 401 with no client-supplied MCP auth headers (those mean + the caller is not a cold-start DCR client), on the scopes the gateway's keyless + flow serves: the aggregate ``/mcp`` endpoint, an ``x-mcp-servers``-scoped request + (the resource the client configured is still ``/mcp``), or a per-server path whose + single target is a gateway-managed oauth2 server. Every other named target keeps + its existing behavior, failing closed to the original admission error.""" if not _is_litellm_auth_admission_error(exc): return False if _has_client_supplied_mcp_auth(mcp_auth_header, mcp_server_auth_headers): return False - return _is_aggregate_mcp_scope(route, mcp_servers) + if len(MCPRequestHandler._extract_target_server_names_from_path(route)) == 0: + return True + return _gateway_dcr_challenge_target(route, mcp_servers, client_ip) is not None -def _aggregate_gateway_dcr_challenge(request: Request, invalid_token: bool) -> HTTPException: - """The RFC 9728 challenge for the aggregate endpoint: points the client at - the gateway's own protected-resource metadata so a DCR client discovers - the gateway as its authorization server and starts the sign-in flow. +def _gateway_dcr_challenge( + request: Request, + route: str, + mcp_servers: list[str] | None, + invalid_token: bool, +) -> HTTPException: + """The RFC 9728 challenge pointing the client at the protected-resource metadata + matching the scope it requested: the per-server document (same URL spelling the + request arrived on) when the single target is a gateway-managed oauth2 server, + else the gateway's aggregate document. Either way the client discovers the gateway + as its authorization server and starts the same sign-in flow. ``invalid_token`` adds the RFC 6750 error code for a request that DID present a bearer that failed admission (expired or revoked), telling spec-compliant clients to re-authorize rather than retry; a request with no credentials at all gets the bare challenge per RFC 6750 section 3.1.""" - error_attr = 'error="invalid_token", ' if invalid_token else "" + target = _gateway_dcr_challenge_target(route, mcp_servers, IPAddressUtils.get_mcp_client_ip(request)) resource_metadata_url = ( - f"{get_request_base_url(request)}/.well-known/oauth-protected-resource{well_known_root_suffix()}/mcp" + get_passthrough_resource_metadata_url(request.scope, target) + if target is not None + else f"{get_request_base_url(request)}/.well-known/oauth-protected-resource{well_known_root_suffix()}/mcp" ) + error_attr = 'error="invalid_token", ' if invalid_token else "" return HTTPException( status_code=401, detail={ @@ -225,14 +284,15 @@ def _admission_failure_fallback( ): verbose_logger.debug("MCP pass-through cold start: deferring admission to route 401 emitter") return UserAPIKeyAuth() - if _is_aggregate_gateway_dcr_challenge_scope( + if _is_gateway_dcr_challenge_scope( route=request_route, mcp_servers=mcp_servers, mcp_auth_header=mcp_auth_header, mcp_server_auth_headers=mcp_server_auth_headers, exc=exc, + client_ip=IPAddressUtils.get_mcp_client_ip(request), ): - raise _aggregate_gateway_dcr_challenge(request, invalid_token=bearer_presented) from exc + raise _gateway_dcr_challenge(request, request_route, mcp_servers, invalid_token=bearer_presented) from exc raise exc @@ -244,6 +304,22 @@ class MCPRequestHandler: 3. Header extraction and validation Utilizes the main `user_api_key_auth` function to validate authentication + + Entitlement-fault contract (``get_allowed_mcp_servers`` / ``get_allowed_tools_for_server``) + ------------------------------------------------------------------------------------------ + Every level (key, team, end user, agent, org) answers "which servers/tools does this level + permit", and a level that answers nothing places no restriction. A lookup FAULT is not that + answer, and the two callers resolve it differently on purpose: + + - A keyless gateway-admitted subject fails CLOSED on any fault at any level. Each of its grant + sources is resolved independently and unioned, so a fault that returned "no restriction" would + win the union as allow-all, and its per-source org ceiling is the ONLY org bound it has. + - Key auth fails closed only where there is POSITIVE evidence an entitlement exists: a principal + row that NAMES an ``object_permission_id`` we cannot load is a known entitlement with unknown + contents (``UnloadableEntitlementError`` -> deny). A fault so early we cannot tell whether the + principal is entitled at all leaves no ceiling, because that is the state that existed before + the level did; denying there would refuse MCP to every caller, most of whom have no entitlement + configured, for the duration of a cold-cache or DB fault. """ LITELLM_API_KEY_HEADER_NAME_PRIMARY = SpecialHeaders.custom_litellm_api_key.value @@ -384,18 +460,18 @@ class MCPRequestHandler: request=request, route=request_route, ) - elif ( - _is_aggregate_mcp_scope(request_route, mcp_servers) - and oauth2_headers - and is_session_bearer_shaped(oauth2_headers["Authorization"]) - ): - # A gateway DCR session bearer at the aggregate /mcp scope: open the identity-only session - # token and admit under the live litellm user. One that does not open fails closed with the - # aggregate invalid_token challenge; a non-session bearer falls through to the oauth2 arm. + elif oauth2_headers and is_session_bearer_shaped(oauth2_headers["Authorization"]): + # A gateway DCR session bearer at any MCP scope: open the identity-only session + # token and admit under the live litellm user; downstream grant resolution + # intersects the admitted subject's servers with any path or header target, so a + # per-server scope narrows and never broadens. One that does not open fails + # closed with the scope's invalid_token challenge; a non-session bearer falls + # through to the oauth2 arm. validated_user_api_key_auth = await MCPRequestHandler._admit_gateway_session( authorization_value=oauth2_headers["Authorization"], request=request, route=request_route, + mcp_servers=mcp_servers, ) elif oauth2_headers: # Authorization on a non-delegated server: the bearer must be a real @@ -731,6 +807,7 @@ class MCPRequestHandler: authorization_value: str, request: Request, route: str, + mcp_servers: list[str] | None, ) -> UserAPIKeyAuth: """Open a gateway DCR session bearer and admit the live litellm user it references. @@ -738,8 +815,8 @@ class MCPRequestHandler: upstream credential (those are vaulted per user, resolved at egress), so authorization is resolved fresh via :meth:`_reload_admitted_user` + the centralized policy gate rather than a mint-time snapshot. Pre-DB gates (size, IP, route allowlist) run first, mirroring the standard - pipeline. Fails closed with the aggregate ``invalid_token`` challenge on an expired, tampered, - foreign, or refresh token, or a missing/deactivated/policy-rejected user.""" + pipeline. Fails closed with the requested scope's ``invalid_token`` challenge on an expired, + tampered, foreign, or refresh token, or a missing/deactivated/policy-rejected user.""" from litellm.proxy._experimental.mcp_server.outbound_credentials.session_credentials import ( NotSessionBearer, SessionBearerAdmitted, @@ -765,20 +842,20 @@ class MCPRequestHandler: ) except HTTPException as exc: # A cryptographically valid bearer whose referenced user is now missing or - # SCIM-deactivated is an invalid_token at the aggregate scope: relay the RFC 9728 + # SCIM-deactivated is an invalid_token at the requested scope: relay the RFC 9728 # challenge so the DCR client re-authorizes, matching the SessionBearerInvalid # arm, instead of a bare 401 with no WWW-Authenticate. A 503 (DB outage) is a # transient availability failure, not an auth failure, so it passes through. if exc.status_code == 401: - raise _aggregate_gateway_dcr_challenge(request, invalid_token=True) from exc + raise _gateway_dcr_challenge(request, route, mcp_servers, invalid_token=True) from exc raise return admitted case SessionBearerInvalid(): - raise _aggregate_gateway_dcr_challenge(request, invalid_token=True) + raise _gateway_dcr_challenge(request, route, mcp_servers, invalid_token=True) case NotSessionBearer(): # Unreachable: the arm is entered only for an is_session_bearer_shaped # value. Kept for match exhaustiveness and fails closed regardless. - raise _aggregate_gateway_dcr_challenge(request, invalid_token=True) + raise _gateway_dcr_challenge(request, route, mcp_servers, invalid_token=True) case _: assert_never(result) @@ -1299,6 +1376,9 @@ class MCPRequestHandler: has an explicit MCP server list, the combined key/team/end_user/agent result is capped to that list. If the org has no list, no extra restriction is applied. + A level that cannot answer is NOT a level that permits everything; see the class docstring + for how each caller shape resolves an entitlement fault. + Returns: List[str]: List of allowed MCP servers by server id """ @@ -1408,6 +1488,15 @@ class MCPRequestHandler: f"Applied agent intersection filter. Final allowed servers: {allowed_mcp_servers}" ) + ######################################################### + # Apply the internal user's own ceiling (the entitlement attached to the human) + ######################################################### + capped, user_restricts = await MCPRequestHandler._apply_user_server_ceiling( + allowed_mcp_servers, user_api_key_auth, keyless_source=keyless_source + ) + allowed_mcp_servers = list(capped) + has_lower_level_mcp_restrictions = has_lower_level_mcp_restrictions or user_restricts + ######################################################### # Apply org-level ceiling if org_id is set ######################################################### @@ -1420,7 +1509,12 @@ class MCPRequestHandler: return list(set(allowed_mcp_servers)) except Exception as e: - verbose_logger.warning(f"Failed to get allowed MCP servers: {str(e)}") + if isinstance(e, UnloadableEntitlementError): + # A ceiling we KNOW exists and cannot read. Denying is the only answer that does not + # widen this caller past what an operator configured, for both caller shapes. + verbose_logger.warning(f"Denying MCP access, entitlement unreadable: {str(e)}") + else: + verbose_logger.warning(f"Failed to get allowed MCP servers: {str(e)}") return [] @staticmethod @@ -1433,11 +1527,15 @@ class MCPRequestHandler: """Cap the resolved server list by this caller's org ceiling: an explicit org list intersects lower-level restrictions (else becomes the ceiling); no org or an empty list leaves it unchanged. - ``keyless_source`` governs both divergences for a keyless admitted source. An UNRESOLVABLE ceiling - fails CLOSED for it (its only org bound is this ceiling, so dropping it on a fault would escalate a - cross-org user) while a key stays fail-open. And an org list may only ever INTERSECT a source (the - admitted model unions grants, so a ceiling must not become one), whereas for a key it may - substitute, that being the key ceiling model.""" + ``keyless_source`` governs both divergences for a keyless admitted source. An INDETERMINATE ceiling + (we cannot tell whether the org restricts at all) fails CLOSED for it (its only org bound is this + ceiling, so dropping it on a fault would escalate a cross-org user) while a key stays fail-open. And + an org list may only ever INTERSECT a source (the admitted model unions grants, so a ceiling must not + become one), whereas for a key it may substitute, that being the key ceiling model. + + The fail-open arm is reached only for an INDETERMINATE fault: a ceiling the org NAMES but that + cannot be read raises out of ``_get_allowed_mcp_servers_for_org`` and never arrives here as + ``None``, so key auth cannot silently shed a ceiling an operator did configure.""" if not (user_api_key_auth and user_api_key_auth.org_id): return allowed_mcp_servers allowed_mcp_servers_for_org = await MCPRequestHandler._get_allowed_mcp_servers_for_org(user_api_key_auth) @@ -1831,17 +1929,30 @@ class MCPRequestHandler: # No team restrictions → use key restrictions allowed_tools = cast(List[str], key_tools) + allowed_tools = _as_list( + await MCPRequestHandler._apply_user_tool_ceiling( + allowed_tools, server_id, user_api_key_auth, keyless_source=keyless_source + ) + ) + return await MCPRequestHandler._apply_agent_and_org_tool_ceilings( allowed_tools, server_id, user_api_key_auth, keyless_source=keyless_source ) except Exception as e: - verbose_logger.warning(f"Failed to get allowed tools for server: {str(e)}") + # An entitlement known to exist but unreadable denies for BOTH caller shapes, so [] rather + # than the None (allow-all) key auth gets for an indeterminate fault. + unreadable_entitlement = isinstance(e, UnloadableEntitlementError) + if unreadable_entitlement: + verbose_logger.warning(f"Denying MCP tools, entitlement unreadable: {str(e)}") + else: + verbose_logger.warning(f"Failed to get allowed tools for server: {str(e)}") # Fail CLOSED for a keyless admitted subject: ANY error must deny the server's tools ([]), # not collapse to allow-all (None); key/JWT auth keeps its prior allow-all-on-error. Both # keyless_source AND the marker are needed: each source resolves through an UNMARKED auth, so # without keyless_source a fault under a source returns None and wins the union as allow-all. - return [] if (keyless_source or _is_mcp_admitted_user_subject(user_api_key_auth)) else None + deny_all = unreadable_entitlement or keyless_source or _is_mcp_admitted_user_subject(user_api_key_auth) + return [] if deny_all else None @staticmethod async def _apply_agent_and_org_tool_ceilings( @@ -1880,7 +1991,9 @@ class MCPRequestHandler: try: org_obj_perm = await MCPRequestHandler._get_org_object_permission(user_api_key_auth) except Exception as e: # noqa: BLE001 # unresolvable org ceiling, decided per caller shape - if keyless_source: + # A ceiling the org NAMES but that cannot be read denies at every caller shape; only an + # INDETERMINATE fault (we cannot tell whether a ceiling exists) keeps key auth open. + if keyless_source or isinstance(e, UnloadableEntitlementError): raise verbose_logger.warning( f"MCP org tool ceiling unresolvable for org_id={user_api_key_auth.org_id!r}; " @@ -1899,6 +2012,18 @@ class MCPRequestHandler: return allowed_tools + @staticmethod + def tool_is_granted(bare_tool_name: str, allowed_tool_names: list[str] | None) -> bool: + """Whether key/team tool permissions reach ``bare_tool_name`` on one server. + + ``None`` means no tool-level restriction; an empty list grants nothing. Entries + name a tool on a single server and every writer stores them bare, so the + comparison is exact against the bare name rather than against the spellings + routing accepts. Both the listing path and the call path answer through here, so + discovery cannot advertise a tool that ``tools/call`` then refuses. + """ + return allowed_tool_names is None or bare_tool_name in allowed_tool_names + @staticmethod async def is_tool_allowed_for_server( tool_name: str, @@ -1909,7 +2034,7 @@ class MCPRequestHandler: Check if a specific tool is allowed for a server based on key/team permissions. Args: - tool_name: Name of the tool to check + tool_name: Bare tool name, already resolved against the server's prefixes server_id: Server ID user_api_key_auth: User auth @@ -1920,17 +2045,7 @@ class MCPRequestHandler: server_id=server_id, user_api_key_auth=user_api_key_auth, ) - - # None means no restrictions (allow all) - if allowed_tools is None: - return True - - # Empty list means no tools allowed - if not allowed_tools: - return False - - # Check if tool is in allowed list - return tool_name in allowed_tools + return MCPRequestHandler.tool_is_granted(tool_name, allowed_tools) @staticmethod def is_tool_allowed( @@ -2209,18 +2324,54 @@ class MCPRequestHandler: verbose_logger.warning(f"Failed to get allowed MCP servers for team: {str(e)}") return [] + @staticmethod + async def _load_named_object_permission( + principal: str, + object_permission_id: str, + prisma_client: "PrismaClient", + user_api_key_auth: UserAPIKeyAuth, + ) -> LiteLLM_ObjectPermissionTable: + """Load the object permission a principal's row NAMES, or raise ``UnloadableEntitlementError``. + + The single place that fault is minted, so end user, agent and org cannot drift on what counts + as "known entitlement, unknown contents". ``get_object_permission`` answers None for both an + absent row and a failed read, and neither is evidence the principal is unrestricted: the link + proves an entitlement was configured, so both must deny.""" + from litellm.proxy.auth.auth_checks import get_object_permission + from litellm.proxy.proxy_server import proxy_logging_obj, user_api_key_cache + + unloadable = UnloadableEntitlementError( + f"{principal} names object_permission_id {object_permission_id!r} which could not be loaded" + ) + try: + object_permission = await get_object_permission( + object_permission_id=object_permission_id, + prisma_client=prisma_client, + user_api_key_cache=user_api_key_cache, + parent_otel_span=user_api_key_auth.parent_otel_span, + proxy_logging_obj=proxy_logging_obj, + ) + except Exception as e: # noqa: BLE001 # a named entitlement we cannot read denies, whatever the read failed with + raise unloadable from e + if object_permission is None: + raise unloadable + return object_permission + @staticmethod async def _get_org_object_permission( user_api_key_auth: Optional[UserAPIKeyAuth] = None, - ): + ) -> LiteLLM_ObjectPermissionTable | None: """ Get org object_permission via the established ``get_org_object`` / ``get_object_permission`` helpers so MCP requests share the same ``user_api_key_cache`` entries as the rest of the proxy. + + ``None`` means the org places NO ceiling: no ``org_id``, no DB, or an org row naming no + permission. A row that NAMES one it cannot load raises ``UnloadableEntitlementError``; + every other lookup failure propagates as itself, leaving the ceiling merely unresolved. """ from litellm.proxy.auth.auth_checks import ( OrganizationNotFoundError, - get_object_permission, get_org_object, ) from litellm.proxy.proxy_server import ( @@ -2256,31 +2407,29 @@ class MCPRequestHandler: if org_obj is None or not org_obj.object_permission_id: return None - # The org NAMES a permission; failing to read it is INDETERMINATE and must not collapse into the - # None that means "no ceiling". Raise and let each caller pick fail-open or fail-closed. - object_permission = await get_object_permission( + # The org NAMES a permission; failing to read it is a KNOWN ceiling with unknown contents and + # must not collapse into the None that means "no ceiling". Raising denies at every caller shape. + return await MCPRequestHandler._load_named_object_permission( + principal=f"org {user_api_key_auth.org_id!r}", object_permission_id=org_obj.object_permission_id, prisma_client=prisma_client, - user_api_key_cache=user_api_key_cache, - parent_otel_span=user_api_key_auth.parent_otel_span, - proxy_logging_obj=proxy_logging_obj, + user_api_key_auth=user_api_key_auth, ) - if object_permission is None: - raise ValueError( - f"org {user_api_key_auth.org_id!r} names object_permission_id " - f"{org_obj.object_permission_id!r} which could not be loaded" - ) - return object_permission @staticmethod async def _get_allowed_mcp_servers_for_org( user_api_key_auth: Optional[UserAPIKeyAuth] = None, - ) -> List[str]: + ) -> list[str] | None: """ Get allowed MCP servers for an organization. Returns the MCP servers from the org's object_permission. - An empty result means the org places no restriction (allow-all from this level). + An empty result means the org places no restriction (allow-all from this level), ``None`` + that the ceiling could not be resolved, which the caller decides per shape. + + A ceiling the org NAMES but we cannot read is neither: it raises out of here so both caller + shapes deny, because dropping a ceiling known to exist is exactly the silent widening the + level is there to prevent. """ try: object_permissions = await MCPRequestHandler._get_org_object_permission(user_api_key_auth) @@ -2308,34 +2457,28 @@ class MCPRequestHandler: except Exception as e: # None = ceiling UNRESOLVED, distinct from [] = org places no restriction. Collapsing them # let a DB fault silently drop a ceiling; the caller picks fail-open/closed from this signal. + # A NAMED-but-unreadable ceiling is a stronger fact than "unresolved" and denies everywhere. + if isinstance(e, UnloadableEntitlementError): + raise verbose_logger.warning(f"Failed to get allowed MCP servers for org: {str(e)}") return None @staticmethod - async def _get_allowed_mcp_servers_for_end_user( - user_api_key_auth: Optional[UserAPIKeyAuth] = None, - ) -> List[str]: - """ - Get allowed MCP servers for an end user. + async def _get_end_user_object_permission( + user_api_key_auth: UserAPIKeyAuth, + prisma_client: "PrismaClient", + ) -> LiteLLM_ObjectPermissionTable | None: + """The end user's own object_permission, or ``None`` when this level places no restriction. - Returns the MCP servers from the end_user's object_permission. - """ + ``None`` covers an end user row that is absent or names no permission, and an end user we + could not resolve at all (``get_end_user_object`` answers None for an absent row AND for a + failed read, so this level genuinely cannot tell those apart). A row that DOES name a + permission we cannot load raises ``UnloadableEntitlementError``: the link is positive + evidence of an entitlement, so its contents may not be assumed empty.""" from litellm.proxy.auth.auth_checks import get_end_user_object - from litellm.proxy.proxy_server import ( - prisma_client, - proxy_logging_obj, - user_api_key_cache, - ) - - if not user_api_key_auth or not user_api_key_auth.end_user_id: - return [] - - if prisma_client is None: - verbose_logger.debug("prisma_client is None") - return [] + from litellm.proxy.proxy_server import proxy_logging_obj, user_api_key_cache try: - # Use optimized get_end_user_object function with caching end_user_obj = await get_end_user_object( end_user_id=user_api_key_auth.end_user_id, prisma_client=prisma_client, @@ -2344,29 +2487,65 @@ class MCPRequestHandler: proxy_logging_obj=proxy_logging_obj, route="/mcp", ) + except Exception as e: # noqa: BLE001 # entitlement unknown, not known-absent: no ceiling, as before this level + verbose_logger.warning(f"Failed to resolve end_user for MCP permissions: {str(e)}") + return None - if end_user_obj is None or end_user_obj.object_permission is None: - return [] + if end_user_obj is None: + return None + if end_user_obj.object_permission is not None: + return end_user_obj.object_permission + if not end_user_obj.object_permission_id: + return None + # The row NAMES a permission the relation did not carry. One shared (cached) lookup decides + # whether it is readable; an unreadable one denies rather than reading as "no restriction". + return await MCPRequestHandler._load_named_object_permission( + principal=f"end user {user_api_key_auth.end_user_id!r}", + object_permission_id=end_user_obj.object_permission_id, + prisma_client=prisma_client, + user_api_key_auth=user_api_key_auth, + ) + @staticmethod + async def _get_allowed_mcp_servers_for_end_user( + user_api_key_auth: Optional[UserAPIKeyAuth] = None, + ) -> List[str]: + """ + Get allowed MCP servers for an end user. + + Returns the MCP servers from the end_user's object_permission; an empty result means this + level places no restriction. An entitlement the end user row NAMES but that cannot be read + raises ``UnloadableEntitlementError`` out of here so the resolver denies. + """ + from litellm.proxy.proxy_server import prisma_client + + if not user_api_key_auth or not user_api_key_auth.end_user_id: + return [] + + if prisma_client is None: + verbose_logger.debug("prisma_client is None") + return [] + + object_permission = await MCPRequestHandler._get_end_user_object_permission(user_api_key_auth, prisma_client) + if object_permission is None: + return [] + + try: # Permission entries may be server_ids OR names/aliases — expand to ids. from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( global_mcp_server_manager, ) - direct_mcp_servers = global_mcp_server_manager.expand_permission_list( - end_user_obj.object_permission.mcp_servers or [] - ) + direct_mcp_servers = global_mcp_server_manager.expand_permission_list(object_permission.mcp_servers or []) # Get MCP servers from access groups access_group_servers = await MCPRequestHandler._get_mcp_servers_from_access_groups( - end_user_obj.object_permission.mcp_access_groups or [] + object_permission.mcp_access_groups or [] ) # servers referenced in tool permissions should also be accessible tool_perm_servers = list( - global_mcp_server_manager.expand_tool_permissions( - end_user_obj.object_permission.mcp_tool_permissions - ).keys() + global_mcp_server_manager.expand_tool_permissions(object_permission.mcp_tool_permissions).keys() ) # Combine all lists @@ -2376,19 +2555,24 @@ class MCPRequestHandler: verbose_logger.warning(f"Failed to get allowed MCP servers for end_user: {str(e)}") return [] - # Sentinel stored in cache when an agent has no object_permission, so we - # don't re-query the DB on every MCP request for that agent. - _AGENT_NO_PERMISSION_SENTINEL = "__agent_no_mcp_permission__" - @staticmethod - async def _get_agent_object_permission( - user_api_key_auth: Optional[UserAPIKeyAuth] = None, - ): - """ - Get agent object_permission via the established ``get_object_permission`` - helper. Caches the ``agent_id -> object_permission_id`` mapping so we - avoid re-reading the agent row on every request, and reuses the shared - ``object_permission_id`` cache populated by the org / team / key paths. + async def _get_user_object_permission( + user_api_key_auth: UserAPIKeyAuth | None = None, + ) -> LiteLLM_ObjectPermissionTable | None: + """The internal user's OWN object_permission: the entitlement attached to the HUMAN rather + than to the credential they authenticated with. + + A key's object_permission is the credential's scope and a team's is the group's; this one + answers "which MCP servers and tools is this person entitled to", independent of how many keys + they hold. Caches the ``user_id -> object_permission_id`` mapping (with a sentinel for "no + entitlement") exactly as the agent path does, then reuses the shared ``object_permission_id`` + cache, so a warm request reads no rows. + + ``None`` means the human places NO ceiling: no user row, or a row naming no permission. The + two fault classes are deliberately NOT collapsed into that: a user row we cannot read leaves + us unable to say whether they are entitled at all, which is exactly the state before this + level existed, so it places no ceiling; a row that NAMES a permission we cannot read is a + KNOWN entitlement with unknown contents, so it raises and the caller denies. """ from litellm.proxy.auth.auth_checks import get_object_permission from litellm.proxy.proxy_server import ( @@ -2397,6 +2581,227 @@ class MCPRequestHandler: user_api_key_cache, ) + if not user_api_key_auth or not user_api_key_auth.user_id: + return None + + if prisma_client is None: + verbose_logger.debug("prisma_client is None") + return None + + user_id = user_api_key_auth.user_id + object_permission_id = await MCPRequestHandler._user_object_permission_id(user_id, prisma_client) + if object_permission_id is None: + return None + + object_permission = await get_object_permission( + object_permission_id=object_permission_id, + prisma_client=prisma_client, + user_api_key_cache=user_api_key_cache, + parent_otel_span=user_api_key_auth.parent_otel_span, + proxy_logging_obj=proxy_logging_obj, + ) + if object_permission is None: + raise ValueError( + f"user {user_id!r} names object_permission_id {object_permission_id!r} which could not be loaded" + ) + return object_permission + + @staticmethod + async def _user_object_permission_id(user_id: str, prisma_client: "PrismaClient") -> str | None: + """The permission row this human's user row links to, or None when they link none. + + Caches the link (with a sentinel for "links none") so a human without an entitlement costs no + DB read per MCP request. Anything other than an id string is treated as a cache MISS rather + than carried into the permission lookup, and a read that fails answers None: not knowing + whether someone is entitled is the state that existed before this level, so it places no + ceiling. Only a link we DID resolve can make the caller deny. + """ + from litellm.proxy.proxy_server import user_api_key_cache + + cache_key = user_object_permission_id_cache_key(user_id) + try: + cached: object = await user_api_key_cache.async_get_cache(key=cache_key) + if cached == USER_NO_MCP_PERMISSION_SENTINEL: + return None + if isinstance(cached, str) and cached: + return cached + user_row = await UserRepository(prisma_client).table.find_unique(where={"user_id": user_id}) + linked: object = getattr(user_row, "object_permission_id", None) if user_row is not None else None + object_permission_id = linked if isinstance(linked, str) and linked else None + await user_api_key_cache.async_set_cache( + key=cache_key, + value=object_permission_id or USER_NO_MCP_PERMISSION_SENTINEL, + ttl=get_management_object_ttl(user_api_key_cache), + ) + return object_permission_id + except Exception as e: # noqa: BLE001 # unknown whether entitled at all: no ceiling, as before + verbose_logger.warning(f"MCP user entitlement: link for {user_id!r} unresolved, no ceiling: {str(e)}") + return None + + @staticmethod + async def _get_allowed_mcp_servers_for_user( + user_api_key_auth: UserAPIKeyAuth | None = None, + ) -> Sequence[str] | None: + """The MCP servers the internal user is entitled to, as server ids. + + ``[]`` means this human places no restriction (allow-all from this level); ``None`` means the + ceiling is UNRESOLVED, which the caller denies on. Servers named only under + ``mcp_tool_permissions`` count as entitled, exactly as they do for a key or a team, so + granting one tool never requires naming its server twice. + """ + from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( + global_mcp_server_manager, + ) + + try: + object_permissions = await MCPRequestHandler._get_user_object_permission(user_api_key_auth) + if object_permissions is None: + return [] + + direct_mcp_servers = global_mcp_server_manager.expand_permission_list(object_permissions.mcp_servers or []) + access_group_servers = await MCPRequestHandler._get_mcp_servers_from_access_groups( + object_permissions.mcp_access_groups or [] + ) + tool_perm_servers = list( + global_mcp_server_manager.expand_tool_permissions(object_permissions.mcp_tool_permissions).keys() + ) + return list(set(direct_mcp_servers + access_group_servers + tool_perm_servers)) + except Exception as e: # noqa: BLE001 # any resolution fault is an unresolved ceiling, never "no ceiling" + verbose_logger.warning(f"Failed to get allowed MCP servers for user: {str(e)}") + return None + + @staticmethod + async def _apply_user_server_ceiling( + allowed_mcp_servers: Sequence[str], + user_api_key_auth: UserAPIKeyAuth | None = None, + *, + keyless_source: bool = False, + ) -> tuple[tuple[str, ...], bool]: + """Narrow a resolved server list by the internal user's own entitlement. + + Returns the capped list and whether this human restricted it at all; the caller needs the + second value because an org list may only CAP a lower-level restriction, never replace one, so + a user ceiling has to be visible to the org step. + + RAISES when the entitlement is known but unreadable, which the resolver's own handler turns + into deny-all. That is the point of the level: dropping a ceiling we know exists is exactly the + silent widening it is there to prevent. + """ + if keyless_source: + return tuple(allowed_mcp_servers), False + entitled = await MCPRequestHandler._get_allowed_mcp_servers_for_user(user_api_key_auth) + if entitled is None: + raise ValueError( + f"MCP user ceiling unresolvable for user_id=" + f"{user_api_key_auth.user_id if user_api_key_auth else None!r}" + ) + if not entitled: + return tuple(allowed_mcp_servers), False + capped = tuple(server for server in allowed_mcp_servers if server in set(entitled)) + verbose_logger.debug(f"Applied user ceiling filter. Final allowed servers: {capped}") + return capped, True + + @staticmethod + async def _user_places_mcp_ceiling(user_api_key_auth: UserAPIKeyAuth | None = None) -> bool: + """Whether this human's own entitlement bounds their MCP access at all. + + True when they are entitled to a specific set of servers, and also when that entitlement is + UNRESOLVED — a caller uses this to decide whether it may skip the resolver, and skipping it on + a transient fault would widen access. + """ + entitled_servers = await MCPRequestHandler._get_allowed_mcp_servers_for_user(user_api_key_auth) + return entitled_servers is None or len(entitled_servers) > 0 + + @staticmethod + async def _apply_user_tool_ceiling( + allowed_tools: Sequence[str] | None, + server_id: str, + user_api_key_auth: UserAPIKeyAuth | None = None, + *, + keyless_source: bool = False, + ) -> Sequence[str] | None: + """Narrow a key/team tool allowlist by the internal user's own tool entitlement. + + The human's entitlement can only ever narrow: a user naming tools on ``server_id`` intersects + (and becomes the allowlist when no lower level restricts), while a user naming none places no + restriction. Returns ``[]`` (deny every tool on this server) when the entitlement cannot be + resolved, because the caller's own except-handler treats a raise as allow-all for key auth. + """ + from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( + global_mcp_server_manager, + ) + + if keyless_source: + return allowed_tools + + try: + object_permissions = await MCPRequestHandler._get_user_object_permission(user_api_key_auth) + except Exception as e: # noqa: BLE001 # an unresolved human entitlement must deny, not widen + verbose_logger.warning(f"MCP user tool ceiling unresolvable, denying tools on {server_id!r}: {str(e)}") + return [] + + if object_permissions is None or not object_permissions.mcp_tool_permissions: + return allowed_tools + + user_tools = global_mcp_server_manager.expand_tool_permissions(object_permissions.mcp_tool_permissions).get( + server_id + ) + if user_tools is None: + return allowed_tools + if allowed_tools is None: + return list(user_tools) + return list(set(allowed_tools) & set(user_tools)) + + # Sentinel stored in cache when an agent has no object_permission, so we + # don't re-query the DB on every MCP request for that agent. + _AGENT_NO_PERMISSION_SENTINEL = "__agent_no_mcp_permission__" + + @staticmethod + async def _agent_object_permission_id(agent_id: str, prisma_client: "PrismaClient") -> str | None: + """The permission row this agent's row links to, or ``None`` when it links none. + + Caches the link (with a sentinel for "links none") so an agent without an entitlement costs + no DB read per MCP request. A read that fails also answers ``None``: not knowing whether the + agent is entitled is the state that existed before this level, so it places no ceiling. Only + a link we DID resolve can make the caller deny.""" + from litellm.proxy.proxy_server import user_api_key_cache + + cache_key = f"agent_object_permission_id:{agent_id}" + try: + cached: object = await user_api_key_cache.async_get_cache(key=cache_key) + if cached == MCPRequestHandler._AGENT_NO_PERMISSION_SENTINEL: + return None + if isinstance(cached, str) and cached: + return cached + agent_row = await AgentsRepository(prisma_client).table.find_unique(where={"agent_id": agent_id}) + linked: object = getattr(agent_row, "object_permission_id", None) if agent_row is not None else None + object_permission_id = linked if isinstance(linked, str) and linked else None + await user_api_key_cache.async_set_cache( + key=cache_key, + value=object_permission_id or MCPRequestHandler._AGENT_NO_PERMISSION_SENTINEL, + ttl=get_management_object_ttl(user_api_key_cache), + ) + return object_permission_id + except Exception as e: # noqa: BLE001 # entitlement unknown, not known-absent: no ceiling, as before this level + verbose_logger.warning(f"Failed to resolve object_permission_id for agent {agent_id!r}: {str(e)}") + return None + + @staticmethod + async def _get_agent_object_permission( + user_api_key_auth: Optional[UserAPIKeyAuth] = None, + ) -> LiteLLM_ObjectPermissionTable | None: + """ + Get agent object_permission via the established ``get_object_permission`` + helper. Caches the ``agent_id -> object_permission_id`` mapping so we + avoid re-reading the agent row on every request, and reuses the shared + ``object_permission_id`` cache populated by the org / team / key paths. + + ``None`` means the agent places NO restriction: no ``agent_id``, no DB, or an agent linking + no permission. An agent that LINKS one we cannot load raises ``UnloadableEntitlementError``, + since a known entitlement with unknown contents must deny rather than read as unrestricted. + """ + from litellm.proxy.proxy_server import prisma_client + if not user_api_key_auth or not user_api_key_auth.agent_id: return None @@ -2405,40 +2810,17 @@ class MCPRequestHandler: return None agent_id = user_api_key_auth.agent_id - cache_key = f"agent_object_permission_id:{agent_id}" - - try: - object_permission_id: Optional[str] = await user_api_key_cache.async_get_cache(key=cache_key) - - if object_permission_id == MCPRequestHandler._AGENT_NO_PERMISSION_SENTINEL: - return None - - if object_permission_id is None: - agent_row = await AgentsRepository(prisma_client).table.find_unique( - where={"agent_id": agent_id}, - ) - object_permission_id = ( - getattr(agent_row, "object_permission_id", None) if agent_row is not None else None - ) - await user_api_key_cache.async_set_cache( - key=cache_key, - value=object_permission_id or MCPRequestHandler._AGENT_NO_PERMISSION_SENTINEL, - ttl=get_management_object_ttl(user_api_key_cache), - ) - if not object_permission_id: - return None - - return await get_object_permission( - object_permission_id=object_permission_id, - prisma_client=prisma_client, - user_api_key_cache=user_api_key_cache, - parent_otel_span=user_api_key_auth.parent_otel_span, - proxy_logging_obj=proxy_logging_obj, - ) - except Exception as e: - verbose_logger.warning(f"Failed to get agent object permission: {str(e)}") + object_permission_id = await MCPRequestHandler._agent_object_permission_id(agent_id, prisma_client) + if object_permission_id is None: return None + return await MCPRequestHandler._load_named_object_permission( + principal=f"agent {agent_id!r}", + object_permission_id=object_permission_id, + prisma_client=prisma_client, + user_api_key_auth=user_api_key_auth, + ) + @staticmethod async def _get_allowed_mcp_servers_for_agent( user_api_key_auth: Optional[UserAPIKeyAuth] = None, @@ -2448,7 +2830,9 @@ class MCPRequestHandler: Get allowed MCP servers for an agent (from the agent's object_permission). Returns the MCP servers from the agent's object_permission. - If agent has no object_permission, returns [] (no extra restriction). + If agent has no object_permission, returns [] (no extra restriction). An entitlement the + agent LINKS but that cannot be read raises ``UnloadableEntitlementError`` out of here so the + resolver denies. Args: user_api_key_auth: User auth with agent_id @@ -2458,13 +2842,13 @@ class MCPRequestHandler: if not user_api_key_auth or not user_api_key_auth.agent_id: return [] - try: - obj_perm = agent_object_permission - if obj_perm is None: - obj_perm = await MCPRequestHandler._get_agent_object_permission(user_api_key_auth) - if obj_perm is None: - return [] + obj_perm = agent_object_permission + if obj_perm is None: + obj_perm = await MCPRequestHandler._get_agent_object_permission(user_api_key_auth) + if obj_perm is None: + return [] + try: direct_mcp_servers = getattr(obj_perm, "mcp_servers", None) or [] if isinstance(direct_mcp_servers, str): direct_mcp_servers = [] @@ -2494,7 +2878,9 @@ class MCPRequestHandler: ) -> Optional[List[str]]: """ Get allowed tool names for a server from the agent's object_permission. - Returns None if agent has no tool restrictions for this server. + Returns None if agent has no tool restrictions for this server. An entitlement the agent + LINKS but that cannot be read raises ``UnloadableEntitlementError`` out of here, which the + tool resolver turns into deny-all for the server rather than an unrestricted tool list. Args: server_id: Server ID to check permissions for @@ -2505,13 +2891,13 @@ class MCPRequestHandler: if not user_api_key_auth or not user_api_key_auth.agent_id: return None - try: - obj_perm = agent_object_permission - if obj_perm is None: - obj_perm = await MCPRequestHandler._get_agent_object_permission(user_api_key_auth) - if obj_perm is None: - return None + obj_perm = agent_object_permission + if obj_perm is None: + obj_perm = await MCPRequestHandler._get_agent_object_permission(user_api_key_auth) + if obj_perm is None: + return None + try: mcp_tool_permissions = getattr(obj_perm, "mcp_tool_permissions", None) if not mcp_tool_permissions or not isinstance(mcp_tool_permissions, dict): return None diff --git a/litellm/proxy/_experimental/mcp_server/db.py b/litellm/proxy/_experimental/mcp_server/db.py index 9fe970f7fa9..3221f3b8dd4 100644 --- a/litellm/proxy/_experimental/mcp_server/db.py +++ b/litellm/proxy/_experimental/mcp_server/db.py @@ -2,22 +2,25 @@ import base64 import binascii import hashlib import json +from collections.abc import Awaitable, Callable, Iterable, Mapping, Sequence from datetime import datetime, timedelta, timezone -from typing import TYPE_CHECKING, Any, Awaitable, Callable, Dict, Iterable, List, Optional, Set, Union, cast +from typing import ( + TYPE_CHECKING, + Any, + TypedDict, + cast, +) from litellm._logging import verbose_proxy_logger from litellm._uuid import uuid from litellm.constants import MCP_PER_USER_TOKEN_EXPIRY_BUFFER_SECONDS from litellm.llms.custom_httpx.http_handler import get_async_httpx_client -from litellm.proxy._experimental.mcp_server.auth.token_endpoint_auth import ( - build_token_endpoint_client_auth, - normalize_token_endpoint_auth_method, -) +from litellm.proxy._experimental.mcp_server.oauth_utils import build_upstream_oauth2_token_request from litellm.proxy._types import ( LiteLLM_MCPServerTable, LiteLLM_ObjectPermissionTable, - LiteLLM_TeamTable, MCPApprovalStatus, + MCPEnvVar, MCPEnvVarScope, MCPSubmissionsSummary, NewMCPServerRequest, @@ -45,9 +48,13 @@ from litellm.types.llms.custom_http import httpxSpecialProvider from litellm.types.mcp import MCPCredentials if TYPE_CHECKING: + from prisma import models as prisma_db_models + from prisma import types as prisma_db_types + from prisma.actions import LiteLLM_MCPUserCredentialsActions, LiteLLM_MCPUserEnvVarsActions + from litellm.types.mcp_server.mcp_server_manager import MCPServer -_AUTH_FLOW_SCOPED_FIELDS: frozenset = frozenset( +_AUTH_FLOW_SCOPED_FIELDS: "frozenset[str]" = frozenset( { "issuer", "authorization_url", @@ -63,7 +70,7 @@ _AUTH_FLOW_SCOPED_FIELDS: frozenset = frozenset( ) -def _blank_to_none(value: Optional[str]) -> Optional[str]: +def _blank_to_none(value: str | None) -> str | None: if not isinstance(value, str): return None return value.strip() or None @@ -76,7 +83,7 @@ def _blank_to_none(value: Optional[str]) -> Optional[str]: # the current code has never written — a cleared column can then never be # silently resurrected by a stale blob copy. These keys are stored plaintext # (endpoints/identifiers, not secrets), so values lift as-is. -_TOKEN_EXCHANGE_COLUMN_FIELDS: frozenset = frozenset( +_TOKEN_EXCHANGE_COLUMN_FIELDS: "frozenset[str]" = frozenset( { "token_exchange_endpoint", "audience", @@ -89,13 +96,33 @@ _TOKEN_EXCHANGE_COLUMN_FIELDS: frozenset = frozenset( # OAuth app (client_id/client_secret) plus the same authorize relay, and neither mints anything the # gateway keeps. So a switch WITHIN this class must preserve the stored app, unlike a cross-class # switch (e.g. an oauth2 row whose client may be DCR-minted and is not reusable elsewhere). -_CLIENT_FORWARDED_AUTH_TYPES: frozenset = frozenset({"true_passthrough", "oauth_delegate"}) +_CLIENT_FORWARDED_AUTH_TYPES: "frozenset[str]" = frozenset({"true_passthrough", "oauth_delegate"}) # Minted token material that must never survive a client rotation on a persisted row. -_MINTED_TOKEN_CREDENTIAL_FIELDS: frozenset = frozenset({"access_token", "refresh_token", "expires_in"}) +_MINTED_TOKEN_CREDENTIAL_FIELDS: "frozenset[str]" = frozenset({"access_token", "refresh_token", "expires_in"}) -def _credential_auth_class(auth_type: Optional[str]) -> Optional[str]: +class _OAuthCredentialAccessToken(TypedDict): + access_token: str + + +class OAuthCredentialPayload(_OAuthCredentialAccessToken, total=False): + type: str + refresh_token: str + expires_at: str + connected_at: str + scopes: list[str] + server_id: str + + +class _OAuthTokenRefreshResponse(TypedDict, total=False): + access_token: str + refresh_token: str + expires_in: int + scope: str + + +def _credential_auth_class(auth_type: str | None) -> str | None: """Collapse the client-forwarded modes to one credential class; every other auth_type is its own class. Used so credential handling keys off whether the stored-credential shape actually changed, not off a raw auth_type inequality that treats true_passthrough<->oauth_delegate as a full reset.""" @@ -104,7 +131,7 @@ def _credential_auth_class(auth_type: Optional[str]) -> Optional[str]: return auth_type -def _drop_stale_minted_on_client_rotation(merged: Dict[str, Any], new_creds: Dict[str, Any]) -> Dict[str, Any]: +def _drop_stale_minted_on_client_rotation(merged: dict[str, object], new_creds: dict[str, object]) -> dict[str, object]: """When the update rotates the client, drop stale minted token keys it did not itself set, so an old app's access/refresh token never rides forward under the new client. A no-op when no client key changed.""" if "client_id" not in new_creds and "client_secret" not in new_creds: @@ -114,13 +141,13 @@ def _drop_stale_minted_on_client_rotation(merged: Dict[str, Any], new_creds: Dic } -def _is_global_env_var_scope(scope: Any) -> bool: +def _is_global_env_var_scope(scope: object) -> bool: """``scope="user"`` entries are placeholders the user fills in; everything else (including a missing scope) is an admin-supplied global value.""" return scope != MCPEnvVarScope.user and scope != "user" -def _encrypt_global_env_var_values(env_vars: Iterable[Dict[str, Any]]) -> None: +def _encrypt_global_env_var_values(env_vars: Iterable[dict[str, str]]) -> None: """Encrypt ``scope="global"`` env var values in place before persisting. Global values hold admin-supplied secrets (API keys, passwords) that get @@ -136,7 +163,7 @@ def _encrypt_global_env_var_values(env_vars: Iterable[Dict[str, Any]]) -> None: entry["value"] = encrypt_value_helper(value) -def decrypt_global_env_var_values(env_vars: Optional[Iterable[Any]]) -> None: +def decrypt_global_env_var_values(env_vars: Iterable[MCPEnvVar | dict[str, str]] | None) -> None: """Decrypt ``scope="global"`` env var values in place after reading the DB. Accepts ``MCPEnvVar`` models (``LiteLLM_MCPServerTable``) or plain dicts @@ -175,7 +202,7 @@ def decrypt_global_env_var_values(env_vars: Optional[Iterable[Any]]) -> None: entry.value = decrypted -def _decrypt_env_vars_on_returned_row(row: Any) -> None: +def _decrypt_env_vars_on_returned_row(row: object) -> None: """Decrypt ``scope="global"`` env var values on a row returned by Prisma create/update. Prisma may hand back ``env_vars`` either as a parsed list (the common case for @@ -205,8 +232,8 @@ def _decrypt_env_vars_on_returned_row(row: Any) -> None: def _reencrypt_global_env_var_values( - env_vars: Optional[Iterable[Any]], new_encryption_key: str -) -> Optional[List[Dict[str, Any]]]: + env_vars: str | Iterable[Mapping[str, str]] | None, new_encryption_key: str +) -> list[dict[str, str]] | None: """Re-encrypt ``scope="global"`` env var values for master-key rotation. Each global value is decrypted with the current salt key and re-encrypted @@ -217,14 +244,17 @@ def _reencrypt_global_env_var_values( """ if not env_vars: return None + entries: Iterable[Mapping[str, str]] if isinstance(env_vars, str): try: - env_vars = json.loads(env_vars) + entries = json.loads(env_vars) except (json.JSONDecodeError, TypeError): return None - if not env_vars: + if not entries: return None - rebuilt = [dict(v) for v in env_vars] + else: + entries = env_vars + rebuilt = [dict(v) for v in entries] rotated = False for entry in rebuilt: if not _is_global_env_var_scope(entry.get("scope")): @@ -250,10 +280,10 @@ def _reencrypt_global_env_var_values( def _prepare_mcp_server_data( - data: Union[NewMCPServerRequest, UpdateMCPServerRequest], + data: NewMCPServerRequest | UpdateMCPServerRequest, exclude_unset: bool = False, - fields_set: Optional[Set[str]] = None, -) -> Dict[str, Any]: + fields_set: set[str] | None = None, +) -> dict[str, Any]: """ Helper function to prepare MCP server data for database operations. Handles JSON field serialization for mcp_info and env fields. @@ -329,7 +359,7 @@ def _prepare_mcp_server_data( # column so the exclude_unset filter is respected: a partial update that # omits env_vars never overwrites the stored value. Global values are # encrypted at rest before serialization. - env_vars = data_dict.get("env_vars") + env_vars: Sequence[Mapping[str, str]] | None = data_dict.get("env_vars") if env_vars is not None: serialized_env_vars = [dict(v) for v in env_vars] _encrypt_global_env_var_values(serialized_env_vars) @@ -356,7 +386,7 @@ def _prepare_mcp_server_data( return data_dict -def encrypt_credentials(credentials: MCPCredentials, encryption_key: Optional[str]) -> MCPCredentials: +def encrypt_credentials(credentials: MCPCredentials, encryption_key: str | None) -> MCPCredentials: auth_value = credentials.get("auth_value") if auth_value is not None: credentials["auth_value"] = encrypt_value_helper( @@ -404,6 +434,98 @@ def encrypt_credentials(credentials: MCPCredentials, encryption_key: Optional[st return credentials +def _credentials_blob_to_mutable_dict(blob: str | Mapping[str, object]) -> dict[str, object]: + parsed_blob: dict[str, object] = json.loads(blob) if isinstance(blob, str) else dict(blob) + return parsed_blob + + +async def _db_find_mcp_server_rows( + prisma_client: PrismaClient, + where: "prisma_db_types.LiteLLM_MCPServerTableWhereInput | None" = None, +) -> "list[prisma_db_models.LiteLLM_MCPServerTable]": + rows: list[prisma_db_models.LiteLLM_MCPServerTable] = await MCPServerRepository(prisma_client).table.find_many( + where=where + ) + return rows + + +async def _db_find_mcp_server_row( + prisma_client: PrismaClient, server_id: str +) -> "prisma_db_models.LiteLLM_MCPServerTable | None": + row: prisma_db_models.LiteLLM_MCPServerTable | None = await MCPServerRepository(prisma_client).table.find_unique( + where={"server_id": server_id} + ) + return row + + +async def _db_update_mcp_server_row( + prisma_client: PrismaClient, + server_id: str, + data: "prisma_db_types.LiteLLM_MCPServerTableUpdateInput", +) -> "prisma_db_models.LiteLLM_MCPServerTable": + row: prisma_db_models.LiteLLM_MCPServerTable = await MCPServerRepository(prisma_client).table.update( + where={"server_id": server_id}, + data=data, + ) + return row + + +def _user_credential_actions( + prisma_client: PrismaClient, +) -> "LiteLLM_MCPUserCredentialsActions[prisma_db_models.LiteLLM_MCPUserCredentials]": + table: LiteLLM_MCPUserCredentialsActions[prisma_db_models.LiteLLM_MCPUserCredentials] = ( + MCPUserCredentialsRepository(prisma_client).table + ) + return table + + +def _user_env_var_actions( + prisma_client: PrismaClient, +) -> "LiteLLM_MCPUserEnvVarsActions[prisma_db_models.LiteLLM_MCPUserEnvVars]": + table: LiteLLM_MCPUserEnvVarsActions[prisma_db_models.LiteLLM_MCPUserEnvVars] = ( + prisma_client.db.litellm_mcpuserenvvars + ) + return table + + +async def _db_find_user_credential_row( + prisma_client: PrismaClient, user_id: str, server_id: str +) -> "prisma_db_models.LiteLLM_MCPUserCredentials | None": + return await _user_credential_actions(prisma_client).find_unique( + where={"user_id_server_id": {"user_id": user_id, "server_id": server_id}} + ) + + +async def _db_find_user_credential_rows( + prisma_client: PrismaClient, + where: "prisma_db_types.LiteLLM_MCPUserCredentialsWhereInput | None" = None, +) -> "list[prisma_db_models.LiteLLM_MCPUserCredentials]": + return await _user_credential_actions(prisma_client).find_many(where=where) + + +async def _db_upsert_user_credential_row( + prisma_client: PrismaClient, user_id: str, server_id: str, credential_b64: str +) -> None: + await MCPUserCredentialsRepository(prisma_client).table.upsert( + where={"user_id_server_id": {"user_id": user_id, "server_id": server_id}}, + data={ + "create": { + "user_id": user_id, + "server_id": server_id, + "credential_b64": credential_b64, + }, + "update": {"credential_b64": credential_b64}, + }, + ) + + +async def _db_find_user_env_var_rows( + prisma_client: PrismaClient, + where: "prisma_db_types.LiteLLM_MCPUserEnvVarsWhereInput | None" = None, +) -> "list[prisma_db_models.LiteLLM_MCPUserEnvVars]": + return await _user_env_var_actions(prisma_client).find_many(where=where) + + def decrypt_credentials( credentials: MCPCredentials, ) -> MCPCredentials: @@ -431,19 +553,19 @@ def decrypt_credentials( async def get_all_mcp_servers( prisma_client: PrismaClient, - approval_status: Optional[str] = None, -) -> List[LiteLLM_MCPServerTable]: + approval_status: str | None = None, +) -> list[LiteLLM_MCPServerTable]: """ Returns mcp servers from the db, optionally filtered by approval_status. Pass approval_status=None to return all servers regardless of approval state. """ try: - where: Dict[str, Any] = {} + where: prisma_db_types.LiteLLM_MCPServerTableWhereInput = {} if approval_status is not None: where["approval_status"] = approval_status - mcp_servers = await MCPServerRepository(prisma_client).table.find_many(where=where if where else {}) + mcp_servers = await _db_find_mcp_server_rows(prisma_client, where if where else {}) - tables = [LiteLLM_MCPServerTable(**mcp_server.model_dump()) for mcp_server in mcp_servers] + tables = [LiteLLM_MCPServerTable.model_validate(mcp_server.model_dump()) for mcp_server in mcp_servers] for table in tables: decrypt_global_env_var_values(table.env_vars) return tables @@ -454,45 +576,45 @@ async def get_all_mcp_servers( return [] -async def get_mcp_server(prisma_client: PrismaClient, server_id: str) -> Optional[LiteLLM_MCPServerTable]: +async def get_mcp_server(prisma_client: PrismaClient, server_id: str) -> LiteLLM_MCPServerTable | None: """ Returns the matching mcp server from the db iff exists """ - mcp_server: Optional[LiteLLM_MCPServerTable] = await MCPServerRepository(prisma_client).table.find_unique( - where={ - "server_id": server_id, - } - ) + mcp_server = await _db_find_mcp_server_row(prisma_client, server_id) if mcp_server is None: return None - table = LiteLLM_MCPServerTable(**mcp_server.model_dump()) + table = LiteLLM_MCPServerTable.model_validate(mcp_server.model_dump()) decrypt_global_env_var_values(table.env_vars) return table -async def get_mcp_servers(prisma_client: PrismaClient, server_ids: Iterable[str]) -> List[LiteLLM_MCPServerTable]: +async def get_mcp_servers(prisma_client: PrismaClient, server_ids: Iterable[str]) -> list[LiteLLM_MCPServerTable]: """ Returns the matching mcp servers from the db with the server_ids """ - _mcp_servers: List[LiteLLM_MCPServerTable] = await MCPServerRepository(prisma_client).table.find_many( + _mcp_servers: list[prisma_db_models.LiteLLM_MCPServerTable] = await MCPServerRepository( + prisma_client + ).table.find_many( where={ "server_id": {"in": server_ids}, } ) - final_mcp_servers: List[LiteLLM_MCPServerTable] = [] + final_mcp_servers: list[LiteLLM_MCPServerTable] = [] for _mcp_server in _mcp_servers: - table = LiteLLM_MCPServerTable(**_mcp_server.model_dump()) + table = LiteLLM_MCPServerTable.model_validate(_mcp_server.model_dump()) decrypt_global_env_var_values(table.env_vars) final_mcp_servers.append(table) return final_mcp_servers -async def get_mcp_servers_by_verificationtoken(prisma_client: PrismaClient, token: str) -> List[str]: +async def get_mcp_servers_by_verificationtoken(prisma_client: PrismaClient, token: str) -> list[str]: """ Returns the mcp servers from the db for the verification token """ - verification_token_record: LiteLLM_TeamTable = await VerificationTokenRepository(prisma_client).table.find_unique( + verification_token_record: prisma_db_models.LiteLLM_VerificationToken | None = await VerificationTokenRepository( + prisma_client + ).table.find_unique( where={ "token": token, }, @@ -501,17 +623,17 @@ async def get_mcp_servers_by_verificationtoken(prisma_client: PrismaClient, toke }, ) - mcp_servers: Optional[List[str]] = [] + mcp_servers: list[str] | None = [] if verification_token_record is not None and verification_token_record.object_permission is not None: mcp_servers = verification_token_record.object_permission.mcp_servers return mcp_servers or [] -async def get_mcp_servers_by_team(prisma_client: PrismaClient, team_id: str) -> List[str]: +async def get_mcp_servers_by_team(prisma_client: PrismaClient, team_id: str) -> list[str]: """ Returns the mcp servers from the db for the team id """ - team_record: LiteLLM_TeamTable = await TeamRepository(prisma_client).table.find_unique( + team_record: prisma_db_models.LiteLLM_TeamTable | None = await TeamRepository(prisma_client).table.find_unique( where={ "team_id": team_id, }, @@ -520,7 +642,7 @@ async def get_mcp_servers_by_team(prisma_client: PrismaClient, team_id: str) -> }, ) - mcp_servers: Optional[List[str]] = [] + mcp_servers: list[str] | None = [] if team_record is not None and team_record.object_permission is not None: mcp_servers = team_record.object_permission.mcp_servers return mcp_servers or [] @@ -529,14 +651,14 @@ async def get_mcp_servers_by_team(prisma_client: PrismaClient, team_id: str) -> async def get_all_mcp_servers_for_user( prisma_client: PrismaClient, user: UserAPIKeyAuth, -) -> List[LiteLLM_MCPServerTable]: +) -> list[LiteLLM_MCPServerTable]: """ Get all the mcp servers filtered by the given user has access to. Following Least-Privilege Principle - the requestor should only be able to see the mcp servers that they have access to. """ - mcp_server_ids: Set[str] = set() + mcp_server_ids: set[str] = set() mcp_servers = [] # Get the mcp servers for the key @@ -557,11 +679,13 @@ async def get_all_mcp_servers_for_user( async def get_objectpermissions_for_mcp_server( prisma_client: PrismaClient, mcp_server_id: str -) -> List[LiteLLM_ObjectPermissionTable]: +) -> list[LiteLLM_ObjectPermissionTable]: """ Get all the object permissions records and the associated team and verficiationtoken records that have access to the mcp server """ - object_permission_records = await ObjectPermissionRepository(prisma_client).table.find_many( + object_permission_records: list[LiteLLM_ObjectPermissionTable] = await ObjectPermissionRepository( + prisma_client + ).table.find_many( where={ "mcp_servers": {"has": mcp_server_id}, }, @@ -574,11 +698,15 @@ async def get_objectpermissions_for_mcp_server( return object_permission_records -async def get_virtualkeys_for_mcp_server(prisma_client: PrismaClient, server_id: str) -> List: +async def get_virtualkeys_for_mcp_server( + prisma_client: PrismaClient, server_id: str +) -> "list[prisma_db_models.LiteLLM_VerificationToken]": """ Get all the virtual keys that have access to the mcp server """ - virtual_keys = await VerificationTokenRepository(prisma_client).table.find_many( + virtual_keys: list[prisma_db_models.LiteLLM_VerificationToken] | None = await VerificationTokenRepository( + prisma_client + ).table.find_many( where={ "mcp_servers": {"has": server_id}, }, @@ -606,8 +734,8 @@ async def delete_mcp_server_from_virtualkey(): async def delete_mcp_server( prisma_client: PrismaClient, server_id: str, - invalidate_token_cache: Optional[Callable[[str, str], Awaitable[None]]] = None, -) -> Optional[LiteLLM_MCPServerTable]: + invalidate_token_cache: Callable[[str, str], Awaitable[None]] | None = None, +) -> LiteLLM_MCPServerTable | None: """ Delete the mcp server from the db by server_id @@ -632,11 +760,11 @@ async def delete_mcp_server( }, ) if deleted_server is not None: - credential_user_ids: List[str] = [] + credential_user_ids: list[str] = [] try: - credential_rows = await prisma_client.db.litellm_mcpusercredentials.find_many( - where={"server_id": server_id} - ) + credential_rows: Sequence[ + prisma_db_models.LiteLLM_MCPUserCredentials + ] = await prisma_client.db.litellm_mcpusercredentials.find_many(where={"server_id": server_id}) credential_user_ids = [row.user_id for row in credential_rows] except Exception as e: # noqa: BLE001 - enumeration is best-effort; cached tokens expire by TTL verbose_proxy_logger.warning( @@ -687,7 +815,7 @@ async def create_mcp_server( data_dict["created_by"] = touched_by data_dict["updated_by"] = touched_by - new_mcp_server = await MCPServerRepository(prisma_client).table.create( + new_mcp_server: LiteLLM_MCPServerTable = await MCPServerRepository(prisma_client).table.create( data=data_dict # type: ignore ) @@ -699,13 +827,11 @@ async def update_mcp_server( prisma_client: PrismaClient, data: UpdateMCPServerRequest, touched_by: str, - fields_set: Optional[Set[str]] = None, + fields_set: set[str] | None = None, ) -> LiteLLM_MCPServerTable: """ Update a new mcp server record in the db """ - import json - from litellm.litellm_core_utils.safe_json_dumps import safe_dumps # Use helper to prepare data with proper JSON serialization. @@ -723,7 +849,7 @@ async def update_mcp_server( url_provided = "url" in data_dict and data_dict["url"] is not None issuer_provided = "issuer" in data_dict if data.auth_type or has_credentials or explicit_te_write or url_provided or issuer_provided: - existing = await MCPServerRepository(prisma_client).table.find_unique(where={"server_id": data.server_id}) + existing = await _db_find_mcp_server_row(prisma_client, data.server_id) auth_type_changed = bool( data.auth_type @@ -763,9 +889,7 @@ async def update_mcp_server( # repopulate the column the admin just cleared. (When credentials ARE in the # update, the merge below performs the same migration.) if explicit_te_write and "credentials" not in data_dict and existing is not None and existing.credentials: - existing_creds = ( - json.loads(existing.credentials) if isinstance(existing.credentials, str) else dict(existing.credentials) - ) + existing_creds = _credentials_blob_to_mutable_dict(existing.credentials) if _TOKEN_EXCHANGE_COLUMN_FIELDS & existing_creds.keys(): for te_field in _TOKEN_EXCHANGE_COLUMN_FIELDS: legacy_value = existing_creds.pop(te_field, None) @@ -784,16 +908,8 @@ async def update_mcp_server( # within the client-forwarded class (true_passthrough ↔ oauth_delegate) keeps # the same declared app and so must merge, not replace. if not auth_type_changed: - existing_creds = ( - json.loads(existing.credentials) - if isinstance(existing.credentials, str) - else dict(existing.credentials) - ) - new_creds = ( - json.loads(data_dict["credentials"]) - if isinstance(data_dict["credentials"], str) - else dict(data_dict["credentials"]) - ) + existing_creds = _credentials_blob_to_mutable_dict(existing.credentials) + new_creds = _credentials_blob_to_mutable_dict(data_dict["credentials"]) # New values override existing; existing keys not in update are preserved. A client # rotation additionally drops the previous app's stale minted token keys. merged = _drop_stale_minted_on_client_rotation({**existing_creds, **new_creds}, new_creds) @@ -823,7 +939,7 @@ async def update_mcp_server( data_dict["credentials"] = Json(None) - updated_mcp_server = await MCPServerRepository(prisma_client).table.update( + updated_mcp_server: LiteLLM_MCPServerTable = await MCPServerRepository(prisma_client).table.update( where={"server_id": data.server_id}, data=data_dict, # type: ignore ) @@ -838,7 +954,9 @@ async def get_mcp_server_oauth_client_credentials(prisma_client: PrismaClient, s LiteLLM_MCPServerTable row, so their dynamically registered client lives here keyed by server_id. The returned value is the raw credentials blob for ``_get_persisted_dcr_credentials`` to parse.""" - row = await MCPServerOAuthClientRepository(prisma_client).table.find_unique(where={"server_id": server_id}) + row: prisma_db_models.LiteLLM_MCPServerOAuthClient | None = await MCPServerOAuthClientRepository( + prisma_client + ).table.find_unique(where={"server_id": server_id}) if row is None: return None return row.credentials @@ -854,7 +972,7 @@ async def upsert_mcp_server_oauth_client_credentials( same way regardless of which store a server's client came from.""" from litellm.litellm_core_utils.safe_json_dumps import safe_dumps - encrypted = encrypt_credentials(credentials=dict(credentials), encryption_key=_get_salt_key()) + encrypted = encrypt_credentials(credentials=MCPCredentials(**credentials), encryption_key=_get_salt_key()) blob = safe_dumps(encrypted) await MCPServerOAuthClientRepository(prisma_client).table.upsert( where={"server_id": server_id}, @@ -865,7 +983,9 @@ async def upsert_mcp_server_oauth_client_credentials( ) -def _reencrypt_mcp_credentials_blob(credentials: object, new_master_key: str) -> str | None: +def _reencrypt_mcp_credentials_blob( + credentials: "str | Mapping[str, object] | None", new_master_key: str +) -> str | None: """Decrypt an at-rest MCP credentials blob with the current key and re-encrypt it under new_master_key, returning the serialized blob or None when there is nothing to rotate. Shared by every table that stores an encrypted MCP credentials blob so a master-key rotation covers them @@ -874,7 +994,7 @@ def _reencrypt_mcp_credentials_blob(credentials: object, new_master_key: str) -> return None from litellm.litellm_core_utils.safe_json_dumps import safe_dumps # noqa: PLC0415 # avoids circular import - creds_dict = json.loads(credentials) if isinstance(credentials, str) else dict(credentials) + creds_dict = _credentials_blob_to_mutable_dict(credentials) decrypted = decrypt_credentials(credentials=cast(MCPCredentials, creds_dict)) encrypted = encrypt_credentials(credentials=decrypted, encryption_key=new_master_key) return safe_dumps(encrypted) @@ -883,11 +1003,11 @@ def _reencrypt_mcp_credentials_blob(credentials: object, new_master_key: str) -> async def rotate_mcp_server_credentials_master_key(prisma_client: PrismaClient, touched_by: str, new_master_key: str): from litellm.litellm_core_utils.safe_json_dumps import safe_dumps # noqa: PLC0415 # avoids circular import - mcp_servers = await MCPServerRepository(prisma_client).table.find_many() + mcp_servers = await _db_find_mcp_server_rows(prisma_client) updated = 0 for mcp_server in mcp_servers: - update_data: Dict[str, Any] = {} + update_data: dict[str, str] = {} rotated_credentials = _reencrypt_mcp_credentials_blob(mcp_server.credentials, new_master_key) if rotated_credentials is not None: @@ -907,7 +1027,9 @@ async def rotate_mcp_server_credentials_master_key(prisma_client: PrismaClient, ) updated += 1 - oauth_clients = await MCPServerOAuthClientRepository(prisma_client).table.find_many() + oauth_clients: list[prisma_db_models.LiteLLM_MCPServerOAuthClient] = await MCPServerOAuthClientRepository( + prisma_client + ).table.find_many() oauth_updated = 0 for oauth_client in oauth_clients: rotated_credentials = _reencrypt_mcp_credentials_blob(oauth_client.credentials, new_master_key) @@ -926,7 +1048,7 @@ async def rotate_mcp_server_credentials_master_key(prisma_client: PrismaClient, ) -def _decode_user_credential(stored: str) -> Optional[str]: +def _decode_user_credential(stored: str) -> str | None: """Read back a value persisted in ``LiteLLM_MCPUserCredentials.credential_b64``. Tries nacl decryption first (current write format). Falls back to a @@ -948,7 +1070,7 @@ def _decode_user_credential(stored: str) -> Optional[str]: return None -def _decode_oauth_payload(stored: str) -> Optional[Dict[str, Any]]: +def _decode_oauth_payload(stored: str) -> OAuthCredentialPayload | None: """Return the OAuth2 payload dict if ``stored`` holds one, else ``None``. A row is considered an OAuth2 credential iff its decoded value parses as @@ -958,6 +1080,7 @@ def _decode_oauth_payload(stored: str) -> Optional[Dict[str, Any]]: decoded = _decode_user_credential(stored) if decoded is None: return None + parsed: OAuthCredentialPayload | None try: parsed = json.loads(decoded) except (ValueError, TypeError): @@ -975,7 +1098,7 @@ async def rotate_mcp_user_credentials_master_key(prisma_client: PrismaClient, ne under the new master key. Rows that are unreadable under both paths are logged and skipped so one corrupt row does not abort the rotation. """ - rows = await MCPUserCredentialsRepository(prisma_client).table.find_many() + rows = await _db_find_user_credential_rows(prisma_client) rotated = 0 skipped = 0 for row in rows: @@ -990,7 +1113,7 @@ async def rotate_mcp_user_credentials_master_key(prisma_client: PrismaClient, ne skipped += 1 continue re_encrypted = encrypt_value_helper(plaintext, new_encryption_key=new_master_key) - await MCPUserCredentialsRepository(prisma_client).table.update( + await _user_credential_actions(prisma_client).update( where={ "user_id_server_id": { "user_id": row.user_id, @@ -1015,7 +1138,7 @@ async def rotate_mcp_user_env_vars_master_key(prisma_client: PrismaClient, new_m skipped so one corrupt row does not abort the rotation nor overwrite values that may still be recoverable. """ - rows = await prisma_client.db.litellm_mcpuserenvvars.find_many() + rows = await _db_find_user_env_var_rows(prisma_client) rotated = 0 skipped = 0 for row in rows: @@ -1034,7 +1157,7 @@ async def rotate_mcp_user_env_vars_master_key(prisma_client: PrismaClient, new_m skipped += 1 continue re_encrypted = encrypt_value_helper(plaintext, new_encryption_key=new_master_key) - await prisma_client.db.litellm_mcpuserenvvars.update( + await _user_env_var_actions(prisma_client).update( where={ "user_id_server_id": { "user_id": row.user_id, @@ -1060,29 +1183,17 @@ async def store_user_credential( """Store a user credential for a BYOK MCP server.""" encoded = encrypt_value_helper(credential) - await MCPUserCredentialsRepository(prisma_client).table.upsert( - where={"user_id_server_id": {"user_id": user_id, "server_id": server_id}}, - data={ - "create": { - "user_id": user_id, - "server_id": server_id, - "credential_b64": encoded, - }, - "update": {"credential_b64": encoded}, - }, - ) + await _db_upsert_user_credential_row(prisma_client, user_id, server_id, encoded) async def get_user_credential( prisma_client: PrismaClient, user_id: str, server_id: str, -) -> Optional[str]: +) -> str | None: """Return credential for a user+server pair, or None.""" - row = await MCPUserCredentialsRepository(prisma_client).table.find_unique( - where={"user_id_server_id": {"user_id": user_id, "server_id": server_id}} - ) + row = await _db_find_user_credential_row(prisma_client, user_id, server_id) if row is None: return None return _decode_user_credential(row.credential_b64) @@ -1094,9 +1205,7 @@ async def has_user_credential( server_id: str, ) -> bool: """Return True if the user has a stored credential for this server.""" - row = await MCPUserCredentialsRepository(prisma_client).table.find_unique( - where={"user_id_server_id": {"user_id": user_id, "server_id": server_id}} - ) + row = await _db_find_user_credential_row(prisma_client, user_id, server_id) return row is not None @@ -1106,7 +1215,7 @@ async def delete_user_credential( server_id: str, ) -> None: """Delete the user's stored credential for a BYOK MCP server.""" - await MCPUserCredentialsRepository(prisma_client).table.delete( + await _user_credential_actions(prisma_client).delete( where={"user_id_server_id": {"user_id": user_id, "server_id": server_id}} ) @@ -1119,9 +1228,9 @@ async def store_user_oauth_credential( user_id: str, server_id: str, access_token: str, - refresh_token: Optional[str] = None, - expires_in: Optional[int] = None, - scopes: Optional[List[str]] = None, + refresh_token: str | None = None, + expires_in: int | None = None, + scopes: list[str] | None = None, skip_byok_guard: bool = False, ) -> None: """Persist an OAuth2 access token for a user+server pair. @@ -1131,11 +1240,11 @@ async def store_user_oauth_credential( differentiates it from plain BYOK API keys. """ - expires_at: Optional[str] = None + expires_at: str | None = None if expires_in is not None: expires_at = (datetime.now(timezone.utc) + timedelta(seconds=expires_in)).isoformat() - payload: Dict[str, Any] = { + payload: OAuthCredentialPayload = { "type": "oauth2", "access_token": access_token, "connected_at": datetime.now(timezone.utc).isoformat(), @@ -1151,9 +1260,7 @@ async def store_user_oauth_credential( # Skip the guard when the caller knows the row is already an OAuth2 credential # (e.g. during token refresh), saving an extra DB round-trip. if not skip_byok_guard: - existing = await MCPUserCredentialsRepository(prisma_client).table.find_unique( - where={"user_id_server_id": {"user_id": user_id, "server_id": server_id}} - ) + existing = await _db_find_user_credential_row(prisma_client, user_id, server_id) if existing is not None and _decode_oauth_payload(existing.credential_b64) is None: # Existing row is either a BYOK secret or an OAuth2 row that no # longer decrypts (e.g. after a salt-key rotation). In either @@ -1166,20 +1273,10 @@ async def store_user_oauth_credential( ) encoded = encrypt_value_helper(json.dumps(payload)) - await MCPUserCredentialsRepository(prisma_client).table.upsert( - where={"user_id_server_id": {"user_id": user_id, "server_id": server_id}}, - data={ - "create": { - "user_id": user_id, - "server_id": server_id, - "credential_b64": encoded, - }, - "update": {"credential_b64": encoded}, - }, - ) + await _db_upsert_user_credential_row(prisma_client, user_id, server_id, encoded) -def is_oauth_credential_expired(cred: Dict[str, Any], buffer_seconds: int = 0) -> bool: +def is_oauth_credential_expired(cred: OAuthCredentialPayload, buffer_seconds: int = 0) -> bool: """Return True if the OAuth2 credential's access_token has expired. Checks the ``expires_at`` ISO-format string stored in the credential payload. @@ -1204,12 +1301,10 @@ async def get_user_oauth_credential( prisma_client: PrismaClient, user_id: str, server_id: str, -) -> Optional[Dict[str, Any]]: +) -> OAuthCredentialPayload | None: """Return the decoded OAuth2 payload dict for a user+server pair, or None.""" - row = await MCPUserCredentialsRepository(prisma_client).table.find_unique( - where={"user_id_server_id": {"user_id": user_id, "server_id": server_id}} - ) + row = await _db_find_user_credential_row(prisma_client, user_id, server_id) if row is None: return None return _decode_oauth_payload(row.credential_b64) @@ -1218,11 +1313,11 @@ async def get_user_oauth_credential( async def list_user_oauth_credentials( prisma_client: PrismaClient, user_id: str, -) -> List[Dict[str, Any]]: +) -> list[OAuthCredentialPayload]: """Return all OAuth2 credential payloads for a user, tagged with server_id.""" - rows = await MCPUserCredentialsRepository(prisma_client).table.find_many(where={"user_id": user_id}) - results: List[Dict[str, Any]] = [] + rows = await _db_find_user_credential_rows(prisma_client, {"user_id": user_id}) + results: list[OAuthCredentialPayload] = [] for row in rows: payload = _decode_oauth_payload(row.credential_b64) if payload is None: @@ -1232,7 +1327,7 @@ async def list_user_oauth_credentials( return results -def _decrypted_credential_field(creds: Dict[str, object], field: str) -> object: +def _decrypted_credential_field(creds: dict[str, object], field: str) -> object: """Return one credential field decrypted with the global salt key; non-string and legacy plaintext values come back unchanged (decrypt_value_helper returns the original on failure).""" value = creds.get(field) @@ -1248,11 +1343,12 @@ def _decrypted_credential_field(creds: Dict[str, object], field: str) -> object: def mcp_oauth_token_identity(server: object) -> tuple[object, ...]: """The upstream-OAuth-token-determining fields of an MCP server: the resource/audience (url, or - spec_path for OpenAPI servers), the OAuth mode/grant (auth_type, oauth2_flow), the - authorization-server endpoints, and the OAuth client + scopes. Mirrors the dashboard's - getOAuthAuthorizationIdentity. When any of these change on a server update, previously stored - per-user tokens were minted for the old identity and are stale. Excludes transport and - delegate_auth_to_upstream, which do not affect what token is minted (RFC 8707/8693). + spec_path for OpenAPI servers, plus the RFC 8707 upstream_resource sent on the authorize and + token legs), the OAuth mode/grant (auth_type, oauth2_flow), the authorization-server endpoints, + and the OAuth client + scopes. Mirrors the dashboard's getOAuthAuthorizationIdentity. When any + of these change on a server update, previously stored per-user tokens were minted for the old + identity and are stale. Excludes transport and delegate_auth_to_upstream, which do not affect + what token is minted (RFC 8693). client_id/client_secret are compared decrypted: stored values are NaCl-encrypted with a fresh nonce on every write, so comparing ciphertext would flag every routine save as an identity @@ -1260,12 +1356,12 @@ def mcp_oauth_token_identity(server: object) -> tuple[object, ...]: creds = getattr(server, "credentials", None) if isinstance(creds, str): try: - parsed: object = json.loads(creds) + parsed: dict[str, object] | None = json.loads(creds) except ValueError: parsed = None else: parsed = creds - creds_dict: Dict[str, object] = parsed if isinstance(parsed, dict) else {} + creds_dict: dict[str, object] = parsed if isinstance(parsed, dict) else {} return ( getattr(server, "url", None), getattr(server, "spec_path", None), @@ -1278,13 +1374,14 @@ def mcp_oauth_token_identity(server: object) -> tuple[object, ...]: _decrypted_credential_field(creds_dict, "client_id"), _decrypted_credential_field(creds_dict, "client_secret"), creds_dict.get("scopes"), + creds_dict.get("upstream_resource"), ) async def purge_user_oauth_credentials_for_server( prisma_client: PrismaClient, server_id: str, - invalidate_token_cache: Optional[Callable[[str, str], Awaitable[None]]] = None, + invalidate_token_cache: Callable[[str, str], Awaitable[None]] | None = None, ) -> int: """Delete every stored per-user OAuth token for a server and invalidate each user's cached token everywhere it can be served from (the legacy per-user token cache and the v2 per-user OAuth @@ -1302,12 +1399,11 @@ async def purge_user_oauth_credentials_for_server( invalidate_token_cache is injectable for tests; it defaults to the manager's shared invalidate_user_oauth_token_cache, the single invalidation point for per-user tokens.""" - repo = MCPUserCredentialsRepository(prisma_client) - rows = await repo.table.find_many(where={"server_id": server_id}) + rows = await _db_find_user_credential_rows(prisma_client, {"server_id": server_id}) oauth_rows = [row for row in rows if _decode_oauth_payload(row.credential_b64) is not None] if not oauth_rows: return 0 - deleted_count = await repo.table.delete_many( + deleted_count = await _user_credential_actions(prisma_client).delete_many( where={"server_id": server_id, "user_id": {"in": [row.user_id for row in oauth_rows]}} ) if invalidate_token_cache is None: @@ -1333,9 +1429,9 @@ async def purge_user_oauth_credentials_for_server( async def refresh_user_oauth_token( prisma_client: PrismaClient, user_id: str, - server: Any, - cred: Dict[str, Any], -) -> Optional[Dict[str, Any]]: + server: "MCPServer", + cred: OAuthCredentialPayload, +) -> OAuthCredentialPayload | None: """Attempt to refresh a per-user OAuth2 token using its stored refresh_token. POSTs to ``server.token_url`` with ``grant_type=refresh_token``. @@ -1346,11 +1442,11 @@ async def refresh_user_oauth_token( warning and returns ``None`` — the caller is responsible for clearing the stale credential and triggering re-authentication. """ - refresh_token: Optional[str] = cred.get("refresh_token") - token_url: Optional[str] = getattr(server, "token_url", None) + refresh_token: str | None = cred.get("refresh_token") + token_url: str | None = getattr(server, "token_url", None) server_id: str = getattr(server, "server_id", "") - client_id: Optional[str] = getattr(server, "client_id", None) - client_secret: Optional[str] = getattr(server, "client_secret", None) + client_id: str | None = getattr(server, "client_id", None) + client_secret: str | None = getattr(server, "client_secret", None) if not refresh_token: verbose_proxy_logger.debug( @@ -1367,24 +1463,25 @@ async def refresh_user_oauth_token( return None try: - client_auth = build_token_endpoint_client_auth( - auth_method=normalize_token_endpoint_auth_method(getattr(server, "token_endpoint_auth_method", None)), + token_request = build_upstream_oauth2_token_request( + server, + auth_method=getattr(server, "token_endpoint_auth_method", None), client_id=client_id, client_secret=client_secret, ) - token_data: Dict[str, str] = { + token_data: dict[str, str] = { "grant_type": "refresh_token", "refresh_token": refresh_token, - **client_auth.body, + **token_request.body, } async_client = get_async_httpx_client(llm_provider=httpxSpecialProvider.Oauth2Check) response = await async_client.post( token_url, - headers={"Accept": "application/json", **client_auth.headers}, + headers={"Accept": "application/json", **token_request.headers}, data=token_data, ) response.raise_for_status() - body: Dict[str, Any] = response.json() + body: _OAuthTokenRefreshResponse = response.json() except Exception as exc: verbose_proxy_logger.warning( "refresh_user_oauth_token: refresh request failed for user=%s server=%s: %s", @@ -1394,7 +1491,7 @@ async def refresh_user_oauth_token( ) return None - access_token: Optional[str] = body.get("access_token") + access_token: str | None = body.get("access_token") if not access_token: verbose_proxy_logger.warning( "refresh_user_oauth_token: token response missing access_token for user=%s server=%s", @@ -1403,7 +1500,7 @@ async def refresh_user_oauth_token( ) return None - expires_in: Optional[int] = None + expires_in: int | None = None raw_expires = body.get("expires_in") try: expires_in = int(raw_expires) if raw_expires is not None else None @@ -1411,10 +1508,10 @@ async def refresh_user_oauth_token( pass # Rotate refresh token when the provider returns a new one - new_refresh_token: Optional[str] = body.get("refresh_token") or refresh_token + new_refresh_token: str | None = body.get("refresh_token") or refresh_token raw_scope = body.get("scope") - scopes: Optional[List[str]] = (raw_scope.split() if isinstance(raw_scope, str) and raw_scope else None) or cred.get( + scopes: list[str] | None = (raw_scope.split() if isinstance(raw_scope, str) and raw_scope else None) or cred.get( "scopes" ) @@ -1439,10 +1536,10 @@ async def refresh_user_oauth_token( async def resolve_valid_user_oauth_token( user_id: str, - server: Any, - cred: Optional[Dict[str, Any]], - prisma_client: Optional[PrismaClient] = None, -) -> Optional[Dict[str, Any]]: + server: "MCPServer", + cred: OAuthCredentialPayload | None, + prisma_client: PrismaClient | None = None, +) -> OAuthCredentialPayload | None: """Return an OAuth2 credential whose access_token is good for the next request. Returns the credential unchanged while its token is valid for at least @@ -1480,7 +1577,7 @@ async def resolve_valid_user_oauth_token( async def resolve_user_oauth_access_token( user_id: str | None, server: "MCPServer", - prefetched_creds: dict[str, dict[str, object]] | None = None, + prefetched_creds: Mapping[str, OAuthCredentialPayload] | None = None, ) -> str | None: """Resolve a user's valid OAuth2 access token for a server: Redis cache, else DB + refresh. @@ -1491,7 +1588,7 @@ async def resolve_user_oauth_access_token( usable token; any error is swallowed to ``None`` so a transient failure reads as "not authorized" rather than raising. """ - server_id = getattr(server, "server_id", None) + server_id: str | None = getattr(server, "server_id", None) if not user_id or not server_id: return None try: @@ -1568,8 +1665,9 @@ async def get_active_submitted_mcp_server_ids_for_user( if not user_id: return [] - rows = await MCPServerRepository(prisma_client).table.find_many( - where={ + rows = await _db_find_mcp_server_rows( + prisma_client, + { "submitted_by": user_id, "approval_status": MCPApprovalStatus.active, }, @@ -1584,15 +1682,16 @@ async def approve_mcp_server( ) -> LiteLLM_MCPServerTable: """Set approval_status=active and record reviewed_at.""" now = datetime.now(timezone.utc) - updated = await MCPServerRepository(prisma_client).table.update( - where={"server_id": server_id}, - data={ + updated = await _db_update_mcp_server_row( + prisma_client, + server_id, + { "approval_status": MCPApprovalStatus.active, "reviewed_at": now, "updated_by": touched_by, }, ) - table = LiteLLM_MCPServerTable(**updated.model_dump()) + table = LiteLLM_MCPServerTable.model_validate(updated.model_dump()) decrypt_global_env_var_values(table.env_vars) return table @@ -1601,22 +1700,19 @@ async def reject_mcp_server( prisma_client: PrismaClient, server_id: str, touched_by: str, - review_notes: Optional[str] = None, + review_notes: str | None = None, ) -> LiteLLM_MCPServerTable: """Set approval_status=rejected, record reviewed_at and review_notes.""" now = datetime.now(timezone.utc) - data: Dict[str, Any] = { + data: prisma_db_types.LiteLLM_MCPServerTableUpdateInput = { "approval_status": MCPApprovalStatus.rejected, "reviewed_at": now, "updated_by": touched_by, } if review_notes is not None: data["review_notes"] = review_notes - updated = await MCPServerRepository(prisma_client).table.update( - where={"server_id": server_id}, - data=data, - ) - table = LiteLLM_MCPServerTable(**updated.model_dump()) + updated = await _db_update_mcp_server_row(prisma_client, server_id, data) + table = LiteLLM_MCPServerTable.model_validate(updated.model_dump()) decrypt_global_env_var_values(table.env_vars) return table @@ -1629,12 +1725,12 @@ async def get_mcp_submissions( along with a summary count breakdown by approval_status. Mirrors get_guardrail_submissions() from guardrail_endpoints.py. """ - rows = await MCPServerRepository(prisma_client).table.find_many( + rows: list[prisma_db_models.LiteLLM_MCPServerTable] = await MCPServerRepository(prisma_client).table.find_many( where={"submitted_at": {"not": None}}, order={"submitted_at": "desc"}, take=500, # safety cap; paginate if needed in a future iteration ) - items = [LiteLLM_MCPServerTable(**r.model_dump()) for r in rows] + items = [LiteLLM_MCPServerTable.model_validate(r.model_dump()) for r in rows] for item in items: decrypt_global_env_var_values(item.env_vars) @@ -1654,7 +1750,7 @@ async def get_mcp_submissions( # ── Per-user MCP environment variables ──────────────────────────────────── -def _decode_user_env_vars(stored: str) -> Dict[str, str]: +def _decode_user_env_vars(stored: str) -> dict[str, str]: """Decrypt a ``values_b64`` blob and parse it as a flat ``{name: value}`` dict.""" decrypted = decrypt_value_helper( value=stored, @@ -1670,6 +1766,7 @@ def _decode_user_env_vars(stored: str) -> Dict[str, str]: "re-enter them rather than silently forwarding ciphertext" ) return {} + parsed: dict[str, object] | None try: parsed = json.loads(decrypted) except (ValueError, TypeError): @@ -1683,9 +1780,9 @@ async def get_user_env_vars( prisma_client: PrismaClient, user_id: str, server_id: str, -) -> Dict[str, str]: +) -> dict[str, str]: """Return the calling user's env var dict for ``server_id`` (empty if none).""" - row = await prisma_client.db.litellm_mcpuserenvvars.find_unique( + row = await _user_env_var_actions(prisma_client).find_unique( where={"user_id_server_id": {"user_id": user_id, "server_id": server_id}} ) if row is None: @@ -1697,7 +1794,7 @@ async def get_user_env_vars_bulk( prisma_client: PrismaClient, user_id: str, server_ids: Iterable[str], -) -> Dict[str, Dict[str, str]]: +) -> dict[str, dict[str, str]]: """Return ``{server_id: {var_name: value}}`` for one user across many servers. Servers with no stored row are simply absent from the result. @@ -1705,7 +1802,7 @@ async def get_user_env_vars_bulk( ids = list(server_ids) if not ids: return {} - rows = await prisma_client.db.litellm_mcpuserenvvars.find_many(where={"user_id": user_id, "server_id": {"in": ids}}) + rows = await _db_find_user_env_var_rows(prisma_client, {"user_id": user_id, "server_id": {"in": ids}}) return {row.server_id: _decode_user_env_vars(row.values_b64) for row in rows} @@ -1713,9 +1810,9 @@ async def merge_user_env_vars( prisma_client: PrismaClient, user_id: str, server_id: str, - updates: Dict[str, str], + updates: dict[str, str], allowed_names: Iterable[str], -) -> Dict[str, str]: +) -> dict[str, str]: """Merge ``updates`` into the user's stored env vars for ``server_id`` and return the resulting set. @@ -1732,7 +1829,7 @@ async def merge_user_env_vars( ) async with prisma_client.db.tx() as tx: await tx.execute_raw("SELECT pg_advisory_xact_lock($1::bigint)", lock_key) - row = await tx.litellm_mcpuserenvvars.find_unique( + row: prisma_db_models.LiteLLM_MCPUserEnvVars | None = await tx.litellm_mcpuserenvvars.find_unique( where={"user_id_server_id": {"user_id": user_id, "server_id": server_id}} ) existing = _decode_user_env_vars(row.values_b64) if row is not None else {} @@ -1762,4 +1859,4 @@ async def delete_user_env_vars( Uses ``delete_many`` so a missing row is a no-op; real DB errors still propagate to the caller instead of being silently swallowed. """ - await prisma_client.db.litellm_mcpuserenvvars.delete_many(where={"user_id": user_id, "server_id": server_id}) + await _user_env_var_actions(prisma_client).delete_many(where={"user_id": user_id, "server_id": server_id}) diff --git a/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py b/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py index 26241119dd8..865787d5a07 100644 --- a/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py +++ b/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py @@ -21,7 +21,6 @@ from litellm.llms.custom_httpx.http_handler import ( ) from litellm.proxy._experimental.mcp_server.auth.token_endpoint_auth import ( TokenEndpointAuthConfigError, - build_token_endpoint_client_auth, normalize_token_endpoint_auth_method, ) from litellm.types.mcp_server.mcp_server_manager import MCPTokenEndpointAuthMethod @@ -54,7 +53,9 @@ from litellm.proxy._experimental.mcp_server.gateway_dcr_flow import ( ) from litellm.proxy._experimental.mcp_server.oauth_utils import ( TOKEN_NO_CACHE_HEADERS, + build_upstream_oauth2_token_request, get_request_base_url, + resolve_upstream_resource, validate_trusted_redirect_uri, well_known_root_suffix, ) @@ -726,6 +727,7 @@ def _redirect_to_upstream_authorize( to the upstream authorize endpoint verbatim, no relay state cookie is set, and the upstream enforces its own registered redirect binding for the client.""" scope_value = scope or (" ".join(mcp_server.scopes) if mcp_server.scopes else None) + upstream_resource = resolve_upstream_resource(mcp_server) passthrough_params = { "client_id": client_id, "redirect_uri": redirect_uri, @@ -734,6 +736,7 @@ def _redirect_to_upstream_authorize( "code_challenge": code_challenge, "code_challenge_method": code_challenge_method, **({"scope": scope_value} if scope_value else {}), + **({"resource": upstream_resource} if upstream_resource else {}), } parsed_auth_url = urlparse(mcp_server.authorization_url or "") merged_params = {**dict(parse_qsl(parsed_auth_url.query)), **passthrough_params} @@ -842,6 +845,10 @@ async def authorize_with_server( if code_challenge_method: params["code_challenge_method"] = code_challenge_method + upstream_resource = resolve_upstream_resource(mcp_server) + if upstream_resource: + params["resource"] = upstream_resource + parsed_auth_url = urlparse(mcp_server.authorization_url) existing_params = dict(parse_qsl(parsed_auth_url.query)) existing_params.update(params) @@ -902,7 +909,8 @@ async def exchange_token_with_server( else (client_token_endpoint_auth_method or mcp_server.token_endpoint_auth_method) ) try: - client_auth = build_token_endpoint_client_auth( + token_request = build_upstream_oauth2_token_request( + mcp_server, auth_method=resolved_auth_method, client_id=resolved_client_id, client_secret=resolved_client_secret, @@ -941,7 +949,7 @@ async def exchange_token_with_server( token_data: dict = { "grant_type": "refresh_token", "refresh_token": upstream_refresh_token, - **client_auth.body, + **token_request.body, } refresh_request_scope = scope or bridge_upstream_scope if refresh_request_scope: @@ -980,7 +988,7 @@ async def exchange_token_with_server( "grant_type": "authorization_code", "code": code, "redirect_uri": resolved_redirect_uri, - **client_auth.body, + **token_request.body, } if code_verifier: token_data["code_verifier"] = code_verifier @@ -991,11 +999,12 @@ async def exchange_token_with_server( if not isinstance(prepared, _BridgeMintReady): return _bridge_mint_error_response(prepared) bridge_mint_ready = prepared + async_client = get_async_httpx_client(llm_provider=httpxSpecialProvider.Oauth2Check) try: response = await async_client.post( mcp_server.token_url, - headers={"Accept": "application/json", **client_auth.headers}, + headers={"Accept": "application/json", **token_request.headers}, data=token_data, ) if response is not None: @@ -1769,10 +1778,12 @@ async def token_endpoint( @router.post("/authorize/complete") -async def authorize_complete(request: Request, flow: str = Form(...)): +async def authorize_complete(request: Request, flow: str = Form(...), delivery: str | None = Form(None)): """Finish an aggregate connect flow: mint the gateway authorization code for the - signed-in user and redirect back to the DCR client. POST plus the per-flow HttpOnly - cookie set at /authorize; an anonymous or bad-flow request just 400s.""" + signed-in user and hand it back to the DCR client, by 303 redirect (default) or, for + a loopback client on a different machine, as a copyable callback URL + (``delivery=manual``). POST plus the per-flow HttpOnly cookie set at /authorize; an + anonymous or bad-flow request just 400s.""" from litellm.proxy.proxy_server import user_api_key_cache # noqa: PLC0415 # circular import at module load return await complete_connect_flow( @@ -1780,6 +1791,7 @@ async def authorize_complete(request: Request, flow: str = Form(...)): flow_handle=flow, session_user_id=_session_cookie_user_id(request), cache=user_api_key_cache, + delivery=delivery, ) @@ -2085,6 +2097,15 @@ async def _build_oauth_protected_resource_response( it. Only the legacy ``is_oauth_passthrough`` opt-in rewrites ``resource`` to the gateway's own URL so clients present the bearer token back to the gateway. + An explicitly named gateway-managed oauth2 server (interactive with + gateway-vaulted per-user tokens, or M2M) advertises the gateway's own + authorization server (``{base}/mcp``): a keyless DCR client that configured the + per-server URL completes the same sign-in flow the aggregate ``/mcp`` endpoint + supports and is admitted with a gateway session bearer. The per-server relay + authorize/token endpoints stay registered for the keyed interactive flow (which + is challenged with an explicit ``authorization_uri``), and the root-resolved + (unnamed) legacy shape keeps the relay authorization server. + Args: request: FastAPI Request object mcp_server_name: Name of the MCP server @@ -2100,6 +2121,7 @@ async def _build_oauth_protected_resource_response( request_base_url = get_request_base_url(request) client_ip = IPAddressUtils.get_mcp_client_ip(request) + explicitly_named = mcp_server_name is not None # When no server name provided, try to resolve the single OAuth2 server if mcp_server_name is None: @@ -2174,6 +2196,13 @@ async def _build_oauth_protected_resource_response( if mcp_server is None or mcp_server.auth_type != MCPAuth.oauth2_token_exchange: _raise_unless_oauth2_discovery_server(mcp_server, mcp_server_name, "not an OAuth-protected resource") + if explicitly_named and mcp_server is not None and mcp_server.is_gateway_managed_oauth2: + return { + "authorization_servers": [f"{request_base_url}/mcp"], + "resource": resource_url, + "scopes_supported": (mcp_server.scopes if mcp_server.scopes else []), + } + return { "authorization_servers": [ (f"{request_base_url}/{mcp_server_name}" if mcp_server_name else f"{request_base_url}") diff --git a/litellm/proxy/_experimental/mcp_server/exceptions.py b/litellm/proxy/_experimental/mcp_server/exceptions.py index 74752809e86..ca2261139c9 100644 --- a/litellm/proxy/_experimental/mcp_server/exceptions.py +++ b/litellm/proxy/_experimental/mcp_server/exceptions.py @@ -57,7 +57,7 @@ class MCPUpstreamAuthError(Exception): ``/.well-known/oauth-protected-resource/mcp/{server_name}``. This keeps the ``resource_metadata`` URI aligned with the resource pattern the client originally targeted, matching the path-aware behaviour of - ``_get_passthrough_resource_metadata_url`` in ``server.py``. + ``get_passthrough_resource_metadata_url`` in ``oauth_utils.py``. """ challenge: Optional[str] = self.www_authenticate if challenge is None and self.status_code == 401 and base_url: diff --git a/litellm/proxy/_experimental/mcp_server/faults/classify.py b/litellm/proxy/_experimental/mcp_server/faults/classify.py index 8b3a09f8d8d..d585df90caa 100644 --- a/litellm/proxy/_experimental/mcp_server/faults/classify.py +++ b/litellm/proxy/_experimental/mcp_server/faults/classify.py @@ -63,18 +63,21 @@ def _classify_oauth_error_code( ) -> UpstreamOAuthFault: """Blame assignment for a contract-conformant OAuth error code, shared by the token and DCR classifiers. Codes by which the upstream blames itself keep that blame; ``invalid_target`` is a - gateway capability gap (RFC 8707 resource indicators, LIT-4339) no matter whose credentials were - presented; credential-indicting codes follow the credential source; everything else, including - codes we do not recognize, is the caller's to act on. The upstream's HTTP status is deliberately - never consulted: status derives from this classification at render time, which is what keeps - status and code from contradicting each other.""" + gateway configuration gap (the RFC 8707 resource indicator this server sends, or fails to send) + no matter whose credentials were presented; credential-indicting codes follow the credential + source; everything else, including codes we do not recognize, is the caller's to act on. The + upstream's HTTP status is deliberately never consulted: status derives from this classification + at render time, which is what keeps status and code from contradicting each other.""" if code == "server_error" or code == "temporarily_unavailable": return UpstreamReportedFault(code=code) if code in GATEWAY_CAPABILITY_CODES: verbose_logger.warning( "MCP server %s: the upstream authorization server rejected the request with " - "invalid_target; it may require RFC 8707 resource indicators, which the gateway " - "does not send yet (tracked as LIT-4339)", + "invalid_target, meaning it did not accept the RFC 8707 resource indicator for this " + "request. Set upstream_resource on this server to the exact resource identifier the " + "authorization server expects (or to 'auto' to send the server's own canonical url); " + "if it is already set and the authorization server does not support resource " + "indicators, unset it and express the target audience through scopes instead", log_context, ) return GatewayRejected(code=code) diff --git a/litellm/proxy/_experimental/mcp_server/faults/render_oauth.py b/litellm/proxy/_experimental/mcp_server/faults/render_oauth.py index 89ce5011830..d7806bc8917 100644 --- a/litellm/proxy/_experimental/mcp_server/faults/render_oauth.py +++ b/litellm/proxy/_experimental/mcp_server/faults/render_oauth.py @@ -16,8 +16,10 @@ from litellm.proxy._experimental.mcp_server.oauth_utils import TOKEN_NO_CACHE_HE def _gateway_rejected_description(code: str) -> str: if code == "invalid_target": return ( - "the upstream authorization server rejected the request (invalid_target); " - "it may require RFC 8707 resource indicators, which the gateway does not send yet" + "the upstream authorization server rejected the request (invalid_target); it did not " + "accept this server's RFC 8707 resource indicator. Set upstream_resource on the MCP " + "server to the resource identifier the authorization server expects, or unset it if " + "that authorization server does not support resource indicators" ) return ( f"the upstream authorization server rejected the gateway's configured client credentials " diff --git a/litellm/proxy/_experimental/mcp_server/faults/types.py b/litellm/proxy/_experimental/mcp_server/faults/types.py index 128b5e3e6cf..635a66dcf68 100644 --- a/litellm/proxy/_experimental/mcp_server/faults/types.py +++ b/litellm/proxy/_experimental/mcp_server/faults/types.py @@ -25,9 +25,10 @@ gateway presented its own stored credentials, these are gateway-side faults the when the caller supplied the credentials, they are the caller's to fix.""" GATEWAY_CAPABILITY_CODES: frozenset[str] = frozenset({"invalid_target"}) -"""Codes that indict a gateway capability regardless of whose credentials were presented: -``invalid_target`` means the upstream wants RFC 8707 resource indicators, which the gateway does not -send yet (LIT-4339). Never the caller's fault.""" +"""Codes that indict gateway configuration regardless of whose credentials were presented: +``invalid_target`` means the upstream did not accept the RFC 8707 resource indicator the server +sent, or requires one it was not configured to send (``upstream_resource``). Never the caller's +fault.""" UPSTREAM_FAULT_CODES: frozenset[str] = frozenset({"server_error", "temporarily_unavailable"}) """Codes by which the upstream blames itself. Relaying them as caller faults would invert blame, so diff --git a/litellm/proxy/_experimental/mcp_server/gateway_dcr_flow.py b/litellm/proxy/_experimental/mcp_server/gateway_dcr_flow.py index 58233c4c9e5..7177b798c5f 100644 --- a/litellm/proxy/_experimental/mcp_server/gateway_dcr_flow.py +++ b/litellm/proxy/_experimental/mcp_server/gateway_dcr_flow.py @@ -39,6 +39,7 @@ from __future__ import annotations import hashlib import hmac +import html import secrets from base64 import urlsafe_b64encode from collections.abc import Mapping @@ -47,7 +48,7 @@ from typing import Awaitable, Callable, Literal, TypeVar from urllib.parse import parse_qsl, urlencode, urlparse, urlunparse from fastapi import HTTPException, Request -from fastapi.responses import JSONResponse, RedirectResponse, Response +from fastapi.responses import HTMLResponse, JSONResponse, RedirectResponse, Response from pydantic import BaseModel, ConfigDict, Field, ValidationError from typing_extensions import assert_never @@ -94,6 +95,13 @@ server-side session store, and the sealed value never appears in a URL).""" CONNECT_FLOW_TTL_SECONDS = 600 GATEWAY_AUTH_CODE_TTL_SECONDS = 120 +MANUAL_DELIVERY_AUTH_CODE_TTL_SECONDS = 300 +"""Lifetime of a code the user delivers by hand (headless/remote client, LIT-4863 class): +copy-pasting a callback URL from a laptop browser to an SSH session is slower than a +browser redirect, so manual-delivery codes get 5 minutes instead of 2, still well under +the 10-minute ceiling RFC 6749 section 4.1.2 recommends. Single-use and PKCE binding are +unchanged, so the longer window only extends how long the legitimate holder has to paste +it, not what an observer could do with it.""" _CLAIM_TTL_BUFFER_SECONDS = 60 _USED_CODE_CACHE_PREFIX = "mcp_gateway_dcr_code_used:" _USED_FLOW_CACHE_PREFIX = "mcp_gateway_dcr_flow_used:" @@ -390,6 +398,7 @@ async def complete_connect_flow( flow_handle: str, session_user_id: str | None, cache: DualCache, + delivery: str | None = None, ) -> Response: """The deliberate finish step of the connect flow: mint the gateway authorization code and send the browser back to the client. @@ -399,7 +408,24 @@ async def complete_connect_flow( into the flow: a link crafted by another party dies here with ``access_denied`` instead of minting a code for the victim's identity. The flow is single-use (an atomic claim on its ``jti``), so a double-submit cannot mint two codes from one sign-in. + + ``delivery`` chooses how the code reaches the client. Default (absent or + ``"redirect"``) is the 303 to the client's registered redirect URI. ``"manual"`` + renders the callback URL on a page instead, for a client whose redirect URI is a + loopback host but which runs on a DIFFERENT machine than the browser (EC2/SSH box, + container): the 303 would dereference the browser machine's loopback and the code + would never arrive, so the user carries it over by pasting the URL into the client or + fetching it from the client machine's terminal. Manual delivery is honored only for + loopback redirect URIs; a routable redirect URI works from any browser by + construction, so those flows always redirect. The user who sees the page is exactly + the user the 303 would have carried the code to, and the same user already sees the + code today in the dead redirect's address bar, so the page exposes the code to no new + party. Unknown ``delivery`` values are rejected rather than defaulted: a client that + asked for manual delivery and got a dead redirect instead would silently lose its + code. """ + if delivery not in (None, "redirect", "manual"): + return _oauth_error(400, "invalid_request", "delivery must be 'redirect' or 'manual'") sealed_flow = request.cookies.get(_flow_cookie_name(flow_handle)) if sealed_flow is None: return _oauth_error(400, "invalid_request", "unknown or expired connect flow") @@ -417,6 +443,8 @@ async def complete_connect_flow( f"{_USED_FLOW_CACHE_PREFIX}{flow.jti}", CONNECT_FLOW_TTL_SECONDS + _CLAIM_TTL_BUFFER_SECONDS ): return _oauth_error(400, "invalid_request", "this connect flow was already completed; restart the connection") + manual_delivery = delivery == "manual" and is_loopback_redirect_host(urlparse(flow.redirect_uri)) + code_ttl = MANUAL_DELIVERY_AUTH_CODE_TTL_SECONDS if manual_delivery else GATEWAY_AUTH_CODE_TTL_SECONDS code = _seal( GATEWAY_AUTH_CODE_PREFIX, _GatewayAuthCode( @@ -426,16 +454,46 @@ async def complete_connect_flow( code_challenge=flow.code_challenge, jti=secrets.token_urlsafe(24), iat=int(now.timestamp()), - exp=int(now.timestamp()) + GATEWAY_AUTH_CODE_TTL_SECONDS, + exp=int(now.timestamp()) + code_ttl, ), ) params = {"code": code, **({"state": flow.state} if flow.state else {})} - response = RedirectResponse(_append_query_params(flow.redirect_uri, params), status_code=303) + callback_url = _append_query_params(flow.redirect_uri, params) + response: Response = ( + _manual_delivery_response(callback_url) if manual_delivery else RedirectResponse(callback_url, status_code=303) + ) path, secure = _cookie_path_and_secure(request) response.delete_cookie(key=_flow_cookie_name(flow_handle), path=path, secure=secure, httponly=True, samesite="lax") return response +def _manual_delivery_response(callback_url: str) -> Response: + """The manual code-delivery page: the callback URL the 303 would have followed, + rendered for the user to carry to the machine the client actually runs on (paste into + the client's prompt, or fetch with curl from that machine's terminal). Served + no-store because the body holds a live single-use code, and the URL is HTML-escaped + because it is client-influenced. The page renders the URL as data only, never as a + ready-to-paste shell command: no single quoting of an attacker-influenced string is + correct across POSIX shells, cmd.exe, and PowerShell (cmd.exe ignores single quotes + and percent-expands inside double quotes), so any command string this page suggested + would be wrong for some shell the user might paste it into.""" + safe_url = html.escape(callback_url, quote=True) + minutes = MANUAL_DELIVERY_AUTH_CODE_TTL_SECONDS // 60 + body = ( + "Finish connecting" + "

Almost done

" + "

Your MCP client runs on a different machine, so this browser cannot deliver the" + " authorization code to it. On the machine where the client runs, paste this URL into" + " the client's prompt (Claude Code accepts the pasted callback URL), or pass it as the" + " quoted argument of a curl command from that machine's terminal:

" + f'

' + f"

The code is single-use and expires in {minutes} minutes. You can close this window" + " once the client confirms it is connected.

" + "" + ) + return HTMLResponse(body, headers=TOKEN_NO_CACHE_HEADERS) + + def _pkce_verifier_matches(code_verifier: str, code_challenge: str) -> bool: """RFC 7636 S256 verification, total over hostile input. The comparison is over bytes so a non-ASCII ``code_challenge`` (which reaches here unvalidated from the client's @@ -601,9 +659,11 @@ async def _authorization_code_grant( if failure is not None: return _reload_failure_response(failure) # Atomic single-use claim is the gate: on a concurrent double-redeem exactly one caller - # wins, and a claim that cannot be recorded fails closed. + # wins, and a claim that cannot be recorded fails closed. The marker's TTL derives from + # the code's own remaining lifetime so it outlives whichever lifetime the code was minted with. if not await guard.claim( - f"{_USED_CODE_CACHE_PREFIX}{parsed.jti}", GATEWAY_AUTH_CODE_TTL_SECONDS + _CLAIM_TTL_BUFFER_SECONDS + f"{_USED_CODE_CACHE_PREFIX}{parsed.jti}", + parsed.exp - int(now.timestamp()) + _CLAIM_TTL_BUFFER_SECONDS, ): return _oauth_error(400, "invalid_grant", "the authorization code was already used") return _session_token_pair(SessionPrincipal(user_id=parsed.user_id, client_id=client_id), keys, now) diff --git a/litellm/proxy/_experimental/mcp_server/guardrail_translation/handler.py b/litellm/proxy/_experimental/mcp_server/guardrail_translation/handler.py index b668833e638..909925da00a 100644 --- a/litellm/proxy/_experimental/mcp_server/guardrail_translation/handler.py +++ b/litellm/proxy/_experimental/mcp_server/guardrail_translation/handler.py @@ -13,11 +13,22 @@ payload (name + arguments) so we just build the tool_call. from typing import TYPE_CHECKING, Any, Dict, Optional +from fastapi import HTTPException from mcp.types import Tool as MCPTool from litellm._logging import verbose_proxy_logger from litellm.experimental_mcp_client.tools import transform_mcp_tool_to_openai_tool from litellm.llms.base_llm.guardrail_translation.base_translation import BaseTranslation +from litellm.proxy._experimental.mcp_server.utils import ( + json_string_leaves, + json_unrewritable_labels, + mcp_content_item_text, + mcp_tool_result_content_list, + mcp_tool_result_structured_content, + set_mcp_tool_result_structured_content, + with_json_string_leaves, + with_mcp_content_item_text, +) from litellm.types.llms.openai import ( ChatCompletionToolParam, ChatCompletionToolParamFunctionChunk, @@ -92,7 +103,93 @@ class MCPGuardrailTranslationHandler(BaseTranslation): user_api_key_dict: Optional[Any] = None, request_data: Optional[dict] = None, ) -> Any: - verbose_proxy_logger.debug( - "MCP Guardrail: Output processing not implemented for MCP tools", + """Scan the text content of an MCP tool result and write masked text back. + + The content list is rewritten in place (only the entries the guardrail + actually changed) rather than returned as a new result: the same object is + already referenced by the logging payload captured before this hook runs, + so a copy would leave the unmasked text in the spend log / span. A + guardrail that rejects the result raises, and the exception propagates to + the caller. + + ``structuredContent`` is scanned and masked too, in the same + ``apply_guardrail`` call: it is serialized to the client alongside + ``content``, so a value living only there would otherwise reach the + client unscanned. + """ + content = mcp_tool_result_content_list(response) + text_blocks = ( + tuple( + (index, text) for index, item in enumerate(content) if (text := mcp_content_item_text(item)) is not None + ) + if content is not None + else () ) + + structured = mcp_tool_result_structured_content(response) + structured_leaves = json_string_leaves(structured) if structured is not None else () + structured_labels = json_unrewritable_labels(structured) if structured is not None else () + if structured_leaves is None or structured_labels is None: + raise HTTPException( + status_code=400, + detail={ + "error": ( + "Content blocked: MCP tool result structuredContent is nested too deeply to be scanned " + "by the configured guardrail" + ) + }, + ) + + if not text_blocks and not structured_leaves and not structured_labels: + verbose_proxy_logger.debug("MCP Guardrail: tool result has no scannable text, nothing to do") + return response + + originals = ( + tuple(text for _, text in text_blocks) + tuple(text for _, text in structured_leaves) + structured_labels + ) + guardrailed_inputs = await guardrail_to_apply.apply_guardrail( + inputs=GenericGuardrailAPIInputs(texts=list(originals)), + request_data=request_data if request_data is not None else {}, + input_type="response", + logging_obj=litellm_logging_obj, + ) + masked_texts = guardrailed_inputs.get("texts") if guardrailed_inputs else None + if masked_texts is None: + return response + if len(masked_texts) != len(originals): + verbose_proxy_logger.warning( + "MCP Guardrail: guardrail returned %d texts for %d tool result texts; leaving the result unmasked", + len(masked_texts), + len(originals), + ) + return response + + split = len(text_blocks) + if content is not None: + for (index, original), masked in zip(text_blocks, masked_texts[:split]): + if masked != original: + content[index] = with_mcp_content_item_text(content[index], masked) + + label_start = split + len(structured_leaves) + if any(masked != original for original, masked in zip(structured_labels, masked_texts[label_start:])): + raise HTTPException( + status_code=400, + detail={ + "error": ( + "Content blocked: MCP tool result matched a masking rule on a non-rewritable field " + "(a structuredContent key or numeric value), which cannot be redacted without changing " + "the payload contract" + ) + }, + ) + + structured_replacements = { + path: masked + for (path, original), masked in zip(structured_leaves, masked_texts[split:label_start]) + if masked != original + } + if structured_replacements: + set_mcp_tool_result_structured_content( + response, with_json_string_leaves(structured, structured_replacements) + ) return response diff --git a/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py b/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py index 0ee74960293..e3f7352e8ca 100644 --- a/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py +++ b/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py @@ -71,6 +71,7 @@ from litellm.proxy._experimental.mcp_server.oauth2_token_cache import ( ) from litellm.proxy._experimental.mcp_server.oauth_utils import ( _redact_mcp_resource_url, + canonicalize_url_identity, ) from litellm.proxy._experimental.mcp_server.outbound_credentials import ( Error, @@ -115,12 +116,14 @@ from litellm.proxy._experimental.mcp_server.utils import ( get_server_prefix, interpolate_headers, is_short_mcp_tool_prefix_enabled, - is_tool_name_prefixed, iter_known_server_prefixes, + iter_known_tool_name_spellings, + match_known_server_prefix, + match_known_tool_name, merge_mcp_headers, normalize_server_name, + openapi_tool_name, parse_admin_env_vars, - split_server_prefix_from_name, strip_known_server_prefix, validate_mcp_server_name, ) @@ -200,6 +203,13 @@ _UPSTREAM_OAUTH_DISCOVERY_AUTH_TYPES: tuple[MCPAuth, ...] = ( ) +# OAuth discovery retry cooldown for servers whose endpoints stay unresolved. The base is one +# reload cadence so a transient upstream failure recovers immediately; the cap bounds the request +# amplification and log volume of a permanently broken configuration. +_OAUTH_DISCOVERY_RETRY_BASE_SECONDS = 30.0 +_OAUTH_DISCOVERY_RETRY_MAX_SECONDS = 900.0 + + def _blank_to_none(value: str | None) -> str | None: """Collapse an absent, empty, or whitespace-only string to ``None``. @@ -247,6 +257,7 @@ def _endpoints_yield_to_issuer( authorization_url: str | None, token_url: str | None, registration_url: str | None, + server_ref: str, ) -> tuple[str | None, str | None, str | None]: """The single rule that makes an admin-configured ``issuer`` the sole authoritative endpoint source (RFC 8414 §3.3): when it is set for a discovery auth type, the stored/manual @@ -256,25 +267,37 @@ def _endpoints_yield_to_issuer( i.e. all ``None`` when issuer-anchored, else the inputs unchanged. Called at every resolution site so the invariant holds in one place instead of being re-derived per merge. """ - if issuer is not None and is_discovery_auth_type: - return None, None, None - return authorization_url, token_url, registration_url + if issuer is None or not is_discovery_auth_type: + return authorization_url, token_url, registration_url + discarded = sorted( + label + for label, value in ( + ("authorization_url", authorization_url), + ("token_url", token_url), + ("registration_url", registration_url), + ) + if value + ) + if discarded: + verbose_logger.warning( + "MCP server %s has a pinned Issuer, so its stored %s %s not used: an anchored issuer is the " + "sole endpoint source (RFC 8414 section 3.3) and a failed issuer fetch fails closed rather " + "than falling back to them. To use manually configured endpoints instead, clear the Issuer " + "field and re-enter the endpoint urls (clearing the Issuer also clears endpoints that may " + "have been resolved under it), or clear the Issuer alone to re-discover from the server url.", + server_ref, + ", ".join(discarded), + "is" if len(discarded) == 1 else "are", + ) + return None, None, None def _normalized_authorize_endpoint(url: str) -> str: - """Compare authorize endpoints on scheme, host, and path only. The default port is elided and - the host is lowercased so ``https://IDP.example.com:443/authorize/`` and - ``https://idp.example.com/authorize`` are the same identity; query and trailing slash are not.""" - parsed = urlparse(url) - scheme = parsed.scheme.lower() - host = (parsed.hostname or "").lower() - default_port = {"https": 443, "http": 80}.get(scheme) - try: - port = parsed.port - except ValueError: - port = None - authority = host if port is None or port == default_port else f"{host}:{port}" - return f"{scheme}://{authority}{parsed.path.rstrip('/')}" + """Compare authorize endpoints / issuers on scheme, host, and path only, through the shared URL + canonicalizer: the default port is elided and the host is lowercased so + ``https://IDP.example.com:443/authorize/`` and ``https://idp.example.com/authorize`` are the same + identity, while query, fragment and a trailing slash are dropped.""" + return canonicalize_url_identity(url) def _issuer_matches(claimed_issuer: object, configured_issuer: str) -> bool: @@ -288,6 +311,68 @@ def _issuer_matches(claimed_issuer: object, configured_issuer: str) -> bool: return _normalized_authorize_endpoint(claimed_issuer) == _normalized_authorize_endpoint(configured_issuer) +def _flow_endpoints_missing( + auth_type: MCPAuthType | None, + oauth2_flow: str | None, + authorization_url: str | None, + token_url: str | None, + token_exchange_endpoint: str | None = None, +) -> bool: + """Whether a built server is missing an endpoint its flow needs to run at all. + + Used by the reload fast-path exemption: discovery runs at build time only, and the fast path + reuses an unchanged row's registry entry verbatim, so a server whose discovery came back empty + (transient upstream failure, rate limiting) would stay broken until some unrelated config write + bumps ``updated_at``, serving its 400 the whole time. Rebuilding just these entries retries + discovery on the normal reload cadence. It costs no extra fetch for servers that resolved, and + none for those with no discovery source, since the build skips discovery for both. + """ + if auth_type == MCPAuth.oauth2_token_exchange: + # A configured exchange endpoint replaces discovery entirely; only a server that must + # discover its token endpoint and still has none is unresolved. + return token_exchange_endpoint is None and token_url is None + if auth_type not in _UPSTREAM_OAUTH_DISCOVERY_AUTH_TYPES: + return False + if oauth2_flow == "client_credentials": + return token_url is None + return authorization_url is None or token_url is None + + +def _oauth_endpoints_unresolved(server: MCPServer) -> bool: + """``_flow_endpoints_missing`` over a built registry entry, for the reload fast-path check. + + The flow comes from ``effective_oauth2_flow``, the one column-first, shape-fallback judge every + flow decision uses, not from the raw column: a legacy row the startup backfill deliberately left + unstamped (the ambiguous M2M shape) serves M2M at request time, and reading the bare column here + would classify it as interactive-missing-endpoints and re-run discovery on every reload. + """ + if ( + server.auth_type == MCPAuth.oauth2_token_exchange + and server.token_exchange_profile == "entra_obo" + and not server.scopes + ): + # entra_obo fails closed at exchange time without a scope (token_exchanger.py), and scopes + # can come from resource discovery, so a server that resolved its endpoints but no scopes is + # still unresolved for its flow. + return True + if server.is_dcr_bridge and not server.client_id and server.registration_url is None: + # A DCR bridge with no admin-configured client can only register callers through the + # upstream's registration endpoint, so a build that resolved the authorize and token + # endpoints but not registration_endpoint (partial metadata) is still unresolved for its + # flow and must keep retrying; without this it silently degrades to the short-circuit arm + # until an unrelated config write. Scopes are deliberately NOT part of completeness: they + # are a request hint the authorization server bounds at consent (RFC 6749 section 3.3), + # and a server without them is fully functional. + return True + return _flow_endpoints_missing( + server.auth_type, + MCPServerManager.effective_oauth2_flow(server), + server.authorization_url, + server.token_url, + server.token_exchange_endpoint, + ) + + def _endpoints_corroborate_authorization_url( source_authorization_url: str | None, trusted_authorization_url: str | None, @@ -319,11 +404,10 @@ def _carry_forward_resolved_oauth_endpoints(new_server: MCPServer, previous_serv during re-discovery downgrades a working server (``authorization_url`` set) to a broken one (``None``, /authorize 400s) with no configuration change. Mirrors the ``short_prefix`` carry-forward. Skipped when the server's ``url`` or ``auth_type`` changed, since the previous - endpoints may then belong to a different upstream. ``registration_url`` IS carried even though - ``_persist_discovered_oauth_endpoints`` refuses to write it to the row: carrying only restores - the same in-memory value the previous build already ran with, while persisting it would flip - ``_dcr_bridge_relays_client_registration`` (which keys off the stored column) for dcr_bridge - servers that never had one configured. + endpoints may then belong to a different upstream. Discovery results live only on the in-memory + registry entry; the gateway never writes them to the row, whose OAuth columns carry admin intent + alone, so this carry is the sole last-known-good mechanism and restores exactly the values the + previous build already ran with. Carry-forward is a non-manual endpoint source, so the same trust rule as discovery applies: the previous ``token_url``/``registration_url``/``scopes`` are carried only when the previous @@ -822,6 +906,20 @@ def _extract_upstream_auth_failure( return upstream_auth_challenge(exc) +def _obo_retry_applies(server: MCPServer, subject_token: str | None) -> bool: + """Whether an upstream 401/403 should invalidate the minted credential and retry once. + + ``oauth2_token_exchange`` can only mint from an inbound subject token, so with no token there is + nothing to re-mint and the plain single call is correct. ``oauth2_id_jag`` also sources its + subject from the identity assertion stored for the user at SSO login, so it qualifies whether or + not the caller presented a token of its own; gating it on the inbound token would leave a + store-sourced bearer un-invalidated and replayed until its TTL. + """ + if server.auth_type == MCPAuth.oauth2_id_jag: + return True + return server.auth_type == MCPAuth.oauth2_token_exchange and bool(subject_token) + + def _warn_on_server_name_fields( *, server_id: str, @@ -1190,6 +1288,40 @@ class MCPServerManager: # empty result, or failure). Used to throttle re-probes for servers that do # not return instructions, and to apply a short cooldown after failures. self._upstream_initialize_instructions_probed_at: dict[str, float] = {} + # Per-server (consecutive failures, monotonic timestamp) for OAuth discovery retries, so a + # server whose endpoints never resolve backs off instead of re-running the full + # RFC 9728 -> 8414 chain, and re-logging its warning, on every reload forever. + self._oauth_discovery_retry_state: dict[ + str, tuple[int, float] + ] = {} # mutable-ok: retry cooldown cache, keyed per server and pruned on success + + def _oauth_discovery_retry_due(self, server_id: str) -> bool: + """Whether an unresolved server is due for another discovery attempt. + + The reload fast-path exemption is what retries a failed discovery, so without a cooldown a + permanently unresolvable server re-runs the whole RFC 9728 -> RFC 8414 -> origin-fallback + chain and re-emits its unresolved-endpoints warning on every reload, per server, forever. + Delay doubles per consecutive failure from ``_OAUTH_DISCOVERY_RETRY_BASE_SECONDS`` up to + ``_OAUTH_DISCOVERY_RETRY_MAX_SECONDS``, so a transient outage still recovers on the next + reload while a broken configuration settles to one attempt per cap. + """ + state = self._oauth_discovery_retry_state.get(server_id) + if state is None: + return True + failures, attempted_at = state + delay = min( + _OAUTH_DISCOVERY_RETRY_BASE_SECONDS * (2 ** max(failures - 1, 0)), + _OAUTH_DISCOVERY_RETRY_MAX_SECONDS, + ) + return (time.monotonic() - attempted_at) >= delay + + def _record_oauth_discovery_outcome(self, server: MCPServer) -> None: + """Advance or clear a server's retry cooldown after a rebuild resolved it or did not.""" + if not _oauth_endpoints_unresolved(server): + self._oauth_discovery_retry_state.pop(server.server_id, None) + return + failures, _ = self._oauth_discovery_retry_state.get(server.server_id, (0, 0.0)) + self._oauth_discovery_retry_state[server.server_id] = (failures + 1, time.monotonic()) def _remember_upstream_initialize_instructions(self, server: MCPServer, client: MCPClient) -> None: raw = getattr(client, "_last_initialize_instructions", None) @@ -1365,6 +1497,7 @@ class MCPServerManager: manual_authorization_url, manual_token_url, manual_registration_url, + server_name or server_id, ) should_discover = _has_oauth_discovery_source(server_url, use_issuer_anchor) and ( is_discovery_auth_type or obo_needs_discovery @@ -1518,6 +1651,7 @@ class MCPServerManager: "subject_token_type", DEFAULT_SUBJECT_TOKEN_TYPE, ), + upstream_resource=server_config.get("upstream_resource", None), # ID-JAG fields id_jag_resource_token_endpoint=server_config.get("id_jag_resource_token_endpoint", None), id_jag_resource=server_config.get("id_jag_resource", None), @@ -1666,7 +1800,7 @@ class MCPServerManager: # Generate tool name (without prefix initially) operation_id = operation.get("operationId", f"{method}_{path.replace('/', '_')}") - base_tool_name = operation_id.replace(" ", "_").lower() + base_tool_name = openapi_tool_name(operation_id) # Add server prefix to tool name prefixed_tool_name = add_server_prefix_to_name(base_tool_name, server_prefix) @@ -1841,7 +1975,6 @@ class MCPServerManager: *, credentials_are_encrypted: bool = True, env_vars_are_encrypted: Optional[bool] = None, - persist_discovered_endpoints: bool = True, ) -> MCPServer: _mcp_info: MCPInfo = mcp_server.mcp_info or {} env_dict = _deserialize_json_dict(getattr(mcp_server, "env", None)) @@ -1932,7 +2065,12 @@ class MCPServerManager: or self._obo_needs_endpoint_discovery(auth_type, token_exchange_endpoint, manual_token_url), ) manual_authorization_url, manual_token_url, manual_registration_url = _endpoints_yield_to_issuer( - manual_issuer, is_discovery_auth_type, manual_authorization_url, manual_token_url, manual_registration_url + manual_issuer, + is_discovery_auth_type, + manual_authorization_url, + manual_token_url, + manual_registration_url, + mcp_server.alias or mcp_server.server_name or mcp_server.server_id, ) gated_oauth_metadata = await self._resolve_table_oauth_metadata( mcp_server=mcp_server, @@ -2017,6 +2155,7 @@ class MCPServerManager: subject_token_type=mcp_server.subject_token_type or (credentials_dict.get("subject_token_type") if credentials_dict else None) or DEFAULT_SUBJECT_TOKEN_TYPE, + upstream_resource=(credentials_dict.get("upstream_resource") if credentials_dict else None), # ID-JAG fields — read from credentials JSON blob id_jag_resource_token_endpoint=( credentials_dict.get("id_jag_resource_token_endpoint") if credentials_dict else None @@ -2039,143 +2178,8 @@ class MCPServerManager: max_concurrent_requests=getattr(mcp_server, "max_concurrent_requests", None), ) _warn_internal_delegate_pkce_if_applicable(new_server, source="database") - if persist_discovered_endpoints: - await self._persist_discovered_obo_token_url( - server_id=mcp_server.server_id, - auth_type=auth_type, - existing_token_url=manual_token_url, - discovered_token_url=new_server.token_url, - ) - await self._persist_discovered_oauth_endpoints( - server_id=mcp_server.server_id, - auth_type=auth_type, - existing_issuer=manual_issuer, - existing_authorization_url=manual_authorization_url, - existing_token_url=manual_token_url, - existing_scopes=scopes, - metadata=gated_oauth_metadata, - is_issuer_anchored=use_issuer_anchor, - ) return new_server - async def _persist_discovered_obo_token_url( - self, - *, - server_id: str, - auth_type: Optional[MCPAuthType], - existing_token_url: Optional[str], - discovered_token_url: Optional[str], - ) -> None: - """Write a freshly discovered OBO token endpoint back onto the DB row. - - ``build_mcp_server_from_table`` resolves ``token_url`` via RFC 9728 -> RFC 8414 for an - ``oauth2_token_exchange`` server that has none configured, but that resolved value otherwise - lives only on the returned in-memory object; the row keeps ``token_url=None`` so every rebuild - re-runs discovery, and a transient upstream outage during a rebuild leaves the server with no - endpoint until discovery next succeeds. Persisting it makes ``_obo_needs_endpoint_discovery`` - return False on the next build. Fires at most once per server (skipped once the row has a - value), and is best-effort: a write failure just means discovery runs again next time. - """ - if auth_type != MCPAuth.oauth2_token_exchange: - return - if existing_token_url or not discovered_token_url: - return - from litellm.proxy.proxy_server import prisma_client # noqa: PLC0415 - - if prisma_client is None: - return - try: - await MCPServerRepository(prisma_client).table.update( - where={"server_id": server_id}, - data={"token_url": discovered_token_url}, - ) - verbose_logger.debug("Persisted discovered OBO token_url for MCP server %s", server_id) - except Exception as exc: # noqa: BLE001 - best-effort; a failed write re-discovers next build - verbose_logger.warning("Failed to persist discovered OBO token_url for MCP server %s: %s", server_id, exc) - - async def _persist_discovered_oauth_endpoints( - self, - *, - server_id: str, - auth_type: MCPAuthType | None, - existing_issuer: str | None, - existing_authorization_url: str | None, - existing_token_url: str | None, - existing_scopes: list[str] | None, - metadata: MCPOAuthMetadata | None, - is_issuer_anchored: bool = False, - ) -> None: - """Write freshly discovered OAuth endpoints back onto the DB row. - - Same rationale as ``_persist_discovered_obo_token_url`` but for the interactive oauth2 - family: discovered ``authorization_url``/``token_url``/``scopes`` otherwise live only on - the in-memory registry entry, which is rebuilt on every client connect (the DCR reuse path - calls ``update_server``) and on every post-write DB reload, so one failed re-discovery - serves the 400 "authorization url is not configured" from /authorize until a later rebuild succeeds. - Only fills row fields that are currently empty, never persists origin-fallback guesses - (RFC 9728/8414-advertised metadata only), and deliberately skips ``registration_url`` - because ``_dcr_bridge_relays_client_registration`` keys off that column. Best-effort: a - failed write re-discovers on the next build. Scopes go through ``update_mcp_server`` so - they merge into the credentials blob without touching the stored client credentials. - - For an issuer-anchored server (``is_issuer_anchored``) the endpoints are re-derived from the - §3.3-validated issuer document on every build, so they are NOT persisted into the endpoint - columns: persisting them would make the next build see populated endpoints and treat them as - authoritative stored values, defeating the "endpoints come solely from the issuer" invariant. - Only the resource-driven scopes are persisted for such servers. - """ - if auth_type not in _UPSTREAM_OAUTH_DISCOVERY_AUTH_TYPES: - return - if metadata is None or metadata.from_origin_fallback: - return - issuer_update = ( - {"issuer": metadata.discovered_issuer} if metadata.discovered_issuer and not existing_issuer else {} - ) - authorization_url_update = ( - {"authorization_url": metadata.authorization_url} - if metadata.authorization_url and not existing_authorization_url and not is_issuer_anchored - else {} - ) - token_url_update = ( - {"token_url": metadata.token_url} - if metadata.token_url and not existing_token_url and not is_issuer_anchored - else {} - ) - scopes_update = {"credentials": {"scopes": metadata.scopes}} if metadata.scopes and not existing_scopes else {} - updates: dict[str, object] = { - **issuer_update, - **authorization_url_update, - **token_url_update, - **scopes_update, - } - if not updates: - return - from litellm.proxy._experimental.mcp_server.db import ( # noqa: PLC0415 # db.py imports this module at load - update_mcp_server, - ) - from litellm.proxy._types import UpdateMCPServerRequest # noqa: PLC0415 # heavy module; import at call time - from litellm.proxy.proxy_server import prisma_client # noqa: PLC0415 # runtime value, set after startup - - if prisma_client is None: - return - try: - await update_mcp_server( - prisma_client=prisma_client, - data=UpdateMCPServerRequest.model_validate({"server_id": server_id, **updates}), - touched_by="mcp_oauth_discovery", - ) - verbose_logger.info( - "Persisted discovered OAuth endpoints for MCP server %s: %s", - server_id, - sorted(updates), - ) - except Exception as exc: # noqa: BLE001 - best-effort; a failed write re-discovers next build - verbose_logger.warning( - "Failed to persist discovered OAuth endpoints for MCP server %s: %s", - server_id, - exc, - ) - async def _maybe_register_openapi_tools(self, server: MCPServer, *, initialize_mapping: bool = True): """Register OpenAPI tools if the server has a spec_path configured.""" if server.spec_path: @@ -2424,6 +2428,11 @@ class MCPServerManager: and not is_admitted_subject and _user_has_admin_view(user_api_key_auth) and not has_explicit_object_permission + # An entitlement attached to the HUMAN binds them whatever their role: it is the + # person's scope, not the credential's, so an admin role is not a waiver of it. An + # UNRESOLVED entitlement also skips the shortcut, so the resolver denies rather than + # handing over the whole registry on a transient fault. + and not await MCPRequestHandler._user_places_mcp_ceiling(user_api_key_auth) ): verbose_logger.debug("Admin user without explicit object_permission - returning all servers") return list(self.get_registry().keys()) @@ -2492,6 +2501,13 @@ class MCPServerManager: the given toolsets. Results are cached via ``user_api_key_cache`` (a Redis-backed ``DualCache`` in production) so that cache entries are shared across workers and cold-cache DB hits are minimised. + + A row names a tool on the server identified by ``server_id``, so the + stored name is the tool's own name and is used as written. It is never + reduced by the server's wire prefix: that prefix is added on the way out + and is not part of any tool's identity, so treating a leading segment as + one silently renames the tool when a native name happens to begin with + it (``greyhound_internal_events`` on a server prefixed ``greyhound``). """ from litellm.proxy._experimental.mcp_server.toolset_db import list_mcp_toolsets from litellm.proxy.proxy_server import prisma_client, user_api_key_cache @@ -2509,12 +2525,9 @@ class MCPServerManager: tool_permissions: dict[str, list[str]] = {} for toolset in toolsets: for tool in toolset.tools: - raw_name = tool["tool_name"] - server = self.get_mcp_server_by_id(tool["server_id"]) - unprefixed = strip_known_server_prefix(raw_name, server) - tool_permissions.setdefault(tool["server_id"], []) - if unprefixed not in tool_permissions[tool["server_id"]]: - tool_permissions[tool["server_id"]].append(unprefixed) + allowed_names = tool_permissions.setdefault(tool["server_id"], []) + if tool["tool_name"] not in allowed_names: + allowed_names.append(tool["tool_name"]) await user_api_key_cache.async_set_cache( key=cache_key, value=tool_permissions, @@ -4189,10 +4202,8 @@ class MCPServerManager: # Register every known prefix form (alias, server_name, server_id, # short ID) so call_tool can resolve regardless of which form a # caller / cached client is using. - self.tool_name_to_mcp_server_name_mapping[original_name] = prefix - for known_prefix in iter_known_server_prefixes(server): - qualified = add_server_prefix_to_name(original_name, known_prefix) - self.tool_name_to_mcp_server_name_mapping[qualified] = prefix + for spelling in iter_known_tool_name_spellings(original_name, server): + self.tool_name_to_mcp_server_name_mapping[spelling] = prefix verbose_logger.info(f"Successfully fetched {len(prefixed_tools)} tools from server {server.name}") return prefixed_tools @@ -4265,28 +4276,29 @@ class MCPServerManager: def check_allowed_or_banned_tools(self, tool_name: str, server: MCPServer) -> bool: """ - Check if the tool is allowed or banned for the given server + Check if the tool is allowed or banned for the given server. + + ``tool_name`` is bare: every caller resolves the boundary against the server's + registered prefixes before dispatch (``server.py``'s ``original_tool_name``, the + Responses handler's ``sanitized_tool_name``). Configured entries are matched by + deriving the spellings routing accepts, never by stripping the entry, which would + cut a second boundary out of a native name that opens with the server prefix. """ from litellm.proxy._experimental.mcp_server.utils import ( server_applies_tool_allowlist, ) if server_applies_tool_allowlist(server): - if not server.allowed_tools: - return False - return tool_name in server.allowed_tools or f"{server.name}-{tool_name}" in server.allowed_tools - if server.disallowed_tools: - return ( - tool_name not in server.disallowed_tools and f"{server.name}-{tool_name}" not in server.disallowed_tools - ) - return True + return match_known_tool_name(tool_name, server, server.allowed_tools or ()) is not None + return match_known_tool_name(tool_name, server, server.disallowed_tools or ()) is None def validate_allowed_params(self, tool_name: str, arguments: dict[str, Any], server: MCPServer) -> None: """ Filter arguments to only include allowed parameters for the given tool. Args: - tool_name: Name of the tool (with or without prefix) + tool_name: Bare tool name, already resolved against the server's + registered prefixes by the caller arguments: Dictionary of arguments to filter server: MCPServer configuration @@ -4296,23 +4308,12 @@ class MCPServerManager: Raises: HTTPException: If allowed_params is configured for this tool but arguments contain disallowed params """ - from litellm.proxy._experimental.mcp_server.utils import ( - split_server_prefix_from_name, - ) - - # If no allowed_params configured, return all arguments - if not server.allowed_params: + allowed_params = server.allowed_params or {} + matched = match_known_tool_name(tool_name, server, allowed_params) + if matched is None: return - # Get the unprefixed tool name to match against config - unprefixed_tool_name, _ = split_server_prefix_from_name(tool_name) - - # Check both prefixed and unprefixed tool names - allowed_params_list = server.allowed_params.get(tool_name) or server.allowed_params.get(unprefixed_tool_name) - - # If this tool doesn't have allowed_params specified, allow all params - if allowed_params_list is None: - return None + allowed_params_list = allowed_params[matched] # Filter arguments to only include allowed parameters disallowed_params = [param for param in arguments.keys() if param not in allowed_params_list] @@ -4394,8 +4395,11 @@ class MCPServerManager: global_mcp_tool_registry, ) - # Get the tool from the registry - tool = global_mcp_tool_registry.get_tool(f"{server.name}-{tool_name}") + # Registration used add_server_prefix_to_name(base, get_server_prefix(server)), + # and tool_name is the bare base name by the time call_tool reaches here, so + # rebuilding the key the same way reproduces it exactly + registry_key = add_server_prefix_to_name(tool_name, get_server_prefix(server)) + tool = global_mcp_tool_registry.get_tool(registry_key) if tool is None: # Tool not found in registry error_msg = f"OpenAPI tool {tool_name} not found in registry" @@ -4432,13 +4436,18 @@ class MCPServerManager: arguments: dict[str, Any], server_name: str, user_api_key_auth: Optional[UserAPIKeyAuth], - proxy_logging_obj: ProxyLogging, + proxy_logging_obj: ProxyLogging | None, server: MCPServer, raw_headers: Optional[dict[str, str]] = None, ) -> dict[str, Any]: """ Run pre-call checks and guardrail hooks for an MCP tool call. + Authorization runs unconditionally; only the guardrail hooks, which are + dispatched through ``proxy_logging_obj``, depend on a logger being + present. An absent logger must never be able to turn an authorization + decision into a no-op. + Returns a dict that may contain: - "arguments": hook-modified tool arguments (only if changed) - "extra_headers": headers injected by pre_mcp_call guardrail hooks @@ -4466,6 +4475,10 @@ class MCPServerManager: server=server, ) + hook_result: dict[str, Any] = {} + if proxy_logging_obj is None: + return hook_result + # Extract incoming Bearer token from raw request headers so # guardrails like MCPJWTSigner can verify + re-sign it (FR-5). normalized_raw = {k.lower(): v for k, v in (raw_headers or {}).items()} @@ -4495,7 +4508,6 @@ class MCPServerManager: # Convert to LLM format for existing guardrail compatibility synthetic_llm_data = proxy_logging_obj._convert_mcp_to_llm_format(mcp_request_obj, pre_hook_kwargs) - hook_result: dict[str, Any] = {} try: # Use standard pre_call_hook modified_data = await proxy_logging_obj.pre_call_hook( @@ -4788,7 +4800,7 @@ class MCPServerManager: arguments=arguments, ) - if mcp_server.auth_type in (MCPAuth.oauth2_token_exchange, MCPAuth.oauth2_id_jag) and subject_token: + if _obo_retry_applies(mcp_server, subject_token): # OBO / ID-JAG: the exchanged token may have been revoked/rotated upstream since it was # cached, so an upstream 401 gets one invalidate + re-mint + retry. Gated to these modes; # all others keep the plain single call below. @@ -5121,19 +5133,17 @@ class MCPServerManager: # Allow validation and modification of tool calls before execution # Using standard pre_call_hook ######################################################### - hook_result: dict[str, Any] = {} - if proxy_logging_obj: - hook_result = await self.pre_call_tool_check( - name=name, - arguments=arguments, - server_name=server_name, - user_api_key_auth=user_api_key_auth, - proxy_logging_obj=proxy_logging_obj, - server=mcp_server, - raw_headers=raw_headers, - ) - if "arguments" in hook_result: - arguments = hook_result["arguments"] + hook_result: dict[str, Any] = await self.pre_call_tool_check( + name=name, + arguments=arguments, + server_name=server_name, + user_api_key_auth=user_api_key_auth, + proxy_logging_obj=proxy_logging_obj, + server=mcp_server, + raw_headers=raw_headers, + ) + if "arguments" in hook_result: + arguments = hook_result["arguments"] # Prepare tasks for during hooks tasks = [] @@ -5255,7 +5265,7 @@ class MCPServerManager: for tool in tools: # The tool.name here is already prefixed from _get_tools_from_server # Extract original name for mapping - original_name, _ = split_server_prefix_from_name(tool.name) + original_name = strip_known_server_prefix(tool.name, server) self.tool_name_to_mcp_server_name_mapping[original_name] = server.name self.tool_name_to_mcp_server_name_mapping[tool.name] = server.name @@ -5292,13 +5302,10 @@ class MCPServerManager: # If not found and tool name is prefixed, extract the prefix and # match against any known form. - if is_tool_name_prefixed(tool_name, known_server_prefixes=set(prefix_to_server.keys())): - ( - original_tool_name, - server_name_from_prefix, - ) = split_server_prefix_from_name(tool_name) - normalised_prefix = normalize_server_name(server_name_from_prefix) - matched_server = prefix_to_server.get(normalised_prefix) + matched = match_known_server_prefix(tool_name, prefix_to_server.keys()) + if matched is not None: + matched_prefix, original_tool_name = matched + matched_server = prefix_to_server.get(matched_prefix) if matched_server is not None and ( original_tool_name in self.tool_name_to_mcp_server_name_mapping or tool_name in self.tool_name_to_mcp_server_name_mapping @@ -5331,7 +5338,7 @@ class MCPServerManager: ] } ) - db_mcp_servers = [LiteLLM_MCPServerTable(**r.model_dump()) for r in raw_rows] + db_mcp_servers = [LiteLLM_MCPServerTable.model_validate(r.model_dump()) for r in raw_rows] verbose_logger.info(f"Found {len(db_mcp_servers)} MCP servers in database") previous_registry = self.registry @@ -5349,6 +5356,10 @@ class MCPServerManager: and existing_server.updated_at is not None and server.updated_at is not None and existing_server.updated_at == server.updated_at + and not ( + _oauth_endpoints_unresolved(existing_server) + and self._oauth_discovery_retry_due(server.server_id) + ) ): # Re-use existing server instance to avoid re-running build_mcp_server_from_table() # which can perform network discovery for OAuth2 servers. @@ -5366,6 +5377,7 @@ class MCPServerManager: # already-decrypted records add_server/update_server are handed. # Decrypt them while building the registry entry. new_server = await self.build_mcp_server_from_table(server, env_vars_are_encrypted=True) + self._record_oauth_discovery_outcome(new_server) # Carry the cached short_prefix from the previous registry entry # (if any) so the prefix is stable across reloads. if existing_server is not None and existing_server.short_prefix: diff --git a/litellm/proxy/_experimental/mcp_server/oauth2_token_cache.py b/litellm/proxy/_experimental/mcp_server/oauth2_token_cache.py index a6acaf8e1d6..b2b3f70d200 100644 --- a/litellm/proxy/_experimental/mcp_server/oauth2_token_cache.py +++ b/litellm/proxy/_experimental/mcp_server/oauth2_token_cache.py @@ -6,6 +6,7 @@ with ``client_id``, ``client_secret``, and ``token_url``. """ import asyncio +import hashlib from typing import TYPE_CHECKING, Dict, Optional, Tuple, Union import httpx @@ -26,8 +27,9 @@ from litellm.proxy.common_utils.encrypt_decrypt_utils import ( decrypt_value_helper, encrypt_value_helper, ) -from litellm.proxy._experimental.mcp_server.auth.token_endpoint_auth import ( - build_token_endpoint_client_auth, +from litellm.proxy._experimental.mcp_server.oauth_utils import ( + build_upstream_oauth2_token_request, + resolve_upstream_resource, ) from litellm.types.llms.custom_http import httpxSpecialProvider @@ -37,10 +39,18 @@ if TYPE_CHECKING: class MCPOAuth2TokenCache(InMemoryCache): """ - In-memory cache for OAuth2 client_credentials tokens, keyed by server_id. + In-memory cache for OAuth2 client_credentials tokens, keyed by the identity of the token + request rather than by server_id alone. + + A minted token is only reusable for the exact request that produced it. Keying on server_id + alone served a token minted under the previous configuration whenever any of those inputs + changed, so editing scopes, rotating the client secret, or setting ``upstream_resource`` + silently kept handing out a token carrying the old scopes or audience until it expired. The + identity below covers every input ``_fetch_token`` puts on the wire, so a change to any of + them misses the cache and mints afresh. Inherits from ``InMemoryCache`` for TTL-based storage and eviction. - Adds per-server ``asyncio.Lock`` to prevent duplicate concurrent fetches. + Adds a per-identity ``asyncio.Lock`` to prevent duplicate concurrent fetches. """ def __init__(self) -> None: @@ -50,8 +60,25 @@ class MCPOAuth2TokenCache(InMemoryCache): ) self._locks: Dict[str, asyncio.Lock] = {} - def _get_lock(self, server_id: str) -> asyncio.Lock: - return self._locks.setdefault(server_id, asyncio.Lock()) + @staticmethod + def _token_identity(server: "MCPServer") -> str: + """Cache key for the token this server's config would mint, prefixed by server_id so a + single server's entries stay greppable and invalidatable. The secret is hashed with the + rest of the identity rather than stored in a key.""" + material = "\x00".join( + ( + server.token_url or "", + server.client_id or "", + server.client_secret or "", + " ".join(server.scopes or ()), + resolve_upstream_resource(server) or "", + server.token_endpoint_auth_method or "", + ) + ) + return f"{server.server_id}:{hashlib.sha256(material.encode()).hexdigest()}" + + def _get_lock(self, identity: str) -> asyncio.Lock: + return self._locks.setdefault(identity, asyncio.Lock()) @staticmethod def _has_client_credentials_config(server: "MCPServer") -> bool: @@ -67,21 +94,21 @@ class MCPOAuth2TokenCache(InMemoryCache): if not self._has_client_credentials_config(server): return None - server_id = server.server_id + identity = self._token_identity(server) # Fast path — cached token is still valid - cached = self.get_cache(server_id) + cached = self.get_cache(identity) if cached is not None: return cached - # Slow path — acquire per-server lock then double-check - async with self._get_lock(server_id): - cached = self.get_cache(server_id) + # Slow path — acquire per-identity lock then double-check + async with self._get_lock(identity): + cached = self.get_cache(identity) if cached is not None: return cached token, ttl = await self._fetch_token(server) - self.set_cache(server_id, token, ttl=ttl) + self.set_cache(identity, token, ttl=ttl) return token async def _fetch_token(self, server: "MCPServer") -> Tuple[str, int]: @@ -100,14 +127,15 @@ class MCPOAuth2TokenCache(InMemoryCache): f"token_url={bool(server.token_url)}" ) - client_auth = build_token_endpoint_client_auth( + token_request = build_upstream_oauth2_token_request( + server, auth_method=server.token_endpoint_auth_method, client_id=server.client_id, client_secret=server.client_secret, ) data: Dict[str, str] = { "grant_type": "client_credentials", - **client_auth.body, + **token_request.body, } if server.scopes: data["scope"] = " ".join(server.scopes) @@ -117,7 +145,7 @@ class MCPOAuth2TokenCache(InMemoryCache): server.server_id, ) - post_kwargs = {"data": data, **({"headers": client_auth.headers} if client_auth.headers else {})} + post_kwargs = {"data": data, **({"headers": token_request.headers} if token_request.headers else {})} try: response = await client.post(server.token_url, **post_kwargs) response.raise_for_status() @@ -159,8 +187,14 @@ class MCPOAuth2TokenCache(InMemoryCache): return access_token, ttl def invalidate(self, server_id: str) -> None: - """Remove a cached token (e.g. after a 401).""" - self.delete_cache(server_id) + """Remove every cached token for a server (e.g. after a 401). + + Entries are keyed by token identity, so one server can hold more than one entry across a + config change; a 401 invalidates all of them rather than only the current configuration's. + """ + prefix = f"{server_id}:" + for key in [k for k in self.cache_dict if isinstance(k, str) and k.startswith(prefix)]: + self.delete_cache(key) mcp_oauth2_token_cache = MCPOAuth2TokenCache() diff --git a/litellm/proxy/_experimental/mcp_server/oauth_issuer_stamp_backfill.py b/litellm/proxy/_experimental/mcp_server/oauth_issuer_stamp_backfill.py new file mode 100644 index 00000000000..874fcc64772 --- /dev/null +++ b/litellm/proxy/_experimental/mcp_server/oauth_issuer_stamp_backfill.py @@ -0,0 +1,148 @@ +"""One-time heal for MCP server rows whose ``issuer`` a released version wrote by itself. + +Until the write was removed, OAuth discovery stamped the issuer it discovered onto the ``issuer`` +column trust-on-first-use. That column means "the admin pinned this trust anchor", so the next +registry build read the gateway's own output back as admin intent: the server turned issuer-anchored +(RFC 8414 section 3.3), its stored authorization/token/registration URLs stopped applying, and a +failed issuer-document fetch left it with no authorize endpoint (GH #34985). + +Deleting the write fixes every row created afterwards but cannot fix a row already stamped, which +still reads as pinned. This heals those rows by clearing the stamp so their configured endpoints +apply again. + +The signal is a heuristic, and deliberately a narrow one. ``updated_by`` records only the most recent +writer, and no audit trail says which field that writer touched, so "discovery wrote this issuer" is +not directly knowable. Two independent clauses bound it, and each rules out a different way of +destroying a pin an admin meant. + +Configured endpoints must be present. A deliberately pinned row very often has none, both because the +Issuer field is documented as overriding them and because ``update_mcp_server`` clears them when an +issuer changes, so "issuer set, endpoints empty" is the canonical shape of a real pin and must never +be cleared on this evidence. Skipping those rows costs little: with nothing configured to restore, the +anchored and resource-rooted paths resolve from the same upstream document, and the row still gets the +unresolved-endpoint retry and the anchored-discard warning. + +The configured endpoints must also share the issuer's origin. A stamped issuer is by construction the +one self-attested by the authorization-server document discovery reached from this very server, so +endpoints typed alongside it address that same authority. An admin who pinned an issuer and typed +endpoints for a different authority is expressing an intent that clearing the issuer would discard, so +that row is warned about and never healed. + +What survives both clauses is a row whose configured endpoints and stamped issuer share an origin, +which is exactly the GH #34985 shape. An admin who pinned that same origin by hand lands here too, and +for them the clear is close to a no-op: their typed endpoints keep serving and still anchor the +RFC 9700 corroboration gate, with only the stricter section 3.3 anchoring lost. Every heal logs the +cleared value so it can be restored, and the clear is recorded under this module's actor so the heal +runs at most once per row. +""" + +from typing import Protocol +from urllib.parse import urlparse + +from litellm._logging import verbose_proxy_logger +from litellm.proxy._experimental.mcp_server.oauth_utils import canonicalize_url_identity +from litellm.proxy.utils import PrismaClient + +# The actor the removed discovery write-back stamped rows with. +_DISCOVERY_ACTOR = "mcp_oauth_discovery" + +# The actor recorded on a healed row, which also makes the heal idempotent: once a row is cleared it +# no longer matches ``updated_by == _DISCOVERY_ACTOR`` and is never reconsidered. +_BACKFILL_ACTOR = "mcp_oauth_issuer_stamp_backfill" + +_AUTH_TYPES_WITH_ISSUER_ANCHORING = ("oauth2", "true_passthrough", "oauth_delegate") + + +def _origin(url: str) -> str | None: + """The scheme-and-authority identity of ``url``, or ``None`` when it has none. + + Built on the shared URL canonicalizer so the lowercase-host and default-port rules match the + RFC 8414 issuer comparison the resolution path uses, instead of being re-derived here. + """ + parsed = urlparse(canonicalize_url_identity(url)) + if not parsed.scheme or not parsed.netloc: + return None + return f"{parsed.scheme}://{parsed.netloc}" + + +class _MCPServerRow(Protocol): + """The MCP server row fields this heal reads, so the untyped DB record is narrowed once here.""" + + server_id: str + alias: str | None + server_name: str | None + auth_type: str | None + issuer: str | None + authorization_url: str | None + token_url: str | None + registration_url: str | None + updated_by: str | None + + +def _is_stamped_issuer_row(row: _MCPServerRow) -> bool: + """Whether this row carries the full signature of a gateway-written issuer stamp. + + The whole rule lives here, including the writer check the query also filters on, so the decision + to clear an admin-visible field is auditable in one place rather than split between a predicate + and a query. + """ + if getattr(row, "updated_by", None) != _DISCOVERY_ACTOR: + return False + if not (getattr(row, "issuer", None) or "").strip(): + return False + if getattr(row, "auth_type", None) not in _AUTH_TYPES_WITH_ISSUER_ANCHORING: + return False + configured = tuple( + value.strip() + for value in (row.authorization_url, row.token_url, row.registration_url) + if value and value.strip() + ) + if not configured: + return False + issuer_origin = _origin(row.issuer or "") + return issuer_origin is not None and all(_origin(endpoint) == issuer_origin for endpoint in configured) + + +async def backfill_discovery_stamped_issuers(prisma_client: PrismaClient) -> int: + """Clear gateway-written issuer stamps, returning the number of rows healed.""" + candidate_rows: list[_MCPServerRow] = await prisma_client.db.litellm_mcpservertable.find_many( + where={ + "updated_by": _DISCOVERY_ACTOR, + "auth_type": {"in": list(_AUTH_TYPES_WITH_ISSUER_ANCHORING)}, + }, + ) + stamped = tuple(row for row in candidate_rows if _is_stamped_issuer_row(row)) + if not stamped: + return 0 + + healed = 0 + for row in stamped: + try: + await prisma_client.db.litellm_mcpservertable.update( + where={"server_id": row.server_id}, + data={"issuer": None, "updated_by": _BACKFILL_ACTOR}, + ) + except Exception as exc: # noqa: BLE001 - per-row best effort; the next boot retries + verbose_proxy_logger.warning( + "MCP issuer stamp backfill: could not heal server_id=%s: %s", row.server_id, exc + ) + continue + healed += 1 + verbose_proxy_logger.warning( + "MCP issuer stamp backfill: cleared issuer %r on server_id=%s (alias=%s). OAuth discovery " + "had written that value onto the Issuer column, which made the server issuer-anchored and " + "fail-closed, and its configured Authorization/Token/Registration URLs were being ignored " + "as a result; those now apply again. If you pinned this issuer deliberately, set it again " + "via the dashboard or PUT /v1/mcp/server to restore RFC 8414 section 3.3 anchoring.", + row.issuer, + row.server_id, + row.alias or row.server_name, + ) + + if healed: + verbose_proxy_logger.warning( + "MCP issuer stamp backfill: healed %d server(s) whose Issuer had been written by OAuth " + "discovery rather than by an admin", + healed, + ) + return healed diff --git a/litellm/proxy/_experimental/mcp_server/oauth_utils.py b/litellm/proxy/_experimental/mcp_server/oauth_utils.py index 9b7760a30d7..8f47aa7344d 100644 --- a/litellm/proxy/_experimental/mcp_server/oauth_utils.py +++ b/litellm/proxy/_experimental/mcp_server/oauth_utils.py @@ -3,14 +3,23 @@ import os from ipaddress import ip_address -from typing import Any, Dict, List, NoReturn, Optional +from typing import TYPE_CHECKING, Any, Dict, List, NoReturn, Optional from urllib.parse import ParseResult, urlparse, urlsplit, urlunparse, urlunsplit from fastapi import HTTPException, Request +from starlette.types import Scope from litellm._logging import verbose_logger +from litellm.proxy._experimental.mcp_server.auth.token_endpoint_auth import ( + TokenEndpointClientAuth, + build_token_endpoint_client_auth, + normalize_token_endpoint_auth_method, +) from litellm.proxy.auth.ip_address_utils import IPAddressUtils +if TYPE_CHECKING: + from litellm.types.mcp_server.mcp_server_manager import MCPServer + # RFC 6749 §5.1 / OAuth 2.1 draft-15 §4.1.3: token-endpoint responses # must not be cached — both success and error bodies may reveal secrets. TOKEN_NO_CACHE_HEADERS = {"Cache-Control": "no-store", "Pragma": "no-cache"} @@ -21,6 +30,10 @@ TOKEN_NO_CACHE_HEADERS = {"Cache-Control": "no-store", "Pragma": "no-cache"} # explicit port, which would otherwise break a literal netloc compare). _DEFAULT_PORTS = {"http": 80, "https": 443} +# Sentinel ``upstream_resource`` value meaning "derive the RFC 8707 resource identifier from the +# server's own url". RFC 8707 requires an absolute URI, so this can never be a real resource value. +UPSTREAM_RESOURCE_AUTO = "auto" + # Env var for ops to allowlist additional redirect_uri origins beyond # same-origin + loopback — needed for first-party OAuth clients hosted # on sister domains (e.g. a web app on app.example.com registering as @@ -167,6 +180,37 @@ def well_known_root_suffix() -> str: return "" if root == "/" else root +def get_passthrough_resource_metadata_url(scope: Scope, server_name: str) -> str: + """The per-server protected-resource metadata URL matching the spelling the request + arrived on, so a strict RFC 9728 client resolves the same route the proxy registered. + ``_original_path`` preserves the ``/{server}/mcp`` spelling through the + ``dynamic_mcp_route`` rewrite; the ``SERVER_ROOT_PATH`` segment is inserted exactly as + the route decorators insert it (see :func:`well_known_root_suffix`).""" + request = Request(scope) + base_url = get_request_base_url(request) + _path = scope.get("_original_path") or scope.get("path", "") or "" + + if _path.startswith(f"/{server_name}/mcp"): + return f"{base_url}/.well-known/oauth-protected-resource{well_known_root_suffix()}/{server_name}/mcp" + return f"{base_url}/.well-known/oauth-protected-resource{well_known_root_suffix()}/mcp/{server_name}" + + +def get_passthrough_www_authenticate( + scope: Scope, + server_name: str, + invalid_token: bool = False, +) -> str: + """The RFC 9728 ``WWW-Authenticate`` value advertising the per-server + protected-resource metadata, with the RFC 6750 ``invalid_token`` error code when the + caller presented a bearer that failed rather than no credential at all.""" + resource_metadata_url = get_passthrough_resource_metadata_url( + scope=scope, + server_name=server_name, + ) + error_attr = 'error="invalid_token", ' if invalid_token else "" + return f'Bearer {error_attr}resource_metadata="{resource_metadata_url}"' + + def validate_loopback_redirect_uri(redirect_uri: str) -> None: """Require a loopback ``redirect_uri`` (OAuth 2.1 §4.1.2.1 + RFC 8252 §7.3 native-app pattern). MCP clients are native apps that listen on @@ -574,3 +618,112 @@ def validate_trusted_redirect_uri(request: Request, redirect_uri: str) -> None: if _trusted_redirect_uri_is_allowed(parsed, redirect_netloc, proxy_base): return _raise_trusted_redirect_uri_rejected(request, redirect_uri, parsed, redirect_netloc, proxy_base) + + +def canonicalize_url_identity(url: str) -> str: + """Normalize a URL to a comparable identity: lowercase scheme and host, drop the scheme's default + port, and strip userinfo, params, query, fragment and a trailing slash while keeping IPv6 + brackets. The one URL-canonicalization primitive shared by the RFC 8707 resource emitter and the + RFC 8414 issuer/authorize-endpoint comparison, so the default-port and IPv6 rules cannot be + present in one and missing in the other. The netloc (not ``parsed.hostname``) carries the + authority so ``[::1]:8080`` survives with its brackets intact.""" + parsed = urlparse(url) + scheme = parsed.scheme.lower() + netloc = _strip_default_port(scheme, parsed.netloc.rpartition("@")[2]) + return urlunparse((scheme, netloc, parsed.path.rstrip("/"), "", "", "")) + + +def _canonical_resource_uri(url: str) -> str | None: + """Canonicalize an upstream MCP server URL into an RFC 8707 resource identifier. + + Keeps only the scheme, host, port and path, which is the shape the MCP authorization spec's + "Canonical Server URI" section describes and every one of its examples takes; the reference + implementation is ``mcp.shared.auth_utils.resource_url_from_server_url``, and this is the stricter + variant. The scheme and host are lowercased, the scheme's default port is dropped so + ``https://host:443/mcp`` and ``https://host/mcp`` never present as two resources, and a trailing + slash is dropped so ``https://host/mcp/`` and ``https://host/mcp`` do not either. + + Userinfo, query and fragment are dropped rather than carried. A transport URL routinely holds + credentials in exactly those components (``user:password@``, ``?api_key=``), while a resource + indicator names the resource and nothing else; this value is published somewhere the transport + URL never goes, into the authorization redirect the browser follows and into token request + bodies, so carrying them would disclose them to the authorization server, its logs, and browser + history. RFC 8707 forbids a fragment outright and says a resource SHOULD NOT carry a query. An + upstream whose identifier genuinely needs more than this is served by setting + ``upstream_resource`` explicitly, which is passed through untouched. + + Returns ``None`` when the URL is not absolute, which cannot yield a valid resource identifier. + """ + parsed = urlparse(url) + if not parsed.scheme or not parsed.netloc: + return None + return canonicalize_url_identity(url) + + +def resolve_upstream_resource(mcp_server: "MCPServer") -> str | None: + """Resolve the RFC 8707 ``resource`` value this server's upstream OAuth legs must carry. + + The MCP authorization spec requires an MCP client to send ``resource`` on both the + authorization request and every token request, naming the canonical URI of the MCP server the + token is for. Authorization server temperaments are irreconcilable and undetectable, so this + stays an explicit per-server opt-in: most SaaS providers ignore the parameter, some hard-reject + it and express audience through scopes instead, and strict or MCP-native ones refuse to mint a + correctly scoped token without it (``invalid_target``). + + ``None`` or blank omits the parameter, which is the default and preserves the behavior of every + server working today. ``"auto"`` derives the canonical URI from the server's own URL; it is not + an absolute URI, so RFC 8707 guarantees it can never collide with a real resource value. Any + other value is sent verbatim, because the identifier has to match what the authorization server + expects exactly and normalizing it could break that match. + + Every upstream leg for a server resolves through this one function, so the authorize request + and the token requests cannot disagree; a token request naming a resource the authorization + request never asked for is itself an ``invalid_target`` under RFC 8707. + """ + configured = (mcp_server.upstream_resource or "").strip() + if not configured: + return None + if configured.lower() != UPSTREAM_RESOURCE_AUTO: + return configured + if not mcp_server.url: + verbose_logger.warning( + "MCP server %s sets upstream_resource=auto but has no url to derive a resource " + "identifier from; omitting the RFC 8707 resource parameter. Set upstream_resource to " + "the exact resource identifier the authorization server expects instead.", + mcp_server.server_id, + ) + return None + canonical = _canonical_resource_uri(mcp_server.url) + if canonical is None: + verbose_logger.warning( + "MCP server %s sets upstream_resource=auto but its url is not an absolute URI, so no " + "RFC 8707 resource identifier could be derived; omitting the resource parameter", + mcp_server.server_id, + ) + return canonical + + +def build_upstream_oauth2_token_request( + mcp_server: "MCPServer", + *, + auth_method: object, + client_id: str | None, + client_secret: str | None, +) -> TokenEndpointClientAuth: + """Client auth plus the RFC 8707 ``resource`` for one upstream plain-OAuth2 token request. + + Resolving both in one call is what stops a leg authenticating without naming the resource its + sibling legs named; the RFC 8693 legs (OBO, id_jag) carry ``audience`` and stay on + ``build_token_endpoint_client_auth``. The client-auth inputs are passed in because a leg may + authenticate as the caller's own client rather than the server's; ``resource`` always comes from + the server, so no leg can choose or forget it. + """ + client_auth = build_token_endpoint_client_auth( + auth_method=normalize_token_endpoint_auth_method(auth_method), + client_id=client_id, + client_secret=client_secret, + ) + resource = resolve_upstream_resource(mcp_server) + if not resource: + return client_auth + return TokenEndpointClientAuth(headers=client_auth.headers, body={**client_auth.body, "resource": resource}) diff --git a/litellm/proxy/_experimental/mcp_server/outbound_credentials/adapter.py b/litellm/proxy/_experimental/mcp_server/outbound_credentials/adapter.py index 565c489e77c..efaa7b742c2 100644 --- a/litellm/proxy/_experimental/mcp_server/outbound_credentials/adapter.py +++ b/litellm/proxy/_experimental/mcp_server/outbound_credentials/adapter.py @@ -18,6 +18,7 @@ from fastapi import HTTPException from pydantic import SecretStr from typing_extensions import assert_never +from litellm.proxy._experimental.mcp_server.oauth_utils import resolve_upstream_resource from litellm.proxy._experimental.mcp_server.outbound_credentials.types import ( ApiKeyConfig, AuthorizationCodeConfig, @@ -144,6 +145,7 @@ def _client_credentials_spec(server: MCPServer, resource: str) -> ServerSpec: token_url=server.token_url, scopes=tuple(server.scopes or ()), audience=server.audience, + upstream_resource=resolve_upstream_resource(server), token_endpoint_auth_method=server.token_endpoint_auth_method, ), ) diff --git a/litellm/proxy/_experimental/mcp_server/outbound_credentials/authz_code_refresher.py b/litellm/proxy/_experimental/mcp_server/outbound_credentials/authz_code_refresher.py index 977fe9c38aa..1d7fcf5afbc 100644 --- a/litellm/proxy/_experimental/mcp_server/outbound_credentials/authz_code_refresher.py +++ b/litellm/proxy/_experimental/mcp_server/outbound_credentials/authz_code_refresher.py @@ -17,8 +17,8 @@ from typing import TYPE_CHECKING, Protocol from litellm._logging import verbose_logger from litellm.proxy._experimental.mcp_server.auth.token_endpoint_auth import ( TokenEndpointAuthConfigError, - build_token_endpoint_client_auth, ) +from litellm.proxy._experimental.mcp_server.oauth_utils import build_upstream_oauth2_token_request from litellm.proxy._experimental.mcp_server.outbound_credentials.oauth_token_store import ( OAuthToken, ) @@ -92,7 +92,8 @@ class AuthorizationCodeRefresher: return None try: - client_auth = build_token_endpoint_client_auth( + token_request = build_upstream_oauth2_token_request( + server, auth_method=server.token_endpoint_auth_method, client_id=server.client_id, client_secret=server.client_secret, @@ -103,9 +104,9 @@ class AuthorizationCodeRefresher: form = { "grant_type": "refresh_token", "refresh_token": token.refresh_token, - **client_auth.body, + **token_request.body, } - body = await self._token_endpoint(server.token_url, form, client_auth.headers) + body = await self._token_endpoint(server.token_url, form, token_request.headers) if body is None: return None access_token = body.get("access_token") diff --git a/litellm/proxy/_experimental/mcp_server/outbound_credentials/client_credentials.py b/litellm/proxy/_experimental/mcp_server/outbound_credentials/client_credentials.py index 9be1121126a..225b7edb547 100644 --- a/litellm/proxy/_experimental/mcp_server/outbound_credentials/client_credentials.py +++ b/litellm/proxy/_experimental/mcp_server/outbound_credentials/client_credentials.py @@ -292,6 +292,7 @@ def _prepare_grant(config: ClientCredentialsConfig) -> Result[_PreparedGrant, Cr **client_auth.body, **({"scope": " ".join(config.scopes)} if config.scopes else {}), **({"audience": config.audience} if config.audience else {}), + **({"resource": config.upstream_resource} if config.upstream_resource else {}), } return Ok( _PreparedGrant( @@ -313,6 +314,7 @@ def _identity_key(config: ClientCredentialsConfig) -> str: config.token_endpoint_auth_method or "", " ".join(config.scopes), config.audience or "", + config.upstream_resource or "", ) ) return hashlib.sha256(material.encode("utf-8")).hexdigest() diff --git a/litellm/proxy/_experimental/mcp_server/outbound_credentials/per_user_oauth_store.py b/litellm/proxy/_experimental/mcp_server/outbound_credentials/per_user_oauth_store.py index 21001c09f25..3a2c748bb82 100644 --- a/litellm/proxy/_experimental/mcp_server/outbound_credentials/per_user_oauth_store.py +++ b/litellm/proxy/_experimental/mcp_server/outbound_credentials/per_user_oauth_store.py @@ -11,7 +11,7 @@ collaborators acquire their globals per call, mirroring v1's lazy-import pattern from __future__ import annotations import asyncio -from collections.abc import Callable +from collections.abc import Callable, Mapping from typing import TYPE_CHECKING from litellm._logging import verbose_logger @@ -54,7 +54,7 @@ ServerLookup = Callable[[str], "MCPServer | None"] StoreBuilder = Callable[[ServerLookup], tuple[InvalidatableOAuthTokenStore, bool]] -async def _read_credential(user_id: str, server_id: str) -> dict[str, object] | None: +async def _read_credential(user_id: str, server_id: str) -> Mapping[str, object] | None: from litellm.proxy._experimental.mcp_server.db import ( # noqa: PLC0415 get_user_oauth_credential, ) diff --git a/litellm/proxy/_experimental/mcp_server/outbound_credentials/resolver.py b/litellm/proxy/_experimental/mcp_server/outbound_credentials/resolver.py index 69984a56311..b70db64ba94 100644 --- a/litellm/proxy/_experimental/mcp_server/outbound_credentials/resolver.py +++ b/litellm/proxy/_experimental/mcp_server/outbound_credentials/resolver.py @@ -10,19 +10,24 @@ at runtime instead of returning `None`. `none`, `api_key` (shared-key source), and `passthrough` (forwards the caller's own inbound token) are live, as is `authorization_code`, which reads the user's token from the injected `OAuthTokenStore`, `token_exchange`, which swaps the caller's inbound token through the injected -`TokenExchanger`, and `client_credentials`, which mints and caches the gateway's M2M token through -the injected `ClientCredentialsTokenSource`. The remaining arms are `not_implemented` stubs that -each land in a follow-up PR with their seam. Pure v2: no imports from v1. +`TokenExchanger`, `client_credentials`, which mints and caches the gateway's M2M token through the +injected `ClientCredentialsTokenSource`, and `id_jag`, which runs the two-leg identity-assertion +grant against a subject token taken from the request or from the injected `SSOAssertionStore`. The +remaining arms are `not_implemented` stubs that each land in a follow-up PR with their seam. Pure +v2: no imports from v1. """ from __future__ import annotations import hashlib +from datetime import datetime, timezone from functools import partial import httpx from typing_extensions import assert_never +from litellm._logging import verbose_proxy_logger + from litellm.proxy._experimental.mcp_server.outbound_credentials.client_credentials import ( ClientCredentialsBearerAuth, ClientCredentialsTokenSource, @@ -41,6 +46,12 @@ from litellm.proxy._experimental.mcp_server.outbound_credentials.result import ( Ok, Result, ) +from litellm.proxy._experimental.mcp_server.outbound_credentials.sso_assertion_store import ( + AssertionStoreUnavailable, + DbSSOAssertionStore, + SSOAssertionStore, + SSOIdentityAssertion, +) from litellm.proxy._experimental.mcp_server.outbound_credentials.token_endpoint import ( ExchangedToken, ExchangedTokenCache, @@ -111,12 +122,14 @@ class UpstreamCredentialProvider: token_endpoint: TokenEndpointClient | None = None, exchanged_tokens: ExchangedTokenCache | None = None, client_credentials_source: ClientCredentialsTokenSource | None = None, + sso_assertion_store: SSOAssertionStore | None = None, ) -> None: self._oauth_token_store: OAuthTokenStore = oauth_token_store or _NullOAuthTokenStore() self._token_exchanger: TokenExchanger = token_exchanger or _NullTokenExchanger() self._token_endpoint: TokenEndpointClient = token_endpoint or TokenEndpointClient() self._exchanged_tokens: ExchangedTokenCache = exchanged_tokens or ExchangedTokenCache() self._client_credentials_source = client_credentials_source or ClientCredentialsTokenSource() + self._sso_assertion_store: SSOAssertionStore = sso_assertion_store or DbSSOAssertionStore() async def resolve_credentials(self, subject: Subject, server: ServerSpec) -> Result[httpx.Auth, CredError]: match server.config: @@ -171,15 +184,73 @@ class UpstreamCredentialProvider: assert_never(config.key_source) async def _id_jag(self, subject: Subject, server: ServerSpec, config: IdJagConfig) -> Result[httpx.Auth, CredError]: - if subject.inbound_token is None: + match await self._id_jag_subject_token(subject): + case Error(err): + return Error(err) + case Ok(subject_token): + return await self._id_jag_exchange(subject, subject_token, server, config) + + async def _id_jag_subject_token(self, subject: Subject) -> Result[str, CredError]: + """The identity token ID-JAG leg 1 asserts, from the request or from the SSO login it was captured at. + + A caller that presents its own IdP identity token wins: that is the strongest available + assertion of who is calling. Otherwise the subject is the assertion captured for this user + at LiteLLM SSO login, which is what lets an agent holding a brokered LiteLLM credential + reach an upstream as the user it was issued for. The user is always taken from the + authenticated principal, never from a caller-supplied field, so no caller can select whose + identity is asserted upstream. + + Every miss is ``precondition_required`` (412) rather than a fall-through to a weaker + credential: ID-JAG exists to assert a specific user, so a missing subject has no safe + substitute. A store outage is the one exception: it is ``upstream_unavailable`` (503), not + 412, because the user has nothing to fix by signing in again, and it is a value rather than + a raised error so a DB blip cannot 500 the egress or the upstream-401 retry. + """ + if subject.inbound_token is not None: + return Ok(subject.inbound_token.get_secret_value()) + if not subject.subject_id: return Error( CredError.of_precondition_required( - "ID-JAG requires a caller identity token; it asserts the calling " - "user's identity upstream and cannot use a static credential." + "ID-JAG requires an identified caller; this request carries neither an " + "identity token nor a resolved LiteLLM user." ) ) - token = subject.inbound_token.get_secret_value() - cache_key = _id_jag_cache_key(token, server.server_id, config) + try: + assertion = await self._sso_assertion_store.fetch(subject.subject_id) + except AssertionStoreUnavailable as exc: + # The driver's message can name hosts, schemas or connection details, and this summary + # is returned to the caller verbatim as a 503 body. Operators get it from the log. + verbose_proxy_logger.warning( + "ID-JAG: the IdP identity assertion store is unreachable for user_id=%s: %s", + subject.subject_id, + exc, + ) + return Error( + CredError.of_upstream_unavailable( + "The IdP identity assertion store is unreachable, so ID-JAG cannot resolve a subject." + ) + ) + if assertion is None: + return Error( + CredError.of_precondition_required( + "ID-JAG requires an IdP identity assertion for this user and none is stored. " + "Sign in through LiteLLM SSO so the gateway captures one." + ) + ) + if _assertion_expired(assertion, datetime.now(timezone.utc)): + return Error( + CredError.of_precondition_required( + "The stored IdP identity assertion for this user has expired. Sign in through " + "LiteLLM SSO again to capture a current one." + ) + ) + return Ok(assertion.id_token.get_secret_value()) + + async def _id_jag_exchange( + self, subject: Subject, token: str, server: ServerSpec, config: IdJagConfig + ) -> Result[httpx.Auth, CredError]: + slot = _id_jag_slot_key(subject, server) + fingerprint = _id_jag_fingerprint(token, server.server_id, config) async def _exchange() -> Result[ExchangedToken, CredError]: leg1_params = { @@ -211,7 +282,7 @@ class UpstreamCredentialProvider: config.client_auth, ) - match await self._exchanged_tokens.get_or_compute(cache_key, _exchange): + match await self._exchanged_tokens.get_or_compute(slot, _exchange, fingerprint=fingerprint): case Ok(access_token): return Ok(StaticHeaderAuth(f"Bearer {access_token}")) case Error(err): @@ -273,17 +344,27 @@ class UpstreamCredentialProvider: re-mintable cached credential here; `client_credentials` recovers inside its own auth flow (`ClientCredentialsBearerAuth` retries the 401'd request once with a fresh token), and other modes are a no-op. + + `id_jag` evicts by a slot key derived from the principal, so it needs no lookup against the + assertion store on this path; the fingerprint stored beside the entry is what keeps a slot + shared between callers safe. """ - if subject.inbound_token is None: - return - if isinstance(server.config, TokenExchangeConfig): + if isinstance(server.config, IdJagConfig): + self._invalidate_id_jag(subject, server) + elif isinstance(server.config, TokenExchangeConfig) and subject.inbound_token is not None: await self._token_exchanger.invalidate( subject.inbound_token.get_secret_value(), server, server.config, tenant_id=subject.tenant_id ) - if isinstance(server.config, IdJagConfig): - self._exchanged_tokens.invalidate( - _id_jag_cache_key(subject.inbound_token.get_secret_value(), server.server_id, server.config) - ) + + def _invalidate_id_jag(self, subject: Subject, server: ServerSpec) -> None: + """Evict the bearer this `(subject, server)` last resolved, without depending on the store. + + The slot is addressed by the principal (plus the caller's own token when it presented one), + never by the credential material, so it stays computable when the assertion store is down. + The fingerprint stored with the entry is what keeps that safe: an entry minted for different + inputs reads as a miss rather than being served. + """ + self._exchanged_tokens.invalidate(_id_jag_slot_key(subject, server)) async def _authz_token(self, subject: Subject, server: ServerSpec) -> OAuthToken | None: """The user's authorization_code token, or None when absent or the store is unreachable. @@ -297,8 +378,37 @@ class UpstreamCredentialProvider: return None -def _id_jag_cache_key(subject_token: str, server_id: str, config: IdJagConfig) -> str: - """Bind the cached leg-2 bearer to the caller token, the server, AND the config that minted it. +def _id_jag_slot_key(subject: Subject, server: ServerSpec) -> str: + """Which cache slot this caller's bearer for this upstream lives in. + + Addressed by the principal, plus the caller's own token when it presented one so two callers + sharing an empty principal do not contend for one slot. Deliberately free of the stored + assertion, which is what lets invalidation compute this while the assertion store is down. The + entry's fingerprint, not this key, is what guarantees a cached bearer matches current inputs. + """ + inbound = subject.inbound_token.get_secret_value() if subject.inbound_token is not None else "" + material = "\x00".join((subject.tenant_id, subject.subject_id, server.server_id, inbound)) + return hashlib.sha256(material.encode()).hexdigest() + + +def _assertion_expired(assertion: SSOIdentityAssertion, now: datetime) -> bool: + """Whether the stored assertion's ``exp`` has passed. An assertion carrying no expiry is + treated as usable and left for the IdP to reject, since the store records what the id_token + claimed rather than imposing a lifetime of its own. A naive ``expires_at`` is read as UTC so a + stored value that lost its offset compares instead of raising. + """ + expires_at = assertion.expires_at + if expires_at is None: + return False + normalized = expires_at if expires_at.tzinfo is not None else expires_at.replace(tzinfo=timezone.utc) + return normalized <= now + + +def _id_jag_fingerprint(subject_token: str, server_id: str, config: IdJagConfig) -> str: + """What the cached leg-2 bearer was minted from: the subject token, the server, and the config. + + Stored beside the bearer and compared on every read, so a rotated assertion or an edited server + config reads as a miss and re-mints instead of serving a bearer authorized under the old policy. Every exchange parameter derives from the config (endpoints, audience, resource, scopes, client auth), so a server update that changes any of them must change the key; otherwise the old bearer, diff --git a/litellm/proxy/_experimental/mcp_server/outbound_credentials/sso_assertion_store.py b/litellm/proxy/_experimental/mcp_server/outbound_credentials/sso_assertion_store.py index e0927cc4f64..d52c718c0b8 100644 --- a/litellm/proxy/_experimental/mcp_server/outbound_credentials/sso_assertion_store.py +++ b/litellm/proxy/_experimental/mcp_server/outbound_credentials/sso_assertion_store.py @@ -18,7 +18,7 @@ from __future__ import annotations import json from datetime import datetime, timezone -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Protocol import jwt from pydantic import BaseModel, ConfigDict, SecretStr, TypeAdapter, ValidationError @@ -160,6 +160,42 @@ async def fetch_sso_identity_assertion(user_id: str) -> SSOIdentityAssertion | N ) +class AssertionStoreUnavailable(Exception): + """Raised by ``fetch`` when the backing store is unreachable (e.g. the DB is down). + + Distinct from returning ``None`` for "this user has no captured assertion": an outage must not + read as a definite absence, which would tell the user to sign in again over a transient failure, + and it must not escape as an unhandled error on the egress or retry path. Mirrors + ``TokenStoreUnavailable`` on the sibling per-user OAuth store. + """ + + +class SSOAssertionStore(Protocol): + """The read seam the ``id_jag`` egress arm depends on, so the arm takes a collaborator + rather than reaching for a module-level function and a proxy global at call time. + + Returns the user's captured assertion, or ``None`` when they have never signed in. Raises + ``AssertionStoreUnavailable`` when the backing store is unreachable. + """ + + async def fetch(self, user_id: str) -> SSOIdentityAssertion | None: ... + + +class DbSSOAssertionStore: + """The live store: the row the SSO callback wrote, read back by ``user_id``. + + A storage failure is re-raised as ``AssertionStoreUnavailable`` so the resolver can map it to a + typed fail-closed result; letting the raw driver error escape would surface a DB blip as a 500 + from credential resolution and from the upstream-401 retry. + """ + + async def fetch(self, user_id: str) -> SSOIdentityAssertion | None: + try: + return await fetch_sso_identity_assertion(user_id) + except Exception as exc: # noqa: BLE001 # any driver/storage failure is an outage, not an absence + raise AssertionStoreUnavailable(str(exc)) from exc + + async def rotate_sso_identity_assertions_master_key(prisma_client: PrismaClient, new_master_key: str) -> None: """Re-encrypt every stored assertion under ``new_master_key`` during a salt-key rotation, mirroring the sibling per-user credential tables; an unreadable row is skipped so one diff --git a/litellm/proxy/_experimental/mcp_server/outbound_credentials/token_endpoint.py b/litellm/proxy/_experimental/mcp_server/outbound_credentials/token_endpoint.py index 4bc5732ec0e..3ed22732c90 100644 --- a/litellm/proxy/_experimental/mcp_server/outbound_credentials/token_endpoint.py +++ b/litellm/proxy/_experimental/mcp_server/outbound_credentials/token_endpoint.py @@ -23,7 +23,7 @@ from dataclasses import dataclass import httpx import jwt -from pydantic import BaseModel, ValidationError +from pydantic import BaseModel, TypeAdapter, ValidationError from typing_extensions import assert_never from litellm._logging import verbose_proxy_logger @@ -51,6 +51,9 @@ from litellm.proxy._experimental.mcp_server.outbound_credentials.types import ( ) from litellm.types.llms.custom_http import httpxSpecialProvider +# The cache stores (fingerprint, token); anything else in the slot is treated as absent. +_CACHED_ENTRY_ADAPTER: TypeAdapter[tuple[str, str]] = TypeAdapter(tuple[str, str]) + CLIENT_ASSERTION_TYPE = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" CLIENT_ASSERTION_LIFETIME_SECONDS = 60 @@ -134,19 +137,28 @@ class ExchangedTokenCache: self, cache_key: str, compute: Callable[[], Awaitable[Result[ExchangedToken, CredError]]], + *, + fingerprint: str = "", ) -> Result[str, CredError]: - cached = self._get(cache_key) + """The cached token for `cache_key`, minting one when absent. + + `fingerprint` lets a caller address a slot by something stable (a principal) while still + guaranteeing the token it gets back was minted for the *current* inputs: a stored entry + whose fingerprint differs reads as a miss and is re-minted over. That keeps eviction + addressable without the key having to encode the credential material it protects. + """ + cached = self._get(cache_key, fingerprint) if cached is not None: return Ok(cached) async with self._lock(cache_key): - cached = self._get(cache_key) + cached = self._get(cache_key, fingerprint) if cached is not None: return Ok(cached) match await compute(): case Ok(token): self._cache.set_cache( # pyright: ignore[reportUnknownMemberType] # InMemoryCache is untyped cache_key, - token.access_token, + (fingerprint, token.access_token), ttl=_cache_ttl_seconds(token.expires_in), ) return Ok(token.access_token) @@ -157,9 +169,18 @@ class ExchangedTokenCache: """Evict one cached token so the next `get_or_compute` re-mints (e.g. after an upstream 401).""" self._cache.delete_cache(cache_key) # pyright: ignore[reportUnknownMemberType] # InMemoryCache is untyped - def _get(self, cache_key: str) -> str | None: - value = self._cache.get_cache(cache_key) # pyright: ignore[reportUnknownMemberType,reportUnknownVariableType] # InMemoryCache is untyped; narrowed by isinstance below - return value if isinstance(value, str) else None + def _get(self, cache_key: str, fingerprint: str) -> str | None: + """The stored token, or None when absent or minted for different inputs. + + The fingerprint comparison is what makes a shared slot safe: a mismatch never returns the + other party's token, it just reads as a miss. + """ + value = self._cache.get_cache(cache_key) # pyright: ignore[reportUnknownMemberType,reportUnknownVariableType] # InMemoryCache is untyped; the adapter below is the type gate + try: + stored_fingerprint, token = _CACHED_ENTRY_ADAPTER.validate_python(value) + except ValidationError: + return None + return token if stored_fingerprint == fingerprint else None def _lock(self, cache_key: str) -> asyncio.Lock: lock = self._locks.get(cache_key) diff --git a/litellm/proxy/_experimental/mcp_server/outbound_credentials/types.py b/litellm/proxy/_experimental/mcp_server/outbound_credentials/types.py index 926d96c8868..f80954986e5 100644 --- a/litellm/proxy/_experimental/mcp_server/outbound_credentials/types.py +++ b/litellm/proxy/_experimental/mcp_server/outbound_credentials/types.py @@ -199,6 +199,7 @@ class ClientCredentialsConfig(BaseModel): token_url: str | None = None scopes: tuple[str, ...] = () audience: str | None = None + upstream_resource: str | None = None token_endpoint_auth_method: Literal["client_secret_post", "client_secret_basic"] | None = None @@ -390,7 +391,8 @@ class Subject(BaseModel): tenant_id: str subject_id: str - # Opaque, already-validated inbound identity. Only `token_exchange` / `passthrough` read it. + # Opaque, already-validated inbound identity. Read by `token_exchange`, `passthrough`, and + # `id_jag` (which falls back to the user's stored SSO assertion when it is absent). inbound_token: SecretStr | None = None diff --git a/litellm/proxy/_experimental/mcp_server/outbound_credentials/v2_token_store.py b/litellm/proxy/_experimental/mcp_server/outbound_credentials/v2_token_store.py index f1b68042c94..eefeec84bfa 100644 --- a/litellm/proxy/_experimental/mcp_server/outbound_credentials/v2_token_store.py +++ b/litellm/proxy/_experimental/mcp_server/outbound_credentials/v2_token_store.py @@ -10,14 +10,14 @@ injected, so the DB/decoding plumbing stays testable and out of this seam. from __future__ import annotations -from collections.abc import Awaitable, Callable +from collections.abc import Awaitable, Callable, Mapping from datetime import datetime, timezone from litellm.proxy._experimental.mcp_server.outbound_credentials.oauth_token_store import ( OAuthToken, ) -CredentialReader = Callable[[str, str], Awaitable["dict[str, object] | None"]] +CredentialReader = Callable[[str, str], Awaitable["Mapping[str, object] | None"]] def _iso_to_epoch(expires_at: str) -> float | None: @@ -39,7 +39,7 @@ def _to_scopes(raw: object) -> tuple[str, ...]: return () -def _to_oauth_token(payload: dict[str, object]) -> OAuthToken | None: +def _to_oauth_token(payload: Mapping[str, object]) -> OAuthToken | None: access_token = payload.get("access_token") if not isinstance(access_token, str): return None diff --git a/litellm/proxy/_experimental/mcp_server/rest_endpoints.py b/litellm/proxy/_experimental/mcp_server/rest_endpoints.py index 26e4176e09b..24d37f81787 100644 --- a/litellm/proxy/_experimental/mcp_server/rest_endpoints.py +++ b/litellm/proxy/_experimental/mcp_server/rest_endpoints.py @@ -1,24 +1,22 @@ import asyncio import importlib +from collections.abc import Awaitable, Callable, Mapping from datetime import datetime from typing import ( + TYPE_CHECKING, Any, - Awaitable, - Callable, - Dict, - List, Literal, - Mapping, - Optional, - Set, - Tuple, - Union, ) import httpx from fastapi import APIRouter, Depends, HTTPException, Query, Request, status from litellm._logging import verbose_logger +from litellm.exceptions import ( + BlockedPiiEntityError, + GuardrailRaisedException, + ModifyResponseException, +) from litellm.proxy._experimental.mcp_server.exceptions import ( MCPServerListError, MCPUpstreamAuthError, @@ -28,6 +26,7 @@ from litellm.proxy._experimental.mcp_server.faults.list_outcomes import ( list_fault_http_status, ) from litellm.proxy._experimental.mcp_server.ui_session_utils import ( + acting_user_auth, build_effective_auth_contexts, ) from litellm.proxy._experimental.mcp_server.utils import ( @@ -38,6 +37,11 @@ from litellm.proxy._experimental.mcp_server.utils import ( from litellm.proxy._types import LitellmUserRoles, UserAPIKeyAuth from litellm.proxy.auth.ip_address_utils import IPAddressUtils from litellm.proxy.auth.user_api_key_auth import user_api_key_auth + +if TYPE_CHECKING: + from mcp.types import CallToolResult + + from litellm.proxy._experimental.mcp_server.db import OAuthCredentialPayload from litellm.proxy.common_utils.http_parsing_utils import _safe_get_request_headers from litellm.types.mcp import MCPAuth from litellm.types.utils import CallTypes @@ -55,6 +59,13 @@ router = APIRouter( tags=["mcp"], ) +_MCP_GUARDRAIL_REJECTIONS = ( + BlockedPiiEntityError, + GuardrailRaisedException, + ModifyResponseException, + HTTPException, +) + def _connection_error_message(exc: BaseException) -> str: if isinstance(exc, httpx.LocalProtocolError): @@ -89,23 +100,31 @@ if MCP_AVAILABLE: MCPServer, _apply_toolset_scope, _fire_mcp_tool_call_logging, - _tool_name_matches, execute_mcp_tool, filter_tools_by_allowed_tools, + filter_tools_by_key_team_permissions, ) ######################################################## ############ MCP Server REST API Routes ################# async def _safe_fire_mcp_tool_call_logging( - logging_obj: Optional[Any], + logging_obj: Any | None, result: Any, start_time: datetime, end_time: datetime, - user_api_key_auth: Optional[UserAPIKeyAuth] = None, - request_data: Optional[Mapping[str, object]] = None, - ) -> None: + user_api_key_auth: UserAPIKeyAuth | None = None, + request_data: Mapping[str, object] | None = None, + ) -> "CallToolResult": + """Fire post-call logging, returning the tool result to send to the client. + + ``post_mcp_call`` guardrails already ran on ``execute_mcp_tool``'s return + path, so the result arriving here is the guardrailed one. A guardrail + rejection raised by a native ``async_post_mcp_tool_call_hook`` is still + re-raised rather than swallowed as a logging failure, which would return + the unguarded result. + """ if logging_obj is None: - return + return result logging_results = await asyncio.gather( _fire_mcp_tool_call_logging( logging_obj, @@ -117,11 +136,13 @@ if MCP_AVAILABLE: ), return_exceptions=True, ) - logging_error = logging_results[0] - if isinstance(logging_error, asyncio.CancelledError): - raise logging_error - if isinstance(logging_error, BaseException): - verbose_logger.warning("MCP tool call logging failed (continuing): %s", logging_error) + outcome = logging_results[0] + if isinstance(outcome, (asyncio.CancelledError, *_MCP_GUARDRAIL_REJECTIONS)): + raise outcome + if isinstance(outcome, BaseException): + verbose_logger.warning("MCP tool call logging failed (continuing): %s", outcome) + return result + return outcome def _relay_upstream_auth_http_exception(e: MCPUpstreamAuthError, request: Request) -> HTTPException: """Convert a client-forwarded pass-through upstream 401 into an HTTPException that preserves the @@ -134,7 +155,7 @@ if MCP_AVAILABLE: async def _handle_virtual_mcp_tool( request: Request, - data: Dict[str, Any], + data: dict[str, Any], tool_name: str, user_api_key_dict: UserAPIKeyAuth, ) -> Any: @@ -200,7 +221,7 @@ if MCP_AVAILABLE: raw_headers=virtual_raw_headers, litellm_logging_obj=virtual_logging_obj, ) - await _safe_fire_mcp_tool_call_logging( + return await _safe_fire_mcp_tool_call_logging( virtual_logging_obj, result, _tool_start_time, @@ -208,13 +229,12 @@ if MCP_AVAILABLE: user_api_key_auth=user_api_key_dict, request_data=data, ) - return result def _get_server_auth_header( server, - mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]], - mcp_auth_header: Optional[str], - ) -> Optional[Union[Dict[str, str], str]]: + mcp_server_auth_headers: dict[str, dict[str, str]] | None, + mcp_auth_header: str | None, + ) -> dict[str, str] | str | None: """Helper function to get server-specific auth header with case-insensitive matching.""" from litellm.proxy._experimental.mcp_server.utils import ( lookup_mcp_server_auth_in_headers, @@ -230,7 +250,7 @@ if MCP_AVAILABLE: return server_auth return mcp_auth_header - def _is_v1_resolved_oauth2_server(server: Optional[MCPServer]) -> bool: + def _is_v1_resolved_oauth2_server(server: MCPServer | None) -> bool: """Whether this server's per-user OAuth2 token is still resolved by v1. A server the v2 resolver owns reads its stored token from the resolver at connect @@ -246,7 +266,7 @@ if MCP_AVAILABLE: return False return to_server_spec(server) is None - def _v1_resolved_oauth2_server_ids(allowed_server_ids: List[str]) -> Set[str]: + def _v1_resolved_oauth2_server_ids(allowed_server_ids: list[str]) -> set[str]: """Return the subset of *allowed_server_ids* whose per-user OAuth2 token is still resolved by v1. @@ -260,10 +280,10 @@ if MCP_AVAILABLE: } async def _get_user_oauth_extra_headers( - server, + server: MCPServer, user_api_key_dict: UserAPIKeyAuth, - prefetched_creds: Optional[Dict[str, Dict[str, Any]]] = None, - ) -> Optional[Dict[str, str]]: + prefetched_creds: dict[str, "OAuthCredentialPayload"] | None = None, + ) -> dict[str, str] | None: """ For OAuth2 servers, look up the user's stored access token and return it as extra_headers {"Authorization": "Bearer "} so that it reaches @@ -315,7 +335,7 @@ if MCP_AVAILABLE: async def _prefetch_user_oauth_creds( user_api_key_dict: UserAPIKeyAuth, - ) -> Dict[str, Dict[str, Any]]: + ) -> dict[str, "OAuthCredentialPayload"]: """Fetch all OAuth2 credentials for the user in a single DB query. Returns a dict keyed by server_id. Used to avoid N+1 DB queries when @@ -379,8 +399,8 @@ if MCP_AVAILABLE: def _resolve_mcp_server_id_for_rest( server_id: str, - allowed_server_ids: Union[Set[str], List[str]], - client_ip: Optional[str] = None, + allowed_server_ids: set[str] | list[str], + client_ip: str | None = None, ) -> str: """ Map REST ``server_id`` (UUID, server_name, or alias) to canonical server_id. @@ -400,7 +420,7 @@ if MCP_AVAILABLE: request: Request, user_api_key_dict: UserAPIKeyAuth, server_id: str, - ) -> Tuple[List[MCPServer], str]: + ) -> tuple[list[MCPServer], str]: """ Resolve allowed MCP servers for a tool call with IP filtering. @@ -471,7 +491,7 @@ if MCP_AVAILABLE: ) # Build allowed_mcp_servers list (only include allowed servers) - allowed_mcp_servers: List[MCPServer] = [] + allowed_mcp_servers: list[MCPServer] = [] for allowed_server_id in allowed_server_ids_set: server = global_mcp_server_manager.get_mcp_server_by_id(allowed_server_id) if server is not None: @@ -482,9 +502,9 @@ if MCP_AVAILABLE: async def _get_tools_for_single_server( server, server_auth_header, - raw_headers: Optional[Dict[str, str]] = None, - user_api_key_auth: Optional[UserAPIKeyAuth] = None, - extra_headers: Optional[Dict[str, str]] = None, + raw_headers: dict[str, str] | None = None, + user_api_key_auth: UserAPIKeyAuth | None = None, + extra_headers: dict[str, str] | None = None, apply_tool_filters: bool = True, ): """Helper function to get tools for a single server. @@ -511,26 +531,24 @@ if MCP_AVAILABLE: tools = filter_tools_by_allowed_tools(tools, server) # Filter by the key's effective tool permissions through the same - # primitive the MCP protocol path uses (direct grants, toolset grants, - # and team/agent/org ceilings), so REST listing cannot drift from it + # function the MCP protocol path uses (direct grants, toolset grants, + # and team/agent/org ceilings), so REST listing cannot drift from it. + # Entries here are tool names on one server, written bare by every + # writer, and dispatch compares them bare; matching a wider set of + # spellings would advertise a tool that tools/call then refuses if user_api_key_auth: - from litellm.proxy._experimental.mcp_server.auth.user_api_key_auth_mcp import ( - MCPRequestHandler, - ) - - allowed_tools_for_server = await MCPRequestHandler.get_allowed_tools_for_server( + tools = await filter_tools_by_key_team_permissions( + tools=tools, server_id=server.server_id, user_api_key_auth=user_api_key_auth, ) - if allowed_tools_for_server is not None: - tools = [tool for tool in tools if _tool_name_matches(tool.name, allowed_tools_for_server)] return _create_tool_response_objects(tools, server) async def _resolve_allowed_mcp_servers_for_tool_call( user_api_key_dict: UserAPIKeyAuth, server_id: str, - ) -> List[MCPServer]: + ) -> list[MCPServer]: """Resolve allowed MCP servers for the given user and validate server_id access.""" auth_contexts = await build_effective_auth_contexts(user_api_key_dict) allowed_server_ids_set = set() @@ -545,7 +563,7 @@ if MCP_AVAILABLE: "message": f"The key is not allowed to access server {server_id}", }, ) - allowed_mcp_servers: List[MCPServer] = [] + allowed_mcp_servers: list[MCPServer] = [] for allowed_server_id in allowed_server_ids_set: server = global_mcp_server_manager.get_mcp_server_by_id(allowed_server_id) if server is not None: @@ -554,10 +572,10 @@ if MCP_AVAILABLE: async def _list_tools_for_single_server( server_id: str, - allowed_server_ids: List[str], - rest_client_ip: Optional[str], + allowed_server_ids: list[str], + rest_client_ip: str | None, mcp_server_auth_headers: dict, - mcp_auth_header: Optional[str], + mcp_auth_header: str | None, raw_headers_from_request: dict, user_api_key_dict: UserAPIKeyAuth, apply_tool_filters: bool = True, @@ -644,17 +662,23 @@ if MCP_AVAILABLE: "message": "Successfully retrieved tools", } - def _as_query_str(value: Any) -> Optional[str]: + def _as_query_str(value: Any) -> str | None: """Coerce an Optional[str] Query param to str|None, dropping unresolved FastAPI defaults.""" return value if isinstance(value, str) else None - async def _resolve_toolset_scope( - toolset_name: Optional[str], + async def _resolve_acting_auth( + toolset_name: str | None, user_api_key_dict: UserAPIKeyAuth, ) -> UserAPIKeyAuth: - """Resolve ``toolset_name`` to its scoped ``UserAPIKeyAuth``, or return unchanged.""" + """The one credential this tools request acts as. + + A toolset name narrows the caller's own credential to that toolset; otherwise a dashboard + session is swapped for its admitted subject. The two are mutually exclusive by construction, + which is why they share an owner: the admitted subject resolves per grant source and a team + source deliberately carries none of the caller's ``object_permission``, so a toolset + narrowing layered on top would evaporate on every team-granted server.""" if not toolset_name: - return user_api_key_dict + return await acting_user_auth(user_api_key_dict) from litellm.proxy.utils import get_prisma_client_or_throw @@ -670,11 +694,9 @@ if MCP_AVAILABLE: @router.get("/tools/list", dependencies=[Depends(user_api_key_auth)]) async def list_tool_rest_api( request: Request, - server_id: Optional[str] = Query(None, description="The server id to list tools for"), - mcp_server_name: Optional[str] = Query( - None, description="Filter tools to a single MCP server by name or alias" - ), - toolset_name: Optional[str] = Query(None, description="Filter tools to a single toolset by name"), + server_id: str | None = Query(None, description="The server id to list tools for"), + mcp_server_name: str | None = Query(None, description="Filter tools to a single MCP server by name or alias"), + toolset_name: str | None = Query(None, description="Filter tools to a single toolset by name"), include_disabled_tools: bool = Query( False, description=( @@ -714,6 +736,7 @@ if MCP_AVAILABLE: try: mcp_server_name = _as_query_str(mcp_server_name) toolset_name = _as_query_str(toolset_name) + user_api_key_dict = await _resolve_acting_auth(toolset_name, user_api_key_dict) # The full catalog (allowlist filter skipped) is admin-only so the # REST endpoint can't be used to enumerate deliberately-disabled tools. @@ -721,8 +744,6 @@ if MCP_AVAILABLE: include_disabled_tools and user_api_key_dict.user_role == LitellmUserRoles.PROXY_ADMIN ) - user_api_key_dict = await _resolve_toolset_scope(toolset_name, user_api_key_dict) - if server_id is None: server_id = mcp_server_name @@ -911,6 +932,7 @@ if MCP_AVAILABLE: ) try: + user_api_key_dict = await acting_user_auth(user_api_key_dict) data = await request.json() tool_name = data.get("name") @@ -981,7 +1003,7 @@ if MCP_AVAILABLE: ) = await _resolve_allowed_mcp_servers_with_ip_filter(request, user_api_key_dict, server_id) # Look up per-user OAuth headers for this server (mirrors list_tool_rest_api). - user_oauth_extra_headers: Optional[Dict[str, str]] = None + user_oauth_extra_headers: dict[str, str] | None = None target_server = next( (s for s in allowed_mcp_servers if s.server_id == canonical_server_id), None, @@ -1004,7 +1026,7 @@ if MCP_AVAILABLE: litellm_logging_obj=data.get("litellm_logging_obj"), requested_server_id=canonical_server_id, ) - await _safe_fire_mcp_tool_call_logging( + return await _safe_fire_mcp_tool_call_logging( logging_obj, result, _tool_start_time, @@ -1012,7 +1034,6 @@ if MCP_AVAILABLE: user_api_key_auth=user_api_key_dict, request_data=data, ) - return result except MCPMissingUserEnvVarsError as e: verbose_logger.info( "MCP tool call missing per-user env vars: server_id=%s missing=%s", @@ -1094,18 +1115,18 @@ if MCP_AVAILABLE: (client_id, client_secret, scopes) — any value may be ``None``. """ creds = request.credentials if isinstance(request.credentials, dict) else {} - client_id: Optional[str] = creds.get("client_id") - client_secret: Optional[str] = creds.get("client_secret") + client_id: str | None = creds.get("client_id") + client_secret: str | None = creds.get("client_secret") scopes_raw = creds.get("scopes") - scopes: Optional[List[str]] = scopes_raw if isinstance(scopes_raw, list) else None + scopes: list[str] | None = scopes_raw if isinstance(scopes_raw, list) else None return client_id, client_secret, scopes async def _execute_with_mcp_client( request: NewMCPServerRequest, operation: Callable[..., Awaitable[Any]], - mcp_auth_header: Optional[Union[str, Dict[str, str]]] = None, - oauth2_headers: Optional[Dict[str, str]] = None, - raw_headers: Optional[Dict[str, str]] = None, + mcp_auth_header: str | dict[str, str] | None = None, + oauth2_headers: dict[str, str] | None = None, + raw_headers: dict[str, str] | None = None, ) -> dict: """ Create a temporary MCP client from *request*, run *operation*, and return the result. @@ -1128,7 +1149,7 @@ if MCP_AVAILABLE: try: client_id, client_secret, scopes = _extract_credentials(request) - _oauth2_flow: Optional[Literal["client_credentials", "authorization_code"]] = request.oauth2_flow or ( + _oauth2_flow: Literal["client_credentials", "authorization_code"] | None = request.oauth2_flow or ( "client_credentials" if client_id and client_secret and request.token_url else None ) # client_credentials requires token_url to fetch a token; without it the @@ -1244,7 +1265,7 @@ if MCP_AVAILABLE: spec = await load_openapi_spec_async(spec_path) paths = spec.get("paths", {}) components = spec.get("components", {}) - tools: List[dict] = [] + tools: list[dict] = [] used_names: set = set() for path, path_item in paths.items(): for method in ("get", "post", "put", "delete", "patch"): @@ -1351,7 +1372,7 @@ if MCP_AVAILABLE: headers = request.headers - mcp_auth_header: Optional[str] = None + mcp_auth_header: str | None = None if new_mcp_server_request.auth_type in { MCPAuth.api_key, MCPAuth.bearer_token, @@ -1365,7 +1386,7 @@ if MCP_AVAILABLE: # Authorization doubles as the admission fallback (LITELLM_API_KEY_HEADER_NAME_SECONDARY): # when the primary x-litellm-api-key header is absent, the Authorization value is the # caller's LiteLLM key, not an upstream token, and must never be forwarded upstream. - oauth2_headers: Optional[Dict[str, str]] = None + oauth2_headers: dict[str, str] | None = None if new_mcp_server_request.auth_type in _UPSTREAM_OAUTH_DISCOVERY_AUTH_TYPES and headers.get( MCPRequestHandler.LITELLM_API_KEY_HEADER_NAME_PRIMARY ): @@ -1376,8 +1397,8 @@ if MCP_AVAILABLE: return await session.list_tools() list_tools_response = await client.run_with_session(_list_tools_session_operation) - list_tools_result: List[MCPTool] = list_tools_response.tools - model_dumped_tools: List[dict] = [tool.model_dump() for tool in list_tools_result] + list_tools_result: list[MCPTool] = list_tools_response.tools + model_dumped_tools: list[dict] = [tool.model_dump() for tool in list_tools_result] return { "tools": model_dumped_tools, "error": None, diff --git a/litellm/proxy/_experimental/mcp_server/server.py b/litellm/proxy/_experimental/mcp_server/server.py index 4fca4406a6f..d8431b9b3bb 100644 --- a/litellm/proxy/_experimental/mcp_server/server.py +++ b/litellm/proxy/_experimental/mcp_server/server.py @@ -13,18 +13,11 @@ import time import traceback import types import uuid +from collections.abc import AsyncIterator, Callable, Mapping from datetime import datetime from typing import ( + TYPE_CHECKING, Any, - AsyncIterator, - Callable, - Dict, - List, - Mapping, - Optional, - Set, - Tuple, - Union, cast, ) @@ -44,6 +37,7 @@ from litellm.llms.custom_httpx.http_handler import ( ) from litellm.proxy._experimental.mcp_server.auth.user_api_key_auth_mcp import ( MCPRequestHandler, + _is_mcp_admitted_user_subject, ) from litellm.proxy._experimental.mcp_server.discoverable_endpoints import ( get_request_base_url, @@ -60,6 +54,7 @@ from litellm.proxy._experimental.mcp_server.mcp_context import ( from litellm.proxy._experimental.mcp_server.mcp_debug import MCPDebug from litellm.proxy._experimental.mcp_server.oauth_utils import ( _redact_mcp_resource_url, + get_passthrough_www_authenticate, ) from litellm.proxy._experimental.mcp_server.utils import ( LITELLM_MCP_SERVER_DESCRIPTION, @@ -70,6 +65,7 @@ from litellm.proxy._experimental.mcp_server.utils import ( extract_mcp_tool_result_error_message, get_server_prefix, iter_known_server_prefixes, + match_known_tool_name, ) from litellm.proxy._types import ( ProxyException, @@ -86,11 +82,14 @@ from litellm.types.mcp_server.mcp_server_manager import MCPInfo, MCPServer from litellm.types.utils import CallTypes, StandardLoggingMCPToolCall from litellm.utils import Rules, client, function_setup +if TYPE_CHECKING: + from litellm.proxy._experimental.mcp_server.db import OAuthCredentialPayload + # Short-lived in-memory cache for BYOK credentials. # Keyed by (user_id, server_id); value is (credential_or_None, monotonic_timestamp). # Storing the credential value (not just a bool) means _get_byok_credential and # _check_byok_credential share a single DB round-trip per TTL window. -_byok_cred_cache: Dict[Tuple[str, str], Tuple[Optional[str], float]] = {} +_byok_cred_cache: dict[tuple[str, str], tuple[str | None, float]] = {} _BYOK_CRED_CACHE_TTL = 60 # seconds _BYOK_CRED_CACHE_MAX_SIZE = 4096 # cap to prevent unbounded growth _STATEFUL_SESSION_IDLE_TIMEOUT_SECONDS = 30 * 60 @@ -106,6 +105,9 @@ _MAX_STATEFUL_SESSIONS_PER_OWNER = 100 # prevents an authenticated client from forcing the proxy to buffer an # arbitrarily large body just to make a routing decision. _MCP_ROUTING_PEEK_MAX_BYTES = 4096 +# ASGI scope key holding the tracing span of the request carrying an MCP +# message, written on the request task and read back by the message handler. +_MCP_TRANSPORT_SPAN_SCOPE_KEY = "litellm_otel_transport_span" def _invalidate_byok_cred_cache(user_id: str, server_id: str) -> None: @@ -117,7 +119,7 @@ def _invalidate_byok_cred_cache(user_id: str, server_id: str) -> None: _byok_cred_cache.pop((user_id, server_id), None) -def _write_byok_cred_cache(user_id: str, server_id: str, credential: Optional[str]) -> None: +def _write_byok_cred_cache(user_id: str, server_id: str, credential: str | None) -> None: """Write a credential value to the cache, evicting all entries if at capacity.""" if len(_byok_cred_cache) >= _BYOK_CRED_CACHE_MAX_SIZE: _byok_cred_cache.clear() @@ -147,7 +149,7 @@ try: # Robust auth lookup keyed by session_object. _session_obj_auth_storage: "weakref.WeakKeyDictionary[Any, MCPAuthenticatedUser]" = weakref.WeakKeyDictionary() - active_mcp_session_var: contextvars.ContextVar[Optional[_McpServerSession]] = contextvars.ContextVar( + active_mcp_session_var: contextvars.ContextVar[_McpServerSession | None] = contextvars.ContextVar( "active_mcp_session", default=None ) except ImportError as e: @@ -172,8 +174,8 @@ _INITIALIZATION_LOCK = asyncio.Lock() def _mcp_session_id_from_headers( - raw_headers: Optional[Dict[str, str]], -) -> Optional[str]: + raw_headers: dict[str, str] | None, +) -> str | None: """The ``mcp-session-id`` of a stateful MCP session, read case-insensitively from the request headers. ``None`` for stateless calls (no such header).""" if not raw_headers: @@ -198,10 +200,10 @@ def _jsonrpc_text_has_top_level_method(text: str) -> bool: depth = 0 in_string = False escaped = False - in_object: List[bool] = [] + in_object: list[bool] = [] reading_key = False expect_key = False - key_chars: List[str] = [] + key_chars: list[str] = [] for ch in text: if in_string: if escaped: @@ -238,14 +240,16 @@ def _jsonrpc_text_has_top_level_method(text: str) -> bool: return False -def _mcp_meta_trace_carrier(req_ctx: object) -> Optional[dict[str, str]]: +def _mcp_meta_trace_carrier(req_ctx: object) -> dict[str, str] | None: """The W3C trace context (``traceparent``/``tracestate``) the MCP client propagated in the request's ``params._meta`` (SEP-414), or ``None``. - Per the OTel MCP semconv the MCP span parents to this propagated context rather - than to the HTTP/session transport (which is recorded as a link instead), so a - streamable-HTTP session that multiplexes many messages does not glue every - message under the session's first request. The client's W3C Baggage is + When present, per the OTel MCP semconv the MCP span parents to this propagated + context rather than to the HTTP transport (which is recorded as a link instead). + When absent, the span nests under the transport span of the request carrying + this specific message, so a streamable-HTTP session that multiplexes many + messages still does not glue every message under the session's first request; + see ``resolve_mcp_span_context``. The client's W3C Baggage is deliberately excluded: it is caller-controlled, and the otel baggage processor stamps allowlisted baggage keys (``litellm.team.id``, ``litellm.metadata.*``, ...) onto the span, so honoring remote baggage would let a client spoof a @@ -259,7 +263,7 @@ def _mcp_meta_trace_carrier(req_ctx: object) -> Optional[dict[str, str]]: return carrier or None -def _otel_set_mcp_trace_carrier(carrier: Optional[dict[str, str]]) -> object: +def _otel_set_mcp_trace_carrier(carrier: dict[str, str] | None) -> object: """Stash ``carrier`` for the otel_v2 MCP span and return a reset token, or ``None`` when otel_v2 is unavailable. Lazily imported so opentelemetry stays an optional dependency.""" @@ -288,6 +292,82 @@ def _otel_reset_mcp_trace_carrier(token: object) -> None: return +def _otel_publish_transport_span_on_scope(scope: Scope) -> None: + """Record this request's tracing span on its own ASGI scope. + + Resolved on the ASGI request task, where the proxy's server span is anchored, + and read back by the MCP message handler through ``req_ctx.request`` — the + ``Request`` the transport attaches to each message. A stateful streamable-HTTP + session handles every message on the task spawned by its ``initialize`` POST, so + the handler's own task cannot see later requests' spans. + + The scope, not the shared session auth context: a JSON-RPC *response* POST + deliberately skips the per-session lock (it can arrive while the tool call that + awaits it is still in flight), so a field on that shared object would be + overwritten mid-call and the tool call would attribute itself to the response's + request. A scope belongs to exactly one request and dies with it, which also + keeps a finished span from being retained by an idle session. + + The live span, not just its context: a failed tool call stamps ``error.*`` on it, + which needs a span still open for writes. Lazily imported so opentelemetry stays + an optional dependency; a no-op when otel_v2 is unavailable or no request span is + anchored.""" + try: + from litellm.integrations.otel.plumbing.context import ( + request_root_span, + ) + + span = request_root_span() + except ImportError: + return + if span is not None: + scope[_MCP_TRANSPORT_SPAN_SCOPE_KEY] = span + + +def _otel_transport_span_from_message(req_ctx: object) -> object: + """The tracing span of the HTTP request that carried this MCP message. + + Read off that request's ASGI scope, reached through the ``Request`` the + streamable-HTTP transport attaches to each message, so it is this message's + transport and not whichever request happens to have touched the session last. + Returns whatever the scope holds; the otel plumbing validates it.""" + request = getattr(req_ctx, "request", None) + scope = getattr(request, "scope", None) + if not isinstance(scope, Mapping): + return None + return scope.get(_MCP_TRANSPORT_SPAN_SCOPE_KEY) + + +def _otel_set_mcp_transport_span(span: object) -> object: + """Publish the current message's transport span, which the otel_v2 MCP span + attaches to and a failed tool call stamps its error on. Returns a reset token, + or ``None`` when otel_v2 is unavailable.""" + if span is None: + return None + try: + from litellm.integrations.otel.plumbing.context import ( + set_mcp_message_transport_span, + ) + + return set_mcp_message_transport_span(span) + except ImportError: + return None + + +def _otel_reset_mcp_transport_span(token: object) -> None: + """Paired with ``_otel_set_mcp_transport_span``.""" + if token is None: + return + try: + from litellm.integrations.otel.plumbing.context import ( + reset_mcp_message_transport_span, + ) + + reset_mcp_message_transport_span(token) + except ImportError: + return + + def _proxy_exception_to_http_exception(exc: ProxyException) -> HTTPException: """Map a ``ProxyException`` to an ``HTTPException`` that preserves its real status code and headers. @@ -381,12 +461,12 @@ if MCP_AVAILABLE: Object returned by the /tools/list REST API route. """ - mcp_info: Optional[MCPInfo] = None + mcp_info: MCPInfo | None = None model_config = ConfigDict(arbitrary_types_allowed=True) - def _normalize_resource_contents(contents: list) -> List[ReadResourceContents]: + def _normalize_resource_contents(contents: list) -> list[ReadResourceContents]: """Normalize ResourceContents to ReadResourceContents, preserving meta (MCP 1.26.0+).""" - normalized: List[ReadResourceContents] = [] + normalized: list[ReadResourceContents] = [] for content in contents: meta = getattr(content, "meta", None) if meta is None and hasattr(content, "model_dump"): @@ -414,15 +494,15 @@ if MCP_AVAILABLE: def _gateway_create_initialization_options( self, - notification_options: Optional[NotificationOptions] = None, - experimental_capabilities: Optional[Dict[str, Dict[str, Any]]] = None, + notification_options: NotificationOptions | None = None, + experimental_capabilities: dict[str, dict[str, Any]] | None = None, ) -> InitializationOptions: opts = Server.create_initialization_options( self, notification_options=notification_options, experimental_capabilities=experimental_capabilities or {}, ) - updates: Dict[str, Any] = {} + updates: dict[str, Any] = {} merged = _mcp_gateway_initialize_instructions.get() if merged is not None: updates["instructions"] = merged @@ -457,21 +537,21 @@ if MCP_AVAILABLE: json_response=False, # enables SSE streaming stateless=False, ) - _stateful_session_auth_contexts: Dict[str, MCPAuthenticatedUser] = {} - _stateful_session_auth_context_last_seen: Dict[str, float] = {} + _stateful_session_auth_contexts: dict[str, MCPAuthenticatedUser] = {} + _stateful_session_auth_context_last_seen: dict[str, float] = {} # Maps session_id -> owner identifier (hashed API key/token) so we can # reject requests that supply a session_id created by a different caller. # Without this, a leaked mcp-session-id could be driven (or terminated) # by any other authenticated proxy user. - _stateful_session_owners: Dict[str, str] = {} + _stateful_session_owners: dict[str, str] = {} # Per-session lock that serializes ``handle_request`` for the same # mcp-session-id. The stored ``MCPAuthenticatedUser`` is mutated in place # by ``_update_auth_context`` each request; without this lock, two # concurrent requests on the same session would clobber each other's # auth headers / mcp_servers / oauth state while in-flight callbacks are # still reading the shared object. - _stateful_session_locks: Dict[str, asyncio.Lock] = {} - _stateful_session_active_request_counts: Dict[str, int] = {} + _stateful_session_locks: dict[str, asyncio.Lock] = {} + _stateful_session_active_request_counts: dict[str, int] = {} def _remove_stateful_session_tracking(session_id: str) -> None: _stateful_session_auth_contexts.pop(session_id, None) @@ -495,10 +575,10 @@ if MCP_AVAILABLE: _session_manager_cm = None _session_manager_stateful_cm = None _sse_session_manager_cm = None - _stateful_auth_context_cleanup_task: Optional[asyncio.Task] = None + _stateful_auth_context_cleanup_task: asyncio.Task | None = None async def _purge_expired_stateful_session_auth_contexts( - now: Optional[float] = None, + now: float | None = None, ) -> None: """Terminate expired stateful sessions and drop their auth contexts.""" now = time.monotonic() if now is None else now @@ -545,7 +625,7 @@ if MCP_AVAILABLE: """ server_instances = getattr(session_manager_stateful, "_server_instances", {}) - def _owned_live_session_ids() -> List[str]: + def _owned_live_session_ids() -> list[str]: return [ session_id for session_id, session_owner in _stateful_session_owners.items() @@ -655,7 +735,7 @@ if MCP_AVAILABLE: ######################################################## @server.list_tools() - async def handle_list_tools() -> "ListToolsResult | List[Tool]": + async def handle_list_tools() -> "ListToolsResult | list[Tool]": """ List all available tools, with each server's listing outcome attached to the result's ``_meta`` (SERVER_OUTCOMES_META_KEY) so a broken upstream is distinguishable from a healthy @@ -670,9 +750,11 @@ if MCP_AVAILABLE: if req_ctx: _session_reset_token = active_mcp_session_var.set(req_ctx.session) _trace_token = None + _transport_token = None try: _trace_token = _otel_set_mcp_trace_carrier(_mcp_meta_trace_carrier(req_ctx)) + _transport_token = _otel_set_mcp_transport_span(_otel_transport_span_from_message(req_ctx)) # Get user authentication from context variable ( user_api_key_auth, @@ -728,11 +810,12 @@ if MCP_AVAILABLE: # This prevents the HTTP stream from failing and allows the client to get a response return [] finally: + _otel_reset_mcp_transport_span(_transport_token) _otel_reset_mcp_trace_carrier(_trace_token) if _session_reset_token is not None: active_mcp_session_var.reset(_session_reset_token) - def _capture_host_progress_callback(host_server) -> Optional[Callable]: + def _capture_host_progress_callback(host_server) -> Callable | None: """Return a progress-forwarding callback bound to the host MCP session. Returns ``None`` when the host did not supply a progress token. @@ -750,7 +833,7 @@ if MCP_AVAILABLE: return None host_session = host_ctx.session - async def forward_progress(progress: float, total: Optional[float]): + async def forward_progress(progress: float, total: float | None): """Forward progress notifications from external MCP to Host""" try: await host_session.send_progress_notification( @@ -769,7 +852,7 @@ if MCP_AVAILABLE: name: str, arguments: dict[str, Any], user_api_key_auth: UserAPIKeyAuth, - ) -> Optional[LiteLLMLoggingObj]: + ) -> LiteLLMLoggingObj | None: """Run the pre-call pipeline (guardrails + logging setup) for a virtual mcp_tool_call so the SSE path spend-logs like the REST path.""" from fastapi import Request @@ -805,15 +888,15 @@ if MCP_AVAILABLE: async def _dispatch_virtual_mcp_tool( name: str, - arguments: Optional[dict[str, Any]], - user_api_key_auth: Optional[UserAPIKeyAuth], - client_ip: Optional[str], - mcp_servers: Optional[list[str]] = None, - mcp_auth_header: Optional[str] = None, - mcp_server_auth_headers: Optional[dict[str, dict[str, str]]] = None, - oauth2_headers: Optional[dict[str, str]] = None, - raw_headers: Optional[dict[str, str]] = None, - ) -> Optional[CallToolResult]: + arguments: dict[str, Any] | None, + user_api_key_auth: UserAPIKeyAuth | None, + client_ip: str | None, + mcp_servers: list[str] | None = None, + mcp_auth_header: str | None = None, + mcp_server_auth_headers: dict[str, dict[str, str]] | None = None, + oauth2_headers: dict[str, str] | None = None, + raw_headers: dict[str, str] | None = None, + ) -> CallToolResult | None: """Handle the mcp_tool_search / mcp_tool_call virtual tools. Returns a CallToolResult when ``name`` is a virtual tool, else ``None`` so @@ -877,7 +960,7 @@ if MCP_AVAILABLE: ) @server.call_tool() - async def mcp_server_tool_call(name: str, arguments: Dict[str, Any] | None) -> CallToolResult: + async def mcp_server_tool_call(name: str, arguments: dict[str, Any] | None) -> CallToolResult: """ Call a specific tool with the provided arguments Args: @@ -901,9 +984,11 @@ if MCP_AVAILABLE: if req_ctx: _session_reset_token = active_mcp_session_var.set(req_ctx.session) _trace_token = None + _transport_token = None try: _trace_token = _otel_set_mcp_trace_carrier(_mcp_meta_trace_carrier(req_ctx)) + _transport_token = _otel_set_mcp_transport_span(_otel_transport_span_from_message(req_ctx)) # Validate arguments ( user_api_key_auth, @@ -1042,12 +1127,13 @@ if MCP_AVAILABLE: return response finally: + _otel_reset_mcp_transport_span(_transport_token) _otel_reset_mcp_trace_carrier(_trace_token) if _session_reset_token is not None: active_mcp_session_var.reset(_session_reset_token) @server.list_prompts() - async def list_prompts() -> List[Prompt]: + async def list_prompts() -> list[Prompt]: """ List all available prompts """ @@ -1096,7 +1182,7 @@ if MCP_AVAILABLE: active_mcp_session_var.reset(_session_reset_token) @server.get_prompt() - async def get_prompt(name: str, arguments: Optional[Dict[str, str]]) -> GetPromptResult: + async def get_prompt(name: str, arguments: dict[str, str] | None) -> GetPromptResult: """ Get a specific prompt with the provided arguments @@ -1143,7 +1229,7 @@ if MCP_AVAILABLE: active_mcp_session_var.reset(_session_reset_token) @server.list_resources() - async def list_resources() -> List[Resource]: + async def list_resources() -> list[Resource]: """List all available resources.""" from mcp.server.lowlevel.server import request_ctx @@ -1186,7 +1272,7 @@ if MCP_AVAILABLE: active_mcp_session_var.reset(_session_reset_token) @server.list_resource_templates() - async def list_resource_templates() -> List[ResourceTemplate]: + async def list_resource_templates() -> list[ResourceTemplate]: """List all available resource templates.""" from mcp.server.lowlevel.server import request_ctx @@ -1274,9 +1360,9 @@ if MCP_AVAILABLE: ######################################################## async def _get_allowed_mcp_servers_from_mcp_server_names( - mcp_servers: Optional[List[str]], - allowed_mcp_servers: List[MCPServer], - ) -> List[MCPServer]: + mcp_servers: list[str] | None, + allowed_mcp_servers: list[MCPServer], + ) -> list[MCPServer]: """ Get the filtered MCP servers from the MCP server names. @@ -1331,39 +1417,22 @@ if MCP_AVAILABLE: return allowed_mcp_servers - def _tool_name_matches(tool_name: str, filter_list: List[str]) -> bool: + def _tool_name_matches(tool_name: str, filter_list: list[str], mcp_server: MCPServer) -> bool: """ Check if a tool name matches any name in the filter list. - Checks both the full tool name and unprefixed version (without server prefix). - This allows users to configure simple tool names regardless of prefixing. - Comparison is case-insensitive to handle OpenAPI operationIds that may be in camelCase. - - Args: - tool_name: The tool name to check (may be prefixed like "server-tool_name") - filter_list: List of tool names to match against - - Returns: - True if the tool name (prefixed or unprefixed) is in the filter list + Reads the same owner the server-level permission checks use, so discovery hides + exactly what dispatch refuses. ``mcp_server`` is required: guessing the boundary + at the first separator mismatches every tool on a server whose prefix contains + the separator. """ - from litellm.proxy._experimental.mcp_server.utils import ( - split_server_prefix_from_name, - ) - - # Normalize filter list to lowercase for case-insensitive comparison - filter_list_lower = [f.lower() for f in filter_list] - - if tool_name.lower() in filter_list_lower: - return True - - # Check if the unprefixed name is in the list (case-insensitive) - unprefixed_name, _ = split_server_prefix_from_name(tool_name) - return unprefixed_name.lower() in filter_list_lower + bare_name = strip_known_server_prefix(tool_name, mcp_server) + return match_known_tool_name(bare_name, mcp_server, filter_list) is not None def filter_tools_by_allowed_tools( - tools: List[MCPTool], + tools: list[MCPTool], mcp_server: MCPServer, - ) -> List[MCPTool]: + ) -> list[MCPTool]: """ Filter tools by allowed/disallowed tools configuration. @@ -1388,20 +1457,24 @@ if MCP_AVAILABLE: if server_applies_tool_allowlist(mcp_server): if not mcp_server.allowed_tools: return [] - tools_to_return = [tool for tool in tools if _tool_name_matches(tool.name, mcp_server.allowed_tools)] + tools_to_return = [ + tool for tool in tools if _tool_name_matches(tool.name, mcp_server.allowed_tools, mcp_server) + ] # Filter by disallowed_tools (blacklist) if mcp_server.disallowed_tools: tools_to_return = [ - tool for tool in tools_to_return if not _tool_name_matches(tool.name, mcp_server.disallowed_tools) + tool + for tool in tools_to_return + if not _tool_name_matches(tool.name, mcp_server.disallowed_tools, mcp_server) ] return tools_to_return def apply_tool_overrides( - tools: List[MCPTool], + tools: list[MCPTool], mcp_server: MCPServer, - ) -> List[MCPTool]: + ) -> list[MCPTool]: """Apply admin-configured display name/description overrides to tools. Overrides are keyed by the unprefixed tool name, same convention as @@ -1413,7 +1486,7 @@ if MCP_AVAILABLE: return tools for tool in tools: - unprefixed, _ = split_server_prefix_from_name(tool.name) + unprefixed = strip_known_server_prefix(tool.name, mcp_server) lookup_key = unprefixed or tool.name if lookup_key in display_name_map: tool.name = display_name_map[lookup_key] @@ -1421,7 +1494,7 @@ if MCP_AVAILABLE: tool.description = description_map[lookup_key] return tools - def _get_client_ip_from_context() -> Optional[str]: + def _get_client_ip_from_context() -> str | None: """ Extract client_ip from auth context. Returns None if context not set (caller should handle this as "no IP filtering"). @@ -1435,10 +1508,10 @@ if MCP_AVAILABLE: return None async def _get_allowed_mcp_servers( - user_api_key_auth: Optional[UserAPIKeyAuth], - mcp_servers: Optional[List[str]], - client_ip: Optional[str] = None, - ) -> List[MCPServer]: + user_api_key_auth: UserAPIKeyAuth | None, + mcp_servers: list[str] | None, + client_ip: str | None = None, + ) -> list[MCPServer]: """Return allowed MCP servers for a request after applying filters. Args: @@ -1479,7 +1552,7 @@ if MCP_AVAILABLE: _ip_blocked, client_ip, ) - allowed_mcp_servers: List[MCPServer] = [] + allowed_mcp_servers: list[MCPServer] = [] for allowed_mcp_server_id in allowed_mcp_server_ids: mcp_server = global_mcp_server_manager.get_mcp_server_by_id(allowed_mcp_server_id) if mcp_server is not None: @@ -1497,7 +1570,7 @@ if MCP_AVAILABLE: def _client_has_per_server_auth_header( server: MCPServer, - mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]], + mcp_server_auth_headers: dict[str, dict[str, str]] | None, ) -> bool: """True if the request carries a per-server ``x-mcp-{alias}-authorization`` header for this server. This is the multi-server binding: it names one @@ -1526,8 +1599,8 @@ if MCP_AVAILABLE: def _client_has_passthrough_authorization( server: MCPServer, - oauth2_headers: Optional[Dict[str, str]], - mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]], + oauth2_headers: dict[str, str] | None, + mcp_server_auth_headers: dict[str, dict[str, str]] | None, ) -> bool: """True if the incoming request already carries an ``Authorization`` header the gateway will forward to this pass-through server. @@ -1545,9 +1618,9 @@ if MCP_AVAILABLE: async def _get_user_oauth_extra_headers_from_db( server: MCPServer, - user_api_key_auth: Optional[UserAPIKeyAuth], - prefetched_creds: Optional[Dict[str, Dict[str, Any]]] = None, - ) -> Optional[Dict[str, str]]: + user_api_key_auth: UserAPIKeyAuth | None, + prefetched_creds: dict[str, dict[str, Any]] | None = None, + ) -> dict[str, str] | None: """Stored OAuth2 token for (user, server) as an ``Authorization: Bearer`` header, or None. Thin wrapper over ``resolve_user_oauth_access_token`` (Redis cache, else DB + refresh); @@ -1565,8 +1638,8 @@ if MCP_AVAILABLE: return {"Authorization": f"Bearer {token}"} if token else None async def _prefetch_oauth_creds_for_user( - user_api_key_auth: Optional[UserAPIKeyAuth], - ) -> Dict[str, Dict[str, Any]]: + user_api_key_auth: UserAPIKeyAuth | None, + ) -> dict[str, "OAuthCredentialPayload"]: """Fetch all OAuth2 credentials for the user in one DB query. Returns a dict keyed by server_id to avoid N+1 queries in asyncio.gather loops. @@ -1591,13 +1664,13 @@ if MCP_AVAILABLE: def _prepare_mcp_server_headers( server: MCPServer, - mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]], - mcp_auth_header: Optional[str], - oauth2_headers: Optional[Dict[str, str]], - raw_headers: Optional[Dict[str, str]], - user_api_key_auth: Optional[UserAPIKeyAuth] = None, - scope_servers: Optional[list[MCPServer]] = None, - ) -> Tuple[Optional[Union[Dict[str, str], str]], Optional[Dict[str, str]]]: + mcp_server_auth_headers: dict[str, dict[str, str]] | None, + mcp_auth_header: str | None, + oauth2_headers: dict[str, str] | None, + raw_headers: dict[str, str] | None, + user_api_key_auth: UserAPIKeyAuth | None = None, + scope_servers: list[MCPServer] | None = None, + ) -> tuple[dict[str, str] | str | None, dict[str, str] | None]: """Build auth and extra headers for a server. ``scope_servers`` is the full server list a fan-out handler iterates. Passing it lets the @@ -1606,7 +1679,7 @@ if MCP_AVAILABLE: explicitly-addressed operations leave it None. Per-server ``x-mcp-{alias}-authorization`` headers are unaffected — they bind one token to one server and are the multi-server shape. """ - server_auth_header: Optional[Union[Dict[str, str], str]] = None + server_auth_header: dict[str, str] | str | None = None if mcp_server_auth_headers: from litellm.proxy._experimental.mcp_server.utils import ( lookup_mcp_server_auth_in_headers, @@ -1618,7 +1691,7 @@ if MCP_AVAILABLE: server_name=server.server_name, ) - extra_headers: Optional[Dict[str, str]] = None + extra_headers: dict[str, str] | None = None is_client_forwarded_mode = server.is_true_passthrough or server.is_oauth_delegate # In a multi-server listing scope the request-wide Authorization can only carry one token, # so it is withheld from a client-forwarded server when another server in scope also consumes @@ -1694,13 +1767,13 @@ if MCP_AVAILABLE: return server_auth_header, extra_headers def _merge_gateway_initialize_instructions( - allowed_mcp_servers: List[MCPServer], - ) -> Optional[str]: + allowed_mcp_servers: list[MCPServer], + ) -> str | None: """YAML/DB override, else upstream text (prefetch on init, or list_tools / health_check / call_tool cache).""" if not allowed_mcp_servers: return None - texts: List[Tuple[str, str]] = [] + texts: list[tuple[str, str]] = [] for server in allowed_mcp_servers: label = server.alias or server.server_name or server.name or server.server_id or "mcp" if server.instructions and server.instructions.strip(): @@ -1720,9 +1793,9 @@ if MCP_AVAILABLE: @contextlib.asynccontextmanager async def _gateway_initialize_instructions_request_scope( - user_api_key_auth: Optional[UserAPIKeyAuth], - mcp_servers: Optional[List[str]], - client_ip: Optional[str], + user_api_key_auth: UserAPIKeyAuth | None, + mcp_servers: list[str] | None, + client_ip: str | None, scoped_server_endpoint: bool = False, ) -> AsyncIterator[None]: allowed = await _get_allowed_mcp_servers( @@ -1765,17 +1838,17 @@ if MCP_AVAILABLE: return get_server_prefix(server) or "unknown" async def _get_tools_from_mcp_servers( - user_api_key_auth: Optional[UserAPIKeyAuth], - mcp_auth_header: Optional[str], - mcp_servers: Optional[List[str]], - 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, + user_api_key_auth: UserAPIKeyAuth | None, + mcp_auth_header: str | None, + mcp_servers: list[str] | None, + mcp_server_auth_headers: dict[str, dict[str, str]] | None = None, + oauth2_headers: dict[str, str] | None = None, + raw_headers: dict[str, str] | None = None, log_list_tools_to_spendlogs: bool = False, - list_tools_log_source: Optional[str] = None, - litellm_trace_id: Optional[str] = None, - request_tags: Optional[list[str]] = None, - client_ip: Optional[str] = None, + list_tools_log_source: str | None = None, + litellm_trace_id: str | None = None, + request_tags: list[str] | None = None, + client_ip: str | None = None, ) -> AggregateToolListing: """ Helper method to fetch tools from MCP servers based on server filtering criteria. @@ -1795,8 +1868,8 @@ if MCP_AVAILABLE: return AggregateToolListing(tools=[], outcomes={}) list_tools_start_time = datetime.now() - litellm_logging_obj: Optional[LiteLLMLoggingObj] = None - list_tools_request_data: Dict[str, Any] = {} + litellm_logging_obj: LiteLLMLoggingObj | None = None + list_tools_request_data: dict[str, Any] = {} if log_list_tools_to_spendlogs: # This is intentionally minimal: only async_success_handler / post_call_failure_hook @@ -1804,7 +1877,7 @@ if MCP_AVAILABLE: list_tools_call_id = str(uuid.uuid4()) # Derive trace_id from raw_headers when not explicitly passed (same as A2A / MCP call_tool) effective_litellm_trace_id = litellm_trace_id or get_chain_id_from_headers(raw_headers) - spend_logs_metadata: Dict[str, Any] = { + spend_logs_metadata: dict[str, Any] = { "mcp_operation": "list_tools", } if isinstance(list_tools_log_source, str): @@ -1877,7 +1950,7 @@ if MCP_AVAILABLE: async def _fetch_and_filter_server_tools( server: MCPServer, - ) -> "tuple[List[MCPTool], ServerOutcome]": + ) -> "tuple[list[MCPTool], ServerOutcome]": """Fetch and filter tools from a single server, classifying any failure into that server's outcome so the aggregate can keep serving the healthy subset without a broken server masquerading as an empty one.""" @@ -1971,8 +2044,8 @@ if MCP_AVAILABLE: results = await asyncio.gather(*tasks) # Flatten results into single list - all_tools: List[MCPTool] = [tool for tools, _ in results for tool in tools] - server_outcomes: Dict[str, ServerOutcome] = { + all_tools: list[MCPTool] = [tool for tools, _ in results for tool in tools] + server_outcomes: dict[str, ServerOutcome] = { _aggregate_server_key(server): outcome for server, (_, outcome) in zip(allowed_mcp_servers, results) if server is not None @@ -1980,7 +2053,7 @@ if MCP_AVAILABLE: # If logging is enabled, enrich spend_logs_metadata with counts if litellm_logging_obj: - per_server_tool_counts: Dict[str, int] = { + per_server_tool_counts: dict[str, int] = { _aggregate_server_key(server): len(server_tools) for server, (server_tools, _) in zip(allowed_mcp_servers, results) if server is not None @@ -2039,13 +2112,13 @@ if MCP_AVAILABLE: raise async def _get_prompts_from_mcp_servers( - user_api_key_auth: Optional[UserAPIKeyAuth], - mcp_auth_header: Optional[str], - mcp_servers: Optional[List[str]], - 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, - ) -> List[Prompt]: + user_api_key_auth: UserAPIKeyAuth | None, + mcp_auth_header: str | None, + mcp_servers: list[str] | None, + mcp_server_auth_headers: dict[str, dict[str, str]] | None = None, + oauth2_headers: dict[str, str] | None = None, + raw_headers: dict[str, str] | None = None, + ) -> list[Prompt]: """ Helper method to fetch prompt from MCP servers based on server filtering criteria. @@ -2104,13 +2177,13 @@ if MCP_AVAILABLE: return all_prompts async def _get_resources_from_mcp_servers( - user_api_key_auth: Optional[UserAPIKeyAuth], - mcp_auth_header: Optional[str], - mcp_servers: Optional[List[str]], - 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, - ) -> List[Resource]: + user_api_key_auth: UserAPIKeyAuth | None, + mcp_auth_header: str | None, + mcp_servers: list[str] | None, + mcp_server_auth_headers: dict[str, dict[str, str]] | None = None, + oauth2_headers: dict[str, str] | None = None, + raw_headers: dict[str, str] | None = None, + ) -> list[Resource]: """Fetch resources from allowed MCP servers.""" if not MCP_AVAILABLE: @@ -2121,7 +2194,7 @@ if MCP_AVAILABLE: mcp_servers=mcp_servers, ) - all_resources: List[Resource] = [] + all_resources: list[Resource] = [] for server in allowed_mcp_servers: if server is None: continue @@ -2155,13 +2228,13 @@ if MCP_AVAILABLE: return all_resources async def _get_resource_templates_from_mcp_servers( - user_api_key_auth: Optional[UserAPIKeyAuth], - mcp_auth_header: Optional[str], - mcp_servers: Optional[List[str]], - 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, - ) -> List[ResourceTemplate]: + user_api_key_auth: UserAPIKeyAuth | None, + mcp_auth_header: str | None, + mcp_servers: list[str] | None, + mcp_server_auth_headers: dict[str, dict[str, str]] | None = None, + oauth2_headers: dict[str, str] | None = None, + raw_headers: dict[str, str] | None = None, + ) -> list[ResourceTemplate]: """Fetch resource templates from allowed MCP servers.""" if not MCP_AVAILABLE: @@ -2172,7 +2245,7 @@ if MCP_AVAILABLE: mcp_servers=mcp_servers, ) - all_resource_templates: List[ResourceTemplate] = [] + all_resource_templates: list[ResourceTemplate] = [] for server in allowed_mcp_servers: if server is None: continue @@ -2216,10 +2289,10 @@ if MCP_AVAILABLE: return all_resource_templates async def filter_tools_by_key_team_permissions( - tools: List[MCPTool], + tools: list[MCPTool], server_id: str, - user_api_key_auth: Optional[UserAPIKeyAuth], - ) -> List[MCPTool]: + user_api_key_auth: UserAPIKeyAuth | None, + ) -> list[MCPTool]: """ Filter tools based on key/team mcp_tool_permissions. @@ -2232,25 +2305,27 @@ if MCP_AVAILABLE: server_id=server_id, user_api_key_auth=user_api_key_auth, ) - if allowed_tool_names is None: - return tools # Tools arrive prefixed with the server's own prefix; strip exactly that # prefix (resolved from the server) rather than the first separator, so a # prefix containing the separator still reduces to the stored bare name. server = global_mcp_server_manager.get_mcp_server_by_id(server_id) - return [t for t in tools if strip_known_server_prefix(t.name, server) in allowed_tool_names] + return [ + t + for t in tools + if MCPRequestHandler.tool_is_granted(strip_known_server_prefix(t.name, server), allowed_tool_names) + ] async def _list_mcp_tools( - user_api_key_auth: Optional[UserAPIKeyAuth] = None, - mcp_auth_header: Optional[str] = None, - mcp_servers: Optional[List[str]] = None, - mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]] = None, - oauth2_headers: Optional[Dict[str, str]] = None, - raw_headers: Optional[Dict[str, str]] = None, + user_api_key_auth: UserAPIKeyAuth | None = None, + mcp_auth_header: str | None = None, + mcp_servers: list[str] | None = None, + mcp_server_auth_headers: dict[str, dict[str, str]] | None = None, + oauth2_headers: dict[str, str] | None = None, + raw_headers: dict[str, str] | None = None, log_list_tools_to_spendlogs: bool = False, - list_tools_log_source: Optional[str] = None, - client_ip: Optional[str] = None, + list_tools_log_source: str | None = None, + client_ip: str | None = None, ) -> AggregateToolListing: """ List all available MCP tools. @@ -2289,13 +2364,13 @@ if MCP_AVAILABLE: return AggregateToolListing(tools=[], outcomes={}) async def _list_mcp_prompts( - user_api_key_auth: Optional[UserAPIKeyAuth] = None, - mcp_auth_header: Optional[str] = None, - mcp_servers: Optional[List[str]] = None, - mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]] = None, - oauth2_headers: Optional[Dict[str, str]] = None, - raw_headers: Optional[Dict[str, str]] = None, - ) -> List[Prompt]: + user_api_key_auth: UserAPIKeyAuth | None = None, + mcp_auth_header: str | None = None, + mcp_servers: list[str] | None = None, + mcp_server_auth_headers: dict[str, dict[str, str]] | None = None, + oauth2_headers: dict[str, str] | None = None, + raw_headers: dict[str, str] | None = None, + ) -> list[Prompt]: """ List all available MCP prompts. @@ -2329,19 +2404,19 @@ if MCP_AVAILABLE: return managed_prompts async def _list_mcp_resources( - user_api_key_auth: Optional[UserAPIKeyAuth] = None, - mcp_auth_header: Optional[str] = None, - mcp_servers: Optional[List[str]] = None, - mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]] = None, - oauth2_headers: Optional[Dict[str, str]] = None, - raw_headers: Optional[Dict[str, str]] = None, - ) -> List[Resource]: + user_api_key_auth: UserAPIKeyAuth | None = None, + mcp_auth_header: str | None = None, + mcp_servers: list[str] | None = None, + mcp_server_auth_headers: dict[str, dict[str, str]] | None = None, + oauth2_headers: dict[str, str] | None = None, + raw_headers: dict[str, str] | None = None, + ) -> list[Resource]: """List all available MCP resources.""" if not MCP_AVAILABLE: return [] - managed_resources: List[Resource] = [] + managed_resources: list[Resource] = [] try: managed_resources = await _get_resources_from_mcp_servers( user_api_key_auth=user_api_key_auth, @@ -2358,19 +2433,19 @@ if MCP_AVAILABLE: return managed_resources async def _list_mcp_resource_templates( - user_api_key_auth: Optional[UserAPIKeyAuth] = None, - mcp_auth_header: Optional[str] = None, - mcp_servers: Optional[List[str]] = None, - mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]] = None, - oauth2_headers: Optional[Dict[str, str]] = None, - raw_headers: Optional[Dict[str, str]] = None, - ) -> List[ResourceTemplate]: + user_api_key_auth: UserAPIKeyAuth | None = None, + mcp_auth_header: str | None = None, + mcp_servers: list[str] | None = None, + mcp_server_auth_headers: dict[str, dict[str, str]] | None = None, + oauth2_headers: dict[str, str] | None = None, + raw_headers: dict[str, str] | None = None, + ) -> list[ResourceTemplate]: """List all available MCP resource templates.""" if not MCP_AVAILABLE: return [] - managed_resource_templates: List[ResourceTemplate] = [] + managed_resource_templates: list[ResourceTemplate] = [] try: managed_resource_templates = await _get_resource_templates_from_mcp_servers( user_api_key_auth=user_api_key_auth, @@ -2394,7 +2469,7 @@ if MCP_AVAILABLE: def _resolve_display_name_to_original( name: str, - allowed_mcp_servers: List[MCPServer], + allowed_mcp_servers: list[MCPServer], ) -> str: """Translate a display-name override back to the original prefixed tool name. @@ -2412,8 +2487,8 @@ if MCP_AVAILABLE: async def _get_byok_credential( mcp_server: MCPServer, - user_api_key_auth: Optional[UserAPIKeyAuth], - ) -> Optional[str]: + user_api_key_auth: UserAPIKeyAuth | None, + ) -> str | None: """Retrieve the stored BYOK credential for a user+server pair. Uses the shared _byok_cred_cache to avoid a DB round-trip on every @@ -2447,7 +2522,7 @@ if MCP_AVAILABLE: async def _check_byok_credential( mcp_server: MCPServer, - user_api_key_auth: Optional[UserAPIKeyAuth], + user_api_key_auth: UserAPIKeyAuth | None, ) -> None: """ If the MCP server is BYOK-enabled, verify that the requesting user has a @@ -2535,15 +2610,15 @@ if MCP_AVAILABLE: async def execute_mcp_tool( name: str, - arguments: Dict[str, Any], - allowed_mcp_servers: List[MCPServer], + arguments: dict[str, Any], + allowed_mcp_servers: list[MCPServer], start_time: datetime, - user_api_key_auth: Optional[UserAPIKeyAuth] = None, - mcp_auth_header: Optional[str] = None, - mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]] = None, - oauth2_headers: Optional[Dict[str, str]] = None, - raw_headers: Optional[Dict[str, str]] = None, - host_progress_callback: Optional[Callable] = None, + user_api_key_auth: UserAPIKeyAuth | None = None, + mcp_auth_header: str | None = None, + mcp_server_auth_headers: dict[str, dict[str, str]] | None = None, + oauth2_headers: dict[str, str] | None = None, + raw_headers: dict[str, str] | None = None, + host_progress_callback: Callable | None = None, **kwargs: Any, ) -> CallToolResult: """ @@ -2567,8 +2642,8 @@ if MCP_AVAILABLE: CallToolResult: Tool execution result """ # Track resolved MCP server for both permission checks and dispatch - mcp_server: Optional[MCPServer] = None - requested_server_id: Optional[str] = kwargs.get("requested_server_id") + mcp_server: MCPServer | None = None + requested_server_id: str | None = kwargs.get("requested_server_id") # If the client called with a display-name override (e.g. "Get Pet"), # translate it back to the original prefixed name before any routing. @@ -2577,7 +2652,7 @@ if MCP_AVAILABLE: # Remove prefix from tool name for logging and processing original_tool_name, server_name = split_server_prefix_from_name(name) - requested_server: Optional[MCPServer] = None + requested_server: MCPServer | None = None if requested_server_id: requested_server = next( (s for s in allowed_mcp_servers if s.server_id == requested_server_id), @@ -2586,7 +2661,7 @@ if MCP_AVAILABLE: name_is_prefixed = False if requested_server is not None and MCP_TOOL_PREFIX_SEPARATOR in name: - all_registry_prefixes: Set[str] = set() + all_registry_prefixes: set[str] = set() for registry_server in global_mcp_server_manager.get_registry().values(): for known_prefix in iter_known_server_prefixes(registry_server): all_registry_prefixes.add(normalize_server_name(known_prefix)) @@ -2614,6 +2689,7 @@ if MCP_AVAILABLE: break if mcp_server is not None: server_name = mcp_server.name + original_tool_name = strip_known_server_prefix(name, mcp_server) if requested_server is not None: if mcp_server is not None and mcp_server.server_id != requested_server.server_id: @@ -2631,6 +2707,7 @@ if MCP_AVAILABLE: if mcp_server is None: mcp_server = requested_server server_name = requested_server.name + original_tool_name = strip_known_server_prefix(name, requested_server) # Only enforce server-level permissions when we can resolve a server if server_name: @@ -2640,7 +2717,7 @@ if MCP_AVAILABLE: ): raise HTTPException( status_code=403, - detail=f"User not allowed to call this tool. Allowed MCP servers: {allowed_mcp_servers}", + detail="User not allowed to call this tool.", ) standard_logging_mcp_tool_call: StandardLoggingMCPToolCall = _get_standard_logging_mcp_tool_call( @@ -2649,7 +2726,7 @@ if MCP_AVAILABLE: server_name=server_name, session_id=_mcp_session_id_from_headers(raw_headers), ) - litellm_logging_obj: Optional[LiteLLMLoggingObj] = kwargs.get("litellm_logging_obj", None) + litellm_logging_obj: LiteLLMLoggingObj | None = kwargs.get("litellm_logging_obj", None) if litellm_logging_obj: litellm_logging_obj.model_call_details["mcp_tool_call_metadata"] = standard_logging_mcp_tool_call litellm_logging_obj.model = f"MCP: {name}" @@ -2742,7 +2819,7 @@ if MCP_AVAILABLE: # because the tool function has headers baked into its closure. # Pre-format the full Authorization header value using the server's # configured auth_type so the generator doesn't need to know the prefix. - auth_header_value: Optional[str] = None + auth_header_value: str | None = None if mcp_auth_header: server_auth_type = getattr(mcp_server, "auth_type", None) if mcp_server else None if server_auth_type == MCPAuth.api_key: @@ -2758,7 +2835,7 @@ if MCP_AVAILABLE: # OpenAPI/local path agrees with the managed paths: M2M and the resolver-owned modes # (token_exchange's raw subject token, authorization_code's stored token) must never # have the caller's Authorization forwarded verbatim upstream. - forwarded_headers: Optional[Dict[str, str]] = None + forwarded_headers: dict[str, str] | None = None if mcp_server and mcp_server.extra_headers and raw_headers: normalized_raw = {str(k).lower(): v for k, v in raw_headers.items() if isinstance(k, str)} skip_caller_authorization = _should_strip_caller_authorization( @@ -2802,13 +2879,14 @@ if MCP_AVAILABLE: _request_resolved_auth_headers.reset(_resolved_token) response = CallToolResult(content=cast(Any, local_content), isError=False) - # Try managed MCP server tool (pass the full prefixed name) + # Try managed MCP server tool (the name is bare; the prefix boundary was + # already resolved above against this server's registered prefixes) # Primary and recommended way to use external MCP servers ######################################################### elif mcp_server: response = await _handle_managed_mcp_tool( server_name=server_name, - name=original_tool_name, # Pass the full name (potentially prefixed) + name=original_tool_name, arguments=arguments, user_api_key_auth=user_api_key_auth, mcp_auth_header=mcp_auth_header, @@ -2824,10 +2902,89 @@ if MCP_AVAILABLE: # Deprecated: Local MCP Server Tool ######################################################### else: + # Gate only what can actually dispatch. When the unprefixed name is + # not in the registry either, `_handle_local_mcp_tool` below reports + # 404 and nothing runs, so demanding a server here would turn every + # unknown tool name into a misleading 503. + if global_mcp_tool_registry.get_tool(original_tool_name) is not None: + # `mcp_server` is None here because the tool name is not in the + # tool -> server mapping, but the name still carries a prefix + # that the server-level check above compared against the + # caller's `allowed_mcp_servers` by exact `name`. So the named + # server is in that list and can carry the tool-level checks, + # even with the mapping cold. Resolve it from + # `allowed_mcp_servers` rather than the registry: the registry + # would happily return a server the caller holds no grant for, + # and matching anything other than `name` would accept a server + # the check never validated. + prefix_server = next( + (candidate for candidate in allowed_mcp_servers if candidate.name == server_name), + None, + ) + if prefix_server is None: + # A non-empty prefix that passed the server-level check + # always matches here, so this arm only fires when the + # prefix was empty, which is exactly the case that check + # skips. Fail closed rather than dispatch with no server to + # evaluate a tool ceiling against. + raise HTTPException( + status_code=503, + detail=( + f"MCP server for tool '{original_tool_name}' is not available; " + "refusing to dispatch without authorization checks. " + "Retry once the server is registered." + ), + ) + + from litellm.proxy.proxy_server import proxy_logging_obj + + hook_result = await global_mcp_server_manager.pre_call_tool_check( + name=original_tool_name, + arguments=arguments, + server_name=server_name, + user_api_key_auth=user_api_key_auth, + proxy_logging_obj=proxy_logging_obj, + server=prefix_server, + raw_headers=raw_headers, + ) + if "arguments" in hook_result: + arguments = hook_result["arguments"] # pyright: ignore[reportAny] # hook returns untyped args + local_content = await _handle_local_mcp_tool(original_tool_name, arguments) response = CallToolResult(content=cast(Any, local_content), isError=False) - return response + return await _run_post_mcp_call_guardrails( + result=response, + litellm_logging_obj=litellm_logging_obj, + user_api_key_auth=user_api_key_auth, + request_data=kwargs, + ) + + async def _run_post_mcp_call_guardrails( + result: CallToolResult, + litellm_logging_obj: LiteLLMLoggingObj | None, + user_api_key_auth: UserAPIKeyAuth | None, + request_data: Mapping[str, object], + ) -> CallToolResult: + """Run ``post_mcp_call`` guardrails over an executed tool result. + + Lives on ``execute_mcp_tool``'s return path rather than inside + ``_fire_mcp_tool_call_logging`` so enforcement never depends on logging + being configured, and so every dispatch route gets it: the MCP protocol + handler, the REST endpoint, and tool search all funnel through here. + A guardrail that rejects the result raises, matching ``pre_mcp_call``. + """ + from litellm.proxy.proxy_server import proxy_logging_obj + + if proxy_logging_obj is None: + return result + return await proxy_logging_obj.post_mcp_call_hook( + response=result, + request_data=( + litellm_logging_obj.model_call_details if litellm_logging_obj is not None else dict(request_data) + ), + user_api_key_dict=user_api_key_auth, + ) _MCP_CREDENTIAL_REQUEST_FIELDS = frozenset( { @@ -2844,10 +3001,16 @@ if MCP_AVAILABLE: result: Any, start_time: datetime, end_time: datetime, - user_api_key_auth: Optional[UserAPIKeyAuth] = None, - request_data: Optional[Mapping[str, object]] = None, - ) -> None: - """Fire post-call logging for an executed MCP tool call. + user_api_key_auth: UserAPIKeyAuth | None = None, + request_data: Mapping[str, object] | None = None, + ) -> CallToolResult: + """Fire post-call logging for an executed MCP tool call, returning the result to send. + + The returned result is what the caller must forward to the client: a + ``post_mcp_call`` guardrail may rewrite the tool output (e.g. mask + sensitive values) or reject it, in which case its exception propagates. + Guardrails run before the success/failure logging so the masked text, not + the raw one, is what gets logged. A result with ``isError=True`` is logged as a failure (``status="failure"`` payload, so OTel marks the span ERROR) while the HTTP wire behavior stays @@ -2863,6 +3026,8 @@ if MCP_AVAILABLE: stripped before the dict is handed to ``post_call_failure_hook`` callbacks. """ + from litellm.proxy.proxy_server import proxy_logging_obj + logging_obj.post_call(original_response=result) await logging_obj.async_post_mcp_tool_call_hook( kwargs=logging_obj.model_call_details, @@ -2874,7 +3039,7 @@ if MCP_AVAILABLE: error_message = extract_mcp_tool_result_error_message(result) if error_message is None: await logging_obj.async_success_handler(result=result, start_time=start_time, end_time=end_time) - return + return result logging_obj.has_run_logging(event_type="sync_success") logging_obj.has_run_logging(event_type="async_success") @@ -2883,8 +3048,7 @@ if MCP_AVAILABLE: await logging_obj.async_failure_handler(tool_error, "", start_time, end_time) if user_api_key_auth is None: - return - from litellm.proxy.proxy_server import proxy_logging_obj + return result if proxy_logging_obj: sanitized_request_data = { @@ -2896,24 +3060,25 @@ if MCP_AVAILABLE: user_api_key_dict=user_api_key_auth, route="/mcp/call_tool", ) + return result @client async def call_mcp_tool( name: str, - arguments: Optional[Dict[str, Any]] = None, - user_api_key_auth: Optional[UserAPIKeyAuth] = None, - mcp_auth_header: Optional[str] = None, - mcp_servers: Optional[List[str]] = None, - mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]] = None, - oauth2_headers: Optional[Dict[str, str]] = None, - raw_headers: Optional[Dict[str, str]] = None, + arguments: dict[str, Any] | None = None, + user_api_key_auth: UserAPIKeyAuth | None = None, + mcp_auth_header: str | None = None, + mcp_servers: list[str] | None = None, + mcp_server_auth_headers: dict[str, dict[str, str]] | None = None, + oauth2_headers: dict[str, str] | None = None, + raw_headers: dict[str, str] | None = None, **kwargs: Any, ) -> CallToolResult: """ Call a specific tool with the provided arguments (handles prefixed tool names). """ start_time = datetime.now() - litellm_logging_obj: Optional[LiteLLMLoggingObj] = kwargs.get("litellm_logging_obj", None) + litellm_logging_obj: LiteLLMLoggingObj | None = kwargs.get("litellm_logging_obj", None) try: if arguments is None: @@ -2924,7 +3089,7 @@ if MCP_AVAILABLE: user_api_key_auth=user_api_key_auth, ) - allowed_mcp_servers: List[MCPServer] = [] + allowed_mcp_servers: list[MCPServer] = [] for allowed_mcp_server_id in allowed_mcp_server_ids: allowed_server = global_mcp_server_manager.get_mcp_server_by_id(allowed_mcp_server_id) if allowed_server is not None: @@ -2979,7 +3144,7 @@ if MCP_AVAILABLE: raise if litellm_logging_obj: - await _fire_mcp_tool_call_logging( + response = await _fire_mcp_tool_call_logging( logging_obj=litellm_logging_obj, result=response, start_time=start_time, @@ -2991,13 +3156,13 @@ if MCP_AVAILABLE: async def mcp_get_prompt( name: str, - arguments: Optional[Dict[str, Any]] = None, - user_api_key_auth: Optional[UserAPIKeyAuth] = None, - mcp_auth_header: Optional[str] = None, - mcp_servers: Optional[List[str]] = None, - mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]] = None, - oauth2_headers: Optional[Dict[str, str]] = None, - raw_headers: Optional[Dict[str, str]] = None, + arguments: dict[str, Any] | None = None, + user_api_key_auth: UserAPIKeyAuth | None = None, + mcp_auth_header: str | None = None, + mcp_servers: list[str] | None = None, + mcp_server_auth_headers: dict[str, dict[str, str]] | None = None, + oauth2_headers: dict[str, str] | None = None, + raw_headers: dict[str, str] | None = None, ) -> GetPromptResult: """ Fetch a specific MCP prompt, handling both prefixed and unprefixed names. @@ -3043,12 +3208,12 @@ if MCP_AVAILABLE: async def mcp_read_resource( url: AnyUrl, - user_api_key_auth: Optional[UserAPIKeyAuth] = None, - mcp_auth_header: Optional[str] = None, - mcp_servers: Optional[List[str]] = None, - mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]] = None, - oauth2_headers: Optional[Dict[str, str]] = None, - raw_headers: Optional[Dict[str, str]] = None, + user_api_key_auth: UserAPIKeyAuth | None = None, + mcp_auth_header: str | None = None, + mcp_servers: list[str] | None = None, + mcp_server_auth_headers: dict[str, dict[str, str]] | None = None, + oauth2_headers: dict[str, str] | None = None, + raw_headers: dict[str, str] | None = None, ) -> ReadResourceResult: """Read resource contents from upstream MCP servers.""" @@ -3092,9 +3257,9 @@ if MCP_AVAILABLE: def _get_standard_logging_mcp_tool_call( name: str, - arguments: Dict[str, Any], - server_name: Optional[str], - session_id: Optional[str] = None, + arguments: dict[str, Any], + server_name: str | None, + session_id: str | None = None, ) -> StandardLoggingMCPToolCall: mcp_server = global_mcp_server_manager._get_mcp_server_from_tool_name(name) namespaced_tool_name = f"{server_name}/{name}" if server_name else name @@ -3121,14 +3286,14 @@ if MCP_AVAILABLE: async def _handle_managed_mcp_tool( server_name: str, name: str, - arguments: Dict[str, Any], - user_api_key_auth: Optional[UserAPIKeyAuth] = None, - mcp_auth_header: Optional[str] = None, - mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]] = None, - 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, + arguments: dict[str, Any], + user_api_key_auth: UserAPIKeyAuth | None = None, + mcp_auth_header: str | None = None, + mcp_server_auth_headers: dict[str, dict[str, str]] | None = None, + oauth2_headers: dict[str, str] | None = None, + raw_headers: dict[str, str] | None = None, + litellm_logging_obj: Any | None = None, + host_progress_callback: Callable | None = None, ) -> CallToolResult: """Handle tool execution for managed server tools""" # Import here to avoid circular import @@ -3150,8 +3315,8 @@ if MCP_AVAILABLE: return call_tool_result async def _handle_local_mcp_tool( - name: str, arguments: Dict[str, Any] - ) -> List[Union[TextContent, ImageContent, EmbeddedResource]]: + name: str, arguments: dict[str, Any] + ) -> list[TextContent | ImageContent | EmbeddedResource]: """ Handle tool execution for local registry tools Note: Local tools don't use prefixes, so we use the original name @@ -3173,13 +3338,13 @@ if MCP_AVAILABLE: verbose_logger.exception(f"Error executing local tool {name}: {str(e)}") return [TextContent(text=f"Error: {str(e)}", type="text")] - def _get_mcp_servers_in_path(path: str) -> Optional[List[str]]: + def _get_mcp_servers_in_path(path: str) -> list[str] | None: """ Get the MCP servers from the path """ import re - mcp_servers_from_path: Optional[List[str]] = None + mcp_servers_from_path: list[str] | None = None segments = [s for s in path.split("/") if s] if len(segments) >= 2 and segments[1] == "mcp" and segments[0] != "mcp": return [segments[0]] @@ -3251,7 +3416,7 @@ if MCP_AVAILABLE: raw_headers, ) - def _get_session_id_from_scope(scope: Scope) -> Optional[str]: + def _get_session_id_from_scope(scope: Scope) -> str | None: """ Extract mcp-session-id from ASGI scope headers. Returns None if not present. @@ -3263,9 +3428,9 @@ if MCP_AVAILABLE: return None def _owner_fingerprint_for( - user_api_key_auth: Optional[UserAPIKeyAuth], - oauth2_headers: Optional[Dict[str, str]] = None, - client_ip: Optional[str] = None, + user_api_key_auth: UserAPIKeyAuth | None, + oauth2_headers: dict[str, str] | None = None, + client_ip: str | None = None, ) -> str: """ Stable, non-reversible identifier for the caller used to bind an @@ -3290,7 +3455,7 @@ if MCP_AVAILABLE: is best-effort in that mode. """ - def _bytes_for_hash(value: Any) -> Optional[bytes]: + def _bytes_for_hash(value: Any) -> bytes | None: """Only hash str/bytes secrets; skip mocks and other unexpected types.""" if value is None: return None @@ -3333,7 +3498,7 @@ if MCP_AVAILABLE: async def _read_request_body_for_routing( receive: Receive, - ) -> Tuple[List[Message], bytes]: + ) -> tuple[list[Message], bytes]: """ Read just enough of the request body to decide whether this is a JSON-RPC ``initialize`` call. Returns the consumed ASGI messages so @@ -3347,8 +3512,8 @@ if MCP_AVAILABLE: force the proxy to buffer an arbitrarily large payload just to make a routing decision. """ - consumed_messages: List[Message] = [] - body_chunks: List[bytes] = [] + consumed_messages: list[Message] = [] + body_chunks: list[bytes] = [] peeked_bytes = 0 while True: @@ -3403,14 +3568,14 @@ if MCP_AVAILABLE: _mcp_session_header = b"mcp-session-id" _headers = scope.get("headers", []) - def _normalize_header_name(header_name: Any) -> Optional[bytes]: + def _normalize_header_name(header_name: Any) -> bytes | None: if isinstance(header_name, bytes): return header_name.lower() if isinstance(header_name, str): return header_name.lower().encode("utf-8", errors="replace") return None - _session_id: Optional[str] = None + _session_id: str | None = None for header_name, header_value in _headers: if _normalize_header_name(header_name) == _mcp_session_header: if isinstance(header_value, bytes): @@ -3528,38 +3693,14 @@ if MCP_AVAILABLE: ) return user_api_key_auth.model_copy(update={"object_permission": updated_op}) - def _get_passthrough_resource_metadata_url(scope: Scope, server_name: str) -> str: - request = StarletteRequest(scope) - base_url = get_request_base_url(request) - _path = scope.get("_original_path") or scope.get("path", "") or "" - - if _path.startswith(f"/{server_name}/mcp"): - return f"{base_url}/.well-known/oauth-protected-resource/{server_name}/mcp" - return f"{base_url}/.well-known/oauth-protected-resource/mcp/{server_name}" - - def _get_passthrough_www_authenticate( - scope: Scope, - server_name: str, - invalid_token: bool = False, - ) -> str: - resource_metadata_url = _get_passthrough_resource_metadata_url( - scope=scope, - server_name=server_name, - ) - params = [] - if invalid_token: - params.append('error="invalid_token"') - params.append(f'resource_metadata="{resource_metadata_url}"') - return "Bearer " + ", ".join(params) - async def _raise_preemptive_401_for_unauthenticated_servers( scope: Scope, - mcp_servers: Optional[List[str]], - oauth2_headers: Optional[Dict[str, str]], - mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]], - user_api_key_auth: Optional[UserAPIKeyAuth], - client_ip: Optional[str], - allowed_server_ids: Optional[Set[str]] = None, + mcp_servers: list[str] | None, + oauth2_headers: dict[str, str] | None, + mcp_server_auth_headers: dict[str, dict[str, str]] | None, + user_api_key_auth: UserAPIKeyAuth | None, + client_ip: str | None, + allowed_server_ids: set[str] | None = None, ) -> None: """Fail fast with HTTP 401 for MCP servers that need user auth but didn't receive it on this request. Covers both gateway-managed OAuth2 @@ -3601,10 +3742,26 @@ if MCP_AVAILABLE: # challenge whenever one is absent, regardless of any bearer. # The v2 resolver owns the existence check, so every # authorization_code resolution (egress and this discovery - # challenge) runs through it. + # challenge) runs through it. A keyless admitted subject is + # challenged with the per-server resource_metadata (whose + # authorization server is the gateway itself, vaulting via the + # authorize interlude); the per-server relay advertised below + # cannot vault without a litellm key on its token request. if await global_mcp_server_manager.has_user_oauth_token(server, user_api_key_auth): continue + if _is_mcp_admitted_user_subject(user_api_key_auth): + raise HTTPException( + status_code=401, + detail="Unauthorized", + headers={ + "www-authenticate": get_passthrough_www_authenticate( + scope=scope, + server_name=server_name, + ) + }, + ) + request = StarletteRequest(scope) base_url = get_request_base_url(request) _path = scope.get("_original_path") or scope.get("path", "") or "" @@ -3629,7 +3786,7 @@ if MCP_AVAILABLE: # the proxied resource_metadata (RFC 9728), not the gateway # authorization_uri above which would authorize against the # gateway instead of the upstream IdP. - www_authenticate = _get_passthrough_www_authenticate( + www_authenticate = get_passthrough_www_authenticate( scope=scope, server_name=server_name, ) @@ -3685,7 +3842,7 @@ if MCP_AVAILABLE: and server.is_oauth_passthrough and not _client_has_passthrough_authorization(server, oauth2_headers, mcp_server_auth_headers) ): - www_authenticate = _get_passthrough_www_authenticate( + www_authenticate = get_passthrough_www_authenticate( scope=scope, server_name=server_name, ) @@ -3702,7 +3859,7 @@ if MCP_AVAILABLE: and _get_forwarded_auth_from_scope(scope) is None and not _client_has_per_server_auth_header(server, mcp_server_auth_headers) ): - www_authenticate = _get_passthrough_www_authenticate( + www_authenticate = get_passthrough_www_authenticate( scope=scope, server_name=server_name, ) @@ -3724,7 +3881,7 @@ if MCP_AVAILABLE: status_code=401, detail="Unauthorized", headers={ - "www-authenticate": _get_passthrough_www_authenticate( + "www-authenticate": get_passthrough_www_authenticate( scope=scope, server_name=server_name, ) @@ -3738,7 +3895,7 @@ if MCP_AVAILABLE: headers={"www-authenticate": upstream_www_authenticate}, ) - def _get_authorization_header_from_scope(scope: Scope) -> Optional[str]: + def _get_authorization_header_from_scope(scope: Scope) -> str | None: """First ``Authorization`` header value in the ASGI scope, or None.""" for key, value in scope.get("headers", []): if key.lower() == b"authorization": @@ -3748,7 +3905,7 @@ if MCP_AVAILABLE: def _scope_has_authorization_header(scope: Scope) -> bool: return _get_authorization_header_from_scope(scope) is not None - def _get_forwarded_auth_from_scope(scope: Scope) -> Optional[str]: + def _get_forwarded_auth_from_scope(scope: Scope) -> str | None: """Return the upstream-bound ``Authorization`` header value, or None. Only returns the ``Authorization`` header when ``x-litellm-api-key`` is @@ -3782,7 +3939,7 @@ if MCP_AVAILABLE: url: str, auth_header: str, timeout: float = 5.0, - ) -> tuple[int, Optional[str]]: + ) -> tuple[int, str | None]: """JSON-RPC initialize-probe the upstream URL to check whether the token is accepted. Uses POST so StreamableHTTP MCP servers run the same auth path as a @@ -3834,9 +3991,9 @@ if MCP_AVAILABLE: async def _check_passthrough_upstream_auth( scope: Scope, - user_api_key_auth: Optional[UserAPIKeyAuth], - mcp_servers: Optional[List[str]], - client_ip: Optional[str], + user_api_key_auth: UserAPIKeyAuth | None, + mcp_servers: list[str] | None, + client_ip: str | None, ) -> None: """Probe pass-through and delegate-auth upstream servers in parallel before the MCP session starts. @@ -3891,7 +4048,7 @@ if MCP_AVAILABLE: mcp_servers=mcp_servers, client_ip=client_ip, ) - passthrough_targets: Tuple[Tuple[MCPServer, str, str], ...] = ( + passthrough_targets: tuple[tuple[MCPServer, str, str], ...] = ( tuple( (srv, forwarded_auth, srv.name) for srv in allowed_servers @@ -3910,7 +4067,7 @@ if MCP_AVAILABLE: ) # Probe the admission-resolved delegate server only when the caller is actually # authorized for it (present in the IP-filtered allowed set), keyed by server_id. - delegate_targets: Tuple[Tuple[MCPServer, str, str], ...] = ( + delegate_targets: tuple[tuple[MCPServer, str, str], ...] = ( tuple( (srv, delegate_auth, requested_single_target) for srv in allowed_servers @@ -3931,7 +4088,7 @@ if MCP_AVAILABLE: # Token is missing or expired: keep pass-through clients on the # protected-resource discovery flow so they re-authorize against # the upstream IdP metadata proxied by LiteLLM. - www_authenticate = _get_passthrough_www_authenticate( + www_authenticate = get_passthrough_www_authenticate( scope=scope, server_name=challenge_server_name, invalid_token=True, @@ -3978,7 +4135,7 @@ if MCP_AVAILABLE: # Apply toolset scope if set server-side via ContextVar (set by # /toolset/{name}/mcp and /{name}/mcp route handlers in proxy_server.py). active_toolset_id = _mcp_active_toolset_id.get() - toolset_allowed_server_ids: Optional[Set[str]] = None + toolset_allowed_server_ids: set[str] | None = None if active_toolset_id and user_api_key_auth is not None: user_api_key_auth = await _apply_toolset_scope(user_api_key_auth, active_toolset_id) op = user_api_key_auth.object_permission @@ -4029,7 +4186,7 @@ if MCP_AVAILABLE: # - No session ID + other → stateless (curl, Inspector, Notion) session_id = _get_session_id_from_scope(scope) is_initialize = False - consumed_messages: List[Message] = [] + consumed_messages: list[Message] = [] # Owner-binding: a live stateful session may only be driven by the # caller that created it. Reject mismatches with 403 so a leaked @@ -4163,11 +4320,11 @@ if MCP_AVAILABLE: "top-level key scan, skipping session lock to avoid deadlock" ) - session_lock: Optional[asyncio.Lock] = None + session_lock: asyncio.Lock | None = None if use_stateful and session_id and request_method in ("POST", "DELETE") and not is_jsonrpc_response: session_lock = _stateful_session_locks.setdefault(session_id, asyncio.Lock()) - active_request_session_ids: List[str] = [] + active_request_session_ids: list[str] = [] def _increment_active_request_session(session_id_to_track: str) -> None: if session_id_to_track in active_request_session_ids: @@ -4186,6 +4343,7 @@ if MCP_AVAILABLE: _increment_active_request_session(initialized_session_id) async def _dispatch() -> None: + _otel_publish_transport_span_on_scope(scope) auth_user = _set_or_update_auth_context( user_api_key_auth=user_api_key_auth, mcp_auth_header=mcp_auth_header, @@ -4299,7 +4457,7 @@ if MCP_AVAILABLE: # downstream probe list matches the fully-authorized server set # (mirrors the streamable HTTP handler). active_toolset_id = _mcp_active_toolset_id.get() - toolset_allowed_server_ids: Optional[Set[str]] = None + toolset_allowed_server_ids: set[str] | None = None if active_toolset_id and user_api_key_auth is not None: user_api_key_auth = await _apply_toolset_scope(user_api_key_auth, active_toolset_id) op = user_api_key_auth.object_permission @@ -4395,7 +4553,7 @@ if MCP_AVAILABLE: "/enabled", description="Returns if the MCP server is enabled", ) - def get_mcp_server_enabled() -> Dict[str, bool]: + def get_mcp_server_enabled() -> dict[str, bool]: """ Returns if the MCP server is enabled """ @@ -4414,13 +4572,13 @@ if MCP_AVAILABLE: def _update_auth_context( auth_user: MCPAuthenticatedUser, - user_api_key_auth: Optional[UserAPIKeyAuth], - mcp_auth_header: Optional[str] = None, - mcp_servers: Optional[List[str]] = None, - mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]] = None, - oauth2_headers: Optional[Dict[str, str]] = None, - raw_headers: Optional[Dict[str, str]] = None, - client_ip: Optional[str] = None, + user_api_key_auth: UserAPIKeyAuth | None, + mcp_auth_header: str | None = None, + mcp_servers: list[str] | None = None, + mcp_server_auth_headers: dict[str, dict[str, str]] | None = None, + oauth2_headers: dict[str, str] | None = None, + raw_headers: dict[str, str] | None = None, + client_ip: str | None = None, ) -> None: auth_user.user_api_key_auth = user_api_key_auth auth_user.mcp_auth_header = mcp_auth_header @@ -4431,13 +4589,13 @@ if MCP_AVAILABLE: auth_user.client_ip = client_ip def set_auth_context( - user_api_key_auth: Optional[UserAPIKeyAuth], - mcp_auth_header: Optional[str] = None, - mcp_servers: Optional[List[str]] = None, - mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]] = None, - oauth2_headers: Optional[Dict[str, str]] = None, - raw_headers: Optional[Dict[str, str]] = None, - client_ip: Optional[str] = None, + user_api_key_auth: UserAPIKeyAuth | None, + mcp_auth_header: str | None = None, + mcp_servers: list[str] | None = None, + mcp_server_auth_headers: dict[str, dict[str, str]] | None = None, + oauth2_headers: dict[str, str] | None = None, + raw_headers: dict[str, str] | None = None, + client_ip: str | None = None, ) -> MCPAuthenticatedUser: """ Set the UserAPIKeyAuth in the auth context variable. @@ -4462,14 +4620,14 @@ if MCP_AVAILABLE: return auth_user def _set_or_update_auth_context( - user_api_key_auth: Optional[UserAPIKeyAuth], - mcp_auth_header: Optional[str] = None, - mcp_servers: Optional[List[str]] = None, - mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]] = None, - oauth2_headers: Optional[Dict[str, str]] = None, - raw_headers: Optional[Dict[str, str]] = None, - client_ip: Optional[str] = None, - session_id: Optional[str] = None, + user_api_key_auth: UserAPIKeyAuth | None, + mcp_auth_header: str | None = None, + mcp_servers: list[str] | None = None, + mcp_server_auth_headers: dict[str, dict[str, str]] | None = None, + oauth2_headers: dict[str, str] | None = None, + raw_headers: dict[str, str] | None = None, + client_ip: str | None = None, + session_id: str | None = None, touch_last_seen: bool = True, copy_existing_session_auth_context: bool = False, ) -> MCPAuthenticatedUser: @@ -4513,7 +4671,7 @@ if MCP_AVAILABLE: send: Send, auth_user: MCPAuthenticatedUser, owner_fingerprint: str, - on_session_registered: Optional[Callable[[str], None]] = None, + on_session_registered: Callable[[str], None] | None = None, ) -> Send: async def wrapped_send(message: Message) -> None: if message.get("type") == "http.response.start": @@ -4532,14 +4690,14 @@ if MCP_AVAILABLE: return wrapped_send - def get_auth_context() -> Tuple[ - Optional[UserAPIKeyAuth], - Optional[str], - Optional[List[str]], - Optional[Dict[str, Dict[str, str]]], - Optional[Dict[str, str]], - Optional[Dict[str, str]], - Optional[str], + def get_auth_context() -> tuple[ + UserAPIKeyAuth | None, + str | None, + list[str] | None, + dict[str, dict[str, str]] | None, + dict[str, str] | None, + dict[str, str] | None, + str | None, ]: """ Get the UserAPIKeyAuth from the auth context variable. @@ -4593,12 +4751,12 @@ if MCP_AVAILABLE: "session identity — session object is unhashable" ) - def _recover_auth_from_session() -> Optional[MCPAuthenticatedUser]: + def _recover_auth_from_session() -> MCPAuthenticatedUser | None: session = _get_current_session() if session is None: return None - stored: Optional[MCPAuthenticatedUser] = None + stored: MCPAuthenticatedUser | None = None try: stored = _session_obj_auth_storage.get(session) except TypeError: @@ -4610,14 +4768,14 @@ if MCP_AVAILABLE: return stored - async def get_or_extract_auth_context() -> Tuple[ - Optional[UserAPIKeyAuth], - Optional[str], - Optional[List[str]], - Optional[Dict[str, Dict[str, str]]], - Optional[Dict[str, str]], - Optional[Dict[str, str]], - Optional[str], + async def get_or_extract_auth_context() -> tuple[ + UserAPIKeyAuth | None, + str | None, + list[str] | None, + dict[str, dict[str, str]] | None, + dict[str, str] | None, + dict[str, str] | None, + str | None, ]: """ Get auth context from ContextVar first, then fall back to session @@ -4656,14 +4814,14 @@ if MCP_AVAILABLE: _client_ip, ) - def get_active_mcp_session() -> Optional[_McpServerSession]: + def get_active_mcp_session() -> _McpServerSession | None: """Return the active MCP session captured during handler execution.""" session = active_mcp_session_var.get() if session is not None: return session return _get_current_session() - def get_active_auth_context() -> Optional[MCPAuthenticatedUser]: + def get_active_auth_context() -> MCPAuthenticatedUser | None: """Return auth context from ContextVar or session storage.""" auth = auth_context_var.get() if auth and isinstance(auth, MCPAuthenticatedUser): diff --git a/litellm/proxy/_experimental/mcp_server/ui_session_utils.py b/litellm/proxy/_experimental/mcp_server/ui_session_utils.py index 1b37b884987..d1d28574988 100644 --- a/litellm/proxy/_experimental/mcp_server/ui_session_utils.py +++ b/litellm/proxy/_experimental/mcp_server/ui_session_utils.py @@ -1,9 +1,11 @@ -"""Helpers to resolve real team contexts for UI session tokens.""" +"""Helpers to resolve the identity a dashboard UI session token acts as.""" from __future__ import annotations from typing import List +from fastapi import HTTPException + from litellm._logging import verbose_logger from litellm.constants import UI_SESSION_TOKEN_TEAM_ID from litellm.proxy._types import UserAPIKeyAuth @@ -23,12 +25,19 @@ def clone_user_api_key_auth_with_team( return cloned_auth +def is_ui_session_credential(user_api_key_auth: UserAPIKeyAuth) -> bool: + """Whether the caller is the dashboard's SSO-minted session token acting as its user, + the only credential shape allowed to widen a request to the owning user's identity.""" + + return user_api_key_auth.team_id == UI_SESSION_TOKEN_TEAM_ID and bool(user_api_key_auth.user_id) + + async def resolve_ui_session_team_ids( user_api_key_auth: UserAPIKeyAuth, ) -> List[str]: """Resolve the real team ids backing a UI session token.""" - if user_api_key_auth.team_id != UI_SESSION_TOKEN_TEAM_ID or not user_api_key_auth.user_id: + if not is_ui_session_credential(user_api_key_auth): return [] from litellm.proxy.auth.auth_checks import get_user_object @@ -68,12 +77,63 @@ async def resolve_ui_session_team_ids( return resolved_team_ids +async def admitted_user_context(user_api_key_auth: UserAPIKeyAuth) -> UserAPIKeyAuth | None: + """THE owner of "resolve this dashboard session's user identity": the same admitted-subject auth a + gateway OAuth session for this user resolves with, carrying the user row's own object permission, + on this request's tracing span. None for any other credential (a caller-passed key is never + widened) and on reload failure, which every caller reads as "no user-level identity available".""" + + user_id = user_api_key_auth.user_id + if not is_ui_session_credential(user_api_key_auth) or user_id is None: + return None + from litellm.proxy._experimental.mcp_server.auth.user_api_key_auth_mcp import ( + MCPRequestHandler, + ) + + try: + admitted = await MCPRequestHandler._reload_admitted_user(user_id) + except HTTPException as e: + verbose_logger.warning(f"MCP dashboard session: admitted-subject reload failed for {user_id}: {e.detail}") + return None + return admitted.model_copy(update={"parent_otel_span": user_api_key_auth.parent_otel_span}) + + +async def acting_user_auth(user_api_key_auth: UserAPIKeyAuth) -> UserAPIKeyAuth: + """The principal acting-as-user MCP routes resolve permissions with. A non-admin dashboard + session acts as the admitted subject, the same identity a gateway session resolves with, so + server reachability, per-source tool ceilings, rate limits, and billing bind identically on + both surfaces. An admin session keeps its operator view and any caller-passed credential is + returned unchanged, never widened. + + Do not combine this with a narrowing that rewrites a single credential's ``object_permission`` + (toolset scope): the admitted subject resolves per grant source and a team source deliberately + carries none of the caller's own grants, so the narrowing would silently evaporate on every + team-granted server. A request carrying such a scope keeps the caller's own credential.""" + + if not is_ui_session_credential(user_api_key_auth): + return user_api_key_auth + from litellm.proxy.management_endpoints.common_utils import _user_has_admin_view + + if _user_has_admin_view(user_api_key_auth): + return user_api_key_auth + admitted = await admitted_user_context(user_api_key_auth) + return admitted if admitted is not None else user_api_key_auth + + async def build_effective_auth_contexts( user_api_key_auth: UserAPIKeyAuth, ) -> List[UserAPIKeyAuth]: - """Return auth contexts that reflect the actual teams for UI session tokens.""" + """Every auth context a management or listing surface must resolve a UI session token through: + one per real team backing the session, plus the session user's own admitted identity, so a grant + made directly to the user row is as visible to the dashboard as it is to a gateway session.""" resolved_team_ids = await resolve_ui_session_team_ids(user_api_key_auth) - if resolved_team_ids: - return [clone_user_api_key_auth_with_team(user_api_key_auth, team_id) for team_id in resolved_team_ids] - return [user_api_key_auth] + team_contexts = ( + [clone_user_api_key_auth_with_team(user_api_key_auth, team_id) for team_id in resolved_team_ids] + if resolved_team_ids + else [user_api_key_auth] + ) + admitted_context = await admitted_user_context(user_api_key_auth) + if admitted_context is None: + return team_contexts + return [*team_contexts, admitted_context] diff --git a/litellm/proxy/_experimental/mcp_server/utils.py b/litellm/proxy/_experimental/mcp_server/utils.py index 80a469b8c1a..698df147247 100644 --- a/litellm/proxy/_experimental/mcp_server/utils.py +++ b/litellm/proxy/_experimental/mcp_server/utils.py @@ -2,8 +2,12 @@ MCP Server Utilities """ +import hashlib +import importlib import json +import os import re +from collections.abc import MutableMapping, MutableSequence from typing import ( Any, Dict, @@ -16,12 +20,10 @@ from typing import ( Tuple, Union, ) - -import hashlib -import importlib -import os from urllib.parse import quote +from litellm.types.mcp_server.mcp_server_manager import MCPServer + # Constants # # NOTE: The environment-backed values below are read once, when this module is @@ -325,8 +327,59 @@ def iter_known_server_prefixes(server: Any) -> Iterator[str]: yield from _emit(server_id) +def iter_known_tool_name_spellings(tool_name: str, server: MCPServer) -> Iterator[str]: + """Yield every name that denotes the bare ``tool_name`` on ``server``: the bare name, + then its wire spelling under each prefix ``iter_known_server_prefixes`` accepts. + ``get_server_prefix`` covers only the currently published one, and that moves with the + alias and with ``LITELLM_USE_SHORT_MCP_TOOL_PREFIX``. + """ + yield tool_name + for prefix in iter_known_server_prefixes(server): + yield add_server_prefix_to_name(tool_name, prefix) + + +def openapi_tool_name(operation_id: str) -> str: + """Return the tool name ``_register_openapi_tools`` registers ``operation_id`` under. + + The single transform between a spec's operationId and the name the gateway serves. + Policy recovers the link by replaying this exact function, which is what keeps it from + deciding for a tool it does not name: two operationIds that register as two tools + necessarily normalize to two names here, because this is the map that registered them. + """ + return operation_id.replace(" ", "_").lower() + + +def match_known_tool_name(tool_name: str, server: MCPServer, names: Iterable[str]) -> str | None: + """Return the entry of ``names`` that denotes ``tool_name`` on ``server``, else ``None``. + + The single question every tool-name-keyed site asks: the allow list, the deny list, + ``allowed_params`` and the discovery filter, so discovery hides exactly what dispatch + refuses. It spans every spelling routing accepts and no more, because a tool's identity + is the exact name routing dispatches; anything looser lets one policy decide two tools. + + On an OpenAPI server the configured entry holds the spec's operationId while routing + holds :func:`openapi_tool_name` of it, so both sides go through that map first. Doing it + with the registering function rather than a lookalike is the whole safety argument: a + coarser one collapses operationIds that registration keeps apart. + + Callers read the returned entry rather than testing a container's values, which is what + stops an explicitly empty ``allowed_params`` list from reading as "nothing configured". + """ + normalize = openapi_tool_name if getattr(server, "spec_path", None) else str + spellings = {normalize(spelling) for spelling in iter_known_tool_name_spellings(tool_name, server)} + return next((name for name in names if normalize(name) in spellings), None) + + def split_server_prefix_from_name(prefixed_name: str) -> Tuple[str, str]: - """Return the unprefixed name plus the server name used as prefix.""" + """Return the unprefixed name plus the server name used as prefix. + + Cuts at the FIRST separator, so the two halves are only trustworthy as a + pair: they reassemble into ``prefixed_name`` exactly, which is what makes + this safe for routing. Reading one half on its own is a guess about where the + boundary fell, and that guess is wrong whenever the prefix itself contains + the separator. Callers that compare a half against configuration must use + :func:`match_known_server_prefix` or :func:`strip_known_server_prefix`. + """ if MCP_TOOL_PREFIX_SEPARATOR in prefixed_name: parts = prefixed_name.split(MCP_TOOL_PREFIX_SEPARATOR, 1) if len(parts) == 2: @@ -334,6 +387,27 @@ def split_server_prefix_from_name(prefixed_name: str) -> Tuple[str, str]: return prefixed_name, "" +def match_known_server_prefix(name: str, known_prefixes: Iterable[str]) -> tuple[str, str] | None: + """Return ``(matched_prefix, bare_name)`` when ``name`` carries a known prefix. + + Candidates are normalized and tried LONGEST first, so a prefix that itself + contains :data:`MCP_TOOL_PREFIX_SEPARATOR` (the UUID ``server_id`` used when + a server has no alias, or a legacy hyphenated alias) wins over a shorter + prefix that is merely its leading segment. Returns ``None`` when no candidate + matches, i.e. ``name`` carries none of these prefixes. + """ + candidates = sorted( + {normalize_server_name(prefix) for prefix in known_prefixes if prefix}, + key=len, + reverse=True, + ) + for prefix in candidates: + separator_suffixed = prefix + MCP_TOOL_PREFIX_SEPARATOR + if name.startswith(separator_suffixed): + return prefix, name[len(separator_suffixed) :] + return None + + def strip_known_server_prefix(name: str, server: Optional[Any]) -> str: """Strip ``server``'s registered prefix from a prefixed tool/resource name. @@ -351,11 +425,8 @@ def strip_known_server_prefix(name: str, server: Optional[Any]) -> str: """ if server is None: return split_server_prefix_from_name(name)[0] - for prefix in iter_known_server_prefixes(server): - candidate = normalize_server_name(prefix) + MCP_TOOL_PREFIX_SEPARATOR - if name.startswith(candidate): - return name[len(candidate) :] - return name + matched = match_known_server_prefix(name, iter_known_server_prefixes(server)) + return name if matched is None else matched[1] def is_tool_name_prefixed( @@ -366,15 +437,16 @@ def is_tool_name_prefixed( Check if tool name has a known MCP server prefix. When ``known_server_prefixes`` is provided the function verifies that the - substring before the first separator is an actual registered server - prefix. Without it the check falls back to the legacy heuristic + name actually starts with one of those prefixes followed by the separator, + matching the longest candidate first so a prefix containing the separator + still resolves. Without it the check falls back to the legacy heuristic (separator present anywhere in the name), which can produce false positives for non-MCP tools whose names contain hyphens (e.g. ``text-to-speech``, ``code-review``). Args: tool_name: Tool name to check. - known_server_prefixes: Optional set of normalised server prefixes + known_server_prefixes: Optional set of normalized server prefixes currently registered in the MCP manager. Pass this whenever the caller has access to the server registry so that the check is accurate. @@ -386,8 +458,7 @@ def is_tool_name_prefixed( return False if known_server_prefixes is not None: - candidate_prefix = tool_name.split(MCP_TOOL_PREFIX_SEPARATOR, 1)[0] - return normalize_server_name(candidate_prefix) in known_server_prefixes + return match_known_server_prefix(tool_name, known_server_prefixes) is not None # Legacy fallback – separator present somewhere in the name. return True @@ -434,6 +505,56 @@ def extract_mcp_tool_result_error_message(result: object) -> Optional[str]: return "MCP tool call returned isError=true" +def mcp_tool_result_content_list(result: object) -> MutableSequence[object] | None: # mutable-ok: see below + """The mutable content list of an MCP tool result, or ``None`` when it has none. + + Deliberately mutable: a guardrail masking the result rewrites entries in place, + because the logging payload captured before the guardrail runs references this + same list, so handing back a copy would leave the unmasked text in the spend log + and the OTel span. + + Accepts both ``mcp.types.CallToolResult`` objects and their dict + equivalents, duck-typed so the ``mcp`` package is not required. + """ + content: object = result.get("content") if isinstance(result, Mapping) else getattr(result, "content", None) + if isinstance(content, MutableSequence): + return content + return None + + +def mcp_content_item_text(item: object) -> str | None: + """The ``text`` of a rewritable MCP content item, or ``None``. + + Only mappings and Pydantic-style models report a text, because those are the + only shapes ``with_mcp_content_item_text`` can rewrite; a caller therefore + never reads text it would be unable to write back (e.g. masked by a + guardrail). Non-text content (images, embedded resources) has no ``text`` + and is reported as ``None``. + """ + text: object + if isinstance(item, Mapping): + text = item.get("text") + elif callable(getattr(item, "model_copy", None)): + text = getattr(item, "text", None) + else: + return None + return text if isinstance(text, str) else None + + +def with_mcp_content_item_text(item: object, text: str) -> object: + """A copy of an MCP content item carrying ``text`` instead of its own. + + Only meaningful for items ``mcp_content_item_text`` returned a text for; any + other item is returned unchanged. + """ + if isinstance(item, Mapping): + return {**item, "text": text} + model_copy = getattr(item, "model_copy", None) + if callable(model_copy): + return model_copy(update={"text": text}) + return item + + TOOL_DISPLAY_NAME_PATTERN = re.compile(r"^[a-zA-Z0-9_-]+$") @@ -618,3 +739,112 @@ def merge_mcp_headers( merged.update({str(k): str(v) for k, v in static_headers.items()}) return merged or None + + +# Local rather than litellm.constants: this module deliberately imports no litellm +# package, so pulling one in for a single integer would drag in litellm/__init__. +MAX_STRUCTURED_CONTENT_SCAN_DEPTH = 100 + + +JSONLeafPath = tuple[str | int, ...] + + +def _flatten_leaf_groups( + groups: Iterable[tuple[tuple[JSONLeafPath, str], ...] | None], +) -> tuple[tuple[JSONLeafPath, str], ...] | None: + """Concatenate child leaf groups, propagating the too-deep sentinel.""" + materialized = tuple(groups) + if any(group is None for group in materialized): + return None + return tuple(leaf for group in materialized if group is not None for leaf in group) + + +def json_string_leaves(value: object, path: JSONLeafPath = ()) -> tuple[tuple[JSONLeafPath, str], ...] | None: + """Depth-first, deterministically ordered string leaves of a JSON value. + + Returns ``None`` when the value is nested past ``MAX_STRUCTURED_CONTENT_SCAN_DEPTH``, + so the caller blocks rather than letting deeper values through unscanned; an + empty tuple means there was simply nothing to scan. A sentinel rather than an + exception because this module is reloaded by tests (see the note above the + environment-backed constants), which would give a custom exception class a new + identity and let it escape a caller's ``except``. + """ + if len(path) > MAX_STRUCTURED_CONTENT_SCAN_DEPTH: + return None + if isinstance(value, str): + return ((path, value),) + if isinstance(value, dict): + return _flatten_leaf_groups(json_string_leaves(item, (*path, key)) for key, item in value.items()) + if isinstance(value, list): + return _flatten_leaf_groups(json_string_leaves(item, (*path, index)) for index, item in enumerate(value)) + return () + + +def with_json_string_leaves( + value: object, + replacements: Mapping[JSONLeafPath, str], + path: JSONLeafPath = (), +) -> object: + """Rebuild a JSON value with the guardrail's rewritten string leaves.""" + if isinstance(value, str): + return replacements.get(path, value) + if isinstance(value, dict): + return {key: with_json_string_leaves(item, replacements, (*path, key)) for key, item in value.items()} + if isinstance(value, list): + return [with_json_string_leaves(item, replacements, (*path, index)) for index, item in enumerate(value)] + return value + + +def json_unrewritable_labels(value: object, path_depth: int = 0) -> tuple[str, ...] | None: + """Strings in a JSON value that carry meaning but cannot be rewritten. + + Dictionary keys and non-string scalars: masking either would change the + payload's contract rather than redact a value, so a caller scans these and + blocks on a match instead of rewriting, matching what the content filter + already does for MCP tool call arguments. ``None`` means the value is nested + past the scan depth, same contract as ``json_string_leaves``. + """ + if path_depth > MAX_STRUCTURED_CONTENT_SCAN_DEPTH: + return None + if isinstance(value, bool) or value is None or isinstance(value, str): + return () + if isinstance(value, (int, float)): + return (str(value),) + if isinstance(value, dict): + own = tuple(key for key in value if isinstance(key, str)) + nested = tuple(json_unrewritable_labels(item, path_depth + 1) for item in value.values()) + if any(group is None for group in nested): + return None + return own + tuple(label for group in nested if group is not None for label in group) + if isinstance(value, list): + nested = tuple(json_unrewritable_labels(item, path_depth + 1) for item in value) + if any(group is None for group in nested): + return None + return tuple(label for group in nested if group is not None for label in group) + return () + + +def mcp_tool_result_structured_content(result: object) -> object: + """The ``structuredContent`` of an MCP tool result, or ``None`` when it has none.""" + if isinstance(result, Mapping): + return result.get("structuredContent") + return getattr(result, "structuredContent", None) + + +def set_mcp_tool_result_structured_content(result: object, value: object) -> bool: + """Replace ``structuredContent`` in place; ``False`` when the shape does not carry it. + + In place for the same reason the content list is: the logging payload captured + before the guardrail ran references this object, so a copy would leave the + unmasked value in the spend log and the OTel span. + """ + if isinstance(result, MutableMapping): + result["structuredContent"] = value + return True + if not hasattr(result, "structuredContent"): + return False + try: + setattr(result, "structuredContent", value) # attribute name is fixed by the MCP result shape + return True + except (AttributeError, TypeError, ValueError): + return False diff --git a/litellm/proxy/_experimental/out/404.html b/litellm/proxy/_experimental/out/404.html index ceb6e41472c..0a164642dab 100644 --- a/litellm/proxy/_experimental/out/404.html +++ b/litellm/proxy/_experimental/out/404.html @@ -1 +1 @@ -404: This page could not be found.LiteLLM Dashboard

404

This page could not be found.

\ No newline at end of file +404: This page could not be found.LiteLLM Dashboard

404

This page could not be found.

\ No newline at end of file diff --git a/litellm/proxy/_experimental/out/404/index.html b/litellm/proxy/_experimental/out/404/index.html index ceb6e41472c..0a164642dab 100644 --- a/litellm/proxy/_experimental/out/404/index.html +++ b/litellm/proxy/_experimental/out/404/index.html @@ -1 +1 @@ -404: This page could not be found.LiteLLM Dashboard

404

This page could not be found.

\ No newline at end of file +404: This page could not be found.LiteLLM Dashboard

404

This page could not be found.

\ No newline at end of file diff --git a/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.__PAGE__.txt b/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.__PAGE__.txt index 229b0276e5f..c10ced8b6bc 100644 --- a/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.__PAGE__.txt +++ b/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.__PAGE__.txt @@ -1,9 +1,9 @@ 1:"$Sreact.fragment" -2:I[347257,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"ClientPageRoot"] -3:I[871135,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js","/litellm-asset-prefix/_next/static/chunks/0mqbd99.ej13v.js","/litellm-asset-prefix/_next/static/chunks/16ufy1iyybswo.js","/litellm-asset-prefix/_next/static/chunks/0ayum-x.hkww~.js","/litellm-asset-prefix/_next/static/chunks/15jl-1gcakfwa.js","/litellm-asset-prefix/_next/static/chunks/003_1s9xbht43.js","/litellm-asset-prefix/_next/static/chunks/0u.r3vzo30ofk.js","/litellm-asset-prefix/_next/static/chunks/0g4qcx-c9gsxn.js","/litellm-asset-prefix/_next/static/chunks/14a-un1blorp~.js","/litellm-asset-prefix/_next/static/chunks/02_q4881cz6h~.js","/litellm-asset-prefix/_next/static/chunks/0lg.6rbfsd-l9.js","/litellm-asset-prefix/_next/static/chunks/0wdlbe750tuzr.js","/litellm-asset-prefix/_next/static/chunks/043q3g5-5-aju.js","/litellm-asset-prefix/_next/static/chunks/0nht59ws0elww.js","/litellm-asset-prefix/_next/static/chunks/03zkt5iyjiqcz.js","/litellm-asset-prefix/_next/static/chunks/0l02mpo6za6ie.js","/litellm-asset-prefix/_next/static/chunks/1667t2pcy0iqm.js","/litellm-asset-prefix/_next/static/chunks/0-_m4km7b1~oe.js","/litellm-asset-prefix/_next/static/chunks/0sx3mu2_l9g_y.js","/litellm-asset-prefix/_next/static/chunks/0sqw622fcvsv4.js","/litellm-asset-prefix/_next/static/chunks/0t8el_ijoskx..js","/litellm-asset-prefix/_next/static/chunks/0el08tticy_20.js","/litellm-asset-prefix/_next/static/chunks/0a.ljputcx8g5.js","/litellm-asset-prefix/_next/static/chunks/02-u6qtmsnqn0.js","/litellm-asset-prefix/_next/static/chunks/076.vm.7w-x2..js","/litellm-asset-prefix/_next/static/chunks/069dx5~5osue0.js","/litellm-asset-prefix/_next/static/chunks/0onea0n77pqw1.js","/litellm-asset-prefix/_next/static/chunks/16jfov1k2wrj0.js","/litellm-asset-prefix/_next/static/chunks/0l7em-5kjv49e.js","/litellm-asset-prefix/_next/static/chunks/0mh1wnrvmv_y7.js","/litellm-asset-prefix/_next/static/chunks/01reddhq423_f.js","/litellm-asset-prefix/_next/static/chunks/0h80lrrstjswl.js","/litellm-asset-prefix/_next/static/chunks/0cmepm.jkel-i.js","/litellm-asset-prefix/_next/static/chunks/0q6~n4y84cejn.js","/litellm-asset-prefix/_next/static/chunks/04jv9e6~9vi.l.js","/litellm-asset-prefix/_next/static/chunks/0d_sm.._5mw-p.js","/litellm-asset-prefix/_next/static/chunks/0elr0ye86.44-.js"],"default"] -6:I[897367,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"OutletBoundary"] +2:I[347257,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"ClientPageRoot"] +3:I[871135,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js","/litellm-asset-prefix/_next/static/chunks/1ioy8obpggx93.js","/litellm-asset-prefix/_next/static/chunks/3_3dj4vdy-3xy.js","/litellm-asset-prefix/_next/static/chunks/1zr7rrk4wkmju.js","/litellm-asset-prefix/_next/static/chunks/2cngn5bal3278.js","/litellm-asset-prefix/_next/static/chunks/2up3bks93iqds.js","/litellm-asset-prefix/_next/static/chunks/0fk0i3e2aixp7.js","/litellm-asset-prefix/_next/static/chunks/0zduf1gntl_f8.js","/litellm-asset-prefix/_next/static/chunks/0dbvgsc7ha049.js","/litellm-asset-prefix/_next/static/chunks/0g_w4tf2inv3i.js","/litellm-asset-prefix/_next/static/chunks/1vquuz09jxl5_.js","/litellm-asset-prefix/_next/static/chunks/17-6zku8f68gf.js","/litellm-asset-prefix/_next/static/chunks/1iakmimqrlpn0.js","/litellm-asset-prefix/_next/static/chunks/1a0bgy7kzrj91.js","/litellm-asset-prefix/_next/static/chunks/0f5fel02jwglw.js","/litellm-asset-prefix/_next/static/chunks/0g8wwba6umbim.js","/litellm-asset-prefix/_next/static/chunks/1di-caw05k3tq.js","/litellm-asset-prefix/_next/static/chunks/00g6xfr4yow7h.js","/litellm-asset-prefix/_next/static/chunks/2kcxwg1mpncp6.js","/litellm-asset-prefix/_next/static/chunks/1fmx49l6q8v39.js","/litellm-asset-prefix/_next/static/chunks/0ww76lz_0cphv.js","/litellm-asset-prefix/_next/static/chunks/2uc2pi4ob086w.js","/litellm-asset-prefix/_next/static/chunks/2hu1vyy-5pv13.js","/litellm-asset-prefix/_next/static/chunks/2l25bmiiw9ixp.js","/litellm-asset-prefix/_next/static/chunks/1uz3jt-tj9lkf.js","/litellm-asset-prefix/_next/static/chunks/3drq2_k-jeio2.js","/litellm-asset-prefix/_next/static/chunks/0dsiq_ok1yngk.js","/litellm-asset-prefix/_next/static/chunks/3srzg1la93pwv.js","/litellm-asset-prefix/_next/static/chunks/17nqbxvhztf3k.js","/litellm-asset-prefix/_next/static/chunks/2c90xukbd3il6.js","/litellm-asset-prefix/_next/static/chunks/0kap_rdm2-lem.js","/litellm-asset-prefix/_next/static/chunks/09l_m9l1emin2.js","/litellm-asset-prefix/_next/static/chunks/1cea03gg5a_c7.js","/litellm-asset-prefix/_next/static/chunks/323l6h8s7ahat.js","/litellm-asset-prefix/_next/static/chunks/112n0hv3cc2rg.js","/litellm-asset-prefix/_next/static/chunks/199uwr871eene.js","/litellm-asset-prefix/_next/static/chunks/105643dvf00hu.js","/litellm-asset-prefix/_next/static/chunks/12wsfsljxg4xv.js","/litellm-asset-prefix/_next/static/chunks/22iools_e0k44.js","/litellm-asset-prefix/_next/static/chunks/0am68mi9t9cb6.js","/litellm-asset-prefix/_next/static/chunks/23-g73xaw3kap.js"],"default"] +6:I[897367,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"OutletBoundary"] 7:"$Sreact.suspense" -0:{"rsc":["$","$1","c",{"children":[["$","$L2",null,{"Component":"$3","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@4","$@5"]}}],[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/1667t2pcy0iqm.js","async":true}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/0-_m4km7b1~oe.js","async":true}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/0sx3mu2_l9g_y.js","async":true}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/0sqw622fcvsv4.js","async":true}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/0t8el_ijoskx..js","async":true}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/0el08tticy_20.js","async":true}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/0a.ljputcx8g5.js","async":true}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/02-u6qtmsnqn0.js","async":true}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/076.vm.7w-x2..js","async":true}],["$","script","script-9",{"src":"/litellm-asset-prefix/_next/static/chunks/069dx5~5osue0.js","async":true}],["$","script","script-10",{"src":"/litellm-asset-prefix/_next/static/chunks/0onea0n77pqw1.js","async":true}],["$","script","script-11",{"src":"/litellm-asset-prefix/_next/static/chunks/16jfov1k2wrj0.js","async":true}],["$","script","script-12",{"src":"/litellm-asset-prefix/_next/static/chunks/0l7em-5kjv49e.js","async":true}],["$","script","script-13",{"src":"/litellm-asset-prefix/_next/static/chunks/0mh1wnrvmv_y7.js","async":true}],["$","script","script-14",{"src":"/litellm-asset-prefix/_next/static/chunks/01reddhq423_f.js","async":true}],["$","script","script-15",{"src":"/litellm-asset-prefix/_next/static/chunks/0h80lrrstjswl.js","async":true}],["$","script","script-16",{"src":"/litellm-asset-prefix/_next/static/chunks/0cmepm.jkel-i.js","async":true}],["$","script","script-17",{"src":"/litellm-asset-prefix/_next/static/chunks/0q6~n4y84cejn.js","async":true}],["$","script","script-18",{"src":"/litellm-asset-prefix/_next/static/chunks/04jv9e6~9vi.l.js","async":true}],["$","script","script-19",{"src":"/litellm-asset-prefix/_next/static/chunks/0d_sm.._5mw-p.js","async":true}],["$","script","script-20",{"src":"/litellm-asset-prefix/_next/static/chunks/0elr0ye86.44-.js","async":true}]],["$","$L6",null,{"children":["$","$7",null,{"name":"Next.MetadataOutlet","children":"$@8"}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"DSHomUr6Sq46Bm2WLdUas"} +0:{"rsc":["$","$1","c",{"children":[["$","$L2",null,{"Component":"$3","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@4","$@5"]}}],[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/00g6xfr4yow7h.js","async":true}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/2kcxwg1mpncp6.js","async":true}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/1fmx49l6q8v39.js","async":true}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/0ww76lz_0cphv.js","async":true}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/2uc2pi4ob086w.js","async":true}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/2hu1vyy-5pv13.js","async":true}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/2l25bmiiw9ixp.js","async":true}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/1uz3jt-tj9lkf.js","async":true}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/3drq2_k-jeio2.js","async":true}],["$","script","script-9",{"src":"/litellm-asset-prefix/_next/static/chunks/0dsiq_ok1yngk.js","async":true}],["$","script","script-10",{"src":"/litellm-asset-prefix/_next/static/chunks/3srzg1la93pwv.js","async":true}],["$","script","script-11",{"src":"/litellm-asset-prefix/_next/static/chunks/17nqbxvhztf3k.js","async":true}],["$","script","script-12",{"src":"/litellm-asset-prefix/_next/static/chunks/2c90xukbd3il6.js","async":true}],["$","script","script-13",{"src":"/litellm-asset-prefix/_next/static/chunks/0kap_rdm2-lem.js","async":true}],["$","script","script-14",{"src":"/litellm-asset-prefix/_next/static/chunks/09l_m9l1emin2.js","async":true}],["$","script","script-15",{"src":"/litellm-asset-prefix/_next/static/chunks/1cea03gg5a_c7.js","async":true}],["$","script","script-16",{"src":"/litellm-asset-prefix/_next/static/chunks/323l6h8s7ahat.js","async":true}],["$","script","script-17",{"src":"/litellm-asset-prefix/_next/static/chunks/112n0hv3cc2rg.js","async":true}],["$","script","script-18",{"src":"/litellm-asset-prefix/_next/static/chunks/199uwr871eene.js","async":true}],["$","script","script-19",{"src":"/litellm-asset-prefix/_next/static/chunks/105643dvf00hu.js","async":true}],["$","script","script-20",{"src":"/litellm-asset-prefix/_next/static/chunks/12wsfsljxg4xv.js","async":true}],["$","script","script-21",{"src":"/litellm-asset-prefix/_next/static/chunks/22iools_e0k44.js","async":true}],["$","script","script-22",{"src":"/litellm-asset-prefix/_next/static/chunks/0am68mi9t9cb6.js","async":true}],["$","script","script-23",{"src":"/litellm-asset-prefix/_next/static/chunks/23-g73xaw3kap.js","async":true}]],["$","$L6",null,{"children":["$","$7",null,{"name":"Next.MetadataOutlet","children":"$@8"}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"qXutWsQW5C1Pf62WxTkEI"} 4:{} 5:"$0:rsc:props:children:0:props:serverProvidedParams:params" 8:null diff --git a/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.txt b/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.txt index 09471b4b64e..ef8a75b27ce 100644 --- a/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.txt +++ b/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.txt @@ -1,7 +1,7 @@ 1:"$Sreact.fragment" -2:I[92825,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"ClientSegmentRoot"] -3:I[216370,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js","/litellm-asset-prefix/_next/static/chunks/0mqbd99.ej13v.js","/litellm-asset-prefix/_next/static/chunks/16ufy1iyybswo.js","/litellm-asset-prefix/_next/static/chunks/0ayum-x.hkww~.js","/litellm-asset-prefix/_next/static/chunks/15jl-1gcakfwa.js","/litellm-asset-prefix/_next/static/chunks/003_1s9xbht43.js","/litellm-asset-prefix/_next/static/chunks/0u.r3vzo30ofk.js","/litellm-asset-prefix/_next/static/chunks/0g4qcx-c9gsxn.js","/litellm-asset-prefix/_next/static/chunks/14a-un1blorp~.js","/litellm-asset-prefix/_next/static/chunks/02_q4881cz6h~.js","/litellm-asset-prefix/_next/static/chunks/0lg.6rbfsd-l9.js","/litellm-asset-prefix/_next/static/chunks/0wdlbe750tuzr.js","/litellm-asset-prefix/_next/static/chunks/043q3g5-5-aju.js","/litellm-asset-prefix/_next/static/chunks/0nht59ws0elww.js","/litellm-asset-prefix/_next/static/chunks/03zkt5iyjiqcz.js","/litellm-asset-prefix/_next/static/chunks/0l02mpo6za6ie.js"],"default"] -4:I[339756,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"default"] -5:I[837457,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"default"] -0:{"rsc":["$","$1","c",{"children":[[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/0mqbd99.ej13v.js","async":true}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/16ufy1iyybswo.js","async":true}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/0ayum-x.hkww~.js","async":true}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/15jl-1gcakfwa.js","async":true}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/003_1s9xbht43.js","async":true}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/0u.r3vzo30ofk.js","async":true}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/0g4qcx-c9gsxn.js","async":true}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/14a-un1blorp~.js","async":true}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/02_q4881cz6h~.js","async":true}],["$","script","script-9",{"src":"/litellm-asset-prefix/_next/static/chunks/0lg.6rbfsd-l9.js","async":true}],["$","script","script-10",{"src":"/litellm-asset-prefix/_next/static/chunks/0wdlbe750tuzr.js","async":true}],["$","script","script-11",{"src":"/litellm-asset-prefix/_next/static/chunks/043q3g5-5-aju.js","async":true}],["$","script","script-12",{"src":"/litellm-asset-prefix/_next/static/chunks/0nht59ws0elww.js","async":true}],["$","script","script-13",{"src":"/litellm-asset-prefix/_next/static/chunks/03zkt5iyjiqcz.js","async":true}],["$","script","script-14",{"src":"/litellm-asset-prefix/_next/static/chunks/0l02mpo6za6ie.js","async":true}]],["$","$L2",null,{"Component":"$3","slots":{"children":["$","$L4",null,{"parallelRouterKey":"children","template":["$","$L5",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]},"serverProvidedParams":{"params":{},"promises":["$@6"]}}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"DSHomUr6Sq46Bm2WLdUas"} +2:I[92825,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"ClientSegmentRoot"] +3:I[216370,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js","/litellm-asset-prefix/_next/static/chunks/1ioy8obpggx93.js","/litellm-asset-prefix/_next/static/chunks/3_3dj4vdy-3xy.js","/litellm-asset-prefix/_next/static/chunks/1zr7rrk4wkmju.js","/litellm-asset-prefix/_next/static/chunks/2cngn5bal3278.js","/litellm-asset-prefix/_next/static/chunks/2up3bks93iqds.js","/litellm-asset-prefix/_next/static/chunks/0fk0i3e2aixp7.js","/litellm-asset-prefix/_next/static/chunks/0zduf1gntl_f8.js","/litellm-asset-prefix/_next/static/chunks/0dbvgsc7ha049.js","/litellm-asset-prefix/_next/static/chunks/0g_w4tf2inv3i.js","/litellm-asset-prefix/_next/static/chunks/1vquuz09jxl5_.js","/litellm-asset-prefix/_next/static/chunks/17-6zku8f68gf.js","/litellm-asset-prefix/_next/static/chunks/1iakmimqrlpn0.js","/litellm-asset-prefix/_next/static/chunks/1a0bgy7kzrj91.js","/litellm-asset-prefix/_next/static/chunks/0f5fel02jwglw.js","/litellm-asset-prefix/_next/static/chunks/0g8wwba6umbim.js","/litellm-asset-prefix/_next/static/chunks/1di-caw05k3tq.js"],"default"] +4:I[339756,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"default"] +5:I[837457,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"default"] +0:{"rsc":["$","$1","c",{"children":[[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/1ioy8obpggx93.js","async":true}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/3_3dj4vdy-3xy.js","async":true}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/1zr7rrk4wkmju.js","async":true}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/2cngn5bal3278.js","async":true}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/2up3bks93iqds.js","async":true}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/0fk0i3e2aixp7.js","async":true}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/0zduf1gntl_f8.js","async":true}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/0dbvgsc7ha049.js","async":true}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/0g_w4tf2inv3i.js","async":true}],["$","script","script-9",{"src":"/litellm-asset-prefix/_next/static/chunks/1vquuz09jxl5_.js","async":true}],["$","script","script-10",{"src":"/litellm-asset-prefix/_next/static/chunks/17-6zku8f68gf.js","async":true}],["$","script","script-11",{"src":"/litellm-asset-prefix/_next/static/chunks/1iakmimqrlpn0.js","async":true}],["$","script","script-12",{"src":"/litellm-asset-prefix/_next/static/chunks/1a0bgy7kzrj91.js","async":true}],["$","script","script-13",{"src":"/litellm-asset-prefix/_next/static/chunks/0f5fel02jwglw.js","async":true}],["$","script","script-14",{"src":"/litellm-asset-prefix/_next/static/chunks/0g8wwba6umbim.js","async":true}],["$","script","script-15",{"src":"/litellm-asset-prefix/_next/static/chunks/1di-caw05k3tq.js","async":true}]],["$","$L2",null,{"Component":"$3","slots":{"children":["$","$L4",null,{"parallelRouterKey":"children","template":["$","$L5",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]},"serverProvidedParams":{"params":{},"promises":["$@6"]}}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"qXutWsQW5C1Pf62WxTkEI"} 6:"$0:rsc:props:children:1:props:serverProvidedParams:params" diff --git a/litellm/proxy/_experimental/out/__next._full.txt b/litellm/proxy/_experimental/out/__next._full.txt index 50353c2afcf..3ee486db39b 100644 --- a/litellm/proxy/_experimental/out/__next._full.txt +++ b/litellm/proxy/_experimental/out/__next._full.txt @@ -1,31 +1,32 @@ 1:"$Sreact.fragment" -2:I[867271,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"default"] -3:I[71195,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"default"] -4:I[557951,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"AuthProvider"] -5:I[339756,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"default"] -6:I[837457,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"default"] -7:I[92825,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"ClientSegmentRoot"] -8:I[216370,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js","/litellm-asset-prefix/_next/static/chunks/0mqbd99.ej13v.js","/litellm-asset-prefix/_next/static/chunks/16ufy1iyybswo.js","/litellm-asset-prefix/_next/static/chunks/0ayum-x.hkww~.js","/litellm-asset-prefix/_next/static/chunks/15jl-1gcakfwa.js","/litellm-asset-prefix/_next/static/chunks/003_1s9xbht43.js","/litellm-asset-prefix/_next/static/chunks/0u.r3vzo30ofk.js","/litellm-asset-prefix/_next/static/chunks/0g4qcx-c9gsxn.js","/litellm-asset-prefix/_next/static/chunks/14a-un1blorp~.js","/litellm-asset-prefix/_next/static/chunks/02_q4881cz6h~.js","/litellm-asset-prefix/_next/static/chunks/0lg.6rbfsd-l9.js","/litellm-asset-prefix/_next/static/chunks/0wdlbe750tuzr.js","/litellm-asset-prefix/_next/static/chunks/043q3g5-5-aju.js","/litellm-asset-prefix/_next/static/chunks/0nht59ws0elww.js","/litellm-asset-prefix/_next/static/chunks/03zkt5iyjiqcz.js","/litellm-asset-prefix/_next/static/chunks/0l02mpo6za6ie.js"],"default"] -d:I[168027,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"default",1] -:HL["/litellm-asset-prefix/_next/static/chunks/05qmwjqau64bz.css","style"] -:HL["/litellm-asset-prefix/_next/static/chunks/0aapv6n5bztwf.css","style"] -:HL["/litellm-asset-prefix/_next/static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2","font",{"crossOrigin":"","type":"font/woff2"}] -0:{"P":null,"c":["",""],"q":"","i":false,"f":[[["",{"children":["(dashboard)",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",16],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/05qmwjqau64bz.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/0aapv6n5bztwf.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"inter_5972bc34-module__OU16Qa__className","children":["$","$L2",null,{"children":["$","$L3",null,{"children":["$","$L4",null,{"children":["$","$L5",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L6",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]}]}]]}],{"children":[["$","$1","c",{"children":[[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/0mqbd99.ej13v.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/16ufy1iyybswo.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/0ayum-x.hkww~.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/15jl-1gcakfwa.js","async":true,"nonce":"$undefined"}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/003_1s9xbht43.js","async":true,"nonce":"$undefined"}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/0u.r3vzo30ofk.js","async":true,"nonce":"$undefined"}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/0g4qcx-c9gsxn.js","async":true,"nonce":"$undefined"}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/14a-un1blorp~.js","async":true,"nonce":"$undefined"}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/02_q4881cz6h~.js","async":true,"nonce":"$undefined"}],["$","script","script-9",{"src":"/litellm-asset-prefix/_next/static/chunks/0lg.6rbfsd-l9.js","async":true,"nonce":"$undefined"}],["$","script","script-10",{"src":"/litellm-asset-prefix/_next/static/chunks/0wdlbe750tuzr.js","async":true,"nonce":"$undefined"}],["$","script","script-11",{"src":"/litellm-asset-prefix/_next/static/chunks/043q3g5-5-aju.js","async":true,"nonce":"$undefined"}],["$","script","script-12",{"src":"/litellm-asset-prefix/_next/static/chunks/0nht59ws0elww.js","async":true,"nonce":"$undefined"}],["$","script","script-13",{"src":"/litellm-asset-prefix/_next/static/chunks/03zkt5iyjiqcz.js","async":true,"nonce":"$undefined"}],["$","script","script-14",{"src":"/litellm-asset-prefix/_next/static/chunks/0l02mpo6za6ie.js","async":true,"nonce":"$undefined"}]],["$","$L7",null,{"Component":"$8","slots":{"children":["$","$L5",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L6",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],"$L9"],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]},"serverProvidedParams":{"params":{},"promises":["$@a"]}}]]}],{"children":["$Lb",{},null,false,null]},null,false,null]},null,false,null],"$Lc",false]],"m":"$undefined","G":["$d",["$Le","$Lf"]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"DSHomUr6Sq46Bm2WLdUas"} -10:I[347257,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"ClientPageRoot"] -11:I[871135,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js","/litellm-asset-prefix/_next/static/chunks/0mqbd99.ej13v.js","/litellm-asset-prefix/_next/static/chunks/16ufy1iyybswo.js","/litellm-asset-prefix/_next/static/chunks/0ayum-x.hkww~.js","/litellm-asset-prefix/_next/static/chunks/15jl-1gcakfwa.js","/litellm-asset-prefix/_next/static/chunks/003_1s9xbht43.js","/litellm-asset-prefix/_next/static/chunks/0u.r3vzo30ofk.js","/litellm-asset-prefix/_next/static/chunks/0g4qcx-c9gsxn.js","/litellm-asset-prefix/_next/static/chunks/14a-un1blorp~.js","/litellm-asset-prefix/_next/static/chunks/02_q4881cz6h~.js","/litellm-asset-prefix/_next/static/chunks/0lg.6rbfsd-l9.js","/litellm-asset-prefix/_next/static/chunks/0wdlbe750tuzr.js","/litellm-asset-prefix/_next/static/chunks/043q3g5-5-aju.js","/litellm-asset-prefix/_next/static/chunks/0nht59ws0elww.js","/litellm-asset-prefix/_next/static/chunks/03zkt5iyjiqcz.js","/litellm-asset-prefix/_next/static/chunks/0l02mpo6za6ie.js","/litellm-asset-prefix/_next/static/chunks/1667t2pcy0iqm.js","/litellm-asset-prefix/_next/static/chunks/0-_m4km7b1~oe.js","/litellm-asset-prefix/_next/static/chunks/0sx3mu2_l9g_y.js","/litellm-asset-prefix/_next/static/chunks/0sqw622fcvsv4.js","/litellm-asset-prefix/_next/static/chunks/0t8el_ijoskx..js","/litellm-asset-prefix/_next/static/chunks/0el08tticy_20.js","/litellm-asset-prefix/_next/static/chunks/0a.ljputcx8g5.js","/litellm-asset-prefix/_next/static/chunks/02-u6qtmsnqn0.js","/litellm-asset-prefix/_next/static/chunks/076.vm.7w-x2..js","/litellm-asset-prefix/_next/static/chunks/069dx5~5osue0.js","/litellm-asset-prefix/_next/static/chunks/0onea0n77pqw1.js","/litellm-asset-prefix/_next/static/chunks/16jfov1k2wrj0.js","/litellm-asset-prefix/_next/static/chunks/0l7em-5kjv49e.js","/litellm-asset-prefix/_next/static/chunks/0mh1wnrvmv_y7.js","/litellm-asset-prefix/_next/static/chunks/01reddhq423_f.js","/litellm-asset-prefix/_next/static/chunks/0h80lrrstjswl.js","/litellm-asset-prefix/_next/static/chunks/0cmepm.jkel-i.js","/litellm-asset-prefix/_next/static/chunks/0q6~n4y84cejn.js","/litellm-asset-prefix/_next/static/chunks/04jv9e6~9vi.l.js","/litellm-asset-prefix/_next/static/chunks/0d_sm.._5mw-p.js","/litellm-asset-prefix/_next/static/chunks/0elr0ye86.44-.js"],"default"] -14:I[897367,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"OutletBoundary"] -15:"$Sreact.suspense" -17:I[897367,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"ViewportBoundary"] -19:I[897367,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"MetadataBoundary"] -9:["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:props:notFound:0:1:props:style","children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style","children":404}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style","children":["$","h2",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style","children":"This page could not be found."}]}]]}]}] -b:["$","$1","c",{"children":[["$","$L10",null,{"Component":"$11","serverProvidedParams":{"searchParams":{},"params":"$0:f:0:1:1:children:0:props:children:1:props:serverProvidedParams:params","promises":["$@12","$@13"]}}],[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/1667t2pcy0iqm.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/0-_m4km7b1~oe.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/0sx3mu2_l9g_y.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/0sqw622fcvsv4.js","async":true,"nonce":"$undefined"}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/0t8el_ijoskx..js","async":true,"nonce":"$undefined"}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/0el08tticy_20.js","async":true,"nonce":"$undefined"}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/0a.ljputcx8g5.js","async":true,"nonce":"$undefined"}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/02-u6qtmsnqn0.js","async":true,"nonce":"$undefined"}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/076.vm.7w-x2..js","async":true,"nonce":"$undefined"}],["$","script","script-9",{"src":"/litellm-asset-prefix/_next/static/chunks/069dx5~5osue0.js","async":true,"nonce":"$undefined"}],["$","script","script-10",{"src":"/litellm-asset-prefix/_next/static/chunks/0onea0n77pqw1.js","async":true,"nonce":"$undefined"}],["$","script","script-11",{"src":"/litellm-asset-prefix/_next/static/chunks/16jfov1k2wrj0.js","async":true,"nonce":"$undefined"}],["$","script","script-12",{"src":"/litellm-asset-prefix/_next/static/chunks/0l7em-5kjv49e.js","async":true,"nonce":"$undefined"}],["$","script","script-13",{"src":"/litellm-asset-prefix/_next/static/chunks/0mh1wnrvmv_y7.js","async":true,"nonce":"$undefined"}],["$","script","script-14",{"src":"/litellm-asset-prefix/_next/static/chunks/01reddhq423_f.js","async":true,"nonce":"$undefined"}],["$","script","script-15",{"src":"/litellm-asset-prefix/_next/static/chunks/0h80lrrstjswl.js","async":true,"nonce":"$undefined"}],["$","script","script-16",{"src":"/litellm-asset-prefix/_next/static/chunks/0cmepm.jkel-i.js","async":true,"nonce":"$undefined"}],["$","script","script-17",{"src":"/litellm-asset-prefix/_next/static/chunks/0q6~n4y84cejn.js","async":true,"nonce":"$undefined"}],["$","script","script-18",{"src":"/litellm-asset-prefix/_next/static/chunks/04jv9e6~9vi.l.js","async":true,"nonce":"$undefined"}],["$","script","script-19",{"src":"/litellm-asset-prefix/_next/static/chunks/0d_sm.._5mw-p.js","async":true,"nonce":"$undefined"}],["$","script","script-20",{"src":"/litellm-asset-prefix/_next/static/chunks/0elr0ye86.44-.js","async":true,"nonce":"$undefined"}]],["$","$L14",null,{"children":["$","$15",null,{"name":"Next.MetadataOutlet","children":"$@16"}]}]]}] -c:["$","$1","h",{"children":[null,["$","$L17",null,{"children":"$L18"}],["$","div",null,{"hidden":true,"children":["$","$L19",null,{"children":["$","$15",null,{"name":"Next.Metadata","children":"$L1a"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}] -e:["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/05qmwjqau64bz.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}] -f:["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/0aapv6n5bztwf.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}] -a:"$0:f:0:1:1:children:0:props:children:1:props:serverProvidedParams:params" -12:{} -13:"$0:f:0:1:1:children:0:props:children:1:props:serverProvidedParams:params" -18:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]] -1b:I[27201,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"IconMark"] -16:null -1a:[["$","title","0",{"children":"LiteLLM Dashboard"}],["$","meta","1",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","2",{"rel":"icon","href":"/favicon.ico?favicon.0~dgapwhi~75y.ico","sizes":"48x48","type":"image/x-icon"}],["$","link","3",{"rel":"icon","href":"/get_favicon"}],["$","$L1b","4",{}]] +2:I[867271,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"default"] +3:I[71195,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"default"] +4:I[557951,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"AuthProvider"] +5:I[339756,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"default"] +6:I[837457,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"default"] +7:I[92825,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"ClientSegmentRoot"] +8:I[216370,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js","/litellm-asset-prefix/_next/static/chunks/1ioy8obpggx93.js","/litellm-asset-prefix/_next/static/chunks/3_3dj4vdy-3xy.js","/litellm-asset-prefix/_next/static/chunks/1zr7rrk4wkmju.js","/litellm-asset-prefix/_next/static/chunks/2cngn5bal3278.js","/litellm-asset-prefix/_next/static/chunks/2up3bks93iqds.js","/litellm-asset-prefix/_next/static/chunks/0fk0i3e2aixp7.js","/litellm-asset-prefix/_next/static/chunks/0zduf1gntl_f8.js","/litellm-asset-prefix/_next/static/chunks/0dbvgsc7ha049.js","/litellm-asset-prefix/_next/static/chunks/0g_w4tf2inv3i.js","/litellm-asset-prefix/_next/static/chunks/1vquuz09jxl5_.js","/litellm-asset-prefix/_next/static/chunks/17-6zku8f68gf.js","/litellm-asset-prefix/_next/static/chunks/1iakmimqrlpn0.js","/litellm-asset-prefix/_next/static/chunks/1a0bgy7kzrj91.js","/litellm-asset-prefix/_next/static/chunks/0f5fel02jwglw.js","/litellm-asset-prefix/_next/static/chunks/0g8wwba6umbim.js","/litellm-asset-prefix/_next/static/chunks/1di-caw05k3tq.js"],"default"] +e:I[168027,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"default",1] +:HL["/litellm-asset-prefix/_next/static/chunks/1kid9zr1--h6y.css","style"] +:HL["/litellm-asset-prefix/_next/static/chunks/3254j4ut19q6_.css","style"] +:HL["/litellm-asset-prefix/_next/static/media/83afe278b6a6bb3c-s.p.2bn3s6zvc0dyp.woff2","font",{"crossOrigin":"","type":"font/woff2"}] +0:{"P":null,"c":["",""],"q":"","i":false,"f":[[["",{"children":["(dashboard)",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",16],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/1kid9zr1--h6y.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/3254j4ut19q6_.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"inter_5972bc34-module__OU16Qa__className","children":["$","$L2",null,{"children":["$","$L3",null,{"children":["$","$L4",null,{"children":["$","$L5",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L6",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]}]}]]}],{"children":[["$","$1","c",{"children":[[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/1ioy8obpggx93.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/3_3dj4vdy-3xy.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/1zr7rrk4wkmju.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/2cngn5bal3278.js","async":true,"nonce":"$undefined"}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/2up3bks93iqds.js","async":true,"nonce":"$undefined"}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/0fk0i3e2aixp7.js","async":true,"nonce":"$undefined"}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/0zduf1gntl_f8.js","async":true,"nonce":"$undefined"}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/0dbvgsc7ha049.js","async":true,"nonce":"$undefined"}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/0g_w4tf2inv3i.js","async":true,"nonce":"$undefined"}],["$","script","script-9",{"src":"/litellm-asset-prefix/_next/static/chunks/1vquuz09jxl5_.js","async":true,"nonce":"$undefined"}],["$","script","script-10",{"src":"/litellm-asset-prefix/_next/static/chunks/17-6zku8f68gf.js","async":true,"nonce":"$undefined"}],["$","script","script-11",{"src":"/litellm-asset-prefix/_next/static/chunks/1iakmimqrlpn0.js","async":true,"nonce":"$undefined"}],["$","script","script-12",{"src":"/litellm-asset-prefix/_next/static/chunks/1a0bgy7kzrj91.js","async":true,"nonce":"$undefined"}],["$","script","script-13",{"src":"/litellm-asset-prefix/_next/static/chunks/0f5fel02jwglw.js","async":true,"nonce":"$undefined"}],["$","script","script-14",{"src":"/litellm-asset-prefix/_next/static/chunks/0g8wwba6umbim.js","async":true,"nonce":"$undefined"}],["$","script","script-15",{"src":"/litellm-asset-prefix/_next/static/chunks/1di-caw05k3tq.js","async":true,"nonce":"$undefined"}]],["$","$L7",null,{"Component":"$8","slots":{"children":["$","$L5",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":"$L9","templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$La","forbidden":"$undefined","unauthorized":"$undefined"}]},"serverProvidedParams":{"params":{},"promises":["$@b"]}}]]}],{"children":["$Lc",{},null,false,null]},null,false,null]},null,false,null],"$Ld",false]],"m":"$undefined","G":["$e",["$Lf","$L10"]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"qXutWsQW5C1Pf62WxTkEI"} +11:I[347257,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"ClientPageRoot"] +12:I[871135,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js","/litellm-asset-prefix/_next/static/chunks/1ioy8obpggx93.js","/litellm-asset-prefix/_next/static/chunks/3_3dj4vdy-3xy.js","/litellm-asset-prefix/_next/static/chunks/1zr7rrk4wkmju.js","/litellm-asset-prefix/_next/static/chunks/2cngn5bal3278.js","/litellm-asset-prefix/_next/static/chunks/2up3bks93iqds.js","/litellm-asset-prefix/_next/static/chunks/0fk0i3e2aixp7.js","/litellm-asset-prefix/_next/static/chunks/0zduf1gntl_f8.js","/litellm-asset-prefix/_next/static/chunks/0dbvgsc7ha049.js","/litellm-asset-prefix/_next/static/chunks/0g_w4tf2inv3i.js","/litellm-asset-prefix/_next/static/chunks/1vquuz09jxl5_.js","/litellm-asset-prefix/_next/static/chunks/17-6zku8f68gf.js","/litellm-asset-prefix/_next/static/chunks/1iakmimqrlpn0.js","/litellm-asset-prefix/_next/static/chunks/1a0bgy7kzrj91.js","/litellm-asset-prefix/_next/static/chunks/0f5fel02jwglw.js","/litellm-asset-prefix/_next/static/chunks/0g8wwba6umbim.js","/litellm-asset-prefix/_next/static/chunks/1di-caw05k3tq.js","/litellm-asset-prefix/_next/static/chunks/00g6xfr4yow7h.js","/litellm-asset-prefix/_next/static/chunks/2kcxwg1mpncp6.js","/litellm-asset-prefix/_next/static/chunks/1fmx49l6q8v39.js","/litellm-asset-prefix/_next/static/chunks/0ww76lz_0cphv.js","/litellm-asset-prefix/_next/static/chunks/2uc2pi4ob086w.js","/litellm-asset-prefix/_next/static/chunks/2hu1vyy-5pv13.js","/litellm-asset-prefix/_next/static/chunks/2l25bmiiw9ixp.js","/litellm-asset-prefix/_next/static/chunks/1uz3jt-tj9lkf.js","/litellm-asset-prefix/_next/static/chunks/3drq2_k-jeio2.js","/litellm-asset-prefix/_next/static/chunks/0dsiq_ok1yngk.js","/litellm-asset-prefix/_next/static/chunks/3srzg1la93pwv.js","/litellm-asset-prefix/_next/static/chunks/17nqbxvhztf3k.js","/litellm-asset-prefix/_next/static/chunks/2c90xukbd3il6.js","/litellm-asset-prefix/_next/static/chunks/0kap_rdm2-lem.js","/litellm-asset-prefix/_next/static/chunks/09l_m9l1emin2.js","/litellm-asset-prefix/_next/static/chunks/1cea03gg5a_c7.js","/litellm-asset-prefix/_next/static/chunks/323l6h8s7ahat.js","/litellm-asset-prefix/_next/static/chunks/112n0hv3cc2rg.js","/litellm-asset-prefix/_next/static/chunks/199uwr871eene.js","/litellm-asset-prefix/_next/static/chunks/105643dvf00hu.js","/litellm-asset-prefix/_next/static/chunks/12wsfsljxg4xv.js","/litellm-asset-prefix/_next/static/chunks/22iools_e0k44.js","/litellm-asset-prefix/_next/static/chunks/0am68mi9t9cb6.js","/litellm-asset-prefix/_next/static/chunks/23-g73xaw3kap.js"],"default"] +15:I[897367,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"OutletBoundary"] +16:"$Sreact.suspense" +18:I[897367,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"ViewportBoundary"] +1a:I[897367,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"MetadataBoundary"] +9:["$","$L6",null,{}] +a:[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:props:notFound:0:1:props:style","children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style","children":404}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style","children":["$","h2",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style","children":"This page could not be found."}]}]]}]}]],[]] +c:["$","$1","c",{"children":[["$","$L11",null,{"Component":"$12","serverProvidedParams":{"searchParams":{},"params":"$0:f:0:1:1:children:0:props:children:1:props:serverProvidedParams:params","promises":["$@13","$@14"]}}],[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/00g6xfr4yow7h.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/2kcxwg1mpncp6.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/1fmx49l6q8v39.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/0ww76lz_0cphv.js","async":true,"nonce":"$undefined"}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/2uc2pi4ob086w.js","async":true,"nonce":"$undefined"}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/2hu1vyy-5pv13.js","async":true,"nonce":"$undefined"}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/2l25bmiiw9ixp.js","async":true,"nonce":"$undefined"}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/1uz3jt-tj9lkf.js","async":true,"nonce":"$undefined"}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/3drq2_k-jeio2.js","async":true,"nonce":"$undefined"}],["$","script","script-9",{"src":"/litellm-asset-prefix/_next/static/chunks/0dsiq_ok1yngk.js","async":true,"nonce":"$undefined"}],["$","script","script-10",{"src":"/litellm-asset-prefix/_next/static/chunks/3srzg1la93pwv.js","async":true,"nonce":"$undefined"}],["$","script","script-11",{"src":"/litellm-asset-prefix/_next/static/chunks/17nqbxvhztf3k.js","async":true,"nonce":"$undefined"}],["$","script","script-12",{"src":"/litellm-asset-prefix/_next/static/chunks/2c90xukbd3il6.js","async":true,"nonce":"$undefined"}],["$","script","script-13",{"src":"/litellm-asset-prefix/_next/static/chunks/0kap_rdm2-lem.js","async":true,"nonce":"$undefined"}],["$","script","script-14",{"src":"/litellm-asset-prefix/_next/static/chunks/09l_m9l1emin2.js","async":true,"nonce":"$undefined"}],["$","script","script-15",{"src":"/litellm-asset-prefix/_next/static/chunks/1cea03gg5a_c7.js","async":true,"nonce":"$undefined"}],["$","script","script-16",{"src":"/litellm-asset-prefix/_next/static/chunks/323l6h8s7ahat.js","async":true,"nonce":"$undefined"}],["$","script","script-17",{"src":"/litellm-asset-prefix/_next/static/chunks/112n0hv3cc2rg.js","async":true,"nonce":"$undefined"}],["$","script","script-18",{"src":"/litellm-asset-prefix/_next/static/chunks/199uwr871eene.js","async":true,"nonce":"$undefined"}],["$","script","script-19",{"src":"/litellm-asset-prefix/_next/static/chunks/105643dvf00hu.js","async":true,"nonce":"$undefined"}],["$","script","script-20",{"src":"/litellm-asset-prefix/_next/static/chunks/12wsfsljxg4xv.js","async":true,"nonce":"$undefined"}],["$","script","script-21",{"src":"/litellm-asset-prefix/_next/static/chunks/22iools_e0k44.js","async":true,"nonce":"$undefined"}],["$","script","script-22",{"src":"/litellm-asset-prefix/_next/static/chunks/0am68mi9t9cb6.js","async":true,"nonce":"$undefined"}],["$","script","script-23",{"src":"/litellm-asset-prefix/_next/static/chunks/23-g73xaw3kap.js","async":true,"nonce":"$undefined"}]],["$","$L15",null,{"children":["$","$16",null,{"name":"Next.MetadataOutlet","children":"$@17"}]}]]}] +d:["$","$1","h",{"children":[null,["$","$L18",null,{"children":"$L19"}],["$","div",null,{"hidden":true,"children":["$","$L1a",null,{"children":["$","$16",null,{"name":"Next.Metadata","children":"$L1b"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}] +f:["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/1kid9zr1--h6y.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}] +10:["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/3254j4ut19q6_.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}] +b:"$0:f:0:1:1:children:0:props:children:1:props:serverProvidedParams:params" +13:{} +14:"$0:f:0:1:1:children:0:props:children:1:props:serverProvidedParams:params" +19:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]] +1c:I[27201,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"IconMark"] +17:null +1b:[["$","title","0",{"children":"LiteLLM Dashboard"}],["$","meta","1",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","2",{"rel":"icon","href":"/favicon.ico?favicon.3arlap5n8tyzg.ico","sizes":"48x48","type":"image/x-icon"}],["$","link","3",{"rel":"icon","href":"/get_favicon"}],["$","$L1c","4",{}]] diff --git a/litellm/proxy/_experimental/out/__next._head.txt b/litellm/proxy/_experimental/out/__next._head.txt index e1dcfe24eb2..9b12cf54d0c 100644 --- a/litellm/proxy/_experimental/out/__next._head.txt +++ b/litellm/proxy/_experimental/out/__next._head.txt @@ -1,6 +1,6 @@ 1:"$Sreact.fragment" -2:I[897367,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"ViewportBoundary"] -3:I[897367,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"MetadataBoundary"] +2:I[897367,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"ViewportBoundary"] +3:I[897367,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"MetadataBoundary"] 4:"$Sreact.suspense" -5:I[27201,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"IconMark"] -0:{"rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[["$","title","0",{"children":"LiteLLM Dashboard"}],["$","meta","1",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","2",{"rel":"icon","href":"/favicon.ico?favicon.0~dgapwhi~75y.ico","sizes":"48x48","type":"image/x-icon"}],["$","link","3",{"rel":"icon","href":"/get_favicon"}],["$","$L5","4",{}]]}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"DSHomUr6Sq46Bm2WLdUas"} +5:I[27201,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"IconMark"] +0:{"rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[["$","title","0",{"children":"LiteLLM Dashboard"}],["$","meta","1",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","2",{"rel":"icon","href":"/favicon.ico?favicon.3arlap5n8tyzg.ico","sizes":"48x48","type":"image/x-icon"}],["$","link","3",{"rel":"icon","href":"/get_favicon"}],["$","$L5","4",{}]]}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"qXutWsQW5C1Pf62WxTkEI"} diff --git a/litellm/proxy/_experimental/out/__next._index.txt b/litellm/proxy/_experimental/out/__next._index.txt index ef93d018c21..8649901b01b 100644 --- a/litellm/proxy/_experimental/out/__next._index.txt +++ b/litellm/proxy/_experimental/out/__next._index.txt @@ -1,9 +1,9 @@ 1:"$Sreact.fragment" -2:I[867271,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"default"] -3:I[71195,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"default"] -4:I[557951,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"AuthProvider"] -5:I[339756,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"default"] -6:I[837457,["/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js"],"default"] -:HL["/litellm-asset-prefix/_next/static/chunks/05qmwjqau64bz.css","style"] -:HL["/litellm-asset-prefix/_next/static/chunks/0aapv6n5bztwf.css","style"] -0:{"rsc":["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/05qmwjqau64bz.css","precedence":"next"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/0aapv6n5bztwf.css","precedence":"next"}],["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/09qhs_ev_bxr8.js","async":true}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/0l6q6-77u4dy~.js","async":true}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/0hpxif-db_y5-.js","async":true}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"inter_5972bc34-module__OU16Qa__className","children":["$","$L2",null,{"children":["$","$L3",null,{"children":["$","$L4",null,{"children":["$","$L5",null,{"parallelRouterKey":"children","template":["$","$L6",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]}]}]}]}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"DSHomUr6Sq46Bm2WLdUas"} +2:I[867271,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"default"] +3:I[71195,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"default"] +4:I[557951,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"AuthProvider"] +5:I[339756,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"default"] +6:I[837457,["/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js"],"default"] +:HL["/litellm-asset-prefix/_next/static/chunks/1kid9zr1--h6y.css","style"] +:HL["/litellm-asset-prefix/_next/static/chunks/3254j4ut19q6_.css","style"] +0:{"rsc":["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/1kid9zr1--h6y.css","precedence":"next"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/3254j4ut19q6_.css","precedence":"next"}],["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/0vggytdohwe7o.js","async":true}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/3c02m_kr-u94p.js","async":true}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/1jfookxfajkeo.js","async":true}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"inter_5972bc34-module__OU16Qa__className","children":["$","$L2",null,{"children":["$","$L3",null,{"children":["$","$L4",null,{"children":["$","$L5",null,{"parallelRouterKey":"children","template":["$","$L6",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]}]}]}]}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"qXutWsQW5C1Pf62WxTkEI"} diff --git a/litellm/proxy/_experimental/out/__next._tree.txt b/litellm/proxy/_experimental/out/__next._tree.txt index 58844a07097..db0015f1f41 100644 --- a/litellm/proxy/_experimental/out/__next._tree.txt +++ b/litellm/proxy/_experimental/out/__next._tree.txt @@ -1,4 +1,4 @@ -:HL["/litellm-asset-prefix/_next/static/chunks/05qmwjqau64bz.css","style"] -:HL["/litellm-asset-prefix/_next/static/chunks/0aapv6n5bztwf.css","style"] -:HL["/litellm-asset-prefix/_next/static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2","font",{"crossOrigin":"","type":"font/woff2"}] -0:{"tree":{"name":"","param":null,"prefetchHints":16,"slots":{"children":{"name":"(dashboard)","param":null,"prefetchHints":0,"slots":{"children":{"name":"__PAGE__","param":null,"prefetchHints":0,"slots":null}}}}},"staleTime":300,"buildId":"DSHomUr6Sq46Bm2WLdUas"} +:HL["/litellm-asset-prefix/_next/static/chunks/1kid9zr1--h6y.css","style"] +:HL["/litellm-asset-prefix/_next/static/chunks/3254j4ut19q6_.css","style"] +:HL["/litellm-asset-prefix/_next/static/media/83afe278b6a6bb3c-s.p.2bn3s6zvc0dyp.woff2","font",{"crossOrigin":"","type":"font/woff2"}] +0:{"tree":{"name":"","param":null,"prefetchHints":16,"slots":{"children":{"name":"(dashboard)","param":null,"prefetchHints":0,"slots":{"children":{"name":"__PAGE__","param":null,"prefetchHints":0,"slots":null}}}}},"staleTime":300,"buildId":"qXutWsQW5C1Pf62WxTkEI"} diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0-_m4km7b1~oe.js b/litellm/proxy/_experimental/out/_next/static/chunks/0-_m4km7b1~oe.js deleted file mode 100644 index 7c857629cc7..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/0-_m4km7b1~oe.js +++ /dev/null @@ -1 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,981339,e=>{"use strict";var t=e.i(185793);e.s(["Skeleton",()=>t.default])},540626,e=>{"use strict";let t;var n,i=e.i(271645);let s=(0,i.createContext)(null);function r(e,t){if(Object.is(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(let[n,i]of e)if(!t.has(n)||!Object.is(i,t.get(n)))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;for(let n of e)if(!t.has(n))return!1;return!0}if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();let n=o(e);if(n.length!==o(t).length)return!1;for(let i=0;ie,n){let s=n?.compare??l,r=(0,i.useCallback)(t=>{let{unsubscribe:n}=e.subscribe(t);return n},[e]),o=(0,i.useCallback)(()=>e.get(),[e]);return(0,a.useSyncExternalStoreWithSelector)(r,o,o,t,s)}function d(e,...t){return"function"==typeof e?e(...t):e}var c=class{#e=!0;#t;#n;#i;#s;#r;#o;#a;#l=0;#u=5;#d=!1;#c=!1;#h=null;#g=()=>{this.debugLog("Connected to event bus"),this.#r=!0,this.#d=!1,this.debugLog("Emitting queued events",this.#s),this.#s.forEach(e=>this.emitEventToBus(e)),this.#s=[],this.stopConnectLoop(),this.#n().removeEventListener("tanstack-connect-success",this.#g)};#v=()=>{if(this.#l{this.#d||(this.#d=!0,this.#n().addEventListener("tanstack-connect-success",this.#g),this.#v())};constructor({pluginId:e,debug:t=!1,enabled:n=!0,reconnectEveryMs:i=300}){this.#t=e,this.#e=n,this.#n=this.getGlobalTarget,this.#i=t,this.debugLog(" Initializing event subscription for plugin",this.#t),this.#s=[],this.#r=!1,this.#c=!1,this.#o=null,this.#a=i}startConnectLoop(){null!==this.#o||this.#r||(this.debugLog(`Starting connect loop (every ${this.#a}ms)`),this.#o=setInterval(this.#v,this.#a))}stopConnectLoop(){this.#d=!1,null!==this.#o&&(clearInterval(this.#o),this.#o=null,this.#s=[],this.debugLog("Stopped connect loop"))}debugLog(...e){this.#i&&console.log(`🌴 [tanstack-devtools:${this.#t}-plugin]`,...e)}getGlobalTarget(){if("u">typeof globalThis&&globalThis.__TANSTACK_EVENT_TARGET__)return this.debugLog("Using global event target"),globalThis.__TANSTACK_EVENT_TARGET__;if("u">typeof window&&void 0!==window.addEventListener)return this.debugLog("Using window as event target"),window;let e="u">typeof EventTarget?new EventTarget:void 0;return void 0===e||void 0===e.addEventListener?(this.debugLog("No event mechanism available, running in non-web environment"),{addEventListener:()=>{},removeEventListener:()=>{},dispatchEvent:()=>!1}):(this.debugLog("Using new EventTarget as fallback"),e)}getPluginId(){return this.#t}dispatchCustomEventShim(e,t){try{let n=new Event(e,{detail:t});this.#n().dispatchEvent(n)}catch(e){this.debugLog("Failed to dispatch shim event")}}dispatchCustomEvent(e,t){try{this.#n().dispatchEvent(new CustomEvent(e,{detail:t}))}catch(n){this.dispatchCustomEventShim(e,t)}}emitEventToBus(e){this.debugLog("Emitting event to client bus",e),this.dispatchCustomEvent("tanstack-dispatch-event",e)}createEventPayload(e,t){return{type:`${this.#t}:${e}`,payload:t,pluginId:this.#t}}emit(e,t){if(!this.#e)return void this.debugLog("Event bus client is disabled, not emitting event",e,t);if(this.#h&&(this.debugLog("Emitting event to internal event target",e,t),this.#h.dispatchEvent(new CustomEvent(`${this.#t}:${e}`,{detail:this.createEventPayload(e,t)}))),this.#c)return void this.debugLog("Previously failed to connect, not emitting to bus");if(!this.#r){this.debugLog("Bus not available, will be pushed as soon as connected"),this.#s.push(this.createEventPayload(e,t)),"u">typeof CustomEvent&&!this.#d&&(this.#f(),this.startConnectLoop());return}return this.emitEventToBus(this.createEventPayload(e,t))}on(e,t,n){let i=n?.withEventTarget??!1,s=`${this.#t}:${e}`;if(i&&(this.#h||(this.#h=new EventTarget),this.#h.addEventListener(s,e=>{t(e.detail)})),!this.#e)return this.debugLog("Event bus client is disabled, not registering event",s),()=>{};let r=e=>{this.debugLog("Received event from bus",e.detail),t(e.detail)};return this.#n().addEventListener(s,r),this.debugLog("Registered event to bus",s),()=>{i&&this.#h?.removeEventListener(s,r),this.#n().removeEventListener(s,r)}}onAll(e){if(!this.#e)return this.debugLog("Event bus client is disabled, not registering event"),()=>{};let t=t=>{e(t.detail)};return this.#n().addEventListener("tanstack-devtools-global",t),()=>this.#n().removeEventListener("tanstack-devtools-global",t)}onAllPluginEvents(e){if(!this.#e)return this.debugLog("Event bus client is disabled, not registering event"),()=>{};let t=t=>{let n=t.detail;this.#t&&n.pluginId!==this.#t||e(n)};return this.#n().addEventListener("tanstack-devtools-global",t),()=>this.#n().removeEventListener("tanstack-devtools-global",t)}};let h=new Map;function g(e){if(void 0!==e)try{return JSON.parse(JSON.stringify(e))}catch{return null}}let v=new class extends c{constructor(e){super({pluginId:"pacer",debug:e?.debug,reconnectEveryMs:1e3})}},f=((n={})[n.None=0]="None",n[n.Mutable=1]="Mutable",n[n.Watching=2]="Watching",n[n.RecursedCheck=4]="RecursedCheck",n[n.Recursed=8]="Recursed",n[n.Dirty=16]="Dirty",n[n.Pending=32]="Pending",n);function p(e,t,n){let i="object"==typeof e,s=i?e:void 0;return{next:(i?e.next:e)?.bind(s),error:(i?e.error:t)?.bind(s),complete:(i?e.complete:n)?.bind(s)}}let b=[],m=0,{link:y,unlink:x,propagate:E,checkDirty:T,shallowPropagate:C}=function({update:e,notify:t,unwatched:n}){return{link:function(e,t,n){let i=t.depsTail;if(void 0!==i&&i.dep===e)return;let s=void 0!==i?i.nextDep:t.deps;if(void 0!==s&&s.dep===e){s.version=n,t.depsTail=s;return}let r=e.subsTail;if(void 0!==r&&r.version===n&&r.sub===t)return;let o=t.depsTail=e.subsTail={version:n,dep:e,sub:t,prevDep:i,nextDep:s,prevSub:r,nextSub:void 0};void 0!==s&&(s.prevDep=o),void 0!==i?i.nextDep=o:t.deps=o,void 0!==r?r.nextSub=o:e.subs=o},unlink:function(e,t=e.sub){let i=e.dep,s=e.prevDep,r=e.nextDep,o=e.nextSub,a=e.prevSub;return void 0!==r?r.prevDep=s:t.depsTail=s,void 0!==s?s.nextDep=r:t.deps=r,void 0!==o?o.prevSub=a:i.subsTail=a,void 0!==a?a.nextSub=o:void 0===(i.subs=o)&&n(i),r},propagate:function(e){let n,i=e.nextSub;e:for(;;){let s=e.sub,r=s.flags;if(r&(f.RecursedCheck|f.Recursed|f.Dirty|f.Pending)?r&(f.RecursedCheck|f.Recursed)?r&f.RecursedCheck?!(r&(f.Dirty|f.Pending))&&function(e,t){let n=t.depsTail;for(;void 0!==n;){if(n===e)return!0;n=n.prevDep}return!1}(e,s)?(s.flags=r|(f.Recursed|f.Pending),r&=f.Mutable):r=f.None:s.flags=r&~f.Recursed|f.Pending:r=f.None:s.flags=r|f.Pending,r&f.Watching&&t(s),r&f.Mutable){let t=s.subs;if(void 0!==t){let s=(e=t).nextSub;void 0!==s&&(n={value:i,prev:n},i=s);continue}}if(void 0!==(e=i)){i=e.nextSub;continue}for(;void 0!==n;)if(e=n.value,n=n.prev,void 0!==e){i=e.nextSub;continue e}break}},checkDirty:function(t,n){let s,r=0,o=!1;e:for(;;){let a=t.dep,l=a.flags;if(n.flags&f.Dirty)o=!0;else if((l&(f.Mutable|f.Dirty))==(f.Mutable|f.Dirty)){if(e(a)){let e=a.subs;void 0!==e.nextSub&&i(e),o=!0}}else if((l&(f.Mutable|f.Pending))==(f.Mutable|f.Pending)){(void 0!==t.nextSub||void 0!==t.prevSub)&&(s={value:t,prev:s}),t=a.deps,n=a,++r;continue}if(!o){let e=t.nextDep;if(void 0!==e){t=e;continue}}for(;r--;){let r=n.subs,a=void 0!==r.nextSub;if(a?(t=s.value,s=s.prev):t=r,o){if(e(n)){a&&i(r),n=t.sub;continue}o=!1}else n.flags&=~f.Pending;n=t.sub;let l=t.nextDep;if(void 0!==l){t=l;continue e}}return o}},shallowPropagate:i};function i(e){do{let n=e.sub,i=n.flags;(i&(f.Pending|f.Dirty))===f.Pending&&(n.flags=i|f.Dirty,(i&(f.Watching|f.RecursedCheck))===f.Watching&&t(n))}while(void 0!==(e=e.nextSub))}}({update:e=>e._update(),notify(e){b[k++]=e,e.flags&=~f.Watching},unwatched(e){void 0!==e.depsTail&&(e.depsTail=void 0,e.flags=f.Mutable|f.Dirty,S(e))}}),w=0,k=0;function S(e){let t=e.depsTail,n=void 0!==t?t.nextDep:e.deps;for(;void 0!==n;)n=x(n,e)}var L=class{constructor(e,n){this.atom=function(e){let n="function"==typeof e,i={_snapshot:n?void 0:e,subs:void 0,subsTail:void 0,deps:void 0,depsTail:void 0,flags:n?f.None:f.Mutable,get:()=>(void 0!==t&&y(i,t,m),i._snapshot),subscribe(e){var n;let s,r,o=p(e),a={current:!1},l=(n=()=>{i.get(),a.current?o.next?.(i._snapshot):a.current=!0},s=()=>{let e=t;t=r,++m,r.depsTail=void 0,r.flags=f.Watching|f.RecursedCheck;try{return n()}finally{t=e,r.flags&=~f.RecursedCheck,S(r)}},r={deps:void 0,depsTail:void 0,subs:void 0,subsTail:void 0,flags:f.Watching|f.RecursedCheck,notify(){let e=this.flags;e&f.Dirty||e&f.Pending&&T(this.deps,this)?s():this.flags=f.Watching},stop(){this.flags=f.None,this.depsTail=void 0,S(this)}},s(),r);return{unsubscribe:()=>{l.stop()}}},_update(s){let r=t,o=(void 0)??Object.is;if(n)t=i,++m,i.depsTail=void 0;else if(void 0===s)return!1;n&&(i.flags=f.Mutable|f.RecursedCheck);try{let t=i._snapshot,r="function"==typeof s?s(t):void 0===s&&n?e(t):s;if(void 0===t||!o(t,r))return i._snapshot=r,!0;return!1}finally{t=r,n&&(i.flags&=~f.RecursedCheck),S(i)}}};return n?(i.flags=f.Mutable|f.Dirty,i.get=function(){let e=i.flags;if(e&f.Dirty||e&f.Pending&&T(i.deps,i)){if(i._update()){let e=i.subs;void 0!==e&&C(e)}}else e&f.Pending&&(i.flags=e&~f.Pending);return void 0!==t&&y(i,t,m),i._snapshot}):i.set=function(e){if(i._update(e)){let e=i.subs;if(void 0!==e&&(E(e),C(e),1)){for(;w{this.options={...this.options,...e},this.#b()||this.cancel()},this.#m=e=>{this.store.setState(t=>{let n={...t,...e},{isPending:i}=n;return{...n,status:this.#b()?i?"pending":"idle":"disabled"}}),((e,t)=>{let n=t.key;if(n){var i,s;h.set(n,t),v.emit(e,{key:(i={...t,key:n}).key,store:{state:g("function"==typeof(s=i.store).get?s.get():s.state)},options:g(i.options)})}})("Debouncer",this)},this.#b=()=>!!d(this.options.enabled,this),this.#y=()=>d(this.options.wait,this),this.maybeExecute=(...e)=>{if(!this.#b())return;this.#m({maybeExecuteCount:this.store.state.maybeExecuteCount+1});let t=!1;this.options.leading&&this.store.state.canLeadingExecute&&(this.#m({canLeadingExecute:!1}),t=!0,this.#x(...e)),this.options.trailing&&this.#m({isPending:!0,lastArgs:e}),this.#p&&clearTimeout(this.#p),this.#p=setTimeout(()=>{this.#m({canLeadingExecute:!0}),this.options.trailing&&!t&&this.#x(...e)},this.#y())},this.#x=(...e)=>{this.#b()&&(this.fn(...e),this.#m({executionCount:this.store.state.executionCount+1,isPending:!1,lastArgs:void 0}),this.options.onExecute?.(e,this))},this.flush=()=>{this.store.state.isPending&&this.store.state.lastArgs&&(this.#E(),this.#x(...this.store.state.lastArgs))},this.#E=()=>{this.#p&&(clearTimeout(this.#p),this.#p=void 0)},this.cancel=()=>{this.#E(),this.#m({canLeadingExecute:!0,isPending:!1})},this.reset=()=>{this.#m(I())},this.key=t.key,this.options={...P,...t},this.#m(this.options.initialState??{}),this.key&&v.on("d-Debouncer",e=>{e.payload.key===this.key&&(this.#m(e.payload.store.state),this.setOptions(e.payload.options))})}#m;#b;#y;#x;#E};e.s(["useDebouncer",0,function(e,t,n=()=>({})){let o={...((0,i.useContext)(s)?.defaultOptions??{}).debouncer,...t},[a]=(0,i.useState)(()=>{let t=new M(e,o);return t.Subscribe=function(e){let n=u(t.store,e.selector,{compare:r});return"function"==typeof e.children?e.children(n):e.children},t});a.fn=e,a.setOptions(o),(0,i.useEffect)(()=>()=>{o.onUnmount?o.onUnmount(a):a.cancel()},[]);let l=u(a.store,n,{compare:r});return(0,i.useMemo)(()=>({...a,state:l}),[a,l])}],540626)},343488,e=>{"use strict";var t=e.i(540626),n=e.i(271645);e.s(["useDebouncedCallback",0,function(e,i){let s=(0,t.useDebouncer)(e,i).maybeExecute;return(0,n.useCallback)((...e)=>s(...e),[s])}])},500727,e=>{"use strict";var t=e.i(266027),n=e.i(243652),i=e.i(602869),s=e.i(135214);let r=(0,n.createQueryKeys)("mcpServers");e.s(["useMCPServers",0,e=>{let{accessToken:n}=(0,s.default)();return(0,t.useQuery)({queryKey:r.list(e?{filters:{teamId:e}}:void 0),queryFn:async()=>await (0,i.fetchMCPServers)(n,e),enabled:!!n})}])},699857,e=>{"use strict";var t=e.i(266027),n=e.i(243652),i=e.i(602869),s=e.i(135214);let r=(0,n.createQueryKeys)("mcpToolsets");e.s(["useMCPToolsets",0,()=>{let{accessToken:e}=(0,s.default)();return(0,t.useQuery)({queryKey:r.list(),queryFn:async()=>await (0,i.fetchMCPToolsets)(e),enabled:!!e})}])},695411,e=>{"use strict";var t=e.i(602869);let n=async e=>{try{let n=await (0,t.modelHubCall)(e);if(n?.data.length>0){let e=n.data.map(e=>({model_group:e.model_group,mode:e?.mode}));return e.sort((e,t)=>e.model_group.localeCompare(t.model_group)),e}return[]}catch(e){throw console.error("Error fetching model info:",e),e}};e.s(["fetchAvailableModels",0,n])},983561,e=>{"use strict";e.i(247167);var t=e.i(931067),n=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"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"};var s=e.i(9583),r=n.forwardRef(function(e,r){return n.createElement(s.default,(0,t.default)({},e,{ref:r,icon:i}))});e.s(["RobotOutlined",0,r],983561)},992619,e=>{"use strict";var t=e.i(843476),n=e.i(271645),i=e.i(779241),s=e.i(599724),r=e.i(199133),o=e.i(983561),a=e.i(343488),l=e.i(695411);e.s(["default",0,({accessToken:e,value:u,placeholder:d="Select a Model",onChange:c,disabled:h=!1,style:g,className:v,showLabel:f=!0,labelText:p="Select Model"})=>{let[b,m]=(0,n.useState)(u),[y,x]=(0,n.useState)(!1),[E,T]=(0,n.useState)([]);(0,n.useEffect)(()=>{m(u)},[u]),(0,n.useEffect)(()=>{e&&(async()=>{try{let t=await (0,l.fetchAvailableModels)(e);t.length>0&&T(t)}catch(e){console.error("Error fetching model info:",e)}})()},[e]);let C=(0,a.useDebouncedCallback)(e=>{m(e),c?.(e)},{wait:500});return(0,t.jsxs)("div",{children:[f&&(0,t.jsxs)(s.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,t.jsx)(o.RobotOutlined,{className:"mr-2"})," ",p]}),(0,t.jsx)(r.Select,{value:b,placeholder:d,onChange:e=>{"custom"===e?(x(!0),m(void 0)):(x(!1),m(e),c&&c(e))},options:[...Array.from(new Set(E.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%",...g},showSearch:!0,className:`rounded-md ${v||""}`,disabled:h}),y&&(0,t.jsx)(i.TextInput,{className:"mt-2",placeholder:"Enter custom model name",onValueChange:C,disabled:h})]})}])},91739,e=>{"use strict";var t=e.i(544195);e.s(["Radio",()=>t.default])},988297,e=>{"use strict";var t=e.i(271645);let n=t.forwardRef(function(e,n){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:n},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 4v16m8-8H4"}))});e.s(["PlusIcon",0,n],988297)},531516,696609,e=>{"use strict";var t=e.i(843476),n=e.i(271645),i=e.i(536916),s=e.i(599724),r=e.i(409797),o=e.i(233565);let a=/\b(delete|remove|destroy|purge|drop|erase|unlink)\b/i,l=/\b(create|add|insert|new|post|submit|register|make|generate|write|upload)\b/i,u=/\b(update|edit|modify|change|patch|put|set|rename|move|transform)\b/i,d=/\b(get|read|list|fetch|search|find|query|retrieve|show|view|check|describe|info)\b/i;function c(e,t=""){let n=e.toLowerCase();if(d.test(n))return"read";if(a.test(n))return"delete";if(u.test(n))return"update";if(l.test(n))return"create";if(t){let e=t.toLowerCase();if(d.test(e))return"read";if(a.test(e))return"delete";if(u.test(e))return"update";if(l.test(e))return"create"}return"unknown"}function h(e){let t={read:[],create:[],update:[],delete:[],unknown:[]};for(let n of e)t[c(n.name,n.description)].push(n);return t}let g={read:{label:"Read",description:"Safe operations — fetch, list, search. No side effects.",risk:"low"},create:{label:"Create",description:"Add new resources — insert, upload, register.",risk:"medium"},update:{label:"Update",description:"Modify existing resources — edit, patch, rename.",risk:"medium"},delete:{label:"Delete",description:"Destructive operations — remove, purge, destroy.",risk:"high"},unknown:{label:"Other",description:"Operations that could not be automatically classified.",risk:"unknown"}};e.s(["CRUD_GROUP_META",0,g,"classifyToolOp",0,c,"groupToolsByCrud",0,h],696609);let v=["read","create","update","delete","unknown"],f={low:"bg-green-100 text-green-800",medium:"bg-yellow-100 text-yellow-800",high:"bg-red-100 text-red-800 font-semibold",unknown:"bg-gray-100 text-gray-700"},p={read:"border-green-200",create:"border-blue-200",update:"border-yellow-200",delete:"border-red-300",unknown:"border-gray-200"},b={read:"bg-green-50",create:"bg-blue-50",update:"bg-yellow-50",delete:"bg-red-50",unknown:"bg-gray-50"};e.s(["default",0,({tools:e,value:a,onChange:l,readOnly:u=!1,searchFilter:d=""})=>{let[c,m]=(0,n.useState)({read:!1,create:!1,update:!1,delete:!1,unknown:!0}),y=(0,n.useMemo)(()=>h(e),[e]),x=(0,n.useMemo)(()=>new Set(void 0===a?e.map(e=>e.name):a),[a,e]),E=e=>{if(u)return;let t=new Set(x);t.has(e)?t.delete(e):t.add(e),l(Array.from(t))};return 0===e.length?null:(0,t.jsx)("div",{className:"space-y-3",children:v.map(e=>{let n,a=y[e];if(0===a.length)return null;if(d){let e=d.toLowerCase();if(!a.some(t=>t.name.toLowerCase().includes(e)||(t.description??"").toLowerCase().includes(e)))return null}let h=g[e],v=(n=y[e]).length>0&&n.every(e=>x.has(e.name)),T=(e=>{let t=y[e];if(0===t.length)return!1;let n=t.filter(e=>x.has(e.name)).length;return n>0&&n{m(t=>({...t,[e]:!t[e]}))},children:[C?(0,t.jsx)(o.ChevronRightIcon,{className:"w-4 h-4 text-gray-500 shrink-0"}):(0,t.jsx)(r.ChevronDownIcon,{className:"w-4 h-4 text-gray-500 shrink-0"}),(0,t.jsx)("span",{className:"font-semibold text-gray-900 text-sm",children:h.label}),(0,t.jsx)("span",{className:`text-xs px-2 py-0.5 rounded-full ${f[h.risk]}`,children:"high"===h.risk?"High Risk":"medium"===h.risk?"Medium Risk":"low"===h.risk?"Safe":"Unclassified"}),(0,t.jsxs)("span",{className:"text-xs text-gray-500 ml-1",children:[a.filter(e=>x.has(e.name)).length,"/",a.length," allowed"]})]}),!u&&(0,t.jsxs)("div",{className:"flex items-center gap-2 ml-4",children:[(0,t.jsx)(s.Text,{className:"text-xs text-gray-500",children:v?"All on":T?"Partial":"All off"}),(0,t.jsx)(i.Checkbox,{checked:v,indeterminate:T,onChange:t=>((e,t)=>{if(u)return;let n=new Set(x);for(let i of y[e])t?n.add(i.name):n.delete(i.name);l(Array.from(n))})(e,t.target.checked),onClick:e=>e.stopPropagation()})]})]}),!C&&(0,t.jsx)("div",{className:"px-4 pt-2 pb-1 text-xs text-gray-500 bg-white border-b border-gray-100",children:h.description}),!C&&(0,t.jsx)("div",{className:"bg-white divide-y divide-gray-50",children:a.filter(e=>!d||e.name.toLowerCase().includes(d.toLowerCase())||(e.description??"").toLowerCase().includes(d.toLowerCase())).map(e=>{let n,r=(n=e.name,x.has(n));return(0,t.jsxs)("div",{className:`flex items-start gap-3 px-4 py-2.5 transition-colors hover:bg-gray-50 ${!u?"cursor-pointer":""} ${r?"":"opacity-60"}`,onClick:()=>E(e.name),children:[(0,t.jsx)(i.Checkbox,{checked:r,onChange:()=>E(e.name),disabled:u,onClick:e=>e.stopPropagation()}),(0,t.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,t.jsx)(s.Text,{className:"font-medium text-gray-900 text-sm",children:e.name}),e.description&&(0,t.jsx)(s.Text,{className:"text-xs text-gray-500 mt-0.5 leading-snug",children:e.description})]}),(0,t.jsx)("span",{className:`text-xs px-1.5 py-0.5 rounded shrink-0 ${r?"bg-green-100 text-green-700":"bg-gray-100 text-gray-500"}`,children:r?"on":"off"})]},e.name)})})]},e)})})}],531516)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0-ahu72ndvhwn.js b/litellm/proxy/_experimental/out/_next/static/chunks/0-ahu72ndvhwn.js deleted file mode 100644 index 61529517908..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/0-ahu72ndvhwn.js +++ /dev/null @@ -1,8 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,530212,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10 19l-7-7m0 0l7-7m-7 7h18"}))});e.s(["ArrowLeftIcon",0,r],530212)},784774,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(115504);let l=r.forwardRef(({className:e,...r},l)=>(0,t.jsx)("div",{"data-slot":"table-container",className:"relative w-full overflow-x-auto",children:(0,t.jsx)("table",{ref:l,"data-slot":"table",className:(0,a.cn)("w-full caption-bottom text-sm",e),...r})}));l.displayName="Table";let n=r.forwardRef(({className:e,...r},l)=>(0,t.jsx)("thead",{ref:l,"data-slot":"table-header",className:(0,a.cn)("[&_tr]:border-b",e),...r}));n.displayName="TableHeader";let o=r.forwardRef(({className:e,...r},l)=>(0,t.jsx)("tbody",{ref:l,"data-slot":"table-body",className:(0,a.cn)("[&_tr:last-child]:border-0",e),...r}));o.displayName="TableBody";let i=r.forwardRef(({className:e,...r},l)=>(0,t.jsx)("tfoot",{ref:l,"data-slot":"table-footer",className:(0,a.cn)("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",e),...r}));i.displayName="TableFooter";let s=r.forwardRef(({className:e,...r},l)=>(0,t.jsx)("tr",{ref:l,"data-slot":"table-row",className:(0,a.cn)("border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",e),...r}));s.displayName="TableRow";let d=r.forwardRef(({className:e,...r},l)=>(0,t.jsx)("th",{ref:l,"data-slot":"table-head",className:(0,a.cn)("h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",e),...r}));d.displayName="TableHead";let c=r.forwardRef(({className:e,...r},l)=>(0,t.jsx)("td",{ref:l,"data-slot":"table-cell",className:(0,a.cn)("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",e),...r}));c.displayName="TableCell",r.forwardRef(({className:e,...r},l)=>(0,t.jsx)("caption",{ref:l,"data-slot":"table-caption",className:(0,a.cn)("mt-4 text-sm text-muted-foreground",e),...r})).displayName="TableCaption",e.s(["Table",0,l,"TableBody",0,o,"TableCell",0,c,"TableFooter",0,i,"TableHead",0,d,"TableHeader",0,n,"TableRow",0,s])},185793,e=>{"use strict";e.i(247167);var t=e.i(271645),r=e.i(343794),a=e.i(242064),l=e.i(529681);let n=e=>{let{prefixCls:a,className:l,style:n,size:o,shape:i}=e,s=(0,r.default)({[`${a}-lg`]:"large"===o,[`${a}-sm`]:"small"===o}),d=(0,r.default)({[`${a}-circle`]:"circle"===i,[`${a}-square`]:"square"===i,[`${a}-round`]:"round"===i}),c=t.useMemo(()=>"number"==typeof o?{width:o,height:o,lineHeight:`${o}px`}:{},[o]);return t.createElement("span",{className:(0,r.default)(a,s,d,l),style:Object.assign(Object.assign({},c),n)})};e.i(296059);var o=e.i(694758),i=e.i(915654),s=e.i(246422),d=e.i(838378);let c=new o.Keyframes("ant-skeleton-loading",{"0%":{backgroundPosition:"100% 50%"},"100%":{backgroundPosition:"0 50%"}}),u=e=>({height:e,lineHeight:(0,i.unit)(e)}),m=e=>Object.assign({width:e},u(e)),g=(e,t)=>Object.assign({width:t(e).mul(5).equal(),minWidth:t(e).mul(5).equal()},u(e)),f=e=>Object.assign({width:e},u(e)),h=(e,t,r)=>{let{skeletonButtonCls:a}=e;return{[`${r}${a}-circle`]:{width:t,minWidth:t,borderRadius:"50%"},[`${r}${a}-round`]:{borderRadius:t}}},p=(e,t)=>Object.assign({width:t(e).mul(2).equal(),minWidth:t(e).mul(2).equal()},u(e)),b=(0,s.genStyleHooks)("Skeleton",e=>{let{componentCls:t,calc:r}=e;return(e=>{let{componentCls:t,skeletonAvatarCls:r,skeletonTitleCls:a,skeletonParagraphCls:l,skeletonButtonCls:n,skeletonInputCls:o,skeletonImageCls:i,controlHeight:s,controlHeightLG:d,controlHeightSM:u,gradientFromColor:b,padding:x,marginSM:v,borderRadius:w,titleHeight:y,blockRadius:C,paragraphLiHeight:k,controlHeightXS:N,paragraphMarginTop:j}=e;return{[t]:{display:"table",width:"100%",[`${t}-header`]:{display:"table-cell",paddingInlineEnd:x,verticalAlign:"top",[r]:Object.assign({display:"inline-block",verticalAlign:"top",background:b},m(s)),[`${r}-circle`]:{borderRadius:"50%"},[`${r}-lg`]:Object.assign({},m(d)),[`${r}-sm`]:Object.assign({},m(u))},[`${t}-content`]:{display:"table-cell",width:"100%",verticalAlign:"top",[a]:{width:"100%",height:y,background:b,borderRadius:C,[`+ ${l}`]:{marginBlockStart:u}},[l]:{padding:0,"> li":{width:"100%",height:k,listStyle:"none",background:b,borderRadius:C,"+ li":{marginBlockStart:N}}},[`${l}> li:last-child:not(:first-child):not(:nth-child(2))`]:{width:"61%"}},[`&-round ${t}-content`]:{[`${a}, ${l} > li`]:{borderRadius:w}}},[`${t}-with-avatar ${t}-content`]:{[a]:{marginBlockStart:v,[`+ ${l}`]:{marginBlockStart:j}}},[`${t}${t}-element`]:Object.assign(Object.assign(Object.assign(Object.assign({display:"inline-block",width:"auto"},(e=>{let{borderRadiusSM:t,skeletonButtonCls:r,controlHeight:a,controlHeightLG:l,controlHeightSM:n,gradientFromColor:o,calc:i}=e;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({[r]:Object.assign({display:"inline-block",verticalAlign:"top",background:o,borderRadius:t,width:i(a).mul(2).equal(),minWidth:i(a).mul(2).equal()},p(a,i))},h(e,a,r)),{[`${r}-lg`]:Object.assign({},p(l,i))}),h(e,l,`${r}-lg`)),{[`${r}-sm`]:Object.assign({},p(n,i))}),h(e,n,`${r}-sm`))})(e)),(e=>{let{skeletonAvatarCls:t,gradientFromColor:r,controlHeight:a,controlHeightLG:l,controlHeightSM:n}=e;return{[t]:Object.assign({display:"inline-block",verticalAlign:"top",background:r},m(a)),[`${t}${t}-circle`]:{borderRadius:"50%"},[`${t}${t}-lg`]:Object.assign({},m(l)),[`${t}${t}-sm`]:Object.assign({},m(n))}})(e)),(e=>{let{controlHeight:t,borderRadiusSM:r,skeletonInputCls:a,controlHeightLG:l,controlHeightSM:n,gradientFromColor:o,calc:i}=e;return{[a]:Object.assign({display:"inline-block",verticalAlign:"top",background:o,borderRadius:r},g(t,i)),[`${a}-lg`]:Object.assign({},g(l,i)),[`${a}-sm`]:Object.assign({},g(n,i))}})(e)),(e=>{let{skeletonImageCls:t,imageSizeBase:r,gradientFromColor:a,borderRadiusSM:l,calc:n}=e;return{[t]:Object.assign(Object.assign({display:"inline-flex",alignItems:"center",justifyContent:"center",verticalAlign:"middle",background:a,borderRadius:l},f(n(r).mul(2).equal())),{[`${t}-path`]:{fill:"#bfbfbf"},[`${t}-svg`]:Object.assign(Object.assign({},f(r)),{maxWidth:n(r).mul(4).equal(),maxHeight:n(r).mul(4).equal()}),[`${t}-svg${t}-svg-circle`]:{borderRadius:"50%"}}),[`${t}${t}-circle`]:{borderRadius:"50%"}}})(e)),[`${t}${t}-block`]:{width:"100%",[n]:{width:"100%"},[o]:{width:"100%"}},[`${t}${t}-active`]:{[` - ${a}, - ${l} > li, - ${r}, - ${n}, - ${o}, - ${i} - `]:Object.assign({},{background:e.skeletonLoadingBackground,backgroundSize:"400% 100%",animationName:c,animationDuration:e.skeletonLoadingMotionDuration,animationTimingFunction:"ease",animationIterationCount:"infinite"})}}})((0,d.mergeToken)(e,{skeletonAvatarCls:`${t}-avatar`,skeletonTitleCls:`${t}-title`,skeletonParagraphCls:`${t}-paragraph`,skeletonButtonCls:`${t}-button`,skeletonInputCls:`${t}-input`,skeletonImageCls:`${t}-image`,imageSizeBase:r(e.controlHeight).mul(1.5).equal(),borderRadius:100,skeletonLoadingBackground:`linear-gradient(90deg, ${e.gradientFromColor} 25%, ${e.gradientToColor} 37%, ${e.gradientFromColor} 63%)`,skeletonLoadingMotionDuration:"1.4s"}))},e=>{let{colorFillContent:t,colorFill:r}=e;return{color:t,colorGradientEnd:r,gradientFromColor:t,gradientToColor:r,titleHeight:e.controlHeight/2,blockRadius:e.borderRadiusSM,paragraphMarginTop:e.marginLG+e.marginXXS,paragraphLiHeight:e.controlHeight/2}},{deprecatedTokens:[["color","gradientFromColor"],["colorGradientEnd","gradientToColor"]]}),x=e=>{let{prefixCls:a,className:l,style:n,rows:o=0}=e,i=Array.from({length:o}).map((r,a)=>t.createElement("li",{key:a,style:{width:((e,t)=>{let{width:r,rows:a=2}=t;return Array.isArray(r)?r[e]:a-1===e?r:void 0})(a,e)}}));return t.createElement("ul",{className:(0,r.default)(a,l),style:n},i)},v=({prefixCls:e,className:a,width:l,style:n})=>t.createElement("h3",{className:(0,r.default)(e,a),style:Object.assign({width:l},n)});function w(e){return e&&"object"==typeof e?e:{}}let y=e=>{let{prefixCls:l,loading:o,className:i,rootClassName:s,style:d,children:c,avatar:u=!1,title:m=!0,paragraph:g=!0,active:f,round:h}=e,{getPrefixCls:p,direction:y,className:C,style:k}=(0,a.useComponentConfig)("skeleton"),N=p("skeleton",l),[j,$,S]=b(N);if(o||!("loading"in e)){let e,a,l=!!u,o=!!m,c=!!g;if(l){let r=Object.assign(Object.assign({prefixCls:`${N}-avatar`},o&&!c?{size:"large",shape:"square"}:{size:"large",shape:"circle"}),w(u));e=t.createElement("div",{className:`${N}-header`},t.createElement(n,Object.assign({},r)))}if(o||c){let e,r;if(o){let r=Object.assign(Object.assign({prefixCls:`${N}-title`},!l&&c?{width:"38%"}:l&&c?{width:"50%"}:{}),w(m));e=t.createElement(v,Object.assign({},r))}if(c){let e,a=Object.assign(Object.assign({prefixCls:`${N}-paragraph`},(e={},l&&o||(e.width="61%"),!l&&o?e.rows=3:e.rows=2,e)),w(g));r=t.createElement(x,Object.assign({},a))}a=t.createElement("div",{className:`${N}-content`},e,r)}let p=(0,r.default)(N,{[`${N}-with-avatar`]:l,[`${N}-active`]:f,[`${N}-rtl`]:"rtl"===y,[`${N}-round`]:h},C,i,s,$,S);return j(t.createElement("div",{className:p,style:Object.assign(Object.assign({},k),d)},e,a))}return null!=c?c:null};y.Button=e=>{let{prefixCls:o,className:i,rootClassName:s,active:d,block:c=!1,size:u="default"}=e,{getPrefixCls:m}=t.useContext(a.ConfigContext),g=m("skeleton",o),[f,h,p]=b(g),x=(0,l.default)(e,["prefixCls"]),v=(0,r.default)(g,`${g}-element`,{[`${g}-active`]:d,[`${g}-block`]:c},i,s,h,p);return f(t.createElement("div",{className:v},t.createElement(n,Object.assign({prefixCls:`${g}-button`,size:u},x))))},y.Avatar=e=>{let{prefixCls:o,className:i,rootClassName:s,active:d,shape:c="circle",size:u="default"}=e,{getPrefixCls:m}=t.useContext(a.ConfigContext),g=m("skeleton",o),[f,h,p]=b(g),x=(0,l.default)(e,["prefixCls","className"]),v=(0,r.default)(g,`${g}-element`,{[`${g}-active`]:d},i,s,h,p);return f(t.createElement("div",{className:v},t.createElement(n,Object.assign({prefixCls:`${g}-avatar`,shape:c,size:u},x))))},y.Input=e=>{let{prefixCls:o,className:i,rootClassName:s,active:d,block:c,size:u="default"}=e,{getPrefixCls:m}=t.useContext(a.ConfigContext),g=m("skeleton",o),[f,h,p]=b(g),x=(0,l.default)(e,["prefixCls"]),v=(0,r.default)(g,`${g}-element`,{[`${g}-active`]:d,[`${g}-block`]:c},i,s,h,p);return f(t.createElement("div",{className:v},t.createElement(n,Object.assign({prefixCls:`${g}-input`,size:u},x))))},y.Image=e=>{let{prefixCls:l,className:n,rootClassName:o,style:i,active:s}=e,{getPrefixCls:d}=t.useContext(a.ConfigContext),c=d("skeleton",l),[u,m,g]=b(c),f=(0,r.default)(c,`${c}-element`,{[`${c}-active`]:s},n,o,m,g);return u(t.createElement("div",{className:f},t.createElement("div",{className:(0,r.default)(`${c}-image`,n),style:i},t.createElement("svg",{viewBox:"0 0 1098 1024",xmlns:"http://www.w3.org/2000/svg",className:`${c}-image-svg`},t.createElement("title",null,"Image placeholder"),t.createElement("path",{d:"M365.714286 329.142857q0 45.714286-32.036571 77.677714t-77.677714 32.036571-77.677714-32.036571-32.036571-77.677714 32.036571-77.677714 77.677714-32.036571 77.677714 32.036571 32.036571 77.677714zM950.857143 548.571429l0 256-804.571429 0 0-109.714286 182.857143-182.857143 91.428571 91.428571 292.571429-292.571429zM1005.714286 146.285714l-914.285714 0q-7.460571 0-12.873143 5.412571t-5.412571 12.873143l0 694.857143q0 7.460571 5.412571 12.873143t12.873143 5.412571l914.285714 0q7.460571 0 12.873143-5.412571t5.412571-12.873143l0-694.857143q0-7.460571-5.412571-12.873143t-12.873143-5.412571zM1097.142857 164.571429l0 694.857143q0 37.741714-26.843429 64.585143t-64.585143 26.843429l-914.285714 0q-37.741714 0-64.585143-26.843429t-26.843429-64.585143l0-694.857143q0-37.741714 26.843429-64.585143t64.585143-26.843429l914.285714 0q37.741714 0 64.585143 26.843429t26.843429 64.585143z",className:`${c}-image-path`})))))},y.Node=e=>{let{prefixCls:l,className:n,rootClassName:o,style:i,active:s,children:d}=e,{getPrefixCls:c}=t.useContext(a.ConfigContext),u=c("skeleton",l),[m,g,f]=b(u),h=(0,r.default)(u,`${u}-element`,{[`${u}-active`]:s},g,n,o,f);return m(t.createElement("div",{className:h},t.createElement("div",{className:(0,r.default)(`${u}-image`,n),style:i},d)))},e.s(["default",0,y],185793)},922611,e=>{"use strict";var t=e.i(271645),r=e.i(175066);function a(){}let l=t.createContext({add:a,remove:a});e.s(["usePanelRef",0,function(e){let a=t.useContext(l),n=t.useRef(null);return(0,r.default)(t=>{if(t){let r=e?t.querySelector(e):t;r&&(a.add(r),n.current=r)}else a.remove(n.current)})}])},500330,e=>{"use strict";var t=e.i(727749);let r=(e,t=0,r=!1,a=!0)=>{if(null==e||!Number.isFinite(e)||0===e&&!a)return"-";let l={minimumFractionDigits:t,maximumFractionDigits:t};if(!r)return e.toLocaleString("en-US",l);let n=e<0?"-":"",o=Math.abs(e),i=o,s="";return o>=1e6?(i=o/1e6,s="M"):o>=1e3&&(i=o/1e3,s="K"),`${n}${i.toLocaleString("en-US",l)}${s}`},a=async(e,r="Copied to clipboard")=>{if(!e)return!1;if(!navigator||!navigator.clipboard||!navigator.clipboard.writeText)return l(e,r);try{return await navigator.clipboard.writeText(e),t.default.success(r),!0}catch(t){return console.error("Clipboard API failed: ",t),l(e,r)}},l=(e,r)=>{try{let a=document.createElement("textarea");a.value=e,a.style.position="fixed",a.style.left="-999999px",a.style.top="-999999px",a.setAttribute("readonly",""),document.body.appendChild(a),a.focus(),a.select();let l=document.execCommand("copy");if(document.body.removeChild(a),l)return t.default.success(r),!0;throw Error("execCommand failed")}catch(e){return t.default.fromBackend("Failed to copy to clipboard"),console.error("Failed to copy: ",e),!1}};e.s(["copyToClipboard",0,a,"formatNumberWithCommas",0,r,"getSpendString",0,(e,t=6)=>{if(null==e||!Number.isFinite(e)||0===e)return"-";let a=r(e,t,!1,!1);if(0===Number(a.replace(/,/g,""))){let e=(1/10**t).toFixed(t);return`< $${e}`}return`$${a}`},"updateExistingKeys",0,function(e,t){let r=structuredClone(e);for(let[e,a]of Object.entries(t))e in r&&(r[e]=a);return r}])},112179,581070,e=>{"use strict";var t=e.i(843476),r=e.i(487486),a=e.i(115504),l=e.i(746798);function n({content:e,trigger:r}){return(0,t.jsx)(l.TooltipProvider,{delay:300,children:(0,t.jsxs)(l.Tooltip,{children:[(0,t.jsx)(l.TooltipTrigger,{render:r}),(0,t.jsx)(l.TooltipContent,{children:e})]})})}e.s(["CellTooltip",0,n],581070);let o={success:"border-green-200 bg-green-50 text-green-600",error:"border-red-200 bg-red-50 text-red-600",warning:"border-amber-200 bg-amber-50 text-amber-600",neutral:"border-gray-200 bg-gray-50 text-gray-600",info:"border-blue-200 bg-blue-50 text-blue-600"};e.s(["StatusBadge",0,function({tone:e,label:l,tooltip:i,dataTestId:s}){let d=(0,t.jsx)(r.Badge,{variant:"outline","data-testid":s,className:(0,a.cn)("whitespace-nowrap font-normal",o[e]),children:l});return i?(0,t.jsx)(n,{content:i,trigger:d}):d}],112179)},200208,399536,997422,146512,e=>{"use strict";var t=e.i(843476),r=e.i(581070);let a=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],l=e=>String(e).padStart(2,"0");e.s(["DateCell",0,function({value:e,precision:n="datetime",fallback:o="-"}){let i,s,d,c=e?new Date(e):null;return!c||Number.isNaN(c.getTime())?(0,t.jsx)("span",{className:"text-muted-foreground",children:o}):(0,t.jsx)(r.CellTooltip,{content:(i=Intl.DateTimeFormat().resolvedOptions().timeZone,s=`${a[c.getMonth()]} ${c.getDate()}, ${c.getFullYear()}`,d=`${l(c.getHours())}:${l(c.getMinutes())}:${l(c.getSeconds())}`,`${s}, ${d} (${i})`),trigger:(0,t.jsx)("span",{className:"whitespace-nowrap",children:"date"===n?`${a[c.getMonth()]} ${c.getDate()}, ${c.getFullYear()}`:`${a[c.getMonth()]} ${c.getDate()}, ${l(c.getHours())}:${l(c.getMinutes())}:${l(c.getSeconds())}`})})}],200208);var n=e.i(174886),o=e.i(115504),i=e.i(500330);let s={pill:{base:"font-mono text-xs font-normal px-2 py-0.5 rounded-md text-left bg-blue-50 text-blue-500",clickable:"hover:bg-blue-100 cursor-pointer"},plain:{base:"font-mono text-xs text-left",clickable:"hover:text-blue-600 cursor-pointer"}};e.s(["IdCell",0,function({value:e,variant:a="pill",onClick:l,copyable:d=!1,truncate:c=!0,fallback:u="-",tooltip:m,disabled:g=!1,dataTestId:f,className:h}){if(!e)return(0,t.jsx)("span",{className:"text-muted-foreground",children:u});let p=!!l&&!g,b=(0,o.cn)(s[a].base,p&&s[a].clickable,c&&"block max-w-[15ch] truncate",g&&"opacity-50",h),x=p?(0,t.jsx)("button",{type:"button",className:b,"data-testid":f,onClick:()=>l(e),children:e}):(0,t.jsx)("span",{className:b,"data-testid":f,children:e}),v=(0,t.jsx)(r.CellTooltip,{content:m??e,trigger:x});return d?(0,t.jsxs)("span",{className:"inline-flex max-w-full items-center gap-1",children:[v,(0,t.jsx)("button",{type:"button","aria-label":"Copy ID",className:"shrink-0 cursor-pointer text-muted-foreground hover:text-foreground",onClick:t=>{t.stopPropagation(),(0,i.copyToClipboard)(e)},children:(0,t.jsx)(n.Copy,{className:"size-3"})})]}):v}],399536);var d=e.i(463059);e.s(["IdentityCell",0,function({title:e,subtitle:r,badge:a,onClick:l,className:n,titleClassName:i}){let s=(0,t.jsxs)("div",{className:"flex min-w-0 flex-col gap-0.5",children:[(0,t.jsx)("span",{className:(0,o.cn)("truncate text-sm font-medium text-foreground",i),children:e}),(null!=r&&""!==r||null!=a)&&(0,t.jsxs)("span",{className:"flex min-w-0 items-center gap-2",children:[null!=r&&""!==r&&(0,t.jsx)("span",{className:"truncate font-mono text-xs text-muted-foreground",children:r}),a]})]});return null!=l?(0,t.jsxs)("button",{type:"button",onClick:l,className:(0,o.cn)("group -mx-2 flex w-[calc(100%+1rem)] cursor-pointer items-center gap-2 rounded-md px-2 py-1 text-left transition-colors hover:bg-muted",n),children:[s,(0,t.jsx)(d.ChevronRight,{className:"ml-auto size-4 shrink-0 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100"})]}):(0,t.jsx)("div",{className:(0,o.cn)("min-w-0",n),children:s})}],997422);let c={hasModelAccess:!1,label:"Management"},u={hasModelAccess:!1,label:"Read-only"},m={hasModelAccess:!1,label:"SCIM"},g={hasModelAccess:!0,label:null},f=e=>e.startsWith("/scim"),h=(e,t)=>1===e.length&&e[0]===t;e.s(["deriveKeyModelScope",0,(e,t)=>"management"===t?c:"read_only"===t?u:Array.isArray(e)&&0!==e.length?e.every(f)?m:h(e,"management_routes")?c:h(e,"info_routes")?u:g:g],146512)},355619,e=>{"use strict";var t=e.i(602869);let r=async(e,r,a)=>{try{if(null===e||null===r)return;if(null!==a){let l=(await (0,t.modelAvailableCall)(a,e,r,!0,null,!0)).data.map(e=>e.id),n=[],o=[];return l.forEach(e=>{e.endsWith("/*")?n.push(e):o.push(e)}),[...n,...o]}}catch(e){console.error("Error fetching user models:",e)}};e.s(["excludeProxyWideSentinel",0,e=>e.filter(e=>"all-proxy-models"!==e),"fetchAvailableModelsForTeamOrKey",0,r,"getModelDisplayName",0,e=>{if("all-proxy-models"===e)return"All Proxy Models";if(e.endsWith("/*")){let t=e.replace("/*","");return`All ${t} models`}return e},"hasAllModelsSentinel",0,e=>e.includes("all-proxy-models")||e.includes("all-team-models"),"unfurlWildcardModelsInList",0,(e,t)=>{let r=[],a=[];return e.forEach(e=>{if(e.endsWith("/*")){let l=e.replace("/*",""),n=t.filter(e=>e.startsWith(l+"/"));a.push(...n),r.push(e)}else a.push(e)}),[...r,...a].filter((e,t,r)=>r.indexOf(e)===t)}])},622826,547227,964471,630500,e=>{"use strict";var t=e.i(581070);e.i(200208),e.i(399536),e.i(997422);var r=e.i(843476),a=e.i(146512),l=e.i(355619),n=e.i(487486);let o="all-proxy-models",i=e=>{if(e===o)return"All Proxy Models";let t=(0,l.getModelDisplayName)(e);return t.length>30?`${t.slice(0,30)}...`:t};e.s(["ModelsCell",0,function({models:e,maxVisible:l=3,allowedRoutes:s,keyType:d}){if(!Array.isArray(e)||0===e.length){let e=(0,a.deriveKeyModelScope)(s,d);return e.hasModelAccess?(0,r.jsx)(n.Badge,{variant:"secondary",children:"All Proxy Models"}):(0,r.jsx)(t.CellTooltip,{content:`Scoped to ${e.label} routes; this key cannot call any models`,trigger:(0,r.jsx)(n.Badge,{variant:"secondary",className:"cursor-default",children:"No model access"})})}let c=e.slice(0,l),u=e.slice(l);return(0,r.jsxs)("div",{className:"flex flex-wrap items-center gap-1",children:[c.map((e,t)=>(0,r.jsx)(n.Badge,{variant:e===o?"secondary":"outline",children:i(e)},t)),u.length>0&&(0,r.jsx)(t.CellTooltip,{content:(0,r.jsx)("div",{className:"flex max-w-[280px] flex-col gap-0.5",children:u.map((e,t)=>(0,r.jsx)("span",{children:i(e)},t))}),trigger:(0,r.jsxs)(n.Badge,{variant:"outline",className:"cursor-default",children:["+",u.length," more"]})})]})}],547227);var s=e.i(500330);e.s(["MoneyCell",0,function({value:e,decimals:t=4,emptyText:a="-",showZero:l=!1}){return null==e||Number.isNaN(e)?(0,r.jsx)("span",{className:"text-muted-foreground",children:a}):0===e?l?(0,r.jsx)("span",{className:"whitespace-nowrap",children:`$${(0,s.formatNumberWithCommas)(0,t,!1,!0)}`}):(0,r.jsx)("span",{className:"text-muted-foreground",children:"-"}):(0,r.jsx)("span",{className:"whitespace-nowrap",children:(0,s.getSpendString)(e,t)})}],964471);var d=e.i(944835);e.s(["SpendBudgetCell",0,function({spend:e,maxBudget:t,teamMaxBudget:a}){let l="number"!=typeof e||Number.isNaN(e)?0:e,n=t??a??null,o=null==t&&null!=a,i="number"==typeof n&&n>0,c=i?l/n*100:0,u=l>0?(0,s.getSpendString)(l,4):"$0.00",m=null===n?"· Unlimited":`of $${(0,s.formatNumberWithCommas)(n)}${o?" (Team)":""}`;return(0,r.jsxs)("div",{className:"flex min-w-[130px] flex-col gap-1",children:[(0,r.jsxs)("div",{className:"whitespace-nowrap text-xs",children:[(0,r.jsx)("span",{className:"font-medium tabular-nums text-foreground",children:u})," ",(0,r.jsx)("span",{className:"text-muted-foreground",children:m})]}),i&&(0,r.jsx)(d.Meter,{value:l,max:n,"aria-valuetext":`${u} of $${(0,s.formatNumberWithCommas)(n)}`,children:(0,r.jsx)(d.MeterTrack,{children:(0,r.jsx)(d.MeterIndicator,{tone:c>100?"over":c>=80?"warning":"default"})})})]})}],630500),e.i(112179),e.s([],622826)},841947,e=>{"use strict";let t=(0,e.i(475254).default)("x",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]);e.s(["default",0,t])},37727,e=>{"use strict";var t=e.i(841947);e.s(["X",()=>t.default])},409797,e=>{"use strict";var t=e.i(631171);e.s(["ChevronDownIcon",()=>t.default])},233565,e=>{"use strict";var t=e.i(246349);e.s(["ChevronRightIcon",()=>t.default])},350967,46757,e=>{"use strict";var t=e.i(290571),r=e.i(444755),a=e.i(673706),l=e.i(271645);let n={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"},o={0:"sm:grid-cols-none",1:"sm:grid-cols-1",2:"sm:grid-cols-2",3:"sm:grid-cols-3",4:"sm:grid-cols-4",5:"sm:grid-cols-5",6:"sm:grid-cols-6",7:"sm:grid-cols-7",8:"sm:grid-cols-8",9:"sm:grid-cols-9",10:"sm:grid-cols-10",11:"sm:grid-cols-11",12:"sm:grid-cols-12"},i={0:"md:grid-cols-none",1:"md:grid-cols-1",2:"md:grid-cols-2",3:"md:grid-cols-3",4:"md:grid-cols-4",5:"md:grid-cols-5",6:"md:grid-cols-6",7:"md:grid-cols-7",8:"md:grid-cols-8",9:"md:grid-cols-9",10:"md:grid-cols-10",11:"md:grid-cols-11",12:"md:grid-cols-12"},s={0:"lg:grid-cols-none",1:"lg:grid-cols-1",2:"lg:grid-cols-2",3:"lg:grid-cols-3",4:"lg:grid-cols-4",5:"lg:grid-cols-5",6:"lg:grid-cols-6",7:"lg:grid-cols-7",8:"lg:grid-cols-8",9:"lg:grid-cols-9",10:"lg:grid-cols-10",11:"lg:grid-cols-11",12:"lg:grid-cols-12"};e.s(["colSpan",0,{1:"col-span-1",2:"col-span-2",3:"col-span-3",4:"col-span-4",5:"col-span-5",6:"col-span-6",7:"col-span-7",8:"col-span-8",9:"col-span-9",10:"col-span-10",11:"col-span-11",12:"col-span-12",13:"col-span-13"},"colSpanLg",0,{1:"lg:col-span-1",2:"lg:col-span-2",3:"lg:col-span-3",4:"lg:col-span-4",5:"lg:col-span-5",6:"lg:col-span-6",7:"lg:col-span-7",8:"lg:col-span-8",9:"lg:col-span-9",10:"lg:col-span-10",11:"lg:col-span-11",12:"lg:col-span-12",13:"lg:col-span-13"},"colSpanMd",0,{1:"md:col-span-1",2:"md:col-span-2",3:"md:col-span-3",4:"md:col-span-4",5:"md:col-span-5",6:"md:col-span-6",7:"md:col-span-7",8:"md:col-span-8",9:"md:col-span-9",10:"md:col-span-10",11:"md:col-span-11",12:"md:col-span-12",13:"md:col-span-13"},"colSpanSm",0,{1:"sm:col-span-1",2:"sm:col-span-2",3:"sm:col-span-3",4:"sm:col-span-4",5:"sm:col-span-5",6:"sm:col-span-6",7:"sm:col-span-7",8:"sm:col-span-8",9:"sm:col-span-9",10:"sm:col-span-10",11:"sm:col-span-11",12:"sm:col-span-12",13:"sm:col-span-13"},"gridCols",0,n,"gridColsLg",0,s,"gridColsMd",0,i,"gridColsSm",0,o],46757);let d=(0,a.makeClassName)("Grid"),c=(e,t)=>e&&Object.keys(t).includes(String(e))?t[e]:"",u=l.default.forwardRef((e,a)=>{let{numItems:u=1,numItemsSm:m,numItemsMd:g,numItemsLg:f,children:h,className:p}=e,b=(0,t.__rest)(e,["numItems","numItemsSm","numItemsMd","numItemsLg","children","className"]),x=c(u,n),v=c(m,o),w=c(g,i),y=c(f,s),C=(0,r.tremorTwMerge)(x,v,w,y);return l.default.createElement("div",Object.assign({ref:a,className:(0,r.tremorTwMerge)(d("root"),"grid",C,p)},b),h)});u.displayName="Grid",e.s(["Grid",0,u],350967)},482725,e=>{"use strict";var t=e.i(244451);e.s(["Spin",()=>t.default])},555987,e=>{"use strict";var t=e.i(221688),r=e.i(950643);let a=/^(https?:|data:|blob:|\/\/)/i;e.s(["resolveLogoSrc",0,(e,l=t.serverRootPath)=>{if(e){let t;return a.test(e)?e:(t=(0,r.normalizeRootPath)(l),`${t}${e.startsWith("/")?e:`/${e}`}`)}}])},728889,e=>{"use strict";var t=e.i(290571),r=e.i(271645),a=e.i(829087),l=e.i(480731),n=e.i(444755),o=e.i(673706),i=e.i(95779);let s={xs:{paddingX:"px-1.5",paddingY:"py-1.5"},sm:{paddingX:"px-1.5",paddingY:"py-1.5"},md:{paddingX:"px-2",paddingY:"py-2"},lg:{paddingX:"px-2",paddingY:"py-2"},xl:{paddingX:"px-2.5",paddingY:"py-2.5"}},d={xs:{height:"h-3",width:"w-3"},sm:{height:"h-5",width:"w-5"},md:{height:"h-5",width:"w-5"},lg:{height:"h-7",width:"w-7"},xl:{height:"h-9",width:"w-9"}},c={simple:{rounded:"",border:"",ring:"",shadow:""},light:{rounded:"rounded-tremor-default",border:"",ring:"",shadow:""},shadow:{rounded:"rounded-tremor-default",border:"border",ring:"",shadow:"shadow-tremor-card dark:shadow-dark-tremor-card"},solid:{rounded:"rounded-tremor-default",border:"border-2",ring:"ring-1",shadow:""},outlined:{rounded:"rounded-tremor-default",border:"border",ring:"ring-2",shadow:""}},u=(0,o.makeClassName)("Icon"),m=r.default.forwardRef((e,m)=>{let{icon:g,variant:f="simple",tooltip:h,size:p=l.Sizes.SM,color:b,className:x}=e,v=(0,t.__rest)(e,["icon","variant","tooltip","size","color","className"]),w=((e,t)=>{switch(e){case"simple":return{textColor:t?(0,o.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:"",borderColor:"",ringColor:""};case"light":return{textColor:t?(0,o.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,n.tremorTwMerge)((0,o.getColorClassNames)(t,i.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-brand-muted dark:bg-dark-tremor-brand-muted",borderColor:"",ringColor:""};case"shadow":return{textColor:t?(0,o.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,n.tremorTwMerge)((0,o.getColorClassNames)(t,i.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-background dark:bg-dark-tremor-background",borderColor:"border-tremor-border dark:border-dark-tremor-border",ringColor:""};case"solid":return{textColor:t?(0,o.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",bgColor:t?(0,n.tremorTwMerge)((0,o.getColorClassNames)(t,i.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-brand dark:bg-dark-tremor-brand",borderColor:"border-tremor-brand-inverted dark:border-dark-tremor-brand-inverted",ringColor:"ring-tremor-ring dark:ring-dark-tremor-ring"};case"outlined":return{textColor:t?(0,o.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,n.tremorTwMerge)((0,o.getColorClassNames)(t,i.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-background dark:bg-dark-tremor-background",borderColor:t?(0,o.getColorClassNames)(t,i.colorPalette.ring).borderColor:"border-tremor-brand-subtle dark:border-dark-tremor-brand-subtle",ringColor:t?(0,n.tremorTwMerge)((0,o.getColorClassNames)(t,i.colorPalette.ring).ringColor,"ring-opacity-40"):"ring-tremor-brand-muted dark:ring-dark-tremor-brand-muted"}}})(f,b),{tooltipProps:y,getReferenceProps:C}=(0,a.useTooltip)();return r.default.createElement("span",Object.assign({ref:(0,o.mergeRefs)([m,y.refs.setReference]),className:(0,n.tremorTwMerge)(u("root"),"inline-flex shrink-0 items-center justify-center",w.bgColor,w.textColor,w.borderColor,w.ringColor,c[f].rounded,c[f].border,c[f].shadow,c[f].ring,s[p].paddingX,s[p].paddingY,x)},C,v),r.default.createElement(a.default,Object.assign({text:h},y)),r.default.createElement(g,{className:(0,n.tremorTwMerge)(u("icon"),"shrink-0",d[p].height,d[p].width)}))});m.displayName="Icon",e.s(["default",0,m],728889)},360820,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 15l7-7 7 7"}))});e.s(["ChevronUpIcon",0,r],360820)},541202,e=>{"use strict";var t=e.i(843476),r=e.i(522016),a=e.i(560445);e.s(["DeprecationBanner",0,({featureName:e})=>(0,t.jsx)(a.Alert,{message:`${e} is on a draft deprecation list`,description:(0,t.jsxs)(t.Fragment,{children:[`${e} is one of several experimental features we're considering removing, potentially as early as September 1, 2026. This list is a draft and is not final. If you rely on this feature, please share feedback on the `,(0,t.jsx)(r.default,{href:"https://github.com/BerriAI/litellm/discussions/32090",target:"_blank",rel:"noopener noreferrer",children:"deprecation discussion"}),"."]}),type:"info",showIcon:!0,closable:!0,style:{marginBottom:16}})])},888288,e=>{"use strict";var t=e.i(271645);e.s(["default",0,(e,r)=>{let a=void 0!==r,[l,n]=(0,t.useState)(e);return[a?r:l,e=>{a||n(e)}]}])},446428,854056,e=>{"use strict";let t;var r=e.i(290571),a=e.i(271645);e.s(["default",0,e=>{var t=(0,r.__rest)(e,[]);return a.default.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"},t),a.default.createElement("path",{d:"M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 10.5858L9.17157 7.75736L7.75736 9.17157L10.5858 12L7.75736 14.8284L9.17157 16.2426L12 13.4142L14.8284 16.2426L16.2426 14.8284L13.4142 12L16.2426 9.17157L14.8284 7.75736L12 10.5858Z"}))}],446428);var l=e.i(746725),n=e.i(914189),o=e.i(553521),i=e.i(835696),s=e.i(941444),d=e.i(178677),c=e.i(294316),u=e.i(83733),m=e.i(233137),g=e.i(732607),f=e.i(397701),h=e.i(700020);function p(e){var t;return!!(e.enter||e.enterFrom||e.enterTo||e.leave||e.leaveFrom||e.leaveTo)||(null!=(t=e.as)?t:C)!==a.Fragment||1===a.default.Children.count(e.children)}let b=(0,a.createContext)(null);b.displayName="TransitionContext";var x=((t=x||{}).Visible="visible",t.Hidden="hidden",t);let v=(0,a.createContext)(null);function w(e){return"children"in e?w(e.children):e.current.filter(({el:e})=>null!==e.current).filter(({state:e})=>"visible"===e).length>0}function y(e,t){let r=(0,s.useLatestValue)(e),i=(0,a.useRef)([]),d=(0,o.useIsMounted)(),c=(0,l.useDisposables)(),u=(0,n.useEvent)((e,t=h.RenderStrategy.Hidden)=>{let a=i.current.findIndex(({el:t})=>t===e);-1!==a&&((0,f.match)(t,{[h.RenderStrategy.Unmount](){i.current.splice(a,1)},[h.RenderStrategy.Hidden](){i.current[a].state="hidden"}}),c.microTask(()=>{var e;!w(i)&&d.current&&(null==(e=r.current)||e.call(r))}))}),m=(0,n.useEvent)(e=>{let t=i.current.find(({el:t})=>t===e);return t?"visible"!==t.state&&(t.state="visible"):i.current.push({el:e,state:"visible"}),()=>u(e,h.RenderStrategy.Unmount)}),g=(0,a.useRef)([]),p=(0,a.useRef)(Promise.resolve()),b=(0,a.useRef)({enter:[],leave:[]}),x=(0,n.useEvent)((e,r,a)=>{g.current.splice(0),t&&(t.chains.current[r]=t.chains.current[r].filter(([t])=>t!==e)),null==t||t.chains.current[r].push([e,new Promise(e=>{g.current.push(e)})]),null==t||t.chains.current[r].push([e,new Promise(e=>{Promise.all(b.current[r].map(([e,t])=>t)).then(()=>e())})]),"enter"===r?p.current=p.current.then(()=>null==t?void 0:t.wait.current).then(()=>a(r)):a(r)}),v=(0,n.useEvent)((e,t,r)=>{Promise.all(b.current[t].splice(0).map(([e,t])=>t)).then(()=>{var e;null==(e=g.current.shift())||e()}).then(()=>r(t))});return(0,a.useMemo)(()=>({children:i,register:m,unregister:u,onStart:x,onStop:v,wait:p,chains:b}),[m,u,i,x,v,b,p])}v.displayName="NestingContext";let C=a.Fragment,k=h.RenderFeatures.RenderStrategy,N=(0,h.forwardRefWithAs)(function(e,t){let{show:r,appear:l=!1,unmount:o=!0,...s}=e,u=(0,a.useRef)(null),g=p(e),f=(0,c.useSyncRefs)(...g?[u,t]:null===t?[]:[t]);(0,d.useServerHandoffComplete)();let x=(0,m.useOpenClosed)();if(void 0===r&&null!==x&&(r=(x&m.State.Open)===m.State.Open),void 0===r)throw Error("A is used but it is missing a `show={true | false}` prop.");let[C,N]=(0,a.useState)(r?"visible":"hidden"),$=y(()=>{r||N("hidden")}),[S,E]=(0,a.useState)(!0),T=(0,a.useRef)([r]);(0,i.useIsoMorphicEffect)(()=>{!1!==S&&T.current[T.current.length-1]!==r&&(T.current.push(r),E(!1))},[T,r]);let M=(0,a.useMemo)(()=>({show:r,appear:l,initial:S}),[r,l,S]);(0,i.useIsoMorphicEffect)(()=>{r?N("visible"):w($)||null===u.current||N("hidden")},[r,$]);let R={unmount:o},O=(0,n.useEvent)(()=>{var t;S&&E(!1),null==(t=e.beforeEnter)||t.call(e)}),I=(0,n.useEvent)(()=>{var t;S&&E(!1),null==(t=e.beforeLeave)||t.call(e)}),A=(0,h.useRender)();return a.default.createElement(v.Provider,{value:$},a.default.createElement(b.Provider,{value:M},A({ourProps:{...R,as:a.Fragment,children:a.default.createElement(j,{ref:f,...R,...s,beforeEnter:O,beforeLeave:I})},theirProps:{},defaultTag:a.Fragment,features:k,visible:"visible"===C,name:"Transition"})))}),j=(0,h.forwardRefWithAs)(function(e,t){var r,l;let{transition:o=!0,beforeEnter:s,afterEnter:x,beforeLeave:N,afterLeave:j,enter:$,enterFrom:S,enterTo:E,entered:T,leave:M,leaveFrom:R,leaveTo:O,...I}=e,[A,L]=(0,a.useState)(null),P=(0,a.useRef)(null),D=p(e),H=(0,c.useSyncRefs)(...D?[P,t,L]:null===t?[]:[t]),B=null==(r=I.unmount)||r?h.RenderStrategy.Unmount:h.RenderStrategy.Hidden,{show:_,appear:F,initial:z}=function(){let e=(0,a.useContext)(b);if(null===e)throw Error("A is used but it is missing a parent or .");return e}(),[W,q]=(0,a.useState)(_?"visible":"hidden"),V=function(){let e=(0,a.useContext)(v);if(null===e)throw Error("A is used but it is missing a parent or .");return e}(),{register:K,unregister:X}=V;(0,i.useIsoMorphicEffect)(()=>K(P),[K,P]),(0,i.useIsoMorphicEffect)(()=>{if(B===h.RenderStrategy.Hidden&&P.current)return _&&"visible"!==W?void q("visible"):(0,f.match)(W,{hidden:()=>X(P),visible:()=>K(P)})},[W,P,K,X,_,B]);let U=(0,d.useServerHandoffComplete)();(0,i.useIsoMorphicEffect)(()=>{if(D&&U&&"visible"===W&&null===P.current)throw Error("Did you forget to passthrough the `ref` to the actual DOM node?")},[P,W,U,D]);let G=z&&!F,Y=F&&_&&z,Z=(0,a.useRef)(!1),J=y(()=>{Z.current||(q("hidden"),X(P))},V),Q=(0,n.useEvent)(e=>{Z.current=!0,J.onStart(P,e?"enter":"leave",e=>{"enter"===e?null==s||s():"leave"===e&&(null==N||N())})}),ee=(0,n.useEvent)(e=>{let t=e?"enter":"leave";Z.current=!1,J.onStop(P,t,e=>{"enter"===e?null==x||x():"leave"===e&&(null==j||j())}),"leave"!==t||w(J)||(q("hidden"),X(P))});(0,a.useEffect)(()=>{D&&o||(Q(_),ee(_))},[_,D,o]);let et=!(!o||!D||!U||G),[,er]=(0,u.useTransition)(et,A,_,{start:Q,end:ee}),ea=(0,h.compact)({ref:H,className:(null==(l=(0,g.classNames)(I.className,Y&&$,Y&&S,er.enter&&$,er.enter&&er.closed&&S,er.enter&&!er.closed&&E,er.leave&&M,er.leave&&!er.closed&&R,er.leave&&er.closed&&O,!er.transition&&_&&T))?void 0:l.trim())||void 0,...(0,u.transitionDataAttributes)(er)}),el=0;"visible"===W&&(el|=m.State.Open),"hidden"===W&&(el|=m.State.Closed),er.enter&&(el|=m.State.Opening),er.leave&&(el|=m.State.Closing);let en=(0,h.useRender)();return a.default.createElement(v.Provider,{value:J},a.default.createElement(m.OpenClosedProvider,{value:el},en({ourProps:ea,theirProps:I,defaultTag:C,features:k,visible:"visible"===W,name:"Transition.Child"})))}),$=(0,h.forwardRefWithAs)(function(e,t){let r=null!==(0,a.useContext)(b),l=null!==(0,m.useOpenClosed)();return a.default.createElement(a.default.Fragment,null,!r&&l?a.default.createElement(N,{ref:t,...e}):a.default.createElement(j,{ref:t,...e}))}),S=Object.assign(N,{Child:$,Root:N});e.s(["Transition",0,S],854056)},757440,e=>{"use strict";var t=e.i(290571),r=e.i(271645);e.s(["default",0,e=>{var a=(0,t.__rest)(e,[]);return r.default.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"},a),r.default.createElement("path",{d:"M11.9999 13.1714L16.9497 8.22168L18.3639 9.63589L11.9999 15.9999L5.63599 9.63589L7.0502 8.22168L11.9999 13.1714Z"}))}])},206929,e=>{"use strict";var t=e.i(290571),r=e.i(757440),a=e.i(271645),l=e.i(446428),n=e.i(444755),o=e.i(673706),i=e.i(103471),s=e.i(495470),d=e.i(854056),c=e.i(888288);let u=(0,o.makeClassName)("Select"),m=a.default.forwardRef((e,o)=>{let{defaultValue:m="",value:g,onValueChange:f,placeholder:h="Select...",disabled:p=!1,icon:b,enableClear:x=!1,required:v,children:w,name:y,error:C=!1,errorMessage:k,className:N,id:j}=e,$=(0,t.__rest)(e,["defaultValue","value","onValueChange","placeholder","disabled","icon","enableClear","required","children","name","error","errorMessage","className","id"]),S=(0,a.useRef)(null),E=a.Children.toArray(w),[T,M]=(0,c.default)(m,g),R=(0,a.useMemo)(()=>{let e=a.default.Children.toArray(w).filter(a.isValidElement);return(0,i.constructValueToNameMapping)(e)},[w]);return a.default.createElement("div",{className:(0,n.tremorTwMerge)("w-full min-w-[10rem] text-tremor-default",N)},a.default.createElement("div",{className:"relative"},a.default.createElement("select",{title:"select-hidden",required:v,className:(0,n.tremorTwMerge)("h-full w-full absolute left-0 top-0 -z-10 opacity-0"),value:T,onChange:e=>{e.preventDefault()},name:y,disabled:p,id:j,onFocus:()=>{let e=S.current;e&&e.focus()}},a.default.createElement("option",{className:"hidden",value:"",disabled:!0,hidden:!0},h),E.map(e=>{let t=e.props.value,r=e.props.children;return a.default.createElement("option",{className:"hidden",key:t,value:t},r)})),a.default.createElement(s.Listbox,Object.assign({as:"div",ref:o,defaultValue:T,value:T,onChange:e=>{null==f||f(e),M(e)},disabled:p,id:j},$),({value:e})=>{var t;return a.default.createElement(a.default.Fragment,null,a.default.createElement(s.ListboxButton,{ref:S,className:(0,n.tremorTwMerge)("w-full outline-none text-left whitespace-nowrap truncate rounded-tremor-default focus:ring-2 transition duration-100 border pr-8 py-2","border-tremor-border shadow-tremor-input focus:border-tremor-brand-subtle focus:ring-tremor-brand-muted","dark:border-dark-tremor-border dark:shadow-dark-tremor-input dark:focus:border-dark-tremor-brand-subtle dark:focus:ring-dark-tremor-brand-muted",b?"pl-10":"pl-3",(0,i.getSelectButtonColors)((0,i.hasValue)(e),p,C))},b&&a.default.createElement("span",{className:(0,n.tremorTwMerge)("absolute inset-y-0 left-0 flex items-center ml-px pl-2.5")},a.default.createElement(b,{className:(0,n.tremorTwMerge)(u("Icon"),"flex-none h-5 w-5","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle")})),a.default.createElement("span",{className:"w-[90%] block truncate"},e&&null!=(t=R.get(e))?t:h),a.default.createElement("span",{className:(0,n.tremorTwMerge)("absolute inset-y-0 right-0 flex items-center mr-3")},a.default.createElement(r.default,{className:(0,n.tremorTwMerge)(u("arrowDownIcon"),"flex-none h-5 w-5","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle")}))),x&&T?a.default.createElement("button",{type:"button",className:(0,n.tremorTwMerge)("absolute inset-y-0 right-0 flex items-center mr-8"),onClick:e=>{e.preventDefault(),M(""),null==f||f("")}},a.default.createElement(l.default,{className:(0,n.tremorTwMerge)(u("clearIcon"),"flex-none h-4 w-4","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle")})):null,a.default.createElement(d.Transition,{enter:"transition ease duration-100 transform",enterFrom:"opacity-0 -translate-y-4",enterTo:"opacity-100 translate-y-0",leave:"transition ease duration-100 transform",leaveFrom:"opacity-100 translate-y-0",leaveTo:"opacity-0 -translate-y-4"},a.default.createElement(s.ListboxOptions,{anchor:"bottom start",className:(0,n.tremorTwMerge)("z-10 w-[var(--button-width)] divide-y overflow-y-auto outline-none rounded-tremor-default max-h-[228px] border [--anchor-gap:4px]","bg-tremor-background border-tremor-border divide-tremor-border shadow-tremor-dropdown","dark:bg-dark-tremor-background dark:border-dark-tremor-border dark:divide-dark-tremor-border dark:shadow-dark-tremor-dropdown")},w)))})),C&&k?a.default.createElement("p",{className:(0,n.tremorTwMerge)("errorMessage","text-sm text-rose-500 mt-1")},k):null)});m.displayName="Select",e.s(["Select",0,m],206929)},560025,e=>{"use strict";e.i(247167);var t=e.i(271645),r=e.i(343794),a=e.i(931067),l=e.i(392221),n=e.i(703923),o=e.i(211577),i=e.i(209428),s=e.i(410160),d=e.i(914949),c=e.i(529681),u=e.i(611935),m=e.i(361275),g=e.i(174428),f=function(e,t){if(!e)return null;var r={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:r.top,bottom:r.bottom,height:r.height}:{left:r.left,right:r.right,width:r.width,top:0,bottom:0,height:0}},h=function(e){return void 0!==e?"".concat(e,"px"):void 0};function p(e){var a=e.prefixCls,n=e.containerRef,o=e.value,s=e.getValueIndex,d=e.motionName,c=e.onMotionStart,p=e.onMotionEnd,b=e.direction,x=e.vertical,v=void 0!==x&&x,w=t.useRef(null),y=t.useState(o),C=(0,l.default)(y,2),k=C[0],N=C[1],j=function(e){var t,r=s(e),l=null==(t=n.current)?void 0:t.querySelectorAll(".".concat(a,"-item"))[r];return(null==l?void 0:l.offsetParent)&&l},$=t.useState(null),S=(0,l.default)($,2),E=S[0],T=S[1],M=t.useState(null),R=(0,l.default)(M,2),O=R[0],I=R[1];(0,g.default)(function(){if(k!==o){var e=j(k),t=j(o),r=f(e,v),a=f(t,v);N(o),T(r),I(a),e&&t?c():p()}},[o]);var A=t.useMemo(function(){if(v){var e;return h(null!=(e=null==E?void 0:E.top)?e:0)}return"rtl"===b?h(-(null==E?void 0:E.right)):h(null==E?void 0:E.left)},[v,b,E]),L=t.useMemo(function(){if(v){var e;return h(null!=(e=null==O?void 0:O.top)?e:0)}return"rtl"===b?h(-(null==O?void 0:O.right)):h(null==O?void 0:O.left)},[v,b,O]);return E&&O?t.createElement(m.default,{visible:!0,motionName:d,motionAppear:!0,onAppearStart:function(){return v?{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 v?{transform:"translateY(var(--thumb-active-top))",height:"var(--thumb-active-height)"}:{transform:"translateX(var(--thumb-active-left))",width:"var(--thumb-active-width)"}},onVisibleChanged:function(){T(null),I(null),p()}},function(e,l){var n=e.className,o=e.style,s=(0,i.default)((0,i.default)({},o),{},{"--thumb-start-left":A,"--thumb-start-width":h(null==E?void 0:E.width),"--thumb-active-left":L,"--thumb-active-width":h(null==O?void 0:O.width),"--thumb-start-top":A,"--thumb-start-height":h(null==E?void 0:E.height),"--thumb-active-top":L,"--thumb-active-height":h(null==O?void 0:O.height)}),d={ref:(0,u.composeRef)(w,l),style:s,className:(0,r.default)("".concat(a,"-thumb"),n)};return t.createElement("div",d)}):null}var b=["prefixCls","direction","vertical","options","disabled","defaultValue","value","name","onChange","className","motionName"],x=function(e){var a=e.prefixCls,l=e.className,n=e.disabled,i=e.checked,s=e.label,d=e.title,c=e.value,u=e.name,m=e.onChange,g=e.onFocus,f=e.onBlur,h=e.onKeyDown,p=e.onKeyUp,b=e.onMouseDown;return t.createElement("label",{className:(0,r.default)(l,(0,o.default)({},"".concat(a,"-item-disabled"),n)),onMouseDown:b},t.createElement("input",{name:u,className:"".concat(a,"-item-input"),type:"radio",disabled:n,checked:i,onChange:function(e){n||m(e,c)},onFocus:g,onBlur:f,onKeyDown:h,onKeyUp:p}),t.createElement("div",{className:"".concat(a,"-item-label"),title:d},s))},v=t.forwardRef(function(e,m){var g,f=e.prefixCls,h=void 0===f?"rc-segmented":f,v=e.direction,w=e.vertical,y=e.options,C=void 0===y?[]:y,k=e.disabled,N=e.defaultValue,j=e.value,$=e.name,S=e.onChange,E=e.className,T=e.motionName,M=(0,n.default)(e,b),R=t.useRef(null),O=t.useMemo(function(){return(0,u.composeRef)(R,m)},[R,m]),I=t.useMemo(function(){return C.map(function(e){if("object"===(0,s.default)(e)&&null!==e){var t=function(e){if(void 0!==e.title)return e.title;if("object"!==(0,s.default)(e.label)){var t;return null==(t=e.label)?void 0:t.toString()}}(e);return(0,i.default)((0,i.default)({},e),{},{title:t})}return{label:null==e?void 0:e.toString(),title:null==e?void 0:e.toString(),value:e}})},[C]),A=(0,d.default)(null==(g=I[0])?void 0:g.value,{value:j,defaultValue:N}),L=(0,l.default)(A,2),P=L[0],D=L[1],H=t.useState(!1),B=(0,l.default)(H,2),_=B[0],F=B[1],z=function(e,t){D(t),null==S||S(t)},W=(0,c.default)(M,["children"]),q=t.useState(!1),V=(0,l.default)(q,2),K=V[0],X=V[1],U=t.useState(!1),G=(0,l.default)(U,2),Y=G[0],Z=G[1],J=function(){Z(!0)},Q=function(){Z(!1)},ee=function(){X(!1)},et=function(e){"Tab"===e.key&&X(!0)},er=function(e){var t=I.findIndex(function(e){return e.value===P}),r=I.length,a=I[(t+e+r)%r];a&&(D(a.value),null==S||S(a.value))},ea=function(e){switch(e.key){case"ArrowLeft":case"ArrowUp":er(-1);break;case"ArrowRight":case"ArrowDown":er(1)}};return t.createElement("div",(0,a.default)({role:"radiogroup","aria-label":"segmented control",tabIndex:k?void 0:0,"aria-orientation":w?"vertical":"horizontal"},W,{className:(0,r.default)(h,(0,o.default)((0,o.default)((0,o.default)({},"".concat(h,"-rtl"),"rtl"===v),"".concat(h,"-disabled"),k),"".concat(h,"-vertical"),w),void 0===E?"":E),ref:O}),t.createElement("div",{className:"".concat(h,"-group")},t.createElement(p,{vertical:w,prefixCls:h,value:P,containerRef:R,motionName:"".concat(h,"-").concat(void 0===T?"thumb-motion":T),direction:v,getValueIndex:function(e){return I.findIndex(function(t){return t.value===e})},onMotionStart:function(){F(!0)},onMotionEnd:function(){F(!1)}}),I.map(function(e){return t.createElement(x,(0,a.default)({},e,{name:$,key:e.value,prefixCls:h,className:(0,r.default)(e.className,"".concat(h,"-item"),(0,o.default)((0,o.default)({},"".concat(h,"-item-selected"),e.value===P&&!_),"".concat(h,"-item-focused"),Y&&K&&e.value===P)),checked:e.value===P,onChange:z,onFocus:J,onBlur:Q,onKeyDown:ea,onKeyUp:et,onMouseDown:ee,disabled:!!k||!!e.disabled}))})))}),w=e.i(981444),y=e.i(242064),C=e.i(517455);e.i(296059);var k=e.i(915654),N=e.i(183293),j=e.i(246422),$=e.i(838378);function S(e,t){return{[`${e}, ${e}:hover, ${e}:focus`]:{color:t.colorTextDisabled,cursor:"not-allowed"}}}function E(e){return{background:e.itemSelectedBg,boxShadow:e.boxShadowTertiary}}let T=Object.assign({overflow:"hidden"},N.textEllipsis),M=(0,j.genStyleHooks)("Segmented",e=>{let{lineWidth:t,calc:r}=e;return(e=>{let{componentCls:t}=e,r=e.calc(e.controlHeight).sub(e.calc(e.trackPadding).mul(2)).equal(),a=e.calc(e.controlHeightLG).sub(e.calc(e.trackPadding).mul(2)).equal(),l=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,N.resetComponent)(e)),{display:"inline-block",padding:e.trackPadding,color:e.itemColor,background:e.trackBg,borderRadius:e.borderRadius,transition:`all ${e.motionDurationMid}`}),(0,N.genFocusStyle)(e)),{[`${t}-group`]:{position:"relative",display:"flex",alignItems:"stretch",justifyItems:"flex-start",flexDirection:"row",width:"100%"},[`&${t}-rtl`]:{direction:"rtl"},[`&${t}-vertical`]:{[`${t}-group`]:{flexDirection:"column"},[`${t}-thumb`]:{width:"100%",height:0,padding:`0 ${(0,k.unit)(e.paddingXXS)}`}},[`&${t}-block`]:{display:"flex"},[`&${t}-block ${t}-item`]:{flex:1,minWidth:0},[`${t}-item`]:{position:"relative",textAlign:"center",cursor:"pointer",transition:`color ${e.motionDurationMid}`,borderRadius:e.borderRadiusSM,transform:"translateZ(0)","&-selected":Object.assign(Object.assign({},E(e)),{color:e.itemSelectedColor}),"&-focused":(0,N.genFocusOutline)(e),"&::after":{content:'""',position:"absolute",zIndex:-1,width:"100%",height:"100%",top:0,insetInlineStart:0,borderRadius:"inherit",opacity:0,transition:`opacity ${e.motionDurationMid}, background-color ${e.motionDurationMid}`,pointerEvents:"none"},[`&:not(${t}-item-selected):not(${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:r,lineHeight:(0,k.unit)(r),padding:`0 ${(0,k.unit)(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"}},[`${t}-thumb`]:Object.assign(Object.assign({},E(e)),{position:"absolute",insetBlockStart:0,insetInlineStart:0,width:0,height:"100%",padding:`${(0,k.unit)(e.paddingXXS)} 0`,borderRadius:e.borderRadiusSM,[`& ~ ${t}-item:not(${t}-item-selected):not(${t}-item-disabled)::after`]:{backgroundColor:"transparent"}}),[`&${t}-lg`]:{borderRadius:e.borderRadiusLG,[`${t}-item-label`]:{minHeight:a,lineHeight:(0,k.unit)(a),padding:`0 ${(0,k.unit)(e.segmentedPaddingHorizontal)}`,fontSize:e.fontSizeLG},[`${t}-item, ${t}-thumb`]:{borderRadius:e.borderRadius}},[`&${t}-sm`]:{borderRadius:e.borderRadiusSM,[`${t}-item-label`]:{minHeight:l,lineHeight:(0,k.unit)(l),padding:`0 ${(0,k.unit)(e.segmentedPaddingHorizontalSM)}`},[`${t}-item, ${t}-thumb`]:{borderRadius:e.borderRadiusXS}}}),S(`&-disabled ${t}-item`,e)),S(`${t}-item-disabled`,e)),{[`${t}-thumb-motion-appear-active`]:{transition:`transform ${e.motionDurationSlow} ${e.motionEaseInOut}, width ${e.motionDurationSlow} ${e.motionEaseInOut}`,willChange:"transform, width"},[`&${t}-shape-round`]:{borderRadius:9999,[`${t}-item, ${t}-thumb`]:{borderRadius:9999}}})}})((0,$.mergeToken)(e,{segmentedPaddingHorizontal:r(e.controlPaddingHorizontal).sub(t).equal(),segmentedPaddingHorizontalSM:r(e.controlPaddingHorizontalSM).sub(t).equal()}))},e=>{let{colorTextLabel:t,colorText:r,colorFillSecondary:a,colorBgElevated:l,colorFill:n,lineWidthBold:o,colorBgLayout:i}=e;return{trackPadding:o,trackBg:i,itemColor:t,itemHoverColor:r,itemHoverBg:a,itemSelectedBg:l,itemActiveBg:n,itemSelectedColor:r}});var R=function(e,t){var r={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&0>t.indexOf(a)&&(r[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var l=0,a=Object.getOwnPropertySymbols(e);lt.indexOf(a[l])&&Object.prototype.propertyIsEnumerable.call(e,a[l])&&(r[a[l]]=e[a[l]]);return r};let O=t.forwardRef((e,a)=>{let l=(0,w.default)(),{prefixCls:n,className:o,rootClassName:i,block:s,options:d=[],size:c="middle",style:u,vertical:m,shape:g="default",name:f=l}=e,h=R(e,["prefixCls","className","rootClassName","block","options","size","style","vertical","shape","name"]),{getPrefixCls:p,direction:b,className:x,style:k}=(0,y.useComponentConfig)("segmented"),N=p("segmented",n),[j,$,S]=M(N),E=(0,C.default)(c),T=t.useMemo(()=>d.map(e=>{if("object"==typeof e&&(null==e?void 0:e.icon)){let{icon:r,label:a}=e;return Object.assign(Object.assign({},R(e,["icon","label"])),{label:t.createElement(t.Fragment,null,t.createElement("span",{className:`${N}-item-icon`},r),a&&t.createElement("span",null,a))})}return e}),[d,N]),O=(0,r.default)(o,i,x,{[`${N}-block`]:s,[`${N}-sm`]:"small"===E,[`${N}-lg`]:"large"===E,[`${N}-vertical`]:m,[`${N}-shape-${g}`]:"round"===g},$,S),I=Object.assign(Object.assign({},k),u);return j(t.createElement(v,Object.assign({},h,{name:f,className:O,style:I,options:T,ref:a,prefixCls:N,direction:b,vertical:m})))});e.s(["Segmented",0,O],560025)},149121,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(152990),l=e.i(682830),n=e.i(784774);e.s(["DataTable",0,function({data:e=[],columns:o,getRowId:i,onRowClick:s,renderSubComponent:d,getRowCanExpand:c,isLoading:u=!1,loadingMessage:m="Loading...",noDataMessage:g="No results",enableSorting:f=!1}){let h=!!d&&!!c,p=o.some(e=>void 0!==e.size),[b,x]=(0,r.useState)([]),v=(0,a.useReactTable)({data:e,columns:o,...f&&{state:{sorting:b},onSortingChange:x,enableSortingRemoval:!1},...h&&{getRowCanExpand:c},...i&&{getRowId:i},getCoreRowModel:(0,l.getCoreRowModel)(),...f&&{getSortedRowModel:(0,l.getSortedRowModel)()},...h&&{getExpandedRowModel:(0,l.getExpandedRowModel)()}}),w=p?{minWidth:v.getCenterTotalSize()}:{minWidth:"400px"};return(0,t.jsx)("div",{className:"rounded-lg custom-border overflow-hidden w-full max-w-full box-border",children:(0,t.jsxs)(n.Table,{className:p?"table-fixed":"table-fixed w-full box-border",style:w,children:[(0,t.jsx)(n.TableHeader,{children:v.getHeaderGroups().map(e=>(0,t.jsx)(n.TableRow,{className:"bg-muted/50 hover:bg-muted/50",children:e.headers.map(e=>{let r=f&&e.column.getCanSort(),l=e.column.getIsSorted(),o=e.column.columnDef.meta?.numeric;return(0,t.jsx)(n.TableHead,{className:`py-1 h-8 text-xs font-medium text-muted-foreground first:pl-4 last:pr-4 ${r?"cursor-pointer select-none hover:bg-muted":""}`,style:p?{width:e.getSize()}:void 0,onClick:r?e.column.getToggleSortingHandler():void 0,children:e.isPlaceholder?null:(0,t.jsxs)("div",{className:`flex items-center gap-1 ${o?"justify-end":""}`,children:[(0,a.flexRender)(e.column.columnDef.header,e.getContext()),r&&(0,t.jsx)("span",{className:"text-muted-foreground",children:"asc"===l?"↑":"desc"===l?"↓":"⇅"})]})},e.id)})},e.id))}),(0,t.jsx)(n.TableBody,{children:u?(0,t.jsx)(n.TableRow,{className:"hover:bg-transparent",children:(0,t.jsx)(n.TableCell,{colSpan:o.length,className:"h-8 text-center",children:(0,t.jsx)("div",{className:"text-center text-muted-foreground",children:(0,t.jsx)("p",{children:m})})})}):v.getRowModel().rows.length>0?v.getRowModel().rows.map(e=>(0,t.jsxs)(r.Fragment,{children:[(0,t.jsx)(n.TableRow,{className:`h-8 ${s?"cursor-pointer":""}`,onClick:()=>s?.(e.original),children:e.getVisibleCells().map(e=>(0,t.jsx)(n.TableCell,{className:`py-0.5 max-h-8 overflow-hidden text-ellipsis whitespace-nowrap first:pl-4 last:pr-4 ${e.column.columnDef.meta?.numeric?"text-right tabular-nums":""}`,style:p?{width:e.column.getSize()}:void 0,children:(0,a.flexRender)(e.column.columnDef.cell,e.getContext())},e.id))}),h&&e.getIsExpanded()&&d&&(0,t.jsx)(n.TableRow,{className:"hover:bg-transparent",children:(0,t.jsx)(n.TableCell,{colSpan:e.getVisibleCells().length,className:"p-0",children:(0,t.jsx)("div",{className:"w-full max-w-full overflow-hidden box-border",children:d({row:e})})})})]},e.id)):(0,t.jsx)(n.TableRow,{className:"hover:bg-transparent",children:(0,t.jsx)(n.TableCell,{colSpan:o.length,className:"h-24 text-center align-middle",children:(0,t.jsx)("p",{className:"text-sm text-muted-foreground",children:g})})})})]})})}])},37091,e=>{"use strict";var t=e.i(290571),r=e.i(95779),a=e.i(444755),l=e.i(673706),n=e.i(271645);let o=n.default.forwardRef((e,o)=>{let{color:i,children:s,className:d}=e,c=(0,t.__rest)(e,["color","children","className"]);return n.default.createElement("p",Object.assign({ref:o,className:(0,a.tremorTwMerge)(i?(0,l.getColorClassNames)(i,r.colorPalette.lightText).textColor:"text-tremor-content-emphasis dark:text-dark-tremor-content-emphasis",d)},c),s)});o.displayName="Subtitle",e.s(["Subtitle",0,o],37091)},617802,1023,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(602869),l=e.i(500330),n=e.i(135214);e.s(["default",0,({userSpend:e,userMaxBudget:o,selectedTeam:i})=>{let{accessToken:s,userRole:d,userId:c}=(0,n.default)(),[u,m]=(0,r.useState)(null!==e?e:0),[g,f]=(0,r.useState)(i?Number((0,l.formatNumberWithCommas)(i.max_budget,4)):null);(0,r.useEffect)(()=>{if(i)if("Default Team"===i.team_alias)f(o);else{let e=!1;if(i.team_memberships)for(let t of i.team_memberships)t.user_id===c&&"max_budget"in t.litellm_budget_table&&null!==t.litellm_budget_table.max_budget&&(f(t.litellm_budget_table.max_budget),e=!0);e||f(i.max_budget)}else f(o)},[i,o]);let[h,p]=(0,r.useState)([]);(0,r.useEffect)(()=>{let e=async()=>{if(!s||!c||!d)return};(async()=>{try{if(null===c||null===d)return;if(null!==s){let e=(await (0,a.modelAvailableCall)(s,c,d)).data.map(e=>e.id);p(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[d,s,c]),(0,r.useEffect)(()=>{null!==e&&m(e)},[e]);let b=[];i&&i.models&&(b=i.models),b&&b.includes("all-proxy-models")?b=h:b&&b.includes("all-team-models")?b=i.models:b&&0===b.length&&(b=h);let x=null!==g?`$${(0,l.formatNumberWithCommas)(Number(g),4)} limit`:"No limit",v=void 0!==u?(0,l.formatNumberWithCommas)(u,4):null;return(0,t.jsx)("div",{className:"flex items-center",children:(0,t.jsxs)("div",{className:"flex justify-between gap-x-6",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-tremor-default text-tremor-content dark:text-dark-tremor-content",children:"Total Spend"}),(0,t.jsxs)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:["$",v]})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-tremor-default text-tremor-content dark:text-dark-tremor-content",children:"Max Budget"}),(0,t.jsx)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:x})]})]})})}],617802),e.i(32117);var o=e.i(343053);e.i(622826);var i=e.i(399536),s=e.i(964471),d=e.i(871943),c=e.i(360820),u=e.i(560025),m=e.i(592968),g=e.i(20147),f=e.i(149121);e.s(["default",0,({topKeys:e,teams:h,showTags:p=!1,topKeysLimit:b,setTopKeysLimit:x})=>{let{accessToken:v,userRole:w,userId:y,premiumUser:C}=(0,n.default)(),[k,N]=(0,r.useState)(!1),[j,$]=(0,r.useState)(null),[S,E]=(0,r.useState)(void 0),[T,M]=(0,r.useState)("table"),[R,O]=(0,r.useState)(new Set),I=async e=>{if(v)try{let t=await (0,a.keyInfoV1Call)(v,e.api_key),r=(e=>{let{key:t,info:r}=e;return{token:t,...r}})(t);E(r),$(e.api_key),N(!0)}catch(e){console.error("Error fetching key info:",e)}},A=()=>{N(!1),$(null),E(void 0)};r.default.useEffect(()=>{let e=e=>{"Escape"===e.key&&k&&A()};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[k]);let L=[{header:"Key ID",accessorKey:"api_key",cell:e=>(0,t.jsx)(i.IdCell,{value:e.getValue(),onClick:()=>I(e.row.original)})},{header:"Key Alias",accessorKey:"key_alias",cell:e=>e.getValue()||"-"}],P={header:"Spend (USD)",accessorKey:"spend",meta:{numeric:!0},cell:e=>(0,t.jsx)(s.MoneyCell,{value:e.getValue(),decimals:2})},D=p?[...L,{header:"Tags",accessorKey:"tags",cell:e=>{let r=e.getValue(),a=e.row.original.api_key,n=R.has(a);if(!r||0===r.length)return"-";let o=r.sort((e,t)=>t.usage-e.usage),i=n?o:o.slice(0,2),s=r.length>2;return(0,t.jsx)("div",{className:"overflow-hidden",children:(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-1",children:[i.map((e,r)=>(0,t.jsx)(m.Tooltip,{title:(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"text-gray-300",children:"Tag Name:"})," ",e.tag]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"text-gray-300",children:"Spend:"})," ",e.usage>0&&e.usage<.01?"<$0.01":`$${(0,l.formatNumberWithCommas)(e.usage,2)}`]})]}),children:(0,t.jsxs)("span",{className:"px-2 py-1 bg-gray-100 rounded-full text-xs",children:[e.tag.slice(0,7),"..."]})},r)),s&&(0,t.jsx)("button",{onClick:()=>{O(e=>{let t=new Set(e);return t.has(a)?t.delete(a):t.add(a),t})},className:"ml-1 p-1 hover:bg-gray-200 rounded-full transition-colors",title:n?"Show fewer tags":"Show all tags",children:n?(0,t.jsx)(c.ChevronUpIcon,{className:"h-3 w-3 text-gray-500"}):(0,t.jsx)(d.ChevronDownIcon,{className:"h-3 w-3 text-gray-500"})})]})})}},P]:[...L,P],H=e.map(e=>({...e,display_key_alias:e.key_alias&&e.key_alias.length>10?`${e.key_alias.slice(0,10)}...`:e.key_alias||"-"}));return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("div",{className:"mb-4 flex justify-between items-center",children:[(0,t.jsx)(u.Segmented,{options:[{label:"5",value:5},{label:"10",value:10},{label:"25",value:25},{label:"50",value:50}],value:b,onChange:e=>x(e)}),(0,t.jsxs)("div",{className:"flex space-x-2",children:[(0,t.jsx)("button",{onClick:()=>M("table"),className:`px-3 py-1 text-sm rounded-md ${"table"===T?"bg-blue-100 text-blue-700":"bg-gray-100 text-gray-700"}`,children:"Table View"}),(0,t.jsx)("button",{onClick:()=>M("chart"),className:`px-3 py-1 text-sm rounded-md ${"chart"===T?"bg-blue-100 text-blue-700":"bg-gray-100 text-gray-700"}`,children:"Chart View"})]})]}),"chart"===T?(0,t.jsx)("div",{className:"relative max-h-[600px] overflow-y-auto",children:(0,t.jsx)(o.BarChart,{className:"mt-4 cursor-pointer hover:opacity-90",style:{height:52*Math.min(H.length,b)},data:H,index:"display_key_alias",categories:["spend"],colors:["cyan"],yAxisWidth:120,tickGap:5,layout:"vertical",showLegend:!1,valueFormatter:e=>`$${(0,l.formatNumberWithCommas)(e,2)}`,onValueChange:e=>I(e),showTooltip:!0,customTooltip:e=>{let r=e.payload?.[0]?.payload;return(0,t.jsx)("div",{className:"relative z-50 p-3 bg-black/90 shadow-lg rounded-lg text-white max-w-xs",children:(0,t.jsxs)("div",{className:"space-y-1.5",children:[(0,t.jsxs)("div",{className:"text-sm",children:[(0,t.jsx)("span",{className:"text-gray-300",children:"Key Alias: "}),(0,t.jsx)("span",{className:"font-mono text-gray-100 break-all",children:r?.key_alias})]}),(0,t.jsxs)("div",{className:"text-sm",children:[(0,t.jsx)("span",{className:"text-gray-300",children:"Key ID: "}),(0,t.jsx)("span",{className:"font-mono text-gray-100 break-all",children:r?.api_key})]}),(0,t.jsxs)("div",{className:"text-sm",children:[(0,t.jsx)("span",{className:"text-gray-300",children:"Spend: "}),(0,t.jsxs)("span",{className:"text-white font-medium",children:["$",(0,l.formatNumberWithCommas)(r?.spend,2)]})]})]})})}})}):(0,t.jsx)("div",{className:"border rounded-lg overflow-hidden max-h-[600px] overflow-y-auto",children:(0,t.jsx)(f.DataTable,{columns:D,data:e,isLoading:!1})}),k&&j&&S&&(0,t.jsx)("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",onClick:e=>{e.target===e.currentTarget&&A()},children:(0,t.jsxs)("div",{className:"bg-white rounded-lg shadow-xl relative w-11/12 max-w-6xl max-h-[90vh] overflow-y-auto min-h-[750px]",children:[(0,t.jsx)("button",{onClick:A,className:"absolute top-4 right-4 text-gray-500 hover:text-gray-700 focus:outline-hidden","aria-label":"Close",children:(0,t.jsx)("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M6 18L18 6M6 6l12 12"})})}),(0,t.jsx)("div",{className:"p-6 h-full",children:(0,t.jsx)(g.default,{keyId:j,onClose:A,keyData:S,teams:h})})]})})]})}],1023)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0.3q2b74j~ty5.js b/litellm/proxy/_experimental/out/_next/static/chunks/0.3q2b74j~ty5.js deleted file mode 100644 index a1d9411fad5..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/0.3q2b74j~ty5.js +++ /dev/null @@ -1 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,981339,e=>{"use strict";var t=e.i(185793);e.s(["Skeleton",()=>t.default])},540626,e=>{"use strict";let t;var r,n=e.i(271645);let o=(0,n.createContext)(null);function i(e,t){if(Object.is(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(let[r,n]of e)if(!t.has(r)||!Object.is(n,t.get(r)))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;for(let r of e)if(!t.has(r))return!1;return!0}if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();let r=s(e);if(r.length!==s(t).length)return!1;for(let n=0;ne,r){let o=r?.compare??l,i=(0,n.useCallback)(t=>{let{unsubscribe:r}=e.subscribe(t);return r},[e]),s=(0,n.useCallback)(()=>e.get(),[e]);return(0,a.useSyncExternalStoreWithSelector)(i,s,s,t,o)}function c(e,...t){return"function"==typeof e?e(...t):e}var u=class{#e=!0;#t;#r;#n;#o;#i;#s;#a;#l=0;#d=5;#c=!1;#u=!1;#g=null;#h=()=>{this.debugLog("Connected to event bus"),this.#i=!0,this.#c=!1,this.debugLog("Emitting queued events",this.#o),this.#o.forEach(e=>this.emitEventToBus(e)),this.#o=[],this.stopConnectLoop(),this.#r().removeEventListener("tanstack-connect-success",this.#h)};#v=()=>{if(this.#l{this.#c||(this.#c=!0,this.#r().addEventListener("tanstack-connect-success",this.#h),this.#v())};constructor({pluginId:e,debug:t=!1,enabled:r=!0,reconnectEveryMs:n=300}){this.#t=e,this.#e=r,this.#r=this.getGlobalTarget,this.#n=t,this.debugLog(" Initializing event subscription for plugin",this.#t),this.#o=[],this.#i=!1,this.#u=!1,this.#s=null,this.#a=n}startConnectLoop(){null!==this.#s||this.#i||(this.debugLog(`Starting connect loop (every ${this.#a}ms)`),this.#s=setInterval(this.#v,this.#a))}stopConnectLoop(){this.#c=!1,null!==this.#s&&(clearInterval(this.#s),this.#s=null,this.#o=[],this.debugLog("Stopped connect loop"))}debugLog(...e){this.#n&&console.log(`🌴 [tanstack-devtools:${this.#t}-plugin]`,...e)}getGlobalTarget(){if("u">typeof globalThis&&globalThis.__TANSTACK_EVENT_TARGET__)return this.debugLog("Using global event target"),globalThis.__TANSTACK_EVENT_TARGET__;if("u">typeof window&&void 0!==window.addEventListener)return this.debugLog("Using window as event target"),window;let e="u">typeof EventTarget?new EventTarget:void 0;return void 0===e||void 0===e.addEventListener?(this.debugLog("No event mechanism available, running in non-web environment"),{addEventListener:()=>{},removeEventListener:()=>{},dispatchEvent:()=>!1}):(this.debugLog("Using new EventTarget as fallback"),e)}getPluginId(){return this.#t}dispatchCustomEventShim(e,t){try{let r=new Event(e,{detail:t});this.#r().dispatchEvent(r)}catch(e){this.debugLog("Failed to dispatch shim event")}}dispatchCustomEvent(e,t){try{this.#r().dispatchEvent(new CustomEvent(e,{detail:t}))}catch(r){this.dispatchCustomEventShim(e,t)}}emitEventToBus(e){this.debugLog("Emitting event to client bus",e),this.dispatchCustomEvent("tanstack-dispatch-event",e)}createEventPayload(e,t){return{type:`${this.#t}:${e}`,payload:t,pluginId:this.#t}}emit(e,t){if(!this.#e)return void this.debugLog("Event bus client is disabled, not emitting event",e,t);if(this.#g&&(this.debugLog("Emitting event to internal event target",e,t),this.#g.dispatchEvent(new CustomEvent(`${this.#t}:${e}`,{detail:this.createEventPayload(e,t)}))),this.#u)return void this.debugLog("Previously failed to connect, not emitting to bus");if(!this.#i){this.debugLog("Bus not available, will be pushed as soon as connected"),this.#o.push(this.createEventPayload(e,t)),"u">typeof CustomEvent&&!this.#c&&(this.#b(),this.startConnectLoop());return}return this.emitEventToBus(this.createEventPayload(e,t))}on(e,t,r){let n=r?.withEventTarget??!1,o=`${this.#t}:${e}`;if(n&&(this.#g||(this.#g=new EventTarget),this.#g.addEventListener(o,e=>{t(e.detail)})),!this.#e)return this.debugLog("Event bus client is disabled, not registering event",o),()=>{};let i=e=>{this.debugLog("Received event from bus",e.detail),t(e.detail)};return this.#r().addEventListener(o,i),this.debugLog("Registered event to bus",o),()=>{n&&this.#g?.removeEventListener(o,i),this.#r().removeEventListener(o,i)}}onAll(e){if(!this.#e)return this.debugLog("Event bus client is disabled, not registering event"),()=>{};let t=t=>{e(t.detail)};return this.#r().addEventListener("tanstack-devtools-global",t),()=>this.#r().removeEventListener("tanstack-devtools-global",t)}onAllPluginEvents(e){if(!this.#e)return this.debugLog("Event bus client is disabled, not registering event"),()=>{};let t=t=>{let r=t.detail;this.#t&&r.pluginId!==this.#t||e(r)};return this.#r().addEventListener("tanstack-devtools-global",t),()=>this.#r().removeEventListener("tanstack-devtools-global",t)}};let g=new Map;function h(e){if(void 0!==e)try{return JSON.parse(JSON.stringify(e))}catch{return null}}let v=new class extends u{constructor(e){super({pluginId:"pacer",debug:e?.debug,reconnectEveryMs:1e3})}},b=((r={})[r.None=0]="None",r[r.Mutable=1]="Mutable",r[r.Watching=2]="Watching",r[r.RecursedCheck=4]="RecursedCheck",r[r.Recursed=8]="Recursed",r[r.Dirty=16]="Dirty",r[r.Pending=32]="Pending",r);function m(e,t,r){let n="object"==typeof e,o=n?e:void 0;return{next:(n?e.next:e)?.bind(o),error:(n?e.error:t)?.bind(o),complete:(n?e.complete:r)?.bind(o)}}let f=[],p=0,{link:C,unlink:x,propagate:T,checkDirty:E,shallowPropagate:k}=function({update:e,notify:t,unwatched:r}){return{link:function(e,t,r){let n=t.depsTail;if(void 0!==n&&n.dep===e)return;let o=void 0!==n?n.nextDep:t.deps;if(void 0!==o&&o.dep===e){o.version=r,t.depsTail=o;return}let i=e.subsTail;if(void 0!==i&&i.version===r&&i.sub===t)return;let s=t.depsTail=e.subsTail={version:r,dep:e,sub:t,prevDep:n,nextDep:o,prevSub:i,nextSub:void 0};void 0!==o&&(o.prevDep=s),void 0!==n?n.nextDep=s:t.deps=s,void 0!==i?i.nextSub=s:e.subs=s},unlink:function(e,t=e.sub){let n=e.dep,o=e.prevDep,i=e.nextDep,s=e.nextSub,a=e.prevSub;return void 0!==i?i.prevDep=o:t.depsTail=o,void 0!==o?o.nextDep=i:t.deps=i,void 0!==s?s.prevSub=a:n.subsTail=a,void 0!==a?a.nextSub=s:void 0===(n.subs=s)&&r(n),i},propagate:function(e){let r,n=e.nextSub;e:for(;;){let o=e.sub,i=o.flags;if(i&(b.RecursedCheck|b.Recursed|b.Dirty|b.Pending)?i&(b.RecursedCheck|b.Recursed)?i&b.RecursedCheck?!(i&(b.Dirty|b.Pending))&&function(e,t){let r=t.depsTail;for(;void 0!==r;){if(r===e)return!0;r=r.prevDep}return!1}(e,o)?(o.flags=i|(b.Recursed|b.Pending),i&=b.Mutable):i=b.None:o.flags=i&~b.Recursed|b.Pending:i=b.None:o.flags=i|b.Pending,i&b.Watching&&t(o),i&b.Mutable){let t=o.subs;if(void 0!==t){let o=(e=t).nextSub;void 0!==o&&(r={value:n,prev:r},n=o);continue}}if(void 0!==(e=n)){n=e.nextSub;continue}for(;void 0!==r;)if(e=r.value,r=r.prev,void 0!==e){n=e.nextSub;continue e}break}},checkDirty:function(t,r){let o,i=0,s=!1;e:for(;;){let a=t.dep,l=a.flags;if(r.flags&b.Dirty)s=!0;else if((l&(b.Mutable|b.Dirty))==(b.Mutable|b.Dirty)){if(e(a)){let e=a.subs;void 0!==e.nextSub&&n(e),s=!0}}else if((l&(b.Mutable|b.Pending))==(b.Mutable|b.Pending)){(void 0!==t.nextSub||void 0!==t.prevSub)&&(o={value:t,prev:o}),t=a.deps,r=a,++i;continue}if(!s){let e=t.nextDep;if(void 0!==e){t=e;continue}}for(;i--;){let i=r.subs,a=void 0!==i.nextSub;if(a?(t=o.value,o=o.prev):t=i,s){if(e(r)){a&&n(i),r=t.sub;continue}s=!1}else r.flags&=~b.Pending;r=t.sub;let l=t.nextDep;if(void 0!==l){t=l;continue e}}return s}},shallowPropagate:n};function n(e){do{let r=e.sub,n=r.flags;(n&(b.Pending|b.Dirty))===b.Pending&&(r.flags=n|b.Dirty,(n&(b.Watching|b.RecursedCheck))===b.Watching&&t(r))}while(void 0!==(e=e.nextSub))}}({update:e=>e._update(),notify(e){f[w++]=e,e.flags&=~b.Watching},unwatched(e){void 0!==e.depsTail&&(e.depsTail=void 0,e.flags=b.Mutable|b.Dirty,S(e))}}),y=0,w=0;function S(e){let t=e.depsTail,r=void 0!==t?t.nextDep:e.deps;for(;void 0!==r;)r=x(r,e)}var P=class{constructor(e,r){this.atom=function(e){let r="function"==typeof e,n={_snapshot:r?void 0:e,subs:void 0,subsTail:void 0,deps:void 0,depsTail:void 0,flags:r?b.None:b.Mutable,get:()=>(void 0!==t&&C(n,t,p),n._snapshot),subscribe(e){var r;let o,i,s=m(e),a={current:!1},l=(r=()=>{n.get(),a.current?s.next?.(n._snapshot):a.current=!0},o=()=>{let e=t;t=i,++p,i.depsTail=void 0,i.flags=b.Watching|b.RecursedCheck;try{return r()}finally{t=e,i.flags&=~b.RecursedCheck,S(i)}},i={deps:void 0,depsTail:void 0,subs:void 0,subsTail:void 0,flags:b.Watching|b.RecursedCheck,notify(){let e=this.flags;e&b.Dirty||e&b.Pending&&E(this.deps,this)?o():this.flags=b.Watching},stop(){this.flags=b.None,this.depsTail=void 0,S(this)}},o(),i);return{unsubscribe:()=>{l.stop()}}},_update(o){let i=t,s=(void 0)??Object.is;if(r)t=n,++p,n.depsTail=void 0;else if(void 0===o)return!1;r&&(n.flags=b.Mutable|b.RecursedCheck);try{let t=n._snapshot,i="function"==typeof o?o(t):void 0===o&&r?e(t):o;if(void 0===t||!s(t,i))return n._snapshot=i,!0;return!1}finally{t=i,r&&(n.flags&=~b.RecursedCheck),S(n)}}};return r?(n.flags=b.Mutable|b.Dirty,n.get=function(){let e=n.flags;if(e&b.Dirty||e&b.Pending&&E(n.deps,n)){if(n._update()){let e=n.subs;void 0!==e&&k(e)}}else e&b.Pending&&(n.flags=e&~b.Pending);return void 0!==t&&C(n,t,p),n._snapshot}):n.set=function(e){if(n._update(e)){let e=n.subs;if(void 0!==e&&(T(e),k(e),1)){for(;y{this.options={...this.options,...e},this.#f()||this.cancel()},this.#p=e=>{this.store.setState(t=>{let r={...t,...e},{isPending:n}=r;return{...r,status:this.#f()?n?"pending":"idle":"disabled"}}),((e,t)=>{let r=t.key;if(r){var n,o;g.set(r,t),v.emit(e,{key:(n={...t,key:r}).key,store:{state:h("function"==typeof(o=n.store).get?o.get():o.state)},options:h(n.options)})}})("Debouncer",this)},this.#f=()=>!!c(this.options.enabled,this),this.#C=()=>c(this.options.wait,this),this.maybeExecute=(...e)=>{if(!this.#f())return;this.#p({maybeExecuteCount:this.store.state.maybeExecuteCount+1});let t=!1;this.options.leading&&this.store.state.canLeadingExecute&&(this.#p({canLeadingExecute:!1}),t=!0,this.#x(...e)),this.options.trailing&&this.#p({isPending:!0,lastArgs:e}),this.#m&&clearTimeout(this.#m),this.#m=setTimeout(()=>{this.#p({canLeadingExecute:!0}),this.options.trailing&&!t&&this.#x(...e)},this.#C())},this.#x=(...e)=>{this.#f()&&(this.fn(...e),this.#p({executionCount:this.store.state.executionCount+1,isPending:!1,lastArgs:void 0}),this.options.onExecute?.(e,this))},this.flush=()=>{this.store.state.isPending&&this.store.state.lastArgs&&(this.#T(),this.#x(...this.store.state.lastArgs))},this.#T=()=>{this.#m&&(clearTimeout(this.#m),this.#m=void 0)},this.cancel=()=>{this.#T(),this.#p({canLeadingExecute:!0,isPending:!1})},this.reset=()=>{this.#p(N())},this.key=t.key,this.options={...B,...t},this.#p(this.options.initialState??{}),this.key&&v.on("d-Debouncer",e=>{e.payload.key===this.key&&(this.#p(e.payload.store.state),this.setOptions(e.payload.options))})}#p;#f;#C;#x;#T};e.s(["useDebouncer",0,function(e,t,r=()=>({})){let s={...((0,n.useContext)(o)?.defaultOptions??{}).debouncer,...t},[a]=(0,n.useState)(()=>{let t=new L(e,s);return t.Subscribe=function(e){let r=d(t.store,e.selector,{compare:i});return"function"==typeof e.children?e.children(r):e.children},t});a.fn=e,a.setOptions(s),(0,n.useEffect)(()=>()=>{s.onUnmount?s.onUnmount(a):a.cancel()},[]);let l=d(a.store,r,{compare:i});return(0,n.useMemo)(()=>({...a,state:l}),[a,l])}],540626)},343488,e=>{"use strict";var t=e.i(540626),r=e.i(271645);e.s(["useDebouncedCallback",0,function(e,n){let o=(0,t.useDebouncer)(e,n).maybeExecute;return(0,r.useCallback)((...e)=>o(...e),[o])}])},653496,e=>{"use strict";var t=e.i(721369);e.s(["Tabs",()=>t.default])},629569,e=>{"use strict";var t=e.i(290571),r=e.i(95779),n=e.i(444755),o=e.i(673706),i=e.i(271645);let s=i.default.forwardRef((e,s)=>{let{color:a,children:l,className:d}=e,c=(0,t.__rest)(e,["color","children","className"]);return i.default.createElement("p",Object.assign({ref:s,className:(0,n.tremorTwMerge)("font-medium text-tremor-title",a?(0,o.getColorClassNames)(a,r.colorPalette.darkText).textColor:"text-tremor-content-strong dark:text-dark-tremor-content-strong",d)},c),l)});s.displayName="Title",e.s(["Title",0,s],629569)},95779,e=>{"use strict";var t=e.i(480731);let r=[t.BaseColors.Blue,t.BaseColors.Cyan,t.BaseColors.Sky,t.BaseColors.Indigo,t.BaseColors.Violet,t.BaseColors.Purple,t.BaseColors.Fuchsia,t.BaseColors.Slate,t.BaseColors.Gray,t.BaseColors.Zinc,t.BaseColors.Neutral,t.BaseColors.Stone,t.BaseColors.Red,t.BaseColors.Orange,t.BaseColors.Amber,t.BaseColors.Yellow,t.BaseColors.Lime,t.BaseColors.Green,t.BaseColors.Emerald,t.BaseColors.Teal,t.BaseColors.Pink,t.BaseColors.Rose];e.s(["colorPalette",0,{canvasBackground:50,lightBackground:100,background:500,darkBackground:600,darkestBackground:800,lightBorder:200,border:500,darkBorder:700,lightRing:200,ring:300,iconRing:500,lightText:400,text:500,iconText:600,darkText:700,darkestText:900,icon:500},"themeColorRange",0,r])},599724,936325,e=>{"use strict";var t=e.i(95779),r=e.i(444755),n=e.i(673706),o=e.i(271645);let i=o.default.forwardRef((e,i)=>{let{color:s,className:a,children:l}=e;return o.default.createElement("p",{ref:i,className:(0,r.tremorTwMerge)("text-tremor-default",s?(0,n.getColorClassNames)(s,t.colorPalette.text).textColor:(0,r.tremorTwMerge)("text-tremor-content","dark:text-dark-tremor-content"),a)},l)});i.displayName="Text",e.s(["default",0,i],936325),e.s(["Text",0,i],599724)},994388,e=>{"use strict";var t=e.i(290571),r=e.i(829087),n=e.i(271645);let o=["preEnter","entering","entered","preExit","exiting","exited","unmounted"],i=e=>({_s:e,status:o[e],isEnter:e<3,isMounted:6!==e,isResolved:2===e||e>4}),s=e=>e?6:5,a=(e,t,r,n,o)=>{clearTimeout(n.current);let s=i(e);t(s),r.current=s,o&&o({current:s})};var l=e.i(480731),d=e.i(444755),c=e.i(673706);let u=e=>{var r=(0,t.__rest)(e,[]);return n.default.createElement("svg",Object.assign({},r,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"}),n.default.createElement("path",{fill:"none",d:"M0 0h24v24H0z"}),n.default.createElement("path",{d:"M18.364 5.636L16.95 7.05A7 7 0 1 0 19 12h2a9 9 0 1 1-2.636-6.364z"}))};var g=e.i(95779);let h={xs:{height:"h-4",width:"w-4"},sm:{height:"h-5",width:"w-5"},md:{height:"h-5",width:"w-5"},lg:{height:"h-6",width:"w-6"},xl:{height:"h-6",width:"w-6"}},v=(e,t)=>{switch(e){case"primary":return{textColor:t?(0,c.getColorClassNames)("white").textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",hoverTextColor:t?(0,c.getColorClassNames)("white").textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",bgColor:t?(0,c.getColorClassNames)(t,g.colorPalette.background).bgColor:"bg-tremor-brand dark:bg-dark-tremor-brand",hoverBgColor:t?(0,c.getColorClassNames)(t,g.colorPalette.darkBackground).hoverBgColor:"hover:bg-tremor-brand-emphasis dark:hover:bg-dark-tremor-brand-emphasis",borderColor:t?(0,c.getColorClassNames)(t,g.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand",hoverBorderColor:t?(0,c.getColorClassNames)(t,g.colorPalette.darkBorder).hoverBorderColor:"hover:border-tremor-brand-emphasis dark:hover:border-dark-tremor-brand-emphasis"};case"secondary":return{textColor:t?(0,c.getColorClassNames)(t,g.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",hoverTextColor:t?(0,c.getColorClassNames)(t,g.colorPalette.text).textColor:"hover:text-tremor-brand-emphasis dark:hover:text-dark-tremor-brand-emphasis",bgColor:(0,c.getColorClassNames)("transparent").bgColor,hoverBgColor:t?(0,d.tremorTwMerge)((0,c.getColorClassNames)(t,g.colorPalette.background).hoverBgColor,"hover:bg-opacity-20 dark:hover:bg-opacity-20"):"hover:bg-tremor-brand-faint dark:hover:bg-dark-tremor-brand-faint",borderColor:t?(0,c.getColorClassNames)(t,g.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand"};case"light":return{textColor:t?(0,c.getColorClassNames)(t,g.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",hoverTextColor:t?(0,c.getColorClassNames)(t,g.colorPalette.darkText).hoverTextColor:"hover:text-tremor-brand-emphasis dark:hover:text-dark-tremor-brand-emphasis",bgColor:(0,c.getColorClassNames)("transparent").bgColor,borderColor:"",hoverBorderColor:""}}},b=(0,c.makeClassName)("Button"),m=({loading:e,iconSize:t,iconPosition:r,Icon:o,needMargin:i,transitionStatus:s})=>{let a=i?r===l.HorizontalPositions.Left?(0,d.tremorTwMerge)("-ml-1","mr-1.5"):(0,d.tremorTwMerge)("-mr-1","ml-1.5"):"",c=(0,d.tremorTwMerge)("w-0 h-0"),g={default:c,entering:c,entered:t,exiting:t,exited:c};return e?n.default.createElement(u,{className:(0,d.tremorTwMerge)(b("icon"),"animate-spin shrink-0",a,g.default,g[s]),style:{transition:"width 150ms"}}):n.default.createElement(o,{className:(0,d.tremorTwMerge)(b("icon"),"shrink-0",t,a)})},f=n.default.forwardRef((e,o)=>{let{icon:u,iconPosition:g=l.HorizontalPositions.Left,size:f=l.Sizes.SM,color:p,variant:C="primary",disabled:x,loading:T=!1,loadingText:E,children:k,tooltip:y,className:w}=e,S=(0,t.__rest)(e,["icon","iconPosition","size","color","variant","disabled","loading","loadingText","children","tooltip","className"]),P=T||x,N=void 0!==u||T,B=T&&E,L=!(!k&&!B),M=(0,d.tremorTwMerge)(h[f].height,h[f].width),R="light"!==C?(0,d.tremorTwMerge)("rounded-tremor-default border","shadow-tremor-input","dark:shadow-dark-tremor-input"):"",I=v(C,p),z=("light"!==C?{xs:{paddingX:"px-2.5",paddingY:"py-1.5",fontSize:"text-xs"},sm:{paddingX:"px-4",paddingY:"py-2",fontSize:"text-sm"},md:{paddingX:"px-4",paddingY:"py-2",fontSize:"text-md"},lg:{paddingX:"px-4",paddingY:"py-2.5",fontSize:"text-lg"},xl:{paddingX:"px-4",paddingY:"py-3",fontSize:"text-xl"}}:{xs:{paddingX:"",paddingY:"",fontSize:"text-xs"},sm:{paddingX:"",paddingY:"",fontSize:"text-sm"},md:{paddingX:"",paddingY:"",fontSize:"text-md"},lg:{paddingX:"",paddingY:"",fontSize:"text-lg"},xl:{paddingX:"",paddingY:"",fontSize:"text-xl"}})[f],{tooltipProps:D,getReferenceProps:_}=(0,r.useTooltip)(300),[O,j]=(({enter:e=!0,exit:t=!0,preEnter:r,preExit:o,timeout:l,initialEntered:d,mountOnEnter:c,unmountOnExit:u,onStateChange:g}={})=>{let[h,v]=(0,n.useState)(()=>i(d?2:s(c))),b=(0,n.useRef)(h),m=(0,n.useRef)(0),[f,p]="object"==typeof l?[l.enter,l.exit]:[l,l],C=(0,n.useCallback)(()=>{let e=((e,t)=>{switch(e){case 1:case 0:return 2;case 4:case 3:return s(t)}})(b.current._s,u);e&&a(e,v,b,m,g)},[g,u]);return[h,(0,n.useCallback)(n=>{let i=e=>{switch(a(e,v,b,m,g),e){case 1:f>=0&&(m.current=((...e)=>setTimeout(...e))(C,f));break;case 4:p>=0&&(m.current=((...e)=>setTimeout(...e))(C,p));break;case 0:case 3:m.current=((...e)=>setTimeout(...e))(()=>{isNaN(document.body.offsetTop)||i(e+1)},0)}},l=b.current.isEnter;"boolean"!=typeof n&&(n=!l),n?l||i(e?+!r:2):l&&i(t?o?3:4:s(u))},[C,g,e,t,r,o,f,p,u]),C]})({timeout:50});return(0,n.useEffect)(()=>{j(T)},[T]),n.default.createElement("button",Object.assign({ref:(0,c.mergeRefs)([o,D.refs.setReference]),className:(0,d.tremorTwMerge)(b("root"),"shrink-0 inline-flex justify-center items-center group font-medium outline-none",R,z.paddingX,z.paddingY,z.fontSize,I.textColor,I.bgColor,I.borderColor,I.hoverBorderColor,P?"opacity-50 cursor-not-allowed":(0,d.tremorTwMerge)(v(C,p).hoverTextColor,v(C,p).hoverBgColor,v(C,p).hoverBorderColor),w),disabled:P},_,S),n.default.createElement(r.default,Object.assign({text:y},D)),N&&g!==l.HorizontalPositions.Right?n.default.createElement(m,{loading:T,iconSize:M,iconPosition:g,Icon:u,transitionStatus:O.status,needMargin:L}):null,B||k?n.default.createElement("span",{className:(0,d.tremorTwMerge)(b("text"),"text-tremor-default whitespace-nowrap")},B?E:k):null,N&&g===l.HorizontalPositions.Right?n.default.createElement(m,{loading:T,iconSize:M,iconPosition:g,Icon:u,transitionStatus:O.status,needMargin:L}):null)});f.displayName="Button",e.s(["Button",0,f],994388)},304967,e=>{"use strict";var t=e.i(290571),r=e.i(271645),n=e.i(480731),o=e.i(95779),i=e.i(444755),s=e.i(673706);let a=(0,s.makeClassName)("Card"),l=r.default.forwardRef((e,l)=>{let{decoration:d="",decorationColor:c,children:u,className:g}=e,h=(0,t.__rest)(e,["decoration","decorationColor","children","className"]);return r.default.createElement("div",Object.assign({ref:l,className:(0,i.tremorTwMerge)(a("root"),"relative w-full text-left ring-1 rounded-tremor-default p-6","bg-tremor-background ring-tremor-ring shadow-tremor-card","dark:bg-dark-tremor-background dark:ring-dark-tremor-ring dark:shadow-dark-tremor-card",c?(0,s.getColorClassNames)(c,o.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand",(e=>{if(!e)return"";switch(e){case n.HorizontalPositions.Left:return"border-l-4";case n.VerticalPositions.Top:return"border-t-4";case n.HorizontalPositions.Right:return"border-r-4";case n.VerticalPositions.Bottom:return"border-b-4";default:return""}})(d),g)},h),u)});l.displayName="Card",e.s(["Card",0,l],304967)},983561,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let n={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"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"};var o=e.i(9583),i=r.forwardRef(function(e,i){return r.createElement(o.default,(0,t.default)({},e,{ref:i,icon:n}))});e.s(["RobotOutlined",0,i],983561)},992619,e=>{"use strict";var t=e.i(843476),r=e.i(271645),n=e.i(779241),o=e.i(599724),i=e.i(199133),s=e.i(983561),a=e.i(343488),l=e.i(695411);e.s(["default",0,({accessToken:e,value:d,placeholder:c="Select a Model",onChange:u,disabled:g=!1,style:h,className:v,showLabel:b=!0,labelText:m="Select Model"})=>{let[f,p]=(0,r.useState)(d),[C,x]=(0,r.useState)(!1),[T,E]=(0,r.useState)([]);(0,r.useEffect)(()=>{p(d)},[d]),(0,r.useEffect)(()=>{e&&(async()=>{try{let t=await (0,l.fetchAvailableModels)(e);t.length>0&&E(t)}catch(e){console.error("Error fetching model info:",e)}})()},[e]);let k=(0,a.useDebouncedCallback)(e=>{p(e),u?.(e)},{wait:500});return(0,t.jsxs)("div",{children:[b&&(0,t.jsxs)(o.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,t.jsx)(s.RobotOutlined,{className:"mr-2"})," ",m]}),(0,t.jsx)(i.Select,{value:f,placeholder:c,onChange:e=>{"custom"===e?(x(!0),p(void 0)):(x(!1),p(e),u&&u(e))},options:[...Array.from(new Set(T.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%",...h},showSearch:!0,className:`rounded-md ${v||""}`,disabled:g}),C&&(0,t.jsx)(n.TextInput,{className:"mt-2",placeholder:"Enter custom model name",onValueChange:k,disabled:g})]})}])}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0.mwuwep0859t.js b/litellm/proxy/_experimental/out/_next/static/chunks/0.mwuwep0859t.js deleted file mode 100644 index c98a610a088..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/0.mwuwep0859t.js +++ /dev/null @@ -1,2 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,54131,399219,e=>{"use strict";let t=(0,e.i(475254).default)("chevron-up",[["path",{d:"m18 15-6-6-6 6",key:"153udz"}]]);e.s(["default",0,t],399219),e.s(["ChevronUpIcon",0,t],54131)},886407,373375,319897,531026,564623,e=>{"use strict";var t=e.i(475254);let n=(0,t.default)("search-x",[["path",{d:"m13.5 8.5-5 5",key:"1cs55j"}],["path",{d:"m8.5 8.5 5 5",key:"a8mexj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}],["path",{d:"m21 21-4.3-4.3",key:"1qie3q"}]]);e.s(["SearchX",0,n],886407);let r=(0,t.default)("chevron-left",[["path",{d:"m15 18-6-6 6-6",key:"1wnfg3"}]]);e.s(["ChevronLeft",0,r],373375);let o=(0,t.default)("chevrons-left",[["path",{d:"m11 17-5-5 5-5",key:"13zhaf"}],["path",{d:"m18 17-5-5 5-5",key:"h8a8et"}]]);e.s(["ChevronsLeft",0,o],319897);let i=(0,t.default)("chevrons-right",[["path",{d:"m6 17 5-5-5-5",key:"xnjwq"}],["path",{d:"m13 17 5-5-5-5",key:"17xmmf"}]]);e.s(["ChevronsRight",0,i],531026),e.s([],564623)},260891,736760,e=>{"use strict";e.i(247167);var t=e.i(271645),n=e.i(708445),r=e.i(146376),o=e.i(108868),i=e.i(667865),s=e.i(446265),l=e.i(229315),a=e.i(675606),u=e.i(56434),c=e.i(46420),d=e.i(621082),p=e.i(449055),f=e.i(647554),g=e.i(596296),m=e.i(503596),h=e.i(157940);function v(e,t,n){switch(e){case"vertical":return t;case"horizontal":return n;default:return t||n}}function x(e,t){return v(t,e===p.ARROW_UP||e===p.ARROW_DOWN,e===p.ARROW_LEFT||e===p.ARROW_RIGHT)}function b(e,t,n){return v(t,e===p.ARROW_DOWN,n?e===p.ARROW_LEFT:e===p.ARROW_RIGHT)||"Enter"===e||" "===e||""===e}e.s(["useListNavigation",0,function(e,S){let{listRef:y,activeIndex:R,onNavigate:C=()=>{},enabled:E=!0,selectedIndex:w=null,allowEscape:M=!1,loopFocus:I=!1,nested:j=!1,rtl:T=!1,virtual:k=!1,focusItemOnOpen:N="auto",focusItemOnHover:P=!0,openOnArrowKeyDown:A=!0,disabledIndices:O,orientation:L="vertical",parentOrientation:D,id:F,resetOnPointerLeave:z=!0,externalTree:_,grid:V}=S,H=null!=V,B="rootStore"in e?e.rootStore:e,U=B.useState("open"),G=B.useState("floatingElement"),W=B.useState("domReferenceElement"),Y=B.context.dataRef,$=(0,g.getFloatingFocusElement)(G),q=(0,g.isTypeableCombobox)(W),K=(0,s.useValueAsRef)($),X=(0,c.useFloatingParentNodeId)(),J=(0,c.useFloatingTree)(_),Z=t.useRef(N),Q=t.useRef(w??-1),ee=t.useRef(null),et=t.useRef(!0),en=(0,i.useStableCallback)(e=>{C(-1===Q.current?null:Q.current,e)}),er=t.useRef(!!G),eo=t.useRef(U),ei=t.useRef(!1),es=t.useRef(!1),el=t.useRef(null),ea=(0,s.useValueAsRef)(O),eu=(0,s.useValueAsRef)(U),ec=(0,s.useValueAsRef)(w),ed=(0,s.useValueAsRef)(z),ep=(0,n.useAnimationFrame)(),ef=(0,n.useAnimationFrame)(),eg=(0,i.useStableCallback)(()=>{function e(e){k?J?.events.emit("virtualfocus",e):el.current=(0,m.enqueueFocus)(e,{sync:ei.current,preventScroll:!0})}let t=y.current[Q.current],n=es.current;t&&e(t),(ei.current?e=>e():e=>ep.request(e))(()=>{let r=y.current[Q.current]||t;!r||(t||e(r),eS&&(n||!et.current)&&r.scrollIntoView?.({block:"nearest",inline:"nearest"}))})});(0,r.useIsoLayoutEffect)(()=>{Y.current.orientation=L},[Y,L]),(0,r.useIsoLayoutEffect)(()=>{E&&(U&&G?(Q.current=w??-1,Z.current&&null!=w&&(es.current=!0,en())):er.current&&(Q.current=-1,en()))},[E,U,G,w,en]),(0,r.useIsoLayoutEffect)(()=>{if(E){if(!U){ei.current=!1;return}if(G)if(null==R){if(ei.current=!1,null!=ec.current)return;if(er.current&&(Q.current=-1,eg()),(!eo.current||!er.current)&&Z.current&&(null!=ee.current||!0===Z.current&&null==ee.current)){let e=0,t=()=>{null==y.current[0]?(e<2&&(e?e=>ef.request(e):queueMicrotask)(t),e+=1):(Q.current=null==ee.current||b(ee.current,L,T)||j?(0,d.getMinListIndex)(y):(0,d.getMaxListIndex)(y),ee.current=null,en())};t()}}else(0,d.isIndexOutOfListBounds)(y.current,R)||(Q.current=R,eg(),es.current=!1)}},[E,U,G,R,ec,j,y,L,T,en,eg,ef]),(0,r.useIsoLayoutEffect)(()=>{if(!E||G||!J||k||!er.current)return;let e=J.nodesRef.current,t=e.find(e=>e.id===X)?.context?.elements.floating,n=(0,f.activeElement)((0,o.ownerDocument)(W??t??null)),r=e.some(e=>e.context&&(0,f.contains)(e.context.elements.floating,n));t&&!r&&et.current&&t.focus({preventScroll:!0})},[E,G,W,J,X,k]),(0,r.useIsoLayoutEffect)(()=>{eo.current=U,er.current=!!G}),(0,r.useIsoLayoutEffect)(()=>{U||(ee.current=null,Z.current=N)},[U,N]);let em=null!=R,eh=(0,i.useStableCallback)(e=>{if(!eu.current)return;let t=y.current.indexOf(e.currentTarget);-1!==t&&(Q.current!==t||R!==t)&&(Q.current=t,en(e))}),ev=(0,i.useStableCallback)(()=>D??J?.nodesRef.current.find(e=>e.id===X)?.context?.dataRef?.current.orientation),ex=(0,i.useStableCallback)(()=>(0,d.getMinListIndex)(y,ea.current)),eb=(0,i.useStableCallback)(e=>{var t;let n,r;if(et.current=!1,ei.current=!0,229===e.which||!eu.current&&e.currentTarget===K.current)return;if(j&&(t=e.key,n=T?t===p.ARROW_RIGHT:t===p.ARROW_LEFT,r=t===p.ARROW_UP,"both"===L||"horizontal"===L&&H?"Escape"===t:v(L,n,r))){x(e.key,ev())||(0,h.stopEvent)(e),B.setOpen(!1,(0,a.createChangeEventDetails)(u.REASONS.listNavigation,e.nativeEvent)),(0,l.isHTMLElement)(W)&&(k?J?.events.emit("virtualfocus",W):W.focus());return}let o=Q.current,i=(0,d.getMinListIndex)(y,O),s=(0,d.getMaxListIndex)(y,O);if(q||("Home"===e.key&&((0,h.stopEvent)(e),Q.current=i,en(e)),"End"===e.key&&((0,h.stopEvent)(e),Q.current=s,en(e))),null!=V){let t=V(e,Q.current,y,L,I,T,O,i,s);if(null!=t&&(Q.current=t,en(e)),"both"===L)return}if(x(e.key,L)){if((0,h.stopEvent)(e),U&&!k&&(0,f.activeElement)(e.currentTarget.ownerDocument)===e.currentTarget){Q.current=b(e.key,L,T)?i:s,en(e);return}b(e.key,L,T)?I?o>=s?M&&o!==y.current.length?Q.current=-1:(ei.current=!1,Q.current=i):Q.current=(0,d.findNonDisabledListIndex)(y.current,{startingIndex:o,disabledIndices:O}):Q.current=Math.min(s,(0,d.findNonDisabledListIndex)(y.current,{startingIndex:o,disabledIndices:O})):I?o<=i?M&&-1!==o?Q.current=y.current.length:(ei.current=!1,Q.current=s):Q.current=(0,d.findNonDisabledListIndex)(y.current,{startingIndex:o,decrement:!0,disabledIndices:O}):Q.current=Math.max(i,(0,d.findNonDisabledListIndex)(y.current,{startingIndex:o,decrement:!0,disabledIndices:O})),(0,d.isIndexOutOfListBounds)(y.current,Q.current)&&(Q.current=-1),en(e)}}),eS=t.useMemo(()=>({onFocus(e){ei.current=!0,eh(e)},onClick:({currentTarget:e})=>e.focus({preventScroll:!0}),onMouseMove(e){ei.current=!0,es.current=!1,P&&eh(e)},onPointerLeave(e){if(!eu.current||!et.current||"touch"===e.pointerType)return;ei.current=!0;let t=e.relatedTarget;if(!(!P||y.current.includes(t))&&ed.current&&(el.current?.(),el.current=null,Q.current=-1,en(e),!k)){let e=K.current,t=(0,f.activeElement)((0,o.ownerDocument)(e));e&&(0,f.contains)(e,t)&&e.focus({preventScroll:!0})}}}),[eh,eu,K,P,y,en,ed,k]),ey=t.useMemo(()=>k&&U&&em&&{"aria-activedescendant":`${F}-${R}`},[k,U,em,F,R]),eR=t.useMemo(()=>({"aria-orientation":"both"===L?void 0:L,...!q?ey:{},onKeyDown(e){if("Tab"===e.key&&e.shiftKey&&U&&!k){let t=(0,f.getTarget)(e.nativeEvent);if(t&&!(0,f.contains)(K.current,t))return;(0,h.stopEvent)(e),B.setOpen(!1,(0,a.createChangeEventDetails)(u.REASONS.focusOut,e.nativeEvent)),(0,l.isHTMLElement)(W)&&W.focus();return}eb(e)},onPointerMove(){et.current=!0}}),[ey,eb,K,L,q,B,U,k,W]),eC=t.useMemo(()=>{function e(e){B.setOpen(!0,(0,a.createChangeEventDetails)(u.REASONS.listNavigation,e.nativeEvent,e.currentTarget))}function t(e){"auto"===N&&(0,h.isVirtualClick)(e.nativeEvent)&&(Z.current=!k)}function n(e){Z.current=N,"auto"===N&&(0,h.isVirtualPointerEvent)(e.nativeEvent)&&(Z.current=!0)}return{onKeyDown(t){var n,r;let o=B.select("open");et.current=!1;let i=t.key.startsWith("Arrow"),s=(n=t.key,r=ev(),v(r,T?n===p.ARROW_LEFT:n===p.ARROW_RIGHT,n===p.ARROW_DOWN)),l=x(t.key,L),a=(j?s:l)||"Enter"===t.key||""===t.key.trim();if(k&&o)return eb(t);if(o||A||!i){if(a){let e=x(t.key,ev());ee.current=j&&e?null:t.key}if(j){s&&((0,h.stopEvent)(t),o?(Q.current=ex(),en(t)):e(t));return}l&&(null!=ec.current&&(Q.current=ec.current),(0,h.stopEvent)(t),!o&&A?e(t):eb(t),o&&en(t))}},onFocus(e){B.select("open")&&!k&&(Q.current=-1,en(e))},onPointerDown:n,onPointerEnter:n,onMouseDown:t,onClick:t}},[eb,N,ex,j,en,B,A,L,ev,T,ec,k]),eE=t.useMemo(()=>({...ey,...eC}),[ey,eC]);return t.useMemo(()=>E?{reference:eE,floating:eR,item:eS,trigger:eC}:{},[E,eE,eR,eC,eS])}],260891);var S=e.i(439957),y=e.i(956789);e.s(["useTypeahead",0,function(e,n){let{listRef:o,elementsRef:s,activeIndex:l,onMatch:a,disabledIndices:u,onTyping:c,enabled:p=!0,resetMs:g=750,selectedIndex:m=null}=n,v="rootStore"in e?e.rootStore:e,x=v.useState("open"),b=(0,S.useTimeout)(),R=t.useRef(""),C=t.useRef(m??l??-1),E=t.useRef(null),w=(0,i.useStableCallback)(e=>{function t(e){let t;return!!(!(t=s?.current[e])||(0,d.isElementVisible)(t))&&(null==u||!(0,d.isListIndexDisabled)(y.EMPTY_ARRAY,e,u))}function n(e,r,o=0){if(0===e.length)return -1;let i=(o%e.length+e.length)%e.length,s=r.toLowerCase();for(let n=0;n0&&" "===e.key&&((0,h.stopEvent)(e),c?.(!0)),R.current.length>0&&" "!==R.current[0]&&-1===n(r,R.current)&&" "!==e.key&&c?.(!1),null==r||1!==e.key.length||e.ctrlKey||e.metaKey||e.altKey)return;x&&" "!==e.key&&((0,h.stopEvent)(e),c?.(!0));let i=""===R.current;i&&(C.current=m??l??-1),r.every((e,n)=>!(e&&t(n))||e[0]?.toLowerCase()!==e[1]?.toLowerCase())&&R.current===e.key&&(R.current="",C.current=E.current),R.current+=e.key,b.start(g,()=>{R.current="",C.current=E.current,c?.(!1)});let p=i?m??l??-1:C.current,f=n(r,R.current,(p??0)+1);-1!==f?(a?.(f),E.current=f):" "!==e.key&&(R.current="",c?.(!1))}),M=(0,i.useStableCallback)(e=>{let t=e.relatedTarget,n=v.select("domReferenceElement"),r=v.select("floatingElement");(0,f.contains)(n,t)||(0,f.contains)(r,t)||(b.clear(),R.current="",C.current=E.current,c?.(!1))});(0,r.useIsoLayoutEffect)(()=>{(x||null===m)&&(b.clear(),E.current=null,""!==R.current&&(R.current=""))},[x,m,b]),(0,r.useIsoLayoutEffect)(()=>{x&&""===R.current&&(C.current=m??l??-1)},[x,m,l]);let I=t.useMemo(()=>({onKeyDown:w,onBlur:M}),[w,M]);return t.useMemo(()=>p?{reference:I,floating:I}:{},[p,I])}],736760)},39707,703902,484325,42191,804659,743024,897886,450001,79870,e=>{"use strict";var t=e.i(271645),n=e.i(502077),r=e.i(828918),o=e.i(921374),i=e.i(713203),s=e.i(394258),l=e.i(590803),a=e.i(951437),u=e.i(146376),c=e.i(667865),d=e.i(446265),p=e.i(334346),f=e.i(714935),g=e.i(956789),m=e.i(385689),h=e.i(17989),v=e.i(265858),x=e.i(260891),b=e.i(736760);e.i(247167);var S=e.i(733332);let y=t.createContext(null),R=t.createContext(null);function C(){let e=t.useContext(y);if(null===e)throw Error((0,S.default)(60));return e}e.s(["SelectFloatingContext",0,R,"SelectRootContext",0,y,"useSelectFloatingContext",0,function(){let e=t.useContext(R);if(null===e)throw Error((0,S.default)(61));return e},"useSelectRootContext",0,C],703902);var E=e.i(469690),w=e.i(381104),M=e.i(538489),I=e.i(223910),j=e.i(616269);let T=(e,t)=>Object.is(e,t);function k(e,t,n){return null==e||null==t?Object.is(e,t):n(e,t)}function N(e,t,n){return e&&0!==e.length?e.findIndex(e=>void 0!==e&&k(e,t,n)):-1}function P(e){if(null==e)return"";if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}}e.s(["compareItemEquality",0,k,"defaultItemEquality",0,T,"findItemIndex",0,N,"removeItem",0,function(e,t,n){return e.filter(e=>!k(t,e,n))},"selectedValueIncludes",0,function(e,t,n){return!!e&&0!==e.length&&e.some(e=>void 0!==e&&k(t,e,n))}],484325);var A=e.i(843476);function O(e){return null!=e&&e.length>0&&"object"==typeof e[0]&&null!=e[0]&&"items"in e[0]}function L(e){if(!Array.isArray(e))return null!=e&&"null"in e;if(O(e)){for(let t of e)for(let e of t.items)if(e&&null==e.value&&null!=e.label)return!0;return!1}for(let t of e)if(t&&null==t.value&&null!=t.label)return!0;return!1}function D(e,t){if(t&&null!=e)return t(e)??"";if(e&&"object"==typeof e){if("label"in e&&null!=e.label)return String(e.label);if("value"in e)return String(e.value)}return P(e)}function F(e,t){return t&&null!=e?t(e)??"":e&&"object"==typeof e&&"value"in e&&"label"in e?P(e.value):P(e)}function z(e,t,n){if(n&&null!=e)return n(e);if(e&&"object"==typeof e&&"label"in e&&null!=e.label)return e.label;if(t&&!Array.isArray(t))return t[e]??D(e,n);if(Array.isArray(t)){let r=O(t)?t.flatMap(e=>e.items):t;if(null==e||"object"!=typeof e){let t=r.find(t=>t.value===e);return t&&null!=t.label?t.label:D(e,n)}if("value"in e){let t=r.find(t=>t&&t.value===e.value);if(t&&null!=t.label)return t.label}}return D(e,n)}e.s(["hasNullItemLabel",0,L,"isGroupedItems",0,O,"resolveMultipleLabels",0,function(e,n,r){return e.reduce((e,o,i)=>(i>0&&e.push(", "),e.push((0,A.jsx)(t.Fragment,{children:z(o,n,r)},i)),e),[])},"resolveSelectedLabel",0,z,"stringifyAsLabel",0,D,"stringifyAsValue",0,F],42191);let _={id:(0,j.createSelector)(e=>e.id),labelId:(0,j.createSelector)(e=>e.labelId),modal:(0,j.createSelector)(e=>e.modal),multiple:(0,j.createSelector)(e=>e.multiple),items:(0,j.createSelector)(e=>e.items),itemToStringLabel:(0,j.createSelector)(e=>e.itemToStringLabel),itemToStringValue:(0,j.createSelector)(e=>e.itemToStringValue),isItemEqualToValue:(0,j.createSelector)(e=>e.isItemEqualToValue),value:(0,j.createSelector)(e=>e.value),hasSelectedValue:(0,j.createSelector)(e=>{let{value:t,multiple:n,itemToStringValue:r}=e;return null!=t&&(n&&Array.isArray(t)?t.length>0:""!==F(t,r))}),hasNullItemLabel:(0,j.createSelector)((e,t)=>!!t&&L(e.items)),open:(0,j.createSelector)(e=>e.open),mounted:(0,j.createSelector)(e=>e.mounted),forceMount:(0,j.createSelector)(e=>e.forceMount),transitionStatus:(0,j.createSelector)(e=>e.transitionStatus),openMethod:(0,j.createSelector)(e=>e.openMethod),activeIndex:(0,j.createSelector)(e=>e.activeIndex),selectedIndex:(0,j.createSelector)(e=>e.selectedIndex),isActive:(0,j.createSelector)((e,t)=>e.activeIndex===t),isSelected:(0,j.createSelector)((e,t)=>{let n=e.isItemEqualToValue,r=e.value;return e.multiple?Array.isArray(r)&&r.some(e=>k(t,e,n)):k(t,r,n)}),isSelectedByFocus:(0,j.createSelector)((e,t)=>e.selectedIndex===t),popupProps:(0,j.createSelector)(e=>e.popupProps),triggerProps:(0,j.createSelector)(e=>e.triggerProps),triggerElement:(0,j.createSelector)(e=>e.triggerElement),positionerElement:(0,j.createSelector)(e=>e.positionerElement),listElement:(0,j.createSelector)(e=>e.listElement),popupSide:(0,j.createSelector)(e=>e.popupSide),scrollUpArrowVisible:(0,j.createSelector)(e=>e.scrollUpArrowVisible),scrollDownArrowVisible:(0,j.createSelector)(e=>e.scrollDownArrowVisible),hasScrollArrows:(0,j.createSelector)(e=>e.hasScrollArrows)};e.s(["selectors",0,_],804659);var V=e.i(675606),H=e.i(56434),B=e.i(137584),U=e.i(884708);function G(e,t,n=(e,t)=>e===t){return e.length===t.length&&e.every((e,r)=>n(e,t[r]))}e.s(["areArraysEqual",0,G],743024);var W=e.i(606039),Y=e.i(32199),$=e.i(550896),q=e.i(264111),K=e.i(176782);e.s(["SelectRoot",0,function(e){let{id:S,value:C,defaultValue:j=null,onValueChange:P,open:O,defaultOpen:L=!1,onOpenChange:z,name:X,form:J,autoComplete:Z,disabled:Q=!1,readOnly:ee=!1,required:et=!1,modal:en=!0,actionsRef:er,inputRef:eo,onOpenChangeComplete:ei,items:es,multiple:el=!1,itemToStringLabel:ea,itemToStringValue:eu,isItemEqualToValue:ec=T,highlightItemOnHover:ed=!0,children:ep}=e,{clearErrors:ef}=(0,U.useFormContext)(),{setDirty:eg,setTouched:em,setFocused:eh,validityData:ev,setFilled:ex,name:eb,disabled:eS,validation:ey,validationMode:eR}=(0,E.useFieldRootContext)(),eC=(0,M.useLabelableId)({id:S}),eE=eS||Q,ew=eb??X,[eM,eI]=(0,a.useControlled)({controlled:C,default:el?j??g.EMPTY_ARRAY:j,name:"Select",state:"value"}),[ej,eT]=(0,a.useControlled)({controlled:O,default:L,name:"Select",state:"open"}),ek=t.useRef([]),eN=t.useRef([]),eP=t.useRef(null),eA=t.useRef(null),eO=t.useRef(0),eL=t.useRef(null),eD=t.useRef([]),eF=t.useRef(!1),ez=t.useRef(null),e_=t.useRef(null),eV=t.useRef({allowSelectedMouseUp:!1,allowUnselectedMouseUp:!1,dragY:0}),eH=t.useRef(!1),{mounted:eB,setMounted:eU,transitionStatus:eG}=(0,I.useTransitionStatus)(ej),{openMethod:eW,triggerProps:eY}=(0,Y.useOpenInteractionType)(ej),e$=(0,o.useRefWithInit)(()=>new f.Store({id:eC,labelId:void 0,modal:en,multiple:el,itemToStringLabel:ea,itemToStringValue:eu,isItemEqualToValue:ec,value:eM,open:ej,mounted:eB,transitionStatus:eG,items:es,forceMount:!1,openMethod:null,activeIndex:null,selectedIndex:null,popupProps:{},triggerProps:{},triggerElement:null,positionerElement:null,listElement:null,popupSide:null,scrollUpArrowVisible:!1,scrollDownArrowVisible:!1,hasScrollArrows:!1})).current,eq=(0,p.useStore)(e$,_.activeIndex),eK=(0,p.useStore)(e$,_.selectedIndex),eX=(0,p.useStore)(e$,_.triggerElement),eJ=(0,p.useStore)(e$,_.positionerElement),eZ=(0,s.usePreviousValue)(eW),eQ=eW??eZ??null,e0=t.useMemo(()=>el?"":F(eM,eu),[el,eM,eu]),e1=t.useMemo(()=>el&&Array.isArray(eM)?eM.map(e=>F(e,eu)):F(eM,eu),[el,eM,eu]),e5=(0,d.useValueAsRef)(e$.state.triggerElement),e2=(0,c.useStableCallback)(()=>e1);(0,w.useRegisterFieldControl)(e5,eC,eM,e2,!eE,X);let e4=t.useRef(eM),e3=el?Array.isArray(eM)&&eM.length>0:null!=eM&&""!==F(eM,eu);(0,u.useIsoLayoutEffect)(()=>{eM!==e4.current&&e$.set("forceMount",!0)},[e$,eM]),(0,u.useIsoLayoutEffect)(()=>{ex(e3)},[e3,ex]),(0,u.useIsoLayoutEffect)(function(){let e,t=eD.current;if(el){let n=Array.isArray(eM)?eM:[];if(0===n.length)e=null;else{let r=N(t,n[n.length-1],ec);e=-1===r?null:r}}else{let n=N(t,eM,ec);e=-1===n?null:n}null===e&&(e_.current=null),ej||e$.set("selectedIndex",e)},[e3,el,ej,eM,eD,ec,e$,e_]),(0,W.useValueChanged)(eM,()=>{let e;ef(ew),eg((e=ev.initialValue,Array.isArray(eM)&&Array.isArray(e)?!G(eM,e,(e,t)=>k(e,t,ec)):eM!==e)),ey.change(eM)});let e6=(0,c.useStableCallback)((e,t)=>{z?.(e,t),!t.isCanceled&&(eT(e),e||t.reason!==H.REASONS.focusOut&&t.reason!==H.REASONS.outsidePress||(em(!0),eh(!1),"onBlur"===eR&&ey.commit(eM)))}),e7=(0,c.useStableCallback)(()=>{eU(!1),e$.update({activeIndex:null,openMethod:null}),ei?.(!1)});(0,B.useOpenChangeComplete)({enabled:!er,open:ej,ref:eP,onComplete(){ej||e7()}}),t.useImperativeHandle(er,()=>({unmount:e7}),[e7]);let e8=(0,c.useStableCallback)((e,t)=>{P?.(e,t),t.isCanceled||eI(e)}),e9=(0,c.useStableCallback)(()=>{let e=e$.state.listElement||eP.current;if(!e)return;let t=(0,$.getMaxScrollOffset)(e.scrollHeight,e.clientHeight),n=(0,$.normalizeScrollOffset)(e.scrollTop,t),r=n>0,o=n(0,l.isElementDisabled)(ek.current[e]),onMatch(e){ej?e$.set("activeIndex",e):e8(eD.current[e],(0,V.createChangeEventDetails)("none"))},onTyping(e){eF.current=e}}),ti=t.useMemo(()=>{let e=(0,K.mergeProps)(to.reference,tr.reference,tn.reference,tt.reference,eY);return eC&&(e.id=eC),e},[tt.reference,to.reference,tr.reference,tn.reference,eY,eC]),ts=t.useMemo(()=>(0,K.mergeProps)(q.FOCUSABLE_POPUP_PROPS,to.floating,tr.floating,tn.floating),[to.floating,tr.floating,tn.floating]),tl=tr.item??g.EMPTY_OBJECT;(0,i.useOnFirstRender)(()=>{e$.update({popupProps:ts,triggerProps:ti})}),(0,u.useIsoLayoutEffect)(()=>{e$.update({id:eC,modal:en,multiple:el,value:eM,open:ej,mounted:eB,transitionStatus:eG,popupProps:ts,triggerProps:ti,items:es,itemToStringLabel:ea,itemToStringValue:eu,isItemEqualToValue:ec,openMethod:eQ})},[e$,eC,en,el,eM,ej,eB,eG,ts,ti,es,ea,eu,ec,eQ]);let ta=t.useMemo(()=>({store:e$,name:ew,required:et,disabled:eE,readOnly:ee,multiple:el,highlightItemOnHover:ed,setValue:e8,setOpen:e6,listRef:ek,popupRef:eP,scrollHandlerRef:eA,handleScrollArrowVisibility:e9,scrollArrowsMountedCountRef:eO,itemProps:tl,valueRef:eL,valuesRef:eD,labelsRef:eN,typingRef:eF,selectionRef:eV,firstItemTextRef:ez,selectedItemTextRef:e_,validation:ey,onOpenChangeComplete:ei,alignItemWithTriggerActiveRef:eH,initialValueRef:e4}),[e$,ew,et,eE,ee,el,ed,e8,e6,tl,ey,ei,e9]),tu=(0,r.useMergedRefs)(eo,ey.inputRef),tc=el&&Array.isArray(eM)&&eM.length>0,td=el?void 0:ew,tp=t.useMemo(()=>el&&Array.isArray(eM)&&ew?eM.map(e=>{let t=F(e,eu);return(0,A.jsx)("input",{type:"hidden",form:J,name:ew,value:t,disabled:eE},t)}):null,[el,eM,J,ew,eu,eE]);return(0,A.jsx)(y.Provider,{value:ta,children:(0,A.jsxs)(R.Provider,{value:te,children:[ep,(0,A.jsx)("input",{...ey.getValidationProps(eE,{onFocus(){e$.state.triggerElement?.focus({focusVisible:!0})},onChange(e){if(e.nativeEvent.defaultPrevented||eE||ee)return;let t=e.currentTarget.value,n=(0,V.createChangeEventDetails)(H.REASONS.none,e.nativeEvent);e$.set("forceMount",!0),queueMicrotask(function(){if(el)return;let e=t.toLowerCase(),r=eD.current.findIndex(t=>F(t,eu).toLowerCase()===e||D(t,ea).toLowerCase()===e);-1===r&&(r=eD.current.findIndex((t,n)=>{let r=eN.current[n];return null!=r&&r.toLowerCase()===e}));let o=-1===r?void 0:eD.current[r];null!=o&&e8(o,n)})}}),id:eC&&null==td?`${eC}-hidden-input`:void 0,form:J,name:td,autoComplete:Z,value:e0,disabled:eE,required:et&&!tc,readOnly:ee,ref:tu,style:ew?n.visuallyHiddenInput:n.visuallyHidden,tabIndex:-1,"aria-hidden":!0,suppressHydrationWarning:!0}),tp]})})}],39707);var X=e.i(552245),J=e.i(875812),Z=e.i(229315),Q=e.i(108868),ee=e.i(647554),et=e.i(757337),en=e.i(247778);function er(e={}){let{id:t,fallbackControlId:n,native:r=!1,setLabelId:o,focusControl:i}=e,{controlId:s,setLabelId:l}=(0,en.useLabelableContext)(),a=(0,c.useStableCallback)(e=>{l(e),o?.(e)}),u=(0,et.useRegisteredLabelId)(t,a),d=s??n;function p(e){let t=(0,ee.getTarget)(e.nativeEvent);t?.closest("button,input,select,textarea")||(!e.defaultPrevented&&e.detail>1&&e.preventDefault(),r||function(e){if(i)return i(e,d);if(!d)return;let t=(0,Q.ownerDocument)(e.currentTarget).getElementById(d);(0,Z.isHTMLElement)(t)&&t.focus({focusVisible:!0})}(e))}return r?{id:u,htmlFor:d??void 0,onMouseDown:p}:{id:u,onClick:p,onPointerDown(e){e.preventDefault()}}}function eo(e){return null==e?void 0:`${e}-label`}e.s(["useLabel",0,er],897886),e.s(["getDefaultLabelId",0,eo,"resolveAriaLabelledBy",0,function(e,t){return e??t}],450001);let ei=t.forwardRef(function(e,t){let{render:n,className:r,style:o,...i}=e;delete i.id;let s=(0,E.useFieldRootContext)(),{store:l}=C(),a=(0,p.useStore)(l,_.triggerElement),u=(0,p.useStore)(l,_.id),c=er({id:eo(u),fallbackControlId:a?.id??u,setLabelId(e){l.set("labelId",e)}});return(0,X.useRenderElement)("div",e,{ref:t,state:s.state,props:[c,i],stateAttributesMapping:J.fieldValidityMapping})});e.s(["SelectLabel",0,ei],79870)},264042,e=>{"use strict";var t=e.i(333848),n=e.i(328744);e.s(["getPseudoElementBounds",0,function(e){let r=e.getBoundingClientRect(),o=(0,t.ownerWindow)(e);if(n.platform.env.jsdom)return r;let i=o.getComputedStyle(e,"::before"),s=o.getComputedStyle(e,"::after");if("none"===i.content&&"none"===s.content)return r;let l=parseFloat(i.width)||0,a=parseFloat(i.height)||0,u=parseFloat(s.width)||0,c=parseFloat(s.height)||0,d=Math.max(r.width,l,u),p=Math.max(r.height,a,c),f=d-r.width,g=p-r.height;return{left:r.left-f/2,right:r.right+f/2,top:r.top-g/2,bottom:r.bottom+g/2}}])},83955,e=>{"use strict";e.i(564623);var t=e.i(39707),n=e.i(79870);e.i(247167);var r=e.i(271645),o=e.i(108868),i=e.i(439957),s=e.i(667865),l=e.i(446265),a=e.i(334346),u=e.i(703902),c=e.i(469690),d=e.i(247778),p=e.i(405005),f=e.i(875812),g=e.i(552245),m=e.i(804659),h=e.i(264042),v=e.i(647554),x=e.i(596296),b=e.i(176782),S=e.i(540886),y=e.i(675606),R=e.i(56434),C=e.i(538489),E=e.i(450001);let w={...p.pressableTriggerOpenStateMapping,...f.fieldValidityMapping,popupSide:e=>e?{"data-popup-side":e}:null,value:()=>null},M=r.forwardRef(function(e,t){let{render:n,className:p,id:f,disabled:M=!1,nativeButton:I=!0,style:j,...T}=e,{setTouched:k,setFocused:N,validationMode:P,state:A,disabled:O}=(0,c.useFieldRootContext)(),{labelId:L}=(0,d.useLabelableContext)(),{store:D,setOpen:F,selectionRef:z,validation:_,readOnly:V,required:H,alignItemWithTriggerActiveRef:B,disabled:U}=(0,u.useSelectRootContext)(),G=O||U||M,W=(0,a.useStore)(D,m.selectors.open),Y=(0,a.useStore)(D,m.selectors.mounted),$=(0,a.useStore)(D,m.selectors.value),q=(0,a.useStore)(D,m.selectors.triggerProps),K=(0,a.useStore)(D,m.selectors.positionerElement),X=(0,a.useStore)(D,m.selectors.listElement),J=(0,a.useStore)(D,m.selectors.popupSide),Z=(0,a.useStore)(D,m.selectors.id),Q=(0,a.useStore)(D,m.selectors.labelId),ee=(0,a.useStore)(D,m.selectors.hasSelectedValue),et=Y&&K?J:null,en=f??Z,er=(0,E.resolveAriaLabelledBy)(L,Q);(0,C.useLabelableId)({id:en});let eo=(0,l.useValueAsRef)(K),ei=r.useRef(null),{getButtonProps:es,buttonRef:el}=(0,S.useButton)({disabled:G,native:I}),ea=(0,s.useStableCallback)(e=>{D.set("triggerElement",e)}),eu=(0,i.useTimeout)(),ec=(0,i.useTimeout)(),ed=(0,i.useTimeout)();r.useEffect(()=>{if(W)return ed.start(400,()=>{z.current.allowUnselectedMouseUp=!0,z.current.allowSelectedMouseUp=!0}),()=>{ed.clear()};z.current={allowSelectedMouseUp:!1,allowUnselectedMouseUp:!1,dragY:0},ec.clear()},[W,z,ec,ed]);let ep=(0,b.mergeProps)(q,{id:en,role:"combobox","aria-expanded":W?"true":"false","aria-haspopup":"listbox","aria-controls":W?X?.id??(0,x.getFloatingFocusElement)(K)?.id:void 0,"aria-labelledby":er,"aria-readonly":V||void 0,"aria-required":H||void 0,tabIndex:G?-1:0,onFocus(e){N(!0),W&&B.current&&F(!1,(0,y.createChangeEventDetails)(R.REASONS.none,e.nativeEvent)),eu.start(0,()=>{D.set("forceMount",!0)})},onBlur(e){(0,v.contains)(K,e.relatedTarget)||(k(!0),N(!1),"onBlur"===P&&_.commit($))},onMouseDown(e){if(W)return;let t=(0,o.ownerDocument)(e.currentTarget);function n(e){if(!ei.current)return;let t=e.target;if((0,v.contains)(ei.current,t)||(0,v.contains)(eo.current,t))return;let n=(0,h.getPseudoElementBounds)(ei.current);e.clientX>=n.left-2&&e.clientX<=n.right+2&&e.clientY>=n.top-2&&e.clientY<=n.bottom+2||F(!1,(0,y.createChangeEventDetails)(R.REASONS.cancelOpen,e))}ec.start(0,()=>{t.addEventListener("mouseup",n,{once:!0})})}},T,es),ef=_.getValidationProps(G,ep);ef.role="combobox";let eg={...A,open:W,disabled:G,value:$,readOnly:V,popupSide:et,placeholder:!ee};return(0,g.useRenderElement)("button",e,{ref:[t,ei,el,ea],state:eg,stateAttributesMapping:w,props:ef})});var I=e.i(42191);let j={value:()=>null},T=r.forwardRef(function(e,t){let{className:n,render:r,children:o,placeholder:i,style:s,...l}=e,{store:c,valueRef:d}=(0,u.useSelectRootContext)(),p=(0,a.useStore)(c,m.selectors.value),f=(0,a.useStore)(c,m.selectors.items),h=(0,a.useStore)(c,m.selectors.itemToStringLabel),v=(0,a.useStore)(c,m.selectors.hasSelectedValue),x=(0,a.useStore)(c,m.selectors.hasNullItemLabel,!v&&null!=i&&null==o),b=null;return b="function"==typeof o?o(p):null!=o?o:v||null==i||x?Array.isArray(p)?(0,I.resolveMultipleLabels)(p,f,h):(0,I.resolveSelectedLabel)(p,f,h):i,(0,g.useRenderElement)("span",e,{state:{value:p,placeholder:!v},ref:[t,d],props:[{children:b},l],stateAttributesMapping:j})}),k=r.forwardRef(function(e,t){let{render:n,className:r,style:o,...i}=e,{store:s}=(0,u.useSelectRootContext)(),l=(0,a.useStore)(s,m.selectors.open);return(0,g.useRenderElement)("span",e,{state:{open:l},ref:t,props:[{"aria-hidden":!0,children:"▼"},i],stateAttributesMapping:p.triggerOpenStateMapping})});var N=e.i(726674);let P=r.createContext(void 0);var A=e.i(843476);let O=r.forwardRef(function(e,t){let{store:n}=(0,u.useSelectRootContext)(),r=(0,a.useStore)(n,m.selectors.mounted),o=(0,a.useStore)(n,m.selectors.forceMount);return r||o?(0,A.jsx)(P.Provider,{value:!0,children:(0,A.jsx)(N.FloatingPortal,{ref:t,...e})}):null});var L=e.i(209407);let D={...p.popupStateMapping,...L.transitionStatusMapping},F=r.forwardRef(function(e,t){let{render:n,className:r,style:o,...i}=e,{store:s}=(0,u.useSelectRootContext)(),l=(0,a.useStore)(s,m.selectors.open),c=(0,a.useStore)(s,m.selectors.mounted),d=(0,a.useStore)(s,m.selectors.transitionStatus);return(0,g.useRenderElement)("div",e,{state:{open:l,transitionStatus:d},ref:t,props:[{role:"presentation",hidden:!c,style:{userSelect:"none",WebkitUserSelect:"none"}},i],stateAttributesMapping:D})});var z=e.i(144394),_=e.i(146376),V=e.i(53687),H=e.i(329365),B=e.i(733332);let U=r.createContext(void 0);function G(){let e=r.useContext(U);if(!e)throw Error((0,B.default)(59));return e}var W=e.i(426),Y=e.i(638396);function $(e,t){e&&Object.assign(e.style,t)}let q={position:"relative",maxHeight:"100%",overflowX:"hidden",overflowY:"auto"};var K=e.i(484325),X=e.i(789579),J=e.i(33383);let Z={position:"fixed"},Q=r.forwardRef(function(e,t){let{anchor:n,positionMethod:o="absolute",className:i,render:l,side:c="bottom",align:d="center",sideOffset:p=0,alignOffset:f=0,collisionBoundary:g="clipping-ancestors",collisionPadding:h,arrowPadding:v=5,sticky:x=!1,disableAnchorTracking:b,alignItemWithTrigger:S=!0,collisionAvoidance:C=Y.DROPDOWN_COLLISION_AVOIDANCE,style:E,...w}=e,{store:M,listRef:I,labelsRef:j,alignItemWithTriggerActiveRef:T,selectedItemTextRef:k,valuesRef:N,initialValueRef:P,popupRef:O,setValue:L}=(0,u.useSelectRootContext)(),D=(0,u.useSelectFloatingContext)(),F=(0,a.useStore)(M,m.selectors.open),B=(0,a.useStore)(M,m.selectors.mounted),G=(0,a.useStore)(M,m.selectors.modal),q=(0,a.useStore)(M,m.selectors.value),Q=(0,a.useStore)(M,m.selectors.openMethod),ee=(0,a.useStore)(M,m.selectors.positionerElement),et=(0,a.useStore)(M,m.selectors.triggerElement),en=(0,a.useStore)(M,m.selectors.isItemEqualToValue),er=(0,a.useStore)(M,m.selectors.transitionStatus),eo=r.useRef(null),ei=r.useRef(null),[es,el]=r.useState(S),ea=B&&es&&"touch"!==Q;B||es===S||el(S),(0,_.useIsoLayoutEffect)(()=>{!B&&(m.selectors.scrollUpArrowVisible(M.state)&&M.set("scrollUpArrowVisible",!1),m.selectors.scrollDownArrowVisible(M.state)&&M.set("scrollDownArrowVisible",!1))},[M,B]),r.useImperativeHandle(T,()=>ea),(0,J.useAnchoredPopupScrollLock)((ea||G)&&F,"touch"===Q,ee,et);let eu=(0,H.useAnchorPositioning)({anchor:n,floatingRootContext:D,positionMethod:o,mounted:B,side:c,sideOffset:p,align:d,alignOffset:f,arrowPadding:v,collisionBoundary:g,collisionPadding:h,sticky:x,disableAnchorTracking:b??ea,collisionAvoidance:C,keepMounted:!0}),ec=ea?"none":eu.side,ed=ea?Z:eu.positionerStyles,ep={open:F,side:ec,align:eu.align,anchorHidden:eu.anchorHidden};(0,_.useIsoLayoutEffect)(()=>{M.set("popupSide",eu.side)},[M,eu.side]);let ef=(0,s.useStableCallback)(e=>{M.set("positionerElement",e)}),eg=(0,X.usePositioner)(e,ep,{styles:ed,transitionStatus:er,props:w,refs:[t,ef],hidden:!B,inert:!F}),em=r.useRef(0),eh=(0,s.useStableCallback)(e=>{if(0===e.size&&0===em.current||0===N.current.length)return;let t=em.current;if(em.current=e.size,e.size===t)return;let n=(0,y.createChangeEventDetails)(R.REASONS.none);if(0!==t&&!M.state.multiple&&null!==q&&-1===(0,K.findItemIndex)(N.current,q,en)){let e=P.current,t=null!=e&&-1!==(0,K.findItemIndex)(N.current,e,en)?e:null;L(t,n),null===t&&(M.set("selectedIndex",null),k.current=null)}if(0!==t&&M.state.multiple&&Array.isArray(q)){let e=q.filter(e=>-1!==(0,K.findItemIndex)(N.current,e,en));(e.length!==q.length||e.some(e=>!(0,K.selectedValueIncludes)(q,e,en)))&&(L(e,n),0===e.length&&(M.set("selectedIndex",null),k.current=null))}if(F&&ea){M.update({scrollUpArrowVisible:!1,scrollDownArrowVisible:!1});let e={height:""};$(ee,e),$(O.current,e)}}),ev=r.useMemo(()=>({...eu,side:ec,alignItemWithTriggerActive:ea,setControlledAlignItemWithTrigger:el,scrollUpArrowRef:eo,scrollDownArrowRef:ei}),[eu,ec,ea,el]);return(0,A.jsx)(V.CompositeList,{elementsRef:I,labelsRef:j,onMapChange:eh,children:(0,A.jsxs)(U.Provider,{value:ev,children:[B&&G&&(0,A.jsx)(W.InternalBackdrop,{inert:(0,z.inertValue)(!F),cutout:et}),eg]})})});var ee=e.i(343084),et=e.i(574735),en=e.i(328744),er=e.i(333848),eo=e.i(708445),ei=e.i(61487),es=e.i(953760),el=e.i(60837),ea=e.i(137584),eu=e.i(96533),ec=e.i(673327),ed=e.i(815982),ep=e.i(201675),ef=e.i(550896),eg=e.i(172410),em=e.i(872855);let eh={...p.popupStateMapping,...L.transitionStatusMapping},ev=r.forwardRef(function(e,t){let{render:n,className:i,style:l,finalFocus:c,...d}=e,{store:p,popupRef:f,onOpenChangeComplete:h,setOpen:v,valueRef:x,firstItemTextRef:b,selectedItemTextRef:S,multiple:C,handleScrollArrowVisibility:E,scrollHandlerRef:w,listRef:M,highlightItemOnHover:I}=(0,u.useSelectRootContext)(),{side:j,align:T,alignItemWithTriggerActive:k,isPositioned:N,setControlledAlignItemWithTrigger:P}=G(),O=null!=(0,eu.useToolbarRootContext)(!0),L=(0,u.useSelectFloatingContext)(),D=(0,em.useDirection)(),{nonce:F,disableStyleElements:z}=(0,eg.useCSPContext)(),V=(0,a.useStore)(p,m.selectors.id),H=(0,a.useStore)(p,m.selectors.open),B=(0,a.useStore)(p,m.selectors.openMethod),U=(0,a.useStore)(p,m.selectors.mounted),W=(0,a.useStore)(p,m.selectors.popupProps),Y=(0,a.useStore)(p,m.selectors.transitionStatus),K=(0,a.useStore)(p,m.selectors.triggerElement),X=(0,a.useStore)(p,m.selectors.positionerElement),J=(0,a.useStore)(p,m.selectors.listElement),Z=r.useRef(!1),Q=r.useRef(!1),ee=r.useRef({}),es=(0,eo.useAnimationFrame)(),ev=(0,s.useStableCallback)(e=>{var t;if(!X||!f.current||!Q.current)return;if(Z.current||!k)return void E();let n="0px"===X.style.top,r="0px"===X.style.bottom;if(!n&&!r)return void E();let i=eS(X),s=(t=X.getBoundingClientRect().height,t/i.y),l=(0,o.ownerDocument)(X),a=(0,er.ownerWindow)(X),u=a.getComputedStyle(X),c=parseFloat(u.marginTop),d=parseFloat(u.marginBottom),p=ex(a.getComputedStyle(f.current)),g=Math.min(l.documentElement.clientHeight-c-d,p),m=e.scrollTop,h=eb(e),v=0,x=null,b=!1,S=!1,y=e=>{X.style.height=`${e}px`},R=n?h-m:m,C=Math.min(s+R,g);if(v=C,R<=ef.SCROLL_EDGE_TOLERANCE_PX){let t;return void((t=(0,ep.clamp)(R,0,g-s))>0&&y(s+t),e.scrollTop=n?h:0,g-(s+t)<=ef.SCROLL_EDGE_TOLERANCE_PX&&(Z.current=!0),E())}if(g-C>ef.SCROLL_EDGE_TOLERANCE_PX)n?S=!0:x=0;else if(b=!0,r&&mef.SCROLL_EDGE_TOLERANCE_PX&&(e.scrollTop=n)}(b||v>=g-ef.SCROLL_EDGE_TOLERANCE_PX)&&(Z.current=!0),E()});r.useImperativeHandle(w,()=>ev,[ev]),(0,ea.useOpenChangeComplete)({open:H,ref:f,onComplete(){H&&h?.(!0)}}),(0,_.useIsoLayoutEffect)(()=>{X&&f.current&&!Object.keys(ee.current).length&&(ee.current={top:X.style.top||"0",left:X.style.left||"0",right:X.style.right,height:X.style.height,bottom:X.style.bottom,minHeight:X.style.minHeight,maxHeight:X.style.maxHeight,marginTop:X.style.marginTop,marginBottom:X.style.marginBottom})},[f,X]),(0,_.useIsoLayoutEffect)(()=>{H||k||(Q.current=!1,Z.current=!1,$(X,ee.current))},[H,k,X,f]),(0,_.useIsoLayoutEffect)(()=>{let e=f.current;if(!H||!K||!X||!e||k&&!N||"ending"===p.state.transitionStatus)return;if(!k){Q.current=!0,es.request(E),e.style.removeProperty("--transform-origin");return}let t=function(e){let{style:t}=e,n={};for(let[e,r]of eR)n[e]=t.getPropertyValue(e),t.setProperty(e,r,"important");return()=>{for(let[e]of eR){let r=n[e];r?t.setProperty(e,r):t.removeProperty(e)}}}(e);e.style.removeProperty("--transform-origin");try{let t,n=S.current;n?.isConnected||(n=!m.selectors.hasSelectedValue(p.state)&&b.current?.isConnected?b.current:null);let r=x.current,i=(0,er.ownerWindow)(X),s=i.getComputedStyle(X),l=i.getComputedStyle(e),a=(0,o.ownerDocument)(K),u=eS(K),c=ey(K.getBoundingClientRect(),u),d=ey(X.getBoundingClientRect(),u),f=c.height,g=J||e,h=g.scrollHeight,v=parseFloat(l.borderBottomWidth),y=parseFloat(s.marginTop)||10,R=parseFloat(s.marginBottom)||10,C=parseFloat(s.minHeight)||100,w=ex(l),j=a.documentElement.clientHeight-y-R,T=a.documentElement.clientWidth,k=j-c.bottom+f,N="rtl"===D?c.right-d.width:c.left,A=0;if(n&&r){let e=ey(r.getBoundingClientRect(),u);t=ey(n.getBoundingClientRect(),u),N=d.left+("rtl"===D?e.right-t.right:e.left-t.left);let o=e.top-c.top+e.height/2;A=t.top-d.top+t.height/2-o}let O=k+A+R+v,L=Math.min(j,O),F=j-y-R,z=O-L;X.style.left=`${(0,ep.clamp)(N,5,T-5-d.width)}px`,X.style.height=`${L}px`,X.style.maxHeight="none",X.style.marginTop=`${y}px`,X.style.marginBottom=`${R}px`,e.style.height="100%";let _=eb(g),V=z>=_-ef.SCROLL_EDGE_TOLERANCE_PX;V&&(L=Math.min(j,d.height)-(z-_));let H=c.top<20||c.bottom>j-20||Math.ceil(L)+ef.SCROLL_EDGE_TOLERANCE_PX=F?"0":`${e}px`,X.style.height=`${L}px`,g.scrollTop=eb(g)}else X.style.bottom="0",g.scrollTop=z;if(t){let n=d.top,r=d.height,o=t.top+t.height/2,i=(0,ep.clamp)(r>0?(o-n)/r*100:50,0,100);e.style.setProperty("--transform-origin",`50% ${i}%`)}(U===j||L>=w)&&(Z.current=!0),E(),I&&null===p.state.selectedIndex&&null===p.state.activeIndex&&null!=M.current[0]&&p.set("activeIndex",0),Q.current=!0}finally{t()}},[p,H,X,K,x,b,S,f,E,k,P,es,J,M,I,D,N]),r.useEffect(()=>{if(!k||!X||!H)return;let e=(0,er.ownerWindow)(X);return(0,et.addEventListener)(e,"resize",function(e){v(!1,(0,y.createChangeEventDetails)(R.REASONS.windowResize,e))})},[v,k,X,H]);let eC={...J?{role:"presentation","aria-orientation":void 0}:{role:"listbox","aria-multiselectable":C||void 0,id:`${V}-list`},onKeyDown(e){O&&ec.COMPOSITE_KEYS.has(e.key)&&e.stopPropagation()},onScroll(e){J||ev(e.currentTarget)},...k&&{style:J?{height:"100%"}:q}},eE=(0,g.useRenderElement)("div",e,{ref:[t,f],state:{open:H,transitionStatus:Y,side:j,align:T},stateAttributesMapping:eh,props:[W,eC,(0,ed.getDisabledMountTransitionStyles)(Y),{className:!J&&k?el.styleDisableScrollbar.className:void 0},d]});return(0,A.jsxs)(r.Fragment,{children:[!z&&el.styleDisableScrollbar.getElement(F),(0,A.jsx)(ei.FloatingFocusManager,{context:L,modal:!1,disabled:!U,openInteractionType:B,returnFocus:c,restoreFocus:!0,children:eE})]})});function ex(e){let t=e.maxHeight||"";return t.endsWith("px")&&parseFloat(t)||1/0}function eb(e){return(0,ef.getMaxScrollOffset)(e.scrollHeight,e.clientHeight)}function eS(e){return es.platform.getScale(e)}function ey(e,t){return(0,ee.rectToClientRect)({x:e.x/t.x,y:e.y/t.y,width:e.width/t.x,height:e.height/t.y})}let eR=[["transform","none"],["scale","1"],["translate","0 0"]],eC=r.forwardRef(function(e,t){let{render:n,className:r,style:o,...i}=e,{store:l,scrollHandlerRef:c}=(0,u.useSelectRootContext)(),{alignItemWithTriggerActive:d}=G(),p=(0,a.useStore)(l,m.selectors.hasScrollArrows),f=(0,a.useStore)(l,m.selectors.openMethod),h=(0,a.useStore)(l,m.selectors.multiple),v=(0,a.useStore)(l,m.selectors.id),x={id:`${v}-list`,role:"listbox","aria-multiselectable":h||void 0,onScroll(e){c.current?.(e.currentTarget)},...d&&{style:q},className:p&&"touch"!==f?el.styleDisableScrollbar.className:void 0},b=(0,s.useStableCallback)(e=>{l.set("listElement",e)});return(0,g.useRenderElement)("div",e,{ref:[t,b],props:[x,i]})});var eE=e.i(673553);let ew=r.createContext(void 0);function eM(){let e=r.useContext(ew);if(!e)throw Error((0,B.default)(57));return e}var eI=e.i(157940);let ej=r.memo(r.forwardRef(function(e,t){let{render:n,className:o,style:i,value:s=null,label:l,disabled:c=!1,nativeButton:d=!1,...p}=e,f=r.useRef(null),h=(0,eE.useCompositeListItem)({label:l,textRef:f,indexGuessBehavior:eE.IndexGuessBehavior.GuessFromOrder}),{store:v,itemProps:x,setOpen:b,setValue:C,selectionRef:E,typingRef:w,valuesRef:M,multiple:I,selectedItemTextRef:j,disabled:T,readOnly:k}=(0,u.useSelectRootContext)(),N=(0,a.useStore)(v,m.selectors.isActive,h.index),P=(0,a.useStore)(v,m.selectors.open),O=(0,a.useStore)(v,m.selectors.isSelected,s),L=(0,a.useStore)(v,m.selectors.isSelectedByFocus,h.index),D=(0,a.useStore)(v,m.selectors.isItemEqualToValue),F=h.index,z=-1!==F,V=r.useRef(null);(0,_.useIsoLayoutEffect)(()=>{if(!z)return;let e=M.current;return e[F]=s,()=>{delete e[F]}},[z,F,s,M]),(0,_.useIsoLayoutEffect)(()=>{if(!z)return;let e=v.state.value,t=e;I&&Array.isArray(e)&&(t=e.length>0?e[e.length-1]:void 0),void 0!==t&&(0,K.compareItemEquality)(s,t,D)&&(v.set("selectedIndex",F),f.current&&(j.current=f.current))},[z,F,I,D,v,s,j]);let H=r.useRef(null),B=r.useRef("mouse"),U=r.useRef(!1),{getButtonProps:G,buttonRef:W}=(0,S.useButton)({disabled:c,focusableWhenDisabled:!0,native:d,composite:!0});function Y(){E.current.dragY=0}let $=(0,g.useRenderElement)("div",e,{ref:[W,t,h.ref,V],state:{disabled:c,selected:O,highlighted:N},props:[x,{role:"option","aria-selected":O,tabIndex:P&&N?0:-1,onKeyDown(e){H.current=e.key,v.set("activeIndex",F)," "===e.key&&w.current&&e.preventDefault()},onClick(e){let t="click"===e.type&&"touch"!==B.current,n=e.nativeEvent.pointerType,r=t&&(0,eI.isVirtualClick)(e.nativeEvent)&&(void 0!==n||N),o=t&&!r&&!U.current;U.current=!1,"keydown"===e.type&&null===H.current||c||"keydown"===e.type&&" "===H.current&&w.current||o||(H.current=null,function(e){if(T||k)return;let t=v.state.value;if(I){let n=Array.isArray(t)?t:[];C(O?(0,K.removeItem)(n,s,D):[...n,s],(0,y.createChangeEventDetails)(R.REASONS.itemPress,e))}else C(s,(0,y.createChangeEventDetails)(R.REASONS.itemPress,e)),b(!1,(0,y.createChangeEventDetails)(R.REASONS.itemPress,e))}(e.nativeEvent))},onPointerEnter(e){B.current=e.pointerType},onPointerMove(e){if("mouse"===e.pointerType&&1===e.buttons){let t=E.current;t.dragY+=e.movementY,t.dragY**2>=64&&(t.allowUnselectedMouseUp=!0)}},onPointerDown(e){B.current=e.pointerType,U.current=!0,Y()},onMouseUp(){if(Y(),c||"touch"===B.current||U.current)return;let e=!E.current.allowSelectedMouseUp&&O,t=!E.current.allowUnselectedMouseUp&&!O;e||t||(U.current=!0,V.current?.click(),U.current=!1)}},p,G]}),q=r.useMemo(()=>({selected:O,index:F,textRef:f,selectedByFocus:L,hasRegistered:z}),[O,F,f,L,z]);return(0,A.jsx)(ew.Provider,{value:q,children:$})}));var eT=e.i(223910);let ek=r.forwardRef(function(e,t){let n=e.keepMounted??!1,{selected:r}=eM();return n||r?(0,A.jsx)(eN,{...e,ref:t}):null}),eN=r.memo(r.forwardRef((e,t)=>{let{render:n,className:o,style:i,keepMounted:s,...l}=e,{selected:a}=eM(),u=r.useRef(null),{transitionStatus:c,setMounted:d}=(0,eT.useTransitionStatus)(a),p=(0,g.useRenderElement)("span",e,{ref:[t,u],state:{selected:a,transitionStatus:c},props:[{"aria-hidden":!0,children:"✔️"},l],stateAttributesMapping:L.transitionStatusMapping});return(0,ea.useOpenChangeComplete)({open:a,ref:u,onComplete(){a||d(!1)}}),p})),eP=r.memo(r.forwardRef(function(e,t){let{index:n,textRef:o,selectedByFocus:i,hasRegistered:s}=eM(),{firstItemTextRef:l,selectedItemTextRef:a}=(0,u.useSelectRootContext)(),{render:c,className:d,style:p,...f}=e,m=r.useCallback(e=>{e&&(s&&0===n&&(l.current=e),s&&i&&(a.current=e))},[l,a,n,i,s]);return(0,g.useRenderElement)("div",e,{ref:[m,t,o],props:f})})),eA={...p.popupStateMapping,...L.transitionStatusMapping},eO=r.forwardRef(function(e,t){let{render:n,className:r,style:o,...i}=e,{store:s}=(0,u.useSelectRootContext)(),{side:l,align:c,arrowRef:d,arrowStyles:p,arrowUncentered:f,alignItemWithTriggerActive:h}=G(),v=(0,a.useStore)(s,m.selectors.open),x=(0,g.useRenderElement)("div",e,{state:{open:v,side:l,align:c,uncentered:f},ref:[d,t],props:[{style:p,"aria-hidden":!0},i],stateAttributesMapping:eA});return h?null:x}),eL=r.forwardRef(function(e,t){let{render:n,className:r,style:o,direction:s,keepMounted:l=!1,...c}=e,d="up"===s,{store:p,popupRef:f,listRef:h,handleScrollArrowVisibility:v,scrollArrowsMountedCountRef:x}=(0,u.useSelectRootContext)(),{side:b,scrollDownArrowRef:S,scrollUpArrowRef:y}=G(),R=d?m.selectors.scrollUpArrowVisible:m.selectors.scrollDownArrowVisible,C=(0,a.useStore)(p,R),E=(0,a.useStore)(p,m.selectors.openMethod),w=C&&"touch"!==E,M=(0,i.useTimeout)(),I=d?y:S,{mounted:j,transitionStatus:T,setMounted:k}=(0,eT.useTransitionStatus)(w);(0,_.useIsoLayoutEffect)(()=>(x.current+=1,p.state.hasScrollArrows||p.set("hasScrollArrows",!0),()=>{x.current=Math.max(0,x.current-1),0===x.current&&p.state.hasScrollArrows&&p.set("hasScrollArrows",!1)}),[p,x]),(0,ea.useOpenChangeComplete)({open:w,ref:I,onComplete(){w||k(!1)}});let N=(0,g.useRenderElement)("div",e,{ref:[t,I],state:{direction:s,visible:w,side:b,transitionStatus:T},props:[{"aria-hidden":!0,children:d?"▲":"▼",style:{position:"absolute"},onMouseMove(e){0===e.movementX&&0===e.movementY||M.isStarted()||(p.set("activeIndex",null),M.start(40,function e(){let t=p.state.listElement??f.current;if(!t)return;p.set("activeIndex",null),v();let n=(0,ef.getMaxScrollOffset)(t.scrollHeight,t.clientHeight),r=(0,ef.normalizeScrollOffset)(t.scrollTop,n),o=r===(d?0:n),i=h.current;if(r!==t.scrollTop&&(t.scrollTop=r),0===i.length&&p.set(d?"scrollUpArrowVisible":"scrollDownArrowVisible",!o),o)return void M.clear();if(i.length>0){let e=I.current?.offsetHeight||0;t.scrollTop=function(e,t,n,r,o,i){if(t){let t=0,r=n+o-ef.SCROLL_EDGE_TOLERANCE_PX;for(let n=0;n=r){t=n;break}}let s=Math.max(0,t-1),l=e[s];return sl){s=Math.max(0,t-1);break}}let a=Math.min(e.length-1,s+1),u=e[a];return a>s&&u?(0,ef.normalizeScrollOffset)(u.offsetTop+u.offsetHeight-r+o,i):i}(i,d,r,t.clientHeight,e,n)}M.start(40,e)}))},onMouseLeave(){M.clear()}},c],stateAttributesMapping:L.transitionStatusMapping});return j||l?N:null}),eD=r.forwardRef(function(e,t){return(0,A.jsx)(eL,{...e,ref:t,direction:"down"})}),eF=r.forwardRef(function(e,t){return(0,A.jsx)(eL,{...e,ref:t,direction:"up"})}),ez=r.createContext(void 0),e_=r.forwardRef(function(e,t){let{render:n,className:o,style:i,...s}=e,[l,a]=r.useState(),u=r.useMemo(()=>({labelId:l,setLabelId:a}),[l,a]),c=(0,g.useRenderElement)("div",e,{ref:t,props:[{role:"group","aria-labelledby":l},s]});return(0,A.jsx)(ez.Provider,{value:u,children:c})});var eV=e.i(788015);let eH=r.forwardRef(function(e,t){let{render:n,className:o,style:i,id:s,...l}=e,{setLabelId:a}=function(){let e=r.useContext(ez);if(void 0===e)throw Error((0,B.default)(56));return e}(),u=(0,eV.useBaseUiId)(s);return(0,_.useIsoLayoutEffect)(()=>{a(u)},[u,a]),(0,g.useRenderElement)("div",e,{ref:t,props:[{id:u},l]})});var eB=e.i(652225);e.s(["Arrow",0,eO,"Backdrop",0,F,"Group",0,e_,"GroupLabel",0,eH,"Icon",0,k,"Item",0,ej,"ItemIndicator",0,ek,"ItemText",0,eP,"Label",()=>n.SelectLabel,"List",0,eC,"Popup",0,ev,"Portal",0,O,"Positioner",0,Q,"Root",()=>t.SelectRoot,"ScrollDownArrow",0,eD,"ScrollUpArrow",0,eF,"Separator",()=>eB.Separator,"Trigger",0,M,"Value",0,T],574786);var eU=e.i(574786);e.s(["Select",0,eU],83955)},807235,967489,152370,981080,649582,e=>{"use strict";var t=e.i(843476),n=e.i(152990),r=e.i(682830),o=e.i(886407),i=e.i(271645),s=e.i(302747),l=e.i(784774),a=e.i(115504),u=e.i(373375),c=e.i(463059),d=e.i(319897),p=e.i(531026),f=e.i(519455),g=e.i(83955),m=e.i(409797),h=e.i(678784),v=e.i(54131);let x=g.Select.Root;function b({className:e,...n}){return(0,t.jsx)(g.Select.Value,{"data-slot":"select-value",className:(0,a.cn)("flex flex-1 text-left",e),...n})}function S({className:e,size:n="default",children:r,...o}){return(0,t.jsxs)(g.Select.Trigger,{"data-slot":"select-trigger","data-size":n,className:(0,a.cn)("flex w-fit items-center justify-between gap-1.5 rounded-md border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",e),...o,children:[r,(0,t.jsx)(g.Select.Icon,{render:(0,t.jsx)(m.ChevronDownIcon,{className:"pointer-events-none size-4 text-muted-foreground"})})]})}function y({className:e,children:n,side:r="bottom",sideOffset:o=4,align:i="center",alignOffset:s=0,alignItemWithTrigger:l=!0,...u}){return(0,t.jsx)(g.Select.Portal,{children:(0,t.jsx)(g.Select.Positioner,{side:r,sideOffset:o,align:i,alignOffset:s,alignItemWithTrigger:l,className:"isolate z-50",children:(0,t.jsxs)(g.Select.Popup,{"data-slot":"select-content","data-align-trigger":l,className:(0,a.cn)("relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",e),...u,children:[(0,t.jsx)(C,{}),(0,t.jsx)(g.Select.List,{children:n}),(0,t.jsx)(E,{})]})})})}function R({className:e,children:n,...r}){return(0,t.jsxs)(g.Select.Item,{"data-slot":"select-item",className:(0,a.cn)("relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",e),...r,children:[(0,t.jsx)(g.Select.ItemText,{className:"flex flex-1 shrink-0 gap-2 whitespace-nowrap",children:n}),(0,t.jsx)(g.Select.ItemIndicator,{render:(0,t.jsx)("span",{className:"pointer-events-none absolute right-2 flex size-4 items-center justify-center"}),children:(0,t.jsx)(h.CheckIcon,{className:"pointer-events-none"})})]})}function C({className:e,...n}){return(0,t.jsx)(g.Select.ScrollUpArrow,{"data-slot":"select-scroll-up-button",className:(0,a.cn)("top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",e),...n,children:(0,t.jsx)(v.ChevronUpIcon,{})})}function E({className:e,...n}){return(0,t.jsx)(g.Select.ScrollDownArrow,{"data-slot":"select-scroll-down-button",className:(0,a.cn)("bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",e),...n,children:(0,t.jsx)(m.ChevronDownIcon,{})})}e.s(["Select",0,x,"SelectContent",0,y,"SelectItem",0,R,"SelectTrigger",0,S,"SelectValue",0,b],967489);let w=[25,50,100];function M({page:e,pageSize:n,rowCount:r,onPageChange:o,onPageSizeChange:i,pageSizeOptions:s=w,isLoading:l=!1,className:g}){let m=n>0?Math.ceil(r/n):0,h=Math.min((e+1)*n,r),v=e>0&&!l,C=e{"string"==typeof e&&i(Number(e))},children:[(0,t.jsx)(S,{size:"sm","data-testid":"pagination-page-size",className:"w-[4.5rem]",children:(0,t.jsx)(b,{})}),(0,t.jsx)(y,{children:s.map(e=>(0,t.jsx)(R,{value:String(e),children:e},e))})]})]}),(0,t.jsxs)("div",{className:"flex items-center gap-4",children:[(0,t.jsx)("span",{"data-testid":"pagination-range",className:"text-sm text-muted-foreground tabular-nums",children:0===r?"No results":`Showing ${0===r?0:e*n+1}-${h} of ${r}`}),(0,t.jsxs)("span",{"data-testid":"pagination-page",className:"text-sm text-muted-foreground tabular-nums",children:["Page ",e+1," of ",Math.max(m,1)]}),(0,t.jsxs)("div",{className:"flex items-center gap-1",children:[(0,t.jsx)(f.Button,{variant:"outline",size:"icon-sm","data-testid":"pagination-first","aria-label":"Go to first page",disabled:!v,onClick:()=>o(0),children:(0,t.jsx)(d.ChevronsLeft,{})}),(0,t.jsx)(f.Button,{variant:"outline",size:"icon-sm","data-testid":"pagination-prev","aria-label":"Go to previous page",disabled:!v,onClick:()=>o(e-1),children:(0,t.jsx)(u.ChevronLeft,{})}),(0,t.jsx)(f.Button,{variant:"outline",size:"icon-sm","data-testid":"pagination-next","aria-label":"Go to next page",disabled:!C,onClick:()=>o(e+1),children:(0,t.jsx)(c.ChevronRight,{})}),(0,t.jsx)(f.Button,{variant:"outline",size:"icon-sm","data-testid":"pagination-last","aria-label":"Go to last page",disabled:!C,onClick:()=>o(E),children:(0,t.jsx)(p.ChevronsRight,{})})]})]})]})}e.s(["DEFAULT_PAGE_SIZE_OPTIONS",0,w,"DataTablePagination",0,M],152370);let I=()=>{};class j extends Error{constructor(e){super(`DataTable misconfiguration: -- ${e.join("\n- ")}`),this.name="DataTableConfigError"}}function T(e){return"id"in e&&"string"==typeof e.id?e.id:"accessorKey"in e&&null!=e.accessorKey?String(e.accessorKey):void 0}function k(e,t,n){let r=e.getIsPinned(),o=t&&n;if(!r&&!o)return{style:{},className:""};let i="left"===r?e.getStart("left"):void 0,s="right"===r?e.getAfter("right"):void 0;return{style:{position:"sticky",zIndex:!1!==r&&t?30:t?20:10,...o?{top:0}:{},...void 0!==i?{left:i}:{},...void 0!==s?{right:s}:{}},className:(0,a.cn)(r?"bg-background":"","left"===r?"shadow-[inset_-1px_0_0_var(--color-border)]":"right"===r?"shadow-[inset_1px_0_0_var(--color-border)]":"")}}function N(e,t){if(t||void 0!==e.columnDef.size)return{width:e.getSize()}}function P({header:e,size:r,stickyHeader:o,enableColumnResizing:i}){let{column:s}=e,u=s.columnDef.meta,c=k(s,!0,o),d=i&&s.getCanResize();return(0,t.jsxs)(l.TableHead,{"data-header-id":e.id,className:(0,a.cn)("relative text-muted-foreground","compact"===r?"h-8 px-2 py-1 text-xs":"",u?.numeric?"text-right":"",u?.className,u?.headerClassName,c.className),style:{...c.style,...N(s,i)},children:[e.isPlaceholder?null:(0,t.jsx)("div",{className:(0,a.cn)("flex items-center gap-1",u?.numeric?"justify-end":""),children:(0,n.flexRender)(s.columnDef.header,e.getContext())}),d&&(0,t.jsx)("div",{"data-resizer":!0,"data-header-id":e.id,onMouseDown:e.getResizeHandler(),onTouchStart:e.getResizeHandler(),onDoubleClick:()=>s.resetSize(),className:(0,a.cn)("absolute top-0 right-0 h-full w-1 cursor-col-resize touch-none select-none hover:bg-border",s.getIsResizing()?"bg-primary":"")})]})}function A({cell:e,size:r,stickyHeader:o,enableColumnResizing:i}){let{column:s}=e,u=s.columnDef.meta,c=k(s,!1,o);return(0,t.jsx)(l.TableCell,{className:(0,a.cn)("overflow-hidden text-ellipsis","compact"===r?"px-2 py-1 text-xs":"",u?.numeric?"text-right tabular-nums":"",u?.className,c.className),style:{...c.style,...N(s,i)},children:(0,n.flexRender)(s.columnDef.cell,e.getContext())})}function O({row:e,size:n,stickyHeader:r,enableColumnResizing:o,onRowClick:s,rowClassName:u,renderSubComponent:c}){let d=void 0!==s,p=e.getVisibleCells();return(0,t.jsxs)(i.Fragment,{children:[(0,t.jsx)(l.TableRow,{"data-row-id":e.id,className:(0,a.cn)(d?"cursor-pointer":"","compact"===n?"h-8":"",u?.(e)),onClick:d?t=>{if(void 0===s)return;let n=t.target;null!==n&&t.currentTarget.contains(n)&&null===n.closest("button, a, input, select, textarea, [role=checkbox], [data-row-click-exempt]")&&s(e.original)}:void 0,children:p.map(e=>(0,t.jsx)(A,{cell:e,size:n,stickyHeader:r,enableColumnResizing:o},e.id))}),void 0!==c&&e.getIsExpanded()&&(0,t.jsx)(l.TableRow,{className:"hover:bg-transparent",children:(0,t.jsx)(l.TableCell,{colSpan:p.length,className:"p-0",children:c({row:e})})})]})}function L({colSpan:e,children:n}){return(0,t.jsx)(l.TableRow,{className:"hover:bg-transparent",children:(0,t.jsx)(l.TableCell,{colSpan:e,className:"h-24 text-center align-middle text-sm text-muted-foreground",children:n})})}function D(){return(0,t.jsxs)("div",{className:"flex flex-col items-center gap-1 py-6",children:[(0,t.jsx)("div",{className:"mb-1 flex size-10 items-center justify-center rounded-lg bg-muted",children:(0,t.jsx)(o.SearchX,{className:"size-5 text-muted-foreground"})}),(0,t.jsx)("div",{className:"text-sm font-medium text-foreground",children:"No results"}),(0,t.jsx)("div",{className:"text-sm text-muted-foreground",children:"No rows match your search or filters."})]})}let F=["w-[58%]","w-[44%]","w-[70%]","w-[50%]","w-[64%]","w-[48%]"];function z({column:e,index:n}){let r=e?.columnDef.meta,o=F[n%F.length],i=r?.skeleton;return r?.renderSkeleton!==void 0?(0,t.jsx)(t.Fragment,{children:r.renderSkeleton()}):"twoLine"===i?(0,t.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,t.jsx)(s.Skeleton,{className:(0,a.cn)("h-3.5",o)}),(0,t.jsx)(s.Skeleton,{className:"h-2.5 w-2/5 opacity-65"})]}):"badge"===i?(0,t.jsx)(s.Skeleton,{className:(0,a.cn)("h-5 w-16 rounded-full",r?.numeric?"ml-auto":"")}):"chips"===i?(0,t.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,t.jsx)(s.Skeleton,{className:"h-5 w-14 rounded-full"}),(0,t.jsx)(s.Skeleton,{className:"h-5 w-20 rounded-full"}),(0,t.jsx)(s.Skeleton,{className:"h-5 w-9 rounded-full opacity-65"})]}):"meter"===i?(0,t.jsxs)("div",{className:"flex flex-col gap-1.5",children:[(0,t.jsx)(s.Skeleton,{className:"h-3.5 w-24"}),(0,t.jsx)(s.Skeleton,{className:"h-1.5 w-full rounded-full"})]}):(0,t.jsx)(s.Skeleton,{className:(0,a.cn)("h-3.5",o,r?.numeric?"ml-auto":"")})}function _({rowCount:e,columns:n,size:r,message:o}){let s=Array.from({length:Math.max(e,1)},(e,t)=>t),u=n.length>0?n:[void 0];return(0,t.jsx)(i.Fragment,{children:s.map(e=>(0,t.jsx)(l.TableRow,{className:(0,a.cn)("hover:bg-transparent","compact"===r?"h-8":""),"data-testid":"skeleton-row",children:u.map((n,i)=>(0,t.jsxs)(l.TableCell,{className:"compact"===r?"px-2 py-1":"",children:[(0,t.jsx)(z,{column:n,index:i}),0===e&&0===i&&void 0!==o?(0,t.jsx)("span",{className:"sr-only",children:o}):null]},n?.id??i))},`skeleton-${e}`))})}function V(e,t,n){let[r,o]=(0,i.useState)(n);return void 0!==e?{value:e,onChange:t??I}:{value:r,onChange:o}}e.s(["DataTable",0,function(e){(0,i.useState)(()=>{let t,n,r,o,i=(t="server"===e.sortingMode&&(void 0===e.sorting||void 0===e.onSortingChange),n=void 0===e.pagination||void 0===e.onPaginationChange||void 0===e.rowCount,r="server"===e.paginationMode&&n,o="server"===e.filterMode&&(void 0===e.columnFilters||void 0===e.onColumnFiltersChange),[t?"sortingMode='server' requires both `sorting` and `onSortingChange`.":null,r?"paginationMode='server' requires `pagination`, `onPaginationChange`, and `rowCount`.":null,o?"filterMode='server' requires both `columnFilters` and `onColumnFiltersChange`.":null,void 0!==e.defaultSorting&&void 0!==e.sorting?"Provide either `defaultSorting` (uncontrolled) or `sorting` (controlled), not both.":null,void 0!==e.defaultColumnFilters&&void 0!==e.columnFilters?"Provide either `defaultColumnFilters` (uncontrolled) or `columnFilters` (controlled), not both.":null].filter(e=>null!==e));if(i.length>0)throw new j(i);return null});let{isLoading:o=!1,loadingMessage:s="Loading…",skeletonRowCount:a=8,noDataMessage:u,paginationMode:c="none",rowCount:d,pageSizeOptions:p=w,enableColumnResizing:f=!1,onRowClick:g,rowClassName:m,renderSubComponent:h,maxBodyHeight:v,size:x="default",toolbar:b,paginationSlot:S,footer:y}=e,R=function(e){var t;let{data:o,columns:s,getRowId:l,sortingMode:a="none",sorting:u,onSortingChange:c,defaultSorting:d,enableSortingRemoval:p=!1,paginationMode:f="none",pagination:g,onPaginationChange:m,rowCount:h,pageSizeOptions:v=w,filterMode:x="none",columnFilters:b,onColumnFiltersChange:S,defaultColumnFilters:y,globalFilter:R,onGlobalFilterChange:C,enableColumnResizing:E=!1,columnResizeMode:M="onEnd",defaultColumnVisibility:I,getRowCanExpand:j,renderSubComponent:k,expanded:N,onExpandedChange:P}=e,A=V(u,c,d??[]),O=V(g,m,{pageIndex:0,pageSize:v[0]??25}),L=V(b,S,y??[]),D=V(R,C,""),F=V(N,P,{}),[z,_]=(0,i.useState)(I??{}),[H,B]=(0,i.useState)({}),U=i.useMemo(()=>{let e;return{left:(e=e=>s.filter(t=>t.meta?.pinned===e).map(T).filter(e=>void 0!==e))("left"),right:e("right")}},[s]),G={data:o,columns:s,state:{sorting:A.value,pagination:O.value,columnFilters:L.value,globalFilter:D.value,expanded:F.value,columnVisibility:z,columnSizing:H},initialState:{columnPinning:U},manualSorting:"server"===a,manualPagination:"server"===f,manualFiltering:"server"===x,enableSortingRemoval:p,enableColumnResizing:E,columnResizeMode:M,onSortingChange:A.onChange,onPaginationChange:O.onChange,onColumnFiltersChange:L.onChange,onGlobalFilterChange:D.onChange,onExpandedChange:F.onChange,onColumnVisibilityChange:_,onColumnSizingChange:B,getCoreRowModel:(0,r.getCoreRowModel)(),...(t=void 0!==k?j:void 0,{..."client"===x?{getFilteredRowModel:(0,r.getFilteredRowModel)()}:{},..."client"===a?{getSortedRowModel:(0,r.getSortedRowModel)()}:{},..."client"===f?{getPaginationRowModel:(0,r.getPaginationRowModel)()}:{},...void 0!==t?{getRowCanExpand:t,getExpandedRowModel:(0,r.getExpandedRowModel)()}:{}}),...void 0!==l?{getRowId:l}:{},..."server"===f&&void 0!==h?{rowCount:h}:{}};return(0,n.useReactTable)(G)}(e),C=R.getRowModel().rows,E=R.getVisibleLeafColumns().length,I=void 0!==v,k=f?{width:R.getTotalSize(),minWidth:"100%"}:void 0,N=(()=>{if(void 0!==S)return S(R);if("none"===c)return null;let e=R.getState().pagination,n="server"===c?d??0:R.getPrePaginationRowModel().rows.length;return(0,t.jsx)(M,{page:e.pageIndex,pageSize:e.pageSize,rowCount:n,onPageChange:e=>R.setPageIndex(e),onPageSizeChange:e=>R.setPageSize(e),pageSizeOptions:p,isLoading:o})})();return(0,t.jsx)("div",{className:"w-full",children:(0,t.jsxs)("div",{className:"overflow-hidden rounded-lg border border-border",children:[void 0!==b&&(0,t.jsx)("div",{className:"border-b border-border px-4 py-3",children:b(R)}),(0,t.jsx)("div",{className:I?"overflow-auto":"overflow-x-auto",style:I?{maxHeight:v}:void 0,children:(0,t.jsxs)(l.Table,{className:f?"table-fixed":"",style:k,children:[(0,t.jsx)(l.TableHeader,{className:I?"sticky top-0 z-20":"",children:R.getHeaderGroups().map(e=>(0,t.jsx)(l.TableRow,{className:"bg-muted/50 hover:bg-muted/50",children:e.headers.map(e=>(0,t.jsx)(P,{header:e,size:x,stickyHeader:I,enableColumnResizing:f},e.id))},e.id))}),(0,t.jsx)(l.TableBody,{children:o?(0,t.jsx)(_,{rowCount:a,columns:R.getVisibleLeafColumns(),size:x,message:s}):0===C.length?(0,t.jsx)(L,{colSpan:E,children:u??(0,t.jsx)(D,{})}):C.map(e=>(0,t.jsx)(O,{row:e,size:x,stickyHeader:I,enableColumnResizing:f,onRowClick:g,rowClassName:m,renderSubComponent:h},e.id))}),void 0!==y&&(0,t.jsx)(l.TableFooter,{children:y(R)})]})}),null!==N&&(0,t.jsx)("div",{className:"border-t border-border",children:N})]})})}],807235);var H=e.i(110204),B=e.i(353753),U=e.i(995926);function G({...e}){return(0,t.jsx)(B.Dialog.Root,{"data-slot":"sheet",...e})}function W({...e}){return(0,t.jsx)(B.Dialog.Portal,{"data-slot":"sheet-portal",...e})}function Y({className:e,...n}){return(0,t.jsx)(B.Dialog.Backdrop,{"data-slot":"sheet-overlay",className:(0,a.cn)("fixed inset-0 z-50 bg-black/10 transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0 supports-backdrop-filter:backdrop-blur-xs",e),...n})}function $({className:e,children:n,side:r="right",showCloseButton:o=!0,...i}){return(0,t.jsxs)(W,{children:[(0,t.jsx)(Y,{}),(0,t.jsxs)(B.Dialog.Popup,{"data-slot":"sheet-content","data-side":r,className:(0,a.cn)("fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=right]:data-ending-style:translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem] data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm",e),...i,children:[n,o&&(0,t.jsxs)(B.Dialog.Close,{"data-slot":"sheet-close",render:(0,t.jsx)(f.Button,{variant:"ghost",className:"absolute top-4 right-4",size:"icon-sm"}),children:[(0,t.jsx)(U.XIcon,{}),(0,t.jsx)("span",{className:"sr-only",children:"Close"})]})]})]})}function q({className:e,...n}){return(0,t.jsx)("div",{"data-slot":"sheet-header",className:(0,a.cn)("flex flex-col gap-1.5 p-4",e),...n})}function K({className:e,...n}){return(0,t.jsx)("div",{"data-slot":"sheet-footer",className:(0,a.cn)("mt-auto flex flex-col gap-2 p-4",e),...n})}function X({className:e,...n}){return(0,t.jsx)(B.Dialog.Title,{"data-slot":"sheet-title",className:(0,a.cn)("font-medium text-foreground",e),...n})}function J({className:e,...n}){return(0,t.jsx)(B.Dialog.Description,{"data-slot":"sheet-description",className:(0,a.cn)("text-sm text-muted-foreground",e),...n})}function Z(e){return Object.fromEntries(e.map(e=>[e.id,e.value]))}e.s(["DataTableFilterDrawer",0,function({table:e,open:n,onOpenChange:r,title:o="Filters",description:s,applyLabel:l="Apply Filters",resetLabel:a="Reset",children:u}){let[c,d]=i.useState(()=>Z(e.getState().columnFilters)),[p,g]=i.useState(n);return n!==p&&(g(n),n&&d(Z(e.getState().columnFilters))),(0,t.jsx)(G,{open:n,onOpenChange:r,children:(0,t.jsxs)($,{side:"right",children:[(0,t.jsxs)(q,{children:[(0,t.jsx)(X,{children:o}),void 0!==s&&(0,t.jsx)(J,{children:s})]}),(0,t.jsx)("div",{className:"flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto p-4","data-testid":"filter-drawer-body",children:u({get:e=>c[e],set:(e,t)=>d(n=>({...n,[e]:t}))})}),(0,t.jsxs)(K,{className:"flex-row",children:[(0,t.jsx)(f.Button,{variant:"outline",className:"flex-1",onClick:()=>{d({}),e.setColumnFilters([])},"data-testid":"filter-drawer-reset",children:a}),(0,t.jsx)(f.Button,{className:"flex-1",onClick:()=>{e.setColumnFilters(Object.entries(c).filter(([,e])=>!(Array.isArray(e)?0===e.length:null==e||""===e)).map(([e,t])=>({id:e,value:t}))),r(!1)},"data-testid":"filter-drawer-apply",children:l})]})]})})},"DataTableFilterField",0,function({label:e,children:n}){return(0,t.jsxs)("div",{className:"flex flex-col gap-1.5",children:[(0,t.jsx)(H.Label,{children:e}),n]})}],981080);let Q=(0,e.i(475254).default)("sliders-horizontal",[["line",{x1:"21",x2:"14",y1:"4",y2:"4",key:"obuewd"}],["line",{x1:"10",x2:"3",y1:"4",y2:"4",key:"1q6298"}],["line",{x1:"21",x2:"12",y1:"12",y2:"12",key:"1iu8h1"}],["line",{x1:"8",x2:"3",y1:"12",y2:"12",key:"ntss68"}],["line",{x1:"21",x2:"16",y1:"20",y2:"20",key:"14d8ph"}],["line",{x1:"12",x2:"3",y1:"20",y2:"20",key:"m0wm8r"}],["line",{x1:"14",x2:"14",y1:"2",y2:"6",key:"14e1ph"}],["line",{x1:"8",x2:"8",y1:"10",y2:"14",key:"1i6ji0"}],["line",{x1:"16",x2:"16",y1:"18",y2:"22",key:"1lctlv"}]]);e.s(["SlidersHorizontal",0,Q],649582)},261027,803414,978921,382370,239613,389554,866506,685996,371714,181194,801545,91384,858307,764270,219712,82264,862050,282593,105953,e=>{"use strict";e.s([],261027),e.i(247167);var t,n=e.i(271645),r=e.i(733332);let o=n.createContext(void 0);function i(e){let t=n.useContext(o);if(void 0===t&&!e)throw Error((0,r.default)(33));return t}e.s(["MenuPositionerContext",0,o,"useMenuPositionerContext",0,i],803414);let s=n.createContext(void 0);function l(e){let t=n.useContext(s);if(void 0===t&&!e)throw Error((0,r.default)(36));return t}e.s(["MenuRootContext",0,s,"useMenuRootContext",0,l],978921);var a=e.i(552245),u=e.i(405005);let c=n.forwardRef(function(e,t){let{render:n,className:r,style:o,...s}=e,{store:c}=l(),{arrowRef:d,side:p,align:f,arrowUncentered:g,arrowStyles:m}=i(),h=c.useState("open");return(0,a.useRenderElement)("div",e,{ref:[d,t],stateAttributesMapping:u.popupStateMapping,state:{open:h,side:p,align:f,uncentered:g},props:{style:m,"aria-hidden":!0,...s}})});e.s(["MenuArrow",0,c],382370);var d=e.i(209407);let p=n.createContext(void 0);function f(e=!0){let t=n.useContext(p);if(void 0===t&&!e)throw Error((0,r.default)(25));return t}e.s(["useContextMenuRootContext",0,f],239613);var g=e.i(56434);let m={...u.popupStateMapping,...d.transitionStatusMapping},h=n.forwardRef(function(e,t){let{render:n,className:r,style:o,...i}=e,{store:s}=l(),u=s.useState("open"),c=s.useState("mounted"),d=s.useState("transitionStatus"),p=s.useState("lastOpenChangeReason"),h=f();return(0,a.useRenderElement)("div",e,{ref:h?.backdropRef?[t,h.backdropRef]:t,state:{open:u,transitionStatus:d},stateAttributesMapping:m,props:[{role:"presentation",hidden:!c,style:{pointerEvents:p===g.REASONS.triggerHover?"none":void 0,userSelect:"none",WebkitUserSelect:"none"}},i]})});e.s(["MenuBackdrop",0,h],389554);var v=e.i(951437);let x=n.createContext(void 0);var b=e.i(828918),S=e.i(540886),y=e.i(176782),R=e.i(328744);function C(e){let{closeOnClick:t,highlighted:r,id:o,nodeId:i,store:s,typingRef:l,itemRef:a,itemMetadata:u}=e,{events:c}=s.useState("floatingTreeRoot"),d=s.useState("open"),p=f(!0),m=void 0!==p;return n.useMemo(()=>({id:o,role:"menuitem",tabIndex:d&&r?0:-1,onKeyDown(e){" "===e.key&&l?.current&&e.preventDefault()},onMouseMove(e){i&&c.emit("itemhover",{nodeId:i,target:e.currentTarget})},onClick(e){t&&c.emit("close",{domEvent:e,reason:g.REASONS.itemPress})},onMouseUp(e){if(p){let t=p.initialCursorPointRef.current;if(p.initialCursorPointRef.current=null,m&&t&&1>=Math.abs(e.clientX-t.x)&&1>=Math.abs(e.clientY-t.y)||m&&!R.platform.os.mac&&2===e.button)return}a.current&&s.context.allowMouseUpTriggerRef.current&&(!m||2===e.button)&&(!u||"regular-item"===u.type)&&a.current.click()}}),[t,r,o,c,i,d,s,l,a,p,m,u])}let E={type:"regular-item"};function w(e){let{closeOnClick:t,disabled:r=!1,highlighted:o,id:i,store:s,typingRef:l=s.context.typingRef,nativeButton:a,itemMetadata:u,nodeId:c}=e,d=s.useState("disabled"),p=n.useRef(null),{getButtonProps:f,buttonRef:g}=(0,S.useButton)({disabled:r||d,focusableWhenDisabled:!0,native:a,composite:!0}),m=C({closeOnClick:t,highlighted:o,id:i,nodeId:c,store:s,typingRef:l,itemRef:p,itemMetadata:u}),h=n.useCallback(e=>(0,y.mergeProps)(m,{onMouseEnter(){"submenu-trigger"===u.type&&u.setActive()}},e,f),[m,f,u]),v=(0,b.useMergedRefs)(p,g);return n.useMemo(()=>({getItemProps:h,itemRef:v}),[h,v])}e.s(["REGULAR_ITEM",0,E,"useMenuItem",0,w],866506);var M=e.i(673553),I=e.i(788015);let j=((t={}).checked="data-checked",t.unchecked="data-unchecked",t.disabled="data-disabled",t.highlighted="data-highlighted",t),T={checked:e=>e?{[j.checked]:""}:{[j.unchecked]:""},...d.transitionStatusMapping};var k=e.i(675606),N=e.i(843476);let P=n.forwardRef(function(e,t){let{render:r,className:o,id:s,label:u,nativeButton:c=!1,disabled:d=!1,closeOnClick:p=!1,checked:f,defaultChecked:m,onCheckedChange:h,style:b,...S}=e,y=(0,M.useCompositeListItem)({label:u}),R=i(!0),C=(0,I.useBaseUiId)(s),{store:j}=l(),P=j.useState("isActive",y.index),A=j.useState("itemProps"),[O,L]=(0,v.useControlled)({controlled:f,default:m??!1,name:"MenuCheckboxItem",state:"checked"}),{getItemProps:D,itemRef:F}=w({closeOnClick:p,disabled:d,highlighted:P,id:C,store:j,nativeButton:c,nodeId:R?.context.nodeId,itemMetadata:E}),z=n.useMemo(()=>({disabled:d,highlighted:P,checked:O}),[d,P,O]),_=(0,a.useRenderElement)("div",e,{state:z,stateAttributesMapping:T,props:[A,{role:"menuitemcheckbox","aria-checked":O,onClick:function(e){let t=(0,k.createChangeEventDetails)(g.REASONS.itemPress,e.nativeEvent,void 0,{preventUnmountOnClose(){}});h?.(!O,t),t.isCanceled||L(e=>!e)}},S,D],ref:[F,t,y.ref]});return(0,N.jsx)(x.Provider,{value:z,children:_})});e.s(["MenuCheckboxItem",0,P],685996);var A=e.i(223910),O=e.i(137584);let L=n.forwardRef(function(e,t){let{render:o,className:i,style:s,keepMounted:l=!1,...u}=e,c=function(){let e=n.useContext(x);if(void 0===e)throw Error((0,r.default)(30));return e}(),d=n.useRef(null),{transitionStatus:p,setMounted:f}=(0,A.useTransitionStatus)(c.checked);(0,O.useOpenChangeComplete)({open:c.checked,ref:d,onComplete(){c.checked||f(!1)}});let g={checked:c.checked,disabled:c.disabled,highlighted:c.highlighted,transitionStatus:p};return(0,a.useRenderElement)("span",e,{state:g,ref:[t,d],stateAttributesMapping:T,props:{"aria-hidden":!0,...u},enabled:l||c.checked})});e.s(["MenuCheckboxItemIndicator",0,L],371714);let D=n.createContext(void 0),F=n.forwardRef(function(e,t){let{render:r,className:o,style:i,...s}=e,[l,u]=n.useState(void 0),c=(0,a.useRenderElement)("div",e,{ref:t,props:{role:"group","aria-labelledby":l,...s}});return(0,N.jsx)(D.Provider,{value:u,children:c})});e.s(["MenuGroup",0,F],181194);var z=e.i(146376);let _=n.forwardRef(function(e,t){let{render:o,className:i,style:s,id:l,...u}=e,c=(0,I.useBaseUiId)(l),d=function(){let e=n.useContext(D);if(void 0===e)throw Error((0,r.default)(31));return e}();return(0,z.useIsoLayoutEffect)(()=>(d(c),()=>{d(void 0)}),[d,c]),(0,a.useRenderElement)("div",e,{ref:t,props:{id:c,role:"presentation",...u}})});e.s(["MenuGroupLabel",0,_],801545);let V=n.forwardRef(function(e,t){let{render:n,className:r,id:o,label:s,nativeButton:u=!1,disabled:c=!1,closeOnClick:d=!0,style:p,...f}=e,g=(0,M.useCompositeListItem)({label:s}),m=i(!0),h=(0,I.useBaseUiId)(o),{store:v}=l(),x=v.useState("isActive",g.index),b=v.useState("itemProps"),{getItemProps:S,itemRef:y}=w({closeOnClick:d,disabled:c,highlighted:x,id:h,store:v,nativeButton:u,nodeId:m?.context.nodeId,itemMetadata:E});return(0,a.useRenderElement)("div",e,{state:{disabled:c,highlighted:x},props:[b,f,S],ref:[y,t,g.ref]})});e.s(["MenuItem",0,V],91384);let H=n.forwardRef(function(e,t){let{render:r,className:o,id:s,label:u,closeOnClick:c=!1,style:d,...p}=e,f=n.useRef(null),g=(0,M.useCompositeListItem)({label:u}),m=i(!0),h=m?.context.nodeId,v=(0,I.useBaseUiId)(s),{store:x}=l(),b=x.useState("isActive",g.index),R=x.useState("itemProps"),E=x.context.typingRef,{getButtonProps:w,buttonRef:j}=(0,S.useButton)({native:!1,composite:!0}),T=C({closeOnClick:c,highlighted:b,id:v,nodeId:h,store:x,typingRef:E,itemRef:f});return(0,a.useRenderElement)("a",e,{state:{highlighted:b},props:[R,p,function(e){return(0,y.mergeProps)(T,e,w)}],ref:[f,j,t,g.ref]})});e.s(["MenuLinkItem",0,H],858307);var B=e.i(61487),U=e.i(431157),G=e.i(96533),W=e.i(673327),Y=e.i(815982);let $={...u.popupStateMapping,...d.transitionStatusMapping},q=n.forwardRef(function(e,t){let{render:r,className:o,style:s,finalFocus:u,...c}=e,{store:d}=l(),{side:p,align:f}=i(),m=null!=(0,G.useToolbarRootContext)(!0),h=d.useState("open"),v=d.useState("transitionStatus"),x=d.useState("popupProps"),b=d.useState("mounted"),S=d.useState("instantType"),y=d.useState("activeTriggerElement"),R=d.useState("parent"),C=d.useState("lastOpenChangeReason"),E=d.useState("rootId"),w=d.useState("floatingRootContext"),M=d.useState("floatingTreeRoot"),I=d.useState("closeDelay"),j=d.useState("activeTriggerElement"),T=d.useState("hoverEnabled"),P=d.useState("disabled"),A=d.useState("openMethod"),L="context-menu"===R.type;(0,O.useOpenChangeComplete)({open:h,ref:d.context.popupRef,onComplete(){h&&d.context.onOpenChangeComplete?.(!0)}}),n.useEffect(()=>{function e(e){d.setOpen(!1,(0,k.createChangeEventDetails)(e.reason,e.domEvent))}return M.events.on("close",e),()=>{M.events.off("close",e)}},[M.events,d]),(0,U.useHoverFloatingInteraction)(w,{enabled:T&&!P&&!L&&"menubar"!==R.type,closeDelay:I});let D=n.useCallback(e=>{d.set("popupElement",e)},[d]),F={transitionStatus:v,side:p,align:f,open:h,nested:"menu"===R.type,instant:S},z=(0,a.useRenderElement)("div",e,{state:F,ref:[t,d.context.popupRef,D],stateAttributesMapping:$,props:[x,{onKeyDown(e){m&&W.COMPOSITE_KEYS.has(e.key)&&e.stopPropagation()}},(0,Y.getDisabledMountTransitionStyles)(v),c,{"data-rootownerid":E}]}),_=void 0===R.type||L;return(y||"menubar"===R.type&&C!==g.REASONS.outsidePress)&&(_=!0),(0,N.jsx)(B.FloatingFocusManager,{context:w,openInteractionType:A,modal:L,disabled:!b,returnFocus:void 0===u?_:u,initialFocus:"menu"!==R.type,restoreFocus:!0,externalTree:"menubar"!==R.type?M:void 0,previousFocusableElement:j,nextFocusableElement:void 0===R.type?d.context.triggerFocusTargetRef:void 0,beforeContentFocusGuardRef:void 0===R.type?d.context.beforeContentFocusGuardRef:void 0,children:z})});e.s(["MenuPopup",0,q],764270);var K=e.i(726674);let X=n.createContext(void 0),J=n.forwardRef(function(e,t){let{keepMounted:n=!1,...r}=e,{store:o}=l();return o.useState("mounted")||n?(0,N.jsx)(X.Provider,{value:n,children:(0,N.jsx)(K.FloatingPortal,{ref:t,...r})}):null});e.s(["MenuPortal",0,J],219712);var Z=e.i(144394),Q=e.i(439957),ee=e.i(46420),et=e.i(329365),en=e.i(53687),er=e.i(426),eo=e.i(638396),ei=e.i(360495),es=e.i(222640),el=e.i(789579),ea=e.i(33383);let eu=n.forwardRef(function(e,t){let{anchor:i,positionMethod:s="absolute",className:a,render:u,side:c,align:d,sideOffset:p=0,alignOffset:m=0,collisionBoundary:h="clipping-ancestors",collisionPadding:v=5,arrowPadding:x=5,sticky:b=!1,disableAnchorTracking:S=!1,collisionAvoidance:y=eo.DROPDOWN_COLLISION_AVOIDANCE,style:R,...C}=e,{store:E}=l(),w=function(){let e=n.useContext(X);if(void 0===e)throw Error((0,r.default)(32));return e}(),M=f(!0),I=E.useState("parent"),j=E.useState("floatingRootContext"),T=E.useState("floatingTreeRoot"),P=E.useState("mounted"),A=E.useState("open"),O=E.useState("modal"),L=E.useState("openMethod"),D=E.useState("activeTriggerElement"),F=E.useState("transitionStatus"),_=E.useState("positionerElement"),V=E.useState("instantType"),H=E.useState("hasViewport"),B=E.useState("lastOpenChangeReason"),U=E.useState("floatingNodeId"),G=E.useState("floatingParentNodeId"),W=j.useState("domReferenceElement"),Y=n.useRef(null),$=(0,es.useAnimationsFinished)(_,!1,!1),q=i,K=p,J=m,eu=d,ec=y;"context-menu"===I.type&&(q=i??I.context?.anchor,eu=eu??"start",c||"center"===eu||(J=e.alignOffset??2,K=e.sideOffset??-5));let ed=c,ep=eu;"menu"===I.type?(ed=ed??"inline-end",ep=ep??"start",ec=e.collisionAvoidance??eo.POPUP_COLLISION_AVOIDANCE):"menubar"===I.type&&(ed=ed??("vertical"===I.context.orientation?"inline-end":"bottom"),ep=ep??"start");let ef="context-menu"===I.type,eg=(0,et.useAnchorPositioning)({anchor:q,floatingRootContext:j,positionMethod:M?"fixed":s,mounted:P,side:ed,sideOffset:K,align:ep,alignOffset:J,arrowPadding:ef?0:x,collisionBoundary:h,collisionPadding:v,sticky:b,nodeId:U,keepMounted:w,disableAnchorTracking:S,collisionAvoidance:ec,shiftCrossAxis:ef&&!("side"in ec&&"flip"===ec.side),externalTree:T,adaptiveOrigin:H?ei.adaptiveOrigin:void 0});n.useEffect(()=>{function e(e){e.open&&(e.parentNodeId===U&&E.set("hoverEnabled",!1),e.nodeId!==U&&e.parentNodeId===E.select("floatingParentNodeId")&&E.setOpen(!1,(0,k.createChangeEventDetails)(g.REASONS.siblingOpen)))}return T.events.on("menuopenchange",e),()=>{T.events.off("menuopenchange",e)}},[E,T.events,U]),n.useEffect(()=>{if(null!=E.select("floatingParentNodeId"))return T.events.on("menuopenchange",e),()=>{T.events.off("menuopenchange",e)};function e(e){if(e.open||e.nodeId!==E.select("floatingParentNodeId"))return;let t=e.reason??g.REASONS.siblingOpen;E.setOpen(!1,(0,k.createChangeEventDetails)(t))}},[T.events,E]);let em=(0,Q.useTimeout)();n.useEffect(()=>{A||em.clear()},[A,em]),n.useEffect(()=>{function e(e){if(A&&e.nodeId===E.select("floatingParentNodeId"))if(e.target&&D&&D!==e.target){let e=E.select("closeDelay");e>0?em.isStarted()||em.start(e,()=>{E.setOpen(!1,(0,k.createChangeEventDetails)(g.REASONS.siblingOpen))}):E.setOpen(!1,(0,k.createChangeEventDetails)(g.REASONS.siblingOpen))}else em.clear()}return T.events.on("itemhover",e),()=>{T.events.off("itemhover",e)}},[T.events,A,D,E,em]),n.useEffect(()=>{let e={open:A,nodeId:U,parentNodeId:G,reason:E.select("lastOpenChangeReason")};T.events.emit("menuopenchange",e)},[T.events,A,E,U,G]),(0,z.useIsoLayoutEffect)(()=>{let e=Y.current;if(W&&(Y.current=W),e&&W&&W!==e){E.set("instantType",void 0);let e=new AbortController;return $(()=>{E.set("instantType","trigger-change")},e.signal),()=>{e.abort()}}},[W,$,E]);let eh={open:A,side:eg.side,align:eg.align,anchorHidden:eg.anchorHidden,nested:"menu"===I.type,instant:V},ev="menubar"===I.type&&I.context.modal,ex=O&&B!==g.REASONS.triggerHover;(0,ea.useAnchoredPopupScrollLock)(A&&(ev||ex),"touch"===L,_,D);let eb=(0,el.usePositioner)(e,eh,{styles:eg.positionerStyles,transitionStatus:F,props:C,refs:[t,E.useStateSetter("positionerElement")],hidden:!P,inert:!A}),eS=P&&"menu"!==I.type&&("menubar"!==I.type&&O&&B!==g.REASONS.triggerHover||"menubar"===I.type&&I.context.modal),ey=null;return"menubar"===I.type?ey=I.context.contentElement:void 0===I.type&&(ey=D),(0,N.jsxs)(o.Provider,{value:eg,children:[eS&&(0,N.jsx)(er.InternalBackdrop,{ref:"context-menu"===I.type||"nested-context-menu"===I.type?I.context.internalBackdropRef:null,inert:(0,Z.inertValue)(!A),cutout:ey}),(0,N.jsx)(ee.FloatingNode,{id:U,children:(0,N.jsx)(en.CompositeList,{elementsRef:E.context.itemDomElements,labelsRef:E.context.itemLabels,children:eb})})]})});e.s(["MenuPositioner",0,eu],82264);var ec=e.i(667865);let ed=n.createContext(void 0),ep=n.memo(n.forwardRef(function(e,t){let{render:r,className:o,value:i,defaultValue:s,onValueChange:l,disabled:u=!1,style:c,"aria-labelledby":d,...p}=e,[f,g]=n.useState(void 0),[m,h]=(0,v.useControlled)({controlled:i,default:s,name:"MenuRadioGroup"}),x=(0,ec.useStableCallback)((e,t)=>{l?.(e,t),t.isCanceled||h(e)}),b=(0,a.useRenderElement)("div",e,{state:{disabled:u},ref:t,props:{role:"group","aria-labelledby":d??f,"aria-disabled":u||void 0,...p}}),S=n.useMemo(()=>({value:m,setValue:x,disabled:u}),[m,x,u]);return(0,N.jsx)(D.Provider,{value:g,children:(0,N.jsx)(ed.Provider,{value:S,children:b})})}));e.s(["MenuRadioGroup",0,ep],862050);let ef=n.createContext(void 0),eg=n.forwardRef(function(e,t){let{render:o,className:s,id:u,label:c,nativeButton:d=!1,disabled:p=!1,closeOnClick:f=!1,value:m,style:h,...v}=e,x=(0,M.useCompositeListItem)({label:c}),b=i(!0),S=(0,I.useBaseUiId)(u),{store:y}=l(),R=y.useState("isActive",x.index),C=y.useState("itemProps"),{value:j,setValue:P,disabled:A}=function(){let e=n.useContext(ed);if(void 0===e)throw Error((0,r.default)(34));return e}(),O=A||p,L=j===m,{getItemProps:D,itemRef:F}=w({closeOnClick:f,disabled:O,highlighted:R,id:S,store:y,nativeButton:d,nodeId:b?.context.nodeId,itemMetadata:E}),z=n.useMemo(()=>({disabled:O,highlighted:R,checked:L}),[O,R,L]),_=(0,a.useRenderElement)("div",e,{state:z,stateAttributesMapping:T,props:[C,{role:"menuitemradio","aria-checked":L,onClick:function(e){P(m,(0,k.createChangeEventDetails)(g.REASONS.itemPress,e.nativeEvent,void 0,{preventUnmountOnClose(){}}))}},v,D],ref:[F,t,x.ref]});return(0,N.jsx)(ef.Provider,{value:z,children:_})});e.s(["MenuRadioItem",0,eg],282593);let em=n.forwardRef(function(e,t){let{render:o,className:i,style:s,keepMounted:l=!1,...u}=e,c=function(){let e=n.useContext(ef);if(void 0===e)throw Error((0,r.default)(35));return e}(),d=n.useRef(null),{transitionStatus:p,setMounted:f}=(0,A.useTransitionStatus)(c.checked);(0,O.useOpenChangeComplete)({open:c.checked,ref:d,onComplete(){c.checked||f(!1)}});let g={checked:c.checked,disabled:c.disabled,highlighted:c.highlighted,transitionStatus:p};return(0,a.useRenderElement)("span",e,{state:g,stateAttributesMapping:T,ref:[t,d],props:{"aria-hidden":!0,...u},enabled:l||c.checked})});e.s(["MenuRadioItemIndicator",0,em],105953)},63947,507447,536481,874671,277450,e=>{"use strict";e.i(247167);var t=e.i(271645),n=e.i(439957),r=e.i(667865),o=e.i(883977),i=e.i(146376),s=e.i(956789),l=e.i(896499),a=e.i(46420),u=e.i(17989),c=e.i(260891),d=e.i(736760),p=e.i(350527),f=e.i(978921),g=e.i(733332);let m=t.createContext(null);function h(e){let n=t.useContext(m);if(null===n&&!e)throw Error((0,g.default)(5));return n}e.s(["useMenubarContext",0,h],507447);var v=e.i(638396),x=e.i(872855),b=e.i(32199),S=e.i(675606),y=e.i(56434),R=e.i(239613),C=e.i(176782),E=e.i(616269),w=e.i(301252),M=e.i(921374),I=e.i(379248),j=e.i(116786),T=e.i(990627);let k={...j.popupStoreSelectors,disabled:(0,E.createSelector)(e=>"menubar"===e.parent.type&&e.parent.context.disabled||e.disabled),modal:(0,E.createSelector)(e=>(void 0===e.parent.type||"context-menu"===e.parent.type)&&(e.modal??!0)),openMethod:(0,E.createSelector)(e=>e.openMethod),allowMouseEnter:(0,E.createSelector)(e=>e.allowMouseEnter),highlightItemOnHover:(0,E.createSelector)(e=>e.highlightItemOnHover),stickIfOpen:(0,E.createSelector)(e=>e.stickIfOpen),parent:(0,E.createSelector)(e=>e.parent),rootId:(0,E.createSelector)(e=>"menu"===e.parent.type?e.parent.store.select("rootId"):void 0!==e.parent.type?e.parent.context.rootId:e.rootId),activeIndex:(0,E.createSelector)(e=>e.activeIndex),isActive:(0,E.createSelector)((e,t)=>e.activeIndex===t),hoverEnabled:(0,E.createSelector)(e=>e.hoverEnabled),instantType:(0,E.createSelector)(e=>e.instantType),lastOpenChangeReason:(0,E.createSelector)(e=>e.openChangeReason),floatingTreeRoot:(0,E.createSelector)(e=>"menu"===e.parent.type?e.parent.store.select("floatingTreeRoot"):e.floatingTreeRoot),floatingNodeId:(0,E.createSelector)(e=>e.floatingNodeId),floatingParentNodeId:(0,E.createSelector)(e=>e.floatingParentNodeId),itemProps:(0,E.createSelector)(e=>e.itemProps),closeDelay:(0,E.createSelector)(e=>e.closeDelay),hasViewport:(0,E.createSelector)(e=>e.hasViewport),keyboardEventRelay:(0,E.createSelector)(e=>e.keyboardEventRelay?e.keyboardEventRelay:"menu"===e.parent.type?e.parent.store.select("keyboardEventRelay"):void 0)};class N extends w.ReactStore{constructor(e){super({...{...(0,j.createInitialPopupStoreState)(),disabled:!1,modal:!0,openMethod:null,allowMouseEnter:!1,highlightItemOnHover:!0,stickIfOpen:!0,parent:{type:void 0},rootId:void 0,activeIndex:null,hoverEnabled:!0,instantType:void 0,openChangeReason:null,floatingTreeRoot:new I.FloatingTreeStore,floatingNodeId:void 0,floatingParentNodeId:null,itemProps:s.EMPTY_OBJECT,keyboardEventRelay:void 0,closeDelay:0,hasViewport:!1},...e},{positionerRef:t.createRef(),popupRef:t.createRef(),typingRef:{current:!1},itemDomElements:{current:[]},itemLabels:{current:[]},allowMouseUpTriggerRef:{current:!1},triggerFocusTargetRef:t.createRef(),beforeContentFocusGuardRef:t.createRef(),onOpenChangeComplete:void 0,triggerElements:new T.PopupTriggerMap},k),this.unsubscribeParentListener=this.observe("parent",e=>{if(this.unsubscribeParentListener?.(),"menu"===e.type){let t=e.store.select("rootId"),n=e.store.select("floatingTreeRoot"),r=e.store.select("keyboardEventRelay");this.unsubscribeParentListener=e.store.subscribe(()=>{let o=e.store.select("rootId"),i=e.store.select("floatingTreeRoot"),s=e.store.select("keyboardEventRelay");(t!==o||n!==i||r!==s)&&(t=o,n=i,r=s,this.notifyAll())}),this.context.allowMouseUpTriggerRef=e.store.context.allowMouseUpTriggerRef;return}void 0!==e.type&&(this.context.allowMouseUpTriggerRef=e.context.allowMouseUpTriggerRef),this.unsubscribeParentListener=null})}setOpen(e,t){this.state.floatingRootContext.context.events.emit("setOpen",{open:e,eventDetails:t})}static useStore(e,t){let n=(0,M.useRefWithInit)(()=>new N(t)).current;return e??n}unsubscribeParentListener=null}e.s(["MenuStore",0,N],536481);var P=e.i(264111);let A=t.createContext(void 0);function O(){return t.useContext(A)}e.s(["MenuSubmenuRootContext",0,A,"useMenuSubmenuRootContext",0,O],874671);var L=e.i(843476);let D=(0,l.fastComponent)(function(e){let l,{children:g,open:m,onOpenChange:E,onOpenChangeComplete:w,defaultOpen:M=!1,disabled:I=!1,modal:j,loopFocus:T=!0,orientation:k="vertical",actionsRef:A,closeParentOnEsc:D=!1,handle:F,triggerId:z,defaultTriggerId:_=null,highlightItemOnHover:V=!0}=e,H=(0,R.useContextMenuRootContext)(!0),B=(0,f.useMenuRootContext)(!0),U=h(!0),G=O(),W=t.useMemo(()=>G&&B?{type:"menu",store:B.store}:U?{type:"menubar",context:U}:H&&!B?{type:"context-menu",context:H}:{type:void 0},[H,B,U,G]),Y=N.useStore(F?.store,{open:M,openProp:m,activeTriggerId:_,triggerIdProp:z,parent:W});(0,P.useInitialOpenSync)(Y,m,M,_),Y.useControlledProp("openProp",m),Y.useControlledProp("triggerIdProp",z),Y.useContextCallback("onOpenChangeComplete",w);let $=(0,o.useId)(),q=(0,o.useId)(),K=Y.useState("floatingTreeRoot"),X=(0,a.useFloatingNodeId)(K),J=(0,a.useFloatingParentNodeId)(),Z=Y.useState("open"),Q=Y.useState("activeTriggerElement"),ee=Y.useState("positionerElement"),et=Y.useState("hoverEnabled"),en=Y.useState("disabled"),er=Y.useState("lastOpenChangeReason"),eo=Y.useState("parent"),ei=Y.useState("activeIndex"),es=Y.useState("payload"),el=Y.useState("floatingParentNodeId"),ea=t.useRef(null),eu=t.useRef("context-menu"!==eo.type),ec=(0,n.useTimeout)(),ed=t.useRef(!0),ep=(0,n.useTimeout)(),ef=null!=el,{openMethod:eg,triggerProps:em}=(0,b.useOpenInteractionType)(Z);Y.useSyncedValues({disabled:I,highlightItemOnHover:V,modal:void 0===eo.type?j:void 0,openMethod:eg,rootId:$}),(0,P.useImplicitActiveTrigger)(Y);let{forceUnmount:eh}=(0,P.useOpenStateTransitions)(Z,Y,()=>{Y.update({allowMouseEnter:!1,stickIfOpen:!0})});(0,i.useIsoLayoutEffect)(()=>{H&&!B?Y.update({parent:{type:"context-menu",context:H},floatingNodeId:X,floatingParentNodeId:J}):B&&Y.update({floatingNodeId:X,floatingParentNodeId:J})},[H,B,X,J,Y]),t.useEffect(()=>{if(Z||(ea.current=null),"context-menu"===eo.type){if(!Z){ec.clear(),eu.current=!1;return}ec.start(500,()=>{eu.current=!0})}},[ec,Z,eo.type]),(0,i.useIsoLayoutEffect)(()=>{Z||et||Y.set("hoverEnabled",!0)},[Z,et,Y]);let ev=(0,r.useStableCallback)((e,t)=>{let n=t.reason;if(Z===e&&t.trigger===Q&&er===n)return;let r=(0,P.attachPreventUnmountOnClose)(t);if(e||null!=t.trigger||(t.trigger=Q??void 0),E?.(e,t),t.isCanceled)return;Y.state.floatingRootContext.dispatchOpenChange(e,t);let o=t.event;if(!1===e&&o?.type==="click"&&"touch"===o.pointerType&&!ed.current)return;e&&n===y.REASONS.triggerFocus?(ed.current=!1,ep.start(300,()=>{ed.current=!0})):(ed.current=!0,ep.clear());let i=(n===y.REASONS.triggerPress||n===y.REASONS.itemPress)&&0===o.detail&&o?.isTrusted,s=!e&&(n===y.REASONS.escapeKey||null==n),l={open:e,openChangeReason:n};ea.current=t.event??null,(0,P.setPopupOpenState)(l,e,t.trigger,r()),Y.update(l),"menubar"===eo.type&&(n===y.REASONS.triggerFocus||n===y.REASONS.focusOut||n===y.REASONS.triggerHover||n===y.REASONS.listNavigation||n===y.REASONS.siblingOpen)?Y.set("instantType","group"):i||s?Y.set("instantType",i?"click":"dismiss"):Y.set("instantType",void 0)}),ex=(0,p.useSyncedFloatingRootContext)({popupStore:Y,floatingId:q,nested:null!=J,onOpenChange:ev}),eb=ex.context.events;t.useEffect(()=>{let e=({open:e,eventDetails:t})=>ev(e,t);return eb.on("setOpen",e),()=>{eb?.off("setOpen",e)}},[eb,ev]);let eS=t.useCallback(()=>{Y.setOpen(!1,(0,S.createChangeEventDetails)(y.REASONS.imperativeAction))},[Y]);t.useImperativeHandle(A,()=>({unmount:eh,close:eS}),[eh,eS]),"context-menu"===eo.type&&(l=eo.context),t.useImperativeHandle(l?.positionerRef,()=>ee,[ee]),t.useImperativeHandle(l?.actionsRef,()=>({setOpen:ev}),[ev]);let ey=(0,u.useDismiss)(ex,{enabled:!en,bubbles:{escapeKey:D&&"menu"===eo.type},outsidePress:()=>"context-menu"!==eo.type||ea.current?.type==="contextmenu"||eu.current,externalTree:ef?K:void 0}),eR=(0,x.useDirection)(),eC=t.useCallback(e=>{Y.select("activeIndex")!==e&&Y.set("activeIndex",e)},[Y]),eE=(0,c.useListNavigation)(ex,{enabled:!en,listRef:Y.context.itemDomElements,activeIndex:ei,nested:void 0!==eo.type,loopFocus:T,orientation:k,parentOrientation:"menubar"===eo.type?eo.context.orientation:void 0,rtl:"rtl"===eR,disabledIndices:s.EMPTY_ARRAY,onNavigate:eC,openOnArrowKeyDown:"context-menu"!==eo.type,externalTree:ef?K:void 0,focusItemOnHover:V}),ew=t.useCallback(e=>{Y.context.typingRef.current=e},[Y]),eM=(0,d.useTypeahead)(ex,{enabled:!en,listRef:Y.context.itemLabels,elementsRef:Y.context.itemDomElements,activeIndex:ei,resetMs:v.TYPEAHEAD_RESET_MS,onMatch:e=>{Z&&e!==ei&&Y.set("activeIndex",e)},onTyping:ew}),eI=t.useMemo(()=>{let e=(0,C.mergeProps)(eM.reference,eE.reference,ey.reference,{onMouseMove(){Y.set("allowMouseEnter",!0)}},em);return e["aria-haspopup"]="menu",e["aria-expanded"]=Z,e},[Y,eM.reference,eE.reference,ey.reference,em,Z]),ej=t.useMemo(()=>{let e=(0,C.mergeProps)(eE.trigger,ey.trigger,em);return e["aria-haspopup"]="menu",e["aria-expanded"]=!1,e},[eE.trigger,ey.trigger,em]),eT=t.useMemo(()=>(0,C.mergeProps)(P.FOCUSABLE_POPUP_PROPS,{id:q,role:"menu","aria-labelledby":Q?.id,onMouseMove(){Y.set("allowMouseEnter",!0),"menu"===eo.type&&Y.set("hoverEnabled",!1)},onClick(){Y.select("hoverEnabled")&&Y.set("hoverEnabled",!1)},onKeyDown(e){let t=Y.select("keyboardEventRelay");t&&!e.isPropagationStopped()&&t(e)}},eM.floating,eE.floating,ey.floating),[Q,q,eo.type,Y,eM.floating,eE.floating,ey.floating]),ek=eE.item??s.EMPTY_OBJECT;(0,P.usePopupInteractionProps)(Y,{floatingRootContext:ex,activeTriggerProps:eI,inactiveTriggerProps:ej,popupProps:eT,itemProps:ek});let eN=t.useMemo(()=>({store:Y,parent:W}),[Y,W]),eP=(0,L.jsx)(f.MenuRootContext.Provider,{value:eN,children:"function"==typeof g?g({payload:es}):g});return void 0===eo.type||"context-menu"===eo.type?(0,L.jsx)(a.FloatingTree,{externalTree:K,children:eP}):eP});e.s(["MenuRoot",0,D],63947),e.s(["MenuSubmenuRoot",0,function(e){let n=(0,f.useMenuRootContext)().store,r=t.useMemo(()=>({parentMenu:n}),[n]);return(0,L.jsx)(A.Provider,{value:r,children:(0,L.jsx)(D,{...e})})}],277450)},451512,e=>{"use strict";e.i(261027);var t,n=e.i(382370),r=e.i(389554),o=e.i(685996),i=e.i(371714),s=e.i(181194),l=e.i(801545),a=e.i(91384),u=e.i(858307),c=e.i(764270),d=e.i(219712),p=e.i(82264),f=e.i(862050),g=e.i(282593),m=e.i(105953),h=e.i(63947),v=e.i(277450);e.i(247167);var x=e.i(733332),b=e.i(271645),S=e.i(439957),y=e.i(108868),R=e.i(896499),C=e.i(667865),E=e.i(146376),w=e.i(956789),M=e.i(650316),I=e.i(385689),j=e.i(46420),T=e.i(413082),k=e.i(872135),N=e.i(379248),P=e.i(647554),A=e.i(978921),O=e.i(405005),L=e.i(552245),D=e.i(540886),F=e.i(264042),z=e.i(395530);function _(e){let{render:t,className:n,style:r,state:o=w.EMPTY_OBJECT,props:i=w.EMPTY_ARRAY,refs:s=w.EMPTY_ARRAY,metadata:l,stateAttributesMapping:a,tag:u="div",...c}=e,{compositeProps:d,compositeRef:p}=(0,z.useCompositeItem)({metadata:l});return(0,L.useRenderElement)(u,e,{state:o,ref:[...s,p],props:[d,...i,c],stateAttributesMapping:a})}var V=e.i(838452),H=e.i(229315),B=e.i(264111),U=e.i(346570),G=e.i(788015),W=e.i(56434),Y=e.i(239613),$=e.i(507447),q=e.i(638396),K=e.i(152535),X=e.i(176782),J=e.i(843476);let Z=(0,R.fastComponentRef)(function(e,t){let n,r,o,{render:i,className:s,style:l,disabled:a=!1,nativeButton:u=!0,id:c,openOnHover:d,delay:p=100,closeDelay:f=0,handle:g,payload:m,...h}=e,v=(0,A.useMenuRootContext)(!0),R=g?.store??v?.store;if(!R)throw Error((0,x.default)(85));let z=(0,G.useBaseUiId)(c),Z=R.useState("isTriggerActive",z),Q=R.useState("floatingRootContext"),ee=R.useState("isOpenedByTrigger",z),et=R.useState("triggerPopupId",z),en=b.useRef(null),er=(n=(0,Y.useContextMenuRootContext)(!0),r=(0,A.useMenuRootContext)(!0),o=(0,$.useMenubarContext)(!0),b.useMemo(()=>o?{type:"menubar",context:o}:n&&!r?{type:"context-menu",context:n}:{type:void 0},[n,r,o])),eo=(0,V.useCompositeRootContext)(!0),ei=(0,j.useFloatingTree)(),es=b.useMemo(()=>ei??new N.FloatingTreeStore,[ei]),el=(0,j.useFloatingNodeId)(es),ea=(0,j.useFloatingParentNodeId)(),{registerTrigger:eu,isMountedByThisTrigger:ec}=(0,B.useTriggerDataForwarding)(z,en,R,{payload:m,closeDelay:f,parent:er,floatingTreeRoot:es,floatingNodeId:el,floatingParentNodeId:ea,keyboardEventRelay:eo?.relayKeyboardEvent}),ed="menubar"===er.type,ep=R.useState("disabled"),ef=a||ep||ed&&er.context.disabled,{getButtonProps:eg,buttonRef:em}=(0,D.useButton)({disabled:ef,native:u});b.useEffect(()=>{ee||void 0!==er.type||(R.context.allowMouseUpTriggerRef.current=!1)},[R,ee,er.type]);let eh=b.useRef(null),ev=(0,S.useTimeout)(),ex=(0,C.useStableCallback)(e=>{if(!eh.current)return;ev.clear(),R.context.allowMouseUpTriggerRef.current=!1;let t=e.target;if((0,P.contains)(eh.current,t)||(0,P.contains)(R.select("positionerElement"),t)||t===eh.current||null!=t&&function e(t){return(0,H.isHTMLElement)(t)&&t.hasAttribute("data-rootownerid")?t.getAttribute("data-rootownerid")??void 0:(0,H.isLastTraversableNode)(t)?void 0:e((0,H.getParentNode)(t))}(t)===R.select("rootId"))return;let n=(0,F.getPseudoElementBounds)(eh.current);e.clientX>=n.left-2&&e.clientX<=n.right+2&&e.clientY>=n.top-2&&e.clientY<=n.bottom+2||es.events.emit("close",{domEvent:e,reason:W.REASONS.cancelOpen})});b.useEffect(()=>{ee&&R.select("lastOpenChangeReason")===W.REASONS.triggerHover&&(0,y.ownerDocument)(eh.current).addEventListener("mouseup",ex,{once:!0})},[ee,ex,R]);let eb=ed&&er.context.hasSubmenuOpen,eS=d??eb,ey=(0,k.useHoverReferenceInteraction)(Q,{enabled:eS&&!ef&&"context-menu"!==er.type&&(!ed||eb&&!ec),handleClose:(0,M.safePolygon)({blockPointerEvents:!ed}),mouseOnly:!0,move:!1,restMs:void 0===er.type?p:void 0,delay:{close:f},triggerElementRef:en,externalTree:es,isActiveTrigger:Z,isClosing:()=>"ending"===R.select("transitionStatus")}),eR=function(e,t){let n=(0,S.useTimeout)(),[r,o]=b.useState(!1);return(0,E.useIsoLayoutEffect)(()=>{e&&"trigger-hover"===t?(o(!0),n.start(q.PATIENT_CLICK_THRESHOLD,()=>{o(!1)})):e||(n.clear(),o(!1))},[e,t,n]),r}(ee,R.select("lastOpenChangeReason")),eC=(0,I.useClick)(Q,{enabled:!ef&&"context-menu"!==er.type,event:ee&&ed?"click":"mousedown",toggle:!0,ignoreMouse:!1,stickIfOpen:void 0===er.type&&eR}),eE=(0,T.useFocus)(Q,{enabled:!ef&&eb}),ew=function(e){let{enabled:t=!0,mouseDownAction:n,open:r}=e,o=b.useRef(!1);return b.useMemo(()=>t?{onMouseDown:e=>{("open"===n&&!r||"close"===n&&r)&&(o.current=!0,(0,y.ownerDocument)(e.currentTarget).addEventListener("click",()=>{o.current=!1},{once:!0}))},onClick:e=>{o.current&&(o.current=!1,e.preventBaseUIHandler())}}:w.EMPTY_OBJECT,[t,n,r])}({open:ee,enabled:ed,mouseDownAction:"open"}),eM=b.useMemo(()=>(0,X.mergeProps)(eE.reference,eC.reference),[eE.reference,eC.reference]),eI=R.useState("triggerProps",ec),{preFocusGuardRef:ej,handlePreFocusGuardFocus:eT,handleFocusTargetFocus:ek}=(0,U.useTriggerFocusGuards)(R,en),eN={disabled:ef,open:ee},eP=[eh,t,em,eu,en],eA=[eM,ey??w.EMPTY_OBJECT,eI,{"aria-haspopup":"menu","aria-controls":et,id:z,onMouseDown:e=>{R.select("open")||(ev.start(200,()=>{R.context.allowMouseUpTriggerRef.current=!0}),(0,y.ownerDocument)(e.currentTarget).addEventListener("mouseup",ex,{once:!0}))}},ed?{role:"menuitem"}:{},ew,h,eg],eO=(0,L.useRenderElement)("button",e,{enabled:!ed,stateAttributesMapping:O.pressableTriggerOpenStateMapping,state:eN,ref:eP,props:eA});return ed?(0,J.jsx)(_,{tag:"button",render:i,className:s,style:l,state:eN,refs:eP,props:eA,stateAttributesMapping:O.pressableTriggerOpenStateMapping}):ee?(0,J.jsxs)(b.Fragment,{children:[(0,J.jsx)(K.FocusGuard,{ref:ej,onFocus:eT},`${z}-pre-focus-guard`),(0,J.jsx)(b.Fragment,{children:eO},z),(0,J.jsx)(K.FocusGuard,{ref:R.context.triggerFocusTargetRef,onFocus:ek},`${z}-post-focus-guard`)]}):(0,J.jsx)(b.Fragment,{children:eO},z)});var Q=e.i(803414),ee=e.i(818390);let et=((t={}).popupWidth="--popup-width",t.popupHeight="--popup-height",t),en={activationDirection:e=>e?{"data-activation-direction":e}:null},er=b.forwardRef(function(e,t){let{render:n,className:r,style:o,children:i,...s}=e,{store:l}=(0,A.useMenuRootContext)(),{side:a}=(0,Q.useMenuPositionerContext)(),u=l.useState("instantType"),{children:c,state:d}=(0,ee.usePopupViewport)({store:l,side:a,cssVars:et,children:i}),p={activationDirection:d.activationDirection,transitioning:d.transitioning,instant:u};return(0,L.useRenderElement)("div",e,{state:p,ref:t,props:[s,{children:c}],stateAttributesMapping:en})});var eo=e.i(652225),ei=e.i(673553),es=e.i(866506),el=e.i(874671);let ea=b.forwardRef(function(e,t){let{render:n,className:r,style:o,label:i,id:s,nativeButton:l=!1,openOnHover:a=!0,delay:u=100,closeDelay:c=0,disabled:d=!1,...p}=e,f=(0,ei.useCompositeListItem)({label:i}),g=(0,Q.useMenuPositionerContext)(),{store:m}=(0,A.useMenuRootContext)(),h=(0,G.useBaseUiId)(s),v=m.useState("open"),S=m.useState("floatingRootContext"),y=m.useState("floatingTreeRoot"),R=m.useState("triggerPopupId",h),C=(0,B.useTriggerRegistration)(h,m),E=b.useCallback(e=>{let t=C(e);return null!==e&&m.select("open")&&null==m.select("activeTriggerId")&&m.update({activeTriggerId:h,activeTriggerElement:e,closeDelay:c}),t},[C,c,m,h]),j=b.useRef(null),T=b.useCallback(e=>{j.current=e,m.set("activeTriggerElement",e)},[m]),N=(0,el.useMenuSubmenuRootContext)();if(!N?.parentMenu)throw Error((0,x.default)(37));m.useSyncedValue("closeDelay",c);let P=N.parentMenu,D=m.useState("disabled"),F=P.useState("disabled"),z=d||D||F,_=P.useState("itemProps"),V=P.useState("isActive",f.index),H=b.useMemo(()=>({type:"submenu-trigger",setActive(){P.select("highlightItemOnHover")&&P.set("activeIndex",f.index)}}),[P,f.index]),{getItemProps:U,itemRef:W}=(0,es.useMenuItem)({closeOnClick:!1,disabled:z,highlighted:V,id:h,store:m,typingRef:P.context.typingRef,nativeButton:l,itemMetadata:H,nodeId:g?.context.nodeId}),Y=m.useState("hoverEnabled"),$=(0,k.useHoverReferenceInteraction)(S,{enabled:Y&&a&&!z,handleClose:(0,M.safePolygon)({blockPointerEvents:!0}),mouseOnly:!0,move:!0,restMs:u,delay:{open:u,close:c},shouldOpen:u>0?()=>P.select("allowMouseEnter"):void 0,triggerElementRef:j,externalTree:y,isClosing:()=>"ending"===m.select("transitionStatus")}),q=(0,I.useClick)(S,{enabled:!z,event:"mousedown",toggle:!a,ignoreMouse:a,stickIfOpen:!1}).reference??w.EMPTY_OBJECT,K=m.useState("triggerProps",!0);return delete K.id,(0,L.useRenderElement)("div",e,{state:{disabled:z,highlighted:V,open:v},stateAttributesMapping:O.triggerOpenStateMapping,props:[q,$,K,_,{"aria-controls":R,tabIndex:v||V?0:-1,onBlur(){V&&P.set("activeIndex",null)}},p,U],ref:[t,f.ref,W,E,T]})});var eu=e.i(675606),ec=e.i(536481);class ed{constructor(){this.store=new ec.MenuStore}open(e){let t=e?this.store.context.triggerElements.getById(e):void 0;if(e&&!t)throw Error((0,x.default)(83,e));this.store.setOpen(!0,(0,eu.createChangeEventDetails)("imperative-action",void 0,t))}close(){this.store.setOpen(!1,(0,eu.createChangeEventDetails)("imperative-action",void 0,void 0))}get isOpen(){return this.store.select("open")}}e.s(["Arrow",()=>n.MenuArrow,"Backdrop",()=>r.MenuBackdrop,"CheckboxItem",()=>o.MenuCheckboxItem,"CheckboxItemIndicator",()=>i.MenuCheckboxItemIndicator,"Group",()=>s.MenuGroup,"GroupLabel",()=>l.MenuGroupLabel,"Handle",0,ed,"Item",()=>a.MenuItem,"LinkItem",()=>u.MenuLinkItem,"Popup",()=>c.MenuPopup,"Portal",()=>d.MenuPortal,"Positioner",()=>p.MenuPositioner,"RadioGroup",()=>f.MenuRadioGroup,"RadioItem",()=>g.MenuRadioItem,"RadioItemIndicator",()=>m.MenuRadioItemIndicator,"Root",()=>h.MenuRoot,"Separator",()=>eo.Separator,"SubmenuRoot",()=>v.MenuSubmenuRoot,"SubmenuTrigger",0,ea,"Trigger",0,Z,"Viewport",0,er,"createHandle",0,function(){return new ed}],160948);var ep=e.i(160948);e.s(["Menu",0,ep],451512)},707701,531649,494862,e=>{"use strict";e.i(807235),e.i(981080),e.i(152370);var t=e.i(843476),n=e.i(16715),r=e.i(555436),o=e.i(649582),i=e.i(37727),s=e.i(487486),l=e.i(519455),a=e.i(793479),u=e.i(115504),c=e.i(451512),d=e.i(643531);let p=(0,e.i(475254).default)("columns-3",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M9 3v18",key:"fh3hqa"}],["path",{d:"M15 3v18",key:"14nvp0"}]]);function f({table:e,label:n="View",className:r}){let o=e.getAllLeafColumns().filter(e=>e.getCanHide());return 0===o.length?null:(0,t.jsxs)(c.Menu.Root,{children:[(0,t.jsx)(c.Menu.Trigger,{render:(0,t.jsxs)(l.Button,{variant:"outline",size:"sm",className:r,"data-testid":"view-options-trigger",children:[(0,t.jsx)(p,{}),n]})}),(0,t.jsx)(c.Menu.Portal,{children:(0,t.jsx)(c.Menu.Positioner,{side:"bottom",align:"end",sideOffset:4,className:"isolate z-50",children:(0,t.jsx)(c.Menu.Popup,{className:"min-w-[12rem] rounded-md bg-popover p-1 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden",children:o.map(e=>(0,t.jsxs)(c.Menu.CheckboxItem,{checked:e.getIsVisible(),onCheckedChange:t=>e.toggleVisibility(t),closeOnClick:!1,"data-testid":`view-option-${e.id}`,className:"relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-7 capitalize outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground",children:[(0,t.jsx)(c.Menu.CheckboxItemIndicator,{className:"absolute left-2 flex size-4 items-center justify-center",children:(0,t.jsx)(d.Check,{className:"size-3.5"})}),e.columnDef.meta?.title??("string"==typeof e.columnDef.header?e.columnDef.header:e.id)]},e.id))})})})]})}e.s(["DataTableToolbar",0,function({table:e,searchValue:c,onSearchChange:d,searchPlaceholder:p="Search",onOpenFilters:g,onRefresh:m,isRefreshing:h=!1,filterLabels:v,formatFilterValue:x,showViewOptions:b=!0,children:S,className:y}){let R=e.getState().columnFilters,C=t=>v?.[t]??e.getColumn(t)?.columnDef.meta?.title??t;return(0,t.jsxs)("div",{className:(0,u.cn)("flex flex-wrap items-center justify-between gap-2",y),children:[(0,t.jsxs)("div",{className:"flex flex-1 flex-wrap items-center gap-2",children:[void 0!==d&&(0,t.jsxs)("div",{className:"relative",children:[(0,t.jsx)(r.Search,{className:"pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground"}),(0,t.jsx)(a.Input,{value:c??"",onChange:e=>d(e.target.value),placeholder:p,className:"h-8 w-56 pl-8","data-testid":"datatable-search"})]}),R.map(n=>{var r,o;return(0,t.jsxs)(s.Badge,{variant:"outline",className:"gap-1 py-1","data-testid":`filter-chip-${n.id}`,children:[(0,t.jsxs)("span",{className:"text-muted-foreground",children:[C(n.id),":"]}),(r=n.id,o=n.value,x?.(r,o)??(Array.isArray(o)?o.join(", "):String(o))),(0,t.jsx)("button",{type:"button","aria-label":`Remove ${C(n.id)} filter`,"data-testid":`filter-chip-remove-${n.id}`,onClick:()=>e.setColumnFilters(e=>e.filter(e=>e.id!==n.id)),className:"ml-0.5 rounded-full text-muted-foreground hover:text-foreground",children:(0,t.jsx)(i.X,{className:"size-3"})})]},n.id)}),R.length>0&&(0,t.jsx)(l.Button,{variant:"ghost",size:"sm",onClick:()=>e.setColumnFilters([]),"data-testid":"datatable-clear-filters",children:"Clear all"})]}),(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[S,void 0!==m&&(0,t.jsx)(l.Button,{variant:"outline",size:"icon-sm",onClick:m,disabled:h,"aria-label":"Refresh",title:"Refresh","data-testid":"datatable-refresh",children:(0,t.jsx)(n.RefreshCw,{className:h?"animate-spin":""})}),b&&(0,t.jsx)(f,{table:e,label:"Columns"}),void 0!==g&&(0,t.jsxs)(l.Button,{variant:"outline",size:"sm",onClick:g,"data-testid":"datatable-filters-trigger",children:[(0,t.jsx)(o.SlidersHorizontal,{}),"Filters",R.length>0&&(0,t.jsx)(s.Badge,{className:"ml-1 h-5 min-w-5 justify-center rounded-full px-1","data-testid":"datatable-filter-count",children:R.length})]})]})]})}],531649);var g=e.i(664659),m=e.i(344523),h=e.i(399219),h=h;function v({sorted:e}){return"asc"===e?(0,t.jsx)(h.default,{className:"size-3.5","data-sort-indicator":"asc"}):"desc"===e?(0,t.jsx)(g.ChevronDown,{className:"size-3.5","data-sort-indicator":"desc"}):(0,t.jsx)(m.ChevronsUpDown,{className:"size-3.5 text-muted-foreground","data-sort-indicator":"none"})}let x="flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground";e.s(["DataTableMultiSortHeader",0,function({table:e,fields:n,className:r}){let o=e.getState().sorting[0],s=void 0!==o&&n.some(e=>e.id===o.id)?o:void 0,l=s?.desc===!0?"desc":"asc",a=void 0!==s&&l,p=n.flatMap(e=>[{key:`${e.id}-asc`,id:e.id,desc:!1,label:`${e.label} ascending`,Icon:h.default},{key:`${e.id}-desc`,id:e.id,desc:!0,label:`${e.label} descending`,Icon:g.ChevronDown}]),f=n.flatMap((e,n)=>{let r=s?.id===e.id,o=(0,t.jsx)("span",{"data-sort-field":e.id,className:r?"font-semibold text-foreground":s?"text-muted-foreground":"",children:e.label},e.id);return 0===n?[o]:[(0,t.jsx)("span",{className:"text-muted-foreground",children:" / "},`sep-${e.id}`),o]});return(0,t.jsxs)("div",{className:(0,u.cn)("flex items-center gap-1",r),children:[(0,t.jsx)("span",{className:"font-medium",children:f}),(0,t.jsxs)(c.Menu.Root,{children:[(0,t.jsx)(c.Menu.Trigger,{render:(0,t.jsx)("button",{type:"button","data-testid":`sort-trigger-${n[0]?.id??"field"}`,"aria-label":`Sort options for ${n.map(e=>e.label).join(" or ")}`,onClick:e=>e.stopPropagation(),className:(0,u.cn)("inline-flex size-6 items-center justify-center rounded-md hover:bg-muted",a?"text-primary":"text-muted-foreground"),children:(0,t.jsx)(v,{sorted:a})})}),(0,t.jsx)(c.Menu.Portal,{children:(0,t.jsx)(c.Menu.Positioner,{side:"bottom",align:"start",sideOffset:4,className:"isolate z-50",children:(0,t.jsxs)(c.Menu.Popup,{className:"min-w-[9rem] rounded-md bg-popover p-1 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden",children:[p.map(n=>{let r=s?.id===n.id&&s.desc===n.desc;return(0,t.jsxs)(c.Menu.Item,{className:(0,u.cn)(x,r?"text-primary":""),onClick:()=>e.setSorting([{id:n.id,desc:n.desc}]),children:[(0,t.jsx)(n.Icon,{className:"size-3.5"})," ",n.label,r&&(0,t.jsx)(d.Check,{className:"ml-auto size-3.5"})]},n.key)}),(0,t.jsxs)(c.Menu.Item,{className:x,onClick:()=>e.setSorting([]),children:[(0,t.jsx)(i.X,{className:"size-3.5"})," Reset"]})]})})})]})]})},"DataTableSortHeader",0,function({column:e,title:n,variant:r="header-cycle",className:o}){let s=e.getIsSorted();return e.getCanSort()?"dropdown-tristate"===r?(0,t.jsxs)("div",{className:(0,u.cn)("flex items-center gap-1",o),children:[(0,t.jsx)("span",{className:"font-medium",children:n}),(0,t.jsxs)(c.Menu.Root,{children:[(0,t.jsx)(c.Menu.Trigger,{render:(0,t.jsx)("button",{type:"button","data-testid":`sort-trigger-${e.id}`,"aria-label":`Sort options for ${e.id}`,onClick:e=>e.stopPropagation(),className:(0,u.cn)("inline-flex size-6 items-center justify-center rounded-md hover:bg-muted",s?"text-primary":"text-muted-foreground"),children:(0,t.jsx)(v,{sorted:s})})}),(0,t.jsx)(c.Menu.Portal,{children:(0,t.jsx)(c.Menu.Positioner,{side:"bottom",align:"start",sideOffset:4,className:"isolate z-50",children:(0,t.jsxs)(c.Menu.Popup,{className:"min-w-[9rem] rounded-md bg-popover p-1 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden",children:[(0,t.jsxs)(c.Menu.Item,{className:x,onClick:()=>e.toggleSorting(!1),children:[(0,t.jsx)(h.default,{className:"size-3.5"})," Ascending"]}),(0,t.jsxs)(c.Menu.Item,{className:x,onClick:()=>e.toggleSorting(!0),children:[(0,t.jsx)(g.ChevronDown,{className:"size-3.5"})," Descending"]}),(0,t.jsxs)(c.Menu.Item,{className:x,onClick:()=>e.clearSorting(),children:[(0,t.jsx)(i.X,{className:"size-3.5"})," Reset"]})]})})})]})]}):(0,t.jsxs)("button",{type:"button","data-testid":`sort-header-${e.id}`,onClick:e.getToggleSortingHandler(),className:(0,u.cn)("flex items-center gap-1 font-medium select-none hover:text-foreground",o),children:[(0,t.jsx)("span",{children:n}),(0,t.jsx)(v,{sorted:s})]}):(0,t.jsx)("span",{className:(0,u.cn)("font-medium",o),children:n})}],494862),e.s([],707701)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0.p~s6ih~c~xe.js b/litellm/proxy/_experimental/out/_next/static/chunks/0.p~s6ih~c~xe.js deleted file mode 100644 index c4e254eb8e6..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/0.p~s6ih~c~xe.js +++ /dev/null @@ -1,10 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,482725,e=>{"use strict";var t=e.i(244451);e.s(["Spin",()=>t.default])},244451,e=>{"use strict";let t;e.i(247167);var n=e.i(271645),i=e.i(343794),a=e.i(242064),l=e.i(763731),o=e.i(174428);let r=80*Math.PI,s=e=>{let{dotClassName:t,style:a,hasCircleCls:l}=e;return n.createElement("circle",{className:(0,i.default)(`${t}-circle`,{[`${t}-circle-bg`]:l}),r:40,cx:50,cy:50,strokeWidth:20,style:a})},d=({percent:e,prefixCls:t})=>{let a=`${t}-dot`,l=`${a}-holder`,d=`${l}-hidden`,[c,u]=n.useState(!1);(0,o.default)(()=>{0!==e&&u(!0)},[0!==e]);let m=Math.max(Math.min(e,100),0);if(!c)return null;let p={strokeDashoffset:`${r/4}`,strokeDasharray:`${r*m/100} ${r*(100-m)/100}`};return n.createElement("span",{className:(0,i.default)(l,`${a}-progress`,m<=0&&d)},n.createElement("svg",{viewBox:"0 0 100 100",role:"progressbar","aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":m},n.createElement(s,{dotClassName:a,hasCircleCls:!0}),n.createElement(s,{dotClassName:a,style:p})))};function c(e){let{prefixCls:t,percent:a=0}=e,l=`${t}-dot`,o=`${l}-holder`,r=`${o}-hidden`;return n.createElement(n.Fragment,null,n.createElement("span",{className:(0,i.default)(o,a>0&&r)},n.createElement("span",{className:(0,i.default)(l,`${t}-dot-spin`)},[1,2,3,4].map(e=>n.createElement("i",{className:`${t}-dot-item`,key:e})))),n.createElement(d,{prefixCls:t,percent:a}))}function u(e){var t;let{prefixCls:a,indicator:o,percent:r}=e,s=`${a}-dot`;return o&&n.isValidElement(o)?(0,l.cloneElement)(o,{className:(0,i.default)(null==(t=o.props)?void 0:t.className,s),percent:r}):n.createElement(c,{prefixCls:a,percent:r})}e.i(296059);var m=e.i(694758),p=e.i(183293),g=e.i(246422),b=e.i(838378);let f=new m.Keyframes("antSpinMove",{to:{opacity:1}}),h=new m.Keyframes("antRotate",{to:{transform:"rotate(405deg)"}}),$=(0,g.genStyleHooks)("Spin",e=>(e=>{let{componentCls:t,calc:n}=e;return{[t]:Object.assign(Object.assign({},(0,p.resetComponent)(e)),{position:"absolute",display:"none",color:e.colorPrimary,fontSize:0,textAlign:"center",verticalAlign:"middle",opacity:0,transition:`transform ${e.motionDurationSlow} ${e.motionEaseInOutCirc}`,"&-spinning":{position:"relative",display:"inline-block",opacity:1},[`${t}-text`]:{fontSize:e.fontSize,paddingTop:n(n(e.dotSize).sub(e.fontSize)).div(2).add(2).equal()},"&-fullscreen":{position:"fixed",width:"100vw",height:"100vh",backgroundColor:e.colorBgMask,zIndex:e.zIndexPopupBase,inset:0,display:"flex",alignItems:"center",flexDirection:"column",justifyContent:"center",opacity:0,visibility:"hidden",transition:`all ${e.motionDurationMid}`,"&-show":{opacity:1,visibility:"visible"},[t]:{[`${t}-dot-holder`]:{color:e.colorWhite},[`${t}-text`]:{color:e.colorTextLightSolid}}},"&-nested-loading":{position:"relative",[`> div > ${t}`]:{position:"absolute",top:0,insetInlineStart:0,zIndex:4,display:"block",width:"100%",height:"100%",maxHeight:e.contentHeight,[`${t}-dot`]:{position:"absolute",top:"50%",insetInlineStart:"50%",margin:n(e.dotSize).mul(-1).div(2).equal()},[`${t}-text`]:{position:"absolute",top:"50%",width:"100%",textShadow:`0 1px 2px ${e.colorBgContainer}`},[`&${t}-show-text ${t}-dot`]:{marginTop:n(e.dotSize).div(2).mul(-1).sub(10).equal()},"&-sm":{[`${t}-dot`]:{margin:n(e.dotSizeSM).mul(-1).div(2).equal()},[`${t}-text`]:{paddingTop:n(n(e.dotSizeSM).sub(e.fontSize)).div(2).add(2).equal()},[`&${t}-show-text ${t}-dot`]:{marginTop:n(e.dotSizeSM).div(2).mul(-1).sub(10).equal()}},"&-lg":{[`${t}-dot`]:{margin:n(e.dotSizeLG).mul(-1).div(2).equal()},[`${t}-text`]:{paddingTop:n(n(e.dotSizeLG).sub(e.fontSize)).div(2).add(2).equal()},[`&${t}-show-text ${t}-dot`]:{marginTop:n(e.dotSizeLG).div(2).mul(-1).sub(10).equal()}}},[`${t}-container`]:{position:"relative",transition:`opacity ${e.motionDurationSlow}`,"&::after":{position:"absolute",top:0,insetInlineEnd:0,bottom:0,insetInlineStart:0,zIndex:10,width:"100%",height:"100%",background:e.colorBgContainer,opacity:0,transition:`all ${e.motionDurationSlow}`,content:'""',pointerEvents:"none"}},[`${t}-blur`]:{clear:"both",opacity:.5,userSelect:"none",pointerEvents:"none","&::after":{opacity:.4,pointerEvents:"auto"}}},"&-tip":{color:e.spinDotDefault},[`${t}-dot-holder`]:{width:"1em",height:"1em",fontSize:e.dotSize,display:"inline-block",transition:`transform ${e.motionDurationSlow} ease, opacity ${e.motionDurationSlow} ease`,transformOrigin:"50% 50%",lineHeight:1,color:e.colorPrimary,"&-hidden":{transform:"scale(0.3)",opacity:0}},[`${t}-dot-progress`]:{position:"absolute",inset:0},[`${t}-dot`]:{position:"relative",display:"inline-block",fontSize:e.dotSize,width:"1em",height:"1em","&-item":{position:"absolute",display:"block",width:n(e.dotSize).sub(n(e.marginXXS).div(2)).div(2).equal(),height:n(e.dotSize).sub(n(e.marginXXS).div(2)).div(2).equal(),background:"currentColor",borderRadius:"100%",transform:"scale(0.75)",transformOrigin:"50% 50%",opacity:.3,animationName:f,animationDuration:"1s",animationIterationCount:"infinite",animationTimingFunction:"linear",animationDirection:"alternate","&:nth-child(1)":{top:0,insetInlineStart:0,animationDelay:"0s"},"&:nth-child(2)":{top:0,insetInlineEnd:0,animationDelay:"0.4s"},"&:nth-child(3)":{insetInlineEnd:0,bottom:0,animationDelay:"0.8s"},"&:nth-child(4)":{bottom:0,insetInlineStart:0,animationDelay:"1.2s"}},"&-spin":{transform:"rotate(45deg)",animationName:h,animationDuration:"1.2s",animationIterationCount:"infinite",animationTimingFunction:"linear"},"&-circle":{strokeLinecap:"round",transition:["stroke-dashoffset","stroke-dasharray","stroke","stroke-width","opacity"].map(t=>`${t} ${e.motionDurationSlow} ease`).join(","),fillOpacity:0,stroke:"currentcolor"},"&-circle-bg":{stroke:e.colorFillSecondary}},[`&-sm ${t}-dot`]:{"&, &-holder":{fontSize:e.dotSizeSM}},[`&-sm ${t}-dot-holder`]:{i:{width:n(n(e.dotSizeSM).sub(n(e.marginXXS).div(2))).div(2).equal(),height:n(n(e.dotSizeSM).sub(n(e.marginXXS).div(2))).div(2).equal()}},[`&-lg ${t}-dot`]:{"&, &-holder":{fontSize:e.dotSizeLG}},[`&-lg ${t}-dot-holder`]:{i:{width:n(n(e.dotSizeLG).sub(e.marginXXS)).div(2).equal(),height:n(n(e.dotSizeLG).sub(e.marginXXS)).div(2).equal()}},[`&${t}-show-text ${t}-text`]:{display:"block"}})}})((0,b.mergeToken)(e,{spinDotDefault:e.colorTextDescription})),e=>{let{controlHeightLG:t,controlHeight:n}=e;return{contentHeight:400,dotSize:t/2,dotSizeSM:.35*t,dotSizeLG:n}}),y=[[30,.05],[70,.03],[96,.01]];var v=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,i=Object.getOwnPropertySymbols(e);at.indexOf(i[a])&&Object.prototype.propertyIsEnumerable.call(e,i[a])&&(n[i[a]]=e[i[a]]);return n};let S=e=>{var l;let{prefixCls:o,spinning:r=!0,delay:s=0,className:d,rootClassName:c,size:m="default",tip:p,wrapperClassName:g,style:b,children:f,fullscreen:h=!1,indicator:S,percent:O}=e,x=v(e,["prefixCls","spinning","delay","className","rootClassName","size","tip","wrapperClassName","style","children","fullscreen","indicator","percent"]),{getPrefixCls:j,direction:w,className:E,style:z,indicator:C}=(0,a.useComponentConfig)("spin"),N=j("spin",o),[k,I,T]=$(N),[P,L]=n.useState(()=>r&&(!r||!s||!!Number.isNaN(Number(s)))),M=function(e,t){let[i,a]=n.useState(0),l=n.useRef(null),o="auto"===t;return n.useEffect(()=>(o&&e&&(a(0),l.current=setInterval(()=>{a(e=>{let t=100-e;for(let n=0;n{l.current&&(clearInterval(l.current),l.current=null)}),[o,e]),o?i:t}(P,O);n.useEffect(()=>{if(r){let e=function(e,t,n){var i,a=n||{},l=a.noTrailing,o=void 0!==l&&l,r=a.noLeading,s=void 0!==r&&r,d=a.debounceMode,c=void 0===d?void 0:d,u=!1,m=0;function p(){i&&clearTimeout(i)}function g(){for(var n=arguments.length,a=Array(n),l=0;le?s?(m=Date.now(),o||(i=setTimeout(c?b:g,e))):g():!0!==o&&(i=setTimeout(c?b:g,void 0===c?e-d:e)))}return g.cancel=function(e){var t=(e||{}).upcomingOnly;p(),u=!(void 0!==t&&t)},g}(s,()=>{L(!0)},{debounceMode:false});return e(),()=>{var t;null==(t=null==e?void 0:e.cancel)||t.call(e)}}L(!1)},[s,r]);let B=n.useMemo(()=>void 0!==f&&!h,[f,h]),D=(0,i.default)(N,E,{[`${N}-sm`]:"small"===m,[`${N}-lg`]:"large"===m,[`${N}-spinning`]:P,[`${N}-show-text`]:!!p,[`${N}-rtl`]:"rtl"===w},d,!h&&c,I,T),G=(0,i.default)(`${N}-container`,{[`${N}-blur`]:P}),R=null!=(l=null!=S?S:C)?l:t,H=Object.assign(Object.assign({},z),b),W=n.createElement("div",Object.assign({},x,{style:H,className:D,"aria-live":"polite","aria-busy":P}),n.createElement(u,{prefixCls:N,indicator:R,percent:M}),p&&(B||h)?n.createElement("div",{className:`${N}-text`},p):null);return k(B?n.createElement("div",Object.assign({},x,{className:(0,i.default)(`${N}-nested-loading`,g,I,T)}),P&&n.createElement("div",{key:"loading"},W),n.createElement("div",{className:G,key:"container"},f)):h?n.createElement("div",{className:(0,i.default)(`${N}-fullscreen`,{[`${N}-fullscreen-show`]:P},c,I,T)},W):W)};S.setDefaultIndicator=e=>{t=e},e.s(["default",0,S],244451)},175712,e=>{"use strict";e.i(247167);var t=e.i(271645),n=e.i(343794),i=e.i(529681),a=e.i(242064),l=e.i(517455),o=e.i(185793),r=e.i(721369),s=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,i=Object.getOwnPropertySymbols(e);at.indexOf(i[a])&&Object.prototype.propertyIsEnumerable.call(e,i[a])&&(n[i[a]]=e[i[a]]);return n};let d=e=>{var{prefixCls:i,className:l,hoverable:o=!0}=e,r=s(e,["prefixCls","className","hoverable"]);let{getPrefixCls:d}=t.useContext(a.ConfigContext),c=d("card",i),u=(0,n.default)(`${c}-grid`,l,{[`${c}-grid-hoverable`]:o});return t.createElement("div",Object.assign({},r,{className:u}))};e.i(296059);var c=e.i(915654),u=e.i(183293),m=e.i(246422),p=e.i(838378);let g=(0,m.genStyleHooks)("Card",e=>{let t=(0,p.mergeToken)(e,{cardShadow:e.boxShadowCard,cardHeadPadding:e.padding,cardPaddingBase:e.paddingLG,cardActionsIconSize:e.fontSize});return[(e=>{let{componentCls:t,cardShadow:n,cardHeadPadding:i,colorBorderSecondary:a,boxShadowTertiary:l,bodyPadding:o,extraColor:r}=e;return{[t]:Object.assign(Object.assign({},(0,u.resetComponent)(e)),{position:"relative",background:e.colorBgContainer,borderRadius:e.borderRadiusLG,[`&:not(${t}-bordered)`]:{boxShadow:l},[`${t}-head`]:(e=>{let{antCls:t,componentCls:n,headerHeight:i,headerPadding:a,tabsMarginBottom:l}=e;return Object.assign(Object.assign({display:"flex",justifyContent:"center",flexDirection:"column",minHeight:i,marginBottom:-1,padding:`0 ${(0,c.unit)(a)}`,color:e.colorTextHeading,fontWeight:e.fontWeightStrong,fontSize:e.headerFontSize,background:e.headerBg,borderBottom:`${(0,c.unit)(e.lineWidth)} ${e.lineType} ${e.colorBorderSecondary}`,borderRadius:`${(0,c.unit)(e.borderRadiusLG)} ${(0,c.unit)(e.borderRadiusLG)} 0 0`},(0,u.clearFix)()),{"&-wrapper":{width:"100%",display:"flex",alignItems:"center"},"&-title":Object.assign(Object.assign({display:"inline-block",flex:1},u.textEllipsis),{[` - > ${n}-typography, - > ${n}-typography-edit-content - `]:{insetInlineStart:0,marginTop:0,marginBottom:0}}),[`${t}-tabs-top`]:{clear:"both",marginBottom:l,color:e.colorText,fontWeight:"normal",fontSize:e.fontSize,"&-bar":{borderBottom:`${(0,c.unit)(e.lineWidth)} ${e.lineType} ${e.colorBorderSecondary}`}}})})(e),[`${t}-extra`]:{marginInlineStart:"auto",color:r,fontWeight:"normal",fontSize:e.fontSize},[`${t}-body`]:{padding:o,borderRadius:`0 0 ${(0,c.unit)(e.borderRadiusLG)} ${(0,c.unit)(e.borderRadiusLG)}`},[`${t}-grid`]:(e=>{let{cardPaddingBase:t,colorBorderSecondary:n,cardShadow:i,lineWidth:a}=e;return{width:"33.33%",padding:t,border:0,borderRadius:0,boxShadow:` - ${(0,c.unit)(a)} 0 0 0 ${n}, - 0 ${(0,c.unit)(a)} 0 0 ${n}, - ${(0,c.unit)(a)} ${(0,c.unit)(a)} 0 0 ${n}, - ${(0,c.unit)(a)} 0 0 0 ${n} inset, - 0 ${(0,c.unit)(a)} 0 0 ${n} inset; - `,transition:`all ${e.motionDurationMid}`,"&-hoverable:hover":{position:"relative",zIndex:1,boxShadow:i}}})(e),[`${t}-cover`]:{"> *":{display:"block",width:"100%",borderRadius:`${(0,c.unit)(e.borderRadiusLG)} ${(0,c.unit)(e.borderRadiusLG)} 0 0`}},[`${t}-actions`]:(e=>{let{componentCls:t,iconCls:n,actionsLiMargin:i,cardActionsIconSize:a,colorBorderSecondary:l,actionsBg:o}=e;return Object.assign(Object.assign({margin:0,padding:0,listStyle:"none",background:o,borderTop:`${(0,c.unit)(e.lineWidth)} ${e.lineType} ${l}`,display:"flex",borderRadius:`0 0 ${(0,c.unit)(e.borderRadiusLG)} ${(0,c.unit)(e.borderRadiusLG)}`},(0,u.clearFix)()),{"& > li":{margin:i,color:e.colorTextDescription,textAlign:"center","> span":{position:"relative",display:"block",minWidth:e.calc(e.cardActionsIconSize).mul(2).equal(),fontSize:e.fontSize,lineHeight:e.lineHeight,cursor:"pointer","&:hover":{color:e.colorPrimary,transition:`color ${e.motionDurationMid}`},[`a:not(${t}-btn), > ${n}`]:{display:"inline-block",width:"100%",color:e.colorIcon,lineHeight:(0,c.unit)(e.fontHeight),transition:`color ${e.motionDurationMid}`,"&:hover":{color:e.colorPrimary}},[`> ${n}`]:{fontSize:a,lineHeight:(0,c.unit)(e.calc(a).mul(e.lineHeight).equal())}},"&:not(:last-child)":{borderInlineEnd:`${(0,c.unit)(e.lineWidth)} ${e.lineType} ${l}`}}})})(e),[`${t}-meta`]:Object.assign(Object.assign({margin:`${(0,c.unit)(e.calc(e.marginXXS).mul(-1).equal())} 0`,display:"flex"},(0,u.clearFix)()),{"&-avatar":{paddingInlineEnd:e.padding},"&-detail":{overflow:"hidden",flex:1,"> div:not(:last-child)":{marginBottom:e.marginXS}},"&-title":Object.assign({color:e.colorTextHeading,fontWeight:e.fontWeightStrong,fontSize:e.fontSizeLG},u.textEllipsis),"&-description":{color:e.colorTextDescription}})}),[`${t}-bordered`]:{border:`${(0,c.unit)(e.lineWidth)} ${e.lineType} ${a}`,[`${t}-cover`]:{marginTop:-1,marginInlineStart:-1,marginInlineEnd:-1}},[`${t}-hoverable`]:{cursor:"pointer",transition:`box-shadow ${e.motionDurationMid}, border-color ${e.motionDurationMid}`,"&:hover":{borderColor:"transparent",boxShadow:n}},[`${t}-contain-grid`]:{borderRadius:`${(0,c.unit)(e.borderRadiusLG)} ${(0,c.unit)(e.borderRadiusLG)} 0 0 `,[`${t}-body`]:{display:"flex",flexWrap:"wrap"},[`&:not(${t}-loading) ${t}-body`]:{marginBlockStart:e.calc(e.lineWidth).mul(-1).equal(),marginInlineStart:e.calc(e.lineWidth).mul(-1).equal(),padding:0}},[`${t}-contain-tabs`]:{[`> div${t}-head`]:{minHeight:0,[`${t}-head-title, ${t}-extra`]:{paddingTop:i}}},[`${t}-type-inner`]:(e=>{let{componentCls:t,colorFillAlter:n,headerPadding:i,bodyPadding:a}=e;return{[`${t}-head`]:{padding:`0 ${(0,c.unit)(i)}`,background:n,"&-title":{fontSize:e.fontSize}},[`${t}-body`]:{padding:`${(0,c.unit)(e.padding)} ${(0,c.unit)(a)}`}}})(e),[`${t}-loading`]:(e=>{let{componentCls:t}=e;return{overflow:"hidden",[`${t}-body`]:{userSelect:"none"}}})(e),[`${t}-rtl`]:{direction:"rtl"}}})(t),(e=>{let{componentCls:t,bodyPaddingSM:n,headerPaddingSM:i,headerHeightSM:a,headerFontSizeSM:l}=e;return{[`${t}-small`]:{[`> ${t}-head`]:{minHeight:a,padding:`0 ${(0,c.unit)(i)}`,fontSize:l,[`> ${t}-head-wrapper`]:{[`> ${t}-extra`]:{fontSize:e.fontSize}}},[`> ${t}-body`]:{padding:n}},[`${t}-small${t}-contain-tabs`]:{[`> ${t}-head`]:{[`${t}-head-title, ${t}-extra`]:{paddingTop:0,display:"flex",alignItems:"center"}}}}})(t)]},e=>{var t,n;return{headerBg:"transparent",headerFontSize:e.fontSizeLG,headerFontSizeSM:e.fontSize,headerHeight:e.fontSizeLG*e.lineHeightLG+2*e.padding,headerHeightSM:e.fontSize*e.lineHeight+2*e.paddingXS,actionsBg:e.colorBgContainer,actionsLiMargin:`${e.paddingSM}px 0`,tabsMarginBottom:-e.padding-e.lineWidth,extraColor:e.colorText,bodyPaddingSM:12,headerPaddingSM:12,bodyPadding:null!=(t=e.bodyPadding)?t:e.paddingLG,headerPadding:null!=(n=e.headerPadding)?n:e.paddingLG}});var b=e.i(792812),f=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,i=Object.getOwnPropertySymbols(e);at.indexOf(i[a])&&Object.prototype.propertyIsEnumerable.call(e,i[a])&&(n[i[a]]=e[i[a]]);return n};let h=e=>{let{actionClasses:n,actions:i=[],actionStyle:a}=e;return t.createElement("ul",{className:n,style:a},i.map((e,n)=>{let a=`action-${n}`;return t.createElement("li",{style:{width:`${100/i.length}%`},key:a},t.createElement("span",null,e))}))},$=t.forwardRef((e,s)=>{let c,{prefixCls:u,className:m,rootClassName:p,style:$,extra:y,headStyle:v={},bodyStyle:S={},title:O,loading:x,bordered:j,variant:w,size:E,type:z,cover:C,actions:N,tabList:k,children:I,activeTabKey:T,defaultActiveTabKey:P,tabBarExtraContent:L,hoverable:M,tabProps:B={},classNames:D,styles:G}=e,R=f(e,["prefixCls","className","rootClassName","style","extra","headStyle","bodyStyle","title","loading","bordered","variant","size","type","cover","actions","tabList","children","activeTabKey","defaultActiveTabKey","tabBarExtraContent","hoverable","tabProps","classNames","styles"]),{getPrefixCls:H,direction:W,card:X}=t.useContext(a.ConfigContext),[q]=(0,b.default)("card",w,j),A=e=>{var t;return(0,n.default)(null==(t=null==X?void 0:X.classNames)?void 0:t[e],null==D?void 0:D[e])},F=e=>{var t;return Object.assign(Object.assign({},null==(t=null==X?void 0:X.styles)?void 0:t[e]),null==G?void 0:G[e])},K=t.useMemo(()=>{let e=!1;return t.Children.forEach(I,t=>{(null==t?void 0:t.type)===d&&(e=!0)}),e},[I]),U=H("card",u),[V,J,Q]=g(U),Y=t.createElement(o.default,{loading:!0,active:!0,paragraph:{rows:4},title:!1},I),Z=void 0!==T,_=Object.assign(Object.assign({},B),{[Z?"activeKey":"defaultActiveKey"]:Z?T:P,tabBarExtraContent:L}),ee=(0,l.default)(E),et=ee&&"default"!==ee?ee:"large",en=k?t.createElement(r.default,Object.assign({size:et},_,{className:`${U}-head-tabs`,onChange:t=>{var n;null==(n=e.onTabChange)||n.call(e,t)},items:k.map(e=>{var{tab:t}=e;return Object.assign({label:t},f(e,["tab"]))})})):null;if(O||y||en){let e=(0,n.default)(`${U}-head`,A("header")),i=(0,n.default)(`${U}-head-title`,A("title")),a=(0,n.default)(`${U}-extra`,A("extra")),l=Object.assign(Object.assign({},v),F("header"));c=t.createElement("div",{className:e,style:l},t.createElement("div",{className:`${U}-head-wrapper`},O&&t.createElement("div",{className:i,style:F("title")},O),y&&t.createElement("div",{className:a,style:F("extra")},y)),en)}let ei=(0,n.default)(`${U}-cover`,A("cover")),ea=C?t.createElement("div",{className:ei,style:F("cover")},C):null,el=(0,n.default)(`${U}-body`,A("body")),eo=Object.assign(Object.assign({},S),F("body")),er=t.createElement("div",{className:el,style:eo},x?Y:I),es=(0,n.default)(`${U}-actions`,A("actions")),ed=(null==N?void 0:N.length)?t.createElement(h,{actionClasses:es,actionStyle:F("actions"),actions:N}):null,ec=(0,i.default)(R,["onTabChange"]),eu=(0,n.default)(U,null==X?void 0:X.className,{[`${U}-loading`]:x,[`${U}-bordered`]:"borderless"!==q,[`${U}-hoverable`]:M,[`${U}-contain-grid`]:K,[`${U}-contain-tabs`]:null==k?void 0:k.length,[`${U}-${ee}`]:ee,[`${U}-type-${z}`]:!!z,[`${U}-rtl`]:"rtl"===W},m,p,J,Q),em=Object.assign(Object.assign({},null==X?void 0:X.style),$);return V(t.createElement("div",Object.assign({ref:s},ec,{className:eu,style:em}),c,ea,er,ed))});var y=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,i=Object.getOwnPropertySymbols(e);at.indexOf(i[a])&&Object.prototype.propertyIsEnumerable.call(e,i[a])&&(n[i[a]]=e[i[a]]);return n};$.Grid=d,$.Meta=e=>{let{prefixCls:i,className:l,avatar:o,title:r,description:s}=e,d=y(e,["prefixCls","className","avatar","title","description"]),{getPrefixCls:c}=t.useContext(a.ConfigContext),u=c("card",i),m=(0,n.default)(`${u}-meta`,l),p=o?t.createElement("div",{className:`${u}-meta-avatar`},o):null,g=r?t.createElement("div",{className:`${u}-meta-title`},r):null,b=s?t.createElement("div",{className:`${u}-meta-description`},s):null,f=g||b?t.createElement("div",{className:`${u}-meta-detail`},g,b):null;return t.createElement("div",Object.assign({},d,{className:m}),p,f)},e.s(["Card",0,$],175712)},869216,e=>{"use strict";e.i(247167);var t=e.i(271645),n=e.i(343794),i=e.i(908206),a=e.i(242064),l=e.i(517455),o=e.i(150073);let r={xxl:3,xl:3,lg:3,md:3,sm:2,xs:1},s=t.default.createContext({});var d=e.i(876556),c=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,i=Object.getOwnPropertySymbols(e);at.indexOf(i[a])&&Object.prototype.propertyIsEnumerable.call(e,i[a])&&(n[i[a]]=e[i[a]]);return n},u=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,i=Object.getOwnPropertySymbols(e);at.indexOf(i[a])&&Object.prototype.propertyIsEnumerable.call(e,i[a])&&(n[i[a]]=e[i[a]]);return n};let m=e=>{let{itemPrefixCls:i,component:a,span:l,className:o,style:r,labelStyle:d,contentStyle:c,bordered:u,label:m,content:p,colon:g,type:b,styles:f}=e,{classNames:h}=t.useContext(s),$=Object.assign(Object.assign({},d),null==f?void 0:f.label),y=Object.assign(Object.assign({},c),null==f?void 0:f.content);if(u)return t.createElement(a,{colSpan:l,style:r,className:(0,n.default)(o,{[`${i}-item-${b}`]:"label"===b||"content"===b,[null==h?void 0:h.label]:(null==h?void 0:h.label)&&"label"===b,[null==h?void 0:h.content]:(null==h?void 0:h.content)&&"content"===b})},null!=m&&t.createElement("span",{style:$},m),null!=p&&t.createElement("span",{style:y},p));return t.createElement(a,{colSpan:l,style:r,className:(0,n.default)(`${i}-item`,o)},t.createElement("div",{className:`${i}-item-container`},null!=m&&t.createElement("span",{style:$,className:(0,n.default)(`${i}-item-label`,null==h?void 0:h.label,{[`${i}-item-no-colon`]:!g})},m),null!=p&&t.createElement("span",{style:y,className:(0,n.default)(`${i}-item-content`,null==h?void 0:h.content)},p)))};function p(e,{colon:n,prefixCls:i,bordered:a},{component:l,type:o,showLabel:r,showContent:s,labelStyle:d,contentStyle:c,styles:u}){return e.map(({label:e,children:p,prefixCls:g=i,className:b,style:f,labelStyle:h,contentStyle:$,span:y=1,key:v,styles:S},O)=>"string"==typeof l?t.createElement(m,{key:`${o}-${v||O}`,className:b,style:f,styles:{label:Object.assign(Object.assign(Object.assign(Object.assign({},d),null==u?void 0:u.label),h),null==S?void 0:S.label),content:Object.assign(Object.assign(Object.assign(Object.assign({},c),null==u?void 0:u.content),$),null==S?void 0:S.content)},span:y,colon:n,component:l,itemPrefixCls:g,bordered:a,label:r?e:null,content:s?p:null,type:o}):[t.createElement(m,{key:`label-${v||O}`,className:b,style:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},d),null==u?void 0:u.label),f),h),null==S?void 0:S.label),span:1,colon:n,component:l[0],itemPrefixCls:g,bordered:a,label:e,type:"label"}),t.createElement(m,{key:`content-${v||O}`,className:b,style:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},c),null==u?void 0:u.content),f),$),null==S?void 0:S.content),span:2*y-1,component:l[1],itemPrefixCls:g,bordered:a,content:p,type:"content"})])}let g=e=>{let n=t.useContext(s),{prefixCls:i,vertical:a,row:l,index:o,bordered:r}=e;return a?t.createElement(t.Fragment,null,t.createElement("tr",{key:`label-${o}`,className:`${i}-row`},p(l,e,Object.assign({component:"th",type:"label",showLabel:!0},n))),t.createElement("tr",{key:`content-${o}`,className:`${i}-row`},p(l,e,Object.assign({component:"td",type:"content",showContent:!0},n)))):t.createElement("tr",{key:o,className:`${i}-row`},p(l,e,Object.assign({component:r?["th","td"]:"td",type:"item",showLabel:!0,showContent:!0},n)))};e.i(296059);var b=e.i(915654),f=e.i(183293),h=e.i(246422),$=e.i(838378);let y=(0,h.genStyleHooks)("Descriptions",e=>(e=>{let{componentCls:t,extraColor:n,itemPaddingBottom:i,itemPaddingEnd:a,colonMarginRight:l,colonMarginLeft:o,titleMarginBottom:r}=e;return{[t]:Object.assign(Object.assign(Object.assign({},(0,f.resetComponent)(e)),(e=>{let{componentCls:t,labelBg:n}=e;return{[`&${t}-bordered`]:{[`> ${t}-view`]:{border:`${(0,b.unit)(e.lineWidth)} ${e.lineType} ${e.colorSplit}`,"> table":{tableLayout:"auto"},[`${t}-row`]:{borderBottom:`${(0,b.unit)(e.lineWidth)} ${e.lineType} ${e.colorSplit}`,"&:first-child":{"> th:first-child, > td:first-child":{borderStartStartRadius:e.borderRadiusLG}},"&:last-child":{borderBottom:"none","> th:first-child, > td:first-child":{borderEndStartRadius:e.borderRadiusLG}},[`> ${t}-item-label, > ${t}-item-content`]:{padding:`${(0,b.unit)(e.padding)} ${(0,b.unit)(e.paddingLG)}`,borderInlineEnd:`${(0,b.unit)(e.lineWidth)} ${e.lineType} ${e.colorSplit}`,"&:last-child":{borderInlineEnd:"none"}},[`> ${t}-item-label`]:{color:e.colorTextSecondary,backgroundColor:n,"&::after":{display:"none"}}}},[`&${t}-middle`]:{[`${t}-row`]:{[`> ${t}-item-label, > ${t}-item-content`]:{padding:`${(0,b.unit)(e.paddingSM)} ${(0,b.unit)(e.paddingLG)}`}}},[`&${t}-small`]:{[`${t}-row`]:{[`> ${t}-item-label, > ${t}-item-content`]:{padding:`${(0,b.unit)(e.paddingXS)} ${(0,b.unit)(e.padding)}`}}}}}})(e)),{"&-rtl":{direction:"rtl"},[`${t}-header`]:{display:"flex",alignItems:"center",marginBottom:r},[`${t}-title`]:Object.assign(Object.assign({},f.textEllipsis),{flex:"auto",color:e.titleColor,fontWeight:e.fontWeightStrong,fontSize:e.fontSizeLG,lineHeight:e.lineHeightLG}),[`${t}-extra`]:{marginInlineStart:"auto",color:n,fontSize:e.fontSize},[`${t}-view`]:{width:"100%",borderRadius:e.borderRadiusLG,table:{width:"100%",tableLayout:"fixed",borderCollapse:"collapse"}},[`${t}-row`]:{"> th, > td":{paddingBottom:i,paddingInlineEnd:a},"> th:last-child, > td:last-child":{paddingInlineEnd:0},"&:last-child":{borderBottom:"none","> th, > td":{paddingBottom:0}}},[`${t}-item-label`]:{color:e.labelColor,fontWeight:"normal",fontSize:e.fontSize,lineHeight:e.lineHeight,textAlign:"start","&::after":{content:'":"',position:"relative",top:-.5,marginInline:`${(0,b.unit)(o)} ${(0,b.unit)(l)}`},[`&${t}-item-no-colon::after`]:{content:'""'}},[`${t}-item-no-label`]:{"&::after":{margin:0,content:'""'}},[`${t}-item-content`]:{display:"table-cell",flex:1,color:e.contentColor,fontSize:e.fontSize,lineHeight:e.lineHeight,wordBreak:"break-word",overflowWrap:"break-word"},[`${t}-item`]:{paddingBottom:0,verticalAlign:"top","&-container":{display:"flex",[`${t}-item-label`]:{display:"inline-flex",alignItems:"baseline"},[`${t}-item-content`]:{display:"inline-flex",alignItems:"baseline",minWidth:"1em"}}},"&-middle":{[`${t}-row`]:{"> th, > td":{paddingBottom:e.paddingSM}}},"&-small":{[`${t}-row`]:{"> th, > td":{paddingBottom:e.paddingXS}}}})}})((0,$.mergeToken)(e,{})),e=>({labelBg:e.colorFillAlter,labelColor:e.colorTextTertiary,titleColor:e.colorText,titleMarginBottom:e.fontSizeSM*e.lineHeightSM,itemPaddingBottom:e.padding,itemPaddingEnd:e.padding,colonMarginRight:e.marginXS,colonMarginLeft:e.marginXXS/2,contentColor:e.colorText,extraColor:e.colorText}));var v=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,i=Object.getOwnPropertySymbols(e);at.indexOf(i[a])&&Object.prototype.propertyIsEnumerable.call(e,i[a])&&(n[i[a]]=e[i[a]]);return n};let S=e=>{let m,{prefixCls:p,title:b,extra:f,column:h,colon:$=!0,bordered:S,layout:O,children:x,className:j,rootClassName:w,style:E,size:z,labelStyle:C,contentStyle:N,styles:k,items:I,classNames:T}=e,P=v(e,["prefixCls","title","extra","column","colon","bordered","layout","children","className","rootClassName","style","size","labelStyle","contentStyle","styles","items","classNames"]),{getPrefixCls:L,direction:M,className:B,style:D,classNames:G,styles:R}=(0,a.useComponentConfig)("descriptions"),H=L("descriptions",p),W=(0,o.default)(),X=t.useMemo(()=>{var e;return"number"==typeof h?h:null!=(e=(0,i.matchScreen)(W,Object.assign(Object.assign({},r),h)))?e:3},[W,h]),q=(m=t.useMemo(()=>I||(0,d.default)(x).map(e=>Object.assign(Object.assign({},null==e?void 0:e.props),{key:e.key})),[I,x]),t.useMemo(()=>m.map(e=>{var{span:t}=e,n=c(e,["span"]);return"filled"===t?Object.assign(Object.assign({},n),{filled:!0}):Object.assign(Object.assign({},n),{span:"number"==typeof t?t:(0,i.matchScreen)(W,t)})}),[m,W])),A=(0,l.default)(z),F=((e,n)=>{let[i,a]=(0,t.useMemo)(()=>{let t,i,a,l;return t=[],i=[],a=!1,l=0,n.filter(e=>e).forEach(n=>{let{filled:o}=n,r=u(n,["filled"]);if(o){i.push(r),t.push(i),i=[],l=0;return}let s=e-l;(l+=n.span||1)>=e?(l>e?(a=!0,i.push(Object.assign(Object.assign({},r),{span:s}))):i.push(r),t.push(i),i=[],l=0):i.push(r)}),i.length>0&&t.push(i),[t=t.map(t=>{let n=t.reduce((e,t)=>e+(t.span||1),0);if(n({labelStyle:C,contentStyle:N,styles:{content:Object.assign(Object.assign({},R.content),null==k?void 0:k.content),label:Object.assign(Object.assign({},R.label),null==k?void 0:k.label)},classNames:{label:(0,n.default)(G.label,null==T?void 0:T.label),content:(0,n.default)(G.content,null==T?void 0:T.content)}}),[C,N,k,T,G,R]);return K(t.createElement(s.Provider,{value:J},t.createElement("div",Object.assign({className:(0,n.default)(H,B,G.root,null==T?void 0:T.root,{[`${H}-${A}`]:A&&"default"!==A,[`${H}-bordered`]:!!S,[`${H}-rtl`]:"rtl"===M},j,w,U,V),style:Object.assign(Object.assign(Object.assign(Object.assign({},D),R.root),null==k?void 0:k.root),E)},P),(b||f)&&t.createElement("div",{className:(0,n.default)(`${H}-header`,G.header,null==T?void 0:T.header),style:Object.assign(Object.assign({},R.header),null==k?void 0:k.header)},b&&t.createElement("div",{className:(0,n.default)(`${H}-title`,G.title,null==T?void 0:T.title),style:Object.assign(Object.assign({},R.title),null==k?void 0:k.title)},b),f&&t.createElement("div",{className:(0,n.default)(`${H}-extra`,G.extra,null==T?void 0:T.extra),style:Object.assign(Object.assign({},R.extra),null==k?void 0:k.extra)},f)),t.createElement("div",{className:`${H}-view`},t.createElement("table",null,t.createElement("tbody",null,F.map((e,n)=>t.createElement(g,{key:n,index:n,colon:$,prefixCls:H,vertical:"vertical"===O,bordered:S,row:e}))))))))};S.Item=({children:e})=>e,e.s(["Descriptions",0,S],869216)},285027,e=>{"use strict";e.i(247167);var t=e.i(931067),n=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"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"};var a=e.i(9583),l=n.forwardRef(function(e,l){return n.createElement(a.default,(0,t.default)({},e,{ref:l,icon:i}))});e.s(["WarningOutlined",0,l],285027)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/00-dyuivh_bf-.js b/litellm/proxy/_experimental/out/_next/static/chunks/00-dyuivh_bf-.js new file mode 100644 index 00000000000..ef1e3d6ad94 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/00-dyuivh_bf-.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,95779,e=>{"use strict";var t=e.i(480731);t.BaseColors.Blue,t.BaseColors.Cyan,t.BaseColors.Sky,t.BaseColors.Indigo,t.BaseColors.Violet,t.BaseColors.Purple,t.BaseColors.Fuchsia,t.BaseColors.Slate,t.BaseColors.Gray,t.BaseColors.Zinc,t.BaseColors.Neutral,t.BaseColors.Stone,t.BaseColors.Red,t.BaseColors.Orange,t.BaseColors.Amber,t.BaseColors.Yellow,t.BaseColors.Lime,t.BaseColors.Green,t.BaseColors.Emerald,t.BaseColors.Teal,t.BaseColors.Pink,t.BaseColors.Rose,e.s(["colorPalette",0,{canvasBackground:50,lightBackground:100,background:500,darkBackground:600,darkestBackground:800,lightBorder:200,border:500,darkBorder:700,lightRing:200,ring:300,iconRing:500,lightText:400,text:500,iconText:600,darkText:700,darkestText:900,icon:500}])},599724,936325,e=>{"use strict";var t=e.i(95779),r=e.i(444755),o=e.i(673706),a=e.i(271645);let n=a.default.forwardRef((e,n)=>{let{color:s,className:l,children:i}=e;return a.default.createElement("p",{ref:n,className:(0,r.tremorTwMerge)("text-tremor-default",s?(0,o.getColorClassNames)(s,t.colorPalette.text).textColor:(0,r.tremorTwMerge)("text-tremor-content","dark:text-dark-tremor-content"),l)},i)});n.displayName="Text",e.s(["default",0,n],936325),e.s(["Text",0,n],599724)},994388,e=>{"use strict";var t=e.i(290571),r=e.i(829087),o=e.i(271645);let a=["preEnter","entering","entered","preExit","exiting","exited","unmounted"],n=e=>({_s:e,status:a[e],isEnter:e<3,isMounted:6!==e,isResolved:2===e||e>4}),s=e=>e?6:5,l=(e,t,r,o,a)=>{clearTimeout(o.current);let s=n(e);t(s),r.current=s,a&&a({current:s})};var i=e.i(480731),c=e.i(444755),d=e.i(673706);let u=e=>{var r=(0,t.__rest)(e,[]);return o.default.createElement("svg",Object.assign({},r,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"}),o.default.createElement("path",{fill:"none",d:"M0 0h24v24H0z"}),o.default.createElement("path",{d:"M18.364 5.636L16.95 7.05A7 7 0 1 0 19 12h2a9 9 0 1 1-2.636-6.364z"}))};var m=e.i(95779);let f={xs:{height:"h-4",width:"w-4"},sm:{height:"h-5",width:"w-5"},md:{height:"h-5",width:"w-5"},lg:{height:"h-6",width:"w-6"},xl:{height:"h-6",width:"w-6"}},p=(e,t)=>{switch(e){case"primary":return{textColor:t?(0,d.getColorClassNames)("white").textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",hoverTextColor:t?(0,d.getColorClassNames)("white").textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",bgColor:t?(0,d.getColorClassNames)(t,m.colorPalette.background).bgColor:"bg-tremor-brand dark:bg-dark-tremor-brand",hoverBgColor:t?(0,d.getColorClassNames)(t,m.colorPalette.darkBackground).hoverBgColor:"hover:bg-tremor-brand-emphasis dark:hover:bg-dark-tremor-brand-emphasis",borderColor:t?(0,d.getColorClassNames)(t,m.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand",hoverBorderColor:t?(0,d.getColorClassNames)(t,m.colorPalette.darkBorder).hoverBorderColor:"hover:border-tremor-brand-emphasis dark:hover:border-dark-tremor-brand-emphasis"};case"secondary":return{textColor:t?(0,d.getColorClassNames)(t,m.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",hoverTextColor:t?(0,d.getColorClassNames)(t,m.colorPalette.text).textColor:"hover:text-tremor-brand-emphasis dark:hover:text-dark-tremor-brand-emphasis",bgColor:(0,d.getColorClassNames)("transparent").bgColor,hoverBgColor:t?(0,c.tremorTwMerge)((0,d.getColorClassNames)(t,m.colorPalette.background).hoverBgColor,"hover:bg-opacity-20 dark:hover:bg-opacity-20"):"hover:bg-tremor-brand-faint dark:hover:bg-dark-tremor-brand-faint",borderColor:t?(0,d.getColorClassNames)(t,m.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand"};case"light":return{textColor:t?(0,d.getColorClassNames)(t,m.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",hoverTextColor:t?(0,d.getColorClassNames)(t,m.colorPalette.darkText).hoverTextColor:"hover:text-tremor-brand-emphasis dark:hover:text-dark-tremor-brand-emphasis",bgColor:(0,d.getColorClassNames)("transparent").bgColor,borderColor:"",hoverBorderColor:""}}},g=(0,d.makeClassName)("Button"),b=({loading:e,iconSize:t,iconPosition:r,Icon:a,needMargin:n,transitionStatus:s})=>{let l=n?r===i.HorizontalPositions.Left?(0,c.tremorTwMerge)("-ml-1","mr-1.5"):(0,c.tremorTwMerge)("-mr-1","ml-1.5"):"",d=(0,c.tremorTwMerge)("w-0 h-0"),m={default:d,entering:d,entered:t,exiting:t,exited:d};return e?o.default.createElement(u,{className:(0,c.tremorTwMerge)(g("icon"),"animate-spin shrink-0",l,m.default,m[s]),style:{transition:"width 150ms"}}):o.default.createElement(a,{className:(0,c.tremorTwMerge)(g("icon"),"shrink-0",t,l)})},h=o.default.forwardRef((e,a)=>{let{icon:u,iconPosition:m=i.HorizontalPositions.Left,size:h=i.Sizes.SM,color:x,variant:v="primary",disabled:C,loading:y=!1,loadingText:k,children:w,tooltip:E,className:T}=e,N=(0,t.__rest)(e,["icon","iconPosition","size","color","variant","disabled","loading","loadingText","children","tooltip","className"]),S=y||C,$=void 0!==u||y,P=y&&k,I=!(!w&&!P),M=(0,c.tremorTwMerge)(f[h].height,f[h].width),F="light"!==v?(0,c.tremorTwMerge)("rounded-tremor-default border","shadow-tremor-input","dark:shadow-dark-tremor-input"):"",R=p(v,x),O=("light"!==v?{xs:{paddingX:"px-2.5",paddingY:"py-1.5",fontSize:"text-xs"},sm:{paddingX:"px-4",paddingY:"py-2",fontSize:"text-sm"},md:{paddingX:"px-4",paddingY:"py-2",fontSize:"text-md"},lg:{paddingX:"px-4",paddingY:"py-2.5",fontSize:"text-lg"},xl:{paddingX:"px-4",paddingY:"py-3",fontSize:"text-xl"}}:{xs:{paddingX:"",paddingY:"",fontSize:"text-xs"},sm:{paddingX:"",paddingY:"",fontSize:"text-sm"},md:{paddingX:"",paddingY:"",fontSize:"text-md"},lg:{paddingX:"",paddingY:"",fontSize:"text-lg"},xl:{paddingX:"",paddingY:"",fontSize:"text-xl"}})[h],{tooltipProps:A,getReferenceProps:B}=(0,r.useTooltip)(300),[j,D]=(({enter:e=!0,exit:t=!0,preEnter:r,preExit:a,timeout:i,initialEntered:c,mountOnEnter:d,unmountOnExit:u,onStateChange:m}={})=>{let[f,p]=(0,o.useState)(()=>n(c?2:s(d))),g=(0,o.useRef)(f),b=(0,o.useRef)(0),[h,x]="object"==typeof i?[i.enter,i.exit]:[i,i],v=(0,o.useCallback)(()=>{let e=((e,t)=>{switch(e){case 1:case 0:return 2;case 4:case 3:return s(t)}})(g.current._s,u);e&&l(e,p,g,b,m)},[m,u]);return[f,(0,o.useCallback)(o=>{let n=e=>{switch(l(e,p,g,b,m),e){case 1:h>=0&&(b.current=((...e)=>setTimeout(...e))(v,h));break;case 4:x>=0&&(b.current=((...e)=>setTimeout(...e))(v,x));break;case 0:case 3:b.current=((...e)=>setTimeout(...e))(()=>{isNaN(document.body.offsetTop)||n(e+1)},0)}},i=g.current.isEnter;"boolean"!=typeof o&&(o=!i),o?i||n(e?+!r:2):i&&n(t?a?3:4:s(u))},[v,m,e,t,r,a,h,x,u]),v]})({timeout:50});return(0,o.useEffect)(()=>{D(y)},[y]),o.default.createElement("button",Object.assign({ref:(0,d.mergeRefs)([a,A.refs.setReference]),className:(0,c.tremorTwMerge)(g("root"),"shrink-0 inline-flex justify-center items-center group font-medium outline-none",F,O.paddingX,O.paddingY,O.fontSize,R.textColor,R.bgColor,R.borderColor,R.hoverBorderColor,S?"opacity-50 cursor-not-allowed":(0,c.tremorTwMerge)(p(v,x).hoverTextColor,p(v,x).hoverBgColor,p(v,x).hoverBorderColor),T),disabled:S},B,N),o.default.createElement(r.default,Object.assign({text:E},A)),$&&m!==i.HorizontalPositions.Right?o.default.createElement(b,{loading:y,iconSize:M,iconPosition:m,Icon:u,transitionStatus:j.status,needMargin:I}):null,P||w?o.default.createElement("span",{className:(0,c.tremorTwMerge)(g("text"),"text-tremor-default whitespace-nowrap")},P?k:w):null,$&&m===i.HorizontalPositions.Right?o.default.createElement(b,{loading:y,iconSize:M,iconPosition:m,Icon:u,transitionStatus:j.status,needMargin:I}):null)});h.displayName="Button",e.s(["Button",0,h],994388)},553521,e=>{"use strict";var t=e.i(271645),r=e.i(835696);e.s(["useIsMounted",0,function(){let e=(0,t.useRef)(!1);return(0,r.useIsoMorphicEffect)(()=>(e.current=!0,()=>{e.current=!1}),[]),e}])},2788,e=>{"use strict";let t;var r=e.i(700020),o=((t=o||{})[t.None=1]="None",t[t.Focusable=2]="Focusable",t[t.Hidden=4]="Hidden",t);let a=(0,r.forwardRefWithAs)(function(e,t){var o;let{features:a=1,...n}=e,s={ref:t,"aria-hidden":(2&a)==2||(null!=(o=n["aria-hidden"])?o:void 0),hidden:(4&a)==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&a)==4&&(2&a)!=2&&{display:"none"}}};return(0,r.useRender)()({ourProps:s,theirProps:n,slot:{},defaultTag:"span",name:"Hidden"})});e.s(["Hidden",0,a,"HiddenFeatures",0,o])},652265,e=>{"use strict";let t,r,o,a,n;e.i(544508);var s=e.i(397701),l=e.i(402155);let i=["[contentEditable=true]","[tabindex]","a[href]","area[href]","button:not([disabled])","iframe","input:not([disabled])","select:not([disabled])","textarea:not([disabled])"].map(e=>`${e}:not([tabindex='-1'])`).join(","),c=["[data-autofocus]"].map(e=>`${e}:not([tabindex='-1'])`).join(",");var d=((t=d||{})[t.First=1]="First",t[t.Previous=2]="Previous",t[t.Next=4]="Next",t[t.Last=8]="Last",t[t.WrapAround=16]="WrapAround",t[t.NoScroll=32]="NoScroll",t[t.AutoFocus=64]="AutoFocus",t),u=((r=u||{})[r.Error=0]="Error",r[r.Overflow=1]="Overflow",r[r.Success=2]="Success",r[r.Underflow=3]="Underflow",r),m=((o=m||{})[o.Previous=-1]="Previous",o[o.Next=1]="Next",o);function f(e=document.body){return null==e?[]:Array.from(e.querySelectorAll(i)).sort((e,t)=>Math.sign((e.tabIndex||Number.MAX_SAFE_INTEGER)-(t.tabIndex||Number.MAX_SAFE_INTEGER)))}var p=((a=p||{})[a.Strict=0]="Strict",a[a.Loose=1]="Loose",a),g=((n=g||{})[n.Keyboard=0]="Keyboard",n[n.Mouse=1]="Mouse",n);function b(e,t=e=>e){return e.slice().sort((e,r)=>{let o=t(e),a=t(r);if(null===o||null===a)return 0;let n=o.compareDocumentPosition(a);return n&Node.DOCUMENT_POSITION_FOLLOWING?-1:n&Node.DOCUMENT_POSITION_PRECEDING?1:0})}function h(e,t,{sorted:r=!0,relativeTo:o=null,skipElements:a=[]}={}){var n,s,l;let i=Array.isArray(e)?e.length>0?e[0].ownerDocument:document:e.ownerDocument,d=Array.isArray(e)?r?b(e):e:64&t?function(e=document.body){return null==e?[]:Array.from(e.querySelectorAll(c)).sort((e,t)=>Math.sign((e.tabIndex||Number.MAX_SAFE_INTEGER)-(t.tabIndex||Number.MAX_SAFE_INTEGER)))}(e):f(e);a.length>0&&d.length>1&&(d=d.filter(e=>!a.some(t=>null!=t&&"current"in t?(null==t?void 0:t.current)===e:t===e))),o=null!=o?o:i.activeElement;let u=(()=>{if(5&t)return 1;if(10&t)return -1;throw Error("Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last")})(),m=(()=>{if(1&t)return 0;if(2&t)return Math.max(0,d.indexOf(o))-1;if(4&t)return Math.max(0,d.indexOf(o))+1;if(8&t)return d.length-1;throw Error("Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last")})(),p=32&t?{preventScroll:!0}:{},g=0,x=d.length,v;do{if(g>=x||g+x<=0)return 0;let e=m+g;if(16&t)e=(e+x)%x;else{if(e<0)return 3;if(e>=x)return 1}null==(v=d[e])||v.focus(p),g+=u}while(v!==i.activeElement)return 6&t&&null!=(l=null==(s=null==(n=v)?void 0:n.matches)?void 0:s.call(n,"textarea,input"))&&l&&v.select(),2}"u">typeof window&&"u">typeof document&&(document.addEventListener("keydown",e=>{e.metaKey||e.altKey||e.ctrlKey||(document.documentElement.dataset.headlessuiFocusVisible="")},!0),document.addEventListener("click",e=>{1===e.detail?delete document.documentElement.dataset.headlessuiFocusVisible:0===e.detail&&(document.documentElement.dataset.headlessuiFocusVisible="")},!0)),e.s(["Focus",0,d,"FocusResult",0,u,"FocusableMode",0,p,"focusFrom",0,function(e,t){return h(f(),t,{relativeTo:e})},"focusIn",0,h,"getFocusableElements",0,f,"isFocusableElement",0,function(e,t=0){var r;return e!==(null==(r=(0,l.getOwnerDocument)(e))?void 0:r.body)&&(0,s.match)(t,{0:()=>e.matches(i),1(){let t=e;for(;null!==t;){if(t.matches(i))return!0;t=t.parentElement}return!1}})},"sortByDomNode",0,b])},970554,e=>{"use strict";let t,r,o;var a=e.i(783222),n=e.i(433336),s=e.i(271645),l=e.i(394487),i=e.i(914189),c=e.i(835696),d=e.i(941444),u=e.i(144279),m=e.i(294316),f=e.i(553521),p=e.i(2788);function g({onFocus:e}){let[t,r]=(0,s.useState)(!0),o=(0,f.useIsMounted)();return t?s.default.createElement(p.Hidden,{as:"button",type:"button",features:p.HiddenFeatures.Focusable,onFocus:t=>{t.preventDefault();let a,n=50;a=requestAnimationFrame(function t(){if(n--<=0){a&&cancelAnimationFrame(a);return}if(e()){if(cancelAnimationFrame(a),!o.current)return;r(!1);return}a=requestAnimationFrame(t)})}}):null}var b=e.i(652265),h=e.i(397701),x=e.i(368578),v=e.i(402155),C=e.i(700020);let y=s.createContext(null);function k({children:e}){let t=s.useRef({groups:new Map,get(e,t){var r;let o=this.groups.get(e);o||(o=new Map,this.groups.set(e,o));let a=null!=(r=o.get(t))?r:0;return o.set(t,a+1),[Array.from(o.keys()).indexOf(t),function(){let e=o.get(t);e>1?o.set(t,e-1):o.delete(t)}]}});return s.createElement(y.Provider,{value:t},e)}function w(e){let t=s.useContext(y);if(!t)throw Error("You must wrap your component in a ");let r=s.useId(),[o,a]=t.current.get(e,r);return s.useEffect(()=>a,[]),o}var E=e.i(998348),T=((t=T||{})[t.Forwards=0]="Forwards",t[t.Backwards=1]="Backwards",t),N=((r=N||{})[r.Less=-1]="Less",r[r.Equal=0]="Equal",r[r.Greater=1]="Greater",r),S=((o=S||{})[o.SetSelectedIndex=0]="SetSelectedIndex",o[o.RegisterTab=1]="RegisterTab",o[o.UnregisterTab=2]="UnregisterTab",o[o.RegisterPanel=3]="RegisterPanel",o[o.UnregisterPanel=4]="UnregisterPanel",o);let $={0(e,t){var r;let o=(0,b.sortByDomNode)(e.tabs,e=>e.current),a=(0,b.sortByDomNode)(e.panels,e=>e.current),n=o.filter(e=>{var t;return!(null!=(t=e.current)&&t.hasAttribute("disabled"))}),s={...e,tabs:o,panels:a};if(t.index<0||t.index>o.length-1){let r=(0,h.match)(Math.sign(t.index-e.selectedIndex),{[-1]:()=>1,0:()=>(0,h.match)(Math.sign(t.index),{[-1]:()=>0,0:()=>0,1:()=>1}),1:()=>0});if(0===n.length)return s;let a=(0,h.match)(r,{0:()=>o.indexOf(n[0]),1:()=>o.indexOf(n[n.length-1])});return{...s,selectedIndex:-1===a?e.selectedIndex:a}}let l=o.slice(0,t.index),i=[...o.slice(t.index),...l].find(e=>n.includes(e));if(!i)return s;let c=null!=(r=o.indexOf(i))?r:e.selectedIndex;return -1===c&&(c=e.selectedIndex),{...s,selectedIndex:c}},1(e,t){if(e.tabs.includes(t.tab))return e;let r=e.tabs[e.selectedIndex],o=(0,b.sortByDomNode)([...e.tabs,t.tab],e=>e.current),a=e.selectedIndex;return e.info.current.isControlled||-1===(a=o.indexOf(r))&&(a=e.selectedIndex),{...e,tabs:o,selectedIndex:a}},2:(e,t)=>({...e,tabs:e.tabs.filter(e=>e!==t.tab)}),3:(e,t)=>e.panels.includes(t.panel)?e:{...e,panels:(0,b.sortByDomNode)([...e.panels,t.panel],e=>e.current)},4:(e,t)=>({...e,panels:e.panels.filter(e=>e!==t.panel)})},P=(0,s.createContext)(null);function I(e){let t=(0,s.useContext)(P);if(null===t){let t=Error(`<${e} /> is missing a parent component.`);throw Error.captureStackTrace&&Error.captureStackTrace(t,I),t}return t}P.displayName="TabsDataContext";let M=(0,s.createContext)(null);function F(e){let t=(0,s.useContext)(M);if(null===t){let t=Error(`<${e} /> is missing a parent component.`);throw Error.captureStackTrace&&Error.captureStackTrace(t,F),t}return t}function R(e,t){return(0,h.match)(t.type,$,e,t)}M.displayName="TabsActionsContext";let O=C.RenderFeatures.RenderStrategy|C.RenderFeatures.Static,A=Object.assign((0,C.forwardRefWithAs)(function(e,t){var r,o;let d=(0,s.useId)(),{id:f=`headlessui-tabs-tab-${d}`,disabled:p=!1,autoFocus:g=!1,...y}=e,{orientation:k,activation:T,selectedIndex:N,tabs:S,panels:$}=I("Tab"),P=F("Tab"),M=I("Tab"),[R,O]=(0,s.useState)(null),A=(0,s.useRef)(null),B=(0,m.useSyncRefs)(A,t,O);(0,c.useIsoMorphicEffect)(()=>P.registerTab(A),[P,A]);let j=w("tabs"),D=S.indexOf(A);-1===D&&(D=j);let z=D===N,L=(0,i.useEvent)(e=>{var t;let r=e();if(r===b.FocusResult.Success&&"auto"===T){let e=null==(t=(0,v.getOwnerDocument)(A))?void 0:t.activeElement,r=M.tabs.findIndex(t=>t.current===e);-1!==r&&P.change(r)}return r}),W=(0,i.useEvent)(e=>{let t=S.map(e=>e.current).filter(Boolean);if(e.key===E.Keys.Space||e.key===E.Keys.Enter){e.preventDefault(),e.stopPropagation(),P.change(D);return}switch(e.key){case E.Keys.Home:case E.Keys.PageUp:return e.preventDefault(),e.stopPropagation(),L(()=>(0,b.focusIn)(t,b.Focus.First));case E.Keys.End:case E.Keys.PageDown:return e.preventDefault(),e.stopPropagation(),L(()=>(0,b.focusIn)(t,b.Focus.Last))}if(L(()=>(0,h.match)(k,{vertical:()=>e.key===E.Keys.ArrowUp?(0,b.focusIn)(t,b.Focus.Previous|b.Focus.WrapAround):e.key===E.Keys.ArrowDown?(0,b.focusIn)(t,b.Focus.Next|b.Focus.WrapAround):b.FocusResult.Error,horizontal:()=>e.key===E.Keys.ArrowLeft?(0,b.focusIn)(t,b.Focus.Previous|b.Focus.WrapAround):e.key===E.Keys.ArrowRight?(0,b.focusIn)(t,b.Focus.Next|b.Focus.WrapAround):b.FocusResult.Error}))===b.FocusResult.Success)return e.preventDefault()}),_=(0,s.useRef)(!1),X=(0,i.useEvent)(()=>{var e;_.current||(_.current=!0,null==(e=A.current)||e.focus({preventScroll:!0}),P.change(D),(0,x.microTask)(()=>{_.current=!1}))}),H=(0,i.useEvent)(e=>{e.preventDefault()}),{isFocusVisible:K,focusProps:G}=(0,a.useFocusRing)({autoFocus:g}),{isHovered:V,hoverProps:Y}=(0,n.useHover)({isDisabled:p}),{pressed:U,pressProps:q}=(0,l.useActivePress)({disabled:p}),Q=(0,s.useMemo)(()=>({selected:z,hover:V,active:U,focus:K,autofocus:g,disabled:p}),[z,V,K,U,g,p]),Z=(0,C.mergeProps)({ref:B,onKeyDown:W,onMouseDown:H,onClick:X,id:f,role:"tab",type:(0,u.useResolveButtonType)(e,R),"aria-controls":null==(o=null==(r=$[D])?void 0:r.current)?void 0:o.id,"aria-selected":z,tabIndex:z?0:-1,disabled:p||void 0,autoFocus:g},G,Y,q);return(0,C.useRender)()({ourProps:Z,theirProps:y,slot:Q,defaultTag:"button",name:"Tabs.Tab"})}),{Group:(0,C.forwardRefWithAs)(function(e,t){let{defaultIndex:r=0,vertical:o=!1,manual:a=!1,onChange:n,selectedIndex:l=null,...u}=e,f=o?"vertical":"horizontal",p=a?"manual":"auto",h=null!==l,x=(0,d.useLatestValue)({isControlled:h}),v=(0,m.useSyncRefs)(t),[y,w]=(0,s.useReducer)(R,{info:x,selectedIndex:null!=l?l:r,tabs:[],panels:[]}),E=(0,s.useMemo)(()=>({selectedIndex:y.selectedIndex}),[y.selectedIndex]),T=(0,d.useLatestValue)(n||(()=>{})),N=(0,d.useLatestValue)(y.tabs),S=(0,s.useMemo)(()=>({orientation:f,activation:p,...y}),[f,p,y]),$=(0,i.useEvent)(e=>(w({type:1,tab:e}),()=>w({type:2,tab:e}))),I=(0,i.useEvent)(e=>(w({type:3,panel:e}),()=>w({type:4,panel:e}))),F=(0,i.useEvent)(e=>{O.current!==e&&T.current(e),h||w({type:0,index:e})}),O=(0,d.useLatestValue)(h?e.selectedIndex:y.selectedIndex),A=(0,s.useMemo)(()=>({registerTab:$,registerPanel:I,change:F}),[]);(0,c.useIsoMorphicEffect)(()=>{w({type:0,index:null!=l?l:r})},[l]),(0,c.useIsoMorphicEffect)(()=>{if(void 0===O.current||y.tabs.length<=0)return;let e=(0,b.sortByDomNode)(y.tabs,e=>e.current);e.some((e,t)=>y.tabs[t]!==e)&&F(e.indexOf(y.tabs[O.current]))});let B=(0,C.useRender)();return s.default.createElement(k,null,s.default.createElement(M.Provider,{value:A},s.default.createElement(P.Provider,{value:S},S.tabs.length<=0&&s.default.createElement(g,{onFocus:()=>{var e,t;for(let r of N.current)if((null==(e=r.current)?void 0:e.tabIndex)===0)return null==(t=r.current)||t.focus(),!0;return!1}}),B({ourProps:{ref:v},theirProps:u,slot:E,defaultTag:"div",name:"Tabs"}))))}),List:(0,C.forwardRefWithAs)(function(e,t){let{orientation:r,selectedIndex:o}=I("Tab.List"),a=(0,m.useSyncRefs)(t),n=(0,s.useMemo)(()=>({selectedIndex:o}),[o]);return(0,C.useRender)()({ourProps:{ref:a,role:"tablist","aria-orientation":r},theirProps:e,slot:n,defaultTag:"div",name:"Tabs.List"})}),Panels:(0,C.forwardRefWithAs)(function(e,t){let{selectedIndex:r}=I("Tab.Panels"),o=(0,m.useSyncRefs)(t),a=(0,s.useMemo)(()=>({selectedIndex:r}),[r]);return(0,C.useRender)()({ourProps:{ref:o},theirProps:e,slot:a,defaultTag:"div",name:"Tabs.Panels"})}),Panel:(0,C.forwardRefWithAs)(function(e,t){var r,o,n,l;let i=(0,s.useId)(),{id:d=`headlessui-tabs-panel-${i}`,tabIndex:u=0,...f}=e,{selectedIndex:g,tabs:b,panels:h}=I("Tab.Panel"),x=F("Tab.Panel"),v=(0,s.useRef)(null),y=(0,m.useSyncRefs)(v,t);(0,c.useIsoMorphicEffect)(()=>x.registerPanel(v),[x,v]);let k=w("panels"),E=h.indexOf(v);-1===E&&(E=k);let T=E===g,{isFocusVisible:N,focusProps:S}=(0,a.useFocusRing)(),$=(0,s.useMemo)(()=>({selected:T,focus:N}),[T,N]),P=(0,C.mergeProps)({ref:y,id:d,role:"tabpanel","aria-labelledby":null==(o=null==(r=b[E])?void 0:r.current)?void 0:o.id,tabIndex:T?u:-1},S),M=(0,C.useRender)();return T||null!=(n=f.unmount)&&!n||null!=(l=f.static)&&l?M({ourProps:P,theirProps:f,slot:$,defaultTag:"div",features:O,visible:T,name:"Tabs.Panel"}):s.default.createElement(p.Hidden,{"aria-hidden":"true",...P})})});e.s(["Tab",0,A],970554)},653824,e=>{"use strict";var t=e.i(290571),r=e.i(970554),o=e.i(444755),a=e.i(673706),n=e.i(271645);let s=(0,a.makeClassName)("TabGroup"),l=n.default.forwardRef((e,a)=>{let{defaultIndex:l,index:i,onIndexChange:c,children:d,className:u}=e,m=(0,t.__rest)(e,["defaultIndex","index","onIndexChange","children","className"]);return n.default.createElement(r.Tab.Group,Object.assign({as:"div",ref:a,defaultIndex:l,selectedIndex:i,onChange:c,className:(0,o.tremorTwMerge)(s("root"),"w-full",u)},m),d)});l.displayName="TabGroup",e.s(["TabGroup",0,l],653824)},405371,910342,e=>{"use strict";var t=e.i(290571),r=e.i(271645),o=e.i(480731);let a=(0,r.createContext)(o.BaseColors.Blue);e.s(["default",0,a],910342);var n=e.i(970554),s=e.i(444755);let l=(0,e.i(673706).makeClassName)("TabList"),i=(0,r.createContext)("line"),c={line:(0,s.tremorTwMerge)("flex border-b space-x-4","border-tremor-border","dark:border-dark-tremor-border"),solid:(0,s.tremorTwMerge)("inline-flex p-0.5 rounded-tremor-default space-x-1.5","bg-tremor-background-subtle","dark:bg-dark-tremor-background-subtle")},d=r.default.forwardRef((e,o)=>{let{color:d,variant:u="line",children:m,className:f}=e,p=(0,t.__rest)(e,["color","variant","children","className"]);return r.default.createElement(n.Tab.List,Object.assign({ref:o,className:(0,s.tremorTwMerge)(l("root"),"justify-start overflow-x-clip",c[u],f)},p),r.default.createElement(i.Provider,{value:u},r.default.createElement(a.Provider,{value:d},m)))});d.displayName="TabList",e.s(["TabVariantContext",0,i,"default",0,d],405371)},881073,e=>{"use strict";var t=e.i(405371);e.s(["TabList",()=>t.default])},197647,e=>{"use strict";var t=e.i(290571),r=e.i(970554),o=e.i(95779),a=e.i(444755),n=e.i(673706),s=e.i(271645),l=e.i(405371),i=e.i(910342);let c=(0,n.makeClassName)("Tab"),d=s.default.forwardRef((e,d)=>{let{icon:u,className:m,children:f}=e,p=(0,t.__rest)(e,["icon","className","children"]),g=(0,s.useContext)(l.TabVariantContext),b=(0,s.useContext)(i.default);return s.default.createElement(r.Tab,Object.assign({ref:d,className:(0,a.tremorTwMerge)(c("root"),"flex whitespace-nowrap truncate max-w-xs outline-none data-focus-visible:ring text-tremor-default transition duration-100",function(e,t){switch(e){case"line":return(0,a.tremorTwMerge)("data-[selected]:border-b-2 hover:border-b-2 border-transparent transition duration-100 -mb-px px-2 py-2","hover:border-tremor-content hover:text-tremor-content-emphasis text-tremor-content","[&:not([data-selected])]:dark:hover:border-dark-tremor-content-emphasis [&:not([data-selected])]:dark:hover:text-dark-tremor-content-emphasis [&:not([data-selected])]:dark:text-dark-tremor-content",t?(0,n.getColorClassNames)(t,o.colorPalette.border).selectBorderColor:["data-[selected]:border-tremor-brand data-[selected]:text-tremor-brand","data-[selected]:dark:border-dark-tremor-brand data-[selected]:dark:text-dark-tremor-brand"]);case"solid":return(0,a.tremorTwMerge)("border-transparent border rounded-tremor-small px-2.5 py-1","data-[selected]:border-tremor-border data-[selected]:bg-tremor-background data-[selected]:shadow-tremor-input [&:not([data-selected])]:hover:text-tremor-content-emphasis data-[selected]:text-tremor-brand [&:not([data-selected])]:text-tremor-content","dark:data-[selected]:border-dark-tremor-border dark:data-[selected]:bg-dark-tremor-background dark:data-[selected]:shadow-dark-tremor-input dark:[&:not([data-selected])]:hover:text-dark-tremor-content-emphasis dark:data-[selected]:text-dark-tremor-brand dark:[&:not([data-selected])]:text-dark-tremor-content",t?(0,n.getColorClassNames)(t,o.colorPalette.text).selectTextColor:"text-tremor-content dark:text-dark-tremor-content")}}(g,b),m,b&&(0,n.getColorClassNames)(b,o.colorPalette.text).selectTextColor)},p),u?s.default.createElement(u,{className:(0,a.tremorTwMerge)(c("icon"),"flex-none h-5 w-5",f?"mr-2":"")}):null,f?s.default.createElement("span",null,f):null)});d.displayName="Tab",e.s(["Tab",0,d],197647)},751734,144582,e=>{"use strict";var t=e.i(271645);let r=(0,t.createContext)(0);e.s(["default",0,r],751734);let o=(0,t.createContext)({selectedValue:void 0,handleValueChange:void 0});e.s(["default",0,o],144582)},723731,e=>{"use strict";var t=e.i(290571),r=e.i(970554),o=e.i(751734),a=e.i(144582),n=e.i(444755),s=e.i(673706),l=e.i(271645);let i=(0,s.makeClassName)("TabPanels"),c=l.default.forwardRef((e,s)=>{let{children:c,className:d}=e,u=(0,t.__rest)(e,["children","className"]);return l.default.createElement(r.Tab.Panels,Object.assign({as:"div",ref:s,className:(0,n.tremorTwMerge)(i("root"),"w-full",d)},u),({selectedIndex:e})=>l.default.createElement(a.default.Provider,{value:{selectedValue:e}},l.default.Children.map(c,(e,t)=>l.default.createElement(o.default.Provider,{value:t},e))))});c.displayName="TabPanels",e.s(["TabPanels",0,c],723731)},404206,e=>{"use strict";var t=e.i(290571),r=e.i(751734),o=e.i(144582),a=e.i(444755),n=e.i(673706),s=e.i(271645);let l=(0,n.makeClassName)("TabPanel"),i=s.default.forwardRef((e,n)=>{let{children:i,className:c}=e,d=(0,t.__rest)(e,["children","className"]),{selectedValue:u}=(0,s.useContext)(o.default),m=u===(0,s.useContext)(r.default);return s.default.createElement("div",Object.assign({ref:n,className:(0,a.tremorTwMerge)(l("root"),"w-full mt-2",m?"":"hidden",c),"aria-selected":m?"true":"false"},d),i)});i.displayName="TabPanel",e.s(["TabPanel",0,i],404206)},309821,e=>{"use strict";e.i(247167);var t=e.i(271645),r=e.i(135551),o=e.i(201072),a=e.i(121229),n=e.i(726289),s=e.i(864517),l=e.i(343794),i=e.i(529681),c=e.i(242064),d=e.i(931067),u=e.i(209428),m=e.i(703923),f={percent:0,prefixCls:"rc-progress",strokeColor:"#2db7f5",strokeLinecap:"round",strokeWidth:1,trailColor:"#D9D9D9",trailWidth:1,gapPosition:"bottom"},p=function(){var e=(0,t.useRef)([]),r=(0,t.useRef)(null);return(0,t.useEffect)(function(){var t=Date.now(),o=!1;e.current.forEach(function(e){if(e){o=!0;var a=e.style;a.transitionDuration=".3s, .3s, .3s, .06s",r.current&&t-r.current<100&&(a.transitionDuration="0s, 0s")}}),o&&(r.current=Date.now())}),e.current},g=e.i(410160),b=e.i(392221),h=e.i(654310),x=0,v=(0,h.default)();let C=function(e){var r=t.useState(),o=(0,b.default)(r,2),a=o[0],n=o[1];return t.useEffect(function(){var e;n("rc_progress_".concat((v?(e=x,x+=1):e="TEST_OR_SSR",e)))},[]),e||a};var y=function(e){var r=e.bg,o=e.children;return t.createElement("div",{style:{width:"100%",height:"100%",background:r}},o)};function k(e,t){return Object.keys(e).map(function(r){var o=parseFloat(r),a="".concat(Math.floor(o*t),"%");return"".concat(e[r]," ").concat(a)})}var w=t.forwardRef(function(e,r){var o=e.prefixCls,a=e.color,n=e.gradientId,s=e.radius,l=e.style,i=e.ptg,c=e.strokeLinecap,d=e.strokeWidth,u=e.size,m=e.gapDegree,f=a&&"object"===(0,g.default)(a),p=u/2,b=t.createElement("circle",{className:"".concat(o,"-circle-path"),r:s,cx:p,cy:p,stroke:f?"#FFF":void 0,strokeLinecap:c,strokeWidth:d,opacity:+(0!==i),style:l,ref:r});if(!f)return b;var h="".concat(n,"-conic"),x=k(a,(360-m)/360),v=k(a,1),C="conic-gradient(from ".concat(m?"".concat(180+m/2,"deg"):"0deg",", ").concat(x.join(", "),")"),w="linear-gradient(to ".concat(m?"bottom":"top",", ").concat(v.join(", "),")");return t.createElement(t.Fragment,null,t.createElement("mask",{id:h},b),t.createElement("foreignObject",{x:0,y:0,width:u,height:u,mask:"url(#".concat(h,")")},t.createElement(y,{bg:w},t.createElement(y,{bg:C}))))}),E=function(e,t,r,o,a,n,s,l,i,c){var d=arguments.length>10&&void 0!==arguments[10]?arguments[10]:0,u=(100-o)/100*t;return"round"===i&&100!==o&&(u+=c/2)>=t&&(u=t-.01),{stroke:"string"==typeof l?l:void 0,strokeDasharray:"".concat(t,"px ").concat(e),strokeDashoffset:u+d,transform:"rotate(".concat(a+r/100*360*((360-n)/360)+(0===n?0:({bottom:0,top:180,left:90,right:-90})[s]),"deg)"),transformOrigin:"".concat(50,"px ").concat(50,"px"),transition:"stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s",fillOpacity:0}},T=["id","prefixCls","steps","strokeWidth","trailWidth","gapDegree","gapPosition","trailColor","strokeLinecap","style","className","strokeColor","percent"];function N(e){var t=null!=e?e:[];return Array.isArray(t)?t:[t]}let S=function(e){var r,o,a,n,s=(0,u.default)((0,u.default)({},f),e),i=s.id,c=s.prefixCls,b=s.steps,h=s.strokeWidth,x=s.trailWidth,v=s.gapDegree,y=void 0===v?0:v,k=s.gapPosition,S=s.trailColor,$=s.strokeLinecap,P=s.style,I=s.className,M=s.strokeColor,F=s.percent,R=(0,m.default)(s,T),O=C(i),A="".concat(O,"-gradient"),B=50-h/2,j=2*Math.PI*B,D=y>0?90+y/2:-90,z=(360-y)/360*j,L="object"===(0,g.default)(b)?b:{count:b,gap:2},W=L.count,_=L.gap,X=N(F),H=N(M),K=H.find(function(e){return e&&"object"===(0,g.default)(e)}),G=K&&"object"===(0,g.default)(K)?"butt":$,V=E(j,z,0,100,D,y,k,S,G,h),Y=p();return t.createElement("svg",(0,d.default)({className:(0,l.default)("".concat(c,"-circle"),I),viewBox:"0 0 ".concat(100," ").concat(100),style:P,id:i,role:"presentation"},R),!W&&t.createElement("circle",{className:"".concat(c,"-circle-trail"),r:B,cx:50,cy:50,stroke:S,strokeLinecap:G,strokeWidth:x||h,style:V}),W?(r=Math.round(W*(X[0]/100)),o=100/W,a=0,Array(W).fill(null).map(function(e,n){var s=n<=r-1?H[0]:S,l=s&&"object"===(0,g.default)(s)?"url(#".concat(A,")"):void 0,i=E(j,z,a,o,D,y,k,s,"butt",h,_);return a+=(z-i.strokeDashoffset+_)*100/z,t.createElement("circle",{key:n,className:"".concat(c,"-circle-path"),r:B,cx:50,cy:50,stroke:l,strokeWidth:h,opacity:1,style:i,ref:function(e){Y[n]=e}})})):(n=0,X.map(function(e,r){var o=H[r]||H[H.length-1],a=E(j,z,n,e,D,y,k,o,G,h);return n+=e,t.createElement(w,{key:r,color:o,ptg:e,radius:B,prefixCls:c,gradientId:A,style:a,strokeLinecap:G,strokeWidth:h,gapDegree:y,ref:function(e){Y[r]=e},size:100})}).reverse()))};var $=e.i(491816);e.i(765846);var P=e.i(896091);function I(e){return!e||e<0?0:e>100?100:e}function M({success:e,successPercent:t}){let r=t;return e&&"progress"in e&&(r=e.progress),e&&"percent"in e&&(r=e.percent),r}let F=(e,t,r)=>{var o,a,n,s;let l=-1,i=-1;if("step"===t){let t=r.steps,o=r.strokeWidth;"string"==typeof e||void 0===e?(l="small"===e?2:14,i=null!=o?o:8):"number"==typeof e?[l,i]=[e,e]:[l=14,i=8]=Array.isArray(e)?e:[e.width,e.height],l*=t}else if("line"===t){let t=null==r?void 0:r.strokeWidth;"string"==typeof e||void 0===e?i=t||("small"===e?6:8):"number"==typeof e?[l,i]=[e,e]:[l=-1,i=8]=Array.isArray(e)?e:[e.width,e.height]}else("circle"===t||"dashboard"===t)&&("string"==typeof e||void 0===e?[l,i]="small"===e?[60,60]:[120,120]:"number"==typeof e?[l,i]=[e,e]:Array.isArray(e)&&(l=null!=(a=null!=(o=e[0])?o:e[1])?a:120,i=null!=(s=null!=(n=e[0])?n:e[1])?s:120));return[l,i]},R=e=>{let{prefixCls:r,trailColor:o=null,strokeLinecap:a="round",gapPosition:n,gapDegree:s,width:i=120,type:c,children:d,success:u,size:m=i,steps:f}=e,[p,g]=F(m,"circle"),{strokeWidth:b}=e;void 0===b&&(b=Math.max(3/p*100,6));let h=t.useMemo(()=>s||0===s?s:"dashboard"===c?75:void 0,[s,c]),x=(({percent:e,success:t,successPercent:r})=>{let o=I(M({success:t,successPercent:r}));return[o,I(I(e)-o)]})(e),v="[object Object]"===Object.prototype.toString.call(e.strokeColor),C=(({success:e={},strokeColor:t})=>{let{strokeColor:r}=e;return[r||P.presetPrimaryColors.green,t||null]})({success:u,strokeColor:e.strokeColor}),y=(0,l.default)(`${r}-inner`,{[`${r}-circle-gradient`]:v}),k=t.createElement(S,{steps:f,percent:f?x[1]:x,strokeWidth:b,trailWidth:b,strokeColor:f?C[1]:C,strokeLinecap:a,trailColor:o,prefixCls:r,gapDegree:h,gapPosition:n||"dashboard"===c&&"bottom"||void 0}),w=p<=20,E=t.createElement("div",{className:y,style:{width:p,height:g,fontSize:.15*p+6}},k,!w&&d);return w?t.createElement($.default,{title:d},E):E};e.i(296059);var O=e.i(694758),A=e.i(915654),B=e.i(183293),j=e.i(246422),D=e.i(838378);let z="--progress-line-stroke-color",L="--progress-percent",W=e=>{let t=e?"100%":"-100%";return new O.Keyframes(`antProgress${e?"RTL":"LTR"}Active`,{"0%":{transform:`translateX(${t}) scaleX(0)`,opacity:.1},"20%":{transform:`translateX(${t}) scaleX(0)`,opacity:.5},to:{transform:"translateX(0) scaleX(1)",opacity:0}})},_=(0,j.genStyleHooks)("Progress",e=>{let t=e.calc(e.marginXXS).div(2).equal(),r=(0,D.mergeToken)(e,{progressStepMarginInlineEnd:t,progressStepMinWidth:t,progressActiveMotionDuration:"2.4s"});return[(e=>{let{componentCls:t,iconCls:r}=e;return{[t]:Object.assign(Object.assign({},(0,B.resetComponent)(e)),{display:"inline-block","&-rtl":{direction:"rtl"},"&-line":{position:"relative",width:"100%",fontSize:e.fontSize},[`${t}-outer`]:{display:"inline-flex",alignItems:"center",width:"100%"},[`${t}-inner`]:{position:"relative",display:"inline-block",width:"100%",flex:1,overflow:"hidden",verticalAlign:"middle",backgroundColor:e.remainingColor,borderRadius:e.lineBorderRadius},[`${t}-inner:not(${t}-circle-gradient)`]:{[`${t}-circle-path`]:{stroke:e.defaultColor}},[`${t}-success-bg, ${t}-bg`]:{position:"relative",background:e.defaultColor,borderRadius:e.lineBorderRadius,transition:`all ${e.motionDurationSlow} ${e.motionEaseInOutCirc}`},[`${t}-layout-bottom`]:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",[`${t}-text`]:{width:"max-content",marginInlineStart:0,marginTop:e.marginXXS}},[`${t}-bg`]:{overflow:"hidden","&::after":{content:'""',background:{_multi_value_:!0,value:["inherit",`var(${z})`]},height:"100%",width:`calc(1 / var(${L}) * 100%)`,display:"block"},[`&${t}-bg-inner`]:{minWidth:"max-content","&::after":{content:"none"},[`${t}-text-inner`]:{color:e.colorWhite,[`&${t}-text-bright`]:{color:"rgba(0, 0, 0, 0.45)"}}}},[`${t}-success-bg`]:{position:"absolute",insetBlockStart:0,insetInlineStart:0,backgroundColor:e.colorSuccess},[`${t}-text`]:{display:"inline-block",marginInlineStart:e.marginXS,color:e.colorText,lineHeight:1,width:"2em",whiteSpace:"nowrap",textAlign:"start",verticalAlign:"middle",wordBreak:"normal",[r]:{fontSize:e.fontSize},[`&${t}-text-outer`]:{width:"max-content"},[`&${t}-text-outer${t}-text-start`]:{width:"max-content",marginInlineStart:0,marginInlineEnd:e.marginXS}},[`${t}-text-inner`]:{display:"flex",justifyContent:"center",alignItems:"center",width:"100%",height:"100%",marginInlineStart:0,padding:`0 ${(0,A.unit)(e.paddingXXS)}`,[`&${t}-text-start`]:{justifyContent:"start"},[`&${t}-text-end`]:{justifyContent:"end"}},[`&${t}-status-active`]:{[`${t}-bg::before`]:{position:"absolute",inset:0,backgroundColor:e.colorBgContainer,borderRadius:e.lineBorderRadius,opacity:0,animationName:W(),animationDuration:e.progressActiveMotionDuration,animationTimingFunction:e.motionEaseOutQuint,animationIterationCount:"infinite",content:'""'}},[`&${t}-rtl${t}-status-active`]:{[`${t}-bg::before`]:{animationName:W(!0)}},[`&${t}-status-exception`]:{[`${t}-bg`]:{backgroundColor:e.colorError},[`${t}-text`]:{color:e.colorError}},[`&${t}-status-exception ${t}-inner:not(${t}-circle-gradient)`]:{[`${t}-circle-path`]:{stroke:e.colorError}},[`&${t}-status-success`]:{[`${t}-bg`]:{backgroundColor:e.colorSuccess},[`${t}-text`]:{color:e.colorSuccess}},[`&${t}-status-success ${t}-inner:not(${t}-circle-gradient)`]:{[`${t}-circle-path`]:{stroke:e.colorSuccess}}})}})(r),(e=>{let{componentCls:t,iconCls:r}=e;return{[t]:{[`${t}-circle-trail`]:{stroke:e.remainingColor},[`&${t}-circle ${t}-inner`]:{position:"relative",lineHeight:1,backgroundColor:"transparent"},[`&${t}-circle ${t}-text`]:{position:"absolute",insetBlockStart:"50%",insetInlineStart:0,width:"100%",margin:0,padding:0,color:e.circleTextColor,fontSize:e.circleTextFontSize,lineHeight:1,whiteSpace:"normal",textAlign:"center",transform:"translateY(-50%)",[r]:{fontSize:e.circleIconFontSize}},[`${t}-circle&-status-exception`]:{[`${t}-text`]:{color:e.colorError}},[`${t}-circle&-status-success`]:{[`${t}-text`]:{color:e.colorSuccess}}},[`${t}-inline-circle`]:{lineHeight:1,[`${t}-inner`]:{verticalAlign:"bottom"}}}})(r),(e=>{let{componentCls:t}=e;return{[t]:{[`${t}-steps`]:{display:"inline-block","&-outer":{display:"flex",flexDirection:"row",alignItems:"center"},"&-item":{flexShrink:0,minWidth:e.progressStepMinWidth,marginInlineEnd:e.progressStepMarginInlineEnd,backgroundColor:e.remainingColor,transition:`all ${e.motionDurationSlow}`,"&-active":{backgroundColor:e.defaultColor}}}}}})(r),(e=>{let{componentCls:t,iconCls:r}=e;return{[t]:{[`${t}-small&-line, ${t}-small&-line ${t}-text ${r}`]:{fontSize:e.fontSizeSM}}}})(r)]},e=>({circleTextColor:e.colorText,defaultColor:e.colorInfo,remainingColor:e.colorFillSecondary,lineBorderRadius:100,circleTextFontSize:"1em",circleIconFontSize:`${e.fontSize/e.fontSizeSM}em`}));var X=function(e,t){var r={};for(var 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 a=0,o=Object.getOwnPropertySymbols(e);at.indexOf(o[a])&&Object.prototype.propertyIsEnumerable.call(e,o[a])&&(r[o[a]]=e[o[a]]);return r};let H=e=>{let{prefixCls:r,direction:o,percent:a,size:n,strokeWidth:s,strokeColor:i,strokeLinecap:c="round",children:d,trailColor:u=null,percentPosition:m,success:f}=e,{align:p,type:g}=m,b=i&&"string"!=typeof i?((e,t)=>{let{from:r=P.presetPrimaryColors.blue,to:o=P.presetPrimaryColors.blue,direction:a="rtl"===t?"to left":"to right"}=e,n=X(e,["from","to","direction"]);if(0!==Object.keys(n).length){let e,t=(e=[],Object.keys(n).forEach(t=>{let r=Number.parseFloat(t.replace(/%/g,""));Number.isNaN(r)||e.push({key:r,value:n[t]})}),(e=e.sort((e,t)=>e.key-t.key)).map(({key:e,value:t})=>`${t} ${e}%`).join(", ")),r=`linear-gradient(${a}, ${t})`;return{background:r,[z]:r}}let s=`linear-gradient(${a}, ${r}, ${o})`;return{background:s,[z]:s}})(i,o):{[z]:i,background:i},h="square"===c||"butt"===c?0:void 0,[x,v]=F(null!=n?n:[-1,s||("small"===n?6:8)],"line",{strokeWidth:s}),C=Object.assign(Object.assign({width:`${I(a)}%`,height:v,borderRadius:h},b),{[L]:I(a)/100}),y=M(e),k={width:`${I(y)}%`,height:v,borderRadius:h,backgroundColor:null==f?void 0:f.strokeColor},w=t.createElement("div",{className:`${r}-inner`,style:{backgroundColor:u||void 0,borderRadius:h}},t.createElement("div",{className:(0,l.default)(`${r}-bg`,`${r}-bg-${g}`),style:C},"inner"===g&&d),void 0!==y&&t.createElement("div",{className:`${r}-success-bg`,style:k})),E="outer"===g&&"start"===p,T="outer"===g&&"end"===p;return"outer"===g&&"center"===p?t.createElement("div",{className:`${r}-layout-bottom`},w,d):t.createElement("div",{className:`${r}-outer`,style:{width:x<0?"100%":x}},E&&d,w,T&&d)},K=e=>{let{size:r,steps:o,rounding:a=Math.round,percent:n=0,strokeWidth:s=8,strokeColor:i,trailColor:c=null,prefixCls:d,children:u}=e,m=a(n/100*o),[f,p]=F(null!=r?r:["small"===r?2:14,s],"step",{steps:o,strokeWidth:s}),g=f/o,b=Array.from({length:o});for(let e=0;et.indexOf(o)&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,o=Object.getOwnPropertySymbols(e);at.indexOf(o[a])&&Object.prototype.propertyIsEnumerable.call(e,o[a])&&(r[o[a]]=e[o[a]]);return r};let V=["normal","exception","active","success"],Y=t.forwardRef((e,d)=>{let u,{prefixCls:m,className:f,rootClassName:p,steps:g,strokeColor:b,percent:h=0,size:x="default",showInfo:v=!0,type:C="line",status:y,format:k,style:w,percentPosition:E={}}=e,T=G(e,["prefixCls","className","rootClassName","steps","strokeColor","percent","size","showInfo","type","status","format","style","percentPosition"]),{align:N="end",type:S="outer"}=E,$=Array.isArray(b)?b[0]:b,P="string"==typeof b||Array.isArray(b)?b:void 0,O=t.useMemo(()=>{if($){let e="string"==typeof $?$:Object.values($)[0];return new r.FastColor(e).isLight()}return!1},[b]),A=t.useMemo(()=>{var t,r;let o=M(e);return Number.parseInt(void 0!==o?null==(t=null!=o?o:0)?void 0:t.toString():null==(r=null!=h?h:0)?void 0:r.toString(),10)},[h,e.success,e.successPercent]),B=t.useMemo(()=>!V.includes(y)&&A>=100?"success":y||"normal",[y,A]),{getPrefixCls:j,direction:D,progress:z}=t.useContext(c.ConfigContext),L=j("progress",m),[W,X,Y]=_(L),U="line"===C,q=U&&!g,Q=t.useMemo(()=>{let r;if(!v)return null;let i=M(e),c=k||(e=>`${e}%`),d=U&&O&&"inner"===S;return"inner"===S||k||"exception"!==B&&"success"!==B?r=c(I(h),I(i)):"exception"===B?r=U?t.createElement(n.default,null):t.createElement(s.default,null):"success"===B&&(r=U?t.createElement(o.default,null):t.createElement(a.default,null)),t.createElement("span",{className:(0,l.default)(`${L}-text`,{[`${L}-text-bright`]:d,[`${L}-text-${N}`]:q,[`${L}-text-${S}`]:q}),title:"string"==typeof r?r:void 0},r)},[v,h,A,B,C,L,k]);"line"===C?u=g?t.createElement(K,Object.assign({},e,{strokeColor:P,prefixCls:L,steps:"object"==typeof g?g.count:g}),Q):t.createElement(H,Object.assign({},e,{strokeColor:$,prefixCls:L,direction:D,percentPosition:{align:N,type:S}}),Q):("circle"===C||"dashboard"===C)&&(u=t.createElement(R,Object.assign({},e,{strokeColor:$,prefixCls:L,progressStatus:B}),Q));let Z=(0,l.default)(L,`${L}-status-${B}`,{[`${L}-${"dashboard"===C&&"circle"||C}`]:"line"!==C,[`${L}-inline-circle`]:"circle"===C&&F(x,"circle")[0]<=20,[`${L}-line`]:q,[`${L}-line-align-${N}`]:q,[`${L}-line-position-${S}`]:q,[`${L}-steps`]:g,[`${L}-show-info`]:v,[`${L}-${x}`]:"string"==typeof x,[`${L}-rtl`]:"rtl"===D},null==z?void 0:z.className,f,p,X,Y);return W(t.createElement("div",Object.assign({ref:d,style:Object.assign(Object.assign({},null==z?void 0:z.style),w),className:Z,role:"progressbar","aria-valuenow":A,"aria-valuemin":0,"aria-valuemax":100},(0,i.default)(T,["trailColor","strokeWidth","width","gapDegree","gapPosition","strokeLinecap","success","successPercent"])),u))});e.s(["default",0,Y],309821)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/003_1s9xbht43.js b/litellm/proxy/_experimental/out/_next/static/chunks/003_1s9xbht43.js deleted file mode 100644 index 74f24e425e0..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/003_1s9xbht43.js +++ /dev/null @@ -1 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,115504,207670,e=>{"use strict";function r(){for(var e,r,o=0,t="",l=arguments.length;o"boolean"==typeof e?`${e}`:0===e?"0":e,t=e=>{let t=function(){for(var o,t,l=arguments.length,a=Array(l),n=0;n{let o=Object.fromEntries(Object.entries(e||{}).filter(e=>{let[r]=e;return!["class","className"].includes(r)}));return t(r.map(e=>e(o)),null==e?void 0:e.class,null==e?void 0:e.className)}},cva:e=>r=>{var l;if((null==e?void 0:e.variants)==null)return t(null==e?void 0:e.base,null==r?void 0:r.class,null==r?void 0:r.className);let{variants:a,defaultVariants:n}=e,s=Object.keys(a).map(e=>{let t=null==r?void 0:r[e],l=null==n?void 0:n[e],s=o(t)||o(l);return a[e][s]}),i={...n,...r&&Object.entries(r).reduce((e,r)=>{let[o,t]=r;return void 0===t?e:{...e,[o]:t}},{})},d=null==e||null==(l=e.compoundVariants)?void 0:l.reduce((e,r)=>{let{class:o,className:t,...l}=r;return Object.entries(l).every(e=>{let[r,o]=e,t=i[r];return Array.isArray(o)?o.includes(t):t===o})?[...e,o,t]:e},[]);return t(null==e?void 0:e.base,s,d,null==r?void 0:r.class,null==r?void 0:r.className)},cx:t}},{compose:l,cva:a,cx:n}=t(),s=(e=new Map,r=null,o)=>({nextPart:e,validators:r,classGroupId:o}),i=[],d=(e,r,o)=>{if(0==e.length-r)return o.classGroupId;let t=e[r],l=o.nextPart.get(t);if(l){let o=d(e,r+1,l);if(o)return o}let a=o.validators;if(null===a)return;let n=0===r?e.join("-"):e.slice(r).join("-"),s=a.length;for(let e=0;e{let o=s();for(let t in e)m(e[t],o,t,r);return o},m=(e,r,o,t)=>{let l=e.length;for(let a=0;a{"string"==typeof e?u(e,r,o):"function"==typeof e?b(e,r,o,t):f(e,r,o,t)},u=(e,r,o)=>{(""===e?r:g(r,e)).classGroupId=o},b=(e,r,o,t)=>{h(e)?m(e(t),r,o,t):(null===r.validators&&(r.validators=[]),r.validators.push({classGroupId:o,validator:e}))},f=(e,r,o,t)=>{let l=Object.entries(e),a=l.length;for(let e=0;e{let o=e,t=r.split("-"),l=t.length;for(let e=0;e"isThemeGetter"in e&&!0===e.isThemeGetter,k=[],x=(e,r,o,t,l)=>({modifiers:e,hasImportantModifier:r,baseClassName:o,maybePostfixModifierPosition:t,isExternal:l}),v=/\s+/,w=e=>{let r;if("string"==typeof e)return e;let o="";for(let t=0;t{let r=r=>r[e]||y;return r.isThemeGetter=!0,r},j=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,O=/^\((?:(\w[\w-]*):)?(.+)\)$/i,N=/^\d+\/\d+$/,C=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,G=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,A=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,$=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,I=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,T=e=>N.test(e),M=e=>!!e&&!Number.isNaN(Number(e)),W=e=>!!e&&Number.isInteger(Number(e)),P=e=>e.endsWith("%")&&M(e.slice(0,-1)),S=e=>C.test(e),q=()=>!0,B=e=>G.test(e)&&!A.test(e),E=()=>!1,K=e=>$.test(e),R=e=>I.test(e),U=e=>!V(e)&&!Q(e),_=e=>et(e,es,E),V=e=>j.test(e),D=e=>et(e,ei,B),F=e=>et(e,ed,M),H=e=>et(e,ea,E),J=e=>et(e,en,R),L=e=>et(e,em,K),Q=e=>O.test(e),X=e=>el(e,ei),Y=e=>el(e,ec),Z=e=>el(e,ea),ee=e=>el(e,es),er=e=>el(e,en),eo=e=>el(e,em,!0),et=(e,r,o)=>{let t=j.exec(e);return!!t&&(t[1]?r(t[1]):o(t[2]))},el=(e,r,o=!1)=>{let t=O.exec(e);return!!t&&(t[1]?r(t[1]):o)},ea=e=>"position"===e||"percentage"===e,en=e=>"image"===e||"url"===e,es=e=>"length"===e||"size"===e||"bg-size"===e,ei=e=>"length"===e,ed=e=>"number"===e,ec=e=>"family-name"===e,em=e=>"shadow"===e,ep=((e,...r)=>{let o,t,l,a,n=e=>{let r=t(e);if(r)return r;let a=((e,r)=>{let{parseClassName:o,getClassGroupId:t,getConflictingClassGroupIds:l,sortModifiers:a}=r,n=[],s=e.trim().split(v),i="";for(let e=s.length-1;e>=0;e-=1){let r=s[e],{isExternal:d,modifiers:c,hasImportantModifier:m,baseClassName:p,maybePostfixModifierPosition:u}=o(r);if(d){i=r+(i.length>0?" "+i:i);continue}let b=!!u,f=t(b?p.substring(0,u):p);if(!f){if(!b||!(f=t(p))){i=r+(i.length>0?" "+i:i);continue}b=!1}let g=0===c.length?"":1===c.length?c[0]:a(c).join(":"),h=m?g+"!":g,k=h+f;if(n.indexOf(k)>-1)continue;n.push(k);let x=l(f,b);for(let e=0;e0?" "+i:i)}return i})(e,o);return l(e,a),a};return a=s=>{var m;let p;return t=(o={cache:(e=>{if(e<1)return{get:()=>void 0,set:()=>{}};let r=0,o=Object.create(null),t=Object.create(null),l=(l,a)=>{o[l]=a,++r>e&&(r=0,t=o,o=Object.create(null))};return{get(e){let r=o[e];return void 0!==r?r:void 0!==(r=t[e])?(l(e,r),r):void 0},set(e,r){e in o?o[e]=r:l(e,r)}}})((m=r.reduce((e,r)=>r(e),e())).cacheSize),parseClassName:(e=>{let{prefix:r,experimentalParseClassName:o}=e,t=e=>{let r,o=[],t=0,l=0,a=0,n=e.length;for(let s=0;sa?r-a:void 0)};if(r){let e=r+":",o=t;t=r=>r.startsWith(e)?o(r.slice(e.length)):x(k,!1,r,void 0,!0)}if(o){let e=t;t=r=>o({className:r,parseClassName:e})}return t})(m),sortModifiers:(p=new Map,m.orderSensitiveModifiers.forEach((e,r)=>{p.set(e,1e6+r)}),e=>{let r=[],o=[];for(let t=0;t0&&(o.sort(),r.push(...o),o=[]),r.push(l)):o.push(l)}return o.length>0&&(o.sort(),r.push(...o)),r}),...(e=>{let r=(e=>{let{theme:r,classGroups:o}=e;return c(o,r)})(e),{conflictingClassGroups:o,conflictingClassGroupModifiers:t}=e;return{getClassGroupId:e=>{if(e.startsWith("[")&&e.endsWith("]")){var o;let r,t,l;return -1===(o=e).slice(1,-1).indexOf(":")?void 0:(t=(r=o.slice(1,-1)).indexOf(":"),(l=r.slice(0,t))?"arbitrary.."+l:void 0)}let t=e.split("-"),l=+(""===t[0]&&t.length>1);return d(t,l,r)},getConflictingClassGroupIds:(e,r)=>{if(r){let r=t[e],l=o[e];if(r){if(l){let e=Array(l.length+r.length);for(let r=0;ra(((...e)=>{let r,o,t=0,l="";for(;t{let e=z("color"),r=z("font"),o=z("text"),t=z("font-weight"),l=z("tracking"),a=z("leading"),n=z("breakpoint"),s=z("container"),i=z("spacing"),d=z("radius"),c=z("shadow"),m=z("inset-shadow"),p=z("text-shadow"),u=z("drop-shadow"),b=z("blur"),f=z("perspective"),g=z("aspect"),h=z("ease"),k=z("animate"),x=()=>["auto","avoid","all","avoid-page","page","left","right","column"],v=()=>["center","top","bottom","left","right","top-left","left-top","top-right","right-top","bottom-right","right-bottom","bottom-left","left-bottom"],w=()=>[...v(),Q,V],y=()=>["auto","hidden","clip","visible","scroll"],j=()=>["auto","contain","none"],O=()=>[Q,V,i],N=()=>[T,"full","auto",...O()],C=()=>[W,"none","subgrid",Q,V],G=()=>["auto",{span:["full",W,Q,V]},W,Q,V],A=()=>[W,"auto",Q,V],$=()=>["auto","min","max","fr",Q,V],I=()=>["start","end","center","between","around","evenly","stretch","baseline","center-safe","end-safe"],B=()=>["start","end","center","stretch","center-safe","end-safe"],E=()=>["auto",...O()],K=()=>[T,"auto","full","dvw","dvh","lvw","lvh","svw","svh","min","max","fit",...O()],R=()=>[e,Q,V],et=()=>[...v(),Z,H,{position:[Q,V]}],el=()=>["no-repeat",{repeat:["","x","y","space","round"]}],ea=()=>["auto","cover","contain",ee,_,{size:[Q,V]}],en=()=>[P,X,D],es=()=>["","none","full",d,Q,V],ei=()=>["",M,X,D],ed=()=>["solid","dashed","dotted","double"],ec=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],em=()=>[M,P,Z,H],ep=()=>["","none",b,Q,V],eu=()=>["none",M,Q,V],eb=()=>["none",M,Q,V],ef=()=>[M,Q,V],eg=()=>[T,"full",...O()];return{cacheSize:500,theme:{animate:["spin","ping","pulse","bounce"],aspect:["video"],blur:[S],breakpoint:[S],color:[q],container:[S],"drop-shadow":[S],ease:["in","out","in-out"],font:[U],"font-weight":["thin","extralight","light","normal","medium","semibold","bold","extrabold","black"],"inset-shadow":[S],leading:["none","tight","snug","normal","relaxed","loose"],perspective:["dramatic","near","normal","midrange","distant","none"],radius:[S],shadow:[S],spacing:["px",M],text:[S],"text-shadow":[S],tracking:["tighter","tight","normal","wide","wider","widest"]},classGroups:{aspect:[{aspect:["auto","square",T,V,Q,g]}],container:["container"],columns:[{columns:[M,V,Q,s]}],"break-after":[{"break-after":x()}],"break-before":[{"break-before":x()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],sr:["sr-only","not-sr-only"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:w()}],overflow:[{overflow:y()}],"overflow-x":[{"overflow-x":y()}],"overflow-y":[{"overflow-y":y()}],overscroll:[{overscroll:j()}],"overscroll-x":[{"overscroll-x":j()}],"overscroll-y":[{"overscroll-y":j()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:N()}],"inset-x":[{"inset-x":N()}],"inset-y":[{"inset-y":N()}],start:[{start:N()}],end:[{end:N()}],top:[{top:N()}],right:[{right:N()}],bottom:[{bottom:N()}],left:[{left:N()}],visibility:["visible","invisible","collapse"],z:[{z:[W,"auto",Q,V]}],basis:[{basis:[T,"full","auto",s,...O()]}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["nowrap","wrap","wrap-reverse"]}],flex:[{flex:[M,T,"auto","initial","none",V]}],grow:[{grow:["",M,Q,V]}],shrink:[{shrink:["",M,Q,V]}],order:[{order:[W,"first","last","none",Q,V]}],"grid-cols":[{"grid-cols":C()}],"col-start-end":[{col:G()}],"col-start":[{"col-start":A()}],"col-end":[{"col-end":A()}],"grid-rows":[{"grid-rows":C()}],"row-start-end":[{row:G()}],"row-start":[{"row-start":A()}],"row-end":[{"row-end":A()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":$()}],"auto-rows":[{"auto-rows":$()}],gap:[{gap:O()}],"gap-x":[{"gap-x":O()}],"gap-y":[{"gap-y":O()}],"justify-content":[{justify:[...I(),"normal"]}],"justify-items":[{"justify-items":[...B(),"normal"]}],"justify-self":[{"justify-self":["auto",...B()]}],"align-content":[{content:["normal",...I()]}],"align-items":[{items:[...B(),{baseline:["","last"]}]}],"align-self":[{self:["auto",...B(),{baseline:["","last"]}]}],"place-content":[{"place-content":I()}],"place-items":[{"place-items":[...B(),"baseline"]}],"place-self":[{"place-self":["auto",...B()]}],p:[{p:O()}],px:[{px:O()}],py:[{py:O()}],ps:[{ps:O()}],pe:[{pe:O()}],pt:[{pt:O()}],pr:[{pr:O()}],pb:[{pb:O()}],pl:[{pl:O()}],m:[{m:E()}],mx:[{mx:E()}],my:[{my:E()}],ms:[{ms:E()}],me:[{me:E()}],mt:[{mt:E()}],mr:[{mr:E()}],mb:[{mb:E()}],ml:[{ml:E()}],"space-x":[{"space-x":O()}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":O()}],"space-y-reverse":["space-y-reverse"],size:[{size:K()}],w:[{w:[s,"screen",...K()]}],"min-w":[{"min-w":[s,"screen","none",...K()]}],"max-w":[{"max-w":[s,"screen","none","prose",{screen:[n]},...K()]}],h:[{h:["screen","lh",...K()]}],"min-h":[{"min-h":["screen","lh","none",...K()]}],"max-h":[{"max-h":["screen","lh",...K()]}],"font-size":[{text:["base",o,X,D]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:[t,Q,F]}],"font-stretch":[{"font-stretch":["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded",P,V]}],"font-family":[{font:[Y,V,r]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:[l,Q,V]}],"line-clamp":[{"line-clamp":[M,"none",Q,F]}],leading:[{leading:[a,...O()]}],"list-image":[{"list-image":["none",Q,V]}],"list-style-position":[{list:["inside","outside"]}],"list-style-type":[{list:["disc","decimal","none",Q,V]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"placeholder-color":[{placeholder:R()}],"text-color":[{text:R()}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...ed(),"wavy"]}],"text-decoration-thickness":[{decoration:[M,"from-font","auto",Q,D]}],"text-decoration-color":[{decoration:R()}],"underline-offset":[{"underline-offset":[M,"auto",Q,V]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:O()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",Q,V]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],wrap:[{wrap:["break-word","anywhere","normal"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",Q,V]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:et()}],"bg-repeat":[{bg:el()}],"bg-size":[{bg:ea()}],"bg-image":[{bg:["none",{linear:[{to:["t","tr","r","br","b","bl","l","tl"]},W,Q,V],radial:["",Q,V],conic:[W,Q,V]},er,J]}],"bg-color":[{bg:R()}],"gradient-from-pos":[{from:en()}],"gradient-via-pos":[{via:en()}],"gradient-to-pos":[{to:en()}],"gradient-from":[{from:R()}],"gradient-via":[{via:R()}],"gradient-to":[{to:R()}],rounded:[{rounded:es()}],"rounded-s":[{"rounded-s":es()}],"rounded-e":[{"rounded-e":es()}],"rounded-t":[{"rounded-t":es()}],"rounded-r":[{"rounded-r":es()}],"rounded-b":[{"rounded-b":es()}],"rounded-l":[{"rounded-l":es()}],"rounded-ss":[{"rounded-ss":es()}],"rounded-se":[{"rounded-se":es()}],"rounded-ee":[{"rounded-ee":es()}],"rounded-es":[{"rounded-es":es()}],"rounded-tl":[{"rounded-tl":es()}],"rounded-tr":[{"rounded-tr":es()}],"rounded-br":[{"rounded-br":es()}],"rounded-bl":[{"rounded-bl":es()}],"border-w":[{border:ei()}],"border-w-x":[{"border-x":ei()}],"border-w-y":[{"border-y":ei()}],"border-w-s":[{"border-s":ei()}],"border-w-e":[{"border-e":ei()}],"border-w-t":[{"border-t":ei()}],"border-w-r":[{"border-r":ei()}],"border-w-b":[{"border-b":ei()}],"border-w-l":[{"border-l":ei()}],"divide-x":[{"divide-x":ei()}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":ei()}],"divide-y-reverse":["divide-y-reverse"],"border-style":[{border:[...ed(),"hidden","none"]}],"divide-style":[{divide:[...ed(),"hidden","none"]}],"border-color":[{border:R()}],"border-color-x":[{"border-x":R()}],"border-color-y":[{"border-y":R()}],"border-color-s":[{"border-s":R()}],"border-color-e":[{"border-e":R()}],"border-color-t":[{"border-t":R()}],"border-color-r":[{"border-r":R()}],"border-color-b":[{"border-b":R()}],"border-color-l":[{"border-l":R()}],"divide-color":[{divide:R()}],"outline-style":[{outline:[...ed(),"none","hidden"]}],"outline-offset":[{"outline-offset":[M,Q,V]}],"outline-w":[{outline:["",M,X,D]}],"outline-color":[{outline:R()}],shadow:[{shadow:["","none",c,eo,L]}],"shadow-color":[{shadow:R()}],"inset-shadow":[{"inset-shadow":["none",m,eo,L]}],"inset-shadow-color":[{"inset-shadow":R()}],"ring-w":[{ring:ei()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:R()}],"ring-offset-w":[{"ring-offset":[M,D]}],"ring-offset-color":[{"ring-offset":R()}],"inset-ring-w":[{"inset-ring":ei()}],"inset-ring-color":[{"inset-ring":R()}],"text-shadow":[{"text-shadow":["none",p,eo,L]}],"text-shadow-color":[{"text-shadow":R()}],opacity:[{opacity:[M,Q,V]}],"mix-blend":[{"mix-blend":[...ec(),"plus-darker","plus-lighter"]}],"bg-blend":[{"bg-blend":ec()}],"mask-clip":[{"mask-clip":["border","padding","content","fill","stroke","view"]},"mask-no-clip"],"mask-composite":[{mask:["add","subtract","intersect","exclude"]}],"mask-image-linear-pos":[{"mask-linear":[M]}],"mask-image-linear-from-pos":[{"mask-linear-from":em()}],"mask-image-linear-to-pos":[{"mask-linear-to":em()}],"mask-image-linear-from-color":[{"mask-linear-from":R()}],"mask-image-linear-to-color":[{"mask-linear-to":R()}],"mask-image-t-from-pos":[{"mask-t-from":em()}],"mask-image-t-to-pos":[{"mask-t-to":em()}],"mask-image-t-from-color":[{"mask-t-from":R()}],"mask-image-t-to-color":[{"mask-t-to":R()}],"mask-image-r-from-pos":[{"mask-r-from":em()}],"mask-image-r-to-pos":[{"mask-r-to":em()}],"mask-image-r-from-color":[{"mask-r-from":R()}],"mask-image-r-to-color":[{"mask-r-to":R()}],"mask-image-b-from-pos":[{"mask-b-from":em()}],"mask-image-b-to-pos":[{"mask-b-to":em()}],"mask-image-b-from-color":[{"mask-b-from":R()}],"mask-image-b-to-color":[{"mask-b-to":R()}],"mask-image-l-from-pos":[{"mask-l-from":em()}],"mask-image-l-to-pos":[{"mask-l-to":em()}],"mask-image-l-from-color":[{"mask-l-from":R()}],"mask-image-l-to-color":[{"mask-l-to":R()}],"mask-image-x-from-pos":[{"mask-x-from":em()}],"mask-image-x-to-pos":[{"mask-x-to":em()}],"mask-image-x-from-color":[{"mask-x-from":R()}],"mask-image-x-to-color":[{"mask-x-to":R()}],"mask-image-y-from-pos":[{"mask-y-from":em()}],"mask-image-y-to-pos":[{"mask-y-to":em()}],"mask-image-y-from-color":[{"mask-y-from":R()}],"mask-image-y-to-color":[{"mask-y-to":R()}],"mask-image-radial":[{"mask-radial":[Q,V]}],"mask-image-radial-from-pos":[{"mask-radial-from":em()}],"mask-image-radial-to-pos":[{"mask-radial-to":em()}],"mask-image-radial-from-color":[{"mask-radial-from":R()}],"mask-image-radial-to-color":[{"mask-radial-to":R()}],"mask-image-radial-shape":[{"mask-radial":["circle","ellipse"]}],"mask-image-radial-size":[{"mask-radial":[{closest:["side","corner"],farthest:["side","corner"]}]}],"mask-image-radial-pos":[{"mask-radial-at":v()}],"mask-image-conic-pos":[{"mask-conic":[M]}],"mask-image-conic-from-pos":[{"mask-conic-from":em()}],"mask-image-conic-to-pos":[{"mask-conic-to":em()}],"mask-image-conic-from-color":[{"mask-conic-from":R()}],"mask-image-conic-to-color":[{"mask-conic-to":R()}],"mask-mode":[{mask:["alpha","luminance","match"]}],"mask-origin":[{"mask-origin":["border","padding","content","fill","stroke","view"]}],"mask-position":[{mask:et()}],"mask-repeat":[{mask:el()}],"mask-size":[{mask:ea()}],"mask-type":[{"mask-type":["alpha","luminance"]}],"mask-image":[{mask:["none",Q,V]}],filter:[{filter:["","none",Q,V]}],blur:[{blur:ep()}],brightness:[{brightness:[M,Q,V]}],contrast:[{contrast:[M,Q,V]}],"drop-shadow":[{"drop-shadow":["","none",u,eo,L]}],"drop-shadow-color":[{"drop-shadow":R()}],grayscale:[{grayscale:["",M,Q,V]}],"hue-rotate":[{"hue-rotate":[M,Q,V]}],invert:[{invert:["",M,Q,V]}],saturate:[{saturate:[M,Q,V]}],sepia:[{sepia:["",M,Q,V]}],"backdrop-filter":[{"backdrop-filter":["","none",Q,V]}],"backdrop-blur":[{"backdrop-blur":ep()}],"backdrop-brightness":[{"backdrop-brightness":[M,Q,V]}],"backdrop-contrast":[{"backdrop-contrast":[M,Q,V]}],"backdrop-grayscale":[{"backdrop-grayscale":["",M,Q,V]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[M,Q,V]}],"backdrop-invert":[{"backdrop-invert":["",M,Q,V]}],"backdrop-opacity":[{"backdrop-opacity":[M,Q,V]}],"backdrop-saturate":[{"backdrop-saturate":[M,Q,V]}],"backdrop-sepia":[{"backdrop-sepia":["",M,Q,V]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":O()}],"border-spacing-x":[{"border-spacing-x":O()}],"border-spacing-y":[{"border-spacing-y":O()}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["","all","colors","opacity","shadow","transform","none",Q,V]}],"transition-behavior":[{transition:["normal","discrete"]}],duration:[{duration:[M,"initial",Q,V]}],ease:[{ease:["linear","initial",h,Q,V]}],delay:[{delay:[M,Q,V]}],animate:[{animate:["none",k,Q,V]}],backface:[{backface:["hidden","visible"]}],perspective:[{perspective:[f,Q,V]}],"perspective-origin":[{"perspective-origin":w()}],rotate:[{rotate:eu()}],"rotate-x":[{"rotate-x":eu()}],"rotate-y":[{"rotate-y":eu()}],"rotate-z":[{"rotate-z":eu()}],scale:[{scale:eb()}],"scale-x":[{"scale-x":eb()}],"scale-y":[{"scale-y":eb()}],"scale-z":[{"scale-z":eb()}],"scale-3d":["scale-3d"],skew:[{skew:ef()}],"skew-x":[{"skew-x":ef()}],"skew-y":[{"skew-y":ef()}],transform:[{transform:[Q,V,"","none","gpu","cpu"]}],"transform-origin":[{origin:w()}],"transform-style":[{transform:["3d","flat"]}],translate:[{translate:eg()}],"translate-x":[{"translate-x":eg()}],"translate-y":[{"translate-y":eg()}],"translate-z":[{"translate-z":eg()}],"translate-none":["translate-none"],accent:[{accent:R()}],appearance:[{appearance:["none","auto"]}],"caret-color":[{caret:R()}],"color-scheme":[{scheme:["normal","dark","light","light-dark","only-dark","only-light"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",Q,V]}],"field-sizing":[{"field-sizing":["fixed","content"]}],"pointer-events":[{"pointer-events":["auto","none"]}],resize:[{resize:["none","","y","x"]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":O()}],"scroll-mx":[{"scroll-mx":O()}],"scroll-my":[{"scroll-my":O()}],"scroll-ms":[{"scroll-ms":O()}],"scroll-me":[{"scroll-me":O()}],"scroll-mt":[{"scroll-mt":O()}],"scroll-mr":[{"scroll-mr":O()}],"scroll-mb":[{"scroll-mb":O()}],"scroll-ml":[{"scroll-ml":O()}],"scroll-p":[{"scroll-p":O()}],"scroll-px":[{"scroll-px":O()}],"scroll-py":[{"scroll-py":O()}],"scroll-ps":[{"scroll-ps":O()}],"scroll-pe":[{"scroll-pe":O()}],"scroll-pt":[{"scroll-pt":O()}],"scroll-pr":[{"scroll-pr":O()}],"scroll-pb":[{"scroll-pb":O()}],"scroll-pl":[{"scroll-pl":O()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",Q,V]}],fill:[{fill:["none",...R()]}],"stroke-w":[{stroke:[M,X,D,F]}],stroke:[{stroke:["none",...R()]}],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-x","border-w-y","border-w-s","border-w-e","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-x","border-color-y","border-color-s","border-color-e","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],translate:["translate-x","translate-y","translate-none"],"translate-none":["translate","translate-x","translate-y","translate-z"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]},orderSensitiveModifiers:["*","**","after","backdrop","before","details-content","file","first-letter","first-line","marker","placeholder","selection"]}}),{cva:eu,cx:eb,compose:ef}=t({hooks:{onComplete:e=>ep(e)}});e.s(["cn",0,eb,"cva",0,eu,"cx",0,eb],115504)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/003w1n3_ylv_2.js b/litellm/proxy/_experimental/out/_next/static/chunks/003w1n3_ylv_2.js deleted file mode 100644 index 7725583c878..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/003w1n3_ylv_2.js +++ /dev/null @@ -1 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,962296,e=>{"use strict";var r=e.i(843476),t=e.i(708347),s=e.i(266027),a=e.i(994388),l=e.i(599724),i=e.i(629569),o=e.i(808613),n=e.i(311451),c=e.i(212931),d=e.i(199133),h=e.i(271645),x=e.i(127952),m=e.i(727749),u=e.i(602869),p=e.i(827252),g=e.i(779241),f=e.i(592968),y=e.i(898586),j=e.i(555987),b=e.i(437902),v=e.i(285027),_=e.i(464571),N=e.i(312361);let{Text:S}=y.Typography,k=({litellmParams:e,accessToken:t,onTestComplete:s})=>{let[a,l]=(0,h.useState)(!0),[i,o]=(0,h.useState)(null),[n,c]=(0,h.useState)(!1);(0,h.useEffect)(()=>{(async()=>{l(!0);try{let r=await (0,u.testSearchToolConnection)(t,e);o(r),"success"===r.status&&m.default.success("Connection test successful!")}catch(e){o({status:"error",message:e instanceof Error?e.message:"Unknown error occurred",error_type:"NetworkError"})}finally{l(!1),s&&s()}})()},[t,e,s]);let d=i?.message?(e=>{if(!e)return"Unknown error";let r=e.split("stack trace:")[0].trim().replace(/^litellm\.(.*?)Error:\s*/,"").replace(/^AuthenticationError:\s*/,"");if(r.includes("")||r.includes("(.*?)<\/title>/);return e?e[1]:r.includes("401")||r.includes("Authorization Required")?"Authentication failed: Invalid API key or credentials":"Authentication error - please check your API key"}return r.length>200?r.substring(0,200)+"...":r})(i.message):"Unknown error";return a?(0,r.jsx)("div",{style:{padding:"24px",borderRadius:"8px",backgroundColor:"#fff"},children:(0,r.jsxs)("div",{style:{textAlign:"center",padding:"32px 20px"},className:"jsx-dc9a0e2d897fe63b",children:[(0,r.jsx)("div",{style:{marginBottom:"16px"},className:"jsx-dc9a0e2d897fe63b loading-spinner",children:(0,r.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,r.jsxs)(S,{style:{fontSize:"16px"},children:["Testing connection to ",e.search_provider||"search provider","..."]}),(0,r.jsx)(b.default,{id:"dc9a0e2d897fe63b",children:"@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}"})]})}):i?(0,r.jsxs)("div",{style:{padding:"24px",borderRadius:"8px",backgroundColor:"#fff"},children:["success"===i.status?(0,r.jsxs)("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",padding:"32px 20px"},children:[(0,r.jsx)("div",{style:{color:"#52c41a",fontSize:"24px",display:"flex",alignItems:"center"},children:(0,r.jsx)("svg",{viewBox:"64 64 896 896",focusable:"false","data-icon":"check-circle",width:"1em",height:"1em",fill:"currentColor","aria-hidden":"true",children:(0,r.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,r.jsxs)("div",{style:{marginLeft:"12px"},children:[(0,r.jsxs)(S,{type:"success",style:{fontSize:"18px",fontWeight:500,display:"block"},children:["Connection to ",e.search_provider," successful!"]}),i.test_query&&(0,r.jsxs)(S,{style:{fontSize:"14px",color:"#666",marginTop:"8px",display:"block"},children:["Test query:"," ",(0,r.jsx)("code",{style:{backgroundColor:"#f0f0f0",padding:"2px 6px",borderRadius:"4px"},children:i.test_query})]}),void 0!==i.results_count&&(0,r.jsxs)(S,{style:{fontSize:"14px",color:"#666",display:"block"},children:["Results retrieved: ",i.results_count]})]})]}):(0,r.jsx)(r.Fragment,{children:(0,r.jsxs)("div",{children:[(0,r.jsxs)("div",{style:{display:"flex",alignItems:"center",marginBottom:"20px"},children:[(0,r.jsx)(v.WarningOutlined,{style:{color:"#ff4d4f",fontSize:"24px",marginRight:"12px"}}),(0,r.jsxs)(S,{type:"danger",style:{fontSize:"18px",fontWeight:500},children:["Connection to ",e.search_provider||"search provider"," failed"]})]}),(0,r.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,r.jsxs)(S,{strong:!0,style:{display:"block",marginBottom:"8px"},children:["Error:"," "]}),(0,r.jsx)(S,{type:"danger",style:{fontSize:"14px",lineHeight:"1.5"},children:d}),i.error_type&&(0,r.jsx)("div",{style:{marginTop:"8px"},children:(0,r.jsxs)(S,{style:{fontSize:"13px",color:"#666"},children:["Error type:"," ",(0,r.jsx)("code",{style:{backgroundColor:"#ffebee",padding:"2px 6px",borderRadius:"4px",color:"#d32f2f"},children:i.error_type})]})}),i.message&&(0,r.jsx)("div",{style:{marginTop:"12px"},children:(0,r.jsx)(_.Button,{type:"link",onClick:()=>c(!n),style:{paddingLeft:0,height:"auto"},children:n?"Hide Details":"Show Details"})})]}),n&&(0,r.jsxs)("div",{style:{marginBottom:"20px"},children:[(0,r.jsx)(S,{strong:!0,style:{display:"block",marginBottom:"8px",fontSize:"15px"},children:"Full Error Details"}),(0,r.jsx)("pre",{style:{backgroundColor:"#f5f5f5",padding:"16px",borderRadius:"8px",fontSize:"13px",maxHeight:"200px",overflow:"auto",border:"1px solid #e8e8e8",lineHeight:"1.5",whiteSpace:"pre-wrap",wordBreak:"break-word"},children:i.message})]}),(0,r.jsxs)("div",{style:{backgroundColor:"#fffbf0",border:"1px solid #ffe58f",borderLeft:"4px solid #faad14",borderRadius:"8px",padding:"16px"},children:[(0,r.jsx)(S,{strong:!0,style:{display:"block",marginBottom:"8px",color:"#d48806"},children:"Troubleshooting tips:"}),(0,r.jsxs)("ul",{style:{margin:"8px 0",paddingLeft:"20px",color:"#ad6800"},children:[(0,r.jsx)("li",{style:{marginBottom:"6px"},children:"Verify your API key is correct and active"}),(0,r.jsx)("li",{style:{marginBottom:"6px"},children:"Check if the search provider service is operational"}),(0,r.jsx)("li",{style:{marginBottom:"6px"},children:"Ensure you have sufficient credits/quota with the provider"}),(0,r.jsx)("li",{style:{marginBottom:"6px"},children:"Review the provider's documentation for any additional requirements"})]})]})]})}),(0,r.jsx)(N.Divider,{style:{margin:"24px 0 16px"}}),(0,r.jsx)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:(0,r.jsx)(_.Button,{type:"link",href:"https://docs.litellm.ai/docs/search",target:"_blank",icon:(0,r.jsx)(p.InfoCircleOutlined,{}),children:"View Search Documentation"})})]}):null},{TextArea:T}=n.Input,w=({providerName:e,displayName:t})=>(0,r.jsxs)("div",{style:{display:"flex",alignItems:"center"},children:[(0,r.jsx)("img",{src:(0,j.resolveLogoSrc)(`/ui/assets/logos/${e}.png`),alt:"",style:{width:"20px",height:"20px",marginRight:"8px",objectFit:"contain"},onError:e=>{e.currentTarget.style.display="none"}}),(0,r.jsx)("span",{children:t})]}),C=({userRole:e,accessToken:l,onCreateSuccess:i,isModalVisible:n,setModalVisible:x})=>{let[j]=o.Form.useForm(),[b,v]=(0,h.useState)(!1),[_,N]=(0,h.useState)({}),[S,C]=(0,h.useState)(!1),[I,z]=(0,h.useState)(!1),[A,P]=(0,h.useState)(""),{data:D,isLoading:F}=(0,s.useQuery)({queryKey:["searchProviders"],queryFn:()=>{if(!l)throw Error("Access Token required");return(0,u.fetchAvailableSearchProviders)(l)},enabled:!!l&&n}),B=D?.providers||[],q=async e=>{v(!0);try{let r={search_tool_name:e.search_tool_name,litellm_params:{search_provider:e.search_provider,api_key:e.api_key,api_base:e.api_base,timeout:e.timeout?parseFloat(e.timeout):void 0,max_retries:e.max_retries?parseInt(e.max_retries):void 0},search_tool_info:e.description?{description:e.description}:void 0};if(null!=l){let e=await (0,u.createSearchTool)(l,r);m.default.success("Search tool created successfully"),j.resetFields(),N({}),x(!1),i(e)}}catch(e){m.default.error("Error creating search tool: "+e)}finally{v(!1)}},E=async()=>{try{await j.validateFields(["search_provider","api_key"]),z(!0),P(`test-${Date.now()}`),C(!0)}catch(e){m.default.error("Please fill in Search Provider and API Key before testing")}};return(h.default.useEffect(()=>{n||N({})},[n]),(0,t.isAdminRole)(e))?(0,r.jsxs)(c.Modal,{title:(0,r.jsxs)("div",{className:"flex items-center space-x-3 pb-4 border-b border-gray-100",children:[(0,r.jsx)("span",{className:"text-2xl",children:"🔍"}),(0,r.jsx)("h2",{className:"text-xl font-semibold text-gray-900",children:"Add New Search Tool"})]}),open:n,width:800,onCancel:()=>{j.resetFields(),N({}),x(!1)},footer:null,className:"top-8",styles:{body:{padding:"24px"},header:{padding:"24px 24px 0 24px",border:"none"}},children:[(0,r.jsx)("div",{className:"mt-6",children:(0,r.jsxs)(o.Form,{form:j,onFinish:q,onValuesChange:(e,r)=>N(r),layout:"vertical",className:"space-y-6",children:[(0,r.jsxs)("div",{className:"grid grid-cols-1 gap-6",children:[(0,r.jsx)(o.Form.Item,{label:(0,r.jsxs)("span",{className:"text-sm font-medium text-gray-700 flex items-center",children:["Search Tool Name",(0,r.jsx)(f.Tooltip,{title:"A unique name to identify this search tool configuration (e.g., 'perplexity-search', 'tavily-news-search').",children:(0,r.jsx)(p.InfoCircleOutlined,{className:"ml-2 text-blue-400 hover:text-blue-600 cursor-help"})})]}),name:"search_tool_name",rules:[{required:!0,message:"Please enter a search tool name"},{pattern:/^[a-zA-Z0-9_-]+$/,message:"Name can only contain letters, numbers, hyphens, and underscores"}],children:(0,r.jsx)(g.TextInput,{placeholder:"e.g., perplexity-search, my-tavily-tool",className:"rounded-lg border-gray-300 focus:border-blue-500 focus:ring-blue-500"})}),(0,r.jsx)(o.Form.Item,{label:(0,r.jsxs)("span",{className:"text-sm font-medium text-gray-700 flex items-center",children:["Search Provider",(0,r.jsx)(f.Tooltip,{title:"Select the search provider you want to use. Each provider has different capabilities and pricing.",children:(0,r.jsx)(p.InfoCircleOutlined,{className:"ml-2 text-blue-400 hover:text-blue-600 cursor-help"})})]}),name:"search_provider",rules:[{required:!0,message:"Please select a search provider"}],children:(0,r.jsx)(d.Select,{placeholder:"Select a search provider",className:"rounded-lg",size:"large",loading:F,showSearch:!0,optionFilterProp:"children",optionLabelProp:"label",children:B.map(e=>(0,r.jsx)(d.Select.Option,{value:e.provider_name,label:(0,r.jsx)(w,{providerName:e.provider_name,displayName:e.ui_friendly_name}),children:(0,r.jsx)(w,{providerName:e.provider_name,displayName:e.ui_friendly_name})},e.provider_name))})}),(0,r.jsx)(o.Form.Item,{label:(0,r.jsxs)("span",{className:"text-sm font-medium text-gray-700 flex items-center",children:["API Key",(0,r.jsx)(f.Tooltip,{title:"The API key for authenticating with the search provider. This will be securely stored.",children:(0,r.jsx)(p.InfoCircleOutlined,{className:"ml-2 text-blue-400 hover:text-blue-600 cursor-help"})})]}),name:"api_key",rules:[{required:!1,message:"Please enter an API key"}],children:(0,r.jsx)(g.TextInput,{type:"password",placeholder:"Enter your API key",className:"rounded-lg border-gray-300 focus:border-blue-500 focus:ring-blue-500"})}),(0,r.jsx)(o.Form.Item,{label:(0,r.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Description (Optional)"}),name:"description",children:(0,r.jsx)(T,{rows:3,placeholder:"Brief description of this search tool's purpose",className:"rounded-lg border-gray-300 focus:border-blue-500 focus:ring-blue-500"})})]}),(0,r.jsxs)("div",{className:"flex justify-between items-center pt-6 border-t border-gray-100",children:[(0,r.jsx)(f.Tooltip,{title:"Get help on our github",children:(0,r.jsx)(y.Typography.Link,{href:"https://github.com/BerriAI/litellm/issues",target:"_blank",children:"Need Help?"})}),(0,r.jsxs)("div",{className:"space-x-2",children:[(0,r.jsx)(a.Button,{onClick:E,loading:I,children:"Test Connection"}),(0,r.jsx)(a.Button,{loading:b,type:"submit",children:"Add Search Tool"})]})]})]})}),(0,r.jsx)(c.Modal,{title:"Connection Test Results",open:S,onCancel:()=>{C(!1),z(!1)},footer:[(0,r.jsx)(a.Button,{onClick:()=>{C(!1),z(!1)},children:"Close"},"close")],width:700,children:S&&l&&(0,r.jsx)(k,{litellmParams:{search_provider:_.search_provider,api_key:_.api_key,api_base:_.api_base},accessToken:l,onTestComplete:()=>z(!1)},A)})]}):null};var I=e.i(332102);e.i(707701);var z=e.i(807235),A=e.i(541071),P=e.i(788699),D=e.i(727612),F=e.i(494862);e.i(622826);var B=e.i(200208),q=e.i(997422),E=e.i(112179),L=e.i(519455),M=e.i(755146),R=e.i(115504);function O({tool:e,onEdit:t,onDelete:s}){let a=e.is_from_config??!1,l=e.search_tool_id;return(0,r.jsxs)(M.DropdownMenu,{children:[(0,r.jsx)(M.DropdownMenuTrigger,{"aria-label":"Open search tool actions","data-testid":`search-tool-actions-${e.search_tool_id||e.search_tool_name}`,className:(0,R.cn)((0,L.buttonVariants)({variant:"ghost",size:"icon-sm"}),"text-muted-foreground"),children:(0,r.jsx)(A.MoreHorizontal,{className:"size-4"})}),(0,r.jsxs)(M.DropdownMenuContent,{align:"end",className:"w-52",children:[(0,r.jsxs)(M.DropdownMenuItem,{disabled:a||!l,"data-testid":"search-tool-action-edit",title:a?"Config search tools cannot be edited on the dashboard. Please edit the config file.":void 0,onClick:()=>l&&t(l),children:[(0,r.jsx)(P.Pencil,{}),"Edit search tool"]}),(0,r.jsx)(M.DropdownMenuSeparator,{}),(0,r.jsxs)(M.DropdownMenuItem,{variant:"destructive",disabled:a||!l,"data-testid":"search-tool-action-delete",title:a?"Config search tools cannot be deleted on the dashboard. Please edit the config file.":void 0,onClick:()=>l&&s(l),children:[(0,r.jsx)(D.Trash2,{}),"Delete search tool"]})]})]})}let H=[{id:"created_at",desc:!0}];function K(){return(0,r.jsxs)("div",{className:"flex flex-col items-center gap-1 py-6",children:[(0,r.jsx)("div",{className:"mb-1 flex size-10 items-center justify-center rounded-lg bg-muted",children:(0,r.jsx)(I.Inbox,{className:"size-5 text-muted-foreground"})}),(0,r.jsx)("div",{className:"text-sm font-medium text-foreground",children:"No search tools configured"}),(0,r.jsx)("div",{className:"text-sm text-muted-foreground",children:"Add a search tool to enable web search for your models."})]})}let $=({searchTools:e,isLoading:t,availableProviders:s,onView:a,onEdit:l,onDelete:i})=>{let[o,n]=(0,h.useState)(H),c=(0,h.useMemo)(()=>(({availableProviders:e,onView:t,onEdit:s,onDelete:a})=>[{id:"search_tool_id",accessorKey:"search_tool_id",meta:{title:"Search Tool ID"},header:({column:e})=>(0,r.jsx)(F.DataTableSortHeader,{column:e,title:"Search Tool ID"}),size:200,enableSorting:!0,cell:({row:e})=>{let s=e.original,a=s.search_tool_id;return s.is_from_config||!a?(0,r.jsx)("span",{className:"text-muted-foreground",children:"-"}):(0,r.jsx)(q.IdentityCell,{title:a,titleClassName:"font-mono text-xs font-normal",onClick:()=>t(a)})}},{id:"search_tool_name",accessorKey:"search_tool_name",meta:{title:"Name"},header:({column:e})=>(0,r.jsx)(F.DataTableSortHeader,{column:e,title:"Name"}),size:200,enableSorting:!0,cell:({row:e})=>(0,r.jsx)("span",{className:"block max-w-60 truncate text-sm font-medium",title:e.original.search_tool_name,children:e.original.search_tool_name||"-"})},{id:"provider",meta:{title:"Provider"},header:"Provider",size:160,enableSorting:!1,cell:({row:t})=>{let s=t.original.litellm_params.search_provider,a=e.find(e=>e.provider_name===s);return(0,r.jsx)("span",{className:"text-sm",children:a?.ui_friendly_name||s})}},{id:"created_at",accessorKey:"created_at",meta:{title:"Created At"},header:({column:e})=>(0,r.jsx)(F.DataTableSortHeader,{column:e,title:"Created At"}),size:130,enableSorting:!0,cell:({row:e})=>(0,r.jsx)(B.DateCell,{value:e.original.created_at,precision:"date"})},{id:"updated_at",accessorKey:"updated_at",meta:{title:"Updated At"},header:({column:e})=>(0,r.jsx)(F.DataTableSortHeader,{column:e,title:"Updated At"}),size:130,enableSorting:!0,cell:({row:e})=>(0,r.jsx)(B.DateCell,{value:e.original.updated_at,precision:"date"})},{id:"source",meta:{title:"Source",skeleton:"badge"},header:"Source",size:100,enableSorting:!1,cell:({row:e})=>{let t=e.original.is_from_config??!1;return(0,r.jsx)(E.StatusBadge,{tone:t?"neutral":"info",label:t?"Config":"DB"})}},{id:"actions",meta:{className:"text-right",headerClassName:"text-right"},header:()=>(0,r.jsx)("span",{className:"sr-only",children:"Actions"}),size:64,enableSorting:!1,enableHiding:!1,cell:({row:e})=>(0,r.jsx)("div",{className:"flex justify-end",children:(0,r.jsx)(O,{tool:e.original,onEdit:s,onDelete:a})})}])({availableProviders:s,onView:a,onEdit:l,onDelete:i}),[s,a,l,i]);return(0,r.jsx)(z.DataTable,{data:e,columns:c,getRowId:(e,r)=>e.search_tool_id||e.search_tool_name||String(r),sortingMode:"client",sorting:o,onSortingChange:n,isLoading:t,loadingMessage:"Loading search tools…",noDataMessage:(0,r.jsx)(K,{}),size:"compact"})};var U=e.i(500330),V=e.i(530212),W=e.i(304967),Q=e.i(350967),G=e.i(678784),Y=e.i(118366),Z=e.i(482725),J=e.i(888259),X=e.i(928685),ee=e.i(56456);let{Text:er}=y.Typography,et=({searchToolName:e,accessToken:t,className:s=""})=>{let[a,l]=(0,h.useState)(""),[o,c]=(0,h.useState)(!1),[d,x]=(0,h.useState)([]),[p,g]=(0,h.useState)({}),[f,y]=(0,h.useState)(!1),j=async()=>{if(!a.trim())return void J.default.warning("Please enter a search query");c(!0);let r=performance.now();try{let s=await (0,u.searchToolQueryCall)(t,e,a),l=performance.now(),i=Math.round(l-r),o={query:a,response:s,timestamp:Date.now(),latency:i};x(e=>[o,...e])}catch(e){console.error("Error querying search tool:",e),m.default.fromBackend("Failed to query search tool")}finally{c(!1)}},b=e=>new Date(e).toLocaleString(),v=(0,r.jsx)(ee.LoadingOutlined,{style:{fontSize:24},spin:!0}),N=d.length>0?d[0]:null;return(0,r.jsxs)(W.Card,{className:"mt-6",children:[(0,r.jsx)("div",{className:"mb-6",children:(0,r.jsx)(i.Title,{children:"Test Search Tool"})}),(0,r.jsxs)("div",{className:"flex flex-col",style:{minHeight:"600px"},children:[(0,r.jsx)("div",{className:"mb-6",children:(0,r.jsxs)("div",{className:"flex items-stretch gap-3",children:[(0,r.jsxs)("div",{className:"flex items-center flex-1 bg-white rounded-lg px-4 transition-all duration-200",style:{border:f?"2px solid #3b82f6":"2px solid #e5e7eb",boxShadow:f?"0 0 0 3px rgba(59, 130, 246, 0.1)":"0 1px 2px 0 rgba(0, 0, 0, 0.05)",height:"48px"},children:[(0,r.jsx)(X.SearchOutlined,{className:"text-gray-400 mr-3",style:{fontSize:"18px"}}),(0,r.jsx)(n.Input,{value:a,onChange:e=>l(e.target.value),onFocus:()=>y(!0),onBlur:()=>y(!1),onPressEnter:e=>{e.shiftKey||(e.preventDefault(),j())},placeholder:"Enter your search query...",disabled:o,bordered:!1,style:{fontSize:"15px",padding:0,height:"100%",boxShadow:"none"}})]}),(0,r.jsx)(_.Button,{type:"primary",onClick:j,disabled:o||!a.trim(),icon:(0,r.jsx)(X.SearchOutlined,{}),loading:o,style:{height:"48px",paddingLeft:"24px",paddingRight:"24px",borderRadius:"8px",fontWeight:500,fontSize:"15px",backgroundColor:o||!a.trim()?void 0:"#1890ff",borderColor:o||!a.trim()?void 0:"#1890ff",boxShadow:"0 1px 2px 0 rgba(0, 0, 0, 0.05)"},children:"Search"})]})}),(0,r.jsx)("div",{className:"flex-1",children:N||o?(0,r.jsxs)("div",{children:[o&&(0,r.jsxs)("div",{className:"flex flex-col justify-center items-center py-16",children:[(0,r.jsx)(Z.Spin,{indicator:v}),(0,r.jsx)(er,{className:"mt-4 text-gray-600 font-medium",children:"Searching..."})]}),N&&!o&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("div",{className:"mb-6 p-4 bg-blue-50 border border-blue-200 rounded-lg",style:{boxShadow:"0 1px 2px 0 rgba(0, 0, 0, 0.05)"},children:(0,r.jsxs)("div",{className:"flex items-center justify-between",children:[(0,r.jsxs)("div",{className:"flex-1",children:[(0,r.jsx)(er,{className:"text-xs font-semibold text-gray-500 uppercase tracking-wide",children:"Search Query"}),(0,r.jsx)("div",{className:"text-base font-semibold text-gray-900 mt-1.5",children:N.query})]}),(0,r.jsxs)("div",{className:"text-right ml-4",children:[(0,r.jsx)(er,{className:"text-xs text-gray-500",children:b(N.timestamp)}),(0,r.jsxs)("div",{className:"flex items-center gap-3 mt-1",children:[(0,r.jsxs)("div",{className:"text-sm font-semibold text-blue-600",children:[N.response?.results?.length||0," ",N.response?.results?.length===1?"result":"results"]}),void 0!==N.latency&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("span",{className:"text-gray-400",children:"•"}),(0,r.jsxs)("div",{className:"text-sm font-semibold text-green-600",children:[N.latency,"ms"]})]})]})]})]})}),N.response&&N.response.results&&N.response.results.length>0?(0,r.jsx)("div",{className:"space-y-3",children:N.response.results.map((e,t)=>{let s=p[`0-${t}`]||!1;return(0,r.jsx)("div",{className:"bg-white border border-gray-200 rounded-lg overflow-hidden transition-all duration-200",style:{boxShadow:"0 1px 2px 0 rgba(0, 0, 0, 0.05)"},onMouseEnter:e=>{e.currentTarget.style.boxShadow="0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)",e.currentTarget.style.borderColor="#e0e7ff"},onMouseLeave:e=>{e.currentTarget.style.boxShadow="0 1px 2px 0 rgba(0, 0, 0, 0.05)",e.currentTarget.style.borderColor="#e5e7eb"},children:(0,r.jsxs)("div",{className:"p-5",children:[(0,r.jsxs)("div",{className:"flex items-start justify-between gap-3 mb-2",children:[(0,r.jsx)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",className:"text-lg font-semibold text-blue-600 hover:text-blue-700 flex-1 leading-snug",style:{textDecoration:"none"},onMouseEnter:e=>e.currentTarget.style.textDecoration="underline",onMouseLeave:e=>e.currentTarget.style.textDecoration="none",children:e.title}),(0,r.jsx)(_.Button,{type:"text",size:"small",className:"shrink-0",icon:(0,r.jsx)("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,r.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"})}),onClick:()=>window.open(e.url,"_blank"),style:{color:"#6b7280"}})]}),(0,r.jsx)("div",{className:"text-sm text-green-700 mb-3 truncate font-medium",children:e.url}),(0,r.jsx)("div",{className:"text-sm text-gray-700 leading-relaxed",children:s?e.snippet:`${e.snippet.substring(0,200)}${e.snippet.length>200?"...":""}`}),e.snippet.length>200&&(0,r.jsx)(_.Button,{type:"link",size:"small",className:"mt-3 p-0 h-auto",onClick:()=>{let e;return e=`0-${t}`,void g(r=>({...r,[e]:!r[e]}))},style:{fontSize:"13px",fontWeight:500,color:"#3b82f6"},children:s?"Show less":"Show more"})]})},t)})}):(0,r.jsxs)("div",{className:"text-center py-12 bg-gray-50 border border-gray-200 rounded-lg",children:[(0,r.jsx)("div",{className:"flex items-center justify-center w-16 h-16 rounded-full bg-gray-100 mx-auto mb-4",children:(0,r.jsx)(X.SearchOutlined,{style:{fontSize:"24px",color:"#9ca3af"}})}),(0,r.jsx)(er,{className:"text-gray-600 font-medium",children:"No results found"}),(0,r.jsx)(er,{className:"text-sm text-gray-500 mt-1",children:"Try a different search query"})]})]}),d.length>1&&(0,r.jsxs)("div",{className:"mt-8 pt-6 border-t border-gray-200",children:[(0,r.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[(0,r.jsx)(er,{className:"text-sm font-semibold text-gray-700",children:"Previous Searches"}),(0,r.jsx)(_.Button,{onClick:()=>{x([]),g({}),m.default.success("Search history cleared")},size:"small",type:"link",style:{fontSize:"13px",fontWeight:500},children:"Clear All"})]}),(0,r.jsx)("div",{className:"space-y-2",children:d.slice(1,6).map((e,t)=>(0,r.jsxs)("div",{className:"p-3 bg-gray-50 border border-gray-200 rounded-lg cursor-pointer transition-all duration-200 hover:bg-gray-100 hover:border-gray-300",onClick:()=>{l(e.query)},children:[(0,r.jsx)("div",{className:"text-sm font-medium text-gray-800 truncate",children:e.query}),(0,r.jsxs)("div",{className:"text-xs text-gray-500 mt-1.5 flex items-center gap-2",children:[(0,r.jsxs)("span",{className:"font-medium text-blue-600",children:[e.response?.results?.length||0," ",e.response?.results?.length===1?"result":"results"]}),void 0!==e.latency&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("span",{children:"•"}),(0,r.jsxs)("span",{className:"font-medium text-green-600",children:[e.latency,"ms"]})]}),(0,r.jsx)("span",{children:"•"}),(0,r.jsx)("span",{children:b(e.timestamp)})]})]},t+1))})]})]}):(0,r.jsxs)("div",{className:"h-full flex flex-col items-center justify-center p-8",children:[(0,r.jsx)("div",{className:"flex items-center justify-center w-24 h-24 rounded-full bg-gray-100 mb-6",children:(0,r.jsx)(X.SearchOutlined,{style:{fontSize:"48px",color:"#9ca3af"}})}),(0,r.jsx)(er,{className:"text-lg text-gray-600 font-medium",children:"Test your search tool"}),(0,r.jsx)(er,{className:"text-sm text-gray-500 mt-2",children:"Enter a query above to see search results"})]})})]})]})},es=({searchTool:e,onBack:t,isEditing:s,accessToken:o,availableProviders:n})=>{var c;let d,[x,m]=(0,h.useState)({}),u=async(e,r)=>{await (0,U.copyToClipboard)(e)&&(m(e=>({...e,[r]:!0})),setTimeout(()=>{m(e=>({...e,[r]:!1}))},2e3))};return(0,r.jsxs)("div",{className:"p-4 max-w-full",children:[(0,r.jsx)("div",{className:"flex justify-between items-center mb-6",children:(0,r.jsxs)("div",{children:[(0,r.jsx)(a.Button,{icon:V.ArrowLeftIcon,variant:"light",className:"mb-4",onClick:t,children:"Back to All Search Tools"}),(0,r.jsxs)("div",{className:"flex items-center cursor-pointer",children:[(0,r.jsx)(i.Title,{children:e.search_tool_name}),(0,r.jsx)(_.Button,{type:"text",size:"small",icon:x["search-tool-name"]?(0,r.jsx)(G.CheckIcon,{size:12}):(0,r.jsx)(Y.CopyIcon,{size:12}),onClick:()=>u(e.search_tool_name,"search-tool-name"),className:`left-2 z-10 transition-all duration-200 ${x["search-tool-name"]?"text-green-600 bg-green-50 border-green-200":"text-gray-500 hover:text-gray-700 hover:bg-gray-100"}`})]}),(0,r.jsxs)("div",{className:"flex items-center cursor-pointer",children:[(0,r.jsx)(l.Text,{className:"text-gray-500 font-mono",children:e.search_tool_id}),(0,r.jsx)(_.Button,{type:"text",size:"small",icon:x["search-tool-id"]?(0,r.jsx)(G.CheckIcon,{size:12}):(0,r.jsx)(Y.CopyIcon,{size:12}),onClick:()=>u(e.search_tool_id,"search-tool-id"),className:`left-2 z-10 transition-all duration-200 ${x["search-tool-id"]?"text-green-600 bg-green-50 border-green-200":"text-gray-500 hover:text-gray-700 hover:bg-gray-100"}`})]})]})}),(0,r.jsxs)(Q.Grid,{numItems:1,numItemsSm:2,numItemsLg:3,className:"gap-6",children:[(0,r.jsxs)(W.Card,{children:[(0,r.jsx)(l.Text,{children:"Provider"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)(i.Title,{children:(c=e.litellm_params.search_provider,d=n.find(e=>e.provider_name===c),d?.ui_friendly_name||c)})})]}),(0,r.jsxs)(W.Card,{children:[(0,r.jsx)(l.Text,{children:"API Key"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)(l.Text,{children:e.litellm_params.api_key?"****":"Not set"})})]}),(0,r.jsxs)(W.Card,{children:[(0,r.jsx)(l.Text,{children:"Created At"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)(l.Text,{children:e.created_at?new Date(e.created_at).toLocaleString():"Unknown"})})]})]}),e.search_tool_info?.description&&(0,r.jsxs)(W.Card,{className:"mt-6",children:[(0,r.jsx)(l.Text,{children:"Description"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)(l.Text,{children:e.search_tool_info.description})})]}),(0,r.jsx)("div",{className:"mt-6",children:o&&(0,r.jsx)(et,{searchToolName:e.search_tool_name,accessToken:o})})]})},ea=({accessToken:e,userRole:p,userID:g})=>{let{data:f,isLoading:y,refetch:j}=(0,s.useQuery)({queryKey:["searchTools"],queryFn:()=>{if(!e)throw Error("Access Token required");return(0,u.fetchSearchTools)(e).then(e=>e.search_tools||[])},enabled:!!e}),{data:b,isLoading:v}=(0,s.useQuery)({queryKey:["searchProviders"],queryFn:()=>{if(!e)throw Error("Access Token required");return(0,u.fetchAvailableSearchProviders)(e)},enabled:!!e}),_=b?.providers||[],[N,S]=(0,h.useState)(null),[k,T]=(0,h.useState)(!1),[w,I]=(0,h.useState)(!1),[z,A]=(0,h.useState)(null),[P,D]=(0,h.useState)(!1),[F,B]=(0,h.useState)(!1),[q,E]=(0,h.useState)(!1),[L]=o.Form.useForm(),M=e=>{A(e),D(!1)},R=e=>{let r=f?.find(r=>r.search_tool_id===e);if(!r)return;let t={search_tool_name:r.search_tool_name,search_provider:r.litellm_params.search_provider,api_key:r.litellm_params.api_key,api_base:r.litellm_params.api_base,timeout:r.litellm_params.timeout,max_retries:r.litellm_params.max_retries,description:r.search_tool_info?.description};L.setFieldsValue(t),A(e),E(!0)};function O(e){S(e),T(!0)}let H=async()=>{if(null!=N&&null!=e){I(!0);try{await (0,u.deleteSearchTool)(e,N),m.default.success("Deleted search tool successfully"),T(!1),S(null),j()}catch(e){console.error("Error deleting the search tool:",e),m.default.error("Failed to delete search tool")}finally{I(!1)}}},K=f?.find(e=>e.search_tool_id===N),U=K?_.find(e=>e.provider_name===K.litellm_params.search_provider):null,V=async()=>{if(e&&z)try{let r=await L.validateFields(),t={search_tool_name:r.search_tool_name,litellm_params:{search_provider:r.search_provider,api_key:r.api_key,api_base:r.api_base,timeout:r.timeout?parseFloat(r.timeout):void 0,max_retries:r.max_retries?parseInt(r.max_retries):void 0},search_tool_info:r.description?{description:r.description}:void 0};await (0,u.updateSearchTool)(e,z,t),m.default.success("Search tool updated successfully"),E(!1),L.resetFields(),A(null),j()}catch(e){console.error("Failed to update search tool:",e),m.default.error("Failed to update search tool")}};return e&&p&&g?(0,r.jsxs)("div",{className:"w-full h-full p-6",children:[(0,r.jsx)(x.default,{isOpen:k,title:"Delete Search Tool",message:"Are you sure you want to delete this search tool? This action cannot be undone.",resourceInformationTitle:"Search Tool Information",resourceInformation:K?[{label:"Name",value:K.search_tool_name},{label:"ID",value:K.search_tool_id,code:!0},{label:"Provider",value:U?.ui_friendly_name||K.litellm_params.search_provider},{label:"Description",value:K.search_tool_info?.description||"-"}]:[],onCancel:()=>{T(!1),S(null)},onOk:H,confirmLoading:w}),(0,r.jsx)(C,{userRole:p,accessToken:e,onCreateSuccess:e=>{B(!1),j()},isModalVisible:F,setModalVisible:B}),(0,r.jsx)(c.Modal,{title:"Edit Search Tool",open:q,onOk:V,onCancel:()=>{E(!1),L.resetFields(),A(null)},width:600,children:(0,r.jsxs)(o.Form,{form:L,layout:"vertical",children:[(0,r.jsx)(o.Form.Item,{name:"search_tool_name",label:"Search Tool Name",rules:[{required:!0,message:"Please enter a search tool name"}],children:(0,r.jsx)(n.Input,{placeholder:"e.g., my-perplexity-search"})}),(0,r.jsx)(o.Form.Item,{name:"search_provider",label:"Search Provider",rules:[{required:!0,message:"Please select a search provider"}],children:(0,r.jsx)(d.Select,{placeholder:"Select a search provider",loading:v,children:_.map(e=>(0,r.jsx)(d.Select.Option,{value:e.provider_name,children:e.ui_friendly_name},e.provider_name))})}),(0,r.jsx)(o.Form.Item,{name:"api_key",label:"API Key",extra:"API key for the search provider",children:(0,r.jsx)(n.Input.Password,{placeholder:"Enter API key"})}),(0,r.jsx)(o.Form.Item,{name:"description",label:"Description",children:(0,r.jsx)(n.Input.TextArea,{rows:3,placeholder:"Description of this search tool"})})]})}),(0,r.jsx)(i.Title,{children:"Search Tools"}),(0,r.jsx)(l.Text,{className:"text-tremor-content mt-2",children:"Configure and manage your search providers"}),(0,t.isAdminRole)(p)&&(0,r.jsx)(a.Button,{className:"mt-4 mb-4",onClick:()=>B(!0),children:"+ Add New Search Tool"}),(0,r.jsx)(()=>z?(0,r.jsx)(es,{searchTool:f?.find(e=>e.search_tool_id===z)||{search_tool_id:"",search_tool_name:"",litellm_params:{search_provider:""}},onBack:()=>{D(!1),A(null),j()},isEditing:P,accessToken:e,availableProviders:_}):(0,r.jsx)("div",{className:"w-full h-full",children:(0,r.jsx)($,{searchTools:f||[],isLoading:y,availableProviders:_,onView:M,onEdit:R,onDelete:O})}),{})]}):(0,r.jsx)("div",{className:"p-6 text-center text-gray-500",children:"Missing required authentication parameters."})};var el=e.i(135214);e.s(["default",0,function(){let{accessToken:e,userRole:t,userId:s}=(0,el.default)();return(0,r.jsx)(ea,{accessToken:e,userRole:t,userID:s})}],962296)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/007c8g8hmd9qz.js b/litellm/proxy/_experimental/out/_next/static/chunks/007c8g8hmd9qz.js new file mode 100644 index 00000000000..fe0f6e8e79a --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/007c8g8hmd9qz.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,510674,e=>{"use strict";var t=e.i(266027),l=e.i(243652),a=e.i(602869),s=e.i(431703),i=e.i(135214),r=e.i(708347);let n=(0,l.createQueryKeys)("projects"),o=[...r.all_admin_roles,...r.internalUserRoles],d=async e=>{let t=(0,a.getProxyBaseUrl)(),l=`${t}/project/list`,i=await fetch(l,{method:"GET",headers:{[(0,a.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!i.ok){let e=await i.json(),t=(0,s.deriveErrorMessage)(e);throw(0,a.handleError)(t),Error(t)}return i.json()};e.s(["projectKeys",0,n,"useProjects",0,()=>{let{accessToken:e,userRole:l}=(0,i.default)();return(0,t.useQuery)({queryKey:n.list({}),queryFn:async()=>d(e),enabled:!!e&&o.includes(l)})}])},207082,e=>{"use strict";var t=e.i(619273),l=e.i(266027),a=e.i(243652),s=e.i(602869),i=e.i(431703),r=e.i(135214);let n=(0,a.createQueryKeys)("keys"),o=async(e,t,l,a={})=>{try{let r=(0,s.getProxyBaseUrl)(),n=new URLSearchParams(Object.entries({team_id:a.teamID,project_id:a.projectID,agent_id:a.agentID,organization_id:a.organizationID,key_alias:a.selectedKeyAlias,key_hash:a.keyHash,user_id:a.userID,page:t,size:l,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",substring_matching:"true"}).filter(([,e])=>null!=e).map(([e,t])=>[e,String(t)])),o=`${r?`${r}/key/list`:"/key/list"}?${n}`,d=await fetch(o,{method:"GET",headers:{[(0,s.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!d.ok){let e=await d.json(),t=(0,i.deriveErrorMessage)(e);throw(0,s.handleError)(t),Error(t)}return await d.json()}catch(e){throw console.error("Failed to list keys:",e),e}},d=(0,a.createQueryKeys)("deletedKeys");e.s(["keyKeys",0,n,"useDeletedKeys",0,(e,a,s={})=>{let{accessToken:i}=(0,r.default)();return(0,l.useQuery)({queryKey:d.list({page:e,limit:a,...s}),queryFn:async()=>await o(i,e,a,{...s,status:"deleted"}),enabled:!!i,staleTime:3e4,placeholderData:t.keepPreviousData})},"useKeys",0,(e,a,s={},i=!0)=>{let{accessToken:d}=(0,r.default)();return(0,l.useQuery)({queryKey:n.list({page:e,limit:a,...s}),queryFn:async()=>await o(d,e,a,s),enabled:!!d&&i,staleTime:3e4,placeholderData:t.keepPreviousData})}])},109034,e=>{"use strict";var t=e.i(266027),l=e.i(243652),a=e.i(602869),s=e.i(135214);let i=(0,l.createQueryKeys)("tags");e.s(["useTags",0,()=>{let{accessToken:e,userId:l,userRole:r}=(0,s.default)();return(0,t.useQuery)({queryKey:i.list({}),queryFn:async()=>await (0,a.tagListCall)(e),enabled:!!(e&&l&&r)})}])},309426,e=>{"use strict";var t=e.i(290571),l=e.i(444755),a=e.i(673706),s=e.i(271645),i=e.i(46757);let r=(0,a.makeClassName)("Col"),n=s.default.forwardRef((e,a)=>{let n,o,d,c,{numColSpan:u=1,numColSpanSm:m,numColSpanMd:g,numColSpanLg:p,children:h,className:x}=e,y=(0,t.__rest)(e,["numColSpan","numColSpanSm","numColSpanMd","numColSpanLg","children","className"]),f=(e,t)=>e&&Object.keys(t).includes(String(e))?t[e]:"";return s.default.createElement("div",Object.assign({ref:a,className:(0,l.tremorTwMerge)(r("root"),(n=f(u,i.colSpan),o=f(m,i.colSpanSm),d=f(g,i.colSpanMd),c=f(p,i.colSpanLg),(0,l.tremorTwMerge)(n,o,d,c)),x)},y),h)});n.displayName="Col",e.s(["Col",0,n],309426)},552130,e=>{"use strict";var t=e.i(843476),l=e.i(271645),a=e.i(199133),s=e.i(602869);e.s(["default",0,({onChange:e,value:i,className:r,accessToken:n,placeholder:o="Select agents",disabled:d=!1})=>{let[c,u]=(0,l.useState)([]),[m,g]=(0,l.useState)([]),[p,h]=(0,l.useState)(!1);(0,l.useEffect)(()=>{(async()=>{if(n){h(!0);try{let e=await (0,s.getAgentsList)(n),t=e?.agents||[];u(t);let l=new Set;t.forEach(e=>{let t=e.agent_access_groups;t&&Array.isArray(t)&&t.forEach(e=>l.add(e))}),g(Array.from(l))}catch(e){console.error("Error fetching agents:",e)}finally{h(!1)}}})()},[n]);let x=[...m.map(e=>({label:e,value:`group:${e}`,isAccessGroup:!0,searchText:`${e} Access Group`})),...c.map(e=>({label:`${e.agent_name||e.agent_id}`,value:e.agent_id,isAccessGroup:!1,searchText:`${e.agent_name||e.agent_id} ${e.agent_id} Agent`}))],y=[...i?.agents||[],...(i?.accessGroups||[]).map(e=>`group:${e}`)];return(0,t.jsx)("div",{children:(0,t.jsx)(a.Select,{mode:"multiple",placeholder:o,onChange:t=>{e({agents:t.filter(e=>!e.startsWith("group:")),accessGroups:t.filter(e=>e.startsWith("group:")).map(e=>e.replace("group:",""))})},value:y,loading:p,className:r,allowClear:!0,showSearch:!0,style:{width:"100%"},disabled:d,filterOption:(e,t)=>(x.find(e=>e.value===t?.value)?.searchText||"").toLowerCase().includes(e.toLowerCase()),children:x.map(e=>(0,t.jsx)(a.Select.Option,{value:e.value,label:e.label,children:(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[(0,t.jsx)("span",{style:{display:"inline-block",width:8,height:8,borderRadius:"50%",background:e.isAccessGroup?"#52c41a":"#722ed1",flexShrink:0}}),(0,t.jsx)("span",{style:{flex:1},children:e.label}),(0,t.jsx)("span",{style:{color:e.isAccessGroup?"#52c41a":"#722ed1",fontSize:"12px",fontWeight:500,opacity:.8},children:e.isAccessGroup?"Access Group":"Agent"})]})},e.value))})})}])},557662,e=>{"use strict";let t={src:e.i(196361).default,width:823,height:807,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAABCUlEQVR42k2Ov0sCYRjH3/f09c68NOuiLg+NvMM6qIaIhgKDlgbBBiH7ARbkFAr+wEFwUBzUSRwUN3+Am4Kbg4sIIg4iOugiguDm5F/gvaLiF57l83yf5/sFYC0VQdJJnS0bObUkSCgnwa4ggPD94O57KkYX46vw/HVftECMNzKRJ2JL8A+KekelfO6s1Y3utl6hNayWahmlznIfhQbv6V4oGP6aOrvtCIFRnH1LKQmkBC7G7BtehmZWzY0NRxEAEo7Dhz/MvrT3P6BvCk5irDVJQURhAx5aKpzh7Pkm7+2BZ1p4YeT0MYIy5Dx6/P+UrvAXFml0TyqjeVtUytsrGX6rac6ew+YNXwKfsTPy4XOyEQAAAABJRU5ErkJggg=="},l={src:e.i(614148).default,width:600,height:450,blurWidth:0,blurHeight:0},a={src:e.i(858236).default,width:200,height:200,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAqklEQVR42mXOzQqCQBQF4NG8PVKLalNRrxW01EgUghZm4Tu0aV3gopBCaDDoh8LMyubaCzQzLj2c1fk2h/zwyZvjI8NTmtMXHj94yfBG5JqE0WrsDWyv70eLGOkbrwJotG316lDVeJvd2pouE3YW4M4nAEBkADTD1eOvBNPUFUUpQAMwplbK7gJsa6hWVG58bXTam0OAmAjYBT63kWk4Myeke2TiJynulvsHOZp6y2XrD90AAAAASUVORK5CYII="},s={src:e.i(508296).default,width:180,height:180,blurWidth:8,blurHeight:8,blurDataURL:"data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/wAARCAAIAAgDAREAAhEBAxEB/9sAQwAKBwcIBwYKCAgICwoKCw4YEA4NDQ4dFRYRGCMfJSQiHyIhJis3LyYpNCkhIjBBMTQ5Oz4+PiUuRElDPEg3PT47/9sAQwEKCwsODQ4cEBAcOygiKDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDvXivVvITItyZVvSwKFmDRbjjPYDB/SutONn6fiaaH/9k="},i={src:e.i(324755).default,width:48,height:48,blurWidth:0,blurHeight:0},r={src:e.i(475151).default,width:14,height:16,blurWidth:0,blurHeight:0},n={src:e.i(274286).default,width:256,height:256,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA/ElEQVR42m3Pz0vCUADA8ed7a3uBjb0sx5C1Ri1oIDJSKEdJgyEFtbwFgScpsGNR1CmyS0Ho0ZOggv+A4F3B30f9HwRRwYMICupNPPg5fa9fANazLQtCtC0jdGbSdFSmN6+Ry/tIHd/+w52jOwyRCDRZL+UJ6eREdXauR0dq8HtiBl7mD25r+MtyLfBO+Fpm19UXTsJ17LnPWhyf+rNvVWOiu38j+Zrgk/CNuHDYtfsiRUa1khYnpH9Y0viQtIGxf1oGfsVoFxzOYULR51f+p6lifo09wdjs0hvuvbKkAhDF7GkUFYpgnLhg8DPtOAghOfAGiWRs2KBz/dqKBVIdOzeF2+/ZAAAAAElFTkSuQmCC"},o={src:e.i(436494).default,width:200,height:200,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAnElEQVR42oXOsQqCUACF4ftWvUFbBFFzQSVRLQ5RmRDkUJFTIUFNEQgNDWFTNURjgyAiOgiiCF7FQRCcVFQQJ1H4t284B1gwzA0UAS/A2+N7pp8nmrne3yynJ6Cp3mBBoARZbfcqjVZ3tkSwlSw7QFHc5gitI+M1delM8LhafyhKNjCN4PPjsR2Fk8f59jDd7JnXHxp+Oh5zVsmrCGlHlzZm+jq8AAAAAElFTkSuQmCC"},d={src:e.i(204086).default,width:48,height:48,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAhElEQVR42oWPuw0DIRBEr6g7aIGQAAQSEiTk1EAHVILogIQAQUPOxoKT5cSfYDbYedqdOc7zfFzXhU9a3vHNfGkDhBB472GMQQgB1lo45/Z+A4wx9N6Rc8acE7VWpJRuYI0YI1prW6UUjDHAOb9fLEAIAaXUPi2lhNYalNJ3hp8h/9V8AqCAe6iqrOaAAAAAAElFTkSuQmCC"},c={src:e.i(531150).default,width:48,height:48,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA40lEQVR42lWOvesBcQDGz0/9VmUl/4lSyqaUic5gM0jKSBlISgaXwWCwGc7gFPKeIikUMXAldec9Wdx5uft+v3KFMzzL8/k89WAIIUweyLG6W9tRFNmKGUHw9wMfAvgfDBfWddWbv5aNE5Gtmr9LiBSNzgq3uQv7UKzY2tZ9uXvfl/4IxxOvyeZn/niyQkWJJkXTjB7ez2oJHk6cNpzo5ohUjeTHRICnSScEQPliGIKistef23FPYUNSo6CwJHGw6xgQggpJEBYZ12UQiY2njOnCPVSv528oCWDbNopMySIv5XkCtum3l9/HqzEAAAAASUVORK5CYII="},u=[{id:"arize",displayName:"Arize",logo:t.src,supports_key_team_logging:!0,dynamic_params:{arize_api_key:"password",arize_space_id:"password"},description:"Arize Logging Integration"},{id:"braintrust",displayName:"Braintrust",logo:a.src,supports_key_team_logging:!1,dynamic_params:{braintrust_api_key:"password",braintrust_project_name:"text"},description:"Braintrust Logging Integration"},{id:"custom_callback_api",displayName:"Custom Callback API",supports_key_team_logging:!0,dynamic_params:{custom_callback_api_url:"text",custom_callback_api_headers:"text"},description:"Custom Callback API Logging Integration"},{id:"galileo",displayName:"Galileo",logo:i.src,supports_key_team_logging:!1,dynamic_params:{GALILEO_API_KEY:"password",GALILEO_PROJECT_ID:"text",GALILEO_LOG_STREAM_ID:"text",GALILEO_BASE_URL:"text",GALILEO_USERNAME:"text",GALILEO_PASSWORD:"password"},description:"Galileo AI Observability Integration"},{id:"datadog",displayName:"Datadog",logo:s.src,supports_key_team_logging:!1,dynamic_params:{dd_api_key:"password",dd_site:"text"},description:"Datadog Logging Integration"},{id:"lago",displayName:"Lago",logo:r.src,supports_key_team_logging:!1,dynamic_params:{lago_api_url:"text",lago_api_key:"password"},description:"Lago Billing Logging Integration"},{id:"langfuse",displayName:"Langfuse",logo:n.src,supports_key_team_logging:!0,dynamic_params:{langfuse_public_key:"text",langfuse_secret_key:"password",langfuse_host:"text"},description:"Langfuse v2 Logging Integration"},{id:"langfuse_otel",displayName:"Langfuse OTEL",logo:n.src,supports_key_team_logging:!0,dynamic_params:{langfuse_public_key:"text",langfuse_secret_key:"password",langfuse_host:"text"},description:"Langfuse v3 OTEL Logging Integration"},{id:"langsmith",displayName:"LangSmith",logo:o.src,supports_key_team_logging:!0,dynamic_params:{langsmith_api_key:"password",langsmith_project:"text",langsmith_base_url:"text",langsmith_sampling_rate:"number"},description:"Langsmith Logging Integration"},{id:"openmeter",displayName:"OpenMeter",logo:d.src,supports_key_team_logging:!1,dynamic_params:{openmeter_api_key:"password",openmeter_base_url:"text"},description:"OpenMeter Logging Integration"},{id:"otel",displayName:"Open Telemetry",logo:c.src,supports_key_team_logging:!1,dynamic_params:{otel_endpoint:"text",otel_headers:"text"},description:"OpenTelemetry Logging Integration"},{id:"s3",displayName:"S3",logo:l.src,supports_key_team_logging:!1,dynamic_params:{s3_bucket_name:"text",aws_access_key_id:"password",aws_secret_access_key:"password",aws_region:"text"},description:"S3 Bucket (AWS) Logging Integration"},{id:"SQS",displayName:"SQS",logo:l.src,supports_key_team_logging:!1,dynamic_params:{sqs_queue_url:"text",aws_access_key_id:"password",aws_secret_access_key:"password",aws_region:"text"},description:"SQS Queue (AWS) Logging Integration"}],m=u.reduce((e,t)=>(e[t.displayName]=t,e),{}),g=u.reduce((e,t)=>(e[t.displayName]=t.id,e),{}),p=u.reduce((e,t)=>(e[t.id]=t.displayName,e),{});e.s(["callbackInfo",0,m,"callback_map",0,g,"mapDisplayToInternalNames",0,e=>e.map(e=>g[e]||e),"mapInternalToDisplayNames",0,e=>e.map(e=>p[e]||e),"reverse_callback_map",0,p],557662)},9314,645526,e=>{"use strict";var t=e.i(843476),l=e.i(199133),a=e.i(981339);e.i(247167);var s=e.i(931067),i=e.i(271645);let r={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M824.2 699.9a301.55 301.55 0 00-86.4-60.4C783.1 602.8 812 546.8 812 484c0-110.8-92.4-201.7-203.2-200-109.1 1.7-197 90.6-197 200 0 62.8 29 118.8 74.2 155.5a300.95 300.95 0 00-86.4 60.4C345 754.6 314 826.8 312 903.8a8 8 0 008 8.2h56c4.3 0 7.9-3.4 8-7.7 1.9-58 25.4-112.3 66.7-153.5A226.62 226.62 0 01612 684c60.9 0 118.2 23.7 161.3 66.8C814.5 792 838 846.3 840 904.3c.1 4.3 3.7 7.7 8 7.7h56a8 8 0 008-8.2c-2-77-33-149.2-87.8-203.9zM612 612c-34.2 0-66.4-13.3-90.5-37.5a126.86 126.86 0 01-37.5-91.8c.3-32.8 13.4-64.5 36.3-88 24-24.6 56.1-38.3 90.4-38.7 33.9-.3 66.8 12.9 91 36.6 24.8 24.3 38.4 56.8 38.4 91.4 0 34.2-13.3 66.3-37.5 90.5A127.3 127.3 0 01612 612zM361.5 510.4c-.9-8.7-1.4-17.5-1.4-26.4 0-15.9 1.5-31.4 4.3-46.5.7-3.6-1.2-7.3-4.5-8.8-13.6-6.1-26.1-14.5-36.9-25.1a127.54 127.54 0 01-38.7-95.4c.9-32.1 13.8-62.6 36.3-85.6 24.7-25.3 57.9-39.1 93.2-38.7 31.9.3 62.7 12.6 86 34.4 7.9 7.4 14.7 15.6 20.4 24.4 2 3.1 5.9 4.4 9.3 3.2 17.6-6.1 36.2-10.4 55.3-12.4 5.6-.6 8.8-6.6 6.3-11.6-32.5-64.3-98.9-108.7-175.7-109.9-110.9-1.7-203.3 89.2-203.3 199.9 0 62.8 28.9 118.8 74.2 155.5-31.8 14.7-61.1 35-86.5 60.4-54.8 54.7-85.8 126.9-87.8 204a8 8 0 008 8.2h56.1c4.3 0 7.9-3.4 8-7.7 1.9-58 25.4-112.3 66.7-153.5 29.4-29.4 65.4-49.8 104.7-59.7 3.9-1 6.5-4.7 6-8.7z"}}]},name:"team",theme:"outlined"};var n=e.i(9583),o=i.forwardRef(function(e,t){return i.createElement(n.default,(0,s.default)({},e,{ref:t,icon:r}))});e.s(["TeamOutlined",0,o],645526);var d=e.i(599724),c=e.i(263147);e.s(["default",0,({value:e,onChange:s,placeholder:i="Select access groups",disabled:r=!1,style:n,className:u,showLabel:m=!1,labelText:g="Access Group",allowClear:p=!0})=>{let{data:h,isLoading:x,isError:y}=(0,c.useAccessGroups)();if(x)return(0,t.jsxs)("div",{children:[m&&(0,t.jsxs)(d.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,t.jsx)(o,{className:"mr-2"})," ",g]}),(0,t.jsx)(a.Skeleton.Input,{active:!0,block:!0,style:{height:32,...n}})]});let f=(h??[]).map(e=>({label:(0,t.jsxs)("span",{children:[(0,t.jsx)("span",{className:"font-medium",children:e.access_group_name})," ",(0,t.jsxs)("span",{className:"text-gray-400 text-xs",children:["(",e.access_group_id,")"]})]}),value:e.access_group_id,selectedLabel:e.access_group_name,searchText:`${e.access_group_name} ${e.access_group_id}`}));return(0,t.jsxs)("div",{children:[m&&(0,t.jsxs)(d.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,t.jsx)(o,{className:"mr-2"})," ",g]}),(0,t.jsx)(l.Select,{mode:"multiple",value:e,placeholder:i,onChange:s,disabled:r,allowClear:p,showSearch:!0,style:{width:"100%",...n},className:`rounded-md ${u??""}`,notFoundContent:y?(0,t.jsx)("span",{className:"text-red-500",children:"Failed to load access groups"}):"No access groups found",filterOption:(e,t)=>(f.find(e=>e.value===t?.value)?.searchText??"").toLowerCase().includes(e.toLowerCase()),optionLabelProp:"selectedLabel",options:f.map(e=>({label:e.label,value:e.value,selectedLabel:e.selectedLabel}))})]})}],9314)},392110,e=>{"use strict";var t=e.i(843476),l=e.i(271645),a=e.i(199133),s=e.i(592968),i=e.i(312361),r=e.i(790848),n=e.i(536916),o=e.i(808613),d=e.i(827252),c=e.i(779241);let{Option:u}=a.Select;e.s(["default",0,({form:e,autoRotationEnabled:m,onAutoRotationChange:g,rotationInterval:p,onRotationIntervalChange:h,isCreateMode:x=!1,neverExpire:y=!1,onNeverExpireChange:f})=>{let b=p&&!["7d","30d","90d","180d","365d"].includes(p),[j,_]=(0,l.useState)(b),[v,A]=(0,l.useState)(b?p:"");return(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Key Expiry Settings"}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,t.jsx)("span",{children:"Expire Key"}),(0,t.jsx)(s.Tooltip,{title:"Set when this key should expire. Format: 30s (seconds), 30m (minutes), 30h (hours), 30d (days). Leave empty to keep the current expiry unchanged.",children:(0,t.jsx)(d.InfoCircleOutlined,{className:"text-gray-400 cursor-help text-xs"})}),!x&&f&&(0,t.jsx)(n.Checkbox,{checked:y,onChange:t=>{let l=t.target.checked;f(l),l&&(e&&"function"==typeof e.setFieldValue?e.setFieldValue("duration",""):e&&"function"==typeof e.setFieldsValue&&e.setFieldsValue({duration:""}))},className:"ml-2 text-sm font-normal text-gray-600",children:"Never Expire"})]}),(0,t.jsx)(o.Form.Item,{name:"duration",noStyle:!0,initialValue:"",children:(0,t.jsx)(c.TextInput,{placeholder:x?"e.g., 30d or leave empty to never expire":"e.g., 30d",className:"w-full",disabled:!x&&y})})]})]}),(0,t.jsx)(i.Divider,{}),(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Auto-Rotation Settings"}),(0,t.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,t.jsx)("span",{children:"Enable Auto-Rotation"}),(0,t.jsx)(s.Tooltip,{title:"Key will automatically regenerate at the specified interval for enhanced security.",children:(0,t.jsx)(d.InfoCircleOutlined,{className:"text-gray-400 cursor-help text-xs"})})]}),(0,t.jsx)(r.Switch,{checked:m,onChange:g,size:"default",className:m?"":"bg-gray-400"})]}),m&&(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,t.jsx)("span",{children:"Rotation Interval"}),(0,t.jsx)(s.Tooltip,{title:"How often the key should be automatically rotated. Choose the interval that best fits your security requirements.",children:(0,t.jsx)(d.InfoCircleOutlined,{className:"text-gray-400 cursor-help text-xs"})})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)(a.Select,{value:j?"custom":p,onChange:e=>{"custom"===e?_(!0):(_(!1),A(""),h(e))},className:"w-full",placeholder:"Select interval",children:[(0,t.jsx)(u,{value:"7d",children:"7 days"}),(0,t.jsx)(u,{value:"30d",children:"30 days"}),(0,t.jsx)(u,{value:"90d",children:"90 days"}),(0,t.jsx)(u,{value:"180d",children:"180 days"}),(0,t.jsx)(u,{value:"365d",children:"365 days"}),(0,t.jsx)(u,{value:"custom",children:"Custom interval"})]}),j&&(0,t.jsxs)("div",{className:"space-y-1",children:[(0,t.jsx)(c.TextInput,{value:v,onChange:e=>{let t=e.target.value;A(t),h(t)},placeholder:"e.g., 1s, 5m, 2h, 14d"}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"Supported formats: seconds (s), minutes (m), hours (h), days (d)"})]})]})]})]}),m&&(0,t.jsx)("div",{className:"bg-blue-50 p-3 rounded-md text-sm text-blue-700",children:"When rotation occurs, you'll receive a notification with the new key. The old key will be deactivated after a brief grace period."})]})]})}])},533882,e=>{"use strict";var t=e.i(843476),l=e.i(271645),a=e.i(250980),s=e.i(797672),i=e.i(68155),r=e.i(304967),n=e.i(629569),o=e.i(599724),d=e.i(269200),c=e.i(427612),u=e.i(64848),m=e.i(942232),g=e.i(496020),p=e.i(977572),h=e.i(992619),x=e.i(727749);e.s(["default",0,({accessToken:e,initialModelAliases:y={},onAliasUpdate:f,showExampleConfig:b=!0})=>{let[j,_]=(0,l.useState)([]),[v,A]=(0,l.useState)({aliasName:"",targetModel:""}),[w,k]=(0,l.useState)(null);(0,l.useEffect)(()=>{_(Object.entries(y).map(([e,t],l)=>({id:`${l}-${e}`,aliasName:e,targetModel:t})))},[y]);let N=()=>{if(!w)return;if(!w.aliasName||!w.targetModel)return void x.default.fromBackend("Please provide both alias name and target model");if(j.some(e=>e.id!==w.id&&e.aliasName===w.aliasName))return void x.default.fromBackend("An alias with this name already exists");let e=j.map(e=>e.id===w.id?w:e);_(e),k(null);let t={};e.forEach(e=>{t[e.aliasName]=e.targetModel}),f&&f(t),x.default.success("Alias updated successfully")},S=()=>{k(null)},C=j.reduce((e,t)=>(e[t.aliasName]=t.targetModel,e),{});return(0,t.jsxs)("div",{className:"mt-4",children:[(0,t.jsxs)("div",{className:"mb-6",children:[(0,t.jsx)(o.Text,{className:"text-sm font-medium text-gray-700 mb-2",children:"Add New Alias"}),(0,t.jsxs)("div",{className:"grid grid-cols-3 gap-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs text-gray-500 mb-1",children:"Alias Name"}),(0,t.jsx)("input",{type:"text",value:v.aliasName,onChange:e=>A({...v,aliasName:e.target.value}),placeholder:"e.g., gpt-4o",className:"w-full px-3 py-2 border border-gray-300 rounded-md text-sm"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs text-gray-500 mb-1",children:"Target Model"}),(0,t.jsx)(h.default,{accessToken:e,value:v.targetModel,placeholder:"Select target model",onChange:e=>A({...v,targetModel:e}),showLabel:!1})]}),(0,t.jsx)("div",{className:"flex items-end",children:(0,t.jsxs)("button",{onClick:()=>{if(!v.aliasName||!v.targetModel)return void x.default.fromBackend("Please provide both alias name and target model");if(j.some(e=>e.aliasName===v.aliasName))return void x.default.fromBackend("An alias with this name already exists");let e=[...j,{id:`${Date.now()}-${v.aliasName}`,aliasName:v.aliasName,targetModel:v.targetModel}];_(e),A({aliasName:"",targetModel:""});let t={};e.forEach(e=>{t[e.aliasName]=e.targetModel}),f&&f(t),x.default.success("Alias added successfully")},disabled:!v.aliasName||!v.targetModel,className:`flex items-center px-4 py-2 rounded-md text-sm ${!v.aliasName||!v.targetModel?"bg-gray-300 text-gray-500 cursor-not-allowed":"bg-green-600 text-white hover:bg-green-700"}`,children:[(0,t.jsx)(a.PlusCircleIcon,{className:"w-4 h-4 mr-1"}),"Add Alias"]})})]})]}),(0,t.jsx)(o.Text,{className:"text-sm font-medium text-gray-700 mb-2",children:"Manage Existing Aliases"}),(0,t.jsx)("div",{className:"rounded-lg custom-border relative mb-6",children:(0,t.jsx)("div",{className:"overflow-x-auto",children:(0,t.jsxs)(d.Table,{className:"[&_td]:py-0.5 [&_th]:py-1",children:[(0,t.jsx)(c.TableHead,{children:(0,t.jsxs)(g.TableRow,{children:[(0,t.jsx)(u.TableHeaderCell,{className:"py-1 h-8",children:"Alias Name"}),(0,t.jsx)(u.TableHeaderCell,{className:"py-1 h-8",children:"Target Model"}),(0,t.jsx)(u.TableHeaderCell,{className:"py-1 h-8",children:"Actions"})]})}),(0,t.jsxs)(m.TableBody,{children:[j.map(l=>(0,t.jsx)(g.TableRow,{className:"h-8",children:w&&w.id===l.id?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(p.TableCell,{className:"py-0.5",children:(0,t.jsx)("input",{type:"text",value:w.aliasName,onChange:e=>k({...w,aliasName:e.target.value}),className:"w-full px-2 py-1 border border-gray-300 rounded-md text-sm"})}),(0,t.jsx)(p.TableCell,{className:"py-0.5",children:(0,t.jsx)(h.default,{accessToken:e,value:w.targetModel,onChange:e=>k({...w,targetModel:e}),showLabel:!1,style:{height:"32px"}})}),(0,t.jsx)(p.TableCell,{className:"py-0.5 whitespace-nowrap",children:(0,t.jsxs)("div",{className:"flex space-x-2",children:[(0,t.jsx)("button",{onClick:N,className:"text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded-sm hover:bg-blue-100",children:"Save"}),(0,t.jsx)("button",{onClick:S,className:"text-xs bg-gray-50 text-gray-600 px-2 py-1 rounded-sm hover:bg-gray-100",children:"Cancel"})]})})]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(p.TableCell,{className:"py-0.5 text-sm text-gray-900",children:l.aliasName}),(0,t.jsx)(p.TableCell,{className:"py-0.5 text-sm text-gray-500",children:l.targetModel}),(0,t.jsx)(p.TableCell,{className:"py-0.5 whitespace-nowrap",children:(0,t.jsxs)("div",{className:"flex space-x-2",children:[(0,t.jsx)("button",{onClick:()=>{k({...l})},className:"text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded-sm hover:bg-blue-100",children:(0,t.jsx)(s.PencilIcon,{className:"w-3 h-3"})}),(0,t.jsx)("button",{onClick:()=>{var e;let t,a;return e=l.id,_(t=j.filter(t=>t.id!==e)),a={},void(t.forEach(e=>{a[e.aliasName]=e.targetModel}),f&&f(a),x.default.success("Alias deleted successfully"))},className:"text-xs bg-red-50 text-red-600 px-2 py-1 rounded-sm hover:bg-red-100",children:(0,t.jsx)(i.TrashIcon,{className:"w-3 h-3"})})]})})]})},l.id)),0===j.length&&(0,t.jsx)(g.TableRow,{children:(0,t.jsx)(p.TableCell,{colSpan:3,className:"py-0.5 text-sm text-gray-500 text-center",children:"No aliases added yet. Add a new alias above."})})]})]})})}),b&&(0,t.jsxs)(r.Card,{children:[(0,t.jsx)(n.Title,{className:"mb-4",children:"Configuration Example"}),(0,t.jsx)(o.Text,{className:"text-gray-600 mb-4",children:"Here's how your current aliases would look in the config:"}),(0,t.jsx)("div",{className:"bg-gray-100 rounded-lg p-4 font-mono text-sm",children:(0,t.jsxs)("div",{className:"text-gray-700",children:["model_aliases:",0===Object.keys(C).length?(0,t.jsxs)("span",{className:"text-gray-500",children:[(0,t.jsx)("br",{}),"  # No aliases configured yet"]}):Object.entries(C).map(([e,l])=>(0,t.jsxs)("span",{children:[(0,t.jsx)("br",{}),'  "',e,'": "',l,'"']},e))]})})]})]})}])},844565,e=>{"use strict";var t=e.i(843476),l=e.i(271645),a=e.i(199133),s=e.i(602869);e.s(["default",0,({onChange:e,value:i,className:r,accessToken:n,placeholder:o="Select pass through routes",disabled:d=!1,teamId:c})=>{let[u,m]=(0,l.useState)([]),[g,p]=(0,l.useState)(!1);return(0,l.useEffect)(()=>{(async()=>{if(n){p(!0);try{let e=await (0,s.getPassThroughEndpointsCall)(n,c);if(e.endpoints){let t=e.endpoints.flatMap(e=>{let t=e.path,l=e.methods;return l&&l.length>0?l.map(e=>({label:`${e} ${t}`,value:t})):[{label:t,value:t}]});m(t)}}catch(e){console.error("Error fetching pass through routes:",e)}finally{p(!1)}}})()},[n,c]),(0,t.jsx)(a.Select,{mode:"tags",placeholder:o,onChange:e,value:i,loading:g,className:r,allowClear:!0,options:u,optionFilterProp:"label",showSearch:!0,style:{width:"100%"},disabled:d})}])},810757,477386,e=>{"use strict";var t=e.i(271645);let l=t.forwardRef(function(e,l){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:l},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"}),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"}))});e.s(["CogIcon",0,l],810757);let a=t.forwardRef(function(e,l){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:l},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"}))});e.s(["BanIcon",0,a],477386)},266484,e=>{"use strict";var t=e.i(843476),l=e.i(199133),a=e.i(592968),s=e.i(312361),i=e.i(827252),r=e.i(994388),n=e.i(304967),o=e.i(779241),d=e.i(988297),c=e.i(68155),u=e.i(810757),m=e.i(477386),g=e.i(557662),p=e.i(174553),h=e.i(435451);let{Option:x}=l.Select;e.s(["default",0,({value:e=[],onChange:y,disabledCallbacks:f=[],onDisabledCallbacksChange:b})=>{let j=Object.entries(g.callbackInfo).filter(([e,t])=>t.supports_key_team_logging).map(([e,t])=>e),_=Object.keys(g.callbackInfo),v=e=>{y?.(e)},A=(t,l,a)=>{let s=[...e];if("callback_name"===l){let e=g.callback_map[a]||a;s[t]={...s[t],[l]:e,callback_vars:{}}}else s[t]={...s[t],[l]:a};v(s)},w=(t,l,a)=>{let s=[...e];s[t]={...s[t],callback_vars:{...s[t].callback_vars,[l]:a}},v(s)};return(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)(m.BanIcon,{className:"w-5 h-5 text-red-500"}),(0,t.jsx)("span",{className:"text-base font-semibold text-gray-800",children:"Disabled Callbacks"}),(0,t.jsx)(a.Tooltip,{title:"Select callbacks to disable for this key. Disabled callbacks will not receive any logging data.",children:(0,t.jsx)(i.InfoCircleOutlined,{className:"text-gray-400 cursor-help"})})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Disabled Callbacks"}),(0,t.jsx)(l.Select,{mode:"multiple",placeholder:"Select callbacks to disable",value:f,onChange:e=>{let t=(0,g.mapDisplayToInternalNames)(e);b?.(t)},style:{width:"100%"},optionLabelProp:"label",children:_.map(e=>{let l=g.callbackInfo[e]?.description;return(0,t.jsx)(x,{value:e,label:e,children:(0,t.jsx)(a.Tooltip,{title:l,placement:"right",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)(p.Logo,{src:g.callbackInfo[e]?.logo,label:e,className:"w-4 h-4 object-contain"}),(0,t.jsx)("span",{children:e})]})})},e)})}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"Select callbacks that should be disabled for this key. These callbacks will not receive any logging data."})]})]}),(0,t.jsx)(s.Divider,{}),(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)(u.CogIcon,{className:"w-5 h-5 text-blue-500"}),(0,t.jsx)("span",{className:"text-base font-semibold text-gray-800",children:"Logging Integrations"}),(0,t.jsx)(a.Tooltip,{title:"Configure callback logging integrations for this team.",children:(0,t.jsx)(i.InfoCircleOutlined,{className:"text-gray-400 cursor-help"})})]}),(0,t.jsx)(r.Button,{variant:"secondary",onClick:()=>{v([...e,{callback_name:"",callback_type:"success",callback_vars:{}}])},icon:d.PlusIcon,size:"sm",className:"hover:border-blue-400 hover:text-blue-500",type:"button",children:"Add Integration"})]}),(0,t.jsx)("div",{className:"space-y-4",children:e.map((s,i)=>{let d=s.callback_name?Object.entries(g.callback_map).find(([e,t])=>t===s.callback_name)?.[0]:void 0;return(0,t.jsxs)(n.Card,{className:"border border-gray-200 shadow-xs hover:shadow-md transition-shadow duration-200",decoration:"top",decorationColor:"blue",children:[(0,t.jsxs)("div",{className:"flex justify-between items-start mb-4",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[d&&(0,t.jsx)(p.Logo,{src:g.callbackInfo[d]?.logo,label:d,className:"w-5 h-5 object-contain"}),(0,t.jsxs)("span",{className:"text-sm font-medium",children:[d||"New Integration"," Configuration"]})]}),(0,t.jsx)(r.Button,{variant:"light",onClick:()=>{v(e.filter((e,t)=>t!==i))},icon:c.TrashIcon,size:"xs",color:"red",className:"hover:bg-red-50",type:"button",children:"Remove"})]}),(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Integration Type"}),(0,t.jsx)(l.Select,{value:d,placeholder:"Select integration",onChange:e=>A(i,"callback_name",e),className:"w-full",optionLabelProp:"label",children:j.map(e=>{let l=g.callbackInfo[e]?.description;return(0,t.jsx)(x,{value:e,label:e,children:(0,t.jsx)(a.Tooltip,{title:l,placement:"right",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)(p.Logo,{src:g.callbackInfo[e]?.logo,label:e,className:"w-4 h-4 object-contain"}),(0,t.jsx)("span",{children:e})]})})},e)})})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Event Type"}),(0,t.jsxs)(l.Select,{value:s.callback_type,onChange:e=>A(i,"callback_type",e),className:"w-full",children:[(0,t.jsx)(x,{value:"success",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("div",{className:"w-2 h-2 bg-green-500 rounded-full"}),(0,t.jsx)("span",{children:"Success Only"})]})}),(0,t.jsx)(x,{value:"failure",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("div",{className:"w-2 h-2 bg-red-500 rounded-full"}),(0,t.jsx)("span",{children:"Failure Only"})]})}),(0,t.jsx)(x,{value:"success_and_failure",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("div",{className:"w-2 h-2 bg-blue-500 rounded-full"}),(0,t.jsx)("span",{children:"Success & Failure"})]})})]})]})]}),((e,l)=>{if(!e.callback_name)return null;let a=Object.entries(g.callback_map).find(([t,l])=>l===e.callback_name)?.[0];if(!a)return null;let s=g.callbackInfo[a]?.dynamic_params||{};return 0===Object.keys(s).length?null:(0,t.jsxs)("div",{className:"mt-6 pt-4 border-t border-gray-100",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2 mb-4",children:[(0,t.jsx)("div",{className:"w-3 h-3 bg-blue-100 rounded-full flex items-center justify-center",children:(0,t.jsx)("div",{className:"w-1.5 h-1.5 bg-blue-500 rounded-full"})}),(0,t.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Integration Parameters"})]}),(0,t.jsx)("div",{className:"grid grid-cols-1 gap-4",children:Object.entries(s).map(([a,s])=>(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 capitalize flex items-center space-x-1",children:[(0,t.jsx)("span",{children:a.replace(/_/g," ")}),"password"===s&&(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-0.5 rounded-sm text-xs font-medium bg-yellow-100 text-yellow-800",children:"Sensitive"}),"number"===s&&(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-0.5 rounded-sm text-xs font-medium bg-yellow-100 text-yellow-800",children:"Number"})]}),"number"===s&&(0,t.jsx)("span",{className:"text-xs text-gray-500",children:"Value must be between 0 and 1"}),"number"===s?(0,t.jsx)(h.default,{step:.01,width:400,placeholder:`os.environ/${a.toUpperCase()}`,value:e.callback_vars[a]||"",onChange:e=>w(l,a,e.target.value)}):(0,t.jsx)(o.TextInput,{type:"password"===s?"password":"text",placeholder:`os.environ/${a.toUpperCase()}`,value:e.callback_vars[a]||"",onChange:e=>w(l,a,e.target.value)})]},a))})]})})(s,i)]})]},i)})}),0===e.length&&(0,t.jsxs)("div",{className:"text-center py-12 text-gray-500 border-2 border-dashed border-gray-200 rounded-lg bg-gray-50/50",children:[(0,t.jsx)(u.CogIcon,{className:"w-12 h-12 text-gray-300 mb-3 mx-auto"}),(0,t.jsx)("div",{className:"text-base font-medium mb-1",children:"No logging integrations configured"}),(0,t.jsx)("div",{className:"text-sm text-gray-400",children:'Click "Add Integration" to configure logging for this team'})]})]})}])},651904,e=>{"use strict";var t=e.i(843476),l=e.i(599724),a=e.i(266484);e.s(["default",0,function({value:e,onChange:s,premiumUser:i=!1,disabledCallbacks:r=[],onDisabledCallbacksChange:n}){return i?(0,t.jsx)(a.default,{value:e,onChange:s,disabledCallbacks:r,onDisabledCallbacksChange:n}):(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex flex-wrap gap-2 mb-3",children:[(0,t.jsx)("div",{className:"inline-flex items-center px-3 py-1.5 rounded-lg bg-green-50 border border-green-200 text-green-800 text-sm font-medium opacity-50",children:"✨ langfuse-logging"}),(0,t.jsx)("div",{className:"inline-flex items-center px-3 py-1.5 rounded-lg bg-green-50 border border-green-200 text-green-800 text-sm font-medium opacity-50",children:"✨ datadog-logging"})]}),(0,t.jsx)("div",{className:"p-3 bg-yellow-50 border border-yellow-200 rounded-lg",children:(0,t.jsxs)(l.Text,{className:"text-sm text-yellow-800",children:["Setting Key/Team logging settings is a LiteLLM Enterprise feature. Global Logging Settings are available for all free users. Get a trial key"," ",(0,t.jsx)("a",{href:"https://www.litellm.ai/#pricing",target:"_blank",rel:"noopener noreferrer",className:"underline",children:"here"}),"."]})})]})}])},939510,e=>{"use strict";var t=e.i(843476),l=e.i(808613),a=e.i(199133),s=e.i(592968),i=e.i(827252);let{Option:r}=a.Select;e.s(["default",0,({type:e,name:n,showDetailedDescriptions:o=!0,className:d="",initialValue:c=null,form:u,onChange:m})=>{let g=e.toUpperCase(),p=e.toLowerCase(),h=`Select 'guaranteed_throughput' to prevent overallocating ${g} limit when the key belongs to a Team with specific ${g} limits.`;return(0,t.jsx)(l.Form.Item,{label:(0,t.jsxs)("span",{children:[g," Rate Limit Type"," ",(0,t.jsx)(s.Tooltip,{title:h,children:(0,t.jsx)(i.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:n,initialValue:c,className:d,children:(0,t.jsx)(a.Select,{defaultValue:o?"default":void 0,placeholder:"Select rate limit type",style:{width:"100%"},optionLabelProp:o?"label":void 0,onChange:e=>{u&&u.setFieldValue(n,e),m&&m(e)},children:o?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r,{value:"best_effort_throughput",label:"Default",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)("div",{style:{fontWeight:500},children:"Default"}),(0,t.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["Best effort throughput - no error if we're overallocating ",p," (Team/Key Limits checked at runtime)."]})]})}),(0,t.jsx)(r,{value:"guaranteed_throughput",label:"Guaranteed throughput",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)("div",{style:{fontWeight:500},children:"Guaranteed throughput"}),(0,t.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["Guaranteed throughput - raise an error if we're overallocating ",p," (also checks model-specific limits)"]})]})}),(0,t.jsx)(r,{value:"dynamic",label:"Dynamic",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)("div",{style:{fontWeight:500},children:"Dynamic"}),(0,t.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["If the key has a set ",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,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r,{value:"best_effort_throughput",children:"Best effort throughput"}),(0,t.jsx)(r,{value:"guaranteed_throughput",children:"Guaranteed throughput"}),(0,t.jsx)(r,{value:"dynamic",children:"Dynamic"})]})})})}])},460285,e=>{"use strict";var t=e.i(843476),l=e.i(271645),a=e.i(404206),s=e.i(723731),i=e.i(653824),r=e.i(881073),n=e.i(197647),o=e.i(343488),d=e.i(602869),c=e.i(158392),u=e.i(419470),m=e.i(695411);let g=(0,l.forwardRef)(({accessToken:e,value:g,onChange:p,modelData:h},x)=>{let[y,f]=(0,l.useState)({routerSettings:{},selectedStrategy:null,enableTagFiltering:!1}),[b,j]=(0,l.useState)([]),[_,v]=(0,l.useState)([]),[A,w]=(0,l.useState)([]),[k,N]=(0,l.useState)([]),[S,C]=(0,l.useState)({}),[T,I]=(0,l.useState)({}),L=(0,l.useRef)(!1),E=(0,l.useRef)(null);(0,l.useEffect)(()=>{let e=g?.router_settings?JSON.stringify({routing_strategy:g.router_settings.routing_strategy,fallbacks:g.router_settings.fallbacks,enable_tag_filtering:g.router_settings.enable_tag_filtering}):null;if(L.current&&e===E.current){L.current=!1;return}if(L.current&&e!==E.current&&(L.current=!1),e!==E.current)if(E.current=e,g?.router_settings){let e=g.router_settings,{fallbacks:t,...l}=e;f({routerSettings:l,selectedStrategy:e.routing_strategy||null,enableTagFiltering:e.enable_tag_filtering??!1});let a=e.fallbacks||[];j(a),v(a&&0!==a.length?a.map((e,t)=>{let[l,a]=Object.entries(e)[0];return{id:(t+1).toString(),primaryModel:l||null,fallbackModels:a||[]}}):[{id:"1",primaryModel:null,fallbackModels:[]}])}else f({routerSettings:{},selectedStrategy:null,enableTagFiltering:!1}),j([]),v([{id:"1",primaryModel:null,fallbackModels:[]}])},[g]),(0,l.useEffect)(()=>{e&&(0,d.getRouterSettingsCall)(e).then(e=>{if(e.fields){let t={};e.fields.forEach(e=>{t[e.field_name]={ui_field_name:e.ui_field_name,field_description:e.field_description,options:e.options,link:e.link}}),C(t);let l=e.fields.find(e=>"routing_strategy"===e.field_name);l?.options&&N(l.options),e.routing_strategy_descriptions&&I(e.routing_strategy_descriptions)}})},[e]),(0,l.useEffect)(()=>{e&&(async()=>{try{let t=await (0,m.fetchAvailableModels)(e);w(t)}catch(e){console.error("Error fetching model info for fallbacks:",e)}})()},[e]);let O=()=>{let e=new Set(["allowed_fails","cooldown_time","num_retries","timeout","retry_after"]),t=new Set(["model_group_alias","retry_policy"]),l=Object.fromEntries(Object.entries({...y.routerSettings,enable_tag_filtering:y.enableTagFiltering,routing_strategy:y.selectedStrategy,fallbacks:b.length>0?b:null}).map(([l,a])=>{if("routing_strategy_args"!==l&&"routing_strategy"!==l&&"enable_tag_filtering"!==l&&"fallbacks"!==l){let s=document.querySelector(`input[name="${l}"]`);if(s){if(void 0!==s.value&&""!==s.value){let i=((l,a,s)=>{if(null==a)return s;let i=String(a).trim();if(""===i||"null"===i.toLowerCase())return null;if(e.has(l)){let e=Number(i);return Number.isNaN(e)?s:e}if(t.has(l)){if(""===i)return null;try{return JSON.parse(i)}catch{return s}}return"true"===i.toLowerCase()||"false"!==i.toLowerCase()&&i})(l,s.value,a);return[l,i]}return[l,null]}}else if("routing_strategy"===l)return[l,y.selectedStrategy];else if("enable_tag_filtering"===l)return[l,y.enableTagFiltering];else if("fallbacks"===l)return[l,b.length>0?b:null];else if("routing_strategy_args"===l&&"latency-based-routing"===y.selectedStrategy){let e=document.querySelector('input[name="lowest_latency_buffer"]'),t=document.querySelector('input[name="ttl"]'),l={};return e?.value&&(l.lowest_latency_buffer=Number(e.value)),t?.value&&(l.ttl=Number(t.value)),["routing_strategy_args",Object.keys(l).length>0?l:null]}return[l,a]}).filter(e=>null!=e)),a=(e,t=!1)=>null==e||"object"==typeof e&&!Array.isArray(e)&&0===Object.keys(e).length||t&&("number"!=typeof e||Number.isNaN(e))?null:e;return{routing_strategy:a(l.routing_strategy),allowed_fails:a(l.allowed_fails,!0),cooldown_time:a(l.cooldown_time,!0),num_retries:a(l.num_retries,!0),timeout:a(l.timeout,!0),retry_after:a(l.retry_after,!0),fallbacks:b.length>0?b:null,context_window_fallbacks:a(l.context_window_fallbacks),retry_policy:a(l.retry_policy),model_group_alias:a(l.model_group_alias),enable_tag_filtering:y.enableTagFiltering,routing_strategy_args:a(l.routing_strategy_args)}},F=(0,o.useDebouncedCallback)(()=>{p&&(L.current=!0,p({router_settings:O()}))},{wait:100});(0,l.useEffect)(()=>{p&&F()},[y,b]);let M=Array.from(new Set(A.map(e=>e.model_group))).sort();return((0,l.useImperativeHandle)(x,()=>({getValue:()=>({router_settings:O()})})),e)?(0,t.jsx)("div",{className:"w-full",children:(0,t.jsxs)(i.TabGroup,{className:"w-full",children:[(0,t.jsxs)(r.TabList,{variant:"line",defaultValue:"1",className:"px-8 pt-4",children:[(0,t.jsx)(n.Tab,{value:"1",children:"Loadbalancing"}),(0,t.jsx)(n.Tab,{value:"2",children:"Fallbacks"})]}),(0,t.jsxs)(s.TabPanels,{className:"px-8 py-6",children:[(0,t.jsx)(a.TabPanel,{children:(0,t.jsx)(c.default,{value:y,onChange:f,routerFieldsMetadata:S,availableRoutingStrategies:k,routingStrategyDescriptions:T})}),(0,t.jsx)(a.TabPanel,{children:(0,t.jsx)(u.FallbackSelectionForm,{groups:_,onGroupsChange:e=>{v(e),j(e.filter(e=>e.primaryModel&&e.fallbackModels.length>0).map(e=>({[e.primaryModel]:e.fallbackModels})))},availableModels:M,maxGroups:5})})]})]})}):null});g.displayName="RouterSettingsAccordion",e.s(["default",0,g])},363256,e=>{"use strict";var t=e.i(843476),l=e.i(199133);let{Text:a}=e.i(898586).Typography;e.s(["default",0,({organizations:e,value:s,onChange:i,disabled:r,loading:n,style:o})=>(0,t.jsx)(l.Select,{showSearch:!0,placeholder:"All Organizations",value:s,onChange:i,disabled:r,loading:n,allowClear:!0,style:{minWidth:280,...o},filterOption:(t,l)=>{if(!l)return!1;let a=e?.find(e=>e.organization_id===l.key);if(!a)return!1;let s=t.toLowerCase().trim(),i=(a.organization_alias||"").toLowerCase(),r=(a.organization_id||"").toLowerCase();return i.includes(s)||r.includes(s)},children:e?.map(e=>(0,t.jsxs)(l.Select.Option,{value:e.organization_id,children:[(0,t.jsx)("span",{className:"font-medium",children:e.organization_alias})," ",(0,t.jsxs)(a,{type:"secondary",children:["(",e.organization_id,")"]})]},e.organization_id))})])},575260,e=>{"use strict";var t=e.i(843476),l=e.i(199133),a=e.i(482725),s=e.i(56456);e.s(["default",0,({projects:e,value:i,onChange:r,disabled:n,loading:o,teamId:d})=>{let c=d?e?.filter(e=>e.team_id===d):e;return(0,t.jsx)(l.Select,{showSearch:!0,placeholder:"Search or select a project",value:i,onChange:r,disabled:n,loading:o,allowClear:!0,notFoundContent:o?(0,t.jsx)(a.Spin,{indicator:(0,t.jsx)(s.LoadingOutlined,{spin:!0}),size:"small"}):void 0,filterOption:(e,t)=>{if(!t)return!1;let l=c?.find(e=>e.project_id===t.key);if(!l)return!1;let a=e.toLowerCase().trim(),s=(l.project_alias||"").toLowerCase(),i=(l.project_id||"").toLowerCase();return s.includes(a)||i.includes(a)},optionFilterProp:"children",children:!o&&c?.map(e=>(0,t.jsxs)(l.Select.Option,{value:e.project_id,children:[(0,t.jsx)("span",{className:"font-medium",children:e.project_alias||e.project_id})," ",(0,t.jsxs)("span",{className:"text-gray-500",children:["(",e.project_id,")"]})]},e.project_id))})}])},128233,319312,833400,e=>{"use strict";var t=e.i(843476),l=e.i(464571),a=e.i(199133),s=e.i(592968),i=e.i(425063),r=e.i(107233),n=e.i(37727),o=e.i(271645);e.s(["BudgetFallbacksEditor",0,function({value:e,onChange:d,availableModels:c}){let[u,m]=(0,o.useState)(()=>{let t;return 0===(t=Object.keys(e)).length?[]:t.map((t,l)=>({id:String(l+1),primaryModel:t,fallbackModels:e[t]}))}),g=e=>{m(e),d(Object.fromEntries(e.filter(e=>null!==e.primaryModel&&e.fallbackModels.length>0).map(e=>[e.primaryModel,e.fallbackModels])))},p=()=>{g([...u,{id:Date.now().toString(),primaryModel:null,fallbackModels:[]}])},h=(e,t)=>{g(u.map(l=>l.id===e?{...l,...t}:l))},x=new Set(u.map(e=>e.primaryModel).filter(Boolean));return 0===u.length?(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"text-xs text-gray-500 mb-2",children:"When a model exceeds its per-model budget, requests automatically reroute to fallback models"}),(0,t.jsx)(l.Button,{size:"small",onClick:p,icon:(0,t.jsx)(r.Plus,{className:"w-3 h-3"}),children:"Add Budget Fallback"})]}):(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"When a model exceeds its per-model budget, requests automatically reroute to fallback models"}),u.map(e=>{let l=c.filter(t=>t===e.primaryModel||!x.has(t)),r=c.filter(t=>t!==e.primaryModel);return(0,t.jsxs)("div",{className:"relative rounded-lg border border-gray-200 bg-gray-50 p-4",children:[(0,t.jsx)("button",{type:"button",onClick:()=>{var t;return t=e.id,void g(u.filter(e=>e.id!==t))},className:"absolute top-2 right-2 text-gray-400 hover:text-red-500 transition-colors p-1",children:(0,t.jsx)(n.X,{className:"w-4 h-4"})}),(0,t.jsxs)("div",{className:"mb-3",children:[(0,t.jsx)("label",{className:"block text-xs font-medium text-gray-600 mb-1",children:"Primary Model"}),(0,t.jsx)(a.Select,{className:"w-full",placeholder:"Select model",value:e.primaryModel,onChange:t=>{let l=e.fallbackModels.filter(e=>e!==t);h(e.id,{primaryModel:t,fallbackModels:l})},showSearch:!0,filterOption:(e,t)=>(t?.label??"").toLowerCase().includes(e.toLowerCase()),options:l.map(e=>({label:e,value:e})),getPopupContainer:e=>e.parentElement||document.body})]}),(0,t.jsx)("div",{className:"flex items-center justify-center -my-1 mb-2",children:(0,t.jsxs)("div",{className:"bg-amber-50 text-amber-600 px-3 py-0.5 rounded-full text-[10px] font-bold border border-amber-100 flex items-center gap-1",children:[(0,t.jsx)(i.ArrowDown,{className:"w-3 h-3"}),"IF BUDGET EXCEEDED, TRY"]})}),(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs font-medium text-gray-600 mb-1",children:"Fallback Models"}),(0,t.jsx)(a.Select,{mode:"multiple",className:"w-full",placeholder:e.primaryModel?"Select fallback models":"Select a primary model first",value:e.fallbackModels,onChange:t=>h(e.id,{fallbackModels:t}),disabled:!e.primaryModel,showSearch:!0,filterOption:(e,t)=>(t?.label??"").toLowerCase().includes(e.toLowerCase()),options:r.map(e=>({label:e,value:e})),getPopupContainer:e=>e.parentElement||document.body,maxTagCount:"responsive",maxTagPlaceholder:e=>(0,t.jsx)(s.Tooltip,{styles:{root:{pointerEvents:"none"}},title:e.map(({value:e})=>e).join(", "),children:(0,t.jsxs)("span",{children:["+",e.length," more"]})})}),e.fallbackModels.length>1&&(0,t.jsx)("div",{className:"text-[10px] text-gray-400 mt-1 ml-1",children:"Tried in order; first model still within its own budget is used"})]})]},e.id)}),(0,t.jsx)(l.Button,{size:"small",onClick:p,icon:(0,t.jsx)(r.Plus,{className:"w-3 h-3"}),children:"Add Budget Fallback"})]})}],128233);var d=e.i(28651);let c=[{value:"1h",label:"Hourly",resetHint:"Resets every hour"},{value:"24h",label:"Daily",resetHint:"Resets daily at midnight UTC"},{value:"7d",label:"Weekly",resetHint:"Resets every Sunday at midnight UTC"},{value:"30d",label:"Monthly",resetHint:"Resets on the 1st of every month at midnight UTC"}];e.s(["BudgetWindowsEditor",0,function({value:e,onChange:s}){let i=(t,l,a)=>{s(e.map((e,s)=>s===t?{...e,[l]:a}:e))};return(0,t.jsxs)("div",{children:[e.map((r,n)=>{let o=c.find(e=>e.value===r.budget_duration)?.resetHint;return(0,t.jsxs)("div",{style:{marginBottom:12},children:[(0,t.jsxs)("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[(0,t.jsx)(a.Select,{value:r.budget_duration,onChange:e=>i(n,"budget_duration",e),style:{width:130},options:c.map(e=>({value:e.value,label:e.label}))}),(0,t.jsx)(d.InputNumber,{step:.01,min:0,precision:2,value:r.max_budget??void 0,onChange:e=>i(n,"max_budget",e??null),placeholder:"Max spend ($)",style:{width:160},prefix:"$"}),(0,t.jsx)(l.Button,{type:"text",danger:!0,size:"small",onClick:()=>{s(e.filter((e,t)=>t!==n))},style:{padding:"0 4px"},children:"✕"})]}),o&&(0,t.jsxs)("div",{style:{fontSize:11,color:"#888",marginTop:3,marginLeft:2},children:["↻ ",o]})]},n)}),(0,t.jsx)(l.Button,{size:"small",onClick:t=>{t.preventDefault(),s([...e,{budget_duration:"24h",max_budget:null}])},children:"+ Add Budget Window"})]})}],319312);var u=e.i(311451);let m=0,g=()=>`tag-row-${m++}`;e.s(["TagRateLimitEditor",0,function({value:e,onChange:a}){let s=(t,l,s)=>{a(e.map((e,a)=>a===t?{...e,[l]:s}:e))};return(0,t.jsxs)("div",{children:[e.map((i,r)=>(0,t.jsxs)("div",{style:{display:"flex",gap:8,alignItems:"center",marginBottom:12},children:[(0,t.jsx)(u.Input,{value:i.tag,onChange:e=>s(r,"tag",e.target.value),placeholder:"Tag (e.g. cell-1)",style:{width:180}}),(0,t.jsx)(d.InputNumber,{min:0,value:i.rpm_limit??void 0,onChange:e=>s(r,"rpm_limit",e??null),placeholder:"RPM",style:{width:120}}),(0,t.jsx)(l.Button,{type:"text",danger:!0,size:"small",onClick:()=>{a(e.filter((e,t)=>t!==r))},style:{padding:"0 4px"},children:"✕"})]},i.id)),(0,t.jsx)(l.Button,{size:"small",onClick:t=>{t.preventDefault(),a([...e,{id:g(),tag:"",rpm_limit:null}])},children:"+ Add Tag Limit"})]})},"tagLimitsToRows",0,e=>{let t=(e=>{if(!e||"object"!=typeof e)return{};let t={};return Object.entries(e).forEach(([e,l])=>{"number"==typeof l&&(t[e]=l)}),t})(e);return Object.keys(t).map(e=>({id:g(),tag:e,rpm_limit:t[e]}))},"tagRowsToLimits",0,e=>{let t={};return e.forEach(({tag:e,rpm_limit:l})=>{let a=e.trim();a&&"number"==typeof l&&(t[a]=l)}),{tag_rpm_limit:t}}],833400)},390605,e=>{"use strict";var t=e.i(843476),l=e.i(271645),a=e.i(602869),s=e.i(599724),i=e.i(482725),r=e.i(91739),n=e.i(500727),o=e.i(531516),d=e.i(696609);e.s(["default",0,({accessToken:e,selectedServers:c,toolPermissions:u,onChange:m,disabled:g=!1})=>{let{data:p=[]}=(0,n.useMCPServers)(),[h,x]=(0,l.useState)({}),[y,f]=(0,l.useState)({}),[b,j]=(0,l.useState)({}),[_,v]=(0,l.useState)({}),A=(0,l.useRef)(u);(0,l.useEffect)(()=>{A.current=u},[u]);let w=(0,l.useMemo)(()=>0===c.length?[]:p.filter(e=>c.includes(e.server_id)),[p,c]),k=async(e,t)=>{f(t=>({...t,[e]:!0})),j(t=>({...t,[e]:""}));try{let l=await (0,a.listMCPTools)(t,e);if(l.error)j(t=>({...t,[e]:l.message||"Failed to fetch tools"})),x(t=>({...t,[e]:[]}));else{let t=l.tools||[];x(l=>({...l,[e]:t}));let a=A.current;if(!a[e]&&t.length>0){let l=t.filter(e=>"delete"!==(0,d.classifyToolOp)(e.name,e.description||"")).map(e=>e.name);m({...a,[e]:l})}}}catch(t){console.error(`Error fetching tools for server ${e}:`,t),j(t=>({...t,[e]:"Failed to fetch tools"})),x(t=>({...t,[e]:[]}))}finally{f(t=>({...t,[e]:!1}))}};(0,l.useEffect)(()=>{w.forEach(t=>{h[t.server_id]||y[t.server_id]||k(t.server_id,e)})},[w,e]);let N=(e,t)=>{m({...u,[e]:t})};return 0===c.length?null:(0,t.jsx)("div",{className:"space-y-4",children:w.map(e=>{let l=e.server_name||e.alias||e.server_id,a=h[e.server_id]||[],n=u[e.server_id]||[],d=y[e.server_id],c=b[e.server_id],p=_[e.server_id]??"crud";return(0,t.jsxs)("div",{className:"border rounded-lg bg-gray-50",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between p-4 border-b bg-white rounded-t-lg",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(s.Text,{className:"font-semibold text-gray-900",children:l}),e.description&&(0,t.jsx)(s.Text,{className:"text-sm text-gray-500",children:e.description})]}),(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[!g&&a.length>0&&(0,t.jsx)(r.Radio.Group,{value:p,onChange:t=>v(l=>({...l,[e.server_id]:t.target.value})),size:"small",optionType:"button",buttonStyle:"solid",options:[{label:"Risk Groups",value:"crud"},{label:"Flat List",value:"flat"}]}),!g&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("button",{type:"button",className:"text-sm text-blue-600 hover:text-blue-700 font-medium",onClick:()=>{var t;let l;return l=h[t=e.server_id]||[],void m({...u,[t]:l.map(e=>e.name)})},disabled:d,children:"Select All"}),(0,t.jsx)("button",{type:"button",className:"text-sm text-blue-600 hover:text-blue-700 font-medium",onClick:()=>{var t;return t=e.server_id,void m({...u,[t]:[]})},disabled:d,children:"Deselect All"})]})]})]}),(0,t.jsxs)("div",{className:"p-4",children:[d&&(0,t.jsxs)("div",{className:"flex items-center justify-center py-8",children:[(0,t.jsx)(i.Spin,{size:"large"}),(0,t.jsx)(s.Text,{className:"ml-3 text-gray-500",children:"Loading tools..."})]}),c&&!d&&(0,t.jsxs)("div",{className:"p-4 bg-red-50 border border-red-200 rounded-lg text-center",children:[(0,t.jsx)(s.Text,{className:"text-red-600 font-medium",children:"Unable to load tools"}),(0,t.jsx)(s.Text,{className:"text-sm text-red-500 mt-1",children:c})]}),!d&&!c&&a.length>0&&"crud"===p&&(0,t.jsx)(o.default,{tools:a,value:u[e.server_id]?n:void 0,onChange:t=>N(e.server_id,t),readOnly:g}),!d&&!c&&a.length>0&&"flat"===p&&(0,t.jsx)("div",{className:"space-y-2",children:a.map(l=>{let a=n.includes(l.name);return(0,t.jsxs)("div",{className:"flex items-start gap-2",children:[(0,t.jsx)("input",{type:"checkbox",checked:a,onChange:()=>{if(g)return;let t=a?n.filter(e=>e!==l.name):[...n,l.name];N(e.server_id,t)},disabled:g,className:"mt-0.5"}),(0,t.jsx)("div",{className:"flex-1 min-w-0",children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(s.Text,{className:"font-medium text-gray-900",children:l.name}),(0,t.jsxs)(s.Text,{className:"text-sm text-gray-500",children:["- ",l.description||"No description"]})]})})]},l.name)})}),!d&&!c&&0===a.length&&(0,t.jsx)("div",{className:"text-center py-6",children:(0,t.jsx)(s.Text,{className:"text-gray-500",children:"No tools available"})})]})]},e.server_id)})})}])},364769,e=>{"use strict";var t=e.i(843476),l=e.i(271645),a=e.i(237016),s=e.i(464571),i=e.i(888259);e.s(["default",0,({apiKey:e})=>{let[r,n]=(0,l.useState)(!1);return(0,t.jsxs)("div",{children:[(0,t.jsxs)("p",{className:"mb-2",children:["Please save this secret key somewhere safe and accessible. For security reasons,"," ",(0,t.jsx)("b",{children:"you will not be able to view it again"})," through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]}),(0,t.jsx)("p",{className:"text-sm text-gray-600 mt-3 mb-1",children:"Virtual Key:"}),(0,t.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,t.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal",margin:0},children:e})}),(0,t.jsx)(a.CopyToClipboard,{text:e,onCopy:()=>{n(!0),i.default.success("Key copied to clipboard"),setTimeout(()=>n(!1),2e3)},children:(0,t.jsx)(s.Button,{type:"primary",style:{marginTop:12},children:r?"Copied!":"Copy Virtual Key"})})]})}])},702597,e=>{"use strict";var t=e.i(843476),l=e.i(207082),a=e.i(109799),s=e.i(510674),i=e.i(109034),r=e.i(292639),n=e.i(135214),o=e.i(500330),d=e.i(827252),c=e.i(912598),u=e.i(677667),m=e.i(130643),g=e.i(898667),p=e.i(994388),h=e.i(309426),x=e.i(350967),y=e.i(599724),f=e.i(779241),b=e.i(629569),j=e.i(464571),_=e.i(808613),v=e.i(311451),A=e.i(212931),w=e.i(91739),k=e.i(199133),N=e.i(790848),S=e.i(262218),C=e.i(592968),T=e.i(898586),I=e.i(343488),L=e.i(741466),E=e.i(271645),O=e.i(708347),F=e.i(552130),M=e.i(557662),R=e.i(9314),B=e.i(860585),P=e.i(82946),D=e.i(392110),U=e.i(533882),z=e.i(844565),V=e.i(651904),K=e.i(939510),G=e.i(460285),Q=e.i(663435),W=e.i(363256),H=e.i(575260),q=e.i(371455),J=e.i(128233),$=e.i(319312),Y=e.i(833400),X=e.i(355619),Z=e.i(75921),ee=e.i(234713),et=e.i(390605),el=e.i(727749),ea=e.i(602869),es=e.i(364769),ei=e.i(435451),er=e.i(916940);let{Option:en}=k.Select,eo=async(e,t,l,a)=>{try{if(null===e||null===t)return[];if(null!==l)return(await (0,ea.modelAvailableCall)(l,e,t,!0,a,!0)).data.map(e=>e.id);return[]}catch(e){return console.error("Error fetching user models:",e),[]}},ed=async(e,t,l,a)=>{try{if(null===e||null===t)return;if(null!==l){let s=(await (0,ea.modelAvailableCall)(l,e,t)).data.map(e=>e.id);a(s)}}catch(e){console.error("Error fetching user models:",e)}};e.s(["default",0,({team:e,teams:ec,data:eu,addKey:em,autoOpenCreate:eg,prefillData:ep})=>{let{accessToken:eh,userId:ex,userRole:ey,premiumUser:ef}=(0,n.default)(),eb=ef||null!=ey&&O.rolesWithWriteAccess.includes(ey),{data:ej,isLoading:e_}=(0,a.useOrganizations)(),{data:ev,isLoading:eA}=(0,s.useProjects)(),{data:ew}=(0,r.useUISettings)(),{data:ek}=(0,i.useTags)(),eN=!!ew?.values?.enable_projects_ui,eS=!!ew?.values?.disable_custom_api_keys,eC=ek?Object.values(ek).map(e=>({value:e.name,label:e.name})):[],eT=(0,c.useQueryClient)(),[eI]=_.Form.useForm(),[eL,eE]=(0,E.useState)(!1),[eO,eF]=(0,E.useState)(null),[eM,eR]=(0,E.useState)(null),[eB,eP]=(0,E.useState)([]),[eD,eU]=(0,E.useState)([]),[ez,eV]=(0,E.useState)("you"),[eK,eG]=(0,E.useState)(!1),[eQ,eW]=(0,E.useState)(null),[eH,eq]=(0,E.useState)([]),[eJ,e$]=(0,E.useState)([]),[eY,eX]=(0,E.useState)([]),[eZ,e0]=(0,E.useState)([]),[e1,e4]=(0,E.useState)(e),[e2,e3]=(0,E.useState)(null),[e6,e5]=(0,E.useState)(null),[e7,e8]=(0,E.useState)(!1),[e9,te]=(0,E.useState)(null),[tt,tl]=(0,E.useState)({}),[ta,ts]=(0,E.useState)([]),[ti,tr]=(0,E.useState)(!1),[tn,to]=(0,E.useState)([]),[td,tc]=(0,E.useState)([]),[tu,tm]=(0,E.useState)("llm_api"),[tg,tp]=(0,E.useState)({}),[th,tx]=(0,E.useState)(!1),[ty,tf]=(0,E.useState)("30d"),[tb,tj]=(0,E.useState)(null),[t_,tv]=(0,E.useState)([]),[tA,tw]=(0,E.useState)([]),[tk,tN]=(0,E.useState)({}),[tS,tC]=(0,E.useState)(0),[tT,tI]=(0,E.useState)(0),[tL,tE]=(0,E.useState)([]),[tO,tF]=(0,E.useState)(null),tM=_.Form.useWatch("models",eI)??[],tR=()=>{eE(!1),eI.resetFields(),e0([]),tc([]),tm("llm_api"),tp({}),tx(!1),tf("30d"),tj(null),tI(e=>e+1),tF(null),e3(null),e5(null),tv([]),tw([]),tN({}),tC(e=>e+1)},tB=()=>{eE(!1),eF(null),e4(null),eI.resetFields(),e0([]),tc([]),tm("llm_api"),tp({}),tx(!1),tf("30d"),tj(null),tI(e=>e+1),tF(null),e3(null),e5(null),tv([]),tw([]),tN({}),tC(e=>e+1)};(0,E.useEffect)(()=>{ex&&ey&&eh&&ed(ex,ey,eh,eP)},[eh,ex,ey]),(0,E.useEffect)(()=>{eh&&(0,ea.getAgentsList)(eh).then(e=>tE(e?.agents||[])).catch(()=>tE([]))},[eh]),(0,E.useEffect)(()=>{let e=async()=>{try{let e=(await (0,ea.getPoliciesList)(eh)).policies.map(e=>e.policy_name);e$(e)}catch(e){console.error("Failed to fetch policies:",e)}},t=async()=>{try{let e=await (0,ea.getPromptsList)(eh);eX(e.prompts.map(e=>e.prompt_id))}catch(e){console.error("Failed to fetch prompts:",e)}};(async()=>{try{let e=(await (0,ea.getGuardrailsList)(eh)).guardrails.map(e=>e.guardrail_name);eq(e)}catch(e){console.error("Failed to fetch guardrails:",e)}})(),e(),t()},[eh]),(0,E.useEffect)(()=>{(async()=>{try{if(eh){let e=sessionStorage.getItem("possibleUserRoles");if(e)tl(JSON.parse(e));else{let e=await (0,ea.getPossibleUserRoles)(eh);sessionStorage.setItem("possibleUserRoles",JSON.stringify(e)),tl(e)}}}catch(e){console.error("Error fetching possible user roles:",e)}})()},[eh]),(0,E.useEffect)(()=>{if(eg&&!eK&&ec&&ey&&O.rolesWithWriteAccess.includes(ey)&&(eE(!0),eG(!0),ep)){if(ep.owned_by&&("another_user"===ep.owned_by&&"Admin"!==ey?eV("you"):eV(ep.owned_by)),ep.team_id){let e=ec?.find(e=>e.team_id===ep.team_id)||null;e&&(e4(e),eI.setFieldsValue({team_id:ep.team_id}))}ep.key_alias&&eI.setFieldsValue({key_alias:ep.key_alias}),ep.models&&ep.models.length>0&&eW(ep.models),ep.key_type&&(tm(ep.key_type),eI.setFieldsValue({key_type:ep.key_type}))}},[eg,ep,ec,eK,eI,ey]);let tP=eD.includes("no-default-models")&&!e1,tD=async e=>{try{let t,a=e?.key_alias??"",s=e?.team_id??null;if((eu?.filter(e=>e.team_id===s).map(e=>e.key_alias)??[]).includes(a))throw Error(`Key alias ${a} already exists for team with ID ${s}, please provide another key alias`);if(el.default.info("Making API Call"),eE(!0),"you"===ez)e.user_id=ex;else if("agent"===ez){if(!tO)return void el.default.fromBackend("Please select an agent");e.agent_id=tO}let i={};try{i=JSON.parse(e.metadata||"{}")}catch(e){console.error("Error parsing metadata:",e)}if("service_account"===ez&&(i.service_account_id=e.key_alias),eZ.length>0&&(i={...i,logging:eZ.filter(e=>e.callback_name)}),td.length>0){let e=(0,M.mapDisplayToInternalNames)(td);i={...i,litellm_disabled_callbacks:e}}if(th&&(e.auto_rotate=!0,e.rotation_interval=ty),e.duration&&""!==e.duration.trim()||(e.duration=null),e.metadata=JSON.stringify(i),e.disable_global_guardrails||delete e.disable_global_guardrails,e.allowed_vector_store_ids&&e.allowed_vector_store_ids.length>0&&(e.object_permission={vector_stores:e.allowed_vector_store_ids},delete e.allowed_vector_store_ids),e.allowed_mcp_servers_and_groups&&(e.allowed_mcp_servers_and_groups.servers?.length>0||e.allowed_mcp_servers_and_groups.accessGroups?.length>0||e.allowed_mcp_servers_and_groups.toolsets?.length>0)){e.object_permission||(e.object_permission={});let{servers:t,accessGroups:l,toolsets:a}=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),a&&a.length>0&&(e.object_permission.mcp_toolsets=a),delete e.allowed_mcp_servers_and_groups}let r=e.mcp_tool_permissions||{};if(Object.keys(r).length>0&&(e.object_permission||(e.object_permission={}),e.object_permission.mcp_tool_permissions=r),delete e.mcp_tool_permissions,e.allowed_mcp_access_groups&&e.allowed_mcp_access_groups.length>0&&(e.object_permission||(e.object_permission={}),e.object_permission.mcp_access_groups=e.allowed_mcp_access_groups,delete e.allowed_mcp_access_groups),e.allowed_agents_and_groups&&(e.allowed_agents_and_groups.agents?.length>0||e.allowed_agents_and_groups.accessGroups?.length>0)){e.object_permission||(e.object_permission={});let{agents:t,accessGroups: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(tg).length>0&&(e.aliases=JSON.stringify(tg)),tb?.router_settings&&Object.values(tb.router_settings).some(e=>null!=e&&""!==e)&&(e.router_settings=tb.router_settings);let n=t_.filter(e=>e.budget_duration&&null!==e.max_budget&&void 0!==e.max_budget);n.length>0&&(e.budget_limits=n);let{tag_rpm_limit:o}=(0,Y.tagRowsToLimits)(tA);Object.keys(o).length>0&&(e.tag_rpm_limit=o),Object.keys(tk).length>0&&(e.budget_fallbacks=tk),t="service_account"===ez?await (0,ea.keyCreateServiceAccountCall)(eh,e):await (0,ea.keyCreateCall)(eh,ex,e),em(t),eT.invalidateQueries({queryKey:l.keyKeys.lists()}),eF(t.key),eR(t.soft_budget),el.default.success("Virtual Key Created"),eI.resetFields(),tv([]),tw([]),tN({}),tC(e=>e+1),localStorage.removeItem("userData"+ex)}catch(t){let e=(e=>{let t;if(!(t=!e||"object"!=typeof e||e instanceof Error?String(e):JSON.stringify(e)).includes("/key/generate")&&!t.includes("KeyManagementRoutes.KEY_GENERATE"))return`Error creating the key: ${e}`;let 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]),a=t?.error||t;a?.message&&(l=a.message)}}else{let t=e?.error||e;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: ${e}`})(t);el.default.fromBackend(e)}};(0,E.useEffect)(()=>{if(e6){let e=ev?.find(e=>e.project_id===e6);eU(e?.models??[]),eI.setFieldValue("models",[]);return}ex&&ey&&eh&&eo(ex,ey,eh,e1?.team_id??null).then(e=>{eU((0,X.excludeProxyWideSentinel)(Array.from(new Set([...e1?.models??[],...e]))))}),eQ||eI.setFieldValue("models",[]),eI.setFieldValue("allowed_mcp_servers_and_groups",{servers:[],accessGroups:[]})},[e1,e6,eh,ex,ey,eI]),(0,E.useEffect)(()=>{if(!eQ||0===eQ.length||!eD||0===eD.length)return;let e=eQ.filter(e=>eD.includes(e));e.length>0&&eI.setFieldsValue({models:e}),eW(null)},[eQ,eD,eI]),(0,E.useEffect)(()=>{if(!e6||!ec)return;let e=ev?.find(e=>e.project_id===e6);if(!e?.team_id||e1?.team_id===e.team_id)return;let t=ec.find(t=>t.team_id===e.team_id)||null;t&&(e4(t),eI.setFieldValue("team_id",t.team_id))},[ec,e6,ev]);let tU=async e=>{if(!e)return void ts([]);tr(!0);try{let t=new URLSearchParams;if(t.append("user_email",e),null==eh)return;let l=(await (0,ea.userFilterUICall)(eh,t)).map(e=>({label:`${e.user_email} (${e.user_id})`,value:e.user_id,user:e}));ts(l)}catch(e){console.error("Error fetching users:",e),el.default.fromBackend("Failed to search for users")}finally{tr(!1)}},tz=(0,I.useDebouncedCallback)(e=>tU(e),{wait:L.DEBOUNCE_WAIT_MS});return(0,t.jsxs)("div",{children:[ey&&O.rolesWithWriteAccess.includes(ey)&&(0,t.jsx)(p.Button,{className:"mx-auto",onClick:()=>eE(!0),"data-testid":"create-key-button",children:"+ Create New Key"}),(0,t.jsx)(A.Modal,{open:eL,width:1e3,footer:null,onOk:tR,onCancel:tB,children:(0,t.jsxs)(_.Form,{form:eI,onFinish:tD,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,t.jsxs)("div",{className:"mb-8",children:[(0,t.jsx)(b.Title,{className:"mb-4",children:"Key Ownership"}),(0,t.jsx)(_.Form.Item,{label:(0,t.jsxs)("span",{children:["Owned By"," ",(0,t.jsx)(C.Tooltip,{title:"Select who will own this Virtual Key",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),className:"mb-4",children:(0,t.jsxs)(w.Radio.Group,{onChange:e=>eV(e.target.value),value:ez,children:[(0,t.jsx)(w.Radio,{value:"you",children:"You"}),(0,t.jsx)(w.Radio,{value:"service_account",children:"Service Account"}),"Admin"===ey&&(0,t.jsx)(w.Radio,{value:"another_user",children:"Another User"}),(0,t.jsxs)(w.Radio,{value:"agent",children:["Agent ",(0,t.jsx)(S.Tag,{color:"purple",children:"New"})]})]})}),"another_user"===ez&&(0,t.jsx)(_.Form.Item,{label:(0,t.jsxs)("span",{children:["User ID"," ",(0,t.jsx)(C.Tooltip,{title:"The user who will own this key and be responsible for its usage",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"user_id",className:"mt-4",rules:[{required:"another_user"===ez,message:"Please input the user ID of the user you are assigning the key to"}],children:(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{style:{display:"flex",marginBottom:"8px"},children:[(0,t.jsx)(k.Select,{showSearch:!0,placeholder:"Type email to search for users",filterOption:!1,onSearch:tz,onSelect:(e,t)=>{let l;return l=t.user,void eI.setFieldsValue({user_id:l.user_id})},options:ta,loading:ti,allowClear:!0,style:{width:"100%"},notFoundContent:ti?"Searching...":"No users found"}),(0,t.jsx)(j.Button,{onClick:()=>e8(!0),style:{marginLeft:"8px"},children:"Create User"})]}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"Search by email to find users"})]})}),"agent"===ez&&(0,t.jsxs)("div",{className:"mt-4 p-4 bg-purple-50 border border-purple-200 rounded-md",children:[(0,t.jsx)("div",{className:"mb-3",children:(0,t.jsxs)("span",{className:"text-sm font-medium text-gray-700",children:["Select Agent ",(0,t.jsx)("span",{className:"text-red-500",children:"*"})]})}),(0,t.jsx)(k.Select,{showSearch:!0,placeholder:"Select an agent",style:{width:"100%"},value:tO,onChange:e=>tF(e),filterOption:(e,t)=>t?.label?.toLowerCase().includes(e.toLowerCase()),options:tL.map(e=>({label:e.agent_name||e.agent_id,value:e.agent_id}))}),(0,t.jsx)("div",{className:"text-xs text-gray-500 mt-2",children:"This key will be used by the selected agent to make requests to LiteLLM"})]}),(0,t.jsx)(_.Form.Item,{label:(0,t.jsxs)("span",{children:["Organization"," ",(0,t.jsx)(C.Tooltip,{title:"The organization this key belongs to. Selecting an organization filters the available teams.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"organization_id",className:"mt-4",children:(0,t.jsx)(W.default,{organizations:ej,loading:e_,disabled:"Admin"!==ey,onChange:e=>{e3(e||null),e4(null),e5(null),eI.setFieldValue("team_id",void 0),eI.setFieldValue("project_id",void 0)}})}),(0,t.jsx)(_.Form.Item,{label:(0,t.jsxs)("span",{children:["Team"," ",(0,t.jsx)(C.Tooltip,{title:"The team this key belongs to, which determines available models and budget limits",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"team_id",initialValue:e?e.team_id:null,className:"mt-4",rules:[{required:"service_account"===ez,message:"Please select a team for the service account"}],help:"service_account"===ez?"required":"",children:(0,t.jsx)(Q.default,{disabled:null!==e6,organizationId:e2,onTeamSelect:e=>{e4(e),e5(null),eI.setFieldValue("project_id",void 0),e?.organization_id?(e3(e.organization_id),eI.setFieldValue("organization_id",e.organization_id)):e||(e3(null),eI.setFieldValue("organization_id",void 0))}})}),eN&&(0,t.jsx)(_.Form.Item,{label:(0,t.jsxs)("span",{children:["Project"," ",(0,t.jsx)(C.Tooltip,{title:"Assign this key to a project. Selecting a project will lock the team to the project's team.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"project_id",className:"mt-4",children:(0,t.jsx)(H.default,{projects:ev,teamId:e1?.team_id,loading:eA||!ec,onChange:e=>{if(!e){e5(null),e4(null),eI.setFieldValue("team_id",void 0);return}e5(e)}})})]}),tP&&(0,t.jsx)("div",{className:"mb-8 p-4 bg-blue-50 border border-blue-200 rounded-md",children:(0,t.jsx)(y.Text,{className:"text-blue-800 text-sm",children:"Please select a team to continue configuring your Virtual Key. If you do not see any teams, please contact your Proxy Admin to either provide you with access to models or to add you to a team."})}),!tP&&(0,t.jsxs)("div",{className:"mb-8",children:[(0,t.jsx)(b.Title,{className:"mb-4",children:"Key Details"}),(0,t.jsx)(_.Form.Item,{label:(0,t.jsxs)("span",{children:["you"===ez||"another_user"===ez?"Key Name":"Service Account ID"," ",(0,t.jsx)(C.Tooltip,{title:"you"===ez||"another_user"===ez?"A descriptive name to identify this key":"Unique identifier for this service account",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"key_alias",rules:[{required:!0,message:`Please input a ${"you"===ez?"key name":"service account ID"}`}],help:"required",children:(0,t.jsx)(f.TextInput,{placeholder:""})}),(0,t.jsx)(_.Form.Item,{label:(0,t.jsxs)("span",{children:["Models"," ",(0,t.jsx)(C.Tooltip,{title:"Select which models this key can access. Choose 'All Team Models' to grant access to all models available to the team. Leave empty to allow access to all models.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"models",rules:[],help:"management"===tu||"read_only"===tu?"Models field is disabled for this key type":"optional - leave empty to allow access to all models",className:"mt-4",children:(0,t.jsxs)(k.Select,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},disabled:"management"===tu||"read_only"===tu,onChange:e=>{e.includes("all-team-models")?eI.setFieldsValue({models:["all-team-models"]}):e.includes("all-proxy-models")&&eI.setFieldsValue({models:["all-proxy-models"]})},children:[!e6&&e1&&(0,t.jsx)(en,{value:"all-team-models",children:"All Team Models"},"all-team-models"),!e6&&!e1&&(0,t.jsx)(en,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),eD.map(e=>(0,t.jsx)(en,{value:e,disabled:(0,X.hasAllModelsSentinel)(tM),children:(0,X.getModelDisplayName)(e)},e))]})}),(0,t.jsx)(_.Form.Item,{label:(0,t.jsxs)("span",{children:["Key Type"," ",(0,t.jsx)(C.Tooltip,{title:"Select the type of key to determine what routes and operations this key can access",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"key_type",initialValue:"llm_api",className:"mt-4",children:(0,t.jsxs)(k.Select,{defaultValue:"llm_api",placeholder:"Select key type",style:{width:"100%"},optionLabelProp:"label",onChange:e=>{tm(e),("management"===e||"read_only"===e)&&eI.setFieldsValue({models:[]})},children:[(0,t.jsx)(en,{value:"llm_api",label:"AI APIs",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)(T.Typography.Text,{strong:!0,children:"AI APIs"}),(0,t.jsx)(T.Typography.Paragraph,{type:"secondary",style:{fontSize:11,margin:"2px 0 0"},children:"Can call only AI API routes (chat/completions, embeddings, etc.)"})]})}),(0,t.jsx)(en,{value:"management",label:"Management",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)(T.Typography.Text,{strong:!0,children:"Management"}),(0,t.jsx)(T.Typography.Paragraph,{type:"secondary",style:{fontSize:11,margin:"2px 0 0"},children:"Can call only management routes (user/team/key management)"})]})}),(0,t.jsx)(en,{value:"default",label:"Full Access",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)(T.Typography.Text,{strong:!0,children:"Full Access"}),(0,t.jsx)(T.Typography.Paragraph,{type:"secondary",style:{fontSize:11,margin:"2px 0 0"},children:"Can call all routes (AI APIs, Management, and read-only)"})]})})]})})]}),!tP&&(0,t.jsx)("div",{className:"mb-8",children:(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(g.AccordionHeader,{children:(0,t.jsx)(b.Title,{className:"m-0",children:"Optional Settings"})}),(0,t.jsxs)(m.AccordionBody,{children:[(0,t.jsx)(_.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Max Budget (USD)"," ",(0,t.jsx)(C.Tooltip,{title:"Maximum amount in USD this key can spend. When reached, the key will be blocked from making further requests",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"max_budget",help:`Budget cannot exceed team max budget: $${e?.max_budget!==null&&e?.max_budget!==void 0?e?.max_budget:"unlimited"}`,rules:[{validator:async(t,l)=>{if(l&&e&&null!==e.max_budget&&l>e.max_budget)throw Error(`Budget cannot exceed team max budget: $${(0,o.formatNumberWithCommas)(e.max_budget,4)}`)}}],children:(0,t.jsx)(ei.default,{step:.01,precision:2,width:200})}),(0,t.jsx)(_.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Reset Budget"," ",(0,t.jsx)(C.Tooltip,{title:"How often the budget should reset. For example, setting 'daily' will reset the budget every 24 hours",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"budget_duration",help:`Team Reset Budget: ${e?.budget_duration!==null&&e?.budget_duration!==void 0?e?.budget_duration:"None"}`,children:(0,t.jsx)(B.default,{onChange:e=>eI.setFieldValue("budget_duration",e)})}),(0,t.jsx)(_.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Budget Windows"," ",(0,t.jsx)(C.Tooltip,{title:"Set multiple independent budget windows (e.g., hourly $10 AND monthly $200). Each window tracks spend separately and resets on its own schedule.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),children:(0,t.jsx)($.BudgetWindowsEditor,{value:t_,onChange:tv})}),(0,t.jsx)(_.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Budget Fallbacks"," ",(0,t.jsx)(C.Tooltip,{title:"When a model exceeds its per-model budget (model_max_budget), requests automatically reroute to fallback models instead of failing. Configure per-model budgets in Advanced Settings.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),children:(0,t.jsx)(J.BudgetFallbacksEditor,{value:tk,onChange:tN,availableModels:eD},tS)}),(0,t.jsx)(_.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Tokens per minute Limit (TPM)"," ",(0,t.jsx)(C.Tooltip,{title:"Maximum number of tokens this key can process per minute. Helps control usage and costs",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"tpm_limit",help:`TPM cannot exceed team TPM limit: ${e?.tpm_limit!==null&&e?.tpm_limit!==void 0?e?.tpm_limit:"unlimited"}`,rules:[{validator:async(t,l)=>{if(l&&e&&null!==e.tpm_limit&&l>e.tpm_limit)throw Error(`TPM limit cannot exceed team TPM limit: ${e.tpm_limit}`)}}],children:(0,t.jsx)(ei.default,{step:1,width:400})}),(0,t.jsx)(K.default,{type:"tpm",name:"tpm_limit_type",className:"mt-4",initialValue:null,form:eI,showDetailedDescriptions:!0}),(0,t.jsx)(_.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Requests per minute Limit (RPM)"," ",(0,t.jsx)(C.Tooltip,{title:"Maximum number of API requests this key can make per minute. Helps prevent abuse and manage load",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"rpm_limit",help:`RPM cannot exceed team RPM limit: ${e?.rpm_limit!==null&&e?.rpm_limit!==void 0?e?.rpm_limit:"unlimited"}`,rules:[{validator:async(t,l)=>{if(l&&e&&null!==e.rpm_limit&&l>e.rpm_limit)throw Error(`RPM limit cannot exceed team RPM limit: ${e.rpm_limit}`)}}],children:(0,t.jsx)(ei.default,{step:1,width:400})}),(0,t.jsx)(K.default,{type:"rpm",name:"rpm_limit_type",className:"mt-4",initialValue:null,form:eI,showDetailedDescriptions:!0}),(0,t.jsx)(_.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Per-Tag Rate Limits"," ",(0,t.jsx)(C.Tooltip,{title:"Scope rate limits to a request tag so each tag (e.g. a cell or group) gets its own RPM counter. Requests without a matching tag fall back to the key-level limit.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),children:(0,t.jsx)(Y.TagRateLimitEditor,{value:tA,onChange:tw})}),(0,t.jsx)(_.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Throttle on budget exceeded"," ",(0,t.jsx)(C.Tooltip,{title:"When this key exceeds its max budget, throttle its TPM/RPM to the globally configured percentage instead of blocking access entirely. Requires budget_exceeded_throttle_percentage in litellm_settings and a TPM/RPM limit on the key.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"throttle_on_budget_exceeded",valuePropName:"checked",children:(0,t.jsx)(N.Switch,{checkedChildren:"Yes",unCheckedChildren:"No"})}),(0,t.jsx)(_.Form.Item,{label:(0,t.jsxs)("span",{children:["Guardrails"," ",(0,t.jsx)(C.Tooltip,{title:"Apply safety guardrails to this key to filter content or enforce policies",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/quick_start",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"guardrails",className:"mt-4",help:eb?"Select existing guardrails or enter new ones":"Premium feature - Upgrade to set guardrails by key",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},disabled:!eb,placeholder:eb?"Select or enter guardrails":"Premium feature - Upgrade to set guardrails by key",options:eH.map(e=>({value:e,label:e}))})}),(0,t.jsx)(_.Form.Item,{label:(0,t.jsxs)("span",{children:["Disable Global Guardrails"," ",(0,t.jsx)(C.Tooltip,{title:"When enabled, this key will bypass any guardrails configured to run on every request (global guardrails)",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/quick_start",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"disable_global_guardrails",className:"mt-4",valuePropName:"checked",help:eb?"Bypass global guardrails for this key":"Premium feature - Upgrade to disable global guardrails by key",children:(0,t.jsx)(N.Switch,{disabled:!eb,checkedChildren:"Yes",unCheckedChildren:"No"})}),(0,t.jsx)(_.Form.Item,{label:(0,t.jsxs)("span",{children:["Policies"," ",(0,t.jsx)(C.Tooltip,{title:"Apply policies to this key to control guardrails and other settings",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/guardrail_policies",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"policies",className:"mt-4",help:ef?"Select existing policies or enter new ones":"Premium feature - Upgrade to set policies by key",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},disabled:!ef,placeholder:ef?"Select or enter policies":"Premium feature - Upgrade to set policies by key",options:eJ.map(e=>({value:e,label:e}))})}),(0,t.jsx)(_.Form.Item,{label:(0,t.jsxs)("span",{children:["Prompts"," ",(0,t.jsx)(C.Tooltip,{title:"Allow this key to use specific prompt templates",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/prompt_management",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"prompts",className:"mt-4",help:ef?"Select existing prompts or enter new ones":"Premium feature - Upgrade to set prompts by key",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},disabled:!ef,placeholder:ef?"Select or enter prompts":"Premium feature - Upgrade to set prompts by key",options:eY.map(e=>({value:e,label:e}))})}),(0,t.jsx)(_.Form.Item,{label:(0,t.jsxs)("span",{children:["Access Groups"," ",(0,t.jsx)(C.Tooltip,{title:"Assign access groups to this key. Access groups control which models, MCP servers, and agents this key can use",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"access_group_ids",className:"mt-4",help:"Select access groups to assign to this key",children:(0,t.jsx)(R.default,{placeholder:"Select access groups (optional)"})}),(0,t.jsx)(_.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed Pass Through Routes"," ",(0,t.jsx)(C.Tooltip,{title:"Allow this key to use specific pass through routes",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/pass_through",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"allowed_passthrough_routes",className:"mt-4",help:ef?"Select existing pass through routes or enter new ones":"Premium feature - Upgrade to set pass through routes by key",children:(0,t.jsx)(z.default,{onChange:e=>eI.setFieldValue("allowed_passthrough_routes",e),value:eI.getFieldValue("allowed_passthrough_routes"),accessToken:eh,placeholder:ef?"Select or enter pass through routes":"Premium feature - Upgrade to set pass through routes by key",disabled:!ef,teamId:e1?e1.team_id:null})}),(0,t.jsx)(_.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed Vector Stores"," ",(0,t.jsx)(C.Tooltip,{title:"Select which vector stores this key can access. If none selected, the key will have access to all available vector stores",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"allowed_vector_store_ids",className:"mt-4",help:"Select vector stores this key can access. Leave empty for access to all vector stores",children:(0,t.jsx)(er.default,{onChange:e=>eI.setFieldValue("allowed_vector_store_ids",e),value:eI.getFieldValue("allowed_vector_store_ids"),accessToken:eh,placeholder:"Select vector stores (optional)"})}),(0,t.jsx)(_.Form.Item,{label:(0,t.jsxs)("span",{children:["Metadata"," ",(0,t.jsx)(C.Tooltip,{title:"JSON object with additional information about this key. Used for tracking or custom logic",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"metadata",className:"mt-4",children:(0,t.jsx)(v.Input.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,t.jsx)(_.Form.Item,{label:(0,t.jsxs)("span",{children:["Tags"," ",(0,t.jsx)(C.Tooltip,{title:"Tags for tracking spend and/or doing tag-based routing. Used for analytics and filtering",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"tags",className:"mt-4",help:"Tags for tracking spend and/or doing tag-based routing.",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},placeholder:"Select or enter tags",tokenSeparators:[","],options:eC})}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(g.AccordionHeader,{children:(0,t.jsx)("b",{children:"MCP Settings"})}),(0,t.jsxs)(m.AccordionBody,{children:[(0,t.jsx)(_.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed MCP Servers"," ",(0,t.jsx)(C.Tooltip,{title:"Select which MCP servers or access groups this key can access",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"allowed_mcp_servers_and_groups",help:"Select MCP servers or access groups this key can access",children:(0,t.jsx)(Z.default,{onChange:e=>eI.setFieldValue("allowed_mcp_servers_and_groups",e),value:eI.getFieldValue("allowed_mcp_servers_and_groups"),accessToken:eh,teamId:e1?.team_id??null,placeholder:"Select MCP servers or access groups (optional)",allowNoMcpServers:!0})}),(0,t.jsx)(_.Form.Item,{name:"mcp_tool_permissions",initialValue:{},hidden:!0,children:(0,t.jsx)(v.Input,{type:"hidden"})}),(0,t.jsx)(_.Form.Item,{noStyle:!0,shouldUpdate:(e,t)=>e.allowed_mcp_servers_and_groups!==t.allowed_mcp_servers_and_groups||e.mcp_tool_permissions!==t.mcp_tool_permissions,children:()=>(0,t.jsx)("div",{className:"mt-6",children:(0,t.jsx)(et.default,{accessToken:eh,selectedServers:(eI.getFieldValue("allowed_mcp_servers_and_groups")?.servers||[]).filter(e=>e!==ee.NO_MCP_SERVERS_SENTINEL),toolPermissions:eI.getFieldValue("mcp_tool_permissions")||{},onChange:e=>eI.setFieldsValue({mcp_tool_permissions:e})})})})]})]}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(g.AccordionHeader,{children:(0,t.jsx)("b",{children:"Agent Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)(_.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed Agents"," ",(0,t.jsx)(C.Tooltip,{title:"Select which agents or access groups this key can access",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"allowed_agents_and_groups",help:"Select agents or access groups this key can access",children:(0,t.jsx)(F.default,{onChange:e=>eI.setFieldValue("allowed_agents_and_groups",e),value:eI.getFieldValue("allowed_agents_and_groups"),accessToken:eh,placeholder:"Select agents or access groups (optional)"})})})]}),ef?(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(g.AccordionHeader,{children:(0,t.jsx)("b",{children:"Logging Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)(V.default,{value:eZ,onChange:e0,premiumUser:!0,disabledCallbacks:td,onDisabledCallbacksChange:tc})})})]}):(0,t.jsx)(C.Tooltip,{title:(0,t.jsxs)("span",{children:["Key-level logging settings is an enterprise feature, get in touch -",(0,t.jsx)("a",{href:"https://www.litellm.ai/enterprise",target:"_blank",children:"https://www.litellm.ai/enterprise"})]}),placement:"top",children:(0,t.jsxs)("div",{style:{position:"relative"},children:[(0,t.jsx)("div",{style:{opacity:.5},children:(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(g.AccordionHeader,{children:(0,t.jsx)("b",{children:"Logging Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)(V.default,{value:eZ,onChange:e0,premiumUser:!1,disabledCallbacks:td,onDisabledCallbacksChange:tc})})})]})}),(0,t.jsx)("div",{style:{position:"absolute",inset:0,cursor:"not-allowed"}})]})}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(g.AccordionHeader,{children:(0,t.jsx)("b",{children:"Router Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4 w-full",children:(0,t.jsx)(G.default,{accessToken:eh||"",value:tb||void 0,onChange:tj,modelData:eB.length>0?{data:eB.map(e=>({model_name:e}))}:void 0},tT)})})]},`router-settings-accordion-${tT}`),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(g.AccordionHeader,{children:(0,t.jsx)("b",{children:"Model Aliases"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsxs)("div",{className:"mt-4",children:[(0,t.jsx)(y.Text,{className:"text-sm text-gray-600 mb-4",children:"Create custom aliases for models that can be used in API calls. This allows you to create shortcuts for specific models."}),(0,t.jsx)(U.default,{accessToken:eh,initialModelAliases:tg,onAliasUpdate:tp,showExampleConfig:!1})]})})]}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(g.AccordionHeader,{children:(0,t.jsx)("b",{children:"Key Lifecycle"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)(D.default,{form:eI,autoRotationEnabled:th,onAutoRotationChange:tx,rotationInterval:ty,onRotationIntervalChange:tf,isCreateMode:!0})})})]}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(g.AccordionHeader,{children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("b",{children:"Advanced Settings"}),(0,t.jsx)(C.Tooltip,{title:(0,t.jsxs)("span",{children:["Learn more about advanced settings in our"," ",(0,t.jsx)("a",{href:ea.proxyBaseUrl?`${ea.proxyBaseUrl}/#/key%20management/generate_key_fn_key_generate_post`:"/#/key%20management/generate_key_fn_key_generate_post",target:"_blank",rel:"noopener noreferrer",className:"text-blue-400 hover:text-blue-300",children:"documentation"})]}),children:(0,t.jsx)(d.InfoCircleOutlined,{className:"text-gray-400 hover:text-gray-300 cursor-help"})})]})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)(P.default,{schemaComponent:"GenerateKeyRequest",form:eI,excludedFields:["key_alias","team_id","organization_id","models","duration","metadata","tags","guardrails","max_budget","budget_duration","tpm_limit","rpm_limit",...eS?["key"]:[]]})})]})]})]})}),(0,t.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,t.jsx)(j.Button,{htmlType:"submit",disabled:tP,style:{opacity:tP?.5:1},children:"Create Key"})})]})}),e7&&(0,t.jsx)(A.Modal,{title:"Create New User",open:e7,onCancel:()=>e8(!1),footer:null,width:800,children:(0,t.jsx)(q.CreateUserButton,{userID:ex,accessToken:eh,teams:ec,possibleUIRoles:tt,onUserCreated:e=>{te(e),eI.setFieldsValue({user_id:e}),e8(!1)},isEmbedded:!0})}),eO&&(0,t.jsx)(A.Modal,{open:eL,onOk:tR,onCancel:tB,footer:null,children:(0,t.jsxs)(x.Grid,{numItems:1,className:"gap-2 w-full",children:[(0,t.jsx)(b.Title,{children:"Save your Key"}),(0,t.jsx)(h.Col,{numColSpan:1,children:null!=eO?(0,t.jsx)(es.default,{apiKey:eO}):(0,t.jsx)(y.Text,{children:"Key being created, this might take 30s"})})]})})]})},"fetchTeamModels",0,eo,"fetchUserModels",0,ed],702597)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/00ccjtnk99zr7.js b/litellm/proxy/_experimental/out/_next/static/chunks/00ccjtnk99zr7.js deleted file mode 100644 index e36db16ad4d..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/00ccjtnk99zr7.js +++ /dev/null @@ -1,8 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,185793,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(343794),n=e.i(242064),r=e.i(529681);let o=e=>{let{prefixCls:n,className:r,style:o,size:i,shape:l}=e,s=(0,a.default)({[`${n}-lg`]:"large"===i,[`${n}-sm`]:"small"===i}),u=(0,a.default)({[`${n}-circle`]:"circle"===l,[`${n}-square`]:"square"===l,[`${n}-round`]:"round"===l}),d=t.useMemo(()=>"number"==typeof i?{width:i,height:i,lineHeight:`${i}px`}:{},[i]);return t.createElement("span",{className:(0,a.default)(n,s,u,r),style:Object.assign(Object.assign({},d),o)})};e.i(296059);var i=e.i(694758),l=e.i(915654),s=e.i(246422),u=e.i(838378);let d=new i.Keyframes("ant-skeleton-loading",{"0%":{backgroundPosition:"100% 50%"},"100%":{backgroundPosition:"0 50%"}}),c=e=>({height:e,lineHeight:(0,l.unit)(e)}),p=e=>Object.assign({width:e},c(e)),g=(e,t)=>Object.assign({width:t(e).mul(5).equal(),minWidth:t(e).mul(5).equal()},c(e)),m=e=>Object.assign({width:e},c(e)),f=(e,t,a)=>{let{skeletonButtonCls:n}=e;return{[`${a}${n}-circle`]:{width:t,minWidth:t,borderRadius:"50%"},[`${a}${n}-round`]:{borderRadius:t}}},b=(e,t)=>Object.assign({width:t(e).mul(2).equal(),minWidth:t(e).mul(2).equal()},c(e)),h=(0,s.genStyleHooks)("Skeleton",e=>{let{componentCls:t,calc:a}=e;return(e=>{let{componentCls:t,skeletonAvatarCls:a,skeletonTitleCls:n,skeletonParagraphCls:r,skeletonButtonCls:o,skeletonInputCls:i,skeletonImageCls:l,controlHeight:s,controlHeightLG:u,controlHeightSM:c,gradientFromColor:h,padding:x,marginSM:C,borderRadius:v,titleHeight:y,blockRadius:S,paragraphLiHeight:O,controlHeightXS:D,paragraphMarginTop:w}=e;return{[t]:{display:"table",width:"100%",[`${t}-header`]:{display:"table-cell",paddingInlineEnd:x,verticalAlign:"top",[a]:Object.assign({display:"inline-block",verticalAlign:"top",background:h},p(s)),[`${a}-circle`]:{borderRadius:"50%"},[`${a}-lg`]:Object.assign({},p(u)),[`${a}-sm`]:Object.assign({},p(c))},[`${t}-content`]:{display:"table-cell",width:"100%",verticalAlign:"top",[n]:{width:"100%",height:y,background:h,borderRadius:S,[`+ ${r}`]:{marginBlockStart:c}},[r]:{padding:0,"> li":{width:"100%",height:O,listStyle:"none",background:h,borderRadius:S,"+ li":{marginBlockStart:D}}},[`${r}> li:last-child:not(:first-child):not(:nth-child(2))`]:{width:"61%"}},[`&-round ${t}-content`]:{[`${n}, ${r} > li`]:{borderRadius:v}}},[`${t}-with-avatar ${t}-content`]:{[n]:{marginBlockStart:C,[`+ ${r}`]:{marginBlockStart:w}}},[`${t}${t}-element`]:Object.assign(Object.assign(Object.assign(Object.assign({display:"inline-block",width:"auto"},(e=>{let{borderRadiusSM:t,skeletonButtonCls:a,controlHeight:n,controlHeightLG:r,controlHeightSM:o,gradientFromColor:i,calc:l}=e;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({[a]:Object.assign({display:"inline-block",verticalAlign:"top",background:i,borderRadius:t,width:l(n).mul(2).equal(),minWidth:l(n).mul(2).equal()},b(n,l))},f(e,n,a)),{[`${a}-lg`]:Object.assign({},b(r,l))}),f(e,r,`${a}-lg`)),{[`${a}-sm`]:Object.assign({},b(o,l))}),f(e,o,`${a}-sm`))})(e)),(e=>{let{skeletonAvatarCls:t,gradientFromColor:a,controlHeight:n,controlHeightLG:r,controlHeightSM:o}=e;return{[t]:Object.assign({display:"inline-block",verticalAlign:"top",background:a},p(n)),[`${t}${t}-circle`]:{borderRadius:"50%"},[`${t}${t}-lg`]:Object.assign({},p(r)),[`${t}${t}-sm`]:Object.assign({},p(o))}})(e)),(e=>{let{controlHeight:t,borderRadiusSM:a,skeletonInputCls:n,controlHeightLG:r,controlHeightSM:o,gradientFromColor:i,calc:l}=e;return{[n]:Object.assign({display:"inline-block",verticalAlign:"top",background:i,borderRadius:a},g(t,l)),[`${n}-lg`]:Object.assign({},g(r,l)),[`${n}-sm`]:Object.assign({},g(o,l))}})(e)),(e=>{let{skeletonImageCls:t,imageSizeBase:a,gradientFromColor:n,borderRadiusSM:r,calc:o}=e;return{[t]:Object.assign(Object.assign({display:"inline-flex",alignItems:"center",justifyContent:"center",verticalAlign:"middle",background:n,borderRadius:r},m(o(a).mul(2).equal())),{[`${t}-path`]:{fill:"#bfbfbf"},[`${t}-svg`]:Object.assign(Object.assign({},m(a)),{maxWidth:o(a).mul(4).equal(),maxHeight:o(a).mul(4).equal()}),[`${t}-svg${t}-svg-circle`]:{borderRadius:"50%"}}),[`${t}${t}-circle`]:{borderRadius:"50%"}}})(e)),[`${t}${t}-block`]:{width:"100%",[o]:{width:"100%"},[i]:{width:"100%"}},[`${t}${t}-active`]:{[` - ${n}, - ${r} > li, - ${a}, - ${o}, - ${i}, - ${l} - `]:Object.assign({},{background:e.skeletonLoadingBackground,backgroundSize:"400% 100%",animationName:d,animationDuration:e.skeletonLoadingMotionDuration,animationTimingFunction:"ease",animationIterationCount:"infinite"})}}})((0,u.mergeToken)(e,{skeletonAvatarCls:`${t}-avatar`,skeletonTitleCls:`${t}-title`,skeletonParagraphCls:`${t}-paragraph`,skeletonButtonCls:`${t}-button`,skeletonInputCls:`${t}-input`,skeletonImageCls:`${t}-image`,imageSizeBase:a(e.controlHeight).mul(1.5).equal(),borderRadius:100,skeletonLoadingBackground:`linear-gradient(90deg, ${e.gradientFromColor} 25%, ${e.gradientToColor} 37%, ${e.gradientFromColor} 63%)`,skeletonLoadingMotionDuration:"1.4s"}))},e=>{let{colorFillContent:t,colorFill:a}=e;return{color:t,colorGradientEnd:a,gradientFromColor:t,gradientToColor:a,titleHeight:e.controlHeight/2,blockRadius:e.borderRadiusSM,paragraphMarginTop:e.marginLG+e.marginXXS,paragraphLiHeight:e.controlHeight/2}},{deprecatedTokens:[["color","gradientFromColor"],["colorGradientEnd","gradientToColor"]]}),x=e=>{let{prefixCls:n,className:r,style:o,rows:i=0}=e,l=Array.from({length:i}).map((a,n)=>t.createElement("li",{key:n,style:{width:((e,t)=>{let{width:a,rows:n=2}=t;return Array.isArray(a)?a[e]:n-1===e?a:void 0})(n,e)}}));return t.createElement("ul",{className:(0,a.default)(n,r),style:o},l)},C=({prefixCls:e,className:n,width:r,style:o})=>t.createElement("h3",{className:(0,a.default)(e,n),style:Object.assign({width:r},o)});function v(e){return e&&"object"==typeof e?e:{}}let y=e=>{let{prefixCls:r,loading:i,className:l,rootClassName:s,style:u,children:d,avatar:c=!1,title:p=!0,paragraph:g=!0,active:m,round:f}=e,{getPrefixCls:b,direction:y,className:S,style:O}=(0,n.useComponentConfig)("skeleton"),D=b("skeleton",r),[w,N,$]=h(D);if(i||!("loading"in e)){let e,n,r=!!c,i=!!p,d=!!g;if(r){let a=Object.assign(Object.assign({prefixCls:`${D}-avatar`},i&&!d?{size:"large",shape:"square"}:{size:"large",shape:"circle"}),v(c));e=t.createElement("div",{className:`${D}-header`},t.createElement(o,Object.assign({},a)))}if(i||d){let e,a;if(i){let a=Object.assign(Object.assign({prefixCls:`${D}-title`},!r&&d?{width:"38%"}:r&&d?{width:"50%"}:{}),v(p));e=t.createElement(C,Object.assign({},a))}if(d){let e,n=Object.assign(Object.assign({prefixCls:`${D}-paragraph`},(e={},r&&i||(e.width="61%"),!r&&i?e.rows=3:e.rows=2,e)),v(g));a=t.createElement(x,Object.assign({},n))}n=t.createElement("div",{className:`${D}-content`},e,a)}let b=(0,a.default)(D,{[`${D}-with-avatar`]:r,[`${D}-active`]:m,[`${D}-rtl`]:"rtl"===y,[`${D}-round`]:f},S,l,s,N,$);return w(t.createElement("div",{className:b,style:Object.assign(Object.assign({},O),u)},e,n))}return null!=d?d:null};y.Button=e=>{let{prefixCls:i,className:l,rootClassName:s,active:u,block:d=!1,size:c="default"}=e,{getPrefixCls:p}=t.useContext(n.ConfigContext),g=p("skeleton",i),[m,f,b]=h(g),x=(0,r.default)(e,["prefixCls"]),C=(0,a.default)(g,`${g}-element`,{[`${g}-active`]:u,[`${g}-block`]:d},l,s,f,b);return m(t.createElement("div",{className:C},t.createElement(o,Object.assign({prefixCls:`${g}-button`,size:c},x))))},y.Avatar=e=>{let{prefixCls:i,className:l,rootClassName:s,active:u,shape:d="circle",size:c="default"}=e,{getPrefixCls:p}=t.useContext(n.ConfigContext),g=p("skeleton",i),[m,f,b]=h(g),x=(0,r.default)(e,["prefixCls","className"]),C=(0,a.default)(g,`${g}-element`,{[`${g}-active`]:u},l,s,f,b);return m(t.createElement("div",{className:C},t.createElement(o,Object.assign({prefixCls:`${g}-avatar`,shape:d,size:c},x))))},y.Input=e=>{let{prefixCls:i,className:l,rootClassName:s,active:u,block:d,size:c="default"}=e,{getPrefixCls:p}=t.useContext(n.ConfigContext),g=p("skeleton",i),[m,f,b]=h(g),x=(0,r.default)(e,["prefixCls"]),C=(0,a.default)(g,`${g}-element`,{[`${g}-active`]:u,[`${g}-block`]:d},l,s,f,b);return m(t.createElement("div",{className:C},t.createElement(o,Object.assign({prefixCls:`${g}-input`,size:c},x))))},y.Image=e=>{let{prefixCls:r,className:o,rootClassName:i,style:l,active:s}=e,{getPrefixCls:u}=t.useContext(n.ConfigContext),d=u("skeleton",r),[c,p,g]=h(d),m=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:s},o,i,p,g);return c(t.createElement("div",{className:m},t.createElement("div",{className:(0,a.default)(`${d}-image`,o),style:l},t.createElement("svg",{viewBox:"0 0 1098 1024",xmlns:"http://www.w3.org/2000/svg",className:`${d}-image-svg`},t.createElement("title",null,"Image placeholder"),t.createElement("path",{d:"M365.714286 329.142857q0 45.714286-32.036571 77.677714t-77.677714 32.036571-77.677714-32.036571-32.036571-77.677714 32.036571-77.677714 77.677714-32.036571 77.677714 32.036571 32.036571 77.677714zM950.857143 548.571429l0 256-804.571429 0 0-109.714286 182.857143-182.857143 91.428571 91.428571 292.571429-292.571429zM1005.714286 146.285714l-914.285714 0q-7.460571 0-12.873143 5.412571t-5.412571 12.873143l0 694.857143q0 7.460571 5.412571 12.873143t12.873143 5.412571l914.285714 0q7.460571 0 12.873143-5.412571t5.412571-12.873143l0-694.857143q0-7.460571-5.412571-12.873143t-12.873143-5.412571zM1097.142857 164.571429l0 694.857143q0 37.741714-26.843429 64.585143t-64.585143 26.843429l-914.285714 0q-37.741714 0-64.585143-26.843429t-26.843429-64.585143l0-694.857143q0-37.741714 26.843429-64.585143t64.585143-26.843429l914.285714 0q37.741714 0 64.585143 26.843429t26.843429 64.585143z",className:`${d}-image-path`})))))},y.Node=e=>{let{prefixCls:r,className:o,rootClassName:i,style:l,active:s,children:u}=e,{getPrefixCls:d}=t.useContext(n.ConfigContext),c=d("skeleton",r),[p,g,m]=h(c),f=(0,a.default)(c,`${c}-element`,{[`${c}-active`]:s},g,o,i,m);return p(t.createElement("div",{className:f},t.createElement("div",{className:(0,a.default)(`${c}-image`,o),style:l},u)))},e.s(["default",0,y],185793)},922611,e=>{"use strict";var t=e.i(271645),a=e.i(175066);function n(){}let r=t.createContext({add:n,remove:n});e.s(["usePanelRef",0,function(e){let n=t.useContext(r),o=t.useRef(null);return(0,a.default)(t=>{if(t){let a=e?t.querySelector(e):t;a&&(n.add(a),o.current=a)}else n.remove(o.current)})}])},500330,e=>{"use strict";var t=e.i(727749);let a=(e,t=0,a=!1,n=!0)=>{if(null==e||!Number.isFinite(e)||0===e&&!n)return"-";let r={minimumFractionDigits:t,maximumFractionDigits:t};if(!a)return e.toLocaleString("en-US",r);let o=e<0?"-":"",i=Math.abs(e),l=i,s="";return i>=1e6?(l=i/1e6,s="M"):i>=1e3&&(l=i/1e3,s="K"),`${o}${l.toLocaleString("en-US",r)}${s}`},n=async(e,a="Copied to clipboard")=>{if(!e)return!1;if(!navigator||!navigator.clipboard||!navigator.clipboard.writeText)return r(e,a);try{return await navigator.clipboard.writeText(e),t.default.success(a),!0}catch(t){return console.error("Clipboard API failed: ",t),r(e,a)}},r=(e,a)=>{try{let n=document.createElement("textarea");n.value=e,n.style.position="fixed",n.style.left="-999999px",n.style.top="-999999px",n.setAttribute("readonly",""),document.body.appendChild(n),n.focus(),n.select();let r=document.execCommand("copy");if(document.body.removeChild(n),r)return t.default.success(a),!0;throw Error("execCommand failed")}catch(e){return t.default.fromBackend("Failed to copy to clipboard"),console.error("Failed to copy: ",e),!1}};e.s(["copyToClipboard",0,n,"formatNumberWithCommas",0,a,"getSpendString",0,(e,t=6)=>{if(null==e||!Number.isFinite(e)||0===e)return"-";let n=a(e,t,!1,!1);if(0===Number(n.replace(/,/g,""))){let e=(1/10**t).toFixed(t);return`< $${e}`}return`$${n}`},"updateExistingKeys",0,function(e,t){let a=structuredClone(e);for(let[e,n]of Object.entries(t))e in a&&(a[e]=n);return a}])},112179,581070,e=>{"use strict";var t=e.i(843476),a=e.i(487486),n=e.i(115504),r=e.i(746798);function o({content:e,trigger:a}){return(0,t.jsx)(r.TooltipProvider,{delay:300,children:(0,t.jsxs)(r.Tooltip,{children:[(0,t.jsx)(r.TooltipTrigger,{render:a}),(0,t.jsx)(r.TooltipContent,{children:e})]})})}e.s(["CellTooltip",0,o],581070);let i={success:"border-green-200 bg-green-50 text-green-600",error:"border-red-200 bg-red-50 text-red-600",warning:"border-amber-200 bg-amber-50 text-amber-600",neutral:"border-gray-200 bg-gray-50 text-gray-600",info:"border-blue-200 bg-blue-50 text-blue-600"};e.s(["StatusBadge",0,function({tone:e,label:r,tooltip:l,dataTestId:s}){let u=(0,t.jsx)(a.Badge,{variant:"outline","data-testid":s,className:(0,n.cn)("whitespace-nowrap font-normal",i[e]),children:r});return l?(0,t.jsx)(o,{content:l,trigger:u}):u}],112179)},200208,399536,997422,146512,e=>{"use strict";var t=e.i(843476),a=e.i(581070);let n=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],r=e=>String(e).padStart(2,"0");e.s(["DateCell",0,function({value:e,precision:o="datetime",fallback:i="-"}){let l,s,u,d=e?new Date(e):null;return!d||Number.isNaN(d.getTime())?(0,t.jsx)("span",{className:"text-muted-foreground",children:i}):(0,t.jsx)(a.CellTooltip,{content:(l=Intl.DateTimeFormat().resolvedOptions().timeZone,s=`${n[d.getMonth()]} ${d.getDate()}, ${d.getFullYear()}`,u=`${r(d.getHours())}:${r(d.getMinutes())}:${r(d.getSeconds())}`,`${s}, ${u} (${l})`),trigger:(0,t.jsx)("span",{className:"whitespace-nowrap",children:"date"===o?`${n[d.getMonth()]} ${d.getDate()}, ${d.getFullYear()}`:`${n[d.getMonth()]} ${d.getDate()}, ${r(d.getHours())}:${r(d.getMinutes())}:${r(d.getSeconds())}`})})}],200208);var o=e.i(174886),i=e.i(115504),l=e.i(500330);let s={pill:{base:"font-mono text-xs font-normal px-2 py-0.5 rounded-md text-left bg-blue-50 text-blue-500",clickable:"hover:bg-blue-100 cursor-pointer"},plain:{base:"font-mono text-xs text-left",clickable:"hover:text-blue-600 cursor-pointer"}};e.s(["IdCell",0,function({value:e,variant:n="pill",onClick:r,copyable:u=!1,truncate:d=!0,fallback:c="-",tooltip:p,disabled:g=!1,dataTestId:m,className:f}){if(!e)return(0,t.jsx)("span",{className:"text-muted-foreground",children:c});let b=!!r&&!g,h=(0,i.cn)(s[n].base,b&&s[n].clickable,d&&"block max-w-[15ch] truncate",g&&"opacity-50",f),x=b?(0,t.jsx)("button",{type:"button",className:h,"data-testid":m,onClick:()=>r(e),children:e}):(0,t.jsx)("span",{className:h,"data-testid":m,children:e}),C=(0,t.jsx)(a.CellTooltip,{content:p??e,trigger:x});return u?(0,t.jsxs)("span",{className:"inline-flex max-w-full items-center gap-1",children:[C,(0,t.jsx)("button",{type:"button","aria-label":"Copy ID",className:"shrink-0 cursor-pointer text-muted-foreground hover:text-foreground",onClick:t=>{t.stopPropagation(),(0,l.copyToClipboard)(e)},children:(0,t.jsx)(o.Copy,{className:"size-3"})})]}):C}],399536);var u=e.i(463059);e.s(["IdentityCell",0,function({title:e,subtitle:a,badge:n,onClick:r,className:o,titleClassName:l}){let s=(0,t.jsxs)("div",{className:"flex min-w-0 flex-col gap-0.5",children:[(0,t.jsx)("span",{className:(0,i.cn)("truncate text-sm font-medium text-foreground",l),children:e}),(null!=a&&""!==a||null!=n)&&(0,t.jsxs)("span",{className:"flex min-w-0 items-center gap-2",children:[null!=a&&""!==a&&(0,t.jsx)("span",{className:"truncate font-mono text-xs text-muted-foreground",children:a}),n]})]});return null!=r?(0,t.jsxs)("button",{type:"button",onClick:r,className:(0,i.cn)("group -mx-2 flex w-[calc(100%+1rem)] cursor-pointer items-center gap-2 rounded-md px-2 py-1 text-left transition-colors hover:bg-muted",o),children:[s,(0,t.jsx)(u.ChevronRight,{className:"ml-auto size-4 shrink-0 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100"})]}):(0,t.jsx)("div",{className:(0,i.cn)("min-w-0",o),children:s})}],997422);let d={hasModelAccess:!1,label:"Management"},c={hasModelAccess:!1,label:"Read-only"},p={hasModelAccess:!1,label:"SCIM"},g={hasModelAccess:!0,label:null},m=e=>e.startsWith("/scim"),f=(e,t)=>1===e.length&&e[0]===t;e.s(["deriveKeyModelScope",0,(e,t)=>"management"===t?d:"read_only"===t?c:Array.isArray(e)&&0!==e.length?e.every(m)?p:f(e,"management_routes")?d:f(e,"info_routes")?c:g:g],146512)},355619,e=>{"use strict";var t=e.i(602869);let a=async(e,a,n)=>{try{if(null===e||null===a)return;if(null!==n){let r=(await (0,t.modelAvailableCall)(n,e,a,!0,null,!0)).data.map(e=>e.id),o=[],i=[];return r.forEach(e=>{e.endsWith("/*")?o.push(e):i.push(e)}),[...o,...i]}}catch(e){console.error("Error fetching user models:",e)}};e.s(["excludeProxyWideSentinel",0,e=>e.filter(e=>"all-proxy-models"!==e),"fetchAvailableModelsForTeamOrKey",0,a,"getModelDisplayName",0,e=>{if("all-proxy-models"===e)return"All Proxy Models";if(e.endsWith("/*")){let t=e.replace("/*","");return`All ${t} models`}return e},"hasAllModelsSentinel",0,e=>e.includes("all-proxy-models")||e.includes("all-team-models"),"unfurlWildcardModelsInList",0,(e,t)=>{let a=[],n=[];return e.forEach(e=>{if(e.endsWith("/*")){let r=e.replace("/*",""),o=t.filter(e=>e.startsWith(r+"/"));n.push(...o),a.push(e)}else n.push(e)}),[...a,...n].filter((e,t,a)=>a.indexOf(e)===t)}])},622826,547227,964471,630500,e=>{"use strict";var t=e.i(581070);e.i(200208),e.i(399536),e.i(997422);var a=e.i(843476),n=e.i(146512),r=e.i(355619),o=e.i(487486);let i="all-proxy-models",l=e=>{if(e===i)return"All Proxy Models";let t=(0,r.getModelDisplayName)(e);return t.length>30?`${t.slice(0,30)}...`:t};e.s(["ModelsCell",0,function({models:e,maxVisible:r=3,allowedRoutes:s,keyType:u}){if(!Array.isArray(e)||0===e.length){let e=(0,n.deriveKeyModelScope)(s,u);return e.hasModelAccess?(0,a.jsx)(o.Badge,{variant:"secondary",children:"All Proxy Models"}):(0,a.jsx)(t.CellTooltip,{content:`Scoped to ${e.label} routes; this key cannot call any models`,trigger:(0,a.jsx)(o.Badge,{variant:"secondary",className:"cursor-default",children:"No model access"})})}let d=e.slice(0,r),c=e.slice(r);return(0,a.jsxs)("div",{className:"flex flex-wrap items-center gap-1",children:[d.map((e,t)=>(0,a.jsx)(o.Badge,{variant:e===i?"secondary":"outline",children:l(e)},t)),c.length>0&&(0,a.jsx)(t.CellTooltip,{content:(0,a.jsx)("div",{className:"flex max-w-[280px] flex-col gap-0.5",children:c.map((e,t)=>(0,a.jsx)("span",{children:l(e)},t))}),trigger:(0,a.jsxs)(o.Badge,{variant:"outline",className:"cursor-default",children:["+",c.length," more"]})})]})}],547227);var s=e.i(500330);e.s(["MoneyCell",0,function({value:e,decimals:t=4,emptyText:n="-",showZero:r=!1}){return null==e||Number.isNaN(e)?(0,a.jsx)("span",{className:"text-muted-foreground",children:n}):0===e?r?(0,a.jsx)("span",{className:"whitespace-nowrap",children:`$${(0,s.formatNumberWithCommas)(0,t,!1,!0)}`}):(0,a.jsx)("span",{className:"text-muted-foreground",children:"-"}):(0,a.jsx)("span",{className:"whitespace-nowrap",children:(0,s.getSpendString)(e,t)})}],964471);var u=e.i(944835);e.s(["SpendBudgetCell",0,function({spend:e,maxBudget:t,teamMaxBudget:n}){let r="number"!=typeof e||Number.isNaN(e)?0:e,o=t??n??null,i=null==t&&null!=n,l="number"==typeof o&&o>0,d=l?r/o*100:0,c=r>0?(0,s.getSpendString)(r,4):"$0.00",p=null===o?"· Unlimited":`of $${(0,s.formatNumberWithCommas)(o)}${i?" (Team)":""}`;return(0,a.jsxs)("div",{className:"flex min-w-[130px] flex-col gap-1",children:[(0,a.jsxs)("div",{className:"whitespace-nowrap text-xs",children:[(0,a.jsx)("span",{className:"font-medium tabular-nums text-foreground",children:c})," ",(0,a.jsx)("span",{className:"text-muted-foreground",children:p})]}),l&&(0,a.jsx)(u.Meter,{value:r,max:o,"aria-valuetext":`${c} of $${(0,s.formatNumberWithCommas)(o)}`,children:(0,a.jsx)(u.MeterTrack,{children:(0,a.jsx)(u.MeterIndicator,{tone:d>100?"over":d>=80?"warning":"default"})})})]})}],630500),e.i(112179),e.s([],622826)},841947,e=>{"use strict";let t=(0,e.i(475254).default)("x",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]);e.s(["default",0,t])},37727,e=>{"use strict";var t=e.i(841947);e.s(["X",()=>t.default])},409797,e=>{"use strict";var t=e.i(631171);e.s(["ChevronDownIcon",()=>t.default])},233565,e=>{"use strict";var t=e.i(246349);e.s(["ChevronRightIcon",()=>t.default])},678784,e=>{"use strict";var t=e.i(678745);e.s(["CheckIcon",()=>t.default])},590803,e=>{"use strict";e.s(["isElementDisabled",0,function(e){return null==e||e.hasAttribute("disabled")||"true"===e.getAttribute("aria-disabled")}])},545356,e=>{"use strict";var t=e.i(271645);let a=t.createContext({register:()=>{},unregister:()=>{},subscribeMapChange:()=>()=>{},elementsRef:{current:[]},nextIndexRef:{current:0}});e.s(["CompositeListContext",0,a,"useCompositeListContext",0,function(){return t.useContext(a)}])},53687,e=>{"use strict";var t=e.i(271645),a=e.i(921374),n=e.i(667865),r=e.i(146376),o=e.i(545356),i=e.i(843476);function l(){return new Map}function s(){return new Set}function u(e,t){let a=e.compareDocumentPosition(t);return a&Node.DOCUMENT_POSITION_FOLLOWING||a&Node.DOCUMENT_POSITION_CONTAINED_BY?-1:a&Node.DOCUMENT_POSITION_PRECEDING||a&Node.DOCUMENT_POSITION_CONTAINS?1:0}e.s(["CompositeList",0,function(e){let{children:d,elementsRef:c,labelsRef:p,onMapChange:g}=e,m=(0,n.useStableCallback)(g),f=t.useRef(0),b=(0,a.useRefWithInit)(s).current,h=(0,a.useRefWithInit)(l).current,[x,C]=t.useState(0),v=t.useRef(x),y=(0,n.useStableCallback)((e,t)=>{h.set(e,t??null),v.current+=1,C(v.current)}),S=(0,n.useStableCallback)(e=>{h.delete(e),v.current+=1,C(v.current)}),O=t.useMemo(()=>{let e=new Map;return Array.from(h.keys()).filter(e=>e.isConnected).sort(u).forEach((t,a)=>{let n=h.get(t)??{};e.set(t,{...n,index:a})}),e},[h,x]);(0,r.useIsoLayoutEffect)(()=>{if("function"!=typeof MutationObserver||0===O.size)return;let e=new MutationObserver(e=>{let t=new Set,a=e=>t.has(e)?t.delete(e):t.add(e);e.forEach(e=>{e.removedNodes.forEach(a),e.addedNodes.forEach(a)}),0===t.size&&(v.current+=1,C(v.current))});return O.forEach((t,a)=>{a.parentElement&&e.observe(a.parentElement,{childList:!0})}),()=>{e.disconnect()}},[O]),(0,r.useIsoLayoutEffect)(()=>{v.current===x&&(c.current.length!==O.size&&(c.current.length=O.size),p&&p.current.length!==O.size&&(p.current.length=O.size),f.current=O.size),m(O)},[m,O,c,p,x]),(0,r.useIsoLayoutEffect)(()=>()=>{c.current=[]},[c]),(0,r.useIsoLayoutEffect)(()=>()=>{p&&(p.current=[])},[p]);let D=(0,n.useStableCallback)(e=>(b.add(e),()=>{b.delete(e)}));(0,r.useIsoLayoutEffect)(()=>{b.forEach(e=>e(O))},[b,O]);let w=t.useMemo(()=>({register:y,unregister:S,subscribeMapChange:D,elementsRef:c,labelsRef:p,nextIndexRef:f}),[y,S,D,c,p,f]);return(0,i.jsx)(o.CompositeListContext.Provider,{value:w,children:d})}])},673553,e=>{"use strict";var t,a=e.i(271645),n=e.i(146376),r=e.i(545356);let o=((t={})[t.None=0]="None",t[t.GuessFromOrder=1]="GuessFromOrder",t);e.s(["IndexGuessBehavior",0,o,"useCompositeListItem",0,function(e={}){let{label:t,metadata:i,textRef:l,indexGuessBehavior:s,index:u}=e,{register:d,unregister:c,subscribeMapChange:p,elementsRef:g,labelsRef:m,nextIndexRef:f}=(0,r.useCompositeListContext)(),b=a.useRef(-1),[h,x]=a.useState(u??(s===o.GuessFromOrder?()=>{if(-1===b.current){let e=f.current;f.current+=1,b.current=e}return b.current}:-1)),C=a.useRef(null),v=a.useCallback(e=>{if(C.current=e,-1!==h&&null!==e&&(g.current[h]=e,m)){let a=void 0!==t;m.current[h]=a?t:l?.current?.textContent??e.textContent}},[h,g,m,t,l]);return(0,n.useIsoLayoutEffect)(()=>{if(null!=u)return;let e=C.current;if(e)return d(e,i),()=>{c(e)}},[u,d,c,i]),(0,n.useIsoLayoutEffect)(()=>{if(null==u)return p(e=>{let t=C.current?e.get(C.current)?.index:null;null!=t&&x(t)})},[u,p,x]),{ref:v,index:h}}])},395530,e=>{"use strict";var t=e.i(271645),a=e.i(828918),n=e.i(838452),r=e.i(673553);e.s(["useCompositeItem",0,function(e={}){let{highlightItemOnHover:o,highlightedIndex:i,onHighlightedIndexChange:l}=(0,n.useCompositeRootContext)(),{ref:s,index:u}=(0,r.useCompositeListItem)(e),d=i===u,c=t.useRef(null),p=(0,a.useMergedRefs)(s,c);return{compositeProps:{tabIndex:d?0:-1,onFocus(){l(u)},onMouseMove(){let e=c.current;if(!o||!e)return;let t=e.hasAttribute("disabled")||"true"===e.ariaDisabled;d||t||e.focus()}},compositeRef:p,index:u}}])},784774,e=>{"use strict";var t=e.i(843476),a=e.i(271645),n=e.i(115504);let r=a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("div",{"data-slot":"table-container",className:"relative w-full overflow-x-auto",children:(0,t.jsx)("table",{ref:r,"data-slot":"table",className:(0,n.cn)("w-full caption-bottom text-sm",e),...a})}));r.displayName="Table";let o=a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("thead",{ref:r,"data-slot":"table-header",className:(0,n.cn)("[&_tr]:border-b",e),...a}));o.displayName="TableHeader";let i=a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("tbody",{ref:r,"data-slot":"table-body",className:(0,n.cn)("[&_tr:last-child]:border-0",e),...a}));i.displayName="TableBody";let l=a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("tfoot",{ref:r,"data-slot":"table-footer",className:(0,n.cn)("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",e),...a}));l.displayName="TableFooter";let s=a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("tr",{ref:r,"data-slot":"table-row",className:(0,n.cn)("border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",e),...a}));s.displayName="TableRow";let u=a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("th",{ref:r,"data-slot":"table-head",className:(0,n.cn)("h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",e),...a}));u.displayName="TableHead";let d=a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("td",{ref:r,"data-slot":"table-cell",className:(0,n.cn)("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",e),...a}));d.displayName="TableCell",a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("caption",{ref:r,"data-slot":"table-caption",className:(0,n.cn)("mt-4 text-sm text-muted-foreground",e),...a})).displayName="TableCaption",e.s(["Table",0,r,"TableBody",0,i,"TableCell",0,d,"TableFooter",0,l,"TableHead",0,u,"TableHeader",0,o,"TableRow",0,s])},302747,e=>{"use strict";var t=e.i(843476),a=e.i(271645),n=e.i(115504);let r=a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("div",{ref:r,"data-slot":"skeleton",className:(0,n.cn)("animate-pulse rounded-md bg-accent",e),...a}));r.displayName="Skeleton",e.s(["Skeleton",0,r])},108821,e=>{"use strict";var t=e.i(733332),a=e.i(271645);let n=a.createContext(!1),r=a.createContext(void 0);e.s(["DialogRootContext",0,r,"IsDrawerContext",0,n,"useDialogRootContext",0,function(e){let n=a.useContext(r);if(!1===e&&void 0===n)throw Error((0,t.default)(27));return n}])},402820,156736,209793,625834,784324,264951,e=>{"use strict";e.i(247167);var t,a,n=e.i(271645),r=e.i(108821),o=e.i(552245),i=e.i(405005),l=e.i(209407);let s={...i.popupStateMapping,...l.transitionStatusMapping},u=n.forwardRef(function(e,t){let{render:a,className:n,style:i,forceRender:l=!1,...u}=e,{store:d}=(0,r.useDialogRootContext)(),c=d.useState("open"),p=d.useState("nested"),g=d.useState("mounted"),m=d.useState("transitionStatus");return(0,o.useRenderElement)("div",e,{state:{open:c,transitionStatus:m},ref:[d.context.backdropRef,t],stateAttributesMapping:s,props:[{role:"presentation",hidden:!g,style:{userSelect:"none",WebkitUserSelect:"none"}},u],enabled:l||!p})});e.s(["DialogBackdrop",0,u],402820);var d=e.i(540886),c=e.i(675606),p=e.i(56434);let g=n.forwardRef(function(e,t){let{render:a,className:n,style:i,disabled:l=!1,nativeButton:s=!0,...u}=e,{store:g}=(0,r.useDialogRootContext)(),m=g.useState("open"),{getButtonProps:f,buttonRef:b}=(0,d.useButton)({disabled:l,native:s});return(0,o.useRenderElement)("button",e,{state:{disabled:l},ref:[t,b],props:[{onClick:function(e){m&&g.setOpen(!1,(0,c.createChangeEventDetails)(p.REASONS.closePress,e.nativeEvent))}},u,f]})});e.s(["DialogClose",0,g],156736);var m=e.i(788015);let f=n.forwardRef(function(e,t){let{render:a,className:n,style:i,id:l,...s}=e,{store:u}=(0,r.useDialogRootContext)(),d=(0,m.useBaseUiId)(l);return u.useSyncedValueWithCleanup("descriptionElementId",d),(0,o.useRenderElement)("p",e,{ref:t,props:[{id:d},s]})});e.s(["DialogDescription",0,f],209793);var b=e.i(61487);let h=((t={}).nestedDialogs="--nested-dialogs",t),x=((a={})[a.open=i.CommonPopupDataAttributes.open]="open",a[a.closed=i.CommonPopupDataAttributes.closed]="closed",a[a.startingStyle=i.CommonPopupDataAttributes.startingStyle]="startingStyle",a[a.endingStyle=i.CommonPopupDataAttributes.endingStyle]="endingStyle",a.nested="data-nested",a.nestedDialogOpen="data-nested-dialog-open",a);var C=e.i(733332);let v=n.createContext(void 0);function y(){let e=n.useContext(v);if(void 0===e)throw Error((0,C.default)(26));return e}e.s(["DialogPortalContext",0,v,"useDialogPortalContext",0,y],625834);var S=e.i(137584),O=e.i(673327),D=e.i(264111),w=e.i(843476);let N={...i.popupStateMapping,...l.transitionStatusMapping,nestedDialogOpen:e=>e?{[x.nestedDialogOpen]:""}:null},$=n.forwardRef(function(e,t){let{render:a,className:n,style:i,finalFocus:l,initialFocus:s,...u}=e,{store:d}=(0,r.useDialogRootContext)(),c=d.useState("descriptionElementId"),p=d.useState("disablePointerDismissal"),g=d.useState("floatingRootContext"),m=d.useState("popupProps"),f=d.useState("modal"),x=d.useState("mounted"),C=d.useState("nested"),v=d.useState("nestedOpenDialogCount"),$=d.useState("open"),R=d.useState("openMethod"),j=d.useState("titleElementId"),E=d.useState("transitionStatus"),k=d.useState("role"),I=g.useState("floatingId"),T=u.id??I;y(),(0,S.useOpenChangeComplete)({open:$,ref:d.context.popupRef,onComplete(){$&&d.context.onOpenChangeComplete?.(!0)}});let M=void 0===s?(0,D.createDefaultInitialFocus)(d.context.popupRef):s,P=d.useStateSetter("popupElement"),A=(0,o.useRenderElement)("div",e,{state:{open:$,nested:C,transitionStatus:E,nestedDialogOpen:v>0},props:[m,{id:T,"aria-labelledby":j??void 0,"aria-describedby":c??void 0,role:k,...D.FOCUSABLE_POPUP_PROPS,hidden:!x,onKeyDown(e){O.COMPOSITE_KEYS.has(e.key)&&e.stopPropagation()},style:{[h.nestedDialogs]:v}},u],ref:[t,d.context.popupRef,P],stateAttributesMapping:N});return(0,w.jsx)(b.FloatingFocusManager,{context:g,openInteractionType:R,disabled:!x,closeOnFocusOut:!p,initialFocus:M,returnFocus:l,modal:!1!==f,restoreFocus:"popup",children:A})});e.s(["DialogPopup",0,$],784324);var R=e.i(144394),j=e.i(726674),E=e.i(426);let k=n.forwardRef(function(e,t){let{keepMounted:a=!1,...n}=e,{store:o}=(0,r.useDialogRootContext)(),i=o.useState("mounted"),l=o.useState("modal"),s=o.useState("open");return i||a?(0,w.jsx)(v.Provider,{value:a,children:(0,w.jsxs)(j.FloatingPortal,{ref:t,...n,children:[i&&!0===l&&(0,w.jsx)(E.InternalBackdrop,{ref:o.context.internalBackdropRef,inert:(0,R.inertValue)(!s)}),e.children]})}):null});e.s(["DialogPortal",0,k],264951)},67530,e=>{"use strict";var t=e.i(271645),a=e.i(145484),n=e.i(956789),r=e.i(17989),o=e.i(647554),i=e.i(675606),l=e.i(56434),s=e.i(264111);e.s(["DialogInteractions",0,function({store:e,parentContext:i,isDrawer:l}){let u=e.useState("open"),d=e.useState("disablePointerDismissal"),c=e.useState("modal"),p=e.useState("popupElement"),g=e.useState("floatingRootContext"),[m,f]=t.useState(0),[b,h]=t.useState(0),x=0===m,C=(0,r.useDismiss)(g,{outsidePressEvent:()=>e.context.internalBackdropRef.current||e.context.backdropRef.current?"intentional":{mouse:"trap-focus"===c?"sloppy":"intentional",touch:"sloppy"},outsidePress(t){if(!e.context.outsidePressEnabledRef.current||"button"in t&&0!==t.button||"touches"in t&&1!==t.touches.length)return!1;let a=(0,o.getTarget)(t);return!!x&&!d&&(!c||!e.context.internalBackdropRef.current&&!e.context.backdropRef.current||e.context.internalBackdropRef.current===a||e.context.backdropRef.current===a||(0,o.contains)(a,p)&&!a?.hasAttribute("data-base-ui-portal"))},escapeKey:x});(0,a.useScrollLock)(u&&!0===c,p),e.useContextCallback("onNestedDialogOpen",(e,t)=>{f(e),h(t)}),e.useContextCallback("onNestedDialogClose",()=>{f(0),h(0)}),t.useEffect(()=>(i?.onNestedDialogOpen&&u&&i.onNestedDialogOpen(m+1,b+ +!!l),i?.onNestedDialogClose&&!u&&i.onNestedDialogClose(),()=>{i?.onNestedDialogClose&&u&&i.onNestedDialogClose()}),[l,u,m,b,i]);let v=C.reference??n.EMPTY_OBJECT,y=C.trigger??n.EMPTY_OBJECT,S=C.floating??n.EMPTY_OBJECT;return(0,s.usePopupInteractionProps)(e,{activeTriggerProps:v,inactiveTriggerProps:y,popupProps:S,nestedOpenDialogCount:m,nestedOpenDrawerCount:b}),null},"useDialogRoot",0,function(e){let{store:a,actionsRef:n}=e,r=a.useState("open");(0,s.usePopupRootSync)(a,r),(0,s.useImplicitActiveTrigger)(a);let{forceUnmount:o}=(0,s.useOpenStateTransitions)(r,a),u=t.useCallback(()=>{a.setOpen(!1,(0,i.createChangeEventDetails)(l.REASONS.imperativeAction))},[a]);t.useImperativeHandle(n,()=>({unmount:o,close:u}),[o,u])}])},366250,301807,e=>{"use strict";var t=e.i(271645),a=e.i(713203),n=e.i(67530),r=e.i(108821),o=e.i(616269),i=e.i(301252),l=e.i(116786),s=e.i(990627),u=e.i(264111);let d={...l.popupStoreSelectors,modal:(0,o.createSelector)(e=>e.modal),nested:(0,o.createSelector)(e=>e.nested),nestedOpenDialogCount:(0,o.createSelector)(e=>e.nestedOpenDialogCount),nestedOpenDrawerCount:(0,o.createSelector)(e=>e.nestedOpenDrawerCount),disablePointerDismissal:(0,o.createSelector)(e=>e.disablePointerDismissal),openMethod:(0,o.createSelector)(e=>e.openMethod),descriptionElementId:(0,o.createSelector)(e=>e.descriptionElementId),titleElementId:(0,o.createSelector)(e=>e.titleElementId),viewportElement:(0,o.createSelector)(e=>e.viewportElement),role:(0,o.createSelector)(e=>e.role)};class c extends i.ReactStore{constructor(e,a,n=!1){const r=new s.PopupTriggerMap,o=function(e={}){return{...(0,l.createInitialPopupStoreState)(),modal:!0,disablePointerDismissal:!1,popupElement:null,viewportElement:null,descriptionElementId:void 0,titleElementId:void 0,openMethod:null,nested:!1,nestedOpenDialogCount:0,nestedOpenDrawerCount:0,role:"dialog",...e}}(e);o.floatingRootContext=(0,l.createPopupFloatingRootContext)(r,a,n),super(o,{popupRef:t.createRef(),backdropRef:t.createRef(),internalBackdropRef:t.createRef(),outsidePressEnabledRef:{current:!0},triggerElements:r,onOpenChange:void 0,onOpenChangeComplete:void 0},d)}setOpen=(e,t)=>{if(t.preventUnmountOnClose=()=>{this.set("preventUnmountingOnClose",!0)},e||null!=t.trigger||null==this.state.activeTriggerId||(t.trigger=this.state.activeTriggerElement??void 0),this.context.onOpenChange?.(e,t),t.isCanceled)return;this.state.floatingRootContext.dispatchOpenChange(e,t);let a={open:e};(0,u.setPopupOpenState)(a,e,t.trigger),this.update(a)};static useStore(e,t){return(0,u.usePopupStore)(e,(e,a)=>new c(t,e,a),!0).store}}e.s(["DialogStore",0,c],301807);var p=e.i(843476);e.s(["useRenderDialogRoot",0,function(e,o="dialog"){let{children:i,open:l,defaultOpen:s=!1,onOpenChange:u,onOpenChangeComplete:d,disablePointerDismissal:g=!1,modal:m=!0,actionsRef:f,handle:b,triggerId:h,defaultTriggerId:x=null}=e,C="alert-dialog"===o,v=(0,r.useDialogRootContext)(!0),y={modal:!!C||m,disablePointerDismissal:C||g,nested:!!v,role:C?"alertdialog":"dialog"},S=c.useStore(b?.store,{open:s,openProp:l,activeTriggerId:x,triggerIdProp:h,...y});(0,a.useOnFirstRender)(()=>{let e=void 0===l&&!1===S.state.open&&!0===s?{open:!0,activeTriggerId:x}:null;C?S.update(e?{...y,...e}:y):e&&S.update(e)}),S.useControlledProp("openProp",l),S.useControlledProp("triggerIdProp",h),S.useSyncedValues(y),S.useContextCallback("onOpenChange",u),S.useContextCallback("onOpenChangeComplete",d);let O=S.useState("open"),D=S.useState("mounted"),w=S.useState("payload");(0,n.useDialogRoot)({store:S,actionsRef:f});let N=t.useMemo(()=>({store:S}),[S]);return(0,p.jsx)(r.IsDrawerContext.Provider,{value:!1,children:(0,p.jsxs)(r.DialogRootContext.Provider,{value:N,children:[(O||D)&&(0,p.jsx)(n.DialogInteractions,{store:S,parentContext:v?.store.context,isDrawer:"drawer"===o}),"function"==typeof i?i({payload:w}):i]})})}],366250)},974217,e=>{"use strict";e.i(247167);var t,a=e.i(271645),n=e.i(552245),r=e.i(405005),o=e.i(209407),i=e.i(108821),l=e.i(625834);let s=((t={})[t.open=r.CommonPopupDataAttributes.open]="open",t[t.closed=r.CommonPopupDataAttributes.closed]="closed",t[t.startingStyle=r.CommonPopupDataAttributes.startingStyle]="startingStyle",t[t.endingStyle=r.CommonPopupDataAttributes.endingStyle]="endingStyle",t.nested="data-nested",t.nestedDialogOpen="data-nested-dialog-open",t),u={...r.popupStateMapping,...o.transitionStatusMapping,nested:e=>e?{[s.nested]:""}:null,nestedDialogOpen:e=>e?{[s.nestedDialogOpen]:""}:null},d=a.forwardRef(function(e,t){let{render:a,className:r,style:o,children:s,...d}=e,c=(0,l.useDialogPortalContext)(),{store:p}=(0,i.useDialogRootContext)(),g=p.useState("open"),m=p.useState("nested"),f=p.useState("transitionStatus"),b=p.useState("nestedOpenDialogCount"),h=p.useState("mounted"),x=p.useStateSetter("viewportElement");return(0,n.useRenderElement)("div",e,{enabled:c||h,state:{open:g,nested:m,transitionStatus:f,nestedDialogOpen:b>0},ref:[t,x],stateAttributesMapping:u,props:[{role:"presentation",hidden:!h,style:{pointerEvents:g?void 0:"none"},children:s},d]})});e.s(["DialogViewport",0,d],974217)},77173,313488,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(108821),n=e.i(552245),r=e.i(788015);let o=t.forwardRef(function(e,t){let{render:o,className:i,style:l,id:s,...u}=e,{store:d}=(0,a.useDialogRootContext)(),c=(0,r.useBaseUiId)(s);return d.useSyncedValueWithCleanup("titleElementId",c),(0,n.useRenderElement)("h2",e,{ref:t,props:[{id:c},u]})});e.s(["DialogTitle",0,o],77173);var i=e.i(733332),l=e.i(540886),s=e.i(405005),u=e.i(638396),d=e.i(264111),c=e.i(385689),p=e.i(32199);let g=t.forwardRef(function(e,o){let{render:g,className:m,style:f,disabled:b=!1,nativeButton:h=!0,id:x,payload:C,handle:v,...y}=e,S=(0,a.useDialogRootContext)(!0),O=v?.store??S?.store;if(!O)throw Error((0,i.default)(79));let D=(0,r.useBaseUiId)(x),w=O.useState("floatingRootContext"),N=O.useState("isOpenedByTrigger",D),$=O.useState("triggerPopupId",D),R=t.useRef(null),{registerTrigger:j,isMountedByThisTrigger:E}=(0,d.useTriggerDataForwarding)(D,R,O,{payload:C}),{getButtonProps:k,buttonRef:I}=(0,l.useButton)({disabled:b,native:h}),T=(0,c.useClick)(w,{enabled:null!=w}),M=(0,p.useOpenMethodTriggerProps)(()=>O.select("open"),e=>{O.set("openMethod",e)}),P=O.useState("triggerProps",E);return(0,n.useRenderElement)("button",e,{state:{disabled:b,open:N},ref:[I,o,j,R],props:[T.reference,P,M,{[u.CLICK_TRIGGER_IDENTIFIER]:"",id:D,"aria-haspopup":"dialog","aria-expanded":N,"aria-controls":$},y,k],stateAttributesMapping:s.triggerOpenStateMapping})});e.s(["DialogTrigger",0,g],313488)},325326,e=>{"use strict";var t=e.i(301807),a=e.i(675606),n=e.i(56434);class r{constructor(e){this.store=e??new t.DialogStore}open(e){let t=e?this.store.context.triggerElements.getById(e):void 0;this.store.setOpen(!0,(0,a.createChangeEventDetails)(n.REASONS.imperativeAction,void 0,t))}openWithPayload(e){this.store.set("payload",e),this.store.setOpen(!0,(0,a.createChangeEventDetails)(n.REASONS.imperativeAction,void 0,void 0))}close(){this.store.setOpen(!1,(0,a.createChangeEventDetails)(n.REASONS.imperativeAction,void 0,void 0))}get isOpen(){return this.store.select("open")}}e.s(["DialogHandle",0,r,"createDialogHandle",0,function(){return new r}])},793479,e=>{"use strict";var t=e.i(843476),a=e.i(271645),n=e.i(115504);let r=a.forwardRef(({className:e,type:a,...r},o)=>(0,t.jsx)("input",{type:a,"data-slot":"input",className:(0,n.cn)("h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30","focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50","aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40",e),ref:o,...r}));r.displayName="Input",e.s(["Input",0,r])},995926,e=>{"use strict";var t=e.i(841947);e.s(["XIcon",()=>t.default])},353753,e=>{"use strict";e.s([],914651),e.i(914651);var t=e.i(402820),a=e.i(156736),n=e.i(209793),r=e.i(784324),o=e.i(264951),i=e.i(271645),l=e.i(108821),s=e.i(366250),u=e.i(974217),d=e.i(77173),c=e.i(313488),p=e.i(325326);e.s(["Backdrop",()=>t.DialogBackdrop,"Close",()=>a.DialogClose,"Description",()=>n.DialogDescription,"Handle",()=>p.DialogHandle,"Popup",()=>r.DialogPopup,"Portal",()=>o.DialogPortal,"Root",0,function(e){let t=i.useContext(l.IsDrawerContext)?"drawer":"dialog";return(0,s.useRenderDialogRoot)(e,t)},"Title",()=>d.DialogTitle,"Trigger",()=>c.DialogTrigger,"Viewport",()=>u.DialogViewport,"createHandle",()=>p.createDialogHandle],828376);var g=e.i(828376);e.s(["Dialog",0,g],353753)},110204,e=>{"use strict";var t=e.i(843476),a=e.i(271645),n=e.i(115504);let r=a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("label",{ref:r,"data-slot":"label",className:(0,n.cn)("flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",e),...a}));r.displayName="Label",e.s(["Label",0,r])},16715,e=>{"use strict";let t=(0,e.i(475254).default)("refresh-cw",[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]]);e.s(["RefreshCw",0,t],16715)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/00g6xfr4yow7h.js b/litellm/proxy/_experimental/out/_next/static/chunks/00g6xfr4yow7h.js new file mode 100644 index 00000000000..248cab25929 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/00g6xfr4yow7h.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,263005,e=>{"use strict";var t=e.i(843476);e.s(["PageHeader",0,function({title:e,subtitle:a,icon:l,actions:i}){return(0,t.jsxs)("div",{className:"flex flex-wrap items-start justify-between gap-4",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2.5",children:[null!=l&&(0,t.jsx)("span",{className:"flex flex-none items-center text-foreground",children:l}),(0,t.jsxs)("div",{className:"min-w-0",children:[(0,t.jsx)("h1",{className:"text-xl font-semibold tracking-tight text-foreground",children:e}),null!=a&&(0,t.jsx)("p",{className:"mt-0.5 text-sm text-muted-foreground",children:a})]})]}),null!=i&&(0,t.jsx)("div",{className:"flex items-center gap-2",children:i})]})}])},655063,e=>{"use strict";var t=e.i(399029),a=e.i(271645);e.s(["useDebouncedValue",0,function(e,l,i){let[r,s,n]=(0,t.useDebouncedState)(e,l,i);return(0,a.useEffect)(()=>{s(e)},[e,s]),[r,n]}])},624687,e=>{"use strict";var t=e.i(843476),a=e.i(271645),l=e.i(115504);let i=a.forwardRef(({className:e,...a},i)=>(0,t.jsx)("textarea",{ref:i,"data-slot":"textarea",className:(0,l.cn)("flex field-sizing-content min-h-16 w-full rounded-md border border-input bg-transparent px-2.5 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",e),...a}));i.displayName="Textarea",e.s(["Textarea",0,i])},950594,e=>{"use strict";var t=e.i(843476),a=e.i(271645),l=e.i(115504),i=e.i(519455),r=e.i(793479),s=e.i(624687);let n=(0,l.cva)({base:"flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4",variants:{align:{"inline-start":"order-first pl-2 has-[>button]:-ml-1 has-[>kbd]:ml-[-0.15rem]","inline-end":"order-last pr-2 has-[>button]:-mr-1 has-[>kbd]:mr-[-0.15rem]","block-start":"order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2","block-end":"order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2"}},defaultVariants:{align:"inline-start"}}),o=(0,l.cva)({base:"flex items-center gap-2 text-sm shadow-none",variants:{size:{xs:"h-6 gap-1 rounded-[calc(var(--radius)-5px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5",sm:"","icon-xs":"size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0","icon-sm":"size-8 p-0 has-[>svg]:p-0"}},defaultVariants:{size:"xs"}}),d=a.forwardRef(({className:e,type:a="button",variant:r="ghost",size:s="xs",...n},d)=>(0,t.jsx)(i.Button,{ref:d,type:a,"data-size":s,variant:r,className:(0,l.cn)(o({size:s}),e),...n}));d.displayName="InputGroupButton";let u=a.forwardRef(({className:e,...a},i)=>(0,t.jsx)(r.Input,{ref:i,"data-slot":"input-group-control",className:(0,l.cn)("flex-1 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent",e),...a}));u.displayName="InputGroupInput",a.forwardRef(({className:e,...a},i)=>(0,t.jsx)(s.Textarea,{ref:i,"data-slot":"input-group-control",className:(0,l.cn)("flex-1 resize-none rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent",e),...a})).displayName="InputGroupTextarea",e.s(["InputGroup",0,function({className:e,...a}){return(0,t.jsx)("div",{"data-slot":"input-group",role:"group",className:(0,l.cn)("group/input-group relative flex h-9 w-full min-w-0 items-center rounded-md border border-input shadow-xs transition-[color,box-shadow] outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5",e),...a})},"InputGroupAddon",0,function({className:e,align:a="inline-start",...i}){return(0,t.jsx)("div",{role:"group","data-slot":"input-group-addon","data-align":a,className:(0,l.cn)(n({align:a}),e),onClick:e=>{e.target.closest("button")||e.currentTarget.parentElement?.querySelector("input")?.focus()},...i})},"InputGroupButton",0,d,"InputGroupInput",0,u,"InputGroupText",0,function({className:e,...a}){return(0,t.jsx)("span",{className:(0,l.cn)("flex items-center gap-2 text-sm text-muted-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",e),...a})}])},552546,e=>{"use strict";var t=e.i(843476),a=e.i(131792);let l=(e,t)=>{let a=t.trim().toLowerCase();return!a||e.label.toLowerCase().includes(a)||(e.sublabel?.toLowerCase().includes(a)??!1)};e.s(["SearchSelect",0,function({options:e,value:i,onValueChange:r,placeholder:s="Select…",emptyText:n="No results",disabled:o=!1,className:d}){let u=e.find(e=>e.value===i)??null;return(0,t.jsxs)(a.Combobox,{items:e,value:u,onValueChange:e=>r(e?.value??""),isItemEqualToValue:(e,t)=>e.value===t.value,itemToStringLabel:e=>e.label,filter:l,disabled:o,children:[(0,t.jsx)(a.ComboboxInput,{placeholder:s,showClear:null!=i&&""!==i,className:`w-full ${d??""}`}),(0,t.jsxs)(a.ComboboxContent,{children:[(0,t.jsx)(a.ComboboxEmpty,{children:n}),(0,t.jsx)(a.ComboboxList,{children:e=>(0,t.jsx)(a.ComboboxItem,{value:e,children:(0,t.jsxs)("span",{className:"flex min-w-0 flex-col",children:[(0,t.jsx)("span",{className:"truncate",children:e.label}),null!=e.sublabel&&""!==e.sublabel&&(0,t.jsx)("span",{className:"truncate text-xs text-muted-foreground",children:e.sublabel})]})},e.value)})]})]})}])},611363,e=>{"use strict";e.s(["navigateWithParams",0,function(e){let t=new URLSearchParams(window.location.search);e(t);let a=t.toString(),l=a?`${window.location.pathname}?${a}`:window.location.pathname;window.history.pushState(null,"",l)}])},502501,e=>{"use strict";var t=e.i(843476),a=e.i(785242),l=e.i(135214),i=e.i(268004),r=e.i(309426),s=e.i(350967),n=e.i(947293),o=e.i(271645),d=e.i(602869);let u=async(e,t,a,l,i)=>{i("Admin"!=a&&"Admin Viewer"!=a?await (0,d.teamListCall)(e,l?.organization_id||null,t):await (0,d.teamListCall)(e,l?.organization_id||null))};var c=e.i(702597),m=e.i(618566),g=e.i(611363),p=e.i(266027),x=e.i(207082),h=e.i(109799),f=e.i(741466);e.i(707701);var b=e.i(807235),v=e.i(981080),y=e.i(531649),_=e.i(552546),w=e.i(263005),k=e.i(793479),j=e.i(655063),S=e.i(465261),C=e.i(20147),I=e.i(827252),N=e.i(282786),z=e.i(898586),D=e.i(494862),T=e.i(302747);e.i(622826);var U=e.i(200208),E=e.i(399536),A=e.i(997422),R=e.i(547227),K=e.i(630500),V=e.i(112179),M=e.i(304911);let L=[{id:"spend",label:"Spend"},{id:"max_budget",label:"Budget"}],P=({userAlias:e,userEmail:a,userId:l,width:i})=>{let r=e||a||l,s="default_user_id"===l,n=(0,t.jsx)("div",{className:"flex flex-col gap-2 text-xs min-w-[200px] max-w-[300px]",children:[{label:"User Alias",value:e},{label:"User Email",value:a},{label:"User ID",value:l}].map(({label:e,value:a})=>(0,t.jsxs)("div",{className:"flex flex-col min-w-0",children:[(0,t.jsx)("span",{className:"text-gray-400",children:e}),a?(0,t.jsx)(z.Typography.Text,{className:"font-mono text-xs",ellipsis:{tooltip:a},copyable:!0,children:a}):(0,t.jsx)("span",{className:"font-mono",children:"-"})]},e))});return!s||e||a?(0,t.jsx)(N.Popover,{content:n,trigger:"hover",placement:"bottomLeft",children:(0,t.jsx)("span",{className:"font-mono text-xs truncate block cursor-default",style:{maxWidth:i,overflow:"hidden"},children:r||"-"})}):(0,t.jsx)(N.Popover,{content:n,trigger:"hover",placement:"bottomLeft",children:(0,t.jsx)("span",{className:"cursor-default",children:(0,t.jsx)(M.default,{userId:l})})})},B=({label:e,tooltip:a})=>(0,t.jsxs)("span",{className:"flex items-center gap-1",children:[e,(0,t.jsx)(N.Popover,{content:a,trigger:"hover",children:(0,t.jsx)(I.InfoCircleOutlined,{className:"text-gray-400 text-xs cursor-help"})})]}),O={token:!1,organization_alias:!1,created_by:!1,updated_at:!1,expires:!1,rate_limits:!1},F=[{id:"created_at",desc:!0}],G={team_id:"Team",org_id:"Organization",user_id:"User ID",key_hash:"Key ID"};function H({headerActions:e}){let i,r,s,{data:n}=(0,h.useOrganizations)(),u=(0,o.useMemo)(()=>n??[],[n]),{data:c}=(0,a.useAllTeams)(),I=(0,o.useMemo)(()=>c??[],[c]),{keyId:N,openKey:z,close:M}=(i=(0,m.useSearchParams)(),r=(0,o.useCallback)(e=>{(0,g.navigateWithParams)(t=>{t.set("key",e)})},[]),s=(0,o.useCallback)(()=>{(0,g.navigateWithParams)(e=>{e.delete("key")})},[]),{keyId:i?.get("key")??null,openKey:r,close:s}),[W,q]=(0,o.useState)(F),[$,J]=(0,o.useState)({pageIndex:0,pageSize:50}),[Q,X]=(0,o.useState)([]),[Y,Z]=(0,o.useState)(!1),[ee,et]=(0,o.useState)(""),[ea]=(0,j.useDebouncedValue)(ee,{wait:f.DEBOUNCE_WAIT_MS}),el=(0,o.useCallback)(e=>{let t=Q.find(t=>t.id===e);return"string"==typeof t?.value&&t.value.trim()?t.value.trim():void 0},[Q]),ei=W[0]?.id,er=(e=>{let t=e[0];if(t)return t.desc?"desc":"asc"})(W),es={teamID:el("team_id"),organizationID:el("org_id"),selectedKeyAlias:ea.trim()||void 0,userID:el("user_id"),keyHash:el("key_hash"),sortBy:ei,sortOrder:er,expand:"user"},{data:en,isPending:eo,isFetching:ed,refetch:eu}=(0,x.useKeys)($.pageIndex+1,$.pageSize,es),ec=(0,o.useMemo)(()=>en?.keys??[],[en]),em=en?.total_count??0,eg=(0,o.useCallback)(e=>{et(e),J(e=>({...e,pageIndex:0}))},[]),ep=(0,o.useCallback)(e=>{q(e),J(e=>({...e,pageIndex:0}))},[]),ex=(0,o.useCallback)(e=>{X(e),J(e=>({...e,pageIndex:0}))},[]),eh=(0,o.useMemo)(()=>(({allTeams:e,organizations:a,onSelectKey:l})=>[{id:"key_alias",accessorKey:"key_alias",meta:{title:"Key",renderSkeleton:()=>(0,t.jsxs)("div",{className:"flex flex-col gap-1 py-1",children:[(0,t.jsx)(T.Skeleton,{className:"h-4 w-32"}),(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(T.Skeleton,{className:"h-3 w-20"}),(0,t.jsx)(T.Skeleton,{className:"h-5 w-16 rounded-full"})]})]})},header:({column:e})=>(0,t.jsx)(D.DataTableSortHeader,{column:e,title:"Key",variant:"header-cycle"}),size:260,enableSorting:!0,cell:({row:e})=>{let a=(e=>{if(!0===e.blocked)return{tone:"error",label:"Blocked",tooltip:e.metadata?.scim_blocked===!0?"Blocked by SCIM (external identity provider deactivated or deleted the owning user).":"Blocked. Requests using this key will be rejected with 401."};let t=e.expires?Date.parse(e.expires):NaN;return!Number.isNaN(t)&&tl(e.original)})}},{id:"token",accessorKey:"token",meta:{title:"Key ID"},header:({column:e})=>(0,t.jsx)(D.DataTableSortHeader,{column:e,title:"Key ID",variant:"header-cycle"}),size:120,enableSorting:!0,cell:e=>(0,t.jsx)(E.IdCell,{value:e.getValue(),onClick:()=>l(e.row.original)})},{id:"team_alias",accessorKey:"team_id",meta:{title:"Team"},header:"Team",size:120,enableSorting:!1,cell:a=>{let l=a.getValue();if(!l)return"-";let i=e.find(e=>e.team_id===l),r=i?.team_alias||l,s=a.cell.column.getSize();return(0,t.jsx)("span",{className:"font-mono text-xs truncate block",style:{maxWidth:s,overflow:"hidden"},children:r})}},{id:"organization_alias",accessorKey:"org_id",meta:{title:"Organization"},header:"Organization",size:140,enableSorting:!1,cell:e=>{let l=e.getValue();if(!l)return"-";let i=a.find(e=>e.organization_id===l),r=i?.organization_alias||l,s=e.cell.column.getSize();return(0,t.jsx)("span",{className:"font-mono text-xs truncate block",style:{maxWidth:s,overflow:"hidden"},children:r})}},{id:"user",accessorKey:"user",meta:{title:"User"},header:()=>(0,t.jsx)(B,{label:"User",tooltip:"Displays the first available value: User Alias, User Email, or User ID."}),size:160,enableSorting:!1,cell:({row:e})=>{let a=e.original;return(0,t.jsx)(P,{userAlias:a.user?.user_alias??null,userEmail:a.user?.user_email??a.user_email??null,userId:a.user_id??null,width:160})}},{id:"created_at",accessorKey:"created_at",meta:{title:"Created At"},header:({column:e})=>(0,t.jsx)(D.DataTableSortHeader,{column:e,title:"Created At",variant:"header-cycle"}),size:120,enableSorting:!0,cell:e=>(0,t.jsx)(U.DateCell,{value:e.getValue(),precision:"date"})},{id:"created_by",accessorKey:"created_by",meta:{title:"Created By"},header:"Created By",size:160,enableSorting:!1,cell:e=>{let a=e.getValue();if(!a)return"-";let l=e.row.original.created_by_user;return(0,t.jsx)(P,{userAlias:l?.user_alias??null,userEmail:l?.user_email??null,userId:a,width:160})}},{id:"updated_at",accessorKey:"updated_at",meta:{title:"Updated At"},header:({column:e})=>(0,t.jsx)(D.DataTableSortHeader,{column:e,title:"Updated At",variant:"header-cycle"}),size:120,enableSorting:!0,cell:e=>(0,t.jsx)(U.DateCell,{value:e.getValue(),precision:"date",fallback:"Never"})},{id:"last_active",accessorKey:"last_active",meta:{title:"Last Active"},header:()=>(0,t.jsx)(B,{label:"Last Active",tooltip:"This is a new field and is not backfilled. Only new key usage will update this value."}),size:130,enableSorting:!1,cell:e=>(0,t.jsx)(U.DateCell,{value:e.getValue(),precision:"date",fallback:"Unknown"})},{id:"expires",accessorKey:"expires",meta:{title:"Expires"},header:"Expires",size:120,enableSorting:!1,cell:e=>(0,t.jsx)(U.DateCell,{value:e.getValue(),precision:"date",fallback:"Never"})},{id:"spend",accessorKey:"spend",meta:{title:"Spend / Budget",skeleton:"meter"},header:({table:e})=>(0,t.jsx)(D.DataTableMultiSortHeader,{table:e,fields:L}),size:180,enableSorting:!0,cell:({row:a})=>{let l=a.original.team_id,i=e.find(e=>e.team_id===l);return(0,t.jsx)(K.SpendBudgetCell,{spend:a.original.spend,maxBudget:a.original.max_budget,teamMaxBudget:i?.max_budget??null})}},{id:"budget_reset_at",accessorKey:"budget_reset_at",meta:{title:"Budget Reset"},header:"Budget Reset",size:130,enableSorting:!1,cell:e=>(0,t.jsx)(U.DateCell,{value:e.getValue(),fallback:"Never"})},{id:"models",accessorKey:"models",meta:{title:"Models",skeleton:"chips"},header:"Models",size:220,enableSorting:!1,cell:e=>(0,t.jsx)(R.ModelsCell,{models:e.getValue(),allowedRoutes:e.row.original.allowed_routes,keyType:e.row.original.key_type})},{id:"rate_limits",meta:{title:"Rate Limits"},header:"Rate Limits",size:140,enableSorting:!1,cell:({row:e})=>{let a=e.original;return(0,t.jsxs)("div",{className:"text-xs",children:[(0,t.jsxs)("div",{children:["TPM: ",null!==a.tpm_limit?a.tpm_limit:"Unlimited"]}),(0,t.jsxs)("div",{children:["RPM: ",null!==a.rpm_limit?a.rpm_limit:"Unlimited"]})]})}}])({allTeams:I,organizations:u,onSelectKey:e=>z(e.token)}),[I,u,z]),ef=(0,o.useMemo)(()=>ec.find(e=>e.token===N),[ec,N]),{data:eb,isError:ev}=function(e,t){let{accessToken:a}=(0,l.default)();return(0,p.useQuery)({queryKey:[...x.keyKeys.detail(e??""),a],queryFn:async()=>{if(!a||!e)throw Error("Missing access token or key id");return{...(await (0,d.keyInfoV1Call)(a,e)).info,token:e,api_key:e}},enabled:!!(a&&e)&&(t?.enabled??!0)})}(N,{enabled:!ef}),ey=ef??eb,e_=(0,o.useMemo)(()=>I.map(e=>({label:e.team_alias||e.team_id,value:e.team_id,sublabel:e.team_alias?e.team_id:void 0})),[I]),ew=(0,o.useMemo)(()=>u.filter(e=>e.organization_id).map(e=>{let t=e.organization_id;return{label:e.organization_alias||t,value:t,sublabel:e.organization_alias?t:void 0}}),[u]),ek=(0,o.useCallback)((e,t)=>{let a=String(t);return"team_id"===e?I.find(e=>e.team_id===a)?.team_alias||a:"org_id"===e&&u.find(e=>e.organization_id===a)?.organization_alias||a},[I,u]);return N?ey||ev?(0,t.jsx)("div",{className:"w-full h-full overflow-hidden",children:(0,t.jsx)(C.default,{keyId:N,onClose:M,keyData:ey,teams:I,onDelete:eu})}):(0,t.jsx)("div",{className:"p-4 text-sm text-muted-foreground",children:"Loading key..."}):(0,t.jsxs)("div",{className:"flex h-full flex-col gap-4 overflow-hidden py-2",children:[(0,t.jsx)(w.PageHeader,{icon:(0,t.jsx)(S.KeyRound,{className:"size-5"}),title:"Virtual Keys",subtitle:"Every key that authenticates requests to the gateway."}),e,(0,t.jsx)(b.DataTable,{data:ec,columns:eh,getRowId:e=>e.token,defaultColumnVisibility:O,sortingMode:"server",sorting:W,onSortingChange:ep,paginationMode:"server",pagination:$,onPaginationChange:J,rowCount:em,filterMode:"server",columnFilters:Q,onColumnFiltersChange:ex,enableColumnResizing:!0,columnResizeMode:"onChange",isLoading:eo,loadingMessage:"Loading keys...",noDataMessage:"No keys found",maxBodyHeight:"calc(75vh - 210px)",size:"compact",toolbar:e=>(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(y.DataTableToolbar,{table:e,searchValue:ee,onSearchChange:eg,searchPlaceholder:"Search by key alias…",onRefresh:()=>eu?.(),isRefreshing:ed,onOpenFilters:()=>Z(!0),filterLabels:G,formatFilterValue:ek}),(0,t.jsx)(v.DataTableFilterDrawer,{table:e,open:Y,onOpenChange:Z,title:"Filters",description:"Narrow down virtual keys",children:({get:e,set:a})=>(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(v.DataTableFilterField,{label:"Team",children:(0,t.jsx)(_.SearchSelect,{options:e_,value:e("team_id")||void 0,onValueChange:e=>a("team_id",e),placeholder:"Select a team…",emptyText:"No teams found"})}),(0,t.jsx)(v.DataTableFilterField,{label:"Organization",children:(0,t.jsx)(_.SearchSelect,{options:ew,value:e("org_id")||void 0,onValueChange:e=>a("org_id",e),placeholder:"Select an organization…",emptyText:"No organizations found"})}),(0,t.jsx)(v.DataTableFilterField,{label:"User ID",children:(0,t.jsx)(k.Input,{value:e("user_id")??"",onChange:e=>a("user_id",e.target.value),placeholder:"Enter User ID…"})}),(0,t.jsx)(v.DataTableFilterField,{label:"Key ID",children:(0,t.jsx)(k.Input,{value:e("key_hash")??"",onChange:e=>a("key_hash",e.target.value),placeholder:"Enter Key ID…"})})]})})]})})]})}let W=({userID:e,userRole:a,teams:l,keys:m,setUserRole:g,userEmail:p,setUserEmail:x,setTeams:h,setKeys:f,premiumUser:b,addKey:v,createClicked:y,autoOpenCreate:_,prefillData:w})=>{let[k,j]=(0,o.useState)(null),[S,C]=(0,o.useState)(null),I=(0,i.getCookie)("token"),[N,z]=(0,o.useState)(null),[D,T]=(0,o.useState)(null),[U,E]=(0,o.useState)([]),[A,R]=(0,o.useState)(null),[K,V]=(0,o.useState)(null);function M(){(0,i.clearTokenCookies)();let e=(0,d.getProxyBaseUrl)(),t=e?`${e}/sso/key/generate`:"/sso/key/generate";return window.location.href=t,null}if((0,o.useEffect)(()=>{let e=()=>{let e=sessionStorage.getItem("token");sessionStorage.clear(),e&&sessionStorage.setItem("token",e)};return window.addEventListener("beforeunload",e),()=>window.removeEventListener("beforeunload",e)},[]),(0,o.useEffect)(()=>{if(I){let e=(0,n.jwtDecode)(I);e&&(z(e.key),e.user_role&&g(function(e){if(!e)return"Undefined Role";switch(e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";case"internal_user":return"Internal User";case"internal_user_viewer":return"Internal Viewer";default:return"Unknown Role"}}(e.user_role)),e.user_email&&x(e.user_email))}if(e&&N&&a&&!k){let t=sessionStorage.getItem("userModels"+e);t?E(JSON.parse(t)):((async()=>{try{let t=await (0,d.getProxyUISettings)(N);R(t);let l=await (0,d.userGetInfoV2)(N,e);j(l),sessionStorage.setItem("userSpendData"+e,JSON.stringify(l));let i=(await (0,d.modelAvailableCall)(N,e,a)).data.map(e=>e.id);E(i),sessionStorage.setItem("userModels"+e,JSON.stringify(i))}catch(e){console.error("There was an error fetching the data",e),e.message.includes("Invalid proxy server token passed")&&M()}})(),u(N,e,a,S,h))}},[e,I,N,a]),(0,o.useEffect)(()=>{N&&(async()=>{try{await (0,d.keyInfoCall)(N,[N])}catch(e){e.message.includes("Invalid proxy server token passed")&&M()}})()},[N]),(0,o.useEffect)(()=>{N&&u(N,e,a,S,h)},[S]),(0,o.useEffect)(()=>{if(null!==m&&null!=K&&null!==K.team_id){let e=0;for(let t of m)K.hasOwnProperty("team_id")&&null!==t.team_id&&t.team_id===K.team_id&&(e+=t.spend);T(e)}else if(null!==m){let e=0;for(let t of m)e+=t.spend;T(e)}},[K]),null==I)return M(),null;try{let e=(0,n.jwtDecode)(I).exp,t=Math.floor(Date.now()/1e3);if(e&&t>=e)return M(),null}catch(e){return console.error("Error decoding token:",e),(0,i.clearTokenCookies)(),M(),null}if(null==N)return null;if(null==e)return(0,t.jsx)("h1",{children:"User ID is not set"});null==a&&g("App Owner");let L="Admin Viewer"!==a&&"proxy_admin_viewer"!==a;return(0,t.jsx)("div",{className:"mx-4 h-[75vh]",children:(0,t.jsx)(s.Grid,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:(0,t.jsx)(r.Col,{numColSpan:1,className:"flex flex-col gap-2",children:(0,t.jsx)(H,{headerActions:L?(0,t.jsx)(c.default,{team:K,teams:l,data:m,addKey:v,autoOpenCreate:_,prefillData:w},K?K.team_id:null):void 0})})})})};var q=e.i(557951);e.s(["default",0,function(){let{userId:e,userRole:i,userEmail:r,accessToken:s,premiumUser:n}=(0,l.default)(),{setUserRole:d,setUserEmail:u}=(0,q.useAuth)(),c=(0,m.useSearchParams)(),[g,p]=(0,o.useState)(null),[x,h]=(0,o.useState)([]),[f,b]=(0,o.useState)(!1),v="true"===c.get("create"),y=(0,o.useMemo)(()=>{if(!v)return;let e=c.get("owned_by"),t=c.get("team_id"),a=c.get("key_alias"),l=c.get("models"),i=c.get("key_type");if(!e&&!t&&!a&&!l&&!i)return;let r=e&&["you","service_account","another_user"].includes(e)?e:void 0,s=i&&["default","llm_api","management"].includes(i)?i:void 0,n=a?a.trim().slice(0,256):void 0,o=l?l.split(",").slice(0,100).map(e=>e.trim().slice(0,256)).filter(e=>e.length>0):void 0;return{owned_by:r,team_id:t?.trim()||void 0,key_alias:n,models:o&&o.length>0?o:void 0,key_type:s}},[c,v]);return(0,o.useEffect)(()=>{s&&e&&i&&(0,a.teamListCall)(s,1,100,{userID:"Admin"!==i&&"Admin Viewer"!==i?e:null}).then(e=>p(e.teams??[])).catch(console.error)},[s,e,i]),(0,t.jsx)(W,{userID:e,userRole:i,premiumUser:n??!1,teams:g,keys:x,setUserRole:d,userEmail:r,setUserEmail:u,setTeams:p,setKeys:h,addKey:e=>{h(t=>t?[...t,e]:[e]),b(e=>!e)},createClicked:f,autoOpenCreate:v,prefillData:y})}],502501)},871135,e=>{"use strict";var t=e.i(843476),a=e.i(502501),l=e.i(936578),i=e.i(602869),r=e.i(207082),s=e.i(708347),n=e.i(557951),o=e.i(321836),d=e.i(571353),u=e.i(618566),c=e.i(271645);function m(){let{authLoading:e,token:m,userRole:g,userID:p}=(0,n.useAuth)(),x=(0,u.useRouter)(),h=(0,u.useSearchParams)(),f=h.get("page"),b=(0,c.useRef)(!1),v=(0,c.useRef)(!1),y=!1===e&&null===m;(0,c.useEffect)(()=>{if(y){(0,o.storeReturnUrl)();let e=(0,o.getLoginUrl)(i.proxyBaseUrl||""),t=(0,o.buildLoginUrlWithReturn)(e);window.location.replace(t)}},[y]);let _=null!==f&&f in d.MIGRATED_PAGES;(0,c.useEffect)(()=>{!e&&_&&x.replace((0,d.migratedHref)(d.MIGRATED_PAGES[f]))},[e,_,f,x]),(0,c.useEffect)(()=>{if(e||!m||b.current)return;b.current=!0;let t=(0,o.consumeReturnUrl)();if(t&&(0,o.isValidReturnUrl)(t)){let e=new URL(t,window.location.origin);if(e.origin!==window.location.origin)return;let a=window.location.href;(0,o.normalizeUrlForCompare)(t)!==(0,o.normalizeUrlForCompare)(a)&&(v.current=!0,window.location.replace(e.href))}},[e,m]),(0,c.useEffect)(()=>{m||(b.current=!1,v.current=!1)},[m]);let w="success"===h.get("login"),k=!e&&!!m,j=w&&k&&""===g,S=w&&k&&s.internalUserRoles.includes(g),{data:C,isLoading:I}=(0,r.useKeys)(1,1,{userID:p},S),N=S&&!I&&C?.keys?.length===0,z=S&&I||N;(0,c.useEffect)(()=>{N&&!v.current&&x.replace((0,d.migratedHref)("connect"))},[N,x]);let D=y||_||j||z;return e||D?(0,t.jsx)(l.default,{}):(0,t.jsx)(a.default,{})}e.s(["default",0,function(){return(0,t.jsx)(c.Suspense,{fallback:(0,t.jsx)(l.default,{}),children:(0,t.jsx)(m,{})})}])}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/00qiry~y.broe.js b/litellm/proxy/_experimental/out/_next/static/chunks/00qiry~y.broe.js deleted file mode 100644 index 2c8f1387ee0..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/00qiry~y.broe.js +++ /dev/null @@ -1 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,916925,e=>{"use strict";var t,a=e.i(555987),n=((t={}).A2A_Agent="A2A Agent",t.AI21="Ai21",t.AI21_CHAT="Ai21 Chat",t.AIML="AI/ML API",t.AIOHTTP_OPENAI="Aiohttp Openai",t.Anthropic="Anthropic",t.ANTHROPIC_TEXT="Anthropic Text",t.AssemblyAI="AssemblyAI",t.AUTO_ROUTER="Auto Router",t.Bedrock="Amazon Bedrock",t.BedrockMantle="Amazon Bedrock Mantle",t.SageMaker="AWS SageMaker",t.Azure="Azure",t.Azure_AI_Studio="Azure AI Foundry (Studio)",t.AZURE_TEXT="Azure Text",t.BASETEN="Baseten",t.BYTEZ="Bytez",t.Cerebras="Cerebras",t.CLARIFAI="Clarifai",t.CLOUDFLARE="Cloudflare",t.CODESTRAL="Codestral",t.Cohere="Cohere",t.COHERE_CHAT="Cohere Chat",t.COMETAPI="Cometapi",t.COMPACTIFAI="Compactifai",t.Cursor="Cursor",t.Dashscope="Dashscope",t.Databricks="Databricks (Qwen API)",t.DATAROBOT="Datarobot",t.DeepInfra="DeepInfra",t.Deepgram="Deepgram",t.Deepseek="Deepseek",t.DOCKER_MODEL_RUNNER="Docker Model Runner",t.DOTPROMPT="Dotprompt",t.ElevenLabs="ElevenLabs",t.EMPOWER="Empower",t.FalAI="Fal AI",t.FEATHERLESS_AI="Featherless Ai",t.FireworksAI="Fireworks AI",t.FRIENDLIAI="Friendliai",t.GALADRIEL="Galadriel",t.GITHUB_COPILOT="Github Copilot",t.Google_AI_Studio="Google AI Studio",t.GradientAI="GradientAI",t.Groq="Groq",t.HEROKU="Heroku",t.Hosted_Vllm="vllm",t.HUGGINGFACE="Huggingface",t.HYPERBOLIC="Hyperbolic",t.Infinity="Infinity",t.JinaAI="Jina AI",t.LAMBDA_AI="Lambda Ai",t.LEMONADE="Lemonade",t.LLAMAFILE="Llamafile",t.LM_STUDIO="Lm Studio",t.LLAMA="Meta Llama",t.MARITALK="Maritalk",t.MiniMax="MiniMax",t.MistralAI="Mistral AI",t.MOONSHOT="Moonshot",t.MORPH="Morph",t.NEBIUS="Nebius",t.NLP_CLOUD="Nlp Cloud",t.NOVITA="Novita",t.NSCALE="Nscale",t.NVIDIA_NIM="Nvidia Nim",t.Ollama="Ollama",t.OLLAMA_CHAT="Ollama Chat",t.OOBABOOGA="Oobabooga",t.OpenAI="OpenAI",t.OPENAI_LIKE="Openai Like",t.OpenAI_Compatible="OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)",t.OpenAI_Text="OpenAI Text Completion",t.OpenAI_Text_Compatible="OpenAI-Compatible Completions (legacy /v1/completions)",t.Openrouter="Openrouter",t.Oracle="Oracle Cloud Infrastructure (OCI)",t.OVHCLOUD="Ovhcloud",t.Perplexity="Perplexity",t.PETALS="Petals",t.PG_VECTOR="Pg Vector",t.PREDIBASE="Predibase",t.RECRAFT="Recraft",t.REPLICATE="Replicate",t.RunwayML="RunwayML",t.SAGEMAKER_LEGACY="Sagemaker",t.Sambanova="Sambanova",t.SAP="SAP Generative AI Hub",t.Snowflake="Snowflake",t.Soniox="Soniox",t.TEXT_COMPLETION_CODESTRAL="Text-Completion-Codestral",t.TogetherAI="TogetherAI",t.TOPAZ="Topaz",t.Triton="Triton",t.V0="V0",t.VERCEL_AI_GATEWAY="Vercel Ai Gateway",t.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)",t.VERTEX_AI_BETA="Vertex Ai Beta",t.VLLM="Vllm",t.VolcEngine="VolcEngine",t.Voyage="Voyage AI",t.WANDB="Wandb",t.WATSONX="Watsonx",t.WATSONX_TEXT="Watsonx Text",t.xAI="xAI",t.XINFERENCE="Xinference",t.ZAI="Z.AI (Zhipu AI)",t);let o={A2A_Agent:"a2a_agent",AI21:"ai21",AI21_CHAT:"ai21_chat",AIML:"aiml",AIOHTTP_OPENAI:"aiohttp_openai",Anthropic:"anthropic",ANTHROPIC_TEXT:"anthropic_text",AssemblyAI:"assemblyai",AUTO_ROUTER:"auto_router",Azure:"azure",Azure_AI_Studio:"azure_ai",AZURE_TEXT:"azure_text",BASETEN:"baseten",Bedrock:"bedrock",BedrockMantle:"bedrock_mantle",BYTEZ:"bytez",Cerebras:"cerebras",CLARIFAI:"clarifai",CLOUDFLARE:"cloudflare",CODESTRAL:"codestral",Cohere:"cohere",COHERE_CHAT:"cohere_chat",COMETAPI:"cometapi",COMPACTIFAI:"compactifai",Cursor:"cursor",Dashscope:"dashscope",Databricks:"databricks",DATAROBOT:"datarobot",DeepInfra:"deepinfra",Deepgram:"deepgram",Deepseek:"deepseek",DOCKER_MODEL_RUNNER:"docker_model_runner",DOTPROMPT:"dotprompt",ElevenLabs:"elevenlabs",EMPOWER:"empower",FalAI:"fal_ai",FEATHERLESS_AI:"featherless_ai",FireworksAI:"fireworks_ai",FRIENDLIAI:"friendliai",GALADRIEL:"galadriel",GITHUB_COPILOT:"github_copilot",Google_AI_Studio:"gemini",GradientAI:"gradient_ai",Groq:"groq",HEROKU:"heroku",Hosted_Vllm:"hosted_vllm",HUGGINGFACE:"huggingface",HYPERBOLIC:"hyperbolic",Infinity:"infinity",JinaAI:"jina_ai",LAMBDA_AI:"lambda_ai",LEMONADE:"lemonade",LLAMAFILE:"llamafile",LLAMA:"meta_llama",LM_STUDIO:"lm_studio",MARITALK:"maritalk",MiniMax:"minimax",MistralAI:"mistral",MOONSHOT:"moonshot",MORPH:"morph",NEBIUS:"nebius",NLP_CLOUD:"nlp_cloud",NOVITA:"novita",NSCALE:"nscale",NVIDIA_NIM:"nvidia_nim",Ollama:"ollama",OLLAMA_CHAT:"ollama_chat",OOBABOOGA:"oobabooga",OpenAI:"openai",OPENAI_LIKE:"openai_like",OpenAI_Compatible:"openai",OpenAI_Text:"text-completion-openai",OpenAI_Text_Compatible:"text-completion-openai",Openrouter:"openrouter",Oracle:"oci",OVHCLOUD:"ovhcloud",Perplexity:"perplexity",PETALS:"petals",PG_VECTOR:"pg_vector",PREDIBASE:"predibase",RECRAFT:"recraft",REPLICATE:"replicate",RunwayML:"runwayml",SAGEMAKER_LEGACY:"sagemaker",SageMaker:"sagemaker_chat",Sambanova:"sambanova",SAP:"sap",Snowflake:"snowflake",Soniox:"soniox",TEXT_COMPLETION_CODESTRAL:"text-completion-codestral",TogetherAI:"together_ai",TOPAZ:"topaz",Triton:"triton",V0:"v0",VERCEL_AI_GATEWAY:"vercel_ai_gateway",Vertex_AI:"vertex_ai",VERTEX_AI_BETA:"vertex_ai_beta",VLLM:"vllm",VolcEngine:"volcengine",Voyage:"voyage",WANDB:"wandb",WATSONX:"watsonx",WATSONX_TEXT:"watsonx_text",xAI:"xai",XINFERENCE:"xinference",ZAI:"zai"},i=new Set(["bedrock_mantle"]),r="/ui/assets/logos/",l={"A2A Agent":`${r}a2a_agent.png`,Ai21:`${r}ai21.svg`,"Ai21 Chat":`${r}ai21.svg`,"AI/ML API":`${r}aiml_api.svg`,"Aiohttp Openai":`${r}openai_small.svg`,Anthropic:`${r}anthropic.svg`,"Anthropic Text":`${r}anthropic.svg`,AssemblyAI:`${r}assemblyai_small.png`,Azure:`${r}microsoft_azure.svg`,"Azure AI Foundry (Studio)":`${r}microsoft_azure.svg`,"Azure Text":`${r}microsoft_azure.svg`,Baseten:`${r}baseten.svg`,"Amazon Bedrock":`${r}bedrock.svg`,"Amazon Bedrock Mantle":`${r}bedrock.svg`,"AWS SageMaker":`${r}bedrock.svg`,Cerebras:`${r}cerebras.svg`,Cloudflare:`${r}cloudflare.svg`,Codestral:`${r}mistral.svg`,Cohere:`${r}cohere.svg`,"Cohere Chat":`${r}cohere.svg`,Cometapi:`${r}cometapi.svg`,Cursor:`${r}cursor.svg`,"Databricks (Qwen API)":`${r}databricks.svg`,Dashscope:`${r}dashscope.svg`,Deepseek:`${r}deepseek.svg`,Deepgram:`${r}deepgram.png`,DeepInfra:`${r}deepinfra.png`,ElevenLabs:`${r}elevenlabs.png`,"Fal AI":`${r}fal_ai.jpg`,"Featherless Ai":`${r}featherless.svg`,"Fireworks AI":`${r}fireworks.svg`,Friendliai:`${r}friendli.svg`,"Github Copilot":`${r}github_copilot.svg`,"Google AI Studio":`${r}google.svg`,GradientAI:`${r}gradientai.svg`,Groq:`${r}groq.svg`,vllm:`${r}vllm.png`,Huggingface:`${r}huggingface.svg`,Hyperbolic:`${r}hyperbolic.svg`,Infinity:`${r}infinity.png`,"Jina AI":`${r}jina.png`,"Lambda Ai":`${r}lambda.svg`,"Lm Studio":`${r}lmstudio.svg`,"Meta Llama":`${r}meta_llama.svg`,MiniMax:`${r}minimax.svg`,"Mistral AI":`${r}mistral.svg`,Moonshot:`${r}moonshot.svg`,Morph:`${r}morph.svg`,Nebius:`${r}nebius.svg`,Novita:`${r}novita.svg`,"Nvidia Nim":`${r}nvidia_nim.svg`,Ollama:`${r}ollama.svg`,"Ollama Chat":`${r}ollama.svg`,Oobabooga:`${r}openai_small.svg`,OpenAI:`${r}openai_small.svg`,"Openai Like":`${r}openai_small.svg`,"OpenAI Text Completion":`${r}openai_small.svg`,"OpenAI-Compatible Completions (legacy /v1/completions)":`${r}openai_small.svg`,"OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)":`${r}openai_small.svg`,Openrouter:`${r}openrouter.svg`,"Oracle Cloud Infrastructure (OCI)":`${r}oracle.svg`,Perplexity:`${r}perplexity-ai.svg`,Recraft:`${r}recraft.svg`,Replicate:`${r}replicate.svg`,RunwayML:`${r}runwayml.png`,Sagemaker:`${r}bedrock.svg`,Sambanova:`${r}sambanova.svg`,"SAP Generative AI Hub":`${r}sap.png`,Snowflake:`${r}snowflake.svg`,Soniox:`${r}soniox.svg`,"Text-Completion-Codestral":`${r}mistral.svg`,TogetherAI:`${r}togetherai.svg`,Topaz:`${r}topaz.svg`,Triton:`${r}nvidia_triton.png`,V0:`${r}v0.svg`,"Vercel Ai Gateway":`${r}vercel.svg`,"Vertex AI (Anthropic, Gemini, etc.)":`${r}google.svg`,"Vertex Ai Beta":`${r}google.svg`,Vllm:`${r}vllm.png`,VolcEngine:`${r}volcengine.png`,"Voyage AI":`${r}voyage.webp`,Watsonx:`${r}watsonx.svg`,"Watsonx Text":`${r}watsonx.svg`,xAI:`${r}xai.svg`,Xinference:`${r}xinference.svg`};e.s(["Providers",()=>n,"getPlaceholder",0,e=>{if("AI/ML API"===e)return"aiml/flux-pro/v1.1";if("Vertex AI (Anthropic, Gemini, etc.)"===e)return"gemini-pro";if("Anthropic"==e)return"claude-3-opus";if("Amazon Bedrock"==e)return"claude-3-opus";if("AWS SageMaker"==e)return"sagemaker/jumpstart-dft-meta-textgeneration-llama-2-7b";else if("Google AI Studio"==e)return"gemini-pro";else if("Azure AI Foundry (Studio)"==e)return"azure_ai/command-r-plus";else if("Azure"==e)return"my-deployment";else if("Oracle Cloud Infrastructure (OCI)"==e)return"oci/xai.grok-4";else if("Snowflake"==e)return"snowflake/mistral-7b";else if("Voyage AI"==e)return"voyage/";else if("Jina AI"==e)return"jina_ai/";else if("VolcEngine"==e)return"volcengine/";else if("DeepInfra"==e)return"deepinfra/";else if("Fal AI"==e)return"fal_ai/fal-ai/flux-pro/v1.1-ultra";else if("RunwayML"==e)return"runwayml/gen4_turbo";else if("Watsonx"===e)return"watsonx/ibm/granite-3-3-8b-instruct";else if("Cursor"===e)return"cursor/claude-4-sonnet";else if("Z.AI (Zhipu AI)"===e)return"zai/glm-4.5";else return"gpt-3.5-turbo"},"getProviderLogoAndName",0,e=>{if(!e)return{logo:"",displayName:"-"};if("gemini"===e.toLowerCase()){let e="Google AI Studio";return{logo:(0,a.resolveLogoSrc)(l[e])??"",displayName:e}}let t=Object.keys(o).find(t=>o[t].toLowerCase()===e.toLowerCase())??Object.keys(o).find(t=>t.toLowerCase()===e.toLowerCase());if(!t)return{logo:"",displayName:e};let i=n[t];return{logo:(0,a.resolveLogoSrc)(l[i])??"",displayName:i}},"getProviderModels",0,(e,t)=>{let a=o[e],n=[];return e&&"object"==typeof t&&(Object.entries(t).forEach(([e,t])=>{if(null!==t&&"object"==typeof t&&"litellm_provider"in t){let o=t.litellm_provider,r="string"==typeof o&&(o.startsWith(`${a}_`)||o.startsWith(`${a}-`));(o===a||r&&!i.has(o))&&n.push(e)}}),"Cohere"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"cohere_chat"===t.litellm_provider&&n.push(e)}),"AWS SageMaker"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"sagemaker_chat"===t.litellm_provider&&n.push(e)})),n},"providerLogoMap",0,l,"provider_map",0,o])},727612,e=>{"use strict";let t=(0,e.i(475254).default)("trash-2",[["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",key:"4alrt4"}],["path",{d:"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",key:"v07s0e"}],["line",{x1:"10",x2:"10",y1:"11",y2:"17",key:"1uufr5"}],["line",{x1:"14",x2:"14",y1:"11",y2:"17",key:"xtxkd"}]]);e.s(["Trash2",0,t],727612)},541071,e=>{"use strict";let t=(0,e.i(475254).default)("ellipsis",[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"19",cy:"12",r:"1",key:"1wjl8i"}],["circle",{cx:"5",cy:"12",r:"1",key:"1pcz8c"}]]);e.s(["MoreHorizontal",0,t],541071)},755146,e=>{"use strict";var t=e.i(843476),a=e.i(451512),n=e.i(115504);e.i(233565),e.i(678784),e.s(["DropdownMenu",0,function({...e}){return(0,t.jsx)(a.Menu.Root,{"data-slot":"dropdown-menu",...e})},"DropdownMenuContent",0,function({align:e="start",alignOffset:o=0,side:i="bottom",sideOffset:r=4,className:l,...s}){return(0,t.jsx)(a.Menu.Portal,{children:(0,t.jsx)(a.Menu.Positioner,{className:"isolate z-50 outline-none",align:e,alignOffset:o,side:i,sideOffset:r,children:(0,t.jsx)(a.Menu.Popup,{"data-slot":"dropdown-menu-content",className:(0,n.cn)("z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95",l),...s})})})},"DropdownMenuItem",0,function({className:e,inset:o,variant:i="default",...r}){return(0,t.jsx)(a.Menu.Item,{"data-slot":"dropdown-menu-item","data-inset":o,"data-variant":i,className:(0,n.cn)("group/dropdown-menu-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive",e),...r})},"DropdownMenuSeparator",0,function({className:e,...o}){return(0,t.jsx)(a.Menu.Separator,{"data-slot":"dropdown-menu-separator",className:(0,n.cn)("-mx-1 my-1 h-px bg-border",e),...o})},"DropdownMenuTrigger",0,function({...e}){return(0,t.jsx)(a.Menu.Trigger,{"data-slot":"dropdown-menu-trigger",...e})}])},332102,e=>{"use strict";let t=(0,e.i(475254).default)("inbox",[["polyline",{points:"22 12 16 12 14 15 10 15 8 12 2 12",key:"o97t9d"}],["path",{d:"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z",key:"oot6mr"}]]);e.s(["Inbox",0,t],332102)},118366,e=>{"use strict";var t=e.i(991124);e.s(["CopyIcon",()=>t.default])},751904,e=>{"use strict";var t=e.i(401361);e.s(["EditOutlined",()=>t.default])},541202,e=>{"use strict";var t=e.i(843476),a=e.i(522016),n=e.i(560445);e.s(["DeprecationBanner",0,({featureName:e})=>(0,t.jsx)(n.Alert,{message:`${e} is on a draft deprecation list`,description:(0,t.jsxs)(t.Fragment,{children:[`${e} is one of several experimental features we're considering removing, potentially as early as September 1, 2026. This list is a draft and is not final. If you rely on this feature, please share feedback on the `,(0,t.jsx)(a.default,{href:"https://github.com/BerriAI/litellm/discussions/32090",target:"_blank",rel:"noopener noreferrer",children:"deprecation discussion"}),"."]}),type:"info",showIcon:!0,closable:!0,style:{marginBottom:16}})])},608856,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(343794),n=e.i(209428),o=e.i(392221),i=e.i(951160),r=e.i(174428),l=t.createContext(null),s=t.createContext({}),c=e.i(211577),d=e.i(931067),u=e.i(361275),m=e.i(404948),p=e.i(244009),g=e.i(703923),f=e.i(611935),v=["prefixCls","className","containerRef"];let h=function(e){var n=e.prefixCls,o=e.className,i=e.containerRef,r=(0,g.default)(e,v),l=t.useContext(s).panel,c=(0,f.useComposeRef)(l,i);return t.createElement("div",(0,d.default)({className:(0,a.default)("".concat(n,"-content"),o),role:"dialog",ref:c},(0,p.default)(e,{aria:!0}),{"aria-modal":"true"},r))};var b=e.i(883110);function x(e){return"string"==typeof e&&String(Number(e))===e?((0,b.default)(!1,"Invalid value type of `width` or `height` which should be number type instead."),Number(e)):e}var A={width:0,height:0,overflow:"hidden",outline:"none",position:"absolute"},$=t.forwardRef(function(e,i){var r,s,g,f=e.prefixCls,v=e.open,b=e.placement,$=e.inline,y=e.push,O=e.forceRender,C=e.autoFocus,I=e.keyboard,k=e.classNames,E=e.rootClassName,S=e.rootStyle,w=e.zIndex,T=e.className,M=e.id,_=e.style,N=e.motion,L=e.width,z=e.height,j=e.children,R=e.mask,D=e.maskClosable,H=e.maskMotion,B=e.maskClassName,P=e.maskStyle,V=e.afterOpenChange,W=e.onClose,F=e.onMouseEnter,G=e.onMouseOver,U=e.onMouseLeave,X=e.onClick,K=e.onKeyDown,Y=e.onKeyUp,Z=e.styles,q=e.drawerRender,J=t.useRef(),Q=t.useRef(),ee=t.useRef();t.useImperativeHandle(i,function(){return J.current}),t.useEffect(function(){if(v&&C){var e;null==(e=J.current)||e.focus({preventScroll:!0})}},[v]);var et=t.useState(!1),ea=(0,o.default)(et,2),en=ea[0],eo=ea[1],ei=t.useContext(l),er=null!=(r=null!=(s=null==(g="boolean"==typeof y?y?{}:{distance:0}:y||{})?void 0:g.distance)?s:null==ei?void 0:ei.pushDistance)?r:180,el=t.useMemo(function(){return{pushDistance:er,push:function(){eo(!0)},pull:function(){eo(!1)}}},[er]);t.useEffect(function(){var e,t;v?null==ei||null==(e=ei.push)||e.call(ei):null==ei||null==(t=ei.pull)||t.call(ei)},[v]),t.useEffect(function(){return function(){var e;null==ei||null==(e=ei.pull)||e.call(ei)}},[]);var es=t.createElement(u.default,(0,d.default)({key:"mask"},H,{visible:R&&v}),function(e,o){var i=e.className,r=e.style;return t.createElement("div",{className:(0,a.default)("".concat(f,"-mask"),i,null==k?void 0:k.mask,B),style:(0,n.default)((0,n.default)((0,n.default)({},r),P),null==Z?void 0:Z.mask),onClick:D&&v?W:void 0,ref:o})}),ec="function"==typeof N?N(b):N,ed={};if(en&&er)switch(b){case"top":ed.transform="translateY(".concat(er,"px)");break;case"bottom":ed.transform="translateY(".concat(-er,"px)");break;case"left":ed.transform="translateX(".concat(er,"px)");break;default:ed.transform="translateX(".concat(-er,"px)")}"left"===b||"right"===b?ed.width=x(L):ed.height=x(z);var eu={onMouseEnter:F,onMouseOver:G,onMouseLeave:U,onClick:X,onKeyDown:K,onKeyUp:Y},em=t.createElement(u.default,(0,d.default)({key:"panel"},ec,{visible:v,forceRender:O,onVisibleChanged:function(e){null==V||V(e)},removeOnLeave:!1,leavedClassName:"".concat(f,"-content-wrapper-hidden")}),function(o,i){var r=o.className,l=o.style,s=t.createElement(h,(0,d.default)({id:M,containerRef:i,prefixCls:f,className:(0,a.default)(T,null==k?void 0:k.content),style:(0,n.default)((0,n.default)({},_),null==Z?void 0:Z.content)},(0,p.default)(e,{aria:!0}),eu),j);return t.createElement("div",(0,d.default)({className:(0,a.default)("".concat(f,"-content-wrapper"),null==k?void 0:k.wrapper,r),style:(0,n.default)((0,n.default)((0,n.default)({},ed),l),null==Z?void 0:Z.wrapper)},(0,p.default)(e,{data:!0})),q?q(s):s)}),ep=(0,n.default)({},S);return w&&(ep.zIndex=w),t.createElement(l.Provider,{value:el},t.createElement("div",{className:(0,a.default)(f,"".concat(f,"-").concat(b),E,(0,c.default)((0,c.default)({},"".concat(f,"-open"),v),"".concat(f,"-inline"),$)),style:ep,tabIndex:-1,ref:J,onKeyDown:function(e){var t,a,n=e.keyCode,o=e.shiftKey;switch(n){case m.default.TAB:n===m.default.TAB&&(o||document.activeElement!==ee.current?o&&document.activeElement===Q.current&&(null==(a=ee.current)||a.focus({preventScroll:!0})):null==(t=Q.current)||t.focus({preventScroll:!0}));break;case m.default.ESC:W&&I&&(e.stopPropagation(),W(e))}}},es,t.createElement("div",{tabIndex:0,ref:Q,style:A,"aria-hidden":"true","data-sentinel":"start"}),em,t.createElement("div",{tabIndex:0,ref:ee,style:A,"aria-hidden":"true","data-sentinel":"end"})))});let y=function(e){var a=e.open,l=e.prefixCls,c=e.placement,d=e.autoFocus,u=e.keyboard,m=e.width,p=e.mask,g=void 0===p||p,f=e.maskClosable,v=e.getContainer,h=e.forceRender,b=e.afterOpenChange,x=e.destroyOnClose,A=e.onMouseEnter,y=e.onMouseOver,O=e.onMouseLeave,C=e.onClick,I=e.onKeyDown,k=e.onKeyUp,E=e.panelRef,S=t.useState(!1),w=(0,o.default)(S,2),T=w[0],M=w[1],_=t.useState(!1),N=(0,o.default)(_,2),L=N[0],z=N[1];(0,r.default)(function(){z(!0)},[]);var j=!!L&&void 0!==a&&a,R=t.useRef(),D=t.useRef();(0,r.default)(function(){j&&(D.current=document.activeElement)},[j]);var H=t.useMemo(function(){return{panel:E}},[E]);if(!h&&!T&&!j&&x)return null;var B=(0,n.default)((0,n.default)({},e),{},{open:j,prefixCls:void 0===l?"rc-drawer":l,placement:void 0===c?"right":c,autoFocus:void 0===d||d,keyboard:void 0===u||u,width:void 0===m?378:m,mask:g,maskClosable:void 0===f||f,inline:!1===v,afterOpenChange:function(e){var t,a;M(e),null==b||b(e),e||!D.current||null!=(t=R.current)&&t.contains(D.current)||null==(a=D.current)||a.focus({preventScroll:!0})},ref:R},{onMouseEnter:A,onMouseOver:y,onMouseLeave:O,onClick:C,onKeyDown:I,onKeyUp:k});return t.createElement(s.Provider,{value:H},t.createElement(i.default,{open:j||h||T,autoDestroy:!1,getContainer:v,autoLock:g&&(j||T)},t.createElement($,B)))};var O=e.i(981444),C=e.i(617206),I=e.i(122767),k=e.i(613541),E=e.i(340010),S=e.i(242064),w=e.i(922611),T=e.i(563113),M=e.i(185793);let _=e=>{var n,o,i,r;let l,{prefixCls:s,ariaId:c,title:d,footer:u,extra:m,closable:p,loading:g,onClose:f,headerStyle:v,bodyStyle:h,footerStyle:b,children:x,classNames:A,styles:$}=e,y=(0,S.useComponentConfig)("drawer");l=!1===p?void 0:void 0===p||!0===p?"start":(null==p?void 0:p.placement)==="end"?"end":"start";let O=t.useCallback(e=>t.createElement("button",{type:"button",onClick:f,className:(0,a.default)(`${s}-close`,{[`${s}-close-${l}`]:"end"===l})},e),[f,s,l]),[C,I]=(0,T.useClosable)((0,T.pickClosable)(e),(0,T.pickClosable)(y),{closable:!0,closeIconRender:O});return t.createElement(t.Fragment,null,d||C?t.createElement("div",{style:Object.assign(Object.assign(Object.assign({},null==(i=y.styles)?void 0:i.header),v),null==$?void 0:$.header),className:(0,a.default)(`${s}-header`,{[`${s}-header-close-only`]:C&&!d&&!m},null==(r=y.classNames)?void 0:r.header,null==A?void 0:A.header)},t.createElement("div",{className:`${s}-header-title`},"start"===l&&I,d&&t.createElement("div",{className:`${s}-title`,id:c},d)),m&&t.createElement("div",{className:`${s}-extra`},m),"end"===l&&I):null,t.createElement("div",{className:(0,a.default)(`${s}-body`,null==A?void 0:A.body,null==(n=y.classNames)?void 0:n.body),style:Object.assign(Object.assign(Object.assign({},null==(o=y.styles)?void 0:o.body),h),null==$?void 0:$.body)},g?t.createElement(M.default,{active:!0,title:!1,paragraph:{rows:5},className:`${s}-body-skeleton`}):x),(()=>{var e,n;if(!u)return null;let o=`${s}-footer`;return t.createElement("div",{className:(0,a.default)(o,null==(e=y.classNames)?void 0:e.footer,null==A?void 0:A.footer),style:Object.assign(Object.assign(Object.assign({},null==(n=y.styles)?void 0:n.footer),b),null==$?void 0:$.footer)},u)})())};e.i(296059);var N=e.i(915654),L=e.i(183293),z=e.i(246422),j=e.i(838378);let R=(e,t)=>({"&-enter, &-appear":Object.assign(Object.assign({},e),{"&-active":t}),"&-leave":Object.assign(Object.assign({},t),{"&-active":e})}),D=(e,t)=>Object.assign({"&-enter, &-appear, &-leave":{"&-start":{transition:"none"},"&-active":{transition:`all ${t}`}}},R({opacity:e},{opacity:1})),H=(0,z.genStyleHooks)("Drawer",e=>{let t=(0,j.mergeToken)(e,{});return[(e=>{let{borderRadiusSM:t,componentCls:a,zIndexPopup:n,colorBgMask:o,colorBgElevated:i,motionDurationSlow:r,motionDurationMid:l,paddingXS:s,padding:c,paddingLG:d,fontSizeLG:u,lineHeightLG:m,lineWidth:p,lineType:g,colorSplit:f,marginXS:v,colorIcon:h,colorIconHover:b,colorBgTextHover:x,colorBgTextActive:A,colorText:$,fontWeightStrong:y,footerPaddingBlock:O,footerPaddingInline:C,calc:I}=e,k=`${a}-content-wrapper`;return{[a]:{position:"fixed",inset:0,zIndex:n,pointerEvents:"none",color:$,"&-pure":{position:"relative",background:i,display:"flex",flexDirection:"column",[`&${a}-left`]:{boxShadow:e.boxShadowDrawerLeft},[`&${a}-right`]:{boxShadow:e.boxShadowDrawerRight},[`&${a}-top`]:{boxShadow:e.boxShadowDrawerUp},[`&${a}-bottom`]:{boxShadow:e.boxShadowDrawerDown}},"&-inline":{position:"absolute"},[`${a}-mask`]:{position:"absolute",inset:0,zIndex:n,background:o,pointerEvents:"auto"},[k]:{position:"absolute",zIndex:n,maxWidth:"100vw",transition:`all ${r}`,"&-hidden":{display:"none"}},[`&-left > ${k}`]:{top:0,bottom:0,left:{_skip_check_:!0,value:0},boxShadow:e.boxShadowDrawerLeft},[`&-right > ${k}`]:{top:0,right:{_skip_check_:!0,value:0},bottom:0,boxShadow:e.boxShadowDrawerRight},[`&-top > ${k}`]:{top:0,insetInline:0,boxShadow:e.boxShadowDrawerUp},[`&-bottom > ${k}`]:{bottom:0,insetInline:0,boxShadow:e.boxShadowDrawerDown},[`${a}-content`]:{display:"flex",flexDirection:"column",width:"100%",height:"100%",overflow:"auto",background:i,pointerEvents:"auto"},[`${a}-header`]:{display:"flex",flex:0,alignItems:"center",padding:`${(0,N.unit)(c)} ${(0,N.unit)(d)}`,fontSize:u,lineHeight:m,borderBottom:`${(0,N.unit)(p)} ${g} ${f}`,"&-title":{display:"flex",flex:1,alignItems:"center",minWidth:0,minHeight:0}},[`${a}-extra`]:{flex:"none"},[`${a}-close`]:Object.assign({display:"inline-flex",width:I(u).add(s).equal(),height:I(u).add(s).equal(),borderRadius:t,justifyContent:"center",alignItems:"center",color:h,fontWeight:y,fontSize:u,fontStyle:"normal",lineHeight:1,textAlign:"center",textTransform:"none",textDecoration:"none",background:"transparent",border:0,cursor:"pointer",transition:`all ${l}`,textRendering:"auto",[`&${a}-close-end`]:{marginInlineStart:v},[`&:not(${a}-close-end)`]:{marginInlineEnd:v},"&:hover":{color:b,backgroundColor:x,textDecoration:"none"},"&:active":{backgroundColor:A}},(0,L.genFocusStyle)(e)),[`${a}-title`]:{flex:1,margin:0,fontWeight:e.fontWeightStrong,fontSize:u,lineHeight:m},[`${a}-body`]:{flex:1,minWidth:0,minHeight:0,padding:d,overflow:"auto",[`${a}-body-skeleton`]:{width:"100%",height:"100%",display:"flex",justifyContent:"center"}},[`${a}-footer`]:{flexShrink:0,padding:`${(0,N.unit)(O)} ${(0,N.unit)(C)}`,borderTop:`${(0,N.unit)(p)} ${g} ${f}`},"&-rtl":{direction:"rtl"}}}})(t),(e=>{let{componentCls:t,motionDurationSlow:a}=e;return{[t]:{[`${t}-mask-motion`]:D(0,a),[`${t}-panel-motion`]:["left","right","top","bottom"].reduce((e,t)=>{let n;return Object.assign(Object.assign({},e),{[`&-${t}`]:[D(.7,a),R({transform:(n="100%",({left:`translateX(-${n})`,right:`translateX(${n})`,top:`translateY(-${n})`,bottom:`translateY(${n})`})[t])},{transform:"none"})]})},{})}}})(t)]},e=>({zIndexPopup:e.zIndexPopupBase,footerPaddingBlock:e.paddingXS,footerPaddingInline:e.padding}));var B=function(e,t){var a={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&0>t.indexOf(n)&&(a[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,n=Object.getOwnPropertySymbols(e);ot.indexOf(n[o])&&Object.prototype.propertyIsEnumerable.call(e,n[o])&&(a[n[o]]=e[n[o]]);return a};let P={distance:180},V=e=>{let{rootClassName:n,width:o,height:i,size:r="default",mask:l=!0,push:s=P,open:c,afterOpenChange:d,onClose:u,prefixCls:m,getContainer:p,panelRef:g=null,style:v,className:h,"aria-labelledby":b,visible:x,afterVisibleChange:A,maskStyle:$,drawerStyle:T,contentWrapperStyle:M,destroyOnClose:N,destroyOnHidden:L}=e,z=B(e,["rootClassName","width","height","size","mask","push","open","afterOpenChange","onClose","prefixCls","getContainer","panelRef","style","className","aria-labelledby","visible","afterVisibleChange","maskStyle","drawerStyle","contentWrapperStyle","destroyOnClose","destroyOnHidden"]),j=(0,O.default)(),R=z.title?j:void 0,{getPopupContainer:D,getPrefixCls:V,direction:W,className:F,style:G,classNames:U,styles:X}=(0,S.useComponentConfig)("drawer"),K=V("drawer",m),[Y,Z,q]=H(K),J=void 0===p&&D?()=>D(document.body):p,Q=(0,a.default)({"no-mask":!l,[`${K}-rtl`]:"rtl"===W},n,Z,q),ee=t.useMemo(()=>null!=o?o:"large"===r?736:378,[o,r]),et=t.useMemo(()=>null!=i?i:"large"===r?736:378,[i,r]),ea={motionName:(0,k.getTransitionName)(K,"mask-motion"),motionAppear:!0,motionEnter:!0,motionLeave:!0,motionDeadline:500},en=(0,w.usePanelRef)(),eo=(0,f.composeRef)(g,en),[ei,er]=(0,I.useZIndex)("Drawer",z.zIndex),{classNames:el={},styles:es={}}=z;return Y(t.createElement(C.default,{form:!0,space:!0},t.createElement(E.default.Provider,{value:er},t.createElement(y,Object.assign({prefixCls:K,onClose:u,maskMotion:ea,motion:e=>({motionName:(0,k.getTransitionName)(K,`panel-motion-${e}`),motionAppear:!0,motionEnter:!0,motionLeave:!0,motionDeadline:500})},z,{classNames:{mask:(0,a.default)(el.mask,U.mask),content:(0,a.default)(el.content,U.content),wrapper:(0,a.default)(el.wrapper,U.wrapper)},styles:{mask:Object.assign(Object.assign(Object.assign({},es.mask),$),X.mask),content:Object.assign(Object.assign(Object.assign({},es.content),T),X.content),wrapper:Object.assign(Object.assign(Object.assign({},es.wrapper),M),X.wrapper)},open:null!=c?c:x,mask:l,push:s,width:ee,height:et,style:Object.assign(Object.assign({},G),v),className:(0,a.default)(F,h),rootClassName:Q,getContainer:J,afterOpenChange:null!=d?d:A,panelRef:eo,zIndex:ei,"aria-labelledby":null!=b?b:R,destroyOnClose:null!=L?L:N}),t.createElement(_,Object.assign({prefixCls:K},z,{ariaId:R,onClose:u}))))))};V._InternalPanelDoNotUseOrYouWillBeFired=e=>{let{prefixCls:n,style:o,className:i,placement:r="right"}=e,l=B(e,["prefixCls","style","className","placement"]),{getPrefixCls:s}=t.useContext(S.ConfigContext),c=s("drawer",n),[d,u,m]=H(c),p=(0,a.default)(c,`${c}-pure`,`${c}-${r}`,u,m,i);return d(t.createElement("div",{className:p,style:o},t.createElement(_,Object.assign({prefixCls:c},l))))},e.s(["Drawer",0,V],608856)},872934,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let n={icon:{tag:"svg",attrs:{"fill-rule":"evenodd",viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M880 912H144c-17.7 0-32-14.3-32-32V144c0-17.7 14.3-32 32-32h360c4.4 0 8 3.6 8 8v56c0 4.4-3.6 8-8 8H184v656h656V520c0-4.4 3.6-8 8-8h56c4.4 0 8 3.6 8 8v360c0 17.7-14.3 32-32 32zM770.87 199.13l-52.2-52.2a8.01 8.01 0 014.7-13.6l179.4-21c5.1-.6 9.5 3.7 8.9 8.9l-21 179.4c-.8 6.6-8.9 9.4-13.6 4.7l-52.4-52.4-256.2 256.2a8.03 8.03 0 01-11.3 0l-42.4-42.4a8.03 8.03 0 010-11.3l256.1-256.3z"}}]},name:"export",theme:"outlined"};var o=e.i(9583),i=a.forwardRef(function(e,i){return a.createElement(o.default,(0,t.default)({},e,{ref:i,icon:n}))});e.s(["ExportOutlined",0,i],872934)},180127,e=>{"use strict";let t=(0,e.i(475254).default)("arrow-left",[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]]);e.s(["default",0,t])},516430,e=>{"use strict";var t=e.i(180127);e.s(["ArrowLeftIcon",()=>t.default])},366308,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let n={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M876.6 239.5c-.5-.9-1.2-1.8-2-2.5-5-5-13.1-5-18.1 0L684.2 409.3l-67.9-67.9L788.7 169c.8-.8 1.4-1.6 2-2.5 3.6-6.1 1.6-13.9-4.5-17.5-98.2-58-226.8-44.7-311.3 39.7-67 67-89.2 162-66.5 247.4l-293 293c-3 3-2.8 7.9.3 11l169.7 169.7c3.1 3.1 8.1 3.3 11 .3l292.9-292.9c85.5 22.8 180.5.7 247.6-66.4 84.4-84.5 97.7-213.1 39.7-311.3zM786 499.8c-58.1 58.1-145.3 69.3-214.6 33.6l-8.8 8.8-.1-.1-274 274.1-79.2-79.2 230.1-230.1s0 .1.1.1l52.8-52.8c-35.7-69.3-24.5-156.5 33.6-214.6a184.2 184.2 0 01144-53.5L537 318.9a32.05 32.05 0 000 45.3l124.5 124.5a32.05 32.05 0 0045.3 0l132.8-132.8c3.7 51.8-14.4 104.8-53.6 143.9z"}}]},name:"tool",theme:"outlined"};var o=e.i(9583),i=a.forwardRef(function(e,i){return a.createElement(o.default,(0,t.default)({},e,{ref:i,icon:n}))});e.s(["ToolOutlined",0,i],366308)},245094,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let n={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M516 673c0 4.4 3.4 8 7.5 8h185c4.1 0 7.5-3.6 7.5-8v-48c0-4.4-3.4-8-7.5-8h-185c-4.1 0-7.5 3.6-7.5 8v48zm-194.9 6.1l192-161c3.8-3.2 3.8-9.1 0-12.3l-192-160.9A7.95 7.95 0 00308 351v62.7c0 2.4 1 4.6 2.9 6.1L420.7 512l-109.8 92.2a8.1 8.1 0 00-2.9 6.1V673c0 6.8 7.9 10.5 13.1 6.1zM880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"}}]},name:"code",theme:"outlined"};var o=e.i(9583),i=a.forwardRef(function(e,i){return a.createElement(o.default,(0,t.default)({},e,{ref:i,icon:n}))});e.s(["CodeOutlined",0,i],245094)},458505,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let n={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"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 372zm47.7-395.2l-25.4-5.9V348.6c38 5.2 61.5 29 65.5 58.2.5 4 3.9 6.9 7.9 6.9h44.9c4.7 0 8.4-4.1 8-8.8-6.1-62.3-57.4-102.3-125.9-109.2V263c0-4.4-3.6-8-8-8h-28.1c-4.4 0-8 3.6-8 8v33c-70.8 6.9-126.2 46-126.2 119 0 67.6 49.8 100.2 102.1 112.7l24.7 6.3v142.7c-44.2-5.9-69-29.5-74.1-61.3-.6-3.8-4-6.6-7.9-6.6H363c-4.7 0-8.4 4-8 8.7 4.5 55 46.2 105.6 135.2 112.1V761c0 4.4 3.6 8 8 8h28.4c4.4 0 8-3.6 8-8.1l-.2-31.7c78.3-6.9 134.3-48.8 134.3-124-.1-69.4-44.2-100.4-109-116.4zm-68.6-16.2c-5.6-1.6-10.3-3.1-15-5-33.8-12.2-49.5-31.9-49.5-57.3 0-36.3 27.5-57 64.5-61.7v124zM534.3 677V543.3c3.1.9 5.9 1.6 8.8 2.2 47.3 14.4 63.2 34.4 63.2 65.1 0 39.1-29.4 62.6-72 66.4z"}}]},name:"dollar",theme:"outlined"};var o=e.i(9583),i=a.forwardRef(function(e,i){return a.createElement(o.default,(0,t.default)({},e,{ref:i,icon:n}))});e.s(["DollarOutlined",0,i],458505)},440987,e=>{"use strict";var t=e.i(903446);e.s(["SettingsIcon",()=>t.default])},219470,812618,e=>{"use strict";e.s(["coy",0,{'code[class*="language-"]':{color:"black",background:"none",fontFamily:"Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace",fontSize:"1em",textAlign:"left",whiteSpace:"pre",wordSpacing:"normal",wordBreak:"normal",wordWrap:"normal",lineHeight:"1.5",MozTabSize:"4",OTabSize:"4",tabSize:"4",WebkitHyphens:"none",MozHyphens:"none",msHyphens:"none",hyphens:"none",maxHeight:"inherit",height:"inherit",padding:"0 1em",display:"block",overflow:"auto"},'pre[class*="language-"]':{color:"black",background:"none",fontFamily:"Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace",fontSize:"1em",textAlign:"left",whiteSpace:"pre",wordSpacing:"normal",wordBreak:"normal",wordWrap:"normal",lineHeight:"1.5",MozTabSize:"4",OTabSize:"4",tabSize:"4",WebkitHyphens:"none",MozHyphens:"none",msHyphens:"none",hyphens:"none",position:"relative",margin:".5em 0",overflow:"visible",padding:"1px",backgroundColor:"#fdfdfd",WebkitBoxSizing:"border-box",MozBoxSizing:"border-box",boxSizing:"border-box",marginBottom:"1em"},'pre[class*="language-"] > code':{position:"relative",zIndex:"1",borderLeft:"10px solid #358ccb",boxShadow:"-1px 0px 0px 0px #358ccb, 0px 0px 0px 1px #dfdfdf",backgroundColor:"#fdfdfd",backgroundImage:"linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%)",backgroundSize:"3em 3em",backgroundOrigin:"content-box",backgroundAttachment:"local"},':not(pre) > code[class*="language-"]':{backgroundColor:"#fdfdfd",WebkitBoxSizing:"border-box",MozBoxSizing:"border-box",boxSizing:"border-box",marginBottom:"1em",position:"relative",padding:".2em",borderRadius:"0.3em",color:"#c92c2c",border:"1px solid rgba(0, 0, 0, 0.1)",display:"inline",whiteSpace:"normal"},'pre[class*="language-"]:before':{content:"''",display:"block",position:"absolute",bottom:"0.75em",left:"0.18em",width:"40%",height:"20%",maxHeight:"13em",boxShadow:"0px 13px 8px #979797",WebkitTransform:"rotate(-2deg)",MozTransform:"rotate(-2deg)",msTransform:"rotate(-2deg)",OTransform:"rotate(-2deg)",transform:"rotate(-2deg)"},'pre[class*="language-"]:after':{content:"''",display:"block",position:"absolute",bottom:"0.75em",left:"auto",width:"40%",height:"20%",maxHeight:"13em",boxShadow:"0px 13px 8px #979797",WebkitTransform:"rotate(2deg)",MozTransform:"rotate(2deg)",msTransform:"rotate(2deg)",OTransform:"rotate(2deg)",transform:"rotate(2deg)",right:"0.75em"},comment:{color:"#7D8B99"},"block-comment":{color:"#7D8B99"},prolog:{color:"#7D8B99"},doctype:{color:"#7D8B99"},cdata:{color:"#7D8B99"},punctuation:{color:"#5F6364"},property:{color:"#c92c2c"},tag:{color:"#c92c2c"},boolean:{color:"#c92c2c"},number:{color:"#c92c2c"},"function-name":{color:"#c92c2c"},constant:{color:"#c92c2c"},symbol:{color:"#c92c2c"},deleted:{color:"#c92c2c"},selector:{color:"#2f9c0a"},"attr-name":{color:"#2f9c0a"},string:{color:"#2f9c0a"},char:{color:"#2f9c0a"},function:{color:"#2f9c0a"},builtin:{color:"#2f9c0a"},inserted:{color:"#2f9c0a"},operator:{color:"#a67f59",background:"rgba(255, 255, 255, 0.5)"},entity:{color:"#a67f59",background:"rgba(255, 255, 255, 0.5)",cursor:"help"},url:{color:"#a67f59",background:"rgba(255, 255, 255, 0.5)"},variable:{color:"#a67f59",background:"rgba(255, 255, 255, 0.5)"},atrule:{color:"#1990b8"},"attr-value":{color:"#1990b8"},keyword:{color:"#1990b8"},"class-name":{color:"#1990b8"},regex:{color:"#e90"},important:{color:"#e90",fontWeight:"normal"},".language-css .token.string":{color:"#a67f59",background:"rgba(255, 255, 255, 0.5)"},".style .token.string":{color:"#a67f59",background:"rgba(255, 255, 255, 0.5)"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"},namespace:{Opacity:".7"},'pre[class*="language-"].line-numbers.line-numbers':{paddingLeft:"0"},'pre[class*="language-"].line-numbers.line-numbers code':{paddingLeft:"3.8em"},'pre[class*="language-"].line-numbers.line-numbers .line-numbers-rows':{left:"0"},'pre[class*="language-"][data-line]':{paddingTop:"0",paddingBottom:"0",paddingLeft:"0"},"pre[data-line] code":{position:"relative",paddingLeft:"4em"},"pre .line-highlight":{marginTop:"0"}}],219470),e.i(247167);var t=e.i(931067),a=e.i(271645);let n={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M632 888H392c-4.4 0-8 3.6-8 8v32c0 17.7 14.3 32 32 32h192c17.7 0 32-14.3 32-32v-32c0-4.4-3.6-8-8-8zM512 64c-181.1 0-328 146.9-328 328 0 121.4 66 227.4 164 284.1V792c0 17.7 14.3 32 32 32h264c17.7 0 32-14.3 32-32V676.1c98-56.7 164-162.7 164-284.1 0-181.1-146.9-328-328-328zm127.9 549.8L604 634.6V752H420V634.6l-35.9-20.8C305.4 568.3 256 484.5 256 392c0-141.4 114.6-256 256-256s256 114.6 256 256c0 92.5-49.4 176.3-128.1 221.8z"}}]},name:"bulb",theme:"outlined"};var o=e.i(9583),i=a.forwardRef(function(e,i){return a.createElement(o.default,(0,t.default)({},e,{ref:i,icon:n}))});e.s(["BulbOutlined",0,i],812618)},447593,285903,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645),n={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"defs",attrs:{},children:[{tag:"style",attrs:{}}]},{tag:"path",attrs:{d:"M899.1 869.6l-53-305.6H864c14.4 0 26-11.6 26-26V346c0-14.4-11.6-26-26-26H618V138c0-14.4-11.6-26-26-26H432c-14.4 0-26 11.6-26 26v182H160c-14.4 0-26 11.6-26 26v192c0 14.4 11.6 26 26 26h17.9l-53 305.6a25.95 25.95 0 0025.6 30.4h723c1.5 0 3-.1 4.4-.4a25.88 25.88 0 0021.2-30zM204 390h272V182h72v208h272v104H204V390zm468 440V674c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v156H416V674c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v156H202.8l45.1-260H776l45.1 260H672z"}}]},name:"clear",theme:"outlined"},o=e.i(9583),i=a.forwardRef(function(e,i){return a.createElement(o.default,(0,t.default)({},e,{ref:i,icon:n}))});e.s(["ClearOutlined",0,i],447593);var r=e.i(843476),l=e.i(592968),s=e.i(637235);let c={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M872 394c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8H708V152c0-4.4-3.6-8-8-8h-64c-4.4 0-8 3.6-8 8v166H400V152c0-4.4-3.6-8-8-8h-64c-4.4 0-8 3.6-8 8v166H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h168v236H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h168v166c0 4.4 3.6 8 8 8h64c4.4 0 8-3.6 8-8V706h228v166c0 4.4 3.6 8 8 8h64c4.4 0 8-3.6 8-8V706h164c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8H708V394h164zM628 630H400V394h228v236z"}}]},name:"number",theme:"outlined"};var d=a.forwardRef(function(e,n){return a.createElement(o.default,(0,t.default)({},e,{ref:n,icon:c}))});let u={icon:{tag:"svg",attrs:{"fill-rule":"evenodd",viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M880 912H144c-17.7 0-32-14.3-32-32V144c0-17.7 14.3-32 32-32h360c4.4 0 8 3.6 8 8v56c0 4.4-3.6 8-8 8H184v656h656V520c0-4.4 3.6-8 8-8h56c4.4 0 8 3.6 8 8v360c0 17.7-14.3 32-32 32zM653.3 424.6l52.2 52.2a8.01 8.01 0 01-4.7 13.6l-179.4 21c-5.1.6-9.5-3.7-8.9-8.9l21-179.4c.8-6.6 8.9-9.4 13.6-4.7l52.4 52.4 256.2-256.2c3.1-3.1 8.2-3.1 11.3 0l42.4 42.4c3.1 3.1 3.1 8.2 0 11.3L653.3 424.6z"}}]},name:"import",theme:"outlined"};var m=a.forwardRef(function(e,n){return a.createElement(o.default,(0,t.default)({},e,{ref:n,icon:u}))}),p=e.i(872934),g=e.i(812618),f=e.i(366308),v=e.i(458505);e.s(["default",0,({timeToFirstToken:e,totalLatency:t,usage:a,toolName:n})=>e||t||a?(0,r.jsxs)("div",{className:"response-metrics mt-2 pt-2 border-t border-gray-100 text-xs text-gray-500 flex flex-wrap gap-3",children:[void 0!==e&&(0,r.jsx)(l.Tooltip,{title:"Time to first token",children:(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(s.ClockCircleOutlined,{className:"mr-1"}),(0,r.jsxs)("span",{children:["TTFT: ",(e/1e3).toFixed(2),"s"]})]})}),void 0!==t&&(0,r.jsx)(l.Tooltip,{title:"Total latency",children:(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(s.ClockCircleOutlined,{className:"mr-1"}),(0,r.jsxs)("span",{children:["Total Latency: ",(t/1e3).toFixed(2),"s"]})]})}),a?.promptTokens!==void 0&&(0,r.jsx)(l.Tooltip,{title:"Prompt tokens",children:(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(m,{className:"mr-1"}),(0,r.jsxs)("span",{children:["In: ",a.promptTokens]})]})}),a?.completionTokens!==void 0&&(0,r.jsx)(l.Tooltip,{title:"Completion tokens",children:(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(p.ExportOutlined,{className:"mr-1"}),(0,r.jsxs)("span",{children:["Out: ",a.completionTokens]})]})}),a?.reasoningTokens!==void 0&&(0,r.jsx)(l.Tooltip,{title:"Reasoning tokens",children:(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(g.BulbOutlined,{className:"mr-1"}),(0,r.jsxs)("span",{children:["Reasoning: ",a.reasoningTokens]})]})}),a?.totalTokens!==void 0&&(0,r.jsx)(l.Tooltip,{title:"Total tokens",children:(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(d,{className:"mr-1"}),(0,r.jsxs)("span",{children:["Total: ",a.totalTokens]})]})}),a?.cost!==void 0&&(0,r.jsx)(l.Tooltip,{title:"Cost",children:(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(v.DollarOutlined,{className:"mr-1"}),(0,r.jsxs)("span",{children:["$",a.cost.toFixed(6)]})]})}),n&&(0,r.jsx)(l.Tooltip,{title:"Tool used",children:(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(f.ToolOutlined,{className:"mr-1"}),(0,r.jsxs)("span",{children:["Tool: ",n]})]})})]}):null],285903)},132104,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let n={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M868 545.5L536.1 163a31.96 31.96 0 00-48.3 0L156 545.5a7.97 7.97 0 006 13.2h81c4.6 0 9-2 12.1-5.5L474 300.9V864c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V300.9l218.9 252.3c3 3.5 7.4 5.5 12.1 5.5h81c6.8 0 10.5-8 6-13.2z"}}]},name:"arrow-up",theme:"outlined"};var o=e.i(9583),i=a.forwardRef(function(e,i){return a.createElement(o.default,(0,t.default)({},e,{ref:i,icon:n}))});e.s(["ArrowUpOutlined",0,i],132104)},573421,e=>{"use strict";e.i(247167);var t=e.i(8211),a=e.i(271645),n=e.i(343794),o=e.i(887719),i=e.i(908206),r=e.i(242064),l=e.i(721132),s=e.i(517455),c=e.i(281256),d=e.i(150073),u=e.i(165370),m=e.i(244451);let p=a.default.createContext({});p.Consumer;var g=e.i(763731),f=e.i(211576),v=function(e,t){var a={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&0>t.indexOf(n)&&(a[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,n=Object.getOwnPropertySymbols(e);ot.indexOf(n[o])&&Object.prototype.propertyIsEnumerable.call(e,n[o])&&(a[n[o]]=e[n[o]]);return a};let h=a.default.forwardRef((e,t)=>{let o,{prefixCls:i,children:l,actions:s,extra:c,styles:d,className:u,classNames:m,colStyle:h}=e,b=v(e,["prefixCls","children","actions","extra","styles","className","classNames","colStyle"]),{grid:x,itemLayout:A}=(0,a.useContext)(p),{getPrefixCls:$,list:y}=(0,a.useContext)(r.ConfigContext),O=e=>{var t,a;return(0,n.default)(null==(a=null==(t=null==y?void 0:y.item)?void 0:t.classNames)?void 0:a[e],null==m?void 0:m[e])},C=e=>{var t,a;return Object.assign(Object.assign({},null==(a=null==(t=null==y?void 0:y.item)?void 0:t.styles)?void 0:a[e]),null==d?void 0:d[e])},I=$("list",i),k=s&&s.length>0&&a.default.createElement("ul",{className:(0,n.default)(`${I}-item-action`,O("actions")),key:"actions",style:C("actions")},s.map((e,t)=>a.default.createElement("li",{key:`${I}-item-action-${t}`},e,t!==s.length-1&&a.default.createElement("em",{className:`${I}-item-action-split`})))),E=a.default.createElement(x?"div":"li",Object.assign({},b,x?{}:{ref:t},{className:(0,n.default)(`${I}-item`,{[`${I}-item-no-flex`]:!("vertical"===A?!!c:(o=!1,a.Children.forEach(l,e=>{"string"==typeof e&&(o=!0)}),!(o&&a.Children.count(l)>1)))},u)}),"vertical"===A&&c?[a.default.createElement("div",{className:`${I}-item-main`,key:"content"},l,k),a.default.createElement("div",{className:(0,n.default)(`${I}-item-extra`,O("extra")),key:"extra",style:C("extra")},c)]:[l,k,(0,g.cloneElement)(c,{key:"extra"})]);return x?a.default.createElement(f.Col,{ref:t,flex:1,style:h},E):E});h.Meta=e=>{var{prefixCls:t,className:o,avatar:i,title:l,description:s}=e,c=v(e,["prefixCls","className","avatar","title","description"]);let{getPrefixCls:d}=(0,a.useContext)(r.ConfigContext),u=d("list",t),m=(0,n.default)(`${u}-item-meta`,o),p=a.default.createElement("div",{className:`${u}-item-meta-content`},l&&a.default.createElement("h4",{className:`${u}-item-meta-title`},l),s&&a.default.createElement("div",{className:`${u}-item-meta-description`},s));return a.default.createElement("div",Object.assign({},c,{className:m}),i&&a.default.createElement("div",{className:`${u}-item-meta-avatar`},i),(l||s)&&p)},e.i(296059);var b=e.i(915654),x=e.i(183293),A=e.i(246422),$=e.i(838378);let y=(0,A.genStyleHooks)("List",e=>{let t=(0,$.mergeToken)(e,{listBorderedCls:`${e.componentCls}-bordered`,minHeight:e.controlHeightLG});return[(e=>{let{componentCls:t,antCls:a,controlHeight:n,minHeight:o,paddingSM:i,marginLG:r,padding:l,itemPadding:s,colorPrimary:c,itemPaddingSM:d,itemPaddingLG:u,paddingXS:m,margin:p,colorText:g,colorTextDescription:f,motionDurationSlow:v,lineWidth:h,headerBg:A,footerBg:$,emptyTextPadding:y,metaMarginBottom:O,avatarMarginRight:C,titleMarginBottom:I,descriptionFontSize:k}=e;return{[t]:Object.assign(Object.assign({},(0,x.resetComponent)(e)),{position:"relative","--rc-virtual-list-scrollbar-bg":e.colorSplit,"*":{outline:"none"},[`${t}-header`]:{background:A},[`${t}-footer`]:{background:$},[`${t}-header, ${t}-footer`]:{paddingBlock:i},[`${t}-pagination`]:{marginBlockStart:r,[`${a}-pagination-options`]:{textAlign:"start"}},[`${t}-spin`]:{minHeight:o,textAlign:"center"},[`${t}-items`]:{margin:0,padding:0,listStyle:"none"},[`${t}-item`]:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:s,color:g,[`${t}-item-meta`]:{display:"flex",flex:1,alignItems:"flex-start",maxWidth:"100%",[`${t}-item-meta-avatar`]:{marginInlineEnd:C},[`${t}-item-meta-content`]:{flex:"1 0",width:0,color:g},[`${t}-item-meta-title`]:{margin:`0 0 ${(0,b.unit)(e.marginXXS)} 0`,color:g,fontSize:e.fontSize,lineHeight:e.lineHeight,"> a":{color:g,transition:`all ${v}`,"&:hover":{color:c}}},[`${t}-item-meta-description`]:{color:f,fontSize:k,lineHeight:e.lineHeight}},[`${t}-item-action`]:{flex:"0 0 auto",marginInlineStart:e.marginXXL,padding:0,fontSize:0,listStyle:"none","& > li":{position:"relative",display:"inline-block",padding:`0 ${(0,b.unit)(m)}`,color:f,fontSize:e.fontSize,lineHeight:e.lineHeight,textAlign:"center","&:first-child":{paddingInlineStart:0}},[`${t}-item-action-split`]:{position:"absolute",insetBlockStart:"50%",insetInlineEnd:0,width:h,height:e.calc(e.fontHeight).sub(e.calc(e.marginXXS).mul(2)).equal(),transform:"translateY(-50%)",backgroundColor:e.colorSplit}}},[`${t}-empty`]:{padding:`${(0,b.unit)(l)} 0`,color:f,fontSize:e.fontSizeSM,textAlign:"center"},[`${t}-empty-text`]:{padding:y,color:e.colorTextDisabled,fontSize:e.fontSize,textAlign:"center"},[`${t}-item-no-flex`]:{display:"block"}}),[`${t}-grid ${a}-col > ${t}-item`]:{display:"block",maxWidth:"100%",marginBlockEnd:p,paddingBlock:0,borderBlockEnd:"none"},[`${t}-vertical ${t}-item`]:{alignItems:"initial",[`${t}-item-main`]:{display:"block",flex:1},[`${t}-item-extra`]:{marginInlineStart:r},[`${t}-item-meta`]:{marginBlockEnd:O,[`${t}-item-meta-title`]:{marginBlockStart:0,marginBlockEnd:I,color:g,fontSize:e.fontSizeLG,lineHeight:e.lineHeightLG}},[`${t}-item-action`]:{marginBlockStart:l,marginInlineStart:"auto","> li":{padding:`0 ${(0,b.unit)(l)}`,"&:first-child":{paddingInlineStart:0}}}},[`${t}-split ${t}-item`]:{borderBlockEnd:`${(0,b.unit)(e.lineWidth)} ${e.lineType} ${e.colorSplit}`,"&:last-child":{borderBlockEnd:"none"}},[`${t}-split ${t}-header`]:{borderBlockEnd:`${(0,b.unit)(e.lineWidth)} ${e.lineType} ${e.colorSplit}`},[`${t}-split${t}-empty ${t}-footer`]:{borderTop:`${(0,b.unit)(e.lineWidth)} ${e.lineType} ${e.colorSplit}`},[`${t}-loading ${t}-spin-nested-loading`]:{minHeight:n},[`${t}-split${t}-something-after-last-item ${a}-spin-container > ${t}-items > ${t}-item:last-child`]:{borderBlockEnd:`${(0,b.unit)(e.lineWidth)} ${e.lineType} ${e.colorSplit}`},[`${t}-lg ${t}-item`]:{padding:u},[`${t}-sm ${t}-item`]:{padding:d},[`${t}:not(${t}-vertical)`]:{[`${t}-item-no-flex`]:{[`${t}-item-action`]:{float:"right"}}}}})(t),(e=>{let{listBorderedCls:t,componentCls:a,paddingLG:n,margin:o,itemPaddingSM:i,itemPaddingLG:r,marginLG:l,borderRadiusLG:s}=e,c=(0,b.unit)(e.calc(s).sub(e.lineWidth).equal());return{[t]:{border:`${(0,b.unit)(e.lineWidth)} ${e.lineType} ${e.colorBorder}`,borderRadius:s,[`${a}-header`]:{borderRadius:`${c} ${c} 0 0`},[`${a}-footer`]:{borderRadius:`0 0 ${c} ${c}`},[`${a}-header,${a}-footer,${a}-item`]:{paddingInline:n},[`${a}-pagination`]:{margin:`${(0,b.unit)(o)} ${(0,b.unit)(l)}`}},[`${t}${a}-sm`]:{[`${a}-item,${a}-header,${a}-footer`]:{padding:i}},[`${t}${a}-lg`]:{[`${a}-item,${a}-header,${a}-footer`]:{padding:r}}}})(t),(e=>{let{componentCls:t,screenSM:a,screenMD:n,marginLG:o,marginSM:i,margin:r}=e;return{[`@media screen and (max-width:${n}px)`]:{[t]:{[`${t}-item`]:{[`${t}-item-action`]:{marginInlineStart:o}}},[`${t}-vertical`]:{[`${t}-item`]:{[`${t}-item-extra`]:{marginInlineStart:o}}}},[`@media screen and (max-width: ${a}px)`]:{[t]:{[`${t}-item`]:{flexWrap:"wrap",[`${t}-action`]:{marginInlineStart:i}}},[`${t}-vertical`]:{[`${t}-item`]:{flexWrap:"wrap-reverse",[`${t}-item-main`]:{minWidth:e.contentWidth},[`${t}-item-extra`]:{margin:`auto auto ${(0,b.unit)(r)}`}}}}}})(t)]},e=>({contentWidth:220,itemPadding:`${(0,b.unit)(e.paddingContentVertical)} 0`,itemPaddingSM:`${(0,b.unit)(e.paddingContentVerticalSM)} ${(0,b.unit)(e.paddingContentHorizontal)}`,itemPaddingLG:`${(0,b.unit)(e.paddingContentVerticalLG)} ${(0,b.unit)(e.paddingContentHorizontalLG)}`,headerBg:"transparent",footerBg:"transparent",emptyTextPadding:e.padding,metaMarginBottom:e.padding,avatarMarginRight:e.padding,titleMarginBottom:e.paddingSM,descriptionFontSize:e.fontSize}));var O=function(e,t){var a={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&0>t.indexOf(n)&&(a[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,n=Object.getOwnPropertySymbols(e);ot.indexOf(n[o])&&Object.prototype.propertyIsEnumerable.call(e,n[o])&&(a[n[o]]=e[n[o]]);return a};let C=a.forwardRef(function(e,g){let{pagination:f=!1,prefixCls:v,bordered:h=!1,split:b=!0,className:x,rootClassName:A,style:$,children:C,itemLayout:I,loadMore:k,grid:E,dataSource:S=[],size:w,header:T,footer:M,loading:_=!1,rowKey:N,renderItem:L,locale:z}=e,j=O(e,["pagination","prefixCls","bordered","split","className","rootClassName","style","children","itemLayout","loadMore","grid","dataSource","size","header","footer","loading","rowKey","renderItem","locale"]),R=f&&"object"==typeof f?f:{},[D,H]=a.useState(R.defaultCurrent||1),[B,P]=a.useState(R.defaultPageSize||10),{getPrefixCls:V,direction:W,className:F,style:G}=(0,r.useComponentConfig)("list"),{renderEmpty:U}=a.useContext(r.ConfigContext),X=e=>(t,a)=>{var n;H(t),P(a),f&&(null==(n=null==f?void 0:f[e])||n.call(f,t,a))},K=X("onChange"),Y=X("onShowSizeChange"),Z=!!(k||f||M),q=V("list",v),[J,Q,ee]=y(q),et=_;"boolean"==typeof et&&(et={spinning:et});let ea=!!(null==et?void 0:et.spinning),en=(0,s.default)(w),eo="";switch(en){case"large":eo="lg";break;case"small":eo="sm"}let ei=(0,n.default)(q,{[`${q}-vertical`]:"vertical"===I,[`${q}-${eo}`]:eo,[`${q}-split`]:b,[`${q}-bordered`]:h,[`${q}-loading`]:ea,[`${q}-grid`]:!!E,[`${q}-something-after-last-item`]:Z,[`${q}-rtl`]:"rtl"===W},F,x,A,Q,ee),er=(0,o.default)({current:1,total:0,position:"bottom"},{total:S.length,current:D,pageSize:B},f||{}),el=Math.ceil(er.total/er.pageSize);er.current=Math.min(er.current,el);let es=f&&a.createElement("div",{className:(0,n.default)(`${q}-pagination`)},a.createElement(u.default,Object.assign({align:"end"},er,{onChange:K,onShowSizeChange:Y}))),ec=(0,t.default)(S);f&&S.length>(er.current-1)*er.pageSize&&(ec=(0,t.default)(S).splice((er.current-1)*er.pageSize,er.pageSize));let ed=Object.keys(E||{}).some(e=>["xs","sm","md","lg","xl","xxl"].includes(e)),eu=(0,d.default)(ed),em=a.useMemo(()=>{for(let e=0;e{if(!E)return;let e=em&&E[em]?E[em]:E.column;if(e)return{width:`${100/e}%`,maxWidth:`${100/e}%`}},[JSON.stringify(E),em]),eg=ea&&a.createElement("div",{style:{minHeight:53}});if(ec.length>0){let e=ec.map((e,t)=>{let n;return L?((n="function"==typeof N?N(e):N?e[N]:e.key)||(n=`list-item-${t}`),a.createElement(a.Fragment,{key:n},L(e,t))):null});eg=E?a.createElement(c.Row,{gutter:E.gutter},a.Children.map(e,e=>a.createElement("div",{key:null==e?void 0:e.key,style:ep},e))):a.createElement("ul",{className:`${q}-items`},e)}else C||ea||(eg=a.createElement("div",{className:`${q}-empty-text`},(null==z?void 0:z.emptyText)||(null==U?void 0:U("List"))||a.createElement(l.default,{componentName:"List"})));let ef=er.position,ev=a.useMemo(()=>({grid:E,itemLayout:I}),[JSON.stringify(E),I]);return J(a.createElement(p.Provider,{value:ev},a.createElement("div",Object.assign({ref:g,style:Object.assign(Object.assign({},G),$),className:ei},j),("top"===ef||"both"===ef)&&es,T&&a.createElement("div",{className:`${q}-header`},T),a.createElement(m.default,Object.assign({},et),eg,C),M&&a.createElement("div",{className:`${q}-footer`},M),k||("bottom"===ef||"both"===ef)&&es)))});C.Item=h,e.s(["List",0,C],573421)},837007,e=>{"use strict";var t=e.i(603908);e.s(["PlusIcon",()=>t.default])}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/00tczcrtv5upo.js b/litellm/proxy/_experimental/out/_next/static/chunks/00tczcrtv5upo.js deleted file mode 100644 index caf394915fd..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/00tczcrtv5upo.js +++ /dev/null @@ -1 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,337822,e=>{"use strict";var t,n=e.i(843476);e.s([],158421),e.i(158421);var i=e.i(271645),r=e.i(956789),a=e.i(17989),o=e.i(46420);e.i(247167);var s=e.i(733332);let l=i.createContext(void 0);function u(e){let t=i.useContext(l);if(void 0===t&&!e)throw Error((0,s.default)(47));return t}var d=e.i(174080),c=e.i(301252),p=e.i(616269),f=e.i(439957),g=e.i(56434),h=e.i(264111),v=e.i(116786),m=e.i(990627),S=e.i(638396);let b={...v.popupStoreSelectors,disabled:(0,p.createSelector)(e=>e.disabled),instantType:(0,p.createSelector)(e=>e.instantType),openMethod:(0,p.createSelector)(e=>e.openMethod),openChangeReason:(0,p.createSelector)(e=>e.openChangeReason),modal:(0,p.createSelector)(e=>e.modal),focusManagerModal:(0,p.createSelector)(e=>e.focusManagerModal),stickIfOpen:(0,p.createSelector)(e=>e.stickIfOpen),titleElementId:(0,p.createSelector)(e=>e.titleElementId),descriptionElementId:(0,p.createSelector)(e=>e.descriptionElementId),openOnHover:(0,p.createSelector)(e=>e.openOnHover),closeDelay:(0,p.createSelector)(e=>e.closeDelay),hasViewport:(0,p.createSelector)(e=>e.hasViewport)};class R extends c.ReactStore{constructor(e,t,n=!1){const r={...(0,v.createInitialPopupStoreState)(),disabled:!1,modal:!1,focusManagerModal:!1,instantType:void 0,openMethod:null,openChangeReason:null,titleElementId:void 0,descriptionElementId:void 0,stickIfOpen:!0,nested:!1,openOnHover:!1,closeDelay:0,hasViewport:!1,...e},a=new m.PopupTriggerMap;r.open&&e?.mounted===void 0&&(r.mounted=!0),r.floatingRootContext=(0,v.createPopupFloatingRootContext)(a,t,n),super(r,{popupRef:i.createRef(),backdropRef:i.createRef(),internalBackdropRef:i.createRef(),onOpenChange:void 0,onOpenChangeComplete:void 0,triggerFocusTargetRef:i.createRef(),beforeContentFocusGuardRef:i.createRef(),stickIfOpenTimeout:new f.Timeout,triggerElements:a},b)}setOpen=(e,t)=>{let n=t.reason===g.REASONS.triggerHover,i=t.reason===g.REASONS.triggerPress&&0===t.event.detail,r=!e&&(t.reason===g.REASONS.escapeKey||null==t.reason),a=(0,h.attachPreventUnmountOnClose)(t),o=this.select("activeTriggerId");if(e||t.reason!==g.REASONS.closePress||null!=t.trigger||null==o||(t.trigger=this.context.triggerElements.getById(o)??this.select("activeTriggerElement")??void 0),this.context.onOpenChange?.(e,t),t.isCanceled)return;this.state.floatingRootContext.dispatchOpenChange(e,t);let s=()=>{let n={open:e,openChangeReason:t.reason};(0,h.setPopupOpenState)(n,e,t.trigger,a()),this.update(n)};n?(this.set("stickIfOpen",!0),this.context.stickIfOpenTimeout.start(S.PATIENT_CLICK_THRESHOLD,()=>{this.set("stickIfOpen",!1)}),d.flushSync(s)):s(),i||r?this.set("instantType",i?"click":"dismiss"):t.reason===g.REASONS.focusOut?this.set("instantType","focus"):this.set("instantType",void 0)};static useStore(e,t){let{store:n,internalStore:r}=(0,h.usePopupStore)(e,(e,n)=>new R(t,e,n));return i.useEffect(()=>r?.disposeEffect(),[r]),n}disposeEffect=()=>this.context.stickIfOpenTimeout.disposeEffect()}var C=e.i(675606),y=e.i(176782);function E({props:e}){let{children:t,open:r,defaultOpen:a=!1,onOpenChange:s,onOpenChangeComplete:u,modal:d=!1,handle:c,triggerId:p,defaultTriggerId:f=null}=e,v=R.useStore(c?.store,{modal:d,open:a,openProp:r,activeTriggerId:f,triggerIdProp:p});(0,h.useInitialOpenSync)(v,r,a,f),v.useControlledProp("openProp",r),v.useControlledProp("triggerIdProp",p);let m=v.useState("open"),S=v.useState("mounted"),b=v.useState("payload"),y=null!=(0,o.useFloatingParentNodeId)();v.useContextCallback("onOpenChange",s),v.useContextCallback("onOpenChangeComplete",u),(0,h.usePopupRootSync)(v,m),(0,h.useImplicitActiveTrigger)(v);let{forceUnmount:P}=(0,h.useOpenStateTransitions)(m,v,()=>{v.update({stickIfOpen:!0,openChangeReason:null})});v.useSyncedValues({modal:d,nested:y}),i.useEffect(()=>{m||v.context.stickIfOpenTimeout.clear()},[v,m]);let O=i.useCallback(()=>{v.setOpen(!1,(0,C.createChangeEventDetails)(g.REASONS.imperativeAction))},[v]);i.useImperativeHandle(e.actionsRef,()=>({unmount:P,close:O}),[P,O]);let k=m||S,I=i.useMemo(()=>({store:v}),[v]);return(0,n.jsxs)(l.Provider,{value:I,children:[k&&(0,n.jsx)(x,{store:v,modal:d}),"function"==typeof t?t({payload:b}):t]})}function x({store:e,modal:t}){let n=e.useState("floatingRootContext"),o=(0,a.useDismiss)(n,{outsidePressEvent:{mouse:"trap-focus"===t?"sloppy":"intentional",touch:"sloppy"}}),s=o.reference??r.EMPTY_OBJECT,l=o.trigger??r.EMPTY_OBJECT,u=i.useMemo(()=>(0,y.mergeProps)(h.FOCUSABLE_POPUP_PROPS,o.floating),[o.floating]);return(0,h.usePopupInteractionProps)(e,{activeTriggerProps:s,inactiveTriggerProps:l,popupProps:u}),null}var P=e.i(540886),O=e.i(405005),k=e.i(552245),I=e.i(650316),w=e.i(385689),T=e.i(872135),M=e.i(788015),A=e.i(152535),F=e.i(346570),j=e.i(32199);let N=i.forwardRef(function(e,t){let{render:r,className:a,style:o,disabled:l=!1,nativeButton:d=!0,handle:c,payload:p,openOnHover:f=!1,delay:v=300,closeDelay:m=0,id:b,...R}=e,C=u(!0),y=c?.store??C?.store;if(!y)throw Error((0,s.default)(74));let E=(0,M.useBaseUiId)(b),x=y.useState("isTriggerActive",E),N=y.useState("floatingRootContext"),D=y.useState("isOpenedByTrigger",E),B=y.useState("triggerPopupId",E),H=i.useRef(null),{registerTrigger:L,isMountedByThisTrigger:V}=(0,h.useTriggerDataForwarding)(E,H,y,{payload:p,disabled:l,openOnHover:f,closeDelay:m}),z=y.useState("openChangeReason"),U=y.useState("stickIfOpen"),K=y.useState("openMethod"),_=y.useState("focusManagerModal"),W=(0,T.useHoverReferenceInteraction)(N,{enabled:!l&&null!=N&&f&&("touch"!==K||z!==g.REASONS.triggerPress),mouseOnly:!0,move:!1,handleClose:(0,I.safePolygon)(),restMs:v,delay:{close:m},triggerElementRef:H,isActiveTrigger:x,isClosing:()=>"ending"===y.select("transitionStatus")}),G=(0,w.useClick)(N,{enabled:null!=N,stickIfOpen:U}),q=(0,j.useOpenMethodTriggerProps)(()=>y.select("open"),e=>{y.set("openMethod",e)}),Y=y.useState("triggerProps",V),{getButtonProps:J,buttonRef:$}=(0,P.useButton)({disabled:l,native:d}),{preFocusGuardRef:Q,handlePreFocusGuardFocus:X,handleFocusTargetFocus:Z}=(0,F.useTriggerFocusGuards)(y,H),ee=(0,k.useRenderElement)("button",e,{state:{disabled:l,open:D},ref:[$,t,L,H],props:[G.reference,W,Y,q,{[S.CLICK_TRIGGER_IDENTIFIER]:"",id:E,"aria-haspopup":"dialog","aria-expanded":D,"aria-controls":B},R,J],stateAttributesMapping:{open:e=>e&&z===g.REASONS.triggerPress?O.pressableTriggerOpenStateMapping.open(e):O.triggerOpenStateMapping.open(e)}});return V&&!_?(0,n.jsxs)(i.Fragment,{children:[(0,n.jsx)(A.FocusGuard,{ref:Q,onFocus:X}),(0,n.jsx)(i.Fragment,{children:ee},E),(0,n.jsx)(A.FocusGuard,{ref:y.context.triggerFocusTargetRef,onFocus:Z})]}):(0,n.jsx)(i.Fragment,{children:ee},E)});var D=e.i(726674);let B=i.createContext(void 0),H=i.forwardRef(function(e,t){let{keepMounted:i=!1,...r}=e,{store:a}=u();return a.useState("mounted")||i?(0,n.jsx)(B.Provider,{value:i,children:(0,n.jsx)(D.FloatingPortal,{ref:t,...r})}):null});var L=e.i(144394),V=e.i(146376);let z=i.createContext(void 0);function U(){let e=i.useContext(z);if(!e)throw Error((0,s.default)(46));return e}var K=e.i(329365),_=e.i(426),W=e.i(222640),G=e.i(360495),q=e.i(789579),Y=e.i(33383);let J=i.forwardRef(function(e,t){let{render:r,className:a,style:l,anchor:d,positionMethod:c="absolute",side:p="bottom",align:f="center",sideOffset:h=0,alignOffset:v=0,collisionBoundary:m="clipping-ancestors",collisionPadding:b=5,arrowPadding:R=5,sticky:C=!1,disableAnchorTracking:y=!1,collisionAvoidance:E=S.POPUP_COLLISION_AVOIDANCE,...x}=e,{store:P}=u(),O=function(){let e=i.useContext(B);if(void 0===e)throw Error((0,s.default)(45));return e}(),k=(0,o.useFloatingNodeId)(),I=P.useState("floatingRootContext"),w=P.useState("mounted"),T=P.useState("open"),M=P.useState("openChangeReason"),A=P.useState("activeTriggerElement"),F=P.useState("modal"),j=P.useState("openMethod"),N=P.useState("positionerElement"),D=P.useState("instantType"),H=P.useState("transitionStatus"),U=P.useState("hasViewport"),J=i.useRef(null),$=(0,W.useAnimationsFinished)(N,!1,!1),Q=(0,K.useAnchorPositioning)({anchor:d,floatingRootContext:I,positionMethod:c,mounted:w,side:p,sideOffset:h,align:f,alignOffset:v,arrowPadding:R,collisionBoundary:m,collisionPadding:b,sticky:C,disableAnchorTracking:y,keepMounted:O,nodeId:k,collisionAvoidance:E,adaptiveOrigin:U?G.adaptiveOrigin:void 0}),X=I.useState("domReferenceElement");(0,V.useIsoLayoutEffect)(()=>{let e=J.current;if(X&&(J.current=X),e&&X&&X!==e){P.set("instantType",void 0);let e=new AbortController;return $(()=>{P.set("instantType","trigger-change")},e.signal),()=>{e.abort()}}},[X,$,P]),(0,Y.useAnchoredPopupScrollLock)(T&&!0===F&&M!==g.REASONS.triggerHover,"touch"===j,N,A);let Z=i.useCallback(e=>{P.set("positionerElement",e)},[P]),ee={open:T,side:Q.side,align:Q.align,anchorHidden:Q.anchorHidden,instant:D},et=(0,q.usePositioner)(e,ee,{styles:Q.positionerStyles,transitionStatus:H,props:x,refs:[t,Z],hidden:!w,inert:!T});return(0,n.jsxs)(z.Provider,{value:Q,children:[w&&!0===F&&M!==g.REASONS.triggerHover&&(0,n.jsx)(_.InternalBackdrop,{ref:P.context.internalBackdropRef,inert:(0,L.inertValue)(!T),cutout:A}),(0,n.jsx)(o.FloatingNode,{id:k,children:et})]})});var $=e.i(229315),Q=e.i(61487),X=e.i(431157),Z=e.i(209407),ee=e.i(137584),et=e.i(673327),en=e.i(96533),ei=e.i(815982),er=e.i(667865);let ea=i.createContext(void 0);function eo(e){let{value:t,children:i}=e;return(0,n.jsx)(ea.Provider,{value:t,children:i})}let es={...O.popupStateMapping,...Z.transitionStatusMapping},el=i.forwardRef(function(e,t){let{render:r,className:a,style:o,initialFocus:s,finalFocus:l,...d}=e,{store:c}=u(),p=U(),f=null!=(0,en.useToolbarRootContext)(!0),{context:v,hasClosePart:m}=function(){let[e,t]=i.useState(0),n=(0,er.useStableCallback)(()=>(t(e=>e+1),()=>{t(e=>Math.max(0,e-1))}));return{context:i.useMemo(()=>({register:n}),[n]),hasClosePart:e>0}}(),S=c.useState("open"),b=c.useState("openMethod"),R=c.useState("instantType"),C=c.useState("transitionStatus"),y=c.useState("popupProps"),E=c.useState("titleElementId"),x=c.useState("descriptionElementId"),P=c.useState("modal"),O=c.useState("mounted"),I=c.useState("openChangeReason"),w=c.useState("activeTriggerElement"),T=c.useState("floatingRootContext"),M=T.useState("floatingId"),A=c.useState("disabled"),F=c.useState("openOnHover"),j=c.useState("closeDelay"),N=d.id??M;(0,ee.useOpenChangeComplete)({open:S,ref:c.context.popupRef,onComplete(){S&&c.context.onOpenChangeComplete?.(!0)}}),(0,X.useHoverFloatingInteraction)(T,{enabled:F&&!A,closeDelay:j});let D=void 0===s?(0,h.createDefaultInitialFocus)(c.context.popupRef):s,B=!1!==P&&m;c.useSyncedValue("focusManagerModal",B);let H=i.useCallback(e=>{c.set("popupElement",e)},[c]),L={open:S,side:p.side,align:p.align,instant:R,transitionStatus:C},V=(0,k.useRenderElement)("div",e,{state:L,ref:[t,c.context.popupRef,H],props:[y,{id:N,role:"dialog",...h.FOCUSABLE_POPUP_PROPS,"aria-labelledby":E,"aria-describedby":x,onKeyDown(e){f&&et.COMPOSITE_KEYS.has(e.key)&&e.stopPropagation()}},(0,ei.getDisabledMountTransitionStyles)(C),d],stateAttributesMapping:es});return(0,n.jsx)(Q.FloatingFocusManager,{context:T,openInteractionType:b,modal:B,disabled:!O||I===g.REASONS.triggerHover,initialFocus:D,returnFocus:l,restoreFocus:"popup",previousFocusableElement:(0,$.isHTMLElement)(w)?w:void 0,nextFocusableElement:c.context.triggerFocusTargetRef,beforeContentFocusGuardRef:c.context.beforeContentFocusGuardRef,children:(0,n.jsx)(eo,{value:v,children:V})})}),eu=i.forwardRef(function(e,t){let{render:n,className:i,style:r,...a}=e,{store:o}=u(),s=o.useState("open"),{arrowRef:l,side:d,align:c,arrowUncentered:p,arrowStyles:f}=U();return(0,k.useRenderElement)("div",e,{state:{open:s,side:d,align:c,uncentered:p},ref:[t,l],props:[{style:f,"aria-hidden":!0},a],stateAttributesMapping:O.popupStateMapping})}),ed={...O.popupStateMapping,...Z.transitionStatusMapping},ec=i.forwardRef(function(e,t){let{render:n,className:i,style:r,...a}=e,{store:o}=u(),s=o.useState("open"),l=o.useState("mounted"),d=o.useState("transitionStatus"),c=o.useState("openChangeReason");return(0,k.useRenderElement)("div",e,{state:{open:s,transitionStatus:d},ref:[o.context.backdropRef,t],props:[{role:"presentation",hidden:!l,style:{pointerEvents:c===g.REASONS.triggerHover?"none":void 0,userSelect:"none",WebkitUserSelect:"none"}},a],stateAttributesMapping:ed})}),ep=i.forwardRef(function(e,t){let{render:n,className:i,style:r,...a}=e,{store:o}=u(),s=(0,M.useBaseUiId)(a.id);return o.useSyncedValueWithCleanup("titleElementId",s),(0,k.useRenderElement)("h2",e,{ref:t,props:[{id:s},a]})}),ef=i.forwardRef(function(e,t){let{render:n,className:i,style:r,...a}=e,{store:o}=u(),s=(0,M.useBaseUiId)(a.id);return o.useSyncedValueWithCleanup("descriptionElementId",s),(0,k.useRenderElement)("p",e,{ref:t,props:[{id:s},a]})}),eg=i.forwardRef(function(e,t){let n,{render:r,className:a,style:o,disabled:s=!1,nativeButton:l=!0,...d}=e,{buttonRef:c,getButtonProps:p}=(0,P.useButton)({disabled:s,focusableWhenDisabled:!1,native:l}),{store:f}=u();return n=i.useContext(ea),(0,V.useIsoLayoutEffect)(()=>n?.register(),[n]),(0,k.useRenderElement)("button",e,{ref:[t,c],props:[{onClick(e){f.setOpen(!1,(0,C.createChangeEventDetails)(g.REASONS.closePress,e.nativeEvent))}},d,p]})}),eh=((t={}).popupWidth="--popup-width",t.popupHeight="--popup-height",t);var ev=e.i(818390);let em={activationDirection:e=>e?{"data-activation-direction":e}:null},eS=i.forwardRef(function(e,t){let{render:n,className:i,style:r,children:a,...o}=e,{store:s}=u(),{side:l}=U(),d=s.useState("instantType"),{children:c,state:p}=(0,ev.usePopupViewport)({store:s,side:l,cssVars:eh,children:a}),f={activationDirection:p.activationDirection,transitioning:p.transitioning,instant:d};return(0,k.useRenderElement)("div",e,{state:f,ref:t,props:[o,{children:c}],stateAttributesMapping:em})});class eb{constructor(){this.store=new R}open(e){let t=e?this.store.context.triggerElements.getById(e)??void 0:void 0;if(e&&!t)throw Error((0,s.default)(80,e));this.store.setOpen(!0,(0,C.createChangeEventDetails)(g.REASONS.imperativeAction,void 0,t))}close(){this.store.setOpen(!1,(0,C.createChangeEventDetails)(g.REASONS.imperativeAction,void 0,void 0))}get isOpen(){return this.store.select("open")}}e.s(["Arrow",0,eu,"Backdrop",0,ec,"Close",0,eg,"Description",0,ef,"Handle",0,eb,"Popup",0,el,"Portal",0,H,"Positioner",0,J,"Root",0,function(e){return u(!0)?(0,n.jsx)(E,{props:e}):(0,n.jsx)(o.FloatingTree,{children:(0,n.jsx)(E,{props:e})})},"Title",0,ep,"Trigger",0,N,"Viewport",0,eS,"createHandle",0,function(){return new eb}],466914);var eR=e.i(466914),eR=eR,eC=e.i(115504);e.s(["Popover",0,function({...e}){return(0,n.jsx)(eR.Root,{"data-slot":"popover",...e})},"PopoverContent",0,function({className:e,align:t="center",alignOffset:i=0,side:r="bottom",sideOffset:a=4,...o}){return(0,n.jsx)(eR.Portal,{children:(0,n.jsx)(eR.Positioner,{align:t,alignOffset:i,side:r,sideOffset:a,className:"isolate z-50",children:(0,n.jsx)(eR.Popup,{"data-slot":"popover-content",className:(0,eC.cn)("z-50 flex w-72 origin-(--transform-origin) flex-col gap-4 rounded-md bg-popover p-4 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",e),...o})})})},"PopoverTrigger",0,function({...e}){return(0,n.jsx)(eR.Trigger,{"data-slot":"popover-trigger",...e})}],337822)},204258,e=>{"use strict";var t,n,i,r=e.i(843476);e.s([],958842),e.i(958842),e.i(247167);var a=e.i(271645),o=e.i(667865),s=e.i(552245),l=e.i(951437),u=e.i(788015),d=e.i(675606),c=e.i(56434),p=e.i(223910),f=e.i(733332);let g=a.createContext(void 0);function h(){let e=a.useContext(g);if(void 0===e)throw Error((0,f.default)(15));return e}var v=e.i(209407);let m=((t={}).open="data-open",t.closed="data-closed",t[t.startingStyle=v.TransitionStatusDataAttributes.startingStyle]="startingStyle",t[t.endingStyle=v.TransitionStatusDataAttributes.endingStyle]="endingStyle",t),S=((n={}).panelOpen="data-panel-open",n),b={[m.open]:""},R={[m.closed]:""},C={open:e=>e?b:R,...v.transitionStatusMapping},y=a.forwardRef(function(e,t){let{render:n,className:i,defaultOpen:f=!1,disabled:h=!1,onOpenChange:v,open:m,style:S,...b}=e,R=(0,o.useStableCallback)(v),y=function(e){let{open:t,defaultOpen:n,onOpenChange:i,disabled:r}=e,[s,f]=(0,l.useControlled)({controlled:t,default:n,name:"Collapsible",state:"open"}),{mounted:g,setMounted:h,transitionStatus:v}=(0,p.useTransitionStatus)(s,!0,!0),m=(0,u.useBaseUiId)(),[S,b]=a.useState(),R=S??m,C=(0,o.useStableCallback)(e=>{let t=!s,n=(0,d.createChangeEventDetails)(c.REASONS.triggerPress,e.nativeEvent);i(t,n),n.isCanceled||f(t)});return a.useMemo(()=>({disabled:r,handleTrigger:C,mounted:g,open:s,panelId:R,setMounted:h,setOpen:f,setPanelIdState:b,transitionStatus:v}),[r,C,g,s,R,h,f,b,v])}({open:m,defaultOpen:f,onOpenChange:R,disabled:h}),E=a.useMemo(()=>({open:y.open,disabled:y.disabled,transitionStatus:y.transitionStatus}),[y.open,y.disabled,y.transitionStatus]),x=a.useMemo(()=>({...y,onOpenChange:R,state:E}),[y,R,E]),P=(0,s.useRenderElement)("div",e,{state:E,ref:t,props:b,stateAttributesMapping:C});return(0,r.jsx)(g.Provider,{value:x,children:P})});var E=e.i(540886);let x={open:e=>e?{[S.panelOpen]:""}:null,...v.transitionStatusMapping},P=a.forwardRef(function(e,t){let{panelId:n,open:i,handleTrigger:r,state:a,disabled:o}=h(),{className:l,disabled:u=o,render:d,nativeButton:c=!0,style:p,...f}=e,{getButtonProps:g,buttonRef:v}=(0,E.useButton)({disabled:u,focusableWhenDisabled:!0,native:c});return(0,s.useRenderElement)("button",e,{state:a,ref:[t,v],props:[{"aria-controls":i?n:void 0,"aria-expanded":i,onClick:r},f,g],stateAttributesMapping:x})});var O=e.i(146376),k=e.i(377570),I=e.i(574735),w=e.i(828918),T=e.i(708445),M=e.i(446265),A=e.i(333848),F=e.i(137584),j=e.i(222640);let N={height:void 0,width:void 0};function D(e){return{height:e.scrollHeight,width:e.scrollWidth}}function B(e){return e.split(",").map(e=>e.trim()).some(e=>""!==e&&Number.parseFloat(e)>0)}function H(e,t,n){let i=e.style.getPropertyValue(t),r=e.style.getPropertyPriority(t);return e.style.setProperty(t,n),()=>{""===i?e.style.removeProperty(t):e.style.setProperty(t,i,r)}}let L=((i={}).collapsiblePanelHeight="--collapsible-panel-height",i.collapsiblePanelWidth="--collapsible-panel-width",i),V=a.forwardRef(function(e,t){let{className:n,hiddenUntilFound:i,keepMounted:r,render:l,id:u,style:p,...f}=e,{mounted:g,onOpenChange:v,open:S,panelId:b,setMounted:R,setPanelIdState:y,setOpen:E,state:x,transitionStatus:P}=h();(0,O.useIsoLayoutEffect)(()=>{if(u)return y(u),()=>{y(void 0)}},[u,y]);let{height:V,props:z,ref:U,shouldPreventOpenAnimation:K,shouldRender:_,transitionStatus:W,width:G}=function(e){let{externalRef:t,hiddenUntilFound:n,id:i,keepMounted:r,mounted:s,onOpenChange:l,open:u,setMounted:p,setOpen:f,transitionStatus:g}=e,h=a.useRef(null),v=a.useRef(null),[S,b]=a.useState(N),R=a.useRef(N),C=a.useRef(!1),y=a.useRef(u),E=a.useRef(!1),[x,P]=a.useState(!1),k=a.useRef(null),L=(0,w.useMergedRefs)(t,h),V=(0,M.useValueAsRef)({mounted:s,open:u}),z=(0,j.useAnimationsFinished)(h,!1,!1),U=!u&&!s,K=x?"idle":g,_=u&&(y.current||E.current),W=!u&&s&&"css-animation"===v.current&&void 0===S.height&&void 0===S.width?R.current:S,G=n&&U&&"css-animation"!==v.current,q=(0,o.useStableCallback)((e,t=!0)=>{t&&(R.current=e),b(e)}),Y=(0,o.useStableCallback)(()=>{k.current?.(),k.current=null}),J=(0,o.useStableCallback)(e=>{Y(),k.current=()=>{k.current=null,e()}}),$=(0,o.useStableCallback)(()=>{u&&s&&"css-animation"===v.current&&(E.current=!0)});(0,O.useIsoLayoutEffect)(()=>{x&&"starting"!==g&&P(!1)},[x,g]),a.useEffect(()=>()=>{$(),Y()},[$,Y]),(0,O.useIsoLayoutEffect)(()=>{let e=h.current;if(!e)return;!u&&k.current&&Y();let t=function(e,t=!1){let n=(0,A.ownerWindow)(e).getComputedStyle(e),i=(n.animationName.split(",").map(e=>e.trim()).some(e=>""!==e&&"none"!==e)||t)&&B(n.animationDuration),r=B(n.transitionDuration);return i&&r||r?"css-transition":i?"css-animation":"none"}(e,_);if(v.current=t,u&&"idle"===g&&y.current&&"css-animation"===t){R.current=D(e);return}if(u&&"starting"===g){let n=C.current;if(C.current=!1,"none"===t){q(D(e)),P(!0);return}if("css-transition"===t){let t=function(e){let t={"justify-content":e.style.justifyContent,"align-items":e.style.alignItems,"align-content":e.style.alignContent,"justify-items":e.style.justifyItems};function n(){Object.entries(t).forEach(([t,n])=>{""===n?e.style.removeProperty(t):e.style.setProperty(t,n)})}Object.keys(t).forEach(t=>{e.style.setProperty(t,"initial","important")});let i=T.AnimationFrame.request(n);return()=>{T.AnimationFrame.cancel(i),n()}}(e);return q(D(e)),n&&(J(H(e,"transition-duration","0s")),P(!0)),t}if("css-animation"===t){if(q(D(e)),!n)return void H(e,"animation-name","none")();let t=H(e,"animation-name","none"),i=H(e,"animation-duration","0s");return t(),J(i),P(!0),void 0}}if(!u&&s&&("idle"===g||"starting"===g)){if(y.current=!1,E.current=!1,"none"===t){q(N,!1),p(!1);return}q(D(e));return}if("ending"!==g)return;if("none"===t)return void p(!1);let n=D(e);(n.height??0)>0||(n.width??0)>0?(q(n),"css-animation"===t&&H(e,"animation-name","none")()):p(!1)},[s,u,Y,q,p,J,_,g]),(0,F.useOpenChangeComplete)({enabled:u&&s&&"idle"===K,open:!0,ref:h,onComplete(){u&&q(N,!1)}}),a.useEffect(()=>{if(u||!s||"ending"!==K||!h.current)return;let e=new AbortController,t=-1;function n(){V.current.open||(p(!1),q(N,!1))}return t=T.AnimationFrame.request(()=>{e.signal.aborted||z(n,e.signal)}),()=>{T.AnimationFrame.cancel(t),e.abort()}},[V,s,u,K,z,q,p]),(0,O.useIsoLayoutEffect)(()=>{let e=h.current;e&&n&&U&&e.setAttribute("hidden","until-found")},[U,n]),a.useEffect(function(){let e=h.current;if(e)return(0,I.addEventListener)(e,"beforematch",function(e){let t=(0,d.createChangeEventDetails)(c.REASONS.none,e);l(!0,t),t.isCanceled||(C.current=!0,f(!0))})},[l,f]);let Q=r||n||s||u;return{height:W.height,props:{...G?{[m.startingStyle]:""}:void 0,hidden:U,id:i},ref:L,shouldPreventOpenAnimation:_,shouldRender:Q,transitionStatus:K,width:W.width}}({externalRef:t,hiddenUntilFound:i??!1,id:b,keepMounted:r??!1,mounted:g,onOpenChange:v,open:S,setMounted:R,setOpen:E,transitionStatus:P}),q={...x,transitionStatus:W},Y=(0,k.resolveStyle)(p,q),J=(0,s.useRenderElement)("div",{...e,style:void 0},{state:q,ref:U,props:[z,{style:{[L.collapsiblePanelHeight]:void 0===V?"auto":`${V}px`,[L.collapsiblePanelWidth]:void 0===G?"auto":`${G}px`}},f,Y?{style:Y}:void 0,K?{style:{animationName:"none"}}:void 0],stateAttributesMapping:C});return _?J:null});e.s(["Panel",0,V,"Root",0,y,"Trigger",0,P],596315);var z=e.i(596315),z=z;e.s(["Collapsible",0,function({...e}){return(0,r.jsx)(z.Root,{"data-slot":"collapsible",...e})},"CollapsibleContent",0,function({...e}){return(0,r.jsx)(z.Panel,{"data-slot":"collapsible-content",...e})},"CollapsibleTrigger",0,function({...e}){return(0,r.jsx)(z.Trigger,{"data-slot":"collapsible-trigger",...e})}],204258)},699375,e=>{"use strict";var t,n=e.i(843476);e.s([],924305),e.i(924305),e.i(247167);var i=e.i(271645),r=e.i(951437),a=e.i(828918),o=e.i(146376),s=e.i(502077),l=e.i(956789),u=e.i(333848),d=e.i(552245),c=e.i(176782),p=e.i(788015),f=e.i(540886),g=e.i(733332);let h=i.createContext(void 0);var v=e.i(875812);let m=((t={}).checked="data-checked",t.unchecked="data-unchecked",t.disabled="data-disabled",t.readonly="data-readonly",t.required="data-required",t.valid="data-valid",t.invalid="data-invalid",t.touched="data-touched",t.dirty="data-dirty",t.filled="data-filled",t.focused="data-focused",t),S={...v.fieldValidityMapping,checked:e=>e?{[m.checked]:""}:{[m.unchecked]:""}};var b=e.i(469690),R=e.i(381104),C=e.i(884708),y=e.i(247778),E=e.i(538489),x=e.i(675606),P=e.i(56434),O=e.i(606039);let k=i.forwardRef(function(e,t){let{checked:g,className:v,defaultChecked:m,"aria-labelledby":k,form:I,id:w,inputRef:T,name:M,nativeButton:A=!1,onCheckedChange:F,readOnly:j=!1,required:N=!1,disabled:D=!1,render:B,uncheckedValue:H,value:L,style:V,...z}=e,{clearErrors:U}=(0,C.useFormContext)(),{state:K,setTouched:_,setDirty:W,validityData:G,setFilled:q,setFocused:Y,validationMode:J,disabled:$,name:Q,validation:X}=(0,b.useFieldRootContext)(),{labelId:Z}=(0,y.useLabelableContext)(),ee=$||D,et=Q??M,en=i.useRef(null),ei=(0,a.useMergedRefs)(en,T,X.inputRef),er=i.useRef(null),ea=(0,p.useBaseUiId)(),eo=(0,E.useLabelableId)({id:w,implicit:!1,controlRef:er}),es=A?void 0:eo,[el,eu]=(0,r.useControlled)({controlled:g,default:!!m,name:"Switch",state:"checked"});(0,R.useRegisterFieldControl)(er,ea,el,void 0,!ee,M),(0,o.useIsoLayoutEffect)(()=>{en.current&&q(en.current.checked)},[en,q]),(0,O.useValueChanged)(el,()=>{U(et),W(el!==G.initialValue),q(el),X.change(el)});let{getButtonProps:ed,buttonRef:ec}=(0,f.useButton)({disabled:ee,native:A}),ep=function(e,t,n,r=!0,a){let[s,l]=i.useState(),u=(0,p.useBaseUiId)(a?`${a}-label`:void 0),d=e??t??s;return(0,o.useIsoLayoutEffect)(()=>{let i=e||t||!r?void 0:function(e,t){let n=function(e){if(!e)return;let t=e.parentElement;if(t&&"LABEL"===t.tagName)return t;let n=e.id;if(n){let t=e.nextElementSibling;if(t&&t.htmlFor===n)return t}let i=e.labels;return i&&i[0]}(e);if(n)return!n.id&&t&&(n.id=t),n.id||void 0}(n.current,u);s!==i&&l(i)}),d}(k,Z,en,!A,es),ef=(0,c.mergeProps)({checked:el,disabled:ee,form:I,id:es,name:et,required:N,style:et?s.visuallyHiddenInput:s.visuallyHidden,tabIndex:-1,type:"checkbox","aria-hidden":!0,ref:ei,onChange(e){if(e.nativeEvent.defaultPrevented)return;if(j)return void e.preventDefault();let t=e.currentTarget.checked,n=(0,x.createChangeEventDetails)(P.REASONS.none,e.nativeEvent);F?.(t,n),n.isCanceled||eu(t)},onFocus(){er.current?.focus()}},e=>X.getValidationProps(ee,e),void 0!==L?{value:L}:l.EMPTY_OBJECT),eg=i.useMemo(()=>({...K,checked:el,disabled:ee,readOnly:j,required:N}),[K,el,ee,j,N]),eh=(0,d.useRenderElement)("span",e,{state:eg,ref:[t,er,ec],props:[{id:A?eo:ea,role:"switch","aria-checked":el,"aria-readonly":j||void 0,"aria-required":N||void 0,"aria-labelledby":ep,onFocus(){ee||Y(!0)},onBlur(){let e=en.current;e&&!ee&&(_(!0),Y(!1),"onBlur"===J&&X.commit(e.checked))},onClick(e){if(j||ee)return;e.preventDefault();let t=en.current;t&&t.dispatchEvent(new((0,u.ownerWindow)(t)).PointerEvent("click",{bubbles:!0,shiftKey:e.shiftKey,ctrlKey:e.ctrlKey,altKey:e.altKey,metaKey:e.metaKey}))}},z,ed,e=>X.getValidationProps(ee,e)],stateAttributesMapping:S});return(0,n.jsxs)(h.Provider,{value:eg,children:[eh,!el&&et&&void 0!==H&&(0,n.jsx)("input",{type:"hidden",form:I,name:et,value:H,disabled:ee}),(0,n.jsx)("input",{...ef,suppressHydrationWarning:!0})]})}),I=i.forwardRef(function(e,t){let{render:n,className:r,style:a,...o}=e,s=function(){let e=i.useContext(h);if(void 0===e)throw Error((0,g.default)(63));return e}();return(0,d.useRenderElement)("span",e,{state:s,ref:t,stateAttributesMapping:S,props:o})});e.s(["Root",0,k,"Thumb",0,I],450994);var w=e.i(450994),w=w,T=e.i(115504);e.s(["Switch",0,function({className:e,size:t="default",...i}){return(0,n.jsx)(w.Root,{"data-slot":"switch","data-size":t,className:(0,T.cn)("peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50",e),...i,children:(0,n.jsx)(w.Thumb,{"data-slot":"switch-thumb",className:"pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] dark:data-checked:bg-primary-foreground group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-unchecked:bg-foreground"})})}],699375)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/00zxtugv201bq.js b/litellm/proxy/_experimental/out/_next/static/chunks/00zxtugv201bq.js deleted file mode 100644 index 527c4632dc8..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/00zxtugv201bq.js +++ /dev/null @@ -1,8 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,185793,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(343794),n=e.i(242064),r=e.i(529681);let o=e=>{let{prefixCls:n,className:r,style:o,size:i,shape:l}=e,s=(0,a.default)({[`${n}-lg`]:"large"===i,[`${n}-sm`]:"small"===i}),u=(0,a.default)({[`${n}-circle`]:"circle"===l,[`${n}-square`]:"square"===l,[`${n}-round`]:"round"===l}),d=t.useMemo(()=>"number"==typeof i?{width:i,height:i,lineHeight:`${i}px`}:{},[i]);return t.createElement("span",{className:(0,a.default)(n,s,u,r),style:Object.assign(Object.assign({},d),o)})};e.i(296059);var i=e.i(694758),l=e.i(915654),s=e.i(246422),u=e.i(838378);let d=new i.Keyframes("ant-skeleton-loading",{"0%":{backgroundPosition:"100% 50%"},"100%":{backgroundPosition:"0 50%"}}),c=e=>({height:e,lineHeight:(0,l.unit)(e)}),p=e=>Object.assign({width:e},c(e)),g=(e,t)=>Object.assign({width:t(e).mul(5).equal(),minWidth:t(e).mul(5).equal()},c(e)),m=e=>Object.assign({width:e},c(e)),f=(e,t,a)=>{let{skeletonButtonCls:n}=e;return{[`${a}${n}-circle`]:{width:t,minWidth:t,borderRadius:"50%"},[`${a}${n}-round`]:{borderRadius:t}}},b=(e,t)=>Object.assign({width:t(e).mul(2).equal(),minWidth:t(e).mul(2).equal()},c(e)),h=(0,s.genStyleHooks)("Skeleton",e=>{let{componentCls:t,calc:a}=e;return(e=>{let{componentCls:t,skeletonAvatarCls:a,skeletonTitleCls:n,skeletonParagraphCls:r,skeletonButtonCls:o,skeletonInputCls:i,skeletonImageCls:l,controlHeight:s,controlHeightLG:u,controlHeightSM:c,gradientFromColor:h,padding:x,marginSM:C,borderRadius:v,titleHeight:y,blockRadius:S,paragraphLiHeight:O,controlHeightXS:D,paragraphMarginTop:w}=e;return{[t]:{display:"table",width:"100%",[`${t}-header`]:{display:"table-cell",paddingInlineEnd:x,verticalAlign:"top",[a]:Object.assign({display:"inline-block",verticalAlign:"top",background:h},p(s)),[`${a}-circle`]:{borderRadius:"50%"},[`${a}-lg`]:Object.assign({},p(u)),[`${a}-sm`]:Object.assign({},p(c))},[`${t}-content`]:{display:"table-cell",width:"100%",verticalAlign:"top",[n]:{width:"100%",height:y,background:h,borderRadius:S,[`+ ${r}`]:{marginBlockStart:c}},[r]:{padding:0,"> li":{width:"100%",height:O,listStyle:"none",background:h,borderRadius:S,"+ li":{marginBlockStart:D}}},[`${r}> li:last-child:not(:first-child):not(:nth-child(2))`]:{width:"61%"}},[`&-round ${t}-content`]:{[`${n}, ${r} > li`]:{borderRadius:v}}},[`${t}-with-avatar ${t}-content`]:{[n]:{marginBlockStart:C,[`+ ${r}`]:{marginBlockStart:w}}},[`${t}${t}-element`]:Object.assign(Object.assign(Object.assign(Object.assign({display:"inline-block",width:"auto"},(e=>{let{borderRadiusSM:t,skeletonButtonCls:a,controlHeight:n,controlHeightLG:r,controlHeightSM:o,gradientFromColor:i,calc:l}=e;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({[a]:Object.assign({display:"inline-block",verticalAlign:"top",background:i,borderRadius:t,width:l(n).mul(2).equal(),minWidth:l(n).mul(2).equal()},b(n,l))},f(e,n,a)),{[`${a}-lg`]:Object.assign({},b(r,l))}),f(e,r,`${a}-lg`)),{[`${a}-sm`]:Object.assign({},b(o,l))}),f(e,o,`${a}-sm`))})(e)),(e=>{let{skeletonAvatarCls:t,gradientFromColor:a,controlHeight:n,controlHeightLG:r,controlHeightSM:o}=e;return{[t]:Object.assign({display:"inline-block",verticalAlign:"top",background:a},p(n)),[`${t}${t}-circle`]:{borderRadius:"50%"},[`${t}${t}-lg`]:Object.assign({},p(r)),[`${t}${t}-sm`]:Object.assign({},p(o))}})(e)),(e=>{let{controlHeight:t,borderRadiusSM:a,skeletonInputCls:n,controlHeightLG:r,controlHeightSM:o,gradientFromColor:i,calc:l}=e;return{[n]:Object.assign({display:"inline-block",verticalAlign:"top",background:i,borderRadius:a},g(t,l)),[`${n}-lg`]:Object.assign({},g(r,l)),[`${n}-sm`]:Object.assign({},g(o,l))}})(e)),(e=>{let{skeletonImageCls:t,imageSizeBase:a,gradientFromColor:n,borderRadiusSM:r,calc:o}=e;return{[t]:Object.assign(Object.assign({display:"inline-flex",alignItems:"center",justifyContent:"center",verticalAlign:"middle",background:n,borderRadius:r},m(o(a).mul(2).equal())),{[`${t}-path`]:{fill:"#bfbfbf"},[`${t}-svg`]:Object.assign(Object.assign({},m(a)),{maxWidth:o(a).mul(4).equal(),maxHeight:o(a).mul(4).equal()}),[`${t}-svg${t}-svg-circle`]:{borderRadius:"50%"}}),[`${t}${t}-circle`]:{borderRadius:"50%"}}})(e)),[`${t}${t}-block`]:{width:"100%",[o]:{width:"100%"},[i]:{width:"100%"}},[`${t}${t}-active`]:{[` - ${n}, - ${r} > li, - ${a}, - ${o}, - ${i}, - ${l} - `]:Object.assign({},{background:e.skeletonLoadingBackground,backgroundSize:"400% 100%",animationName:d,animationDuration:e.skeletonLoadingMotionDuration,animationTimingFunction:"ease",animationIterationCount:"infinite"})}}})((0,u.mergeToken)(e,{skeletonAvatarCls:`${t}-avatar`,skeletonTitleCls:`${t}-title`,skeletonParagraphCls:`${t}-paragraph`,skeletonButtonCls:`${t}-button`,skeletonInputCls:`${t}-input`,skeletonImageCls:`${t}-image`,imageSizeBase:a(e.controlHeight).mul(1.5).equal(),borderRadius:100,skeletonLoadingBackground:`linear-gradient(90deg, ${e.gradientFromColor} 25%, ${e.gradientToColor} 37%, ${e.gradientFromColor} 63%)`,skeletonLoadingMotionDuration:"1.4s"}))},e=>{let{colorFillContent:t,colorFill:a}=e;return{color:t,colorGradientEnd:a,gradientFromColor:t,gradientToColor:a,titleHeight:e.controlHeight/2,blockRadius:e.borderRadiusSM,paragraphMarginTop:e.marginLG+e.marginXXS,paragraphLiHeight:e.controlHeight/2}},{deprecatedTokens:[["color","gradientFromColor"],["colorGradientEnd","gradientToColor"]]}),x=e=>{let{prefixCls:n,className:r,style:o,rows:i=0}=e,l=Array.from({length:i}).map((a,n)=>t.createElement("li",{key:n,style:{width:((e,t)=>{let{width:a,rows:n=2}=t;return Array.isArray(a)?a[e]:n-1===e?a:void 0})(n,e)}}));return t.createElement("ul",{className:(0,a.default)(n,r),style:o},l)},C=({prefixCls:e,className:n,width:r,style:o})=>t.createElement("h3",{className:(0,a.default)(e,n),style:Object.assign({width:r},o)});function v(e){return e&&"object"==typeof e?e:{}}let y=e=>{let{prefixCls:r,loading:i,className:l,rootClassName:s,style:u,children:d,avatar:c=!1,title:p=!0,paragraph:g=!0,active:m,round:f}=e,{getPrefixCls:b,direction:y,className:S,style:O}=(0,n.useComponentConfig)("skeleton"),D=b("skeleton",r),[w,N,$]=h(D);if(i||!("loading"in e)){let e,n,r=!!c,i=!!p,d=!!g;if(r){let a=Object.assign(Object.assign({prefixCls:`${D}-avatar`},i&&!d?{size:"large",shape:"square"}:{size:"large",shape:"circle"}),v(c));e=t.createElement("div",{className:`${D}-header`},t.createElement(o,Object.assign({},a)))}if(i||d){let e,a;if(i){let a=Object.assign(Object.assign({prefixCls:`${D}-title`},!r&&d?{width:"38%"}:r&&d?{width:"50%"}:{}),v(p));e=t.createElement(C,Object.assign({},a))}if(d){let e,n=Object.assign(Object.assign({prefixCls:`${D}-paragraph`},(e={},r&&i||(e.width="61%"),!r&&i?e.rows=3:e.rows=2,e)),v(g));a=t.createElement(x,Object.assign({},n))}n=t.createElement("div",{className:`${D}-content`},e,a)}let b=(0,a.default)(D,{[`${D}-with-avatar`]:r,[`${D}-active`]:m,[`${D}-rtl`]:"rtl"===y,[`${D}-round`]:f},S,l,s,N,$);return w(t.createElement("div",{className:b,style:Object.assign(Object.assign({},O),u)},e,n))}return null!=d?d:null};y.Button=e=>{let{prefixCls:i,className:l,rootClassName:s,active:u,block:d=!1,size:c="default"}=e,{getPrefixCls:p}=t.useContext(n.ConfigContext),g=p("skeleton",i),[m,f,b]=h(g),x=(0,r.default)(e,["prefixCls"]),C=(0,a.default)(g,`${g}-element`,{[`${g}-active`]:u,[`${g}-block`]:d},l,s,f,b);return m(t.createElement("div",{className:C},t.createElement(o,Object.assign({prefixCls:`${g}-button`,size:c},x))))},y.Avatar=e=>{let{prefixCls:i,className:l,rootClassName:s,active:u,shape:d="circle",size:c="default"}=e,{getPrefixCls:p}=t.useContext(n.ConfigContext),g=p("skeleton",i),[m,f,b]=h(g),x=(0,r.default)(e,["prefixCls","className"]),C=(0,a.default)(g,`${g}-element`,{[`${g}-active`]:u},l,s,f,b);return m(t.createElement("div",{className:C},t.createElement(o,Object.assign({prefixCls:`${g}-avatar`,shape:d,size:c},x))))},y.Input=e=>{let{prefixCls:i,className:l,rootClassName:s,active:u,block:d,size:c="default"}=e,{getPrefixCls:p}=t.useContext(n.ConfigContext),g=p("skeleton",i),[m,f,b]=h(g),x=(0,r.default)(e,["prefixCls"]),C=(0,a.default)(g,`${g}-element`,{[`${g}-active`]:u,[`${g}-block`]:d},l,s,f,b);return m(t.createElement("div",{className:C},t.createElement(o,Object.assign({prefixCls:`${g}-input`,size:c},x))))},y.Image=e=>{let{prefixCls:r,className:o,rootClassName:i,style:l,active:s}=e,{getPrefixCls:u}=t.useContext(n.ConfigContext),d=u("skeleton",r),[c,p,g]=h(d),m=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:s},o,i,p,g);return c(t.createElement("div",{className:m},t.createElement("div",{className:(0,a.default)(`${d}-image`,o),style:l},t.createElement("svg",{viewBox:"0 0 1098 1024",xmlns:"http://www.w3.org/2000/svg",className:`${d}-image-svg`},t.createElement("title",null,"Image placeholder"),t.createElement("path",{d:"M365.714286 329.142857q0 45.714286-32.036571 77.677714t-77.677714 32.036571-77.677714-32.036571-32.036571-77.677714 32.036571-77.677714 77.677714-32.036571 77.677714 32.036571 32.036571 77.677714zM950.857143 548.571429l0 256-804.571429 0 0-109.714286 182.857143-182.857143 91.428571 91.428571 292.571429-292.571429zM1005.714286 146.285714l-914.285714 0q-7.460571 0-12.873143 5.412571t-5.412571 12.873143l0 694.857143q0 7.460571 5.412571 12.873143t12.873143 5.412571l914.285714 0q7.460571 0 12.873143-5.412571t5.412571-12.873143l0-694.857143q0-7.460571-5.412571-12.873143t-12.873143-5.412571zM1097.142857 164.571429l0 694.857143q0 37.741714-26.843429 64.585143t-64.585143 26.843429l-914.285714 0q-37.741714 0-64.585143-26.843429t-26.843429-64.585143l0-694.857143q0-37.741714 26.843429-64.585143t64.585143-26.843429l914.285714 0q37.741714 0 64.585143 26.843429t26.843429 64.585143z",className:`${d}-image-path`})))))},y.Node=e=>{let{prefixCls:r,className:o,rootClassName:i,style:l,active:s,children:u}=e,{getPrefixCls:d}=t.useContext(n.ConfigContext),c=d("skeleton",r),[p,g,m]=h(c),f=(0,a.default)(c,`${c}-element`,{[`${c}-active`]:s},g,o,i,m);return p(t.createElement("div",{className:f},t.createElement("div",{className:(0,a.default)(`${c}-image`,o),style:l},u)))},e.s(["default",0,y],185793)},922611,e=>{"use strict";var t=e.i(271645),a=e.i(175066);function n(){}let r=t.createContext({add:n,remove:n});e.s(["usePanelRef",0,function(e){let n=t.useContext(r),o=t.useRef(null);return(0,a.default)(t=>{if(t){let a=e?t.querySelector(e):t;a&&(n.add(a),o.current=a)}else n.remove(o.current)})}])},500330,e=>{"use strict";var t=e.i(727749);let a=(e,t=0,a=!1,n=!0)=>{if(null==e||!Number.isFinite(e)||0===e&&!n)return"-";let r={minimumFractionDigits:t,maximumFractionDigits:t};if(!a)return e.toLocaleString("en-US",r);let o=e<0?"-":"",i=Math.abs(e),l=i,s="";return i>=1e6?(l=i/1e6,s="M"):i>=1e3&&(l=i/1e3,s="K"),`${o}${l.toLocaleString("en-US",r)}${s}`},n=async(e,a="Copied to clipboard")=>{if(!e)return!1;if(!navigator||!navigator.clipboard||!navigator.clipboard.writeText)return r(e,a);try{return await navigator.clipboard.writeText(e),t.default.success(a),!0}catch(t){return console.error("Clipboard API failed: ",t),r(e,a)}},r=(e,a)=>{try{let n=document.createElement("textarea");n.value=e,n.style.position="fixed",n.style.left="-999999px",n.style.top="-999999px",n.setAttribute("readonly",""),document.body.appendChild(n),n.focus(),n.select();let r=document.execCommand("copy");if(document.body.removeChild(n),r)return t.default.success(a),!0;throw Error("execCommand failed")}catch(e){return t.default.fromBackend("Failed to copy to clipboard"),console.error("Failed to copy: ",e),!1}};e.s(["copyToClipboard",0,n,"formatNumberWithCommas",0,a,"getSpendString",0,(e,t=6)=>{if(null==e||!Number.isFinite(e)||0===e)return"-";let n=a(e,t,!1,!1);if(0===Number(n.replace(/,/g,""))){let e=(1/10**t).toFixed(t);return`< $${e}`}return`$${n}`},"updateExistingKeys",0,function(e,t){let a=structuredClone(e);for(let[e,n]of Object.entries(t))e in a&&(a[e]=n);return a}])},112179,581070,e=>{"use strict";var t=e.i(843476),a=e.i(487486),n=e.i(115504),r=e.i(746798);function o({content:e,trigger:a}){return(0,t.jsx)(r.TooltipProvider,{delay:300,children:(0,t.jsxs)(r.Tooltip,{children:[(0,t.jsx)(r.TooltipTrigger,{render:a}),(0,t.jsx)(r.TooltipContent,{children:e})]})})}e.s(["CellTooltip",0,o],581070);let i={success:"border-green-200 bg-green-50 text-green-600",error:"border-red-200 bg-red-50 text-red-600",warning:"border-amber-200 bg-amber-50 text-amber-600",neutral:"border-gray-200 bg-gray-50 text-gray-600",info:"border-blue-200 bg-blue-50 text-blue-600"};e.s(["StatusBadge",0,function({tone:e,label:r,tooltip:l,dataTestId:s}){let u=(0,t.jsx)(a.Badge,{variant:"outline","data-testid":s,className:(0,n.cn)("whitespace-nowrap font-normal",i[e]),children:r});return l?(0,t.jsx)(o,{content:l,trigger:u}):u}],112179)},200208,399536,997422,146512,e=>{"use strict";var t=e.i(843476),a=e.i(581070);let n=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],r=e=>String(e).padStart(2,"0");e.s(["DateCell",0,function({value:e,precision:o="datetime",fallback:i="-"}){let l,s,u,d=e?new Date(e):null;return!d||Number.isNaN(d.getTime())?(0,t.jsx)("span",{className:"text-muted-foreground",children:i}):(0,t.jsx)(a.CellTooltip,{content:(l=Intl.DateTimeFormat().resolvedOptions().timeZone,s=`${n[d.getMonth()]} ${d.getDate()}, ${d.getFullYear()}`,u=`${r(d.getHours())}:${r(d.getMinutes())}:${r(d.getSeconds())}`,`${s}, ${u} (${l})`),trigger:(0,t.jsx)("span",{className:"whitespace-nowrap",children:"date"===o?`${n[d.getMonth()]} ${d.getDate()}, ${d.getFullYear()}`:`${n[d.getMonth()]} ${d.getDate()}, ${r(d.getHours())}:${r(d.getMinutes())}:${r(d.getSeconds())}`})})}],200208);var o=e.i(174886),i=e.i(115504),l=e.i(500330);let s={pill:{base:"font-mono text-xs font-normal px-2 py-0.5 rounded-md text-left bg-blue-50 text-blue-500",clickable:"hover:bg-blue-100 cursor-pointer"},plain:{base:"font-mono text-xs text-left",clickable:"hover:text-blue-600 cursor-pointer"}};e.s(["IdCell",0,function({value:e,variant:n="pill",onClick:r,copyable:u=!1,truncate:d=!0,fallback:c="-",tooltip:p,disabled:g=!1,dataTestId:m,className:f}){if(!e)return(0,t.jsx)("span",{className:"text-muted-foreground",children:c});let b=!!r&&!g,h=(0,i.cn)(s[n].base,b&&s[n].clickable,d&&"block max-w-[15ch] truncate",g&&"opacity-50",f),x=b?(0,t.jsx)("button",{type:"button",className:h,"data-testid":m,onClick:()=>r(e),children:e}):(0,t.jsx)("span",{className:h,"data-testid":m,children:e}),C=(0,t.jsx)(a.CellTooltip,{content:p??e,trigger:x});return u?(0,t.jsxs)("span",{className:"inline-flex max-w-full items-center gap-1",children:[C,(0,t.jsx)("button",{type:"button","aria-label":"Copy ID",className:"shrink-0 cursor-pointer text-muted-foreground hover:text-foreground",onClick:t=>{t.stopPropagation(),(0,l.copyToClipboard)(e)},children:(0,t.jsx)(o.Copy,{className:"size-3"})})]}):C}],399536);var u=e.i(463059);e.s(["IdentityCell",0,function({title:e,subtitle:a,badge:n,onClick:r,className:o,titleClassName:l}){let s=(0,t.jsxs)("div",{className:"flex min-w-0 flex-col gap-0.5",children:[(0,t.jsx)("span",{className:(0,i.cn)("truncate text-sm font-medium text-foreground",l),children:e}),(null!=a&&""!==a||null!=n)&&(0,t.jsxs)("span",{className:"flex min-w-0 items-center gap-2",children:[null!=a&&""!==a&&(0,t.jsx)("span",{className:"truncate font-mono text-xs text-muted-foreground",children:a}),n]})]});return null!=r?(0,t.jsxs)("button",{type:"button",onClick:r,className:(0,i.cn)("group -mx-2 flex w-[calc(100%+1rem)] cursor-pointer items-center gap-2 rounded-md px-2 py-1 text-left transition-colors hover:bg-muted",o),children:[s,(0,t.jsx)(u.ChevronRight,{className:"ml-auto size-4 shrink-0 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100"})]}):(0,t.jsx)("div",{className:(0,i.cn)("min-w-0",o),children:s})}],997422);let d={hasModelAccess:!1,label:"Management"},c={hasModelAccess:!1,label:"Read-only"},p={hasModelAccess:!1,label:"SCIM"},g={hasModelAccess:!0,label:null},m=e=>e.startsWith("/scim"),f=(e,t)=>1===e.length&&e[0]===t;e.s(["deriveKeyModelScope",0,(e,t)=>"management"===t?d:"read_only"===t?c:Array.isArray(e)&&0!==e.length?e.every(m)?p:f(e,"management_routes")?d:f(e,"info_routes")?c:g:g],146512)},355619,e=>{"use strict";var t=e.i(602869);let a=async(e,a,n)=>{try{if(null===e||null===a)return;if(null!==n){let r=(await (0,t.modelAvailableCall)(n,e,a,!0,null,!0)).data.map(e=>e.id),o=[],i=[];return r.forEach(e=>{e.endsWith("/*")?o.push(e):i.push(e)}),[...o,...i]}}catch(e){console.error("Error fetching user models:",e)}};e.s(["excludeProxyWideSentinel",0,e=>e.filter(e=>"all-proxy-models"!==e),"fetchAvailableModelsForTeamOrKey",0,a,"getModelDisplayName",0,e=>{if("all-proxy-models"===e)return"All Proxy Models";if(e.endsWith("/*")){let t=e.replace("/*","");return`All ${t} models`}return e},"hasAllModelsSentinel",0,e=>e.includes("all-proxy-models")||e.includes("all-team-models"),"unfurlWildcardModelsInList",0,(e,t)=>{let a=[],n=[];return e.forEach(e=>{if(e.endsWith("/*")){let r=e.replace("/*",""),o=t.filter(e=>e.startsWith(r+"/"));n.push(...o),a.push(e)}else n.push(e)}),[...a,...n].filter((e,t,a)=>a.indexOf(e)===t)}])},622826,547227,964471,630500,e=>{"use strict";var t=e.i(581070);e.i(200208),e.i(399536),e.i(997422);var a=e.i(843476),n=e.i(146512),r=e.i(355619),o=e.i(487486);let i="all-proxy-models",l=e=>{if(e===i)return"All Proxy Models";let t=(0,r.getModelDisplayName)(e);return t.length>30?`${t.slice(0,30)}...`:t};e.s(["ModelsCell",0,function({models:e,maxVisible:r=3,allowedRoutes:s,keyType:u}){if(!Array.isArray(e)||0===e.length){let e=(0,n.deriveKeyModelScope)(s,u);return e.hasModelAccess?(0,a.jsx)(o.Badge,{variant:"secondary",children:"All Proxy Models"}):(0,a.jsx)(t.CellTooltip,{content:`Scoped to ${e.label} routes; this key cannot call any models`,trigger:(0,a.jsx)(o.Badge,{variant:"secondary",className:"cursor-default",children:"No model access"})})}let d=e.slice(0,r),c=e.slice(r);return(0,a.jsxs)("div",{className:"flex flex-wrap items-center gap-1",children:[d.map((e,t)=>(0,a.jsx)(o.Badge,{variant:e===i?"secondary":"outline",children:l(e)},t)),c.length>0&&(0,a.jsx)(t.CellTooltip,{content:(0,a.jsx)("div",{className:"flex max-w-[280px] flex-col gap-0.5",children:c.map((e,t)=>(0,a.jsx)("span",{children:l(e)},t))}),trigger:(0,a.jsxs)(o.Badge,{variant:"outline",className:"cursor-default",children:["+",c.length," more"]})})]})}],547227);var s=e.i(500330);e.s(["MoneyCell",0,function({value:e,decimals:t=4,emptyText:n="-",showZero:r=!1}){return null==e||Number.isNaN(e)?(0,a.jsx)("span",{className:"text-muted-foreground",children:n}):0===e?r?(0,a.jsx)("span",{className:"whitespace-nowrap",children:`$${(0,s.formatNumberWithCommas)(0,t,!1,!0)}`}):(0,a.jsx)("span",{className:"text-muted-foreground",children:"-"}):(0,a.jsx)("span",{className:"whitespace-nowrap",children:(0,s.getSpendString)(e,t)})}],964471);var u=e.i(944835);e.s(["SpendBudgetCell",0,function({spend:e,maxBudget:t,teamMaxBudget:n}){let r="number"!=typeof e||Number.isNaN(e)?0:e,o=t??n??null,i=null==t&&null!=n,l="number"==typeof o&&o>0,d=l?r/o*100:0,c=r>0?(0,s.getSpendString)(r,4):"$0.00",p=null===o?"· Unlimited":`of $${(0,s.formatNumberWithCommas)(o)}${i?" (Team)":""}`;return(0,a.jsxs)("div",{className:"flex min-w-[130px] flex-col gap-1",children:[(0,a.jsxs)("div",{className:"whitespace-nowrap text-xs",children:[(0,a.jsx)("span",{className:"font-medium tabular-nums text-foreground",children:c})," ",(0,a.jsx)("span",{className:"text-muted-foreground",children:p})]}),l&&(0,a.jsx)(u.Meter,{value:r,max:o,"aria-valuetext":`${c} of $${(0,s.formatNumberWithCommas)(o)}`,children:(0,a.jsx)(u.MeterTrack,{children:(0,a.jsx)(u.MeterIndicator,{tone:d>100?"over":d>=80?"warning":"default"})})})]})}],630500),e.i(112179),e.s([],622826)},841947,e=>{"use strict";let t=(0,e.i(475254).default)("x",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]);e.s(["default",0,t])},37727,e=>{"use strict";var t=e.i(841947);e.s(["X",()=>t.default])},409797,e=>{"use strict";var t=e.i(631171);e.s(["ChevronDownIcon",()=>t.default])},233565,e=>{"use strict";var t=e.i(246349);e.s(["ChevronRightIcon",()=>t.default])},678784,e=>{"use strict";var t=e.i(678745);e.s(["CheckIcon",()=>t.default])},545356,e=>{"use strict";var t=e.i(271645);let a=t.createContext({register:()=>{},unregister:()=>{},subscribeMapChange:()=>()=>{},elementsRef:{current:[]},nextIndexRef:{current:0}});e.s(["CompositeListContext",0,a,"useCompositeListContext",0,function(){return t.useContext(a)}])},673553,e=>{"use strict";var t,a=e.i(271645),n=e.i(146376),r=e.i(545356);let o=((t={})[t.None=0]="None",t[t.GuessFromOrder=1]="GuessFromOrder",t);e.s(["IndexGuessBehavior",0,o,"useCompositeListItem",0,function(e={}){let{label:t,metadata:i,textRef:l,indexGuessBehavior:s,index:u}=e,{register:d,unregister:c,subscribeMapChange:p,elementsRef:g,labelsRef:m,nextIndexRef:f}=(0,r.useCompositeListContext)(),b=a.useRef(-1),[h,x]=a.useState(u??(s===o.GuessFromOrder?()=>{if(-1===b.current){let e=f.current;f.current+=1,b.current=e}return b.current}:-1)),C=a.useRef(null),v=a.useCallback(e=>{if(C.current=e,-1!==h&&null!==e&&(g.current[h]=e,m)){let a=void 0!==t;m.current[h]=a?t:l?.current?.textContent??e.textContent}},[h,g,m,t,l]);return(0,n.useIsoLayoutEffect)(()=>{if(null!=u)return;let e=C.current;if(e)return d(e,i),()=>{c(e)}},[u,d,c,i]),(0,n.useIsoLayoutEffect)(()=>{if(null==u)return p(e=>{let t=C.current?e.get(C.current)?.index:null;null!=t&&x(t)})},[u,p,x]),{ref:v,index:h}}])},53687,e=>{"use strict";var t=e.i(271645),a=e.i(921374),n=e.i(667865),r=e.i(146376),o=e.i(545356),i=e.i(843476);function l(){return new Map}function s(){return new Set}function u(e,t){let a=e.compareDocumentPosition(t);return a&Node.DOCUMENT_POSITION_FOLLOWING||a&Node.DOCUMENT_POSITION_CONTAINED_BY?-1:a&Node.DOCUMENT_POSITION_PRECEDING||a&Node.DOCUMENT_POSITION_CONTAINS?1:0}e.s(["CompositeList",0,function(e){let{children:d,elementsRef:c,labelsRef:p,onMapChange:g}=e,m=(0,n.useStableCallback)(g),f=t.useRef(0),b=(0,a.useRefWithInit)(s).current,h=(0,a.useRefWithInit)(l).current,[x,C]=t.useState(0),v=t.useRef(x),y=(0,n.useStableCallback)((e,t)=>{h.set(e,t??null),v.current+=1,C(v.current)}),S=(0,n.useStableCallback)(e=>{h.delete(e),v.current+=1,C(v.current)}),O=t.useMemo(()=>{let e=new Map;return Array.from(h.keys()).filter(e=>e.isConnected).sort(u).forEach((t,a)=>{let n=h.get(t)??{};e.set(t,{...n,index:a})}),e},[h,x]);(0,r.useIsoLayoutEffect)(()=>{if("function"!=typeof MutationObserver||0===O.size)return;let e=new MutationObserver(e=>{let t=new Set,a=e=>t.has(e)?t.delete(e):t.add(e);e.forEach(e=>{e.removedNodes.forEach(a),e.addedNodes.forEach(a)}),0===t.size&&(v.current+=1,C(v.current))});return O.forEach((t,a)=>{a.parentElement&&e.observe(a.parentElement,{childList:!0})}),()=>{e.disconnect()}},[O]),(0,r.useIsoLayoutEffect)(()=>{v.current===x&&(c.current.length!==O.size&&(c.current.length=O.size),p&&p.current.length!==O.size&&(p.current.length=O.size),f.current=O.size),m(O)},[m,O,c,p,x]),(0,r.useIsoLayoutEffect)(()=>()=>{c.current=[]},[c]),(0,r.useIsoLayoutEffect)(()=>()=>{p&&(p.current=[])},[p]);let D=(0,n.useStableCallback)(e=>(b.add(e),()=>{b.delete(e)}));(0,r.useIsoLayoutEffect)(()=>{b.forEach(e=>e(O))},[b,O]);let w=t.useMemo(()=>({register:y,unregister:S,subscribeMapChange:D,elementsRef:c,labelsRef:p,nextIndexRef:f}),[y,S,D,c,p,f]);return(0,i.jsx)(o.CompositeListContext.Provider,{value:w,children:d})}])},395530,e=>{"use strict";var t=e.i(271645),a=e.i(828918),n=e.i(838452),r=e.i(673553);e.s(["useCompositeItem",0,function(e={}){let{highlightItemOnHover:o,highlightedIndex:i,onHighlightedIndexChange:l}=(0,n.useCompositeRootContext)(),{ref:s,index:u}=(0,r.useCompositeListItem)(e),d=i===u,c=t.useRef(null),p=(0,a.useMergedRefs)(s,c);return{compositeProps:{tabIndex:d?0:-1,onFocus(){l(u)},onMouseMove(){let e=c.current;if(!o||!e)return;let t=e.hasAttribute("disabled")||"true"===e.ariaDisabled;d||t||e.focus()}},compositeRef:p,index:u}}])},590803,e=>{"use strict";e.s(["isElementDisabled",0,function(e){return null==e||e.hasAttribute("disabled")||"true"===e.getAttribute("aria-disabled")}])},784774,e=>{"use strict";var t=e.i(843476),a=e.i(271645),n=e.i(115504);let r=a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("div",{"data-slot":"table-container",className:"relative w-full overflow-x-auto",children:(0,t.jsx)("table",{ref:r,"data-slot":"table",className:(0,n.cn)("w-full caption-bottom text-sm",e),...a})}));r.displayName="Table";let o=a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("thead",{ref:r,"data-slot":"table-header",className:(0,n.cn)("[&_tr]:border-b",e),...a}));o.displayName="TableHeader";let i=a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("tbody",{ref:r,"data-slot":"table-body",className:(0,n.cn)("[&_tr:last-child]:border-0",e),...a}));i.displayName="TableBody";let l=a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("tfoot",{ref:r,"data-slot":"table-footer",className:(0,n.cn)("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",e),...a}));l.displayName="TableFooter";let s=a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("tr",{ref:r,"data-slot":"table-row",className:(0,n.cn)("border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",e),...a}));s.displayName="TableRow";let u=a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("th",{ref:r,"data-slot":"table-head",className:(0,n.cn)("h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",e),...a}));u.displayName="TableHead";let d=a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("td",{ref:r,"data-slot":"table-cell",className:(0,n.cn)("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",e),...a}));d.displayName="TableCell",a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("caption",{ref:r,"data-slot":"table-caption",className:(0,n.cn)("mt-4 text-sm text-muted-foreground",e),...a})).displayName="TableCaption",e.s(["Table",0,r,"TableBody",0,i,"TableCell",0,d,"TableFooter",0,l,"TableHead",0,u,"TableHeader",0,o,"TableRow",0,s])},302747,e=>{"use strict";var t=e.i(843476),a=e.i(271645),n=e.i(115504);let r=a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("div",{ref:r,"data-slot":"skeleton",className:(0,n.cn)("animate-pulse rounded-md bg-accent",e),...a}));r.displayName="Skeleton",e.s(["Skeleton",0,r])},108821,e=>{"use strict";var t=e.i(733332),a=e.i(271645);let n=a.createContext(!1),r=a.createContext(void 0);e.s(["DialogRootContext",0,r,"IsDrawerContext",0,n,"useDialogRootContext",0,function(e){let n=a.useContext(r);if(!1===e&&void 0===n)throw Error((0,t.default)(27));return n}])},402820,156736,209793,625834,784324,264951,e=>{"use strict";e.i(247167);var t,a,n=e.i(271645),r=e.i(108821),o=e.i(552245),i=e.i(405005),l=e.i(209407);let s={...i.popupStateMapping,...l.transitionStatusMapping},u=n.forwardRef(function(e,t){let{render:a,className:n,style:i,forceRender:l=!1,...u}=e,{store:d}=(0,r.useDialogRootContext)(),c=d.useState("open"),p=d.useState("nested"),g=d.useState("mounted"),m=d.useState("transitionStatus");return(0,o.useRenderElement)("div",e,{state:{open:c,transitionStatus:m},ref:[d.context.backdropRef,t],stateAttributesMapping:s,props:[{role:"presentation",hidden:!g,style:{userSelect:"none",WebkitUserSelect:"none"}},u],enabled:l||!p})});e.s(["DialogBackdrop",0,u],402820);var d=e.i(540886),c=e.i(675606),p=e.i(56434);let g=n.forwardRef(function(e,t){let{render:a,className:n,style:i,disabled:l=!1,nativeButton:s=!0,...u}=e,{store:g}=(0,r.useDialogRootContext)(),m=g.useState("open"),{getButtonProps:f,buttonRef:b}=(0,d.useButton)({disabled:l,native:s});return(0,o.useRenderElement)("button",e,{state:{disabled:l},ref:[t,b],props:[{onClick:function(e){m&&g.setOpen(!1,(0,c.createChangeEventDetails)(p.REASONS.closePress,e.nativeEvent))}},u,f]})});e.s(["DialogClose",0,g],156736);var m=e.i(788015);let f=n.forwardRef(function(e,t){let{render:a,className:n,style:i,id:l,...s}=e,{store:u}=(0,r.useDialogRootContext)(),d=(0,m.useBaseUiId)(l);return u.useSyncedValueWithCleanup("descriptionElementId",d),(0,o.useRenderElement)("p",e,{ref:t,props:[{id:d},s]})});e.s(["DialogDescription",0,f],209793);var b=e.i(61487);let h=((t={}).nestedDialogs="--nested-dialogs",t),x=((a={})[a.open=i.CommonPopupDataAttributes.open]="open",a[a.closed=i.CommonPopupDataAttributes.closed]="closed",a[a.startingStyle=i.CommonPopupDataAttributes.startingStyle]="startingStyle",a[a.endingStyle=i.CommonPopupDataAttributes.endingStyle]="endingStyle",a.nested="data-nested",a.nestedDialogOpen="data-nested-dialog-open",a);var C=e.i(733332);let v=n.createContext(void 0);function y(){let e=n.useContext(v);if(void 0===e)throw Error((0,C.default)(26));return e}e.s(["DialogPortalContext",0,v,"useDialogPortalContext",0,y],625834);var S=e.i(137584),O=e.i(673327),D=e.i(264111),w=e.i(843476);let N={...i.popupStateMapping,...l.transitionStatusMapping,nestedDialogOpen:e=>e?{[x.nestedDialogOpen]:""}:null},$=n.forwardRef(function(e,t){let{render:a,className:n,style:i,finalFocus:l,initialFocus:s,...u}=e,{store:d}=(0,r.useDialogRootContext)(),c=d.useState("descriptionElementId"),p=d.useState("disablePointerDismissal"),g=d.useState("floatingRootContext"),m=d.useState("popupProps"),f=d.useState("modal"),x=d.useState("mounted"),C=d.useState("nested"),v=d.useState("nestedOpenDialogCount"),$=d.useState("open"),R=d.useState("openMethod"),j=d.useState("titleElementId"),E=d.useState("transitionStatus"),k=d.useState("role"),I=g.useState("floatingId"),T=u.id??I;y(),(0,S.useOpenChangeComplete)({open:$,ref:d.context.popupRef,onComplete(){$&&d.context.onOpenChangeComplete?.(!0)}});let M=void 0===s?(0,D.createDefaultInitialFocus)(d.context.popupRef):s,P=d.useStateSetter("popupElement"),A=(0,o.useRenderElement)("div",e,{state:{open:$,nested:C,transitionStatus:E,nestedDialogOpen:v>0},props:[m,{id:T,"aria-labelledby":j??void 0,"aria-describedby":c??void 0,role:k,...D.FOCUSABLE_POPUP_PROPS,hidden:!x,onKeyDown(e){O.COMPOSITE_KEYS.has(e.key)&&e.stopPropagation()},style:{[h.nestedDialogs]:v}},u],ref:[t,d.context.popupRef,P],stateAttributesMapping:N});return(0,w.jsx)(b.FloatingFocusManager,{context:g,openInteractionType:R,disabled:!x,closeOnFocusOut:!p,initialFocus:M,returnFocus:l,modal:!1!==f,restoreFocus:"popup",children:A})});e.s(["DialogPopup",0,$],784324);var R=e.i(144394),j=e.i(726674),E=e.i(426);let k=n.forwardRef(function(e,t){let{keepMounted:a=!1,...n}=e,{store:o}=(0,r.useDialogRootContext)(),i=o.useState("mounted"),l=o.useState("modal"),s=o.useState("open");return i||a?(0,w.jsx)(v.Provider,{value:a,children:(0,w.jsxs)(j.FloatingPortal,{ref:t,...n,children:[i&&!0===l&&(0,w.jsx)(E.InternalBackdrop,{ref:o.context.internalBackdropRef,inert:(0,R.inertValue)(!s)}),e.children]})}):null});e.s(["DialogPortal",0,k],264951)},67530,e=>{"use strict";var t=e.i(271645),a=e.i(145484),n=e.i(956789),r=e.i(17989),o=e.i(647554),i=e.i(675606),l=e.i(56434),s=e.i(264111);e.s(["DialogInteractions",0,function({store:e,parentContext:i,isDrawer:l}){let u=e.useState("open"),d=e.useState("disablePointerDismissal"),c=e.useState("modal"),p=e.useState("popupElement"),g=e.useState("floatingRootContext"),[m,f]=t.useState(0),[b,h]=t.useState(0),x=0===m,C=(0,r.useDismiss)(g,{outsidePressEvent:()=>e.context.internalBackdropRef.current||e.context.backdropRef.current?"intentional":{mouse:"trap-focus"===c?"sloppy":"intentional",touch:"sloppy"},outsidePress(t){if(!e.context.outsidePressEnabledRef.current||"button"in t&&0!==t.button||"touches"in t&&1!==t.touches.length)return!1;let a=(0,o.getTarget)(t);return!!x&&!d&&(!c||!e.context.internalBackdropRef.current&&!e.context.backdropRef.current||e.context.internalBackdropRef.current===a||e.context.backdropRef.current===a||(0,o.contains)(a,p)&&!a?.hasAttribute("data-base-ui-portal"))},escapeKey:x});(0,a.useScrollLock)(u&&!0===c,p),e.useContextCallback("onNestedDialogOpen",(e,t)=>{f(e),h(t)}),e.useContextCallback("onNestedDialogClose",()=>{f(0),h(0)}),t.useEffect(()=>(i?.onNestedDialogOpen&&u&&i.onNestedDialogOpen(m+1,b+ +!!l),i?.onNestedDialogClose&&!u&&i.onNestedDialogClose(),()=>{i?.onNestedDialogClose&&u&&i.onNestedDialogClose()}),[l,u,m,b,i]);let v=C.reference??n.EMPTY_OBJECT,y=C.trigger??n.EMPTY_OBJECT,S=C.floating??n.EMPTY_OBJECT;return(0,s.usePopupInteractionProps)(e,{activeTriggerProps:v,inactiveTriggerProps:y,popupProps:S,nestedOpenDialogCount:m,nestedOpenDrawerCount:b}),null},"useDialogRoot",0,function(e){let{store:a,actionsRef:n}=e,r=a.useState("open");(0,s.usePopupRootSync)(a,r),(0,s.useImplicitActiveTrigger)(a);let{forceUnmount:o}=(0,s.useOpenStateTransitions)(r,a),u=t.useCallback(()=>{a.setOpen(!1,(0,i.createChangeEventDetails)(l.REASONS.imperativeAction))},[a]);t.useImperativeHandle(n,()=>({unmount:o,close:u}),[o,u])}])},366250,301807,e=>{"use strict";var t=e.i(271645),a=e.i(713203),n=e.i(67530),r=e.i(108821),o=e.i(616269),i=e.i(301252),l=e.i(116786),s=e.i(990627),u=e.i(264111);let d={...l.popupStoreSelectors,modal:(0,o.createSelector)(e=>e.modal),nested:(0,o.createSelector)(e=>e.nested),nestedOpenDialogCount:(0,o.createSelector)(e=>e.nestedOpenDialogCount),nestedOpenDrawerCount:(0,o.createSelector)(e=>e.nestedOpenDrawerCount),disablePointerDismissal:(0,o.createSelector)(e=>e.disablePointerDismissal),openMethod:(0,o.createSelector)(e=>e.openMethod),descriptionElementId:(0,o.createSelector)(e=>e.descriptionElementId),titleElementId:(0,o.createSelector)(e=>e.titleElementId),viewportElement:(0,o.createSelector)(e=>e.viewportElement),role:(0,o.createSelector)(e=>e.role)};class c extends i.ReactStore{constructor(e,a,n=!1){const r=new s.PopupTriggerMap,o=function(e={}){return{...(0,l.createInitialPopupStoreState)(),modal:!0,disablePointerDismissal:!1,popupElement:null,viewportElement:null,descriptionElementId:void 0,titleElementId:void 0,openMethod:null,nested:!1,nestedOpenDialogCount:0,nestedOpenDrawerCount:0,role:"dialog",...e}}(e);o.floatingRootContext=(0,l.createPopupFloatingRootContext)(r,a,n),super(o,{popupRef:t.createRef(),backdropRef:t.createRef(),internalBackdropRef:t.createRef(),outsidePressEnabledRef:{current:!0},triggerElements:r,onOpenChange:void 0,onOpenChangeComplete:void 0},d)}setOpen=(e,t)=>{if(t.preventUnmountOnClose=()=>{this.set("preventUnmountingOnClose",!0)},e||null!=t.trigger||null==this.state.activeTriggerId||(t.trigger=this.state.activeTriggerElement??void 0),this.context.onOpenChange?.(e,t),t.isCanceled)return;this.state.floatingRootContext.dispatchOpenChange(e,t);let a={open:e};(0,u.setPopupOpenState)(a,e,t.trigger),this.update(a)};static useStore(e,t){return(0,u.usePopupStore)(e,(e,a)=>new c(t,e,a),!0).store}}e.s(["DialogStore",0,c],301807);var p=e.i(843476);e.s(["useRenderDialogRoot",0,function(e,o="dialog"){let{children:i,open:l,defaultOpen:s=!1,onOpenChange:u,onOpenChangeComplete:d,disablePointerDismissal:g=!1,modal:m=!0,actionsRef:f,handle:b,triggerId:h,defaultTriggerId:x=null}=e,C="alert-dialog"===o,v=(0,r.useDialogRootContext)(!0),y={modal:!!C||m,disablePointerDismissal:C||g,nested:!!v,role:C?"alertdialog":"dialog"},S=c.useStore(b?.store,{open:s,openProp:l,activeTriggerId:x,triggerIdProp:h,...y});(0,a.useOnFirstRender)(()=>{let e=void 0===l&&!1===S.state.open&&!0===s?{open:!0,activeTriggerId:x}:null;C?S.update(e?{...y,...e}:y):e&&S.update(e)}),S.useControlledProp("openProp",l),S.useControlledProp("triggerIdProp",h),S.useSyncedValues(y),S.useContextCallback("onOpenChange",u),S.useContextCallback("onOpenChangeComplete",d);let O=S.useState("open"),D=S.useState("mounted"),w=S.useState("payload");(0,n.useDialogRoot)({store:S,actionsRef:f});let N=t.useMemo(()=>({store:S}),[S]);return(0,p.jsx)(r.IsDrawerContext.Provider,{value:!1,children:(0,p.jsxs)(r.DialogRootContext.Provider,{value:N,children:[(O||D)&&(0,p.jsx)(n.DialogInteractions,{store:S,parentContext:v?.store.context,isDrawer:"drawer"===o}),"function"==typeof i?i({payload:w}):i]})})}],366250)},974217,e=>{"use strict";e.i(247167);var t,a=e.i(271645),n=e.i(552245),r=e.i(405005),o=e.i(209407),i=e.i(108821),l=e.i(625834);let s=((t={})[t.open=r.CommonPopupDataAttributes.open]="open",t[t.closed=r.CommonPopupDataAttributes.closed]="closed",t[t.startingStyle=r.CommonPopupDataAttributes.startingStyle]="startingStyle",t[t.endingStyle=r.CommonPopupDataAttributes.endingStyle]="endingStyle",t.nested="data-nested",t.nestedDialogOpen="data-nested-dialog-open",t),u={...r.popupStateMapping,...o.transitionStatusMapping,nested:e=>e?{[s.nested]:""}:null,nestedDialogOpen:e=>e?{[s.nestedDialogOpen]:""}:null},d=a.forwardRef(function(e,t){let{render:a,className:r,style:o,children:s,...d}=e,c=(0,l.useDialogPortalContext)(),{store:p}=(0,i.useDialogRootContext)(),g=p.useState("open"),m=p.useState("nested"),f=p.useState("transitionStatus"),b=p.useState("nestedOpenDialogCount"),h=p.useState("mounted"),x=p.useStateSetter("viewportElement");return(0,n.useRenderElement)("div",e,{enabled:c||h,state:{open:g,nested:m,transitionStatus:f,nestedDialogOpen:b>0},ref:[t,x],stateAttributesMapping:u,props:[{role:"presentation",hidden:!h,style:{pointerEvents:g?void 0:"none"},children:s},d]})});e.s(["DialogViewport",0,d],974217)},77173,313488,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(108821),n=e.i(552245),r=e.i(788015);let o=t.forwardRef(function(e,t){let{render:o,className:i,style:l,id:s,...u}=e,{store:d}=(0,a.useDialogRootContext)(),c=(0,r.useBaseUiId)(s);return d.useSyncedValueWithCleanup("titleElementId",c),(0,n.useRenderElement)("h2",e,{ref:t,props:[{id:c},u]})});e.s(["DialogTitle",0,o],77173);var i=e.i(733332),l=e.i(540886),s=e.i(405005),u=e.i(638396),d=e.i(264111),c=e.i(385689),p=e.i(32199);let g=t.forwardRef(function(e,o){let{render:g,className:m,style:f,disabled:b=!1,nativeButton:h=!0,id:x,payload:C,handle:v,...y}=e,S=(0,a.useDialogRootContext)(!0),O=v?.store??S?.store;if(!O)throw Error((0,i.default)(79));let D=(0,r.useBaseUiId)(x),w=O.useState("floatingRootContext"),N=O.useState("isOpenedByTrigger",D),$=O.useState("triggerPopupId",D),R=t.useRef(null),{registerTrigger:j,isMountedByThisTrigger:E}=(0,d.useTriggerDataForwarding)(D,R,O,{payload:C}),{getButtonProps:k,buttonRef:I}=(0,l.useButton)({disabled:b,native:h}),T=(0,c.useClick)(w,{enabled:null!=w}),M=(0,p.useOpenMethodTriggerProps)(()=>O.select("open"),e=>{O.set("openMethod",e)}),P=O.useState("triggerProps",E);return(0,n.useRenderElement)("button",e,{state:{disabled:b,open:N},ref:[I,o,j,R],props:[T.reference,P,M,{[u.CLICK_TRIGGER_IDENTIFIER]:"",id:D,"aria-haspopup":"dialog","aria-expanded":N,"aria-controls":$},y,k],stateAttributesMapping:s.triggerOpenStateMapping})});e.s(["DialogTrigger",0,g],313488)},325326,e=>{"use strict";var t=e.i(301807),a=e.i(675606),n=e.i(56434);class r{constructor(e){this.store=e??new t.DialogStore}open(e){let t=e?this.store.context.triggerElements.getById(e):void 0;this.store.setOpen(!0,(0,a.createChangeEventDetails)(n.REASONS.imperativeAction,void 0,t))}openWithPayload(e){this.store.set("payload",e),this.store.setOpen(!0,(0,a.createChangeEventDetails)(n.REASONS.imperativeAction,void 0,void 0))}close(){this.store.setOpen(!1,(0,a.createChangeEventDetails)(n.REASONS.imperativeAction,void 0,void 0))}get isOpen(){return this.store.select("open")}}e.s(["DialogHandle",0,r,"createDialogHandle",0,function(){return new r}])},793479,e=>{"use strict";var t=e.i(843476),a=e.i(271645),n=e.i(115504);let r=a.forwardRef(({className:e,type:a,...r},o)=>(0,t.jsx)("input",{type:a,"data-slot":"input",className:(0,n.cn)("h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30","focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50","aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40",e),ref:o,...r}));r.displayName="Input",e.s(["Input",0,r])},353753,e=>{"use strict";e.s([],914651),e.i(914651);var t=e.i(402820),a=e.i(156736),n=e.i(209793),r=e.i(784324),o=e.i(264951),i=e.i(271645),l=e.i(108821),s=e.i(366250),u=e.i(974217),d=e.i(77173),c=e.i(313488),p=e.i(325326);e.s(["Backdrop",()=>t.DialogBackdrop,"Close",()=>a.DialogClose,"Description",()=>n.DialogDescription,"Handle",()=>p.DialogHandle,"Popup",()=>r.DialogPopup,"Portal",()=>o.DialogPortal,"Root",0,function(e){let t=i.useContext(l.IsDrawerContext)?"drawer":"dialog";return(0,s.useRenderDialogRoot)(e,t)},"Title",()=>d.DialogTitle,"Trigger",()=>c.DialogTrigger,"Viewport",()=>u.DialogViewport,"createHandle",()=>p.createDialogHandle],828376);var g=e.i(828376);e.s(["Dialog",0,g],353753)},995926,e=>{"use strict";var t=e.i(841947);e.s(["XIcon",()=>t.default])},110204,e=>{"use strict";var t=e.i(843476),a=e.i(271645),n=e.i(115504);let r=a.forwardRef(({className:e,...a},r)=>(0,t.jsx)("label",{ref:r,"data-slot":"label",className:(0,n.cn)("flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",e),...a}));r.displayName="Label",e.s(["Label",0,r])},16715,e=>{"use strict";let t=(0,e.i(475254).default)("refresh-cw",[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]]);e.s(["RefreshCw",0,t],16715)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0175usbyz91lt.js b/litellm/proxy/_experimental/out/_next/static/chunks/0175usbyz91lt.js deleted file mode 100644 index 71aafb4c7f0..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/0175usbyz91lt.js +++ /dev/null @@ -1,16 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,91874,e=>{"use strict";var t=e.i(931067),n=e.i(209428),i=e.i(211577),a=e.i(392221),l=e.i(703923),o=e.i(343794),r=e.i(914949),s=e.i(271645),d=["prefixCls","className","style","checked","disabled","defaultChecked","type","title","onChange"],c=(0,s.forwardRef)(function(e,c){var u=e.prefixCls,p=void 0===u?"rc-checkbox":u,m=e.className,b=e.style,g=e.checked,f=e.disabled,h=e.defaultChecked,$=e.type,y=void 0===$?"checkbox":$,v=e.title,S=e.onChange,O=(0,l.default)(e,d),x=(0,s.useRef)(null),C=(0,s.useRef)(null),j=(0,r.default)(void 0!==h&&h,{value:g}),w=(0,a.default)(j,2),E=w[0],k=w[1];(0,s.useImperativeHandle)(c,function(){return{focus:function(e){var t;null==(t=x.current)||t.focus(e)},blur:function(){var e;null==(e=x.current)||e.blur()},input:x.current,nativeElement:C.current}});var z=(0,o.default)(p,m,(0,i.default)((0,i.default)({},"".concat(p,"-checked"),E),"".concat(p,"-disabled"),f));return s.createElement("span",{className:z,title:v,style:b,ref:C},s.createElement("input",(0,t.default)({},O,{className:"".concat(p,"-input"),ref:x,onChange:function(t){f||("checked"in e||k(t.target.checked),null==S||S({target:(0,n.default)((0,n.default)({},e),{},{type:y,checked:t.target.checked}),stopPropagation:function(){t.stopPropagation()},preventDefault:function(){t.preventDefault()},nativeEvent:t.nativeEvent}))},disabled:f,checked:!!E,type:y})),s.createElement("span",{className:"".concat(p,"-inner")}))});e.s(["default",0,c])},421512,236836,e=>{"use strict";let t=e.i(271645).default.createContext(null);e.s(["default",0,t],421512),e.i(296059);var n=e.i(915654),i=e.i(183293),a=e.i(246422),l=e.i(838378);function o(e,t){return(e=>{let{checkboxCls:t}=e,a=`${t}-wrapper`;return[{[`${t}-group`]:Object.assign(Object.assign({},(0,i.resetComponent)(e)),{display:"inline-flex",flexWrap:"wrap",columnGap:e.marginXS,[`> ${e.antCls}-row`]:{flex:1}}),[a]:Object.assign(Object.assign({},(0,i.resetComponent)(e)),{display:"inline-flex",alignItems:"baseline",cursor:"pointer","&:after":{display:"inline-block",width:0,overflow:"hidden",content:"'\\a0'"},[`& + ${a}`]:{marginInlineStart:0},[`&${a}-in-form-item`]:{'input[type="checkbox"]':{width:14,height:14}}}),[t]:Object.assign(Object.assign({},(0,i.resetComponent)(e)),{position:"relative",whiteSpace:"nowrap",lineHeight:1,cursor:"pointer",borderRadius:e.borderRadiusSM,alignSelf:"center",[`${t}-input`]:{position:"absolute",inset:0,zIndex:1,cursor:"pointer",opacity:0,margin:0,[`&:focus-visible + ${t}-inner`]:(0,i.genFocusOutline)(e)},[`${t}-inner`]:{boxSizing:"border-box",display:"block",width:e.checkboxSize,height:e.checkboxSize,direction:"ltr",backgroundColor:e.colorBgContainer,border:`${(0,n.unit)(e.lineWidth)} ${e.lineType} ${e.colorBorder}`,borderRadius:e.borderRadiusSM,borderCollapse:"separate",transition:`all ${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:`${(0,n.unit)(e.lineWidthBold)} solid ${e.colorWhite}`,borderTop:0,borderInlineStart:0,transform:"rotate(45deg) scale(0) translate(-50%,-50%)",opacity:0,content:'""',transition:`all ${e.motionDurationFast} ${e.motionEaseInBack}, opacity ${e.motionDurationFast}`}},"& + span":{paddingInlineStart:e.paddingXS,paddingInlineEnd:e.paddingXS}})},{[` - ${a}:not(${a}-disabled), - ${t}:not(${t}-disabled) - `]:{[`&:hover ${t}-inner`]:{borderColor:e.colorPrimary}},[`${a}:not(${a}-disabled)`]:{[`&:hover ${t}-checked:not(${t}-disabled) ${t}-inner`]:{backgroundColor:e.colorPrimaryHover,borderColor:"transparent"},[`&:hover ${t}-checked:not(${t}-disabled):after`]:{borderColor:e.colorPrimaryHover}}},{[`${t}-checked`]:{[`${t}-inner`]:{backgroundColor:e.colorPrimary,borderColor:e.colorPrimary,"&:after":{opacity:1,transform:"rotate(45deg) scale(1) translate(-50%,-50%)",transition:`all ${e.motionDurationMid} ${e.motionEaseOutBack} ${e.motionDurationFast}`}}},[` - ${a}-checked:not(${a}-disabled), - ${t}-checked:not(${t}-disabled) - `]:{[`&:hover ${t}-inner`]:{backgroundColor:e.colorPrimaryHover,borderColor:"transparent"}}},{[t]:{"&-indeterminate":{"&":{[`${t}-inner`]:{backgroundColor:`${e.colorBgContainer}`,borderColor:`${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 ${t}-inner`]:{backgroundColor:`${e.colorBgContainer}`,borderColor:`${e.colorPrimary}`}}}}},{[`${a}-disabled`]:{cursor:"not-allowed"},[`${t}-disabled`]:{[`&, ${t}-input`]:{cursor:"not-allowed",pointerEvents:"none"},[`${t}-inner`]:{background:e.colorBgContainerDisabled,borderColor:e.colorBorder,"&:after":{borderColor:e.colorTextDisabled}},"&:after":{display:"none"},"& + span":{color:e.colorTextDisabled},[`&${t}-indeterminate ${t}-inner::after`]:{background:e.colorTextDisabled}}}]})((0,l.mergeToken)(t,{checkboxCls:`.${e}`,checkboxSize:t.controlInteractiveSize}))}let r=(0,a.genStyleHooks)("Checkbox",(e,{prefixCls:t})=>[o(t,e)]);e.s(["default",0,r,"getStyle",0,o],236836)},681216,e=>{"use strict";var t=e.i(271645),n=e.i(963188);e.s(["default",0,function(e){let i=t.default.useRef(null),a=()=>{n.default.cancel(i.current),i.current=null};return[()=>{a(),i.current=(0,n.default)(()=>{i.current=null})},t=>{i.current&&(t.stopPropagation(),a()),null==e||e(t)}]}])},374276,e=>{"use strict";e.i(247167);var t=e.i(271645),n=e.i(343794),i=e.i(91874),a=e.i(611935),l=e.i(121872),o=e.i(26905),r=e.i(242064),s=e.i(937328),d=e.i(321883),c=e.i(62139),u=e.i(421512),p=e.i(236836),m=e.i(681216),b=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,i=Object.getOwnPropertySymbols(e);at.indexOf(i[a])&&Object.prototype.propertyIsEnumerable.call(e,i[a])&&(n[i[a]]=e[i[a]]);return n};let g=t.forwardRef((e,g)=>{var f;let{prefixCls:h,className:$,rootClassName:y,children:v,indeterminate:S=!1,style:O,onMouseEnter:x,onMouseLeave:C,skipGroup:j=!1,disabled:w}=e,E=b(e,["prefixCls","className","rootClassName","children","indeterminate","style","onMouseEnter","onMouseLeave","skipGroup","disabled"]),{getPrefixCls:k,direction:z,checkbox:N}=t.useContext(r.ConfigContext),I=t.useContext(u.default),{isFormItemInput:P}=t.useContext(c.FormItemInputContext),T=t.useContext(s.default),M=null!=(f=(null==I?void 0:I.disabled)||w)?f:T,B=t.useRef(E.value),D=t.useRef(null),L=(0,a.composeRef)(g,D);t.useEffect(()=>{null==I||I.registerValue(E.value)},[]),t.useEffect(()=>{if(!j)return E.value!==B.current&&(null==I||I.cancelValue(B.current),null==I||I.registerValue(E.value),B.current=E.value),()=>null==I?void 0:I.cancelValue(E.value)},[E.value]),t.useEffect(()=>{var e;(null==(e=D.current)?void 0:e.input)&&(D.current.input.indeterminate=S)},[S]);let R=k("checkbox",h),G=(0,d.default)(R),[H,W,q]=(0,p.default)(R,G),X=Object.assign({},E);I&&!j&&(X.onChange=(...e)=>{E.onChange&&E.onChange.apply(E,e),I.toggleOption&&I.toggleOption({label:v,value:E.value})},X.name=I.name,X.checked=I.value.includes(E.value));let F=(0,n.default)(`${R}-wrapper`,{[`${R}-rtl`]:"rtl"===z,[`${R}-wrapper-checked`]:X.checked,[`${R}-wrapper-disabled`]:M,[`${R}-wrapper-in-form-item`]:P},null==N?void 0:N.className,$,y,q,G,W),A=(0,n.default)({[`${R}-indeterminate`]:S},o.TARGET_CLS,W),[K,V]=(0,m.default)(X.onClick);return H(t.createElement(l.default,{component:"Checkbox",disabled:M},t.createElement("label",{className:F,style:Object.assign(Object.assign({},null==N?void 0:N.style),O),onMouseEnter:x,onMouseLeave:C,onClick:K},t.createElement(i.default,Object.assign({},X,{onClick:V,prefixCls:R,className:A,disabled:M,ref:L})),null!=v&&t.createElement("span",{className:`${R}-label`},v))))});var f=e.i(8211),h=e.i(529681),$=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,i=Object.getOwnPropertySymbols(e);at.indexOf(i[a])&&Object.prototype.propertyIsEnumerable.call(e,i[a])&&(n[i[a]]=e[i[a]]);return n};let y=t.forwardRef((e,i)=>{let{defaultValue:a,children:l,options:o=[],prefixCls:s,className:c,rootClassName:m,style:b,onChange:y}=e,v=$(e,["defaultValue","children","options","prefixCls","className","rootClassName","style","onChange"]),{getPrefixCls:S,direction:O}=t.useContext(r.ConfigContext),[x,C]=t.useState(v.value||a||[]),[j,w]=t.useState([]);t.useEffect(()=>{"value"in v&&C(v.value||[])},[v.value]);let E=t.useMemo(()=>o.map(e=>"string"==typeof e||"number"==typeof e?{label:e,value:e}:e),[o]),k=e=>{w(t=>t.filter(t=>t!==e))},z=e=>{w(t=>[].concat((0,f.default)(t),[e]))},N=e=>{let t=x.indexOf(e.value),n=(0,f.default)(x);-1===t?n.push(e.value):n.splice(t,1),"value"in v||C(n),null==y||y(n.filter(e=>j.includes(e)).sort((e,t)=>E.findIndex(t=>t.value===e)-E.findIndex(e=>e.value===t)))},I=S("checkbox",s),P=`${I}-group`,T=(0,d.default)(I),[M,B,D]=(0,p.default)(I,T),L=(0,h.default)(v,["value","disabled"]),R=o.length?E.map(e=>t.createElement(g,{prefixCls:I,key:e.value.toString(),disabled:"disabled"in e?e.disabled:v.disabled,value:e.value,checked:x.includes(e.value),onChange:e.onChange,className:(0,n.default)(`${P}-item`,e.className),style:e.style,title:e.title,id:e.id,required:e.required},e.label)):l,G=t.useMemo(()=>({toggleOption:N,value:x,disabled:v.disabled,name:v.name,registerValue:z,cancelValue:k}),[N,x,v.disabled,v.name,z,k]),H=(0,n.default)(P,{[`${P}-rtl`]:"rtl"===O},c,m,D,T,B);return M(t.createElement("div",Object.assign({className:H,style:b},L,{ref:i}),t.createElement(u.default.Provider,{value:G},R)))});g.Group=y,g.__ANT_CHECKBOX=!0,e.s(["default",0,g],374276)},244451,e=>{"use strict";let t;e.i(247167);var n=e.i(271645),i=e.i(343794),a=e.i(242064),l=e.i(763731),o=e.i(174428);let r=80*Math.PI,s=e=>{let{dotClassName:t,style:a,hasCircleCls:l}=e;return n.createElement("circle",{className:(0,i.default)(`${t}-circle`,{[`${t}-circle-bg`]:l}),r:40,cx:50,cy:50,strokeWidth:20,style:a})},d=({percent:e,prefixCls:t})=>{let a=`${t}-dot`,l=`${a}-holder`,d=`${l}-hidden`,[c,u]=n.useState(!1);(0,o.default)(()=>{0!==e&&u(!0)},[0!==e]);let p=Math.max(Math.min(e,100),0);if(!c)return null;let m={strokeDashoffset:`${r/4}`,strokeDasharray:`${r*p/100} ${r*(100-p)/100}`};return n.createElement("span",{className:(0,i.default)(l,`${a}-progress`,p<=0&&d)},n.createElement("svg",{viewBox:"0 0 100 100",role:"progressbar","aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":p},n.createElement(s,{dotClassName:a,hasCircleCls:!0}),n.createElement(s,{dotClassName:a,style:m})))};function c(e){let{prefixCls:t,percent:a=0}=e,l=`${t}-dot`,o=`${l}-holder`,r=`${o}-hidden`;return n.createElement(n.Fragment,null,n.createElement("span",{className:(0,i.default)(o,a>0&&r)},n.createElement("span",{className:(0,i.default)(l,`${t}-dot-spin`)},[1,2,3,4].map(e=>n.createElement("i",{className:`${t}-dot-item`,key:e})))),n.createElement(d,{prefixCls:t,percent:a}))}function u(e){var t;let{prefixCls:a,indicator:o,percent:r}=e,s=`${a}-dot`;return o&&n.isValidElement(o)?(0,l.cloneElement)(o,{className:(0,i.default)(null==(t=o.props)?void 0:t.className,s),percent:r}):n.createElement(c,{prefixCls:a,percent:r})}e.i(296059);var p=e.i(694758),m=e.i(183293),b=e.i(246422),g=e.i(838378);let f=new p.Keyframes("antSpinMove",{to:{opacity:1}}),h=new p.Keyframes("antRotate",{to:{transform:"rotate(405deg)"}}),$=(0,b.genStyleHooks)("Spin",e=>(e=>{let{componentCls:t,calc:n}=e;return{[t]:Object.assign(Object.assign({},(0,m.resetComponent)(e)),{position:"absolute",display:"none",color:e.colorPrimary,fontSize:0,textAlign:"center",verticalAlign:"middle",opacity:0,transition:`transform ${e.motionDurationSlow} ${e.motionEaseInOutCirc}`,"&-spinning":{position:"relative",display:"inline-block",opacity:1},[`${t}-text`]:{fontSize:e.fontSize,paddingTop:n(n(e.dotSize).sub(e.fontSize)).div(2).add(2).equal()},"&-fullscreen":{position:"fixed",width:"100vw",height:"100vh",backgroundColor:e.colorBgMask,zIndex:e.zIndexPopupBase,inset:0,display:"flex",alignItems:"center",flexDirection:"column",justifyContent:"center",opacity:0,visibility:"hidden",transition:`all ${e.motionDurationMid}`,"&-show":{opacity:1,visibility:"visible"},[t]:{[`${t}-dot-holder`]:{color:e.colorWhite},[`${t}-text`]:{color:e.colorTextLightSolid}}},"&-nested-loading":{position:"relative",[`> div > ${t}`]:{position:"absolute",top:0,insetInlineStart:0,zIndex:4,display:"block",width:"100%",height:"100%",maxHeight:e.contentHeight,[`${t}-dot`]:{position:"absolute",top:"50%",insetInlineStart:"50%",margin:n(e.dotSize).mul(-1).div(2).equal()},[`${t}-text`]:{position:"absolute",top:"50%",width:"100%",textShadow:`0 1px 2px ${e.colorBgContainer}`},[`&${t}-show-text ${t}-dot`]:{marginTop:n(e.dotSize).div(2).mul(-1).sub(10).equal()},"&-sm":{[`${t}-dot`]:{margin:n(e.dotSizeSM).mul(-1).div(2).equal()},[`${t}-text`]:{paddingTop:n(n(e.dotSizeSM).sub(e.fontSize)).div(2).add(2).equal()},[`&${t}-show-text ${t}-dot`]:{marginTop:n(e.dotSizeSM).div(2).mul(-1).sub(10).equal()}},"&-lg":{[`${t}-dot`]:{margin:n(e.dotSizeLG).mul(-1).div(2).equal()},[`${t}-text`]:{paddingTop:n(n(e.dotSizeLG).sub(e.fontSize)).div(2).add(2).equal()},[`&${t}-show-text ${t}-dot`]:{marginTop:n(e.dotSizeLG).div(2).mul(-1).sub(10).equal()}}},[`${t}-container`]:{position:"relative",transition:`opacity ${e.motionDurationSlow}`,"&::after":{position:"absolute",top:0,insetInlineEnd:0,bottom:0,insetInlineStart:0,zIndex:10,width:"100%",height:"100%",background:e.colorBgContainer,opacity:0,transition:`all ${e.motionDurationSlow}`,content:'""',pointerEvents:"none"}},[`${t}-blur`]:{clear:"both",opacity:.5,userSelect:"none",pointerEvents:"none","&::after":{opacity:.4,pointerEvents:"auto"}}},"&-tip":{color:e.spinDotDefault},[`${t}-dot-holder`]:{width:"1em",height:"1em",fontSize:e.dotSize,display:"inline-block",transition:`transform ${e.motionDurationSlow} ease, opacity ${e.motionDurationSlow} ease`,transformOrigin:"50% 50%",lineHeight:1,color:e.colorPrimary,"&-hidden":{transform:"scale(0.3)",opacity:0}},[`${t}-dot-progress`]:{position:"absolute",inset:0},[`${t}-dot`]:{position:"relative",display:"inline-block",fontSize:e.dotSize,width:"1em",height:"1em","&-item":{position:"absolute",display:"block",width:n(e.dotSize).sub(n(e.marginXXS).div(2)).div(2).equal(),height:n(e.dotSize).sub(n(e.marginXXS).div(2)).div(2).equal(),background:"currentColor",borderRadius:"100%",transform:"scale(0.75)",transformOrigin:"50% 50%",opacity:.3,animationName:f,animationDuration:"1s",animationIterationCount:"infinite",animationTimingFunction:"linear",animationDirection:"alternate","&:nth-child(1)":{top:0,insetInlineStart:0,animationDelay:"0s"},"&:nth-child(2)":{top:0,insetInlineEnd:0,animationDelay:"0.4s"},"&:nth-child(3)":{insetInlineEnd:0,bottom:0,animationDelay:"0.8s"},"&:nth-child(4)":{bottom:0,insetInlineStart:0,animationDelay:"1.2s"}},"&-spin":{transform:"rotate(45deg)",animationName:h,animationDuration:"1.2s",animationIterationCount:"infinite",animationTimingFunction:"linear"},"&-circle":{strokeLinecap:"round",transition:["stroke-dashoffset","stroke-dasharray","stroke","stroke-width","opacity"].map(t=>`${t} ${e.motionDurationSlow} ease`).join(","),fillOpacity:0,stroke:"currentcolor"},"&-circle-bg":{stroke:e.colorFillSecondary}},[`&-sm ${t}-dot`]:{"&, &-holder":{fontSize:e.dotSizeSM}},[`&-sm ${t}-dot-holder`]:{i:{width:n(n(e.dotSizeSM).sub(n(e.marginXXS).div(2))).div(2).equal(),height:n(n(e.dotSizeSM).sub(n(e.marginXXS).div(2))).div(2).equal()}},[`&-lg ${t}-dot`]:{"&, &-holder":{fontSize:e.dotSizeLG}},[`&-lg ${t}-dot-holder`]:{i:{width:n(n(e.dotSizeLG).sub(e.marginXXS)).div(2).equal(),height:n(n(e.dotSizeLG).sub(e.marginXXS)).div(2).equal()}},[`&${t}-show-text ${t}-text`]:{display:"block"}})}})((0,g.mergeToken)(e,{spinDotDefault:e.colorTextDescription})),e=>{let{controlHeightLG:t,controlHeight:n}=e;return{contentHeight:400,dotSize:t/2,dotSizeSM:.35*t,dotSizeLG:n}}),y=[[30,.05],[70,.03],[96,.01]];var v=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,i=Object.getOwnPropertySymbols(e);at.indexOf(i[a])&&Object.prototype.propertyIsEnumerable.call(e,i[a])&&(n[i[a]]=e[i[a]]);return n};let S=e=>{var l;let{prefixCls:o,spinning:r=!0,delay:s=0,className:d,rootClassName:c,size:p="default",tip:m,wrapperClassName:b,style:g,children:f,fullscreen:h=!1,indicator:S,percent:O}=e,x=v(e,["prefixCls","spinning","delay","className","rootClassName","size","tip","wrapperClassName","style","children","fullscreen","indicator","percent"]),{getPrefixCls:C,direction:j,className:w,style:E,indicator:k}=(0,a.useComponentConfig)("spin"),z=C("spin",o),[N,I,P]=$(z),[T,M]=n.useState(()=>r&&(!r||!s||!!Number.isNaN(Number(s)))),B=function(e,t){let[i,a]=n.useState(0),l=n.useRef(null),o="auto"===t;return n.useEffect(()=>(o&&e&&(a(0),l.current=setInterval(()=>{a(e=>{let t=100-e;for(let n=0;n{l.current&&(clearInterval(l.current),l.current=null)}),[o,e]),o?i:t}(T,O);n.useEffect(()=>{if(r){let e=function(e,t,n){var i,a=n||{},l=a.noTrailing,o=void 0!==l&&l,r=a.noLeading,s=void 0!==r&&r,d=a.debounceMode,c=void 0===d?void 0:d,u=!1,p=0;function m(){i&&clearTimeout(i)}function b(){for(var n=arguments.length,a=Array(n),l=0;le?s?(p=Date.now(),o||(i=setTimeout(c?g:b,e))):b():!0!==o&&(i=setTimeout(c?g:b,void 0===c?e-d:e)))}return b.cancel=function(e){var t=(e||{}).upcomingOnly;m(),u=!(void 0!==t&&t)},b}(s,()=>{M(!0)},{debounceMode:false});return e(),()=>{var t;null==(t=null==e?void 0:e.cancel)||t.call(e)}}M(!1)},[s,r]);let D=n.useMemo(()=>void 0!==f&&!h,[f,h]),L=(0,i.default)(z,w,{[`${z}-sm`]:"small"===p,[`${z}-lg`]:"large"===p,[`${z}-spinning`]:T,[`${z}-show-text`]:!!m,[`${z}-rtl`]:"rtl"===j},d,!h&&c,I,P),R=(0,i.default)(`${z}-container`,{[`${z}-blur`]:T}),G=null!=(l=null!=S?S:k)?l:t,H=Object.assign(Object.assign({},E),g),W=n.createElement("div",Object.assign({},x,{style:H,className:L,"aria-live":"polite","aria-busy":T}),n.createElement(u,{prefixCls:z,indicator:G,percent:B}),m&&(D||h)?n.createElement("div",{className:`${z}-text`},m):null);return N(D?n.createElement("div",Object.assign({},x,{className:(0,i.default)(`${z}-nested-loading`,b,I,P)}),T&&n.createElement("div",{key:"loading"},W),n.createElement("div",{className:R,key:"container"},f)):h?n.createElement("div",{className:(0,i.default)(`${z}-fullscreen`,{[`${z}-fullscreen-show`]:T},c,I,P)},W):W)};S.setDefaultIndicator=e=>{t=e},e.s(["default",0,S],244451)},175712,e=>{"use strict";e.i(247167);var t=e.i(271645),n=e.i(343794),i=e.i(529681),a=e.i(242064),l=e.i(517455),o=e.i(185793),r=e.i(721369),s=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,i=Object.getOwnPropertySymbols(e);at.indexOf(i[a])&&Object.prototype.propertyIsEnumerable.call(e,i[a])&&(n[i[a]]=e[i[a]]);return n};let d=e=>{var{prefixCls:i,className:l,hoverable:o=!0}=e,r=s(e,["prefixCls","className","hoverable"]);let{getPrefixCls:d}=t.useContext(a.ConfigContext),c=d("card",i),u=(0,n.default)(`${c}-grid`,l,{[`${c}-grid-hoverable`]:o});return t.createElement("div",Object.assign({},r,{className:u}))};e.i(296059);var c=e.i(915654),u=e.i(183293),p=e.i(246422),m=e.i(838378);let b=(0,p.genStyleHooks)("Card",e=>{let t=(0,m.mergeToken)(e,{cardShadow:e.boxShadowCard,cardHeadPadding:e.padding,cardPaddingBase:e.paddingLG,cardActionsIconSize:e.fontSize});return[(e=>{let{componentCls:t,cardShadow:n,cardHeadPadding:i,colorBorderSecondary:a,boxShadowTertiary:l,bodyPadding:o,extraColor:r}=e;return{[t]:Object.assign(Object.assign({},(0,u.resetComponent)(e)),{position:"relative",background:e.colorBgContainer,borderRadius:e.borderRadiusLG,[`&:not(${t}-bordered)`]:{boxShadow:l},[`${t}-head`]:(e=>{let{antCls:t,componentCls:n,headerHeight:i,headerPadding:a,tabsMarginBottom:l}=e;return Object.assign(Object.assign({display:"flex",justifyContent:"center",flexDirection:"column",minHeight:i,marginBottom:-1,padding:`0 ${(0,c.unit)(a)}`,color:e.colorTextHeading,fontWeight:e.fontWeightStrong,fontSize:e.headerFontSize,background:e.headerBg,borderBottom:`${(0,c.unit)(e.lineWidth)} ${e.lineType} ${e.colorBorderSecondary}`,borderRadius:`${(0,c.unit)(e.borderRadiusLG)} ${(0,c.unit)(e.borderRadiusLG)} 0 0`},(0,u.clearFix)()),{"&-wrapper":{width:"100%",display:"flex",alignItems:"center"},"&-title":Object.assign(Object.assign({display:"inline-block",flex:1},u.textEllipsis),{[` - > ${n}-typography, - > ${n}-typography-edit-content - `]:{insetInlineStart:0,marginTop:0,marginBottom:0}}),[`${t}-tabs-top`]:{clear:"both",marginBottom:l,color:e.colorText,fontWeight:"normal",fontSize:e.fontSize,"&-bar":{borderBottom:`${(0,c.unit)(e.lineWidth)} ${e.lineType} ${e.colorBorderSecondary}`}}})})(e),[`${t}-extra`]:{marginInlineStart:"auto",color:r,fontWeight:"normal",fontSize:e.fontSize},[`${t}-body`]:{padding:o,borderRadius:`0 0 ${(0,c.unit)(e.borderRadiusLG)} ${(0,c.unit)(e.borderRadiusLG)}`},[`${t}-grid`]:(e=>{let{cardPaddingBase:t,colorBorderSecondary:n,cardShadow:i,lineWidth:a}=e;return{width:"33.33%",padding:t,border:0,borderRadius:0,boxShadow:` - ${(0,c.unit)(a)} 0 0 0 ${n}, - 0 ${(0,c.unit)(a)} 0 0 ${n}, - ${(0,c.unit)(a)} ${(0,c.unit)(a)} 0 0 ${n}, - ${(0,c.unit)(a)} 0 0 0 ${n} inset, - 0 ${(0,c.unit)(a)} 0 0 ${n} inset; - `,transition:`all ${e.motionDurationMid}`,"&-hoverable:hover":{position:"relative",zIndex:1,boxShadow:i}}})(e),[`${t}-cover`]:{"> *":{display:"block",width:"100%",borderRadius:`${(0,c.unit)(e.borderRadiusLG)} ${(0,c.unit)(e.borderRadiusLG)} 0 0`}},[`${t}-actions`]:(e=>{let{componentCls:t,iconCls:n,actionsLiMargin:i,cardActionsIconSize:a,colorBorderSecondary:l,actionsBg:o}=e;return Object.assign(Object.assign({margin:0,padding:0,listStyle:"none",background:o,borderTop:`${(0,c.unit)(e.lineWidth)} ${e.lineType} ${l}`,display:"flex",borderRadius:`0 0 ${(0,c.unit)(e.borderRadiusLG)} ${(0,c.unit)(e.borderRadiusLG)}`},(0,u.clearFix)()),{"& > li":{margin:i,color:e.colorTextDescription,textAlign:"center","> span":{position:"relative",display:"block",minWidth:e.calc(e.cardActionsIconSize).mul(2).equal(),fontSize:e.fontSize,lineHeight:e.lineHeight,cursor:"pointer","&:hover":{color:e.colorPrimary,transition:`color ${e.motionDurationMid}`},[`a:not(${t}-btn), > ${n}`]:{display:"inline-block",width:"100%",color:e.colorIcon,lineHeight:(0,c.unit)(e.fontHeight),transition:`color ${e.motionDurationMid}`,"&:hover":{color:e.colorPrimary}},[`> ${n}`]:{fontSize:a,lineHeight:(0,c.unit)(e.calc(a).mul(e.lineHeight).equal())}},"&:not(:last-child)":{borderInlineEnd:`${(0,c.unit)(e.lineWidth)} ${e.lineType} ${l}`}}})})(e),[`${t}-meta`]:Object.assign(Object.assign({margin:`${(0,c.unit)(e.calc(e.marginXXS).mul(-1).equal())} 0`,display:"flex"},(0,u.clearFix)()),{"&-avatar":{paddingInlineEnd:e.padding},"&-detail":{overflow:"hidden",flex:1,"> div:not(:last-child)":{marginBottom:e.marginXS}},"&-title":Object.assign({color:e.colorTextHeading,fontWeight:e.fontWeightStrong,fontSize:e.fontSizeLG},u.textEllipsis),"&-description":{color:e.colorTextDescription}})}),[`${t}-bordered`]:{border:`${(0,c.unit)(e.lineWidth)} ${e.lineType} ${a}`,[`${t}-cover`]:{marginTop:-1,marginInlineStart:-1,marginInlineEnd:-1}},[`${t}-hoverable`]:{cursor:"pointer",transition:`box-shadow ${e.motionDurationMid}, border-color ${e.motionDurationMid}`,"&:hover":{borderColor:"transparent",boxShadow:n}},[`${t}-contain-grid`]:{borderRadius:`${(0,c.unit)(e.borderRadiusLG)} ${(0,c.unit)(e.borderRadiusLG)} 0 0 `,[`${t}-body`]:{display:"flex",flexWrap:"wrap"},[`&:not(${t}-loading) ${t}-body`]:{marginBlockStart:e.calc(e.lineWidth).mul(-1).equal(),marginInlineStart:e.calc(e.lineWidth).mul(-1).equal(),padding:0}},[`${t}-contain-tabs`]:{[`> div${t}-head`]:{minHeight:0,[`${t}-head-title, ${t}-extra`]:{paddingTop:i}}},[`${t}-type-inner`]:(e=>{let{componentCls:t,colorFillAlter:n,headerPadding:i,bodyPadding:a}=e;return{[`${t}-head`]:{padding:`0 ${(0,c.unit)(i)}`,background:n,"&-title":{fontSize:e.fontSize}},[`${t}-body`]:{padding:`${(0,c.unit)(e.padding)} ${(0,c.unit)(a)}`}}})(e),[`${t}-loading`]:(e=>{let{componentCls:t}=e;return{overflow:"hidden",[`${t}-body`]:{userSelect:"none"}}})(e),[`${t}-rtl`]:{direction:"rtl"}}})(t),(e=>{let{componentCls:t,bodyPaddingSM:n,headerPaddingSM:i,headerHeightSM:a,headerFontSizeSM:l}=e;return{[`${t}-small`]:{[`> ${t}-head`]:{minHeight:a,padding:`0 ${(0,c.unit)(i)}`,fontSize:l,[`> ${t}-head-wrapper`]:{[`> ${t}-extra`]:{fontSize:e.fontSize}}},[`> ${t}-body`]:{padding:n}},[`${t}-small${t}-contain-tabs`]:{[`> ${t}-head`]:{[`${t}-head-title, ${t}-extra`]:{paddingTop:0,display:"flex",alignItems:"center"}}}}})(t)]},e=>{var t,n;return{headerBg:"transparent",headerFontSize:e.fontSizeLG,headerFontSizeSM:e.fontSize,headerHeight:e.fontSizeLG*e.lineHeightLG+2*e.padding,headerHeightSM:e.fontSize*e.lineHeight+2*e.paddingXS,actionsBg:e.colorBgContainer,actionsLiMargin:`${e.paddingSM}px 0`,tabsMarginBottom:-e.padding-e.lineWidth,extraColor:e.colorText,bodyPaddingSM:12,headerPaddingSM:12,bodyPadding:null!=(t=e.bodyPadding)?t:e.paddingLG,headerPadding:null!=(n=e.headerPadding)?n:e.paddingLG}});var g=e.i(792812),f=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,i=Object.getOwnPropertySymbols(e);at.indexOf(i[a])&&Object.prototype.propertyIsEnumerable.call(e,i[a])&&(n[i[a]]=e[i[a]]);return n};let h=e=>{let{actionClasses:n,actions:i=[],actionStyle:a}=e;return t.createElement("ul",{className:n,style:a},i.map((e,n)=>{let a=`action-${n}`;return t.createElement("li",{style:{width:`${100/i.length}%`},key:a},t.createElement("span",null,e))}))},$=t.forwardRef((e,s)=>{let c,{prefixCls:u,className:p,rootClassName:m,style:$,extra:y,headStyle:v={},bodyStyle:S={},title:O,loading:x,bordered:C,variant:j,size:w,type:E,cover:k,actions:z,tabList:N,children:I,activeTabKey:P,defaultActiveTabKey:T,tabBarExtraContent:M,hoverable:B,tabProps:D={},classNames:L,styles:R}=e,G=f(e,["prefixCls","className","rootClassName","style","extra","headStyle","bodyStyle","title","loading","bordered","variant","size","type","cover","actions","tabList","children","activeTabKey","defaultActiveTabKey","tabBarExtraContent","hoverable","tabProps","classNames","styles"]),{getPrefixCls:H,direction:W,card:q}=t.useContext(a.ConfigContext),[X]=(0,g.default)("card",j,C),F=e=>{var t;return(0,n.default)(null==(t=null==q?void 0:q.classNames)?void 0:t[e],null==L?void 0:L[e])},A=e=>{var t;return Object.assign(Object.assign({},null==(t=null==q?void 0:q.styles)?void 0:t[e]),null==R?void 0:R[e])},K=t.useMemo(()=>{let e=!1;return t.Children.forEach(I,t=>{(null==t?void 0:t.type)===d&&(e=!0)}),e},[I]),V=H("card",u),[_,U,J]=b(V),Q=t.createElement(o.default,{loading:!0,active:!0,paragraph:{rows:4},title:!1},I),Y=void 0!==P,Z=Object.assign(Object.assign({},D),{[Y?"activeKey":"defaultActiveKey"]:Y?P:T,tabBarExtraContent:M}),ee=(0,l.default)(w),et=ee&&"default"!==ee?ee:"large",en=N?t.createElement(r.default,Object.assign({size:et},Z,{className:`${V}-head-tabs`,onChange:t=>{var n;null==(n=e.onTabChange)||n.call(e,t)},items:N.map(e=>{var{tab:t}=e;return Object.assign({label:t},f(e,["tab"]))})})):null;if(O||y||en){let e=(0,n.default)(`${V}-head`,F("header")),i=(0,n.default)(`${V}-head-title`,F("title")),a=(0,n.default)(`${V}-extra`,F("extra")),l=Object.assign(Object.assign({},v),A("header"));c=t.createElement("div",{className:e,style:l},t.createElement("div",{className:`${V}-head-wrapper`},O&&t.createElement("div",{className:i,style:A("title")},O),y&&t.createElement("div",{className:a,style:A("extra")},y)),en)}let ei=(0,n.default)(`${V}-cover`,F("cover")),ea=k?t.createElement("div",{className:ei,style:A("cover")},k):null,el=(0,n.default)(`${V}-body`,F("body")),eo=Object.assign(Object.assign({},S),A("body")),er=t.createElement("div",{className:el,style:eo},x?Q:I),es=(0,n.default)(`${V}-actions`,F("actions")),ed=(null==z?void 0:z.length)?t.createElement(h,{actionClasses:es,actionStyle:A("actions"),actions:z}):null,ec=(0,i.default)(G,["onTabChange"]),eu=(0,n.default)(V,null==q?void 0:q.className,{[`${V}-loading`]:x,[`${V}-bordered`]:"borderless"!==X,[`${V}-hoverable`]:B,[`${V}-contain-grid`]:K,[`${V}-contain-tabs`]:null==N?void 0:N.length,[`${V}-${ee}`]:ee,[`${V}-type-${E}`]:!!E,[`${V}-rtl`]:"rtl"===W},p,m,U,J),ep=Object.assign(Object.assign({},null==q?void 0:q.style),$);return _(t.createElement("div",Object.assign({ref:s},ec,{className:eu,style:ep}),c,ea,er,ed))});var y=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,i=Object.getOwnPropertySymbols(e);at.indexOf(i[a])&&Object.prototype.propertyIsEnumerable.call(e,i[a])&&(n[i[a]]=e[i[a]]);return n};$.Grid=d,$.Meta=e=>{let{prefixCls:i,className:l,avatar:o,title:r,description:s}=e,d=y(e,["prefixCls","className","avatar","title","description"]),{getPrefixCls:c}=t.useContext(a.ConfigContext),u=c("card",i),p=(0,n.default)(`${u}-meta`,l),m=o?t.createElement("div",{className:`${u}-meta-avatar`},o):null,b=r?t.createElement("div",{className:`${u}-meta-title`},r):null,g=s?t.createElement("div",{className:`${u}-meta-description`},s):null,f=b||g?t.createElement("div",{className:`${u}-meta-detail`},b,g):null;return t.createElement("div",Object.assign({},d,{className:p}),m,f)},e.s(["Card",0,$],175712)},869216,e=>{"use strict";e.i(247167);var t=e.i(271645),n=e.i(343794),i=e.i(908206),a=e.i(242064),l=e.i(517455),o=e.i(150073);let r={xxl:3,xl:3,lg:3,md:3,sm:2,xs:1},s=t.default.createContext({});var d=e.i(876556),c=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,i=Object.getOwnPropertySymbols(e);at.indexOf(i[a])&&Object.prototype.propertyIsEnumerable.call(e,i[a])&&(n[i[a]]=e[i[a]]);return n},u=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,i=Object.getOwnPropertySymbols(e);at.indexOf(i[a])&&Object.prototype.propertyIsEnumerable.call(e,i[a])&&(n[i[a]]=e[i[a]]);return n};let p=e=>{let{itemPrefixCls:i,component:a,span:l,className:o,style:r,labelStyle:d,contentStyle:c,bordered:u,label:p,content:m,colon:b,type:g,styles:f}=e,{classNames:h}=t.useContext(s),$=Object.assign(Object.assign({},d),null==f?void 0:f.label),y=Object.assign(Object.assign({},c),null==f?void 0:f.content);if(u)return t.createElement(a,{colSpan:l,style:r,className:(0,n.default)(o,{[`${i}-item-${g}`]:"label"===g||"content"===g,[null==h?void 0:h.label]:(null==h?void 0:h.label)&&"label"===g,[null==h?void 0:h.content]:(null==h?void 0:h.content)&&"content"===g})},null!=p&&t.createElement("span",{style:$},p),null!=m&&t.createElement("span",{style:y},m));return t.createElement(a,{colSpan:l,style:r,className:(0,n.default)(`${i}-item`,o)},t.createElement("div",{className:`${i}-item-container`},null!=p&&t.createElement("span",{style:$,className:(0,n.default)(`${i}-item-label`,null==h?void 0:h.label,{[`${i}-item-no-colon`]:!b})},p),null!=m&&t.createElement("span",{style:y,className:(0,n.default)(`${i}-item-content`,null==h?void 0:h.content)},m)))};function m(e,{colon:n,prefixCls:i,bordered:a},{component:l,type:o,showLabel:r,showContent:s,labelStyle:d,contentStyle:c,styles:u}){return e.map(({label:e,children:m,prefixCls:b=i,className:g,style:f,labelStyle:h,contentStyle:$,span:y=1,key:v,styles:S},O)=>"string"==typeof l?t.createElement(p,{key:`${o}-${v||O}`,className:g,style:f,styles:{label:Object.assign(Object.assign(Object.assign(Object.assign({},d),null==u?void 0:u.label),h),null==S?void 0:S.label),content:Object.assign(Object.assign(Object.assign(Object.assign({},c),null==u?void 0:u.content),$),null==S?void 0:S.content)},span:y,colon:n,component:l,itemPrefixCls:b,bordered:a,label:r?e:null,content:s?m:null,type:o}):[t.createElement(p,{key:`label-${v||O}`,className:g,style:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},d),null==u?void 0:u.label),f),h),null==S?void 0:S.label),span:1,colon:n,component:l[0],itemPrefixCls:b,bordered:a,label:e,type:"label"}),t.createElement(p,{key:`content-${v||O}`,className:g,style:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},c),null==u?void 0:u.content),f),$),null==S?void 0:S.content),span:2*y-1,component:l[1],itemPrefixCls:b,bordered:a,content:m,type:"content"})])}let b=e=>{let n=t.useContext(s),{prefixCls:i,vertical:a,row:l,index:o,bordered:r}=e;return a?t.createElement(t.Fragment,null,t.createElement("tr",{key:`label-${o}`,className:`${i}-row`},m(l,e,Object.assign({component:"th",type:"label",showLabel:!0},n))),t.createElement("tr",{key:`content-${o}`,className:`${i}-row`},m(l,e,Object.assign({component:"td",type:"content",showContent:!0},n)))):t.createElement("tr",{key:o,className:`${i}-row`},m(l,e,Object.assign({component:r?["th","td"]:"td",type:"item",showLabel:!0,showContent:!0},n)))};e.i(296059);var g=e.i(915654),f=e.i(183293),h=e.i(246422),$=e.i(838378);let y=(0,h.genStyleHooks)("Descriptions",e=>(e=>{let{componentCls:t,extraColor:n,itemPaddingBottom:i,itemPaddingEnd:a,colonMarginRight:l,colonMarginLeft:o,titleMarginBottom:r}=e;return{[t]:Object.assign(Object.assign(Object.assign({},(0,f.resetComponent)(e)),(e=>{let{componentCls:t,labelBg:n}=e;return{[`&${t}-bordered`]:{[`> ${t}-view`]:{border:`${(0,g.unit)(e.lineWidth)} ${e.lineType} ${e.colorSplit}`,"> table":{tableLayout:"auto"},[`${t}-row`]:{borderBottom:`${(0,g.unit)(e.lineWidth)} ${e.lineType} ${e.colorSplit}`,"&:first-child":{"> th:first-child, > td:first-child":{borderStartStartRadius:e.borderRadiusLG}},"&:last-child":{borderBottom:"none","> th:first-child, > td:first-child":{borderEndStartRadius:e.borderRadiusLG}},[`> ${t}-item-label, > ${t}-item-content`]:{padding:`${(0,g.unit)(e.padding)} ${(0,g.unit)(e.paddingLG)}`,borderInlineEnd:`${(0,g.unit)(e.lineWidth)} ${e.lineType} ${e.colorSplit}`,"&:last-child":{borderInlineEnd:"none"}},[`> ${t}-item-label`]:{color:e.colorTextSecondary,backgroundColor:n,"&::after":{display:"none"}}}},[`&${t}-middle`]:{[`${t}-row`]:{[`> ${t}-item-label, > ${t}-item-content`]:{padding:`${(0,g.unit)(e.paddingSM)} ${(0,g.unit)(e.paddingLG)}`}}},[`&${t}-small`]:{[`${t}-row`]:{[`> ${t}-item-label, > ${t}-item-content`]:{padding:`${(0,g.unit)(e.paddingXS)} ${(0,g.unit)(e.padding)}`}}}}}})(e)),{"&-rtl":{direction:"rtl"},[`${t}-header`]:{display:"flex",alignItems:"center",marginBottom:r},[`${t}-title`]:Object.assign(Object.assign({},f.textEllipsis),{flex:"auto",color:e.titleColor,fontWeight:e.fontWeightStrong,fontSize:e.fontSizeLG,lineHeight:e.lineHeightLG}),[`${t}-extra`]:{marginInlineStart:"auto",color:n,fontSize:e.fontSize},[`${t}-view`]:{width:"100%",borderRadius:e.borderRadiusLG,table:{width:"100%",tableLayout:"fixed",borderCollapse:"collapse"}},[`${t}-row`]:{"> th, > td":{paddingBottom:i,paddingInlineEnd:a},"> th:last-child, > td:last-child":{paddingInlineEnd:0},"&:last-child":{borderBottom:"none","> th, > td":{paddingBottom:0}}},[`${t}-item-label`]:{color:e.labelColor,fontWeight:"normal",fontSize:e.fontSize,lineHeight:e.lineHeight,textAlign:"start","&::after":{content:'":"',position:"relative",top:-.5,marginInline:`${(0,g.unit)(o)} ${(0,g.unit)(l)}`},[`&${t}-item-no-colon::after`]:{content:'""'}},[`${t}-item-no-label`]:{"&::after":{margin:0,content:'""'}},[`${t}-item-content`]:{display:"table-cell",flex:1,color:e.contentColor,fontSize:e.fontSize,lineHeight:e.lineHeight,wordBreak:"break-word",overflowWrap:"break-word"},[`${t}-item`]:{paddingBottom:0,verticalAlign:"top","&-container":{display:"flex",[`${t}-item-label`]:{display:"inline-flex",alignItems:"baseline"},[`${t}-item-content`]:{display:"inline-flex",alignItems:"baseline",minWidth:"1em"}}},"&-middle":{[`${t}-row`]:{"> th, > td":{paddingBottom:e.paddingSM}}},"&-small":{[`${t}-row`]:{"> th, > td":{paddingBottom:e.paddingXS}}}})}})((0,$.mergeToken)(e,{})),e=>({labelBg:e.colorFillAlter,labelColor:e.colorTextTertiary,titleColor:e.colorText,titleMarginBottom:e.fontSizeSM*e.lineHeightSM,itemPaddingBottom:e.padding,itemPaddingEnd:e.padding,colonMarginRight:e.marginXS,colonMarginLeft:e.marginXXS/2,contentColor:e.colorText,extraColor:e.colorText}));var v=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var a=0,i=Object.getOwnPropertySymbols(e);at.indexOf(i[a])&&Object.prototype.propertyIsEnumerable.call(e,i[a])&&(n[i[a]]=e[i[a]]);return n};let S=e=>{let p,{prefixCls:m,title:g,extra:f,column:h,colon:$=!0,bordered:S,layout:O,children:x,className:C,rootClassName:j,style:w,size:E,labelStyle:k,contentStyle:z,styles:N,items:I,classNames:P}=e,T=v(e,["prefixCls","title","extra","column","colon","bordered","layout","children","className","rootClassName","style","size","labelStyle","contentStyle","styles","items","classNames"]),{getPrefixCls:M,direction:B,className:D,style:L,classNames:R,styles:G}=(0,a.useComponentConfig)("descriptions"),H=M("descriptions",m),W=(0,o.default)(),q=t.useMemo(()=>{var e;return"number"==typeof h?h:null!=(e=(0,i.matchScreen)(W,Object.assign(Object.assign({},r),h)))?e:3},[W,h]),X=(p=t.useMemo(()=>I||(0,d.default)(x).map(e=>Object.assign(Object.assign({},null==e?void 0:e.props),{key:e.key})),[I,x]),t.useMemo(()=>p.map(e=>{var{span:t}=e,n=c(e,["span"]);return"filled"===t?Object.assign(Object.assign({},n),{filled:!0}):Object.assign(Object.assign({},n),{span:"number"==typeof t?t:(0,i.matchScreen)(W,t)})}),[p,W])),F=(0,l.default)(E),A=((e,n)=>{let[i,a]=(0,t.useMemo)(()=>{let t,i,a,l;return t=[],i=[],a=!1,l=0,n.filter(e=>e).forEach(n=>{let{filled:o}=n,r=u(n,["filled"]);if(o){i.push(r),t.push(i),i=[],l=0;return}let s=e-l;(l+=n.span||1)>=e?(l>e?(a=!0,i.push(Object.assign(Object.assign({},r),{span:s}))):i.push(r),t.push(i),i=[],l=0):i.push(r)}),i.length>0&&t.push(i),[t=t.map(t=>{let n=t.reduce((e,t)=>e+(t.span||1),0);if(n({labelStyle:k,contentStyle:z,styles:{content:Object.assign(Object.assign({},G.content),null==N?void 0:N.content),label:Object.assign(Object.assign({},G.label),null==N?void 0:N.label)},classNames:{label:(0,n.default)(R.label,null==P?void 0:P.label),content:(0,n.default)(R.content,null==P?void 0:P.content)}}),[k,z,N,P,R,G]);return K(t.createElement(s.Provider,{value:U},t.createElement("div",Object.assign({className:(0,n.default)(H,D,R.root,null==P?void 0:P.root,{[`${H}-${F}`]:F&&"default"!==F,[`${H}-bordered`]:!!S,[`${H}-rtl`]:"rtl"===B},C,j,V,_),style:Object.assign(Object.assign(Object.assign(Object.assign({},L),G.root),null==N?void 0:N.root),w)},T),(g||f)&&t.createElement("div",{className:(0,n.default)(`${H}-header`,R.header,null==P?void 0:P.header),style:Object.assign(Object.assign({},G.header),null==N?void 0:N.header)},g&&t.createElement("div",{className:(0,n.default)(`${H}-title`,R.title,null==P?void 0:P.title),style:Object.assign(Object.assign({},G.title),null==N?void 0:N.title)},g),f&&t.createElement("div",{className:(0,n.default)(`${H}-extra`,R.extra,null==P?void 0:P.extra),style:Object.assign(Object.assign({},G.extra),null==N?void 0:N.extra)},f)),t.createElement("div",{className:`${H}-view`},t.createElement("table",null,t.createElement("tbody",null,A.map((e,n)=>t.createElement(b,{key:n,index:n,colon:$,prefixCls:H,vertical:"vertical"===O,bordered:S,row:e}))))))))};S.Item=({children:e})=>e,e.s(["Descriptions",0,S],869216)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/017kxo-8o84bv.js b/litellm/proxy/_experimental/out/_next/static/chunks/017kxo-8o84bv.js new file mode 100644 index 00000000000..edb12734d22 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/017kxo-8o84bv.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,560025,e=>{"use strict";e.i(247167);var t=e.i(271645),n=e.i(343794),a=e.i(931067),l=e.i(392221),o=e.i(703923),i=e.i(211577),r=e.i(209428),s=e.i(410160),c=e.i(914949),u=e.i(529681),d=e.i(611935),f=e.i(361275),m=e.i(174428),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}},p=function(e){return void 0!==e?"".concat(e,"px"):void 0};function g(e){var a=e.prefixCls,o=e.containerRef,i=e.value,s=e.getValueIndex,c=e.motionName,u=e.onMotionStart,g=e.onMotionEnd,h=e.direction,b=e.vertical,y=void 0!==b&&b,w=t.useRef(null),x=t.useState(i),$=(0,l.default)(x,2),C=$[0],O=$[1],S=function(e){var t,n=s(e),l=null==(t=o.current)?void 0:t.querySelectorAll(".".concat(a,"-item"))[n];return(null==l?void 0:l.offsetParent)&&l},k=t.useState(null),E=(0,l.default)(k,2),N=E[0],j=E[1],R=t.useState(null),M=(0,l.default)(R,2),z=M[0],D=M[1];(0,m.default)(function(){if(C!==i){var e=S(C),t=S(i),n=v(e,y),a=v(t,y);O(i),j(n),D(a),e&&t?u():g()}},[i]);var I=t.useMemo(function(){if(y){var e;return p(null!=(e=null==N?void 0:N.top)?e:0)}return"rtl"===h?p(-(null==N?void 0:N.right)):p(null==N?void 0:N.left)},[y,h,N]),H=t.useMemo(function(){if(y){var e;return p(null!=(e=null==z?void 0:z.top)?e:0)}return"rtl"===h?p(-(null==z?void 0:z.right)):p(null==z?void 0:z.left)},[y,h,z]);return N&&z?t.createElement(f.default,{visible:!0,motionName:c,motionAppear:!0,onAppearStart:function(){return y?{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 y?{transform:"translateY(var(--thumb-active-top))",height:"var(--thumb-active-height)"}:{transform:"translateX(var(--thumb-active-left))",width:"var(--thumb-active-width)"}},onVisibleChanged:function(){j(null),D(null),g()}},function(e,l){var o=e.className,i=e.style,s=(0,r.default)((0,r.default)({},i),{},{"--thumb-start-left":I,"--thumb-start-width":p(null==N?void 0:N.width),"--thumb-active-left":H,"--thumb-active-width":p(null==z?void 0:z.width),"--thumb-start-top":I,"--thumb-start-height":p(null==N?void 0:N.height),"--thumb-active-top":H,"--thumb-active-height":p(null==z?void 0:z.height)}),c={ref:(0,d.composeRef)(w,l),style:s,className:(0,n.default)("".concat(a,"-thumb"),o)};return t.createElement("div",c)}):null}var h=["prefixCls","direction","vertical","options","disabled","defaultValue","value","name","onChange","className","motionName"],b=function(e){var a=e.prefixCls,l=e.className,o=e.disabled,r=e.checked,s=e.label,c=e.title,u=e.value,d=e.name,f=e.onChange,m=e.onFocus,v=e.onBlur,p=e.onKeyDown,g=e.onKeyUp,h=e.onMouseDown;return t.createElement("label",{className:(0,n.default)(l,(0,i.default)({},"".concat(a,"-item-disabled"),o)),onMouseDown:h},t.createElement("input",{name:d,className:"".concat(a,"-item-input"),type:"radio",disabled:o,checked:r,onChange:function(e){o||f(e,u)},onFocus:m,onBlur:v,onKeyDown:p,onKeyUp:g}),t.createElement("div",{className:"".concat(a,"-item-label"),title:c},s))},y=t.forwardRef(function(e,f){var m,v=e.prefixCls,p=void 0===v?"rc-segmented":v,y=e.direction,w=e.vertical,x=e.options,$=void 0===x?[]:x,C=e.disabled,O=e.defaultValue,S=e.value,k=e.name,E=e.onChange,N=e.className,j=e.motionName,R=(0,o.default)(e,h),M=t.useRef(null),z=t.useMemo(function(){return(0,d.composeRef)(M,f)},[M,f]),D=t.useMemo(function(){return $.map(function(e){if("object"===(0,s.default)(e)&&null!==e){var t=function(e){if(void 0!==e.title)return e.title;if("object"!==(0,s.default)(e.label)){var t;return null==(t=e.label)?void 0:t.toString()}}(e);return(0,r.default)((0,r.default)({},e),{},{title:t})}return{label:null==e?void 0:e.toString(),title:null==e?void 0:e.toString(),value:e}})},[$]),I=(0,c.default)(null==(m=D[0])?void 0:m.value,{value:S,defaultValue:O}),H=(0,l.default)(I,2),L=H[0],P=H[1],B=t.useState(!1),A=(0,l.default)(B,2),K=A[0],T=A[1],V=function(e,t){P(t),null==E||E(t)},U=(0,u.default)(R,["children"]),F=t.useState(!1),W=(0,l.default)(F,2),X=W[0],q=W[1],Y=t.useState(!1),_=(0,l.default)(Y,2),G=_[0],Z=_[1],J=function(){Z(!0)},Q=function(){Z(!1)},ee=function(){q(!1)},et=function(e){"Tab"===e.key&&q(!0)},en=function(e){var t=D.findIndex(function(e){return e.value===L}),n=D.length,a=D[(t+e+n)%n];a&&(P(a.value),null==E||E(a.value))},ea=function(e){switch(e.key){case"ArrowLeft":case"ArrowUp":en(-1);break;case"ArrowRight":case"ArrowDown":en(1)}};return t.createElement("div",(0,a.default)({role:"radiogroup","aria-label":"segmented control",tabIndex:C?void 0:0,"aria-orientation":w?"vertical":"horizontal"},U,{className:(0,n.default)(p,(0,i.default)((0,i.default)((0,i.default)({},"".concat(p,"-rtl"),"rtl"===y),"".concat(p,"-disabled"),C),"".concat(p,"-vertical"),w),void 0===N?"":N),ref:z}),t.createElement("div",{className:"".concat(p,"-group")},t.createElement(g,{vertical:w,prefixCls:p,value:L,containerRef:M,motionName:"".concat(p,"-").concat(void 0===j?"thumb-motion":j),direction:y,getValueIndex:function(e){return D.findIndex(function(t){return t.value===e})},onMotionStart:function(){T(!0)},onMotionEnd:function(){T(!1)}}),D.map(function(e){return t.createElement(b,(0,a.default)({},e,{name:k,key:e.value,prefixCls:p,className:(0,n.default)(e.className,"".concat(p,"-item"),(0,i.default)((0,i.default)({},"".concat(p,"-item-selected"),e.value===L&&!K),"".concat(p,"-item-focused"),G&&X&&e.value===L)),checked:e.value===L,onChange:V,onFocus:J,onBlur:Q,onKeyDown:ea,onKeyUp:et,onMouseDown:ee,disabled:!!C||!!e.disabled}))})))}),w=e.i(981444),x=e.i(242064),$=e.i(517455);e.i(296059);var C=e.i(915654),O=e.i(183293),S=e.i(246422),k=e.i(838378);function E(e,t){return{[`${e}, ${e}:hover, ${e}:focus`]:{color:t.colorTextDisabled,cursor:"not-allowed"}}}function N(e){return{background:e.itemSelectedBg,boxShadow:e.boxShadowTertiary}}let j=Object.assign({overflow:"hidden"},O.textEllipsis),R=(0,S.genStyleHooks)("Segmented",e=>{let{lineWidth:t,calc:n}=e;return(e=>{let{componentCls:t}=e,n=e.calc(e.controlHeight).sub(e.calc(e.trackPadding).mul(2)).equal(),a=e.calc(e.controlHeightLG).sub(e.calc(e.trackPadding).mul(2)).equal(),l=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,O.resetComponent)(e)),{display:"inline-block",padding:e.trackPadding,color:e.itemColor,background:e.trackBg,borderRadius:e.borderRadius,transition:`all ${e.motionDurationMid}`}),(0,O.genFocusStyle)(e)),{[`${t}-group`]:{position:"relative",display:"flex",alignItems:"stretch",justifyItems:"flex-start",flexDirection:"row",width:"100%"},[`&${t}-rtl`]:{direction:"rtl"},[`&${t}-vertical`]:{[`${t}-group`]:{flexDirection:"column"},[`${t}-thumb`]:{width:"100%",height:0,padding:`0 ${(0,C.unit)(e.paddingXXS)}`}},[`&${t}-block`]:{display:"flex"},[`&${t}-block ${t}-item`]:{flex:1,minWidth:0},[`${t}-item`]:{position:"relative",textAlign:"center",cursor:"pointer",transition:`color ${e.motionDurationMid}`,borderRadius:e.borderRadiusSM,transform:"translateZ(0)","&-selected":Object.assign(Object.assign({},N(e)),{color:e.itemSelectedColor}),"&-focused":(0,O.genFocusOutline)(e),"&::after":{content:'""',position:"absolute",zIndex:-1,width:"100%",height:"100%",top:0,insetInlineStart:0,borderRadius:"inherit",opacity:0,transition:`opacity ${e.motionDurationMid}, background-color ${e.motionDurationMid}`,pointerEvents:"none"},[`&:not(${t}-item-selected):not(${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,C.unit)(n),padding:`0 ${(0,C.unit)(e.segmentedPaddingHorizontal)}`},j),"&-icon + *":{marginInlineStart:e.calc(e.marginSM).div(2).equal()},"&-input":{position:"absolute",insetBlockStart:0,insetInlineStart:0,width:0,height:0,opacity:0,pointerEvents:"none"}},[`${t}-thumb`]:Object.assign(Object.assign({},N(e)),{position:"absolute",insetBlockStart:0,insetInlineStart:0,width:0,height:"100%",padding:`${(0,C.unit)(e.paddingXXS)} 0`,borderRadius:e.borderRadiusSM,[`& ~ ${t}-item:not(${t}-item-selected):not(${t}-item-disabled)::after`]:{backgroundColor:"transparent"}}),[`&${t}-lg`]:{borderRadius:e.borderRadiusLG,[`${t}-item-label`]:{minHeight:a,lineHeight:(0,C.unit)(a),padding:`0 ${(0,C.unit)(e.segmentedPaddingHorizontal)}`,fontSize:e.fontSizeLG},[`${t}-item, ${t}-thumb`]:{borderRadius:e.borderRadius}},[`&${t}-sm`]:{borderRadius:e.borderRadiusSM,[`${t}-item-label`]:{minHeight:l,lineHeight:(0,C.unit)(l),padding:`0 ${(0,C.unit)(e.segmentedPaddingHorizontalSM)}`},[`${t}-item, ${t}-thumb`]:{borderRadius:e.borderRadiusXS}}}),E(`&-disabled ${t}-item`,e)),E(`${t}-item-disabled`,e)),{[`${t}-thumb-motion-appear-active`]:{transition:`transform ${e.motionDurationSlow} ${e.motionEaseInOut}, width ${e.motionDurationSlow} ${e.motionEaseInOut}`,willChange:"transform, width"},[`&${t}-shape-round`]:{borderRadius:9999,[`${t}-item, ${t}-thumb`]:{borderRadius:9999}}})}})((0,k.mergeToken)(e,{segmentedPaddingHorizontal:n(e.controlPaddingHorizontal).sub(t).equal(),segmentedPaddingHorizontalSM:n(e.controlPaddingHorizontalSM).sub(t).equal()}))},e=>{let{colorTextLabel:t,colorText:n,colorFillSecondary:a,colorBgElevated:l,colorFill:o,lineWidthBold:i,colorBgLayout:r}=e;return{trackPadding:i,trackBg:r,itemColor:t,itemHoverColor:n,itemHoverBg:a,itemSelectedBg:l,itemActiveBg:o,itemSelectedColor:n}});var M=function(e,t){var n={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&0>t.indexOf(a)&&(n[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var l=0,a=Object.getOwnPropertySymbols(e);lt.indexOf(a[l])&&Object.prototype.propertyIsEnumerable.call(e,a[l])&&(n[a[l]]=e[a[l]]);return n};let z=t.forwardRef((e,a)=>{let l=(0,w.default)(),{prefixCls:o,className:i,rootClassName:r,block:s,options:c=[],size:u="middle",style:d,vertical:f,shape:m="default",name:v=l}=e,p=M(e,["prefixCls","className","rootClassName","block","options","size","style","vertical","shape","name"]),{getPrefixCls:g,direction:h,className:b,style:C}=(0,x.useComponentConfig)("segmented"),O=g("segmented",o),[S,k,E]=R(O),N=(0,$.default)(u),j=t.useMemo(()=>c.map(e=>{if("object"==typeof e&&(null==e?void 0:e.icon)){let{icon:n,label:a}=e;return Object.assign(Object.assign({},M(e,["icon","label"])),{label:t.createElement(t.Fragment,null,t.createElement("span",{className:`${O}-item-icon`},n),a&&t.createElement("span",null,a))})}return e}),[c,O]),z=(0,n.default)(i,r,b,{[`${O}-block`]:s,[`${O}-sm`]:"small"===N,[`${O}-lg`]:"large"===N,[`${O}-vertical`]:f,[`${O}-shape-${m}`]:"round"===m},k,E),D=Object.assign(Object.assign({},C),d);return S(t.createElement(y,Object.assign({},p,{name:v,className:z,style:D,options:j,ref:a,prefixCls:O,direction:h,vertical:f})))});e.s(["Segmented",0,z],560025)},362024,e=>{"use strict";var t=e.i(988122);e.s(["Collapse",()=>t.default])},240647,e=>{"use strict";var t=e.i(286612);e.s(["RightOutlined",()=>t.default])},149192,e=>{"use strict";var t=e.i(864517);e.s(["CloseOutlined",()=>t.default])},518617,e=>{"use strict";e.i(247167);var t=e.i(931067),n=e.i(271645);let a={icon:{tag:"svg",attrs:{"fill-rule":"evenodd",viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64c247.4 0 448 200.6 448 448S759.4 960 512 960 64 759.4 64 512 264.6 64 512 64zm0 76c-205.4 0-372 166.6-372 372s166.6 372 372 372 372-166.6 372-372-166.6-372-372-372zm128.01 198.83c.03 0 .05.01.09.06l45.02 45.01a.2.2 0 01.05.09.12.12 0 010 .07c0 .02-.01.04-.05.08L557.25 512l127.87 127.86a.27.27 0 01.05.06v.02a.12.12 0 010 .07c0 .03-.01.05-.05.09l-45.02 45.02a.2.2 0 01-.09.05.12.12 0 01-.07 0c-.02 0-.04-.01-.08-.05L512 557.25 384.14 685.12c-.04.04-.06.05-.08.05a.12.12 0 01-.07 0c-.03 0-.05-.01-.09-.05l-45.02-45.02a.2.2 0 01-.05-.09.12.12 0 010-.07c0-.02.01-.04.06-.08L466.75 512 338.88 384.14a.27.27 0 01-.05-.06l-.01-.02a.12.12 0 010-.07c0-.03.01-.05.05-.09l45.02-45.02a.2.2 0 01.09-.05.12.12 0 01.07 0c.02 0 .04.01.08.06L512 466.75l127.86-127.86c.04-.05.06-.06.08-.06a.12.12 0 01.07 0z"}}]},name:"close-circle",theme:"outlined"};var l=e.i(9583),o=n.forwardRef(function(e,o){return n.createElement(l.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["CloseCircleOutlined",0,o],518617)},19732,e=>{"use strict";e.i(247167);var t=e.i(931067),n=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 472a40 40 0 1080 0 40 40 0 10-80 0zm367 352.9L696.3 352V178H768v-68H256v68h71.7v174L145 824.9c-2.8 7.4-4.3 15.2-4.3 23.1 0 35.3 28.7 64 64 64h614.6c7.9 0 15.7-1.5 23.1-4.3 33-12.7 49.4-49.8 36.6-82.8zM395.7 364.7V180h232.6v184.7L719.2 600c-20.7-5.3-42.1-8-63.9-8-61.2 0-119.2 21.5-165.3 60a188.78 188.78 0 01-121.3 43.9c-32.7 0-64.1-8.3-91.8-23.7l118.8-307.5zM210.5 844l41.7-107.8c35.7 18.1 75.4 27.8 116.6 27.8 61.2 0 119.2-21.5 165.3-60 33.9-28.2 76.3-43.9 121.3-43.9 35 0 68.4 9.5 97.6 27.1L813.5 844h-603z"}}]},name:"experiment",theme:"outlined"};var l=e.i(9583),o=n.forwardRef(function(e,o){return n.createElement(l.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["ExperimentOutlined",0,o],19732)},366308,e=>{"use strict";e.i(247167);var t=e.i(931067),n=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M876.6 239.5c-.5-.9-1.2-1.8-2-2.5-5-5-13.1-5-18.1 0L684.2 409.3l-67.9-67.9L788.7 169c.8-.8 1.4-1.6 2-2.5 3.6-6.1 1.6-13.9-4.5-17.5-98.2-58-226.8-44.7-311.3 39.7-67 67-89.2 162-66.5 247.4l-293 293c-3 3-2.8 7.9.3 11l169.7 169.7c3.1 3.1 8.1 3.3 11 .3l292.9-292.9c85.5 22.8 180.5.7 247.6-66.4 84.4-84.5 97.7-213.1 39.7-311.3zM786 499.8c-58.1 58.1-145.3 69.3-214.6 33.6l-8.8 8.8-.1-.1-274 274.1-79.2-79.2 230.1-230.1s0 .1.1.1l52.8-52.8c-35.7-69.3-24.5-156.5 33.6-214.6a184.2 184.2 0 01144-53.5L537 318.9a32.05 32.05 0 000 45.3l124.5 124.5a32.05 32.05 0 0045.3 0l132.8-132.8c3.7 51.8-14.4 104.8-53.6 143.9z"}}]},name:"tool",theme:"outlined"};var l=e.i(9583),o=n.forwardRef(function(e,o){return n.createElement(l.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["ToolOutlined",0,o],366308)},782273,e=>{"use strict";e.i(247167);var t=e.i(931067),n=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M625.9 115c-5.9 0-11.9 1.6-17.4 5.3L254 352H90c-8.8 0-16 7.2-16 16v288c0 8.8 7.2 16 16 16h164l354.5 231.7c5.5 3.6 11.6 5.3 17.4 5.3 16.7 0 32.1-13.3 32.1-32.1V147.1c0-18.8-15.4-32.1-32.1-32.1zM586 803L293.4 611.7l-18-11.7H146V424h129.4l17.9-11.7L586 221v582zm348-327H806c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16h128c8.8 0 16-7.2 16-16v-40c0-8.8-7.2-16-16-16zm-41.9 261.8l-110.3-63.7a15.9 15.9 0 00-21.7 5.9l-19.9 34.5c-4.4 7.6-1.8 17.4 5.8 21.8L856.3 800a15.9 15.9 0 0021.7-5.9l19.9-34.5c4.4-7.6 1.7-17.4-5.8-21.8zM760 344a15.9 15.9 0 0021.7 5.9L892 286.2c7.6-4.4 10.2-14.2 5.8-21.8L878 230a15.9 15.9 0 00-21.7-5.9L746 287.8a15.99 15.99 0 00-5.8 21.8L760 344z"}}]},name:"sound",theme:"outlined"};var l=e.i(9583),o=n.forwardRef(function(e,o){return n.createElement(l.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["SoundOutlined",0,o],782273)},313603,e=>{"use strict";e.i(247167);var t=e.i(931067),n=e.i(271645);let a={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"};var l=e.i(9583),o=n.forwardRef(function(e,o){return n.createElement(l.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["SettingOutlined",0,o],313603)},793916,e=>{"use strict";e.i(247167);var t=e.i(931067),n=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M842 454c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8 0 140.3-113.7 254-254 254S258 594.3 258 454c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8 0 168.7 126.6 307.9 290 327.6V884H326.7c-13.7 0-24.7 14.3-24.7 32v36c0 4.4 2.8 8 6.2 8h407.6c3.4 0 6.2-3.6 6.2-8v-36c0-17.7-11-32-24.7-32H548V782.1c165.3-18 294-158 294-328.1zM512 624c93.9 0 170-75.2 170-168V232c0-92.8-76.1-168-170-168s-170 75.2-170 168v224c0 92.8 76.1 168 170 168zm-94-392c0-50.6 41.9-92 94-92s94 41.4 94 92v224c0 50.6-41.9 92-94 92s-94-41.4-94-92V232z"}}]},name:"audio",theme:"outlined"};var l=e.i(9583),o=n.forwardRef(function(e,o){return n.createElement(l.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["AudioOutlined",0,o],793916)},608856,e=>{"use strict";e.i(247167);var t=e.i(271645),n=e.i(343794),a=e.i(209428),l=e.i(392221),o=e.i(951160),i=e.i(174428),r=t.createContext(null),s=t.createContext({}),c=e.i(211577),u=e.i(931067),d=e.i(361275),f=e.i(404948),m=e.i(244009),v=e.i(703923),p=e.i(611935),g=["prefixCls","className","containerRef"];let h=function(e){var a=e.prefixCls,l=e.className,o=e.containerRef,i=(0,v.default)(e,g),r=t.useContext(s).panel,c=(0,p.useComposeRef)(r,o);return t.createElement("div",(0,u.default)({className:(0,n.default)("".concat(a,"-content"),l),role:"dialog",ref:c},(0,m.default)(e,{aria:!0}),{"aria-modal":"true"},i))};var b=e.i(883110);function y(e){return"string"==typeof e&&String(Number(e))===e?((0,b.default)(!1,"Invalid value type of `width` or `height` which should be number type instead."),Number(e)):e}var w={width:0,height:0,overflow:"hidden",outline:"none",position:"absolute"},x=t.forwardRef(function(e,o){var i,s,v,p=e.prefixCls,g=e.open,b=e.placement,x=e.inline,$=e.push,C=e.forceRender,O=e.autoFocus,S=e.keyboard,k=e.classNames,E=e.rootClassName,N=e.rootStyle,j=e.zIndex,R=e.className,M=e.id,z=e.style,D=e.motion,I=e.width,H=e.height,L=e.children,P=e.mask,B=e.maskClosable,A=e.maskMotion,K=e.maskClassName,T=e.maskStyle,V=e.afterOpenChange,U=e.onClose,F=e.onMouseEnter,W=e.onMouseOver,X=e.onMouseLeave,q=e.onClick,Y=e.onKeyDown,_=e.onKeyUp,G=e.styles,Z=e.drawerRender,J=t.useRef(),Q=t.useRef(),ee=t.useRef();t.useImperativeHandle(o,function(){return J.current}),t.useEffect(function(){if(g&&O){var e;null==(e=J.current)||e.focus({preventScroll:!0})}},[g]);var et=t.useState(!1),en=(0,l.default)(et,2),ea=en[0],el=en[1],eo=t.useContext(r),ei=null!=(i=null!=(s=null==(v="boolean"==typeof $?$?{}:{distance:0}:$||{})?void 0:v.distance)?s:null==eo?void 0:eo.pushDistance)?i:180,er=t.useMemo(function(){return{pushDistance:ei,push:function(){el(!0)},pull:function(){el(!1)}}},[ei]);t.useEffect(function(){var e,t;g?null==eo||null==(e=eo.push)||e.call(eo):null==eo||null==(t=eo.pull)||t.call(eo)},[g]),t.useEffect(function(){return function(){var e;null==eo||null==(e=eo.pull)||e.call(eo)}},[]);var es=t.createElement(d.default,(0,u.default)({key:"mask"},A,{visible:P&&g}),function(e,l){var o=e.className,i=e.style;return t.createElement("div",{className:(0,n.default)("".concat(p,"-mask"),o,null==k?void 0:k.mask,K),style:(0,a.default)((0,a.default)((0,a.default)({},i),T),null==G?void 0:G.mask),onClick:B&&g?U:void 0,ref:l})}),ec="function"==typeof D?D(b):D,eu={};if(ea&&ei)switch(b){case"top":eu.transform="translateY(".concat(ei,"px)");break;case"bottom":eu.transform="translateY(".concat(-ei,"px)");break;case"left":eu.transform="translateX(".concat(ei,"px)");break;default:eu.transform="translateX(".concat(-ei,"px)")}"left"===b||"right"===b?eu.width=y(I):eu.height=y(H);var ed={onMouseEnter:F,onMouseOver:W,onMouseLeave:X,onClick:q,onKeyDown:Y,onKeyUp:_},ef=t.createElement(d.default,(0,u.default)({key:"panel"},ec,{visible:g,forceRender:C,onVisibleChanged:function(e){null==V||V(e)},removeOnLeave:!1,leavedClassName:"".concat(p,"-content-wrapper-hidden")}),function(l,o){var i=l.className,r=l.style,s=t.createElement(h,(0,u.default)({id:M,containerRef:o,prefixCls:p,className:(0,n.default)(R,null==k?void 0:k.content),style:(0,a.default)((0,a.default)({},z),null==G?void 0:G.content)},(0,m.default)(e,{aria:!0}),ed),L);return t.createElement("div",(0,u.default)({className:(0,n.default)("".concat(p,"-content-wrapper"),null==k?void 0:k.wrapper,i),style:(0,a.default)((0,a.default)((0,a.default)({},eu),r),null==G?void 0:G.wrapper)},(0,m.default)(e,{data:!0})),Z?Z(s):s)}),em=(0,a.default)({},N);return j&&(em.zIndex=j),t.createElement(r.Provider,{value:er},t.createElement("div",{className:(0,n.default)(p,"".concat(p,"-").concat(b),E,(0,c.default)((0,c.default)({},"".concat(p,"-open"),g),"".concat(p,"-inline"),x)),style:em,tabIndex:-1,ref:J,onKeyDown:function(e){var t,n,a=e.keyCode,l=e.shiftKey;switch(a){case f.default.TAB:a===f.default.TAB&&(l||document.activeElement!==ee.current?l&&document.activeElement===Q.current&&(null==(n=ee.current)||n.focus({preventScroll:!0})):null==(t=Q.current)||t.focus({preventScroll:!0}));break;case f.default.ESC:U&&S&&(e.stopPropagation(),U(e))}}},es,t.createElement("div",{tabIndex:0,ref:Q,style:w,"aria-hidden":"true","data-sentinel":"start"}),ef,t.createElement("div",{tabIndex:0,ref:ee,style:w,"aria-hidden":"true","data-sentinel":"end"})))});let $=function(e){var n=e.open,r=e.prefixCls,c=e.placement,u=e.autoFocus,d=e.keyboard,f=e.width,m=e.mask,v=void 0===m||m,p=e.maskClosable,g=e.getContainer,h=e.forceRender,b=e.afterOpenChange,y=e.destroyOnClose,w=e.onMouseEnter,$=e.onMouseOver,C=e.onMouseLeave,O=e.onClick,S=e.onKeyDown,k=e.onKeyUp,E=e.panelRef,N=t.useState(!1),j=(0,l.default)(N,2),R=j[0],M=j[1],z=t.useState(!1),D=(0,l.default)(z,2),I=D[0],H=D[1];(0,i.default)(function(){H(!0)},[]);var L=!!I&&void 0!==n&&n,P=t.useRef(),B=t.useRef();(0,i.default)(function(){L&&(B.current=document.activeElement)},[L]);var A=t.useMemo(function(){return{panel:E}},[E]);if(!h&&!R&&!L&&y)return null;var K=(0,a.default)((0,a.default)({},e),{},{open:L,prefixCls:void 0===r?"rc-drawer":r,placement:void 0===c?"right":c,autoFocus:void 0===u||u,keyboard:void 0===d||d,width:void 0===f?378:f,mask:v,maskClosable:void 0===p||p,inline:!1===g,afterOpenChange:function(e){var t,n;M(e),null==b||b(e),e||!B.current||null!=(t=P.current)&&t.contains(B.current)||null==(n=B.current)||n.focus({preventScroll:!0})},ref:P},{onMouseEnter:w,onMouseOver:$,onMouseLeave:C,onClick:O,onKeyDown:S,onKeyUp:k});return t.createElement(s.Provider,{value:A},t.createElement(o.default,{open:L||h||R,autoDestroy:!1,getContainer:g,autoLock:v&&(L||R)},t.createElement(x,K)))};var C=e.i(981444),O=e.i(617206),S=e.i(122767),k=e.i(613541),E=e.i(340010),N=e.i(242064),j=e.i(922611),R=e.i(563113),M=e.i(185793);let z=e=>{var a,l,o,i;let r,{prefixCls:s,ariaId:c,title:u,footer:d,extra:f,closable:m,loading:v,onClose:p,headerStyle:g,bodyStyle:h,footerStyle:b,children:y,classNames:w,styles:x}=e,$=(0,N.useComponentConfig)("drawer");r=!1===m?void 0:void 0===m||!0===m?"start":(null==m?void 0:m.placement)==="end"?"end":"start";let C=t.useCallback(e=>t.createElement("button",{type:"button",onClick:p,className:(0,n.default)(`${s}-close`,{[`${s}-close-${r}`]:"end"===r})},e),[p,s,r]),[O,S]=(0,R.useClosable)((0,R.pickClosable)(e),(0,R.pickClosable)($),{closable:!0,closeIconRender:C});return t.createElement(t.Fragment,null,u||O?t.createElement("div",{style:Object.assign(Object.assign(Object.assign({},null==(o=$.styles)?void 0:o.header),g),null==x?void 0:x.header),className:(0,n.default)(`${s}-header`,{[`${s}-header-close-only`]:O&&!u&&!f},null==(i=$.classNames)?void 0:i.header,null==w?void 0:w.header)},t.createElement("div",{className:`${s}-header-title`},"start"===r&&S,u&&t.createElement("div",{className:`${s}-title`,id:c},u)),f&&t.createElement("div",{className:`${s}-extra`},f),"end"===r&&S):null,t.createElement("div",{className:(0,n.default)(`${s}-body`,null==w?void 0:w.body,null==(a=$.classNames)?void 0:a.body),style:Object.assign(Object.assign(Object.assign({},null==(l=$.styles)?void 0:l.body),h),null==x?void 0:x.body)},v?t.createElement(M.default,{active:!0,title:!1,paragraph:{rows:5},className:`${s}-body-skeleton`}):y),(()=>{var e,a;if(!d)return null;let l=`${s}-footer`;return t.createElement("div",{className:(0,n.default)(l,null==(e=$.classNames)?void 0:e.footer,null==w?void 0:w.footer),style:Object.assign(Object.assign(Object.assign({},null==(a=$.styles)?void 0:a.footer),b),null==x?void 0:x.footer)},d)})())};e.i(296059);var D=e.i(915654),I=e.i(183293),H=e.i(246422),L=e.i(838378);let P=(e,t)=>({"&-enter, &-appear":Object.assign(Object.assign({},e),{"&-active":t}),"&-leave":Object.assign(Object.assign({},t),{"&-active":e})}),B=(e,t)=>Object.assign({"&-enter, &-appear, &-leave":{"&-start":{transition:"none"},"&-active":{transition:`all ${t}`}}},P({opacity:e},{opacity:1})),A=(0,H.genStyleHooks)("Drawer",e=>{let t=(0,L.mergeToken)(e,{});return[(e=>{let{borderRadiusSM:t,componentCls:n,zIndexPopup:a,colorBgMask:l,colorBgElevated:o,motionDurationSlow:i,motionDurationMid:r,paddingXS:s,padding:c,paddingLG:u,fontSizeLG:d,lineHeightLG:f,lineWidth:m,lineType:v,colorSplit:p,marginXS:g,colorIcon:h,colorIconHover:b,colorBgTextHover:y,colorBgTextActive:w,colorText:x,fontWeightStrong:$,footerPaddingBlock:C,footerPaddingInline:O,calc:S}=e,k=`${n}-content-wrapper`;return{[n]:{position:"fixed",inset:0,zIndex:a,pointerEvents:"none",color:x,"&-pure":{position:"relative",background:o,display:"flex",flexDirection:"column",[`&${n}-left`]:{boxShadow:e.boxShadowDrawerLeft},[`&${n}-right`]:{boxShadow:e.boxShadowDrawerRight},[`&${n}-top`]:{boxShadow:e.boxShadowDrawerUp},[`&${n}-bottom`]:{boxShadow:e.boxShadowDrawerDown}},"&-inline":{position:"absolute"},[`${n}-mask`]:{position:"absolute",inset:0,zIndex:a,background:l,pointerEvents:"auto"},[k]:{position:"absolute",zIndex:a,maxWidth:"100vw",transition:`all ${i}`,"&-hidden":{display:"none"}},[`&-left > ${k}`]:{top:0,bottom:0,left:{_skip_check_:!0,value:0},boxShadow:e.boxShadowDrawerLeft},[`&-right > ${k}`]:{top:0,right:{_skip_check_:!0,value:0},bottom:0,boxShadow:e.boxShadowDrawerRight},[`&-top > ${k}`]:{top:0,insetInline:0,boxShadow:e.boxShadowDrawerUp},[`&-bottom > ${k}`]:{bottom:0,insetInline:0,boxShadow:e.boxShadowDrawerDown},[`${n}-content`]:{display:"flex",flexDirection:"column",width:"100%",height:"100%",overflow:"auto",background:o,pointerEvents:"auto"},[`${n}-header`]:{display:"flex",flex:0,alignItems:"center",padding:`${(0,D.unit)(c)} ${(0,D.unit)(u)}`,fontSize:d,lineHeight:f,borderBottom:`${(0,D.unit)(m)} ${v} ${p}`,"&-title":{display:"flex",flex:1,alignItems:"center",minWidth:0,minHeight:0}},[`${n}-extra`]:{flex:"none"},[`${n}-close`]:Object.assign({display:"inline-flex",width:S(d).add(s).equal(),height:S(d).add(s).equal(),borderRadius:t,justifyContent:"center",alignItems:"center",color:h,fontWeight:$,fontSize:d,fontStyle:"normal",lineHeight:1,textAlign:"center",textTransform:"none",textDecoration:"none",background:"transparent",border:0,cursor:"pointer",transition:`all ${r}`,textRendering:"auto",[`&${n}-close-end`]:{marginInlineStart:g},[`&:not(${n}-close-end)`]:{marginInlineEnd:g},"&:hover":{color:b,backgroundColor:y,textDecoration:"none"},"&:active":{backgroundColor:w}},(0,I.genFocusStyle)(e)),[`${n}-title`]:{flex:1,margin:0,fontWeight:e.fontWeightStrong,fontSize:d,lineHeight:f},[`${n}-body`]:{flex:1,minWidth:0,minHeight:0,padding:u,overflow:"auto",[`${n}-body-skeleton`]:{width:"100%",height:"100%",display:"flex",justifyContent:"center"}},[`${n}-footer`]:{flexShrink:0,padding:`${(0,D.unit)(C)} ${(0,D.unit)(O)}`,borderTop:`${(0,D.unit)(m)} ${v} ${p}`},"&-rtl":{direction:"rtl"}}}})(t),(e=>{let{componentCls:t,motionDurationSlow:n}=e;return{[t]:{[`${t}-mask-motion`]:B(0,n),[`${t}-panel-motion`]:["left","right","top","bottom"].reduce((e,t)=>{let a;return Object.assign(Object.assign({},e),{[`&-${t}`]:[B(.7,n),P({transform:(a="100%",({left:`translateX(-${a})`,right:`translateX(${a})`,top:`translateY(-${a})`,bottom:`translateY(${a})`})[t])},{transform:"none"})]})},{})}}})(t)]},e=>({zIndexPopup:e.zIndexPopupBase,footerPaddingBlock:e.paddingXS,footerPaddingInline:e.padding}));var K=function(e,t){var n={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&0>t.indexOf(a)&&(n[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var l=0,a=Object.getOwnPropertySymbols(e);lt.indexOf(a[l])&&Object.prototype.propertyIsEnumerable.call(e,a[l])&&(n[a[l]]=e[a[l]]);return n};let T={distance:180},V=e=>{let{rootClassName:a,width:l,height:o,size:i="default",mask:r=!0,push:s=T,open:c,afterOpenChange:u,onClose:d,prefixCls:f,getContainer:m,panelRef:v=null,style:g,className:h,"aria-labelledby":b,visible:y,afterVisibleChange:w,maskStyle:x,drawerStyle:R,contentWrapperStyle:M,destroyOnClose:D,destroyOnHidden:I}=e,H=K(e,["rootClassName","width","height","size","mask","push","open","afterOpenChange","onClose","prefixCls","getContainer","panelRef","style","className","aria-labelledby","visible","afterVisibleChange","maskStyle","drawerStyle","contentWrapperStyle","destroyOnClose","destroyOnHidden"]),L=(0,C.default)(),P=H.title?L:void 0,{getPopupContainer:B,getPrefixCls:V,direction:U,className:F,style:W,classNames:X,styles:q}=(0,N.useComponentConfig)("drawer"),Y=V("drawer",f),[_,G,Z]=A(Y),J=void 0===m&&B?()=>B(document.body):m,Q=(0,n.default)({"no-mask":!r,[`${Y}-rtl`]:"rtl"===U},a,G,Z),ee=t.useMemo(()=>null!=l?l:"large"===i?736:378,[l,i]),et=t.useMemo(()=>null!=o?o:"large"===i?736:378,[o,i]),en={motionName:(0,k.getTransitionName)(Y,"mask-motion"),motionAppear:!0,motionEnter:!0,motionLeave:!0,motionDeadline:500},ea=(0,j.usePanelRef)(),el=(0,p.composeRef)(v,ea),[eo,ei]=(0,S.useZIndex)("Drawer",H.zIndex),{classNames:er={},styles:es={}}=H;return _(t.createElement(O.default,{form:!0,space:!0},t.createElement(E.default.Provider,{value:ei},t.createElement($,Object.assign({prefixCls:Y,onClose:d,maskMotion:en,motion:e=>({motionName:(0,k.getTransitionName)(Y,`panel-motion-${e}`),motionAppear:!0,motionEnter:!0,motionLeave:!0,motionDeadline:500})},H,{classNames:{mask:(0,n.default)(er.mask,X.mask),content:(0,n.default)(er.content,X.content),wrapper:(0,n.default)(er.wrapper,X.wrapper)},styles:{mask:Object.assign(Object.assign(Object.assign({},es.mask),x),q.mask),content:Object.assign(Object.assign(Object.assign({},es.content),R),q.content),wrapper:Object.assign(Object.assign(Object.assign({},es.wrapper),M),q.wrapper)},open:null!=c?c:y,mask:r,push:s,width:ee,height:et,style:Object.assign(Object.assign({},W),g),className:(0,n.default)(F,h),rootClassName:Q,getContainer:J,afterOpenChange:null!=u?u:w,panelRef:el,zIndex:eo,"aria-labelledby":null!=b?b:P,destroyOnClose:null!=I?I:D}),t.createElement(z,Object.assign({prefixCls:Y},H,{ariaId:P,onClose:d}))))))};V._InternalPanelDoNotUseOrYouWillBeFired=e=>{let{prefixCls:a,style:l,className:o,placement:i="right"}=e,r=K(e,["prefixCls","style","className","placement"]),{getPrefixCls:s}=t.useContext(N.ConfigContext),c=s("drawer",a),[u,d,f]=A(c),m=(0,n.default)(c,`${c}-pure`,`${c}-${i}`,d,f,o);return u(t.createElement("div",{className:m,style:l},t.createElement(z,Object.assign({prefixCls:c},r))))},e.s(["Drawer",0,V],608856)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/01hy_w_4bnb34.js b/litellm/proxy/_experimental/out/_next/static/chunks/01hy_w_4bnb34.js deleted file mode 100644 index 1745aa89f8f..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/01hy_w_4bnb34.js +++ /dev/null @@ -1 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,118366,e=>{"use strict";var t=e.i(991124);e.s(["CopyIcon",()=>t.default])},541071,e=>{"use strict";let t=(0,e.i(475254).default)("ellipsis",[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"19",cy:"12",r:"1",key:"1wjl8i"}],["circle",{cx:"5",cy:"12",r:"1",key:"1pcz8c"}]]);e.s(["MoreHorizontal",0,t],541071)},755146,e=>{"use strict";var t=e.i(843476),r=e.i(451512),a=e.i(115504);e.i(233565),e.i(678784),e.s(["DropdownMenu",0,function({...e}){return(0,t.jsx)(r.Menu.Root,{"data-slot":"dropdown-menu",...e})},"DropdownMenuContent",0,function({align:e="start",alignOffset:n=0,side:l="bottom",sideOffset:s=4,className:i,...o}){return(0,t.jsx)(r.Menu.Portal,{children:(0,t.jsx)(r.Menu.Positioner,{className:"isolate z-50 outline-none",align:e,alignOffset:n,side:l,sideOffset:s,children:(0,t.jsx)(r.Menu.Popup,{"data-slot":"dropdown-menu-content",className:(0,a.cn)("z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95",i),...o})})})},"DropdownMenuItem",0,function({className:e,inset:n,variant:l="default",...s}){return(0,t.jsx)(r.Menu.Item,{"data-slot":"dropdown-menu-item","data-inset":n,"data-variant":l,className:(0,a.cn)("group/dropdown-menu-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive",e),...s})},"DropdownMenuSeparator",0,function({className:e,...n}){return(0,t.jsx)(r.Menu.Separator,{"data-slot":"dropdown-menu-separator",className:(0,a.cn)("-mx-1 my-1 h-px bg-border",e),...n})},"DropdownMenuTrigger",0,function({...e}){return(0,t.jsx)(r.Menu.Trigger,{"data-slot":"dropdown-menu-trigger",...e})}])},727612,e=>{"use strict";let t=(0,e.i(475254).default)("trash-2",[["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",key:"4alrt4"}],["path",{d:"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",key:"v07s0e"}],["line",{x1:"10",x2:"10",y1:"11",y2:"17",key:"1uufr5"}],["line",{x1:"14",x2:"14",y1:"11",y2:"17",key:"xtxkd"}]]);e.s(["Trash2",0,t],727612)},788699,e=>{"use strict";let t=(0,e.i(475254).default)("pencil",[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}],["path",{d:"m15 5 4 4",key:"1mk7zo"}]]);e.s(["Pencil",0,t],788699)},655063,e=>{"use strict";var t=e.i(399029),r=e.i(271645);e.s(["useDebouncedValue",0,function(e,a,n){let[l,s,i]=(0,t.useDebouncedState)(e,a,n);return(0,r.useEffect)(()=>{s(e)},[e,s]),[l,i]}])},91979,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M909.1 209.3l-56.4 44.1C775.8 155.1 656.2 92 521.9 92 290 92 102.3 279.5 102 511.5 101.7 743.7 289.8 932 521.9 932c181.3 0 335.8-115 394.6-276.1 1.5-4.2-.7-8.9-4.9-10.3l-56.7-19.5a8 8 0 00-10.1 4.8c-1.8 5-3.8 10-5.9 14.9-17.3 41-42.1 77.8-73.7 109.4A344.77 344.77 0 01655.9 829c-42.3 17.9-87.4 27-133.8 27-46.5 0-91.5-9.1-133.8-27A341.5 341.5 0 01279 755.2a342.16 342.16 0 01-73.7-109.4c-17.9-42.4-27-87.4-27-133.9s9.1-91.5 27-133.9c17.3-41 42.1-77.8 73.7-109.4 31.6-31.6 68.4-56.4 109.3-73.8 42.3-17.9 87.4-27 133.8-27 46.5 0 91.5 9.1 133.8 27a341.5 341.5 0 01109.3 73.8c9.9 9.9 19.2 20.4 27.8 31.4l-60.2 47a8 8 0 003 14.1l175.6 43c5 1.2 9.9-2.6 9.9-7.7l.8-180.9c-.1-6.6-7.8-10.3-13-6.2z"}}]},name:"reload",theme:"outlined"};var n=e.i(9583),l=r.forwardRef(function(e,l){return r.createElement(n.default,(0,t.default)({},e,{ref:l,icon:a}))});e.s(["ReloadOutlined",0,l],91979)},751904,e=>{"use strict";var t=e.i(401361);e.s(["EditOutlined",()=>t.default])},987432,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M893.3 293.3L730.7 130.7c-7.5-7.5-16.7-13-26.7-16V112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V338.5c0-17-6.7-33.2-18.7-45.2zM384 184h256v104H384V184zm456 656H184V184h136v136c0 17.7 14.3 32 32 32h320c17.7 0 32-14.3 32-32V205.8l136 136V840zM512 442c-79.5 0-144 64.5-144 144s64.5 144 144 144 144-64.5 144-144-64.5-144-144-144zm0 224c-44.2 0-80-35.8-80-80s35.8-80 80-80 80 35.8 80 80-35.8 80-80 80z"}}]},name:"save",theme:"outlined"};var n=e.i(9583),l=r.forwardRef(function(e,l){return r.createElement(n.default,(0,t.default)({},e,{ref:l,icon:a}))});e.s(["SaveOutlined",0,l],987432)},21548,e=>{"use strict";var t=e.i(616303);e.s(["Empty",()=>t.default])},564897,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M696 480H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h368c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8z"}},{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"}}]},name:"minus-circle",theme:"outlined"};var n=e.i(9583),l=r.forwardRef(function(e,l){return r.createElement(n.default,(0,t.default)({},e,{ref:l,icon:a}))});e.s(["MinusCircleOutlined",0,l],564897)},822315,(e,t,r)=>{e.e,t.exports=function(){"use strict";var e="millisecond",t="second",r="minute",a="hour",n="week",l="month",s="quarter",i="year",o="date",d="Invalid Date",u=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,c=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,m=function(e,t,r){var a=String(e);return!a||a.length>=t?e:""+Array(t+1-a.length).join(r)+e},f="en",h={};h[f]={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(e){var t=["th","st","nd","rd"],r=e%100;return"["+e+(t[(r-20)%10]||t[r]||t[0])+"]"}};var p="$isDayjsObject",g=function(e){return e instanceof y||!(!e||!e[p])},x=function e(t,r,a){var n;if(!t)return f;if("string"==typeof t){var l=t.toLowerCase();h[l]&&(n=l),r&&(h[l]=r,n=l);var s=t.split("-");if(!n&&s.length>1)return e(s[0])}else{var i=t.name;h[i]=t,n=i}return!a&&n&&(f=n),n||!a&&f},b=function(e,t){if(g(e))return e.clone();var r="object"==typeof t?t:{};return r.date=e,r.args=arguments,new y(r)},v={s:m,z:function(e){var t=-e.utcOffset(),r=Math.abs(t);return(t<=0?"+":"-")+m(Math.floor(r/60),2,"0")+":"+m(r%60,2,"0")},m:function e(t,r){if(t.date(){"use strict";e.i(247167);var t=e.i(8211),r=e.i(271645),a=e.i(343794),n=e.i(529681),l=e.i(242064),s=e.i(704914),i=e.i(876556),o=e.i(290224),d=e.i(251224),u=function(e,t){var r={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&0>t.indexOf(a)&&(r[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var n=0,a=Object.getOwnPropertySymbols(e);nt.indexOf(a[n])&&Object.prototype.propertyIsEnumerable.call(e,a[n])&&(r[a[n]]=e[a[n]]);return r};function c({suffixCls:e,tagName:t,displayName:a}){return a=>r.forwardRef((n,l)=>r.createElement(a,Object.assign({ref:l,suffixCls:e,tagName:t},n)))}let m=r.forwardRef((e,t)=>{let{prefixCls:n,suffixCls:s,className:i,tagName:o}=e,c=u(e,["prefixCls","suffixCls","className","tagName"]),{getPrefixCls:m}=r.useContext(l.ConfigContext),f=m("layout",n),[h,p,g]=(0,d.default)(f),x=s?`${f}-${s}`:f;return h(r.createElement(o,Object.assign({className:(0,a.default)(n||x,i,p,g),ref:t},c)))}),f=r.forwardRef((e,c)=>{let{direction:m}=r.useContext(l.ConfigContext),[f,h]=r.useState([]),{prefixCls:p,className:g,rootClassName:x,children:b,hasSider:v,tagName:y,style:w}=e,C=u(e,["prefixCls","className","rootClassName","children","hasSider","tagName","style"]),M=(0,n.default)(C,["suffixCls"]),{getPrefixCls:j,className:k,style:S}=(0,l.useComponentConfig)("layout"),$=j("layout",p),O="boolean"==typeof v?v:!!f.length||(0,i.default)(b).some(e=>e.type===o.default),[N,_,I]=(0,d.default)($),D=(0,a.default)($,{[`${$}-has-sider`]:O,[`${$}-rtl`]:"rtl"===m},k,g,x,_,I),z=r.useMemo(()=>({siderHook:{addSider:e=>{h(r=>[].concat((0,t.default)(r),[e]))},removeSider:e=>{h(t=>t.filter(t=>t!==e))}}}),[]);return N(r.createElement(s.LayoutContext.Provider,{value:z},r.createElement(y,Object.assign({ref:c,className:D,style:Object.assign(Object.assign({},S),w)},M),b)))}),h=c({tagName:"div",displayName:"Layout"})(f),p=c({suffixCls:"header",tagName:"header",displayName:"Header"})(m),g=c({suffixCls:"footer",tagName:"footer",displayName:"Footer"})(m),x=c({suffixCls:"content",tagName:"main",displayName:"Content"})(m);h.Header=p,h.Footer=g,h.Content=x,h.Sider=o.default,h._InternalSiderContext=o.SiderContext,e.s(["Layout",0,h],372943);let b=(0,e.i(475254).default)("layers",[["path",{d:"M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z",key:"zw3jo"}],["path",{d:"M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12",key:"1wduqc"}],["path",{d:"M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17",key:"kqbvx6"}]]);e.s(["default",0,b],113625)},160818,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M854.4 800.9c.2-.3.5-.6.7-.9C920.6 722.1 960 621.7 960 512s-39.4-210.1-104.8-288c-.2-.3-.5-.5-.7-.8-1.1-1.3-2.1-2.5-3.2-3.7-.4-.5-.8-.9-1.2-1.4l-4.1-4.7-.1-.1c-1.5-1.7-3.1-3.4-4.6-5.1l-.1-.1c-3.2-3.4-6.4-6.8-9.7-10.1l-.1-.1-4.8-4.8-.3-.3c-1.5-1.5-3-2.9-4.5-4.3-.5-.5-1-1-1.6-1.5-1-1-2-1.9-3-2.8-.3-.3-.7-.6-1-1C736.4 109.2 629.5 64 512 64s-224.4 45.2-304.3 119.2c-.3.3-.7.6-1 1-1 .9-2 1.9-3 2.9-.5.5-1 1-1.6 1.5-1.5 1.4-3 2.9-4.5 4.3l-.3.3-4.8 4.8-.1.1c-3.3 3.3-6.5 6.7-9.7 10.1l-.1.1c-1.6 1.7-3.1 3.4-4.6 5.1l-.1.1c-1.4 1.5-2.8 3.1-4.1 4.7-.4.5-.8.9-1.2 1.4-1.1 1.2-2.1 2.5-3.2 3.7-.2.3-.5.5-.7.8C103.4 301.9 64 402.3 64 512s39.4 210.1 104.8 288c.2.3.5.6.7.9l3.1 3.7c.4.5.8.9 1.2 1.4l4.1 4.7c0 .1.1.1.1.2 1.5 1.7 3 3.4 4.6 5l.1.1c3.2 3.4 6.4 6.8 9.6 10.1l.1.1c1.6 1.6 3.1 3.2 4.7 4.7l.3.3c3.3 3.3 6.7 6.5 10.1 9.6 80.1 74 187 119.2 304.5 119.2s224.4-45.2 304.3-119.2a300 300 0 0010-9.6l.3-.3c1.6-1.6 3.2-3.1 4.7-4.7l.1-.1c3.3-3.3 6.5-6.7 9.6-10.1l.1-.1c1.5-1.7 3.1-3.3 4.6-5 0-.1.1-.1.1-.2 1.4-1.5 2.8-3.1 4.1-4.7.4-.5.8-.9 1.2-1.4a99 99 0 003.3-3.7zm4.1-142.6c-13.8 32.6-32 62.8-54.2 90.2a444.07 444.07 0 00-81.5-55.9c11.6-46.9 18.8-98.4 20.7-152.6H887c-3 40.9-12.6 80.6-28.5 118.3zM887 484H743.5c-1.9-54.2-9.1-105.7-20.7-152.6 29.3-15.6 56.6-34.4 81.5-55.9A373.86 373.86 0 01887 484zM658.3 165.5c39.7 16.8 75.8 40 107.6 69.2a394.72 394.72 0 01-59.4 41.8c-15.7-45-35.8-84.1-59.2-115.4 3.7 1.4 7.4 2.9 11 4.4zm-90.6 700.6c-9.2 7.2-18.4 12.7-27.7 16.4V697a389.1 389.1 0 01115.7 26.2c-8.3 24.6-17.9 47.3-29 67.8-17.4 32.4-37.8 58.3-59 75.1zm59-633.1c11 20.6 20.7 43.3 29 67.8A389.1 389.1 0 01540 327V141.6c9.2 3.7 18.5 9.1 27.7 16.4 21.2 16.7 41.6 42.6 59 75zM540 640.9V540h147.5c-1.6 44.2-7.1 87.1-16.3 127.8l-.3 1.2A445.02 445.02 0 00540 640.9zm0-156.9V383.1c45.8-2.8 89.8-12.5 130.9-28.1l.3 1.2c9.2 40.7 14.7 83.5 16.3 127.8H540zm-56 56v100.9c-45.8 2.8-89.8 12.5-130.9 28.1l-.3-1.2c-9.2-40.7-14.7-83.5-16.3-127.8H484zm-147.5-56c1.6-44.2 7.1-87.1 16.3-127.8l.3-1.2c41.1 15.6 85 25.3 130.9 28.1V484H336.5zM484 697v185.4c-9.2-3.7-18.5-9.1-27.7-16.4-21.2-16.7-41.7-42.7-59.1-75.1-11-20.6-20.7-43.3-29-67.8 37.2-14.6 75.9-23.3 115.8-26.1zm0-370a389.1 389.1 0 01-115.7-26.2c8.3-24.6 17.9-47.3 29-67.8 17.4-32.4 37.8-58.4 59.1-75.1 9.2-7.2 18.4-12.7 27.7-16.4V327zM365.7 165.5c3.7-1.5 7.3-3 11-4.4-23.4 31.3-43.5 70.4-59.2 115.4-21-12-40.9-26-59.4-41.8 31.8-29.2 67.9-52.4 107.6-69.2zM165.5 365.7c13.8-32.6 32-62.8 54.2-90.2 24.9 21.5 52.2 40.3 81.5 55.9-11.6 46.9-18.8 98.4-20.7 152.6H137c3-40.9 12.6-80.6 28.5-118.3zM137 540h143.5c1.9 54.2 9.1 105.7 20.7 152.6a444.07 444.07 0 00-81.5 55.9A373.86 373.86 0 01137 540zm228.7 318.5c-39.7-16.8-75.8-40-107.6-69.2 18.5-15.8 38.4-29.7 59.4-41.8 15.7 45 35.8 84.1 59.2 115.4-3.7-1.4-7.4-2.9-11-4.4zm292.6 0c-3.7 1.5-7.3 3-11 4.4 23.4-31.3 43.5-70.4 59.2-115.4 21 12 40.9 26 59.4 41.8a373.81 373.81 0 01-107.6 69.2z"}}]},name:"global",theme:"outlined"};var n=e.i(9583),l=r.forwardRef(function(e,l){return r.createElement(n.default,(0,t.default)({},e,{ref:l,icon:a}))});e.s(["GlobalOutlined",0,l],160818)},360820,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 15l7-7 7 7"}))});e.s(["ChevronUpIcon",0,r],360820)},728889,e=>{"use strict";var t=e.i(290571),r=e.i(271645),a=e.i(829087),n=e.i(480731),l=e.i(444755),s=e.i(673706),i=e.i(95779);let o={xs:{paddingX:"px-1.5",paddingY:"py-1.5"},sm:{paddingX:"px-1.5",paddingY:"py-1.5"},md:{paddingX:"px-2",paddingY:"py-2"},lg:{paddingX:"px-2",paddingY:"py-2"},xl:{paddingX:"px-2.5",paddingY:"py-2.5"}},d={xs:{height:"h-3",width:"w-3"},sm:{height:"h-5",width:"w-5"},md:{height:"h-5",width:"w-5"},lg:{height:"h-7",width:"w-7"},xl:{height:"h-9",width:"w-9"}},u={simple:{rounded:"",border:"",ring:"",shadow:""},light:{rounded:"rounded-tremor-default",border:"",ring:"",shadow:""},shadow:{rounded:"rounded-tremor-default",border:"border",ring:"",shadow:"shadow-tremor-card dark:shadow-dark-tremor-card"},solid:{rounded:"rounded-tremor-default",border:"border-2",ring:"ring-1",shadow:""},outlined:{rounded:"rounded-tremor-default",border:"border",ring:"ring-2",shadow:""}},c=(0,s.makeClassName)("Icon"),m=r.default.forwardRef((e,m)=>{let{icon:f,variant:h="simple",tooltip:p,size:g=n.Sizes.SM,color:x,className:b}=e,v=(0,t.__rest)(e,["icon","variant","tooltip","size","color","className"]),y=((e,t)=>{switch(e){case"simple":return{textColor:t?(0,s.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:"",borderColor:"",ringColor:""};case"light":return{textColor:t?(0,s.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,l.tremorTwMerge)((0,s.getColorClassNames)(t,i.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-brand-muted dark:bg-dark-tremor-brand-muted",borderColor:"",ringColor:""};case"shadow":return{textColor:t?(0,s.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,l.tremorTwMerge)((0,s.getColorClassNames)(t,i.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-background dark:bg-dark-tremor-background",borderColor:"border-tremor-border dark:border-dark-tremor-border",ringColor:""};case"solid":return{textColor:t?(0,s.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",bgColor:t?(0,l.tremorTwMerge)((0,s.getColorClassNames)(t,i.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-brand dark:bg-dark-tremor-brand",borderColor:"border-tremor-brand-inverted dark:border-dark-tremor-brand-inverted",ringColor:"ring-tremor-ring dark:ring-dark-tremor-ring"};case"outlined":return{textColor:t?(0,s.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,l.tremorTwMerge)((0,s.getColorClassNames)(t,i.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-background dark:bg-dark-tremor-background",borderColor:t?(0,s.getColorClassNames)(t,i.colorPalette.ring).borderColor:"border-tremor-brand-subtle dark:border-dark-tremor-brand-subtle",ringColor:t?(0,l.tremorTwMerge)((0,s.getColorClassNames)(t,i.colorPalette.ring).ringColor,"ring-opacity-40"):"ring-tremor-brand-muted dark:ring-dark-tremor-brand-muted"}}})(h,x),{tooltipProps:w,getReferenceProps:C}=(0,a.useTooltip)();return r.default.createElement("span",Object.assign({ref:(0,s.mergeRefs)([m,w.refs.setReference]),className:(0,l.tremorTwMerge)(c("root"),"inline-flex shrink-0 items-center justify-center",y.bgColor,y.textColor,y.borderColor,y.ringColor,u[h].rounded,u[h].border,u[h].shadow,u[h].ring,o[g].paddingX,o[g].paddingY,b)},C,v),r.default.createElement(a.default,Object.assign({text:p},w)),r.default.createElement(f,{className:(0,l.tremorTwMerge)(c("icon"),"shrink-0",d[g].height,d[g].width)}))});m.displayName="Icon",e.s(["default",0,m],728889)},752978,e=>{"use strict";var t=e.i(728889);e.s(["Icon",()=>t.default])},591935,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"}))});e.s(["PencilAltIcon",0,r],591935)},551332,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"}))});e.s(["ClipboardCopyIcon",0,r],551332)},122577,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"}),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M21 12a9 9 0 11-18 0 9 9 0 0118 0z"}))});e.s(["PlayIcon",0,r],122577)},434626,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"}))});e.s(["ExternalLinkIcon",0,r],434626)},902555,e=>{"use strict";var t=e.i(843476),r=e.i(591935),a=e.i(122577),n=e.i(278587),l=e.i(68155),s=e.i(360820),i=e.i(871943),o=e.i(434626),d=e.i(551332),u=e.i(592968),c=e.i(115504),m=e.i(752978);function f({icon:e,onClick:r,className:a,disabled:n,dataTestId:l}){return n?(0,t.jsx)(m.Icon,{icon:e,size:"sm",className:"opacity-50 cursor-not-allowed","data-testid":l}):(0,t.jsx)(m.Icon,{icon:e,size:"sm",onClick:r,className:(0,c.cx)("cursor-pointer",a),"data-testid":l})}let h={Edit:{icon:r.PencilAltIcon,className:"hover:text-blue-600"},Delete:{icon:l.TrashIcon,className:"hover:text-red-600"},Test:{icon:a.PlayIcon,className:"hover:text-blue-600"},Regenerate:{icon:n.RefreshIcon,className:"hover:text-green-600"},Up:{icon:s.ChevronUpIcon,className:"hover:text-blue-600"},Down:{icon:i.ChevronDownIcon,className:"hover:text-blue-600"},Open:{icon:o.ExternalLinkIcon,className:"hover:text-green-600"},Copy:{icon:d.ClipboardCopyIcon,className:"hover:text-blue-600"}};e.s(["default",0,function({onClick:e,tooltipText:r,disabled:a=!1,disabledTooltipText:n,dataTestId:l,variant:s}){let{icon:i,className:o}=h[s];return(0,t.jsx)(u.Tooltip,{title:a?n:r,children:(0,t.jsx)("span",{children:(0,t.jsx)(f,{icon:i,onClick:e,className:o,disabled:a,dataTestId:l})})})}],902555)},625901,e=>{"use strict";var t=e.i(266027),r=e.i(621482),a=e.i(243652),n=e.i(602869),l=e.i(135214);let s=(0,a.createQueryKeys)("models"),i=(0,a.createQueryKeys)("modelHub"),o=(0,a.createQueryKeys)("allProxyModels");(0,a.createQueryKeys)("selectedTeamModels");let d=(0,a.createQueryKeys)("infiniteModels"),u=(0,a.createQueryKeys)("userModels");e.s(["useAllProxyModels",0,()=>{let{accessToken:e,userId:r,userRole:a}=(0,l.default)();return(0,t.useQuery)({queryKey:o.list({}),queryFn:async()=>await (0,n.modelAvailableCall)(e,r,a,!0,null,!0,!1,"expand"),enabled:!!(e&&r&&a)})},"useInfiniteModelInfo",0,(e=50,t)=>{let{accessToken:a,userId:s,userRole:i}=(0,l.default)();return(0,r.useInfiniteQuery)({queryKey:d.list({filters:{...s&&{userId:s},...i&&{userRole:i},size:e,...t&&{search:t}}}),queryFn:async({pageParam:r})=>await (0,n.modelInfoCall)(a,s,i,r,e,t),initialPageParam:1,getNextPageParam:e=>{if(e.current_page{let{accessToken:e}=(0,l.default)();return(0,t.useQuery)({queryKey:i.list({}),queryFn:async()=>await (0,n.modelHubCall)(e),enabled:!!e})},"useModelsInfo",0,(e=1,r=50,a,i,o,d,u)=>{let{accessToken:c,userId:m,userRole:f}=(0,l.default)();return(0,t.useQuery)({queryKey:s.list({filters:{...m&&{userId:m},...f&&{userRole:f},page:e,size:r,...a&&{search:a},...i&&{modelId:i},...o&&{teamId:o},...d&&{sortBy:d},...u&&{sortOrder:u}}}),queryFn:async()=>await (0,n.modelInfoCall)(c,m,f,e,r,a,i,o,d,u),enabled:!!(c&&m&&f)})},"useUserModels",0,()=>{let{accessToken:e,userId:r,userRole:a}=(0,l.default)();return(0,t.useQuery)({queryKey:u.list({}),queryFn:async()=>(await (0,n.modelAvailableCall)(e,r,a)).data.map(e=>e.id),enabled:!!(e&&r&&a)})}])},738014,e=>{"use strict";var t=e.i(135214),r=e.i(602869),a=e.i(266027);let n=(0,e.i(243652).createQueryKeys)("users");e.s(["useCurrentUser",0,()=>{let{accessToken:e,userId:l}=(0,t.default)();return(0,a.useQuery)({queryKey:n.detail(l),queryFn:async()=>await (0,r.userGetInfoV2)(e),enabled:!!(e&&l)})}])},162386,e=>{"use strict";var t=e.i(843476),r=e.i(625901),a=e.i(109799),n=e.i(785242),l=e.i(738014),s=e.i(199133),i=e.i(981339),o=e.i(592968);let d={label:"All Proxy Models",value:"all-proxy-models"},u={label:"No Default Models",value:"no-default-models"},c=[d,u],m={user:({allProxyModels:e,userModels:t,options:r})=>t&&r?.includeUserModels?t:[],team:({allProxyModels:e,selectedOrganization:t,userModels:r})=>t?t.models.includes(d.value)||0===t.models.length?e:e.filter(e=>t.models.includes(e)):e??[],organization:({allProxyModels:e})=>e,global:({allProxyModels:e})=>e};e.s(["ModelSelect",0,e=>{let{teamID:f,organizationID:h,options:p,context:g,dataTestId:x,value:b=[],onChange:v,style:y}=e,{includeUserModels:w,showAllTeamModelsOption:C,showAllProxyModelsOverride:M,includeSpecialOptions:j}=p||{},{data:k,isLoading:S}=(0,r.useAllProxyModels)(),{data:$,isLoading:O}=(0,n.useTeam)(f),{data:N,isLoading:_}=(0,a.useOrganization)(h),{data:I,isLoading:D}=(0,l.useCurrentUser)(),z=e=>c.some(t=>t.value===e),T=b.some(z),A=N?.models.includes(d.value)||N?.models.length===0;if(S||O||_||D)return(0,t.jsx)(i.Skeleton.Input,{active:!0,block:!0});let{wildcard:P,regular:E}=(e=>{let t=[],r=[];for(let a of e)a.endsWith("/*")?t.push(a):r.push(a);return{wildcard:t,regular:r}})(((e,t,r)=>{let a=Array.from(new Map(e.map(e=>[e.id,e])).values()).map(e=>e.id);if(t.options?.showAllProxyModelsOverride)return a;let n=m[t.context];return n?n({allProxyModels:a,...r,options:t.options}):[]})(k?.data??[],e,{selectedTeam:$,selectedOrganization:N,userModels:I?.models}));return(0,t.jsx)(s.Select,{"data-testid":x,value:b,onChange:e=>{let t=e.filter(z);v(t.length>0?[t[t.length-1]]:e)},style:y,options:[...j?[{label:(0,t.jsx)("span",{children:"Special Options"}),title:"Special Options",options:[...M||A&&j||"global"===g?[{label:(0,t.jsx)("span",{children:"All Proxy Models"}),value:d.value,disabled:b.length>0&&b.some(e=>z(e)&&e!==d.value),key:d.value}]:[],{label:(0,t.jsx)("span",{children:"No Default Models"}),value:u.value,disabled:b.length>0&&b.some(e=>z(e)&&e!==u.value),key:u.value}]}]:[],...P.length>0?[{label:(0,t.jsx)("span",{children:"Wildcard Options"}),title:"Wildcard Options",options:P.map(e=>{let r=e.replace("/*",""),a=r.charAt(0).toUpperCase()+r.slice(1);return{label:(0,t.jsx)("span",{children:`All ${a} models`}),value:e,disabled:T}})}]:[],{label:(0,t.jsx)("span",{children:"Models"}),title:"Models",options:E.map(e=>({label:(0,t.jsx)("span",{children:e}),value:e,disabled:T}))}],mode:"multiple",placeholder:"Select Models",allowClear:!0,maxTagCount:"responsive",maxTagPlaceholder:e=>(0,t.jsx)(o.Tooltip,{styles:{root:{pointerEvents:"none"}},title:e.map(({value:e})=>e).join(", "),children:(0,t.jsxs)("span",{children:["+",e.length," more"]})})})}],162386)},907308,276173,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(212931),n=e.i(808613),l=e.i(464571),s=e.i(199133),i=e.i(592968),o=e.i(213205),d=e.i(343488),u=e.i(602869),c=e.i(741466);e.s(["default",0,({isVisible:e,onCancel:m,onSubmit:f,accessToken:h,title:p="Add Team Member",roles:g=[{label:"admin",value:"admin",description:"Admin role. Can create team keys, add members, and manage settings."},{label:"user",value:"user",description:"User role. Can view team info, but not manage it."}],defaultRole:x="user",teamId:b})=>{let[v]=n.Form.useForm(),[y,w]=(0,r.useState)([]),[C,M]=(0,r.useState)(!1),[j,k]=(0,r.useState)("user_email"),[S,$]=(0,r.useState)(!1),O=async(e,t)=>{if(!e)return void w([]);M(!0);try{let r=new URLSearchParams;if(r.append(t,e),b&&r.append("team_id",b),null==h)return;let a=(await (0,u.userFilterUICall)(h,r)).map(e=>({label:"user_email"===t?`${e.user_email}`:`${e.user_id}`,value:"user_email"===t?e.user_email:e.user_id,user:e}));w(a)}catch(e){console.error("Error fetching users:",e)}finally{M(!1)}},N=(0,d.useDebouncedCallback)((e,t)=>O(e,t),{wait:c.DEBOUNCE_WAIT_MS}),_=(e,t)=>{k(t),N(e,t)},I=(e,t)=>{let r=t.user;v.setFieldsValue({user_email:r.user_email,user_id:r.user_id,role:v.getFieldValue("role")})},D=async e=>{$(!0);try{await f(e)}finally{$(!1)}};return(0,t.jsx)(a.Modal,{title:p,open:e,onCancel:()=>{v.resetFields(),w([]),m()},footer:null,width:800,maskClosable:!S,children:(0,t.jsxs)(n.Form,{form:v,onFinish:D,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",initialValues:{role:x},children:[(0,t.jsx)(n.Form.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,t.jsx)(s.Select,{showSearch:!0,className:"w-full",placeholder:"Search by email",filterOption:!1,onSearch:e=>_(e,"user_email"),onSelect:(e,t)=>I(e,t),options:"user_email"===j?y:[],loading:C,allowClear:!0,"data-testid":"member-email-search"})}),(0,t.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,t.jsx)(n.Form.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,t.jsx)(s.Select,{showSearch:!0,className:"w-full",placeholder:"Search by user ID",filterOption:!1,onSearch:e=>_(e,"user_id"),onSelect:(e,t)=>I(e,t),options:"user_id"===j?y:[],loading:C,allowClear:!0})}),(0,t.jsx)(n.Form.Item,{label:"Member Role",name:"role",className:"mb-4",children:(0,t.jsx)(s.Select,{defaultValue:x,children:g.map(e=>(0,t.jsx)(s.Select.Option,{value:e.value,children:(0,t.jsxs)(i.Tooltip,{title:e.description,children:[(0,t.jsx)("span",{className:"font-medium",children:e.label}),(0,t.jsxs)("span",{className:"ml-2 text-gray-500 text-sm",children:["- ",e.description]})]})},e.value))})}),(0,t.jsx)("div",{className:"text-right mt-4",children:(0,t.jsx)(l.Button,{type:"primary",htmlType:"submit",icon:(0,t.jsx)(o.UserAddOutlined,{}),loading:S,children:S?"Adding...":"Add Member"})})]})})}],907308);var m=e.i(599724),f=e.i(779241),h=e.i(435451),p=e.i(860585);e.s(["default",0,({visible:e,onCancel:i,onSubmit:o,initialData:d,mode:u,config:c})=>{let g,[x]=n.Form.useForm(),[b,v]=(0,r.useState)(!1);(0,r.useEffect)(()=>{if(e)if("edit"===u&&d){let e={...d,role:d.role||c.defaultRole,max_budget_in_team:d.max_budget_in_team||null,tpm_limit:d.tpm_limit||null,rpm_limit:d.rpm_limit||null,budget_duration:d.budget_duration||null,allowed_models:d.allowed_models||[]};x.setFieldsValue(e)}else x.resetFields(),x.setFieldsValue({role:c.defaultRole||c.roleOptions[0]?.value})},[e,d,u,x,c.defaultRole,c.roleOptions]);let y=async e=>{try{v(!0);let t=Object.entries(e).reduce((e,[t,r])=>{if("string"==typeof r){let a=r.trim();return""===a&&("max_budget_in_team"===t||"tpm_limit"===t||"rpm_limit"===t)?{...e,[t]:null}:{...e,[t]:a}}return{...e,[t]:r}},{});await Promise.resolve(o(t)),x.resetFields()}catch(e){console.error("Form submission error:",e)}finally{v(!1)}};return(0,t.jsx)(a.Modal,{title:c.title||("add"===u?"Add Member":"Edit Member"),open:e,width:1e3,footer:null,onCancel:i,children:(0,t.jsxs)(n.Form,{form:x,onFinish:y,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[c.showEmail&&(0,t.jsx)(n.Form.Item,{label:"Email",name:"user_email",className:"mb-4",rules:[{type:"email",message:"Please enter a valid email!"}],children:(0,t.jsx)(f.TextInput,{placeholder:"user@example.com"})}),c.showEmail&&c.showUserId&&(0,t.jsx)("div",{className:"text-center mb-4",children:(0,t.jsx)(m.Text,{children:"OR"})}),c.showUserId&&(0,t.jsx)(n.Form.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,t.jsx)(f.TextInput,{placeholder:"user_123"})}),(0,t.jsx)(n.Form.Item,{label:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("span",{children:"Role"}),"edit"===u&&d&&(0,t.jsxs)("span",{className:"text-gray-500 text-sm",children:["(Current: ",(g=d.role,c.roleOptions.find(e=>e.value===g)?.label||g),")"]})]}),name:"role",className:"mb-4",rules:[{required:!0,message:"Please select a role!"}],children:(0,t.jsx)(s.Select,{children:"edit"===u&&d?[...c.roleOptions.filter(e=>e.value===d.role),...c.roleOptions.filter(e=>e.value!==d.role)].map(e=>(0,t.jsx)(s.Select.Option,{value:e.value,children:e.label},e.value)):c.roleOptions.map(e=>(0,t.jsx)(s.Select.Option,{value:e.value,children:e.label},e.value))})}),c.additionalFields?.map(e=>(0,t.jsx)(n.Form.Item,{label:e.label,name:e.name,className:"mb-4",rules:e.rules,children:(e=>{switch(e.type){case"input":return(0,t.jsx)(f.TextInput,{placeholder:e.placeholder});case"numerical":return(0,t.jsx)(h.default,{step:e.step||1,min:e.min||0,style:{width:"100%"},placeholder:e.placeholder||"Enter a numerical value"});case"select":return(0,t.jsx)(s.Select,{children:e.options?.map(e=>(0,t.jsx)(s.Select.Option,{value:e.value,children:e.label},e.value))});case"multi-select":return(0,t.jsx)(s.Select,{mode:"multiple",placeholder:e.placeholder||"Select options",options:e.options,allowClear:!0});case"budget-duration":return(0,t.jsx)(p.default,{});default:return null}})(e)},e.name)),(0,t.jsxs)("div",{className:"text-right mt-6",children:[(0,t.jsx)(l.Button,{onClick:i,className:"mr-2",disabled:b,children:"Cancel"}),(0,t.jsx)(l.Button,{type:"default",htmlType:"submit",loading:b,children:"add"===u?b?"Adding...":"Add Member":b?"Saving...":"Save Changes"})]})]})})}],276173)},294612,e=>{"use strict";var t=e.i(843476),r=e.i(100486),a=e.i(827252),n=e.i(213205),l=e.i(771674),s=e.i(464571),i=e.i(770914),o=e.i(291542),d=e.i(262218),u=e.i(592968),c=e.i(898586),m=e.i(902555);let{Text:f}=c.Typography;e.s(["default",0,function({members:e,canEdit:c,onEdit:h,onDelete:p,onAddMember:g,roleColumnTitle:x="Role",roleTooltip:b,extraColumns:v=[],showDeleteForMember:y,emptyText:w}){let C=[{title:"User Email",dataIndex:"user_email",key:"user_email",render:e=>(0,t.jsx)(f,{children:e||"-"})},{title:"User ID",dataIndex:"user_id",key:"user_id",render:e=>"default_user_id"===e?(0,t.jsx)(d.Tag,{color:"blue",children:"Default Proxy Admin"}):(0,t.jsx)(f,{children:e||"-"})},{title:b?(0,t.jsxs)(i.Space,{direction:"horizontal",children:[x,(0,t.jsx)(u.Tooltip,{title:b,children:(0,t.jsx)(a.InfoCircleOutlined,{})})]}):x,dataIndex:"role",key:"role",render:e=>(0,t.jsxs)(i.Space,{children:[e?.toLowerCase()==="admin"||e?.toLowerCase()==="org_admin"?(0,t.jsx)(r.CrownOutlined,{}):(0,t.jsx)(l.UserOutlined,{}),(0,t.jsx)(f,{style:{textTransform:"capitalize"},children:e||"-"})]})},...v,{title:"Actions",key:"actions",fixed:"right",width:120,render:(e,r)=>c?(0,t.jsxs)(i.Space,{children:[(0,t.jsx)(m.default,{variant:"Edit",tooltipText:"Edit member",dataTestId:"edit-member",onClick:()=>h(r)}),(!y||y(r))&&(0,t.jsx)(m.default,{variant:"Delete",tooltipText:"Delete member",dataTestId:"delete-member",onClick:()=>p(r)})]}):null}];return(0,t.jsxs)(i.Space,{direction:"vertical",style:{width:"100%"},children:[(0,t.jsxs)("span",{className:"inline-flex text-sm text-gray-700",children:[e.length," Member",1!==e.length?"s":""]}),(0,t.jsx)(o.Table,{columns:C,dataSource:e,rowKey:e=>e.user_id??e.user_email??JSON.stringify(e),pagination:!1,size:"small",scroll:{x:"max-content"},locale:w?{emptyText:w}:void 0}),g&&c&&(0,t.jsx)(s.Button,{icon:(0,t.jsx)(n.UserAddOutlined,{}),type:"primary",onClick:g,children:"Add Member"})]})}])}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/01ozl298h03bw.js b/litellm/proxy/_experimental/out/_next/static/chunks/01ozl298h03bw.js deleted file mode 100644 index 2e954ace99a..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/01ozl298h03bw.js +++ /dev/null @@ -1,8 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,95779,e=>{"use strict";var t=e.i(480731);let r=[t.BaseColors.Blue,t.BaseColors.Cyan,t.BaseColors.Sky,t.BaseColors.Indigo,t.BaseColors.Violet,t.BaseColors.Purple,t.BaseColors.Fuchsia,t.BaseColors.Slate,t.BaseColors.Gray,t.BaseColors.Zinc,t.BaseColors.Neutral,t.BaseColors.Stone,t.BaseColors.Red,t.BaseColors.Orange,t.BaseColors.Amber,t.BaseColors.Yellow,t.BaseColors.Lime,t.BaseColors.Green,t.BaseColors.Emerald,t.BaseColors.Teal,t.BaseColors.Pink,t.BaseColors.Rose];e.s(["colorPalette",0,{canvasBackground:50,lightBackground:100,background:500,darkBackground:600,darkestBackground:800,lightBorder:200,border:500,darkBorder:700,lightRing:200,ring:300,iconRing:500,lightText:400,text:500,iconText:600,darkText:700,darkestText:900,icon:500},"themeColorRange",0,r])},994388,e=>{"use strict";var t=e.i(290571),r=e.i(829087),a=e.i(271645);let l=["preEnter","entering","entered","preExit","exiting","exited","unmounted"],o=e=>({_s:e,status:l[e],isEnter:e<3,isMounted:6!==e,isResolved:2===e||e>4}),n=e=>e?6:5,i=(e,t,r,a,l)=>{clearTimeout(a.current);let n=o(e);t(n),r.current=n,l&&l({current:n})};var s=e.i(480731),d=e.i(444755),c=e.i(673706);let u=e=>{var r=(0,t.__rest)(e,[]);return a.default.createElement("svg",Object.assign({},r,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"}),a.default.createElement("path",{fill:"none",d:"M0 0h24v24H0z"}),a.default.createElement("path",{d:"M18.364 5.636L16.95 7.05A7 7 0 1 0 19 12h2a9 9 0 1 1-2.636-6.364z"}))};var g=e.i(95779);let m={xs:{height:"h-4",width:"w-4"},sm:{height:"h-5",width:"w-5"},md:{height:"h-5",width:"w-5"},lg:{height:"h-6",width:"w-6"},xl:{height:"h-6",width:"w-6"}},p=(e,t)=>{switch(e){case"primary":return{textColor:t?(0,c.getColorClassNames)("white").textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",hoverTextColor:t?(0,c.getColorClassNames)("white").textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",bgColor:t?(0,c.getColorClassNames)(t,g.colorPalette.background).bgColor:"bg-tremor-brand dark:bg-dark-tremor-brand",hoverBgColor:t?(0,c.getColorClassNames)(t,g.colorPalette.darkBackground).hoverBgColor:"hover:bg-tremor-brand-emphasis dark:hover:bg-dark-tremor-brand-emphasis",borderColor:t?(0,c.getColorClassNames)(t,g.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand",hoverBorderColor:t?(0,c.getColorClassNames)(t,g.colorPalette.darkBorder).hoverBorderColor:"hover:border-tremor-brand-emphasis dark:hover:border-dark-tremor-brand-emphasis"};case"secondary":return{textColor:t?(0,c.getColorClassNames)(t,g.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",hoverTextColor:t?(0,c.getColorClassNames)(t,g.colorPalette.text).textColor:"hover:text-tremor-brand-emphasis dark:hover:text-dark-tremor-brand-emphasis",bgColor:(0,c.getColorClassNames)("transparent").bgColor,hoverBgColor:t?(0,d.tremorTwMerge)((0,c.getColorClassNames)(t,g.colorPalette.background).hoverBgColor,"hover:bg-opacity-20 dark:hover:bg-opacity-20"):"hover:bg-tremor-brand-faint dark:hover:bg-dark-tremor-brand-faint",borderColor:t?(0,c.getColorClassNames)(t,g.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand"};case"light":return{textColor:t?(0,c.getColorClassNames)(t,g.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",hoverTextColor:t?(0,c.getColorClassNames)(t,g.colorPalette.darkText).hoverTextColor:"hover:text-tremor-brand-emphasis dark:hover:text-dark-tremor-brand-emphasis",bgColor:(0,c.getColorClassNames)("transparent").bgColor,borderColor:"",hoverBorderColor:""}}},h=(0,c.makeClassName)("Button"),b=({loading:e,iconSize:t,iconPosition:r,Icon:l,needMargin:o,transitionStatus:n})=>{let i=o?r===s.HorizontalPositions.Left?(0,d.tremorTwMerge)("-ml-1","mr-1.5"):(0,d.tremorTwMerge)("-mr-1","ml-1.5"):"",c=(0,d.tremorTwMerge)("w-0 h-0"),g={default:c,entering:c,entered:t,exiting:t,exited:c};return e?a.default.createElement(u,{className:(0,d.tremorTwMerge)(h("icon"),"animate-spin shrink-0",i,g.default,g[n]),style:{transition:"width 150ms"}}):a.default.createElement(l,{className:(0,d.tremorTwMerge)(h("icon"),"shrink-0",t,i)})},x=a.default.forwardRef((e,l)=>{let{icon:u,iconPosition:g=s.HorizontalPositions.Left,size:x=s.Sizes.SM,color:f,variant:C="primary",disabled:v,loading:$=!1,loadingText:k,children:y,tooltip:j,className:w}=e,N=(0,t.__rest)(e,["icon","iconPosition","size","color","variant","disabled","loading","loadingText","children","tooltip","className"]),B=$||v,T=void 0!==u||$,S=$&&k,M=!(!y&&!S),O=(0,d.tremorTwMerge)(m[x].height,m[x].width),E="light"!==C?(0,d.tremorTwMerge)("rounded-tremor-default border","shadow-tremor-input","dark:shadow-dark-tremor-input"):"",P=p(C,f),z=("light"!==C?{xs:{paddingX:"px-2.5",paddingY:"py-1.5",fontSize:"text-xs"},sm:{paddingX:"px-4",paddingY:"py-2",fontSize:"text-sm"},md:{paddingX:"px-4",paddingY:"py-2",fontSize:"text-md"},lg:{paddingX:"px-4",paddingY:"py-2.5",fontSize:"text-lg"},xl:{paddingX:"px-4",paddingY:"py-3",fontSize:"text-xl"}}:{xs:{paddingX:"",paddingY:"",fontSize:"text-xs"},sm:{paddingX:"",paddingY:"",fontSize:"text-sm"},md:{paddingX:"",paddingY:"",fontSize:"text-md"},lg:{paddingX:"",paddingY:"",fontSize:"text-lg"},xl:{paddingX:"",paddingY:"",fontSize:"text-xl"}})[x],{tooltipProps:A,getReferenceProps:R}=(0,r.useTooltip)(300),[q,I]=(({enter:e=!0,exit:t=!0,preEnter:r,preExit:l,timeout:s,initialEntered:d,mountOnEnter:c,unmountOnExit:u,onStateChange:g}={})=>{let[m,p]=(0,a.useState)(()=>o(d?2:n(c))),h=(0,a.useRef)(m),b=(0,a.useRef)(0),[x,f]="object"==typeof s?[s.enter,s.exit]:[s,s],C=(0,a.useCallback)(()=>{let e=((e,t)=>{switch(e){case 1:case 0:return 2;case 4:case 3:return n(t)}})(h.current._s,u);e&&i(e,p,h,b,g)},[g,u]);return[m,(0,a.useCallback)(a=>{let o=e=>{switch(i(e,p,h,b,g),e){case 1:x>=0&&(b.current=((...e)=>setTimeout(...e))(C,x));break;case 4:f>=0&&(b.current=((...e)=>setTimeout(...e))(C,f));break;case 0:case 3:b.current=((...e)=>setTimeout(...e))(()=>{isNaN(document.body.offsetTop)||o(e+1)},0)}},s=h.current.isEnter;"boolean"!=typeof a&&(a=!s),a?s||o(e?+!r:2):s&&o(t?l?3:4:n(u))},[C,g,e,t,r,l,x,f,u]),C]})({timeout:50});return(0,a.useEffect)(()=>{I($)},[$]),a.default.createElement("button",Object.assign({ref:(0,c.mergeRefs)([l,A.refs.setReference]),className:(0,d.tremorTwMerge)(h("root"),"shrink-0 inline-flex justify-center items-center group font-medium outline-none",E,z.paddingX,z.paddingY,z.fontSize,P.textColor,P.bgColor,P.borderColor,P.hoverBorderColor,B?"opacity-50 cursor-not-allowed":(0,d.tremorTwMerge)(p(C,f).hoverTextColor,p(C,f).hoverBgColor,p(C,f).hoverBorderColor),w),disabled:B},R,N),a.default.createElement(r.default,Object.assign({text:j},A)),T&&g!==s.HorizontalPositions.Right?a.default.createElement(b,{loading:$,iconSize:O,iconPosition:g,Icon:u,transitionStatus:q.status,needMargin:M}):null,S||y?a.default.createElement("span",{className:(0,d.tremorTwMerge)(h("text"),"text-tremor-default whitespace-nowrap")},S?k:y):null,T&&g===s.HorizontalPositions.Right?a.default.createElement(b,{loading:$,iconSize:O,iconPosition:g,Icon:u,transitionStatus:q.status,needMargin:M}):null)});x.displayName="Button",e.s(["Button",0,x],994388)},185793,e=>{"use strict";e.i(247167);var t=e.i(271645),r=e.i(343794),a=e.i(242064),l=e.i(529681);let o=e=>{let{prefixCls:a,className:l,style:o,size:n,shape:i}=e,s=(0,r.default)({[`${a}-lg`]:"large"===n,[`${a}-sm`]:"small"===n}),d=(0,r.default)({[`${a}-circle`]:"circle"===i,[`${a}-square`]:"square"===i,[`${a}-round`]:"round"===i}),c=t.useMemo(()=>"number"==typeof n?{width:n,height:n,lineHeight:`${n}px`}:{},[n]);return t.createElement("span",{className:(0,r.default)(a,s,d,l),style:Object.assign(Object.assign({},c),o)})};e.i(296059);var n=e.i(694758),i=e.i(915654),s=e.i(246422),d=e.i(838378);let c=new n.Keyframes("ant-skeleton-loading",{"0%":{backgroundPosition:"100% 50%"},"100%":{backgroundPosition:"0 50%"}}),u=e=>({height:e,lineHeight:(0,i.unit)(e)}),g=e=>Object.assign({width:e},u(e)),m=(e,t)=>Object.assign({width:t(e).mul(5).equal(),minWidth:t(e).mul(5).equal()},u(e)),p=e=>Object.assign({width:e},u(e)),h=(e,t,r)=>{let{skeletonButtonCls:a}=e;return{[`${r}${a}-circle`]:{width:t,minWidth:t,borderRadius:"50%"},[`${r}${a}-round`]:{borderRadius:t}}},b=(e,t)=>Object.assign({width:t(e).mul(2).equal(),minWidth:t(e).mul(2).equal()},u(e)),x=(0,s.genStyleHooks)("Skeleton",e=>{let{componentCls:t,calc:r}=e;return(e=>{let{componentCls:t,skeletonAvatarCls:r,skeletonTitleCls:a,skeletonParagraphCls:l,skeletonButtonCls:o,skeletonInputCls:n,skeletonImageCls:i,controlHeight:s,controlHeightLG:d,controlHeightSM:u,gradientFromColor:x,padding:f,marginSM:C,borderRadius:v,titleHeight:$,blockRadius:k,paragraphLiHeight:y,controlHeightXS:j,paragraphMarginTop:w}=e;return{[t]:{display:"table",width:"100%",[`${t}-header`]:{display:"table-cell",paddingInlineEnd:f,verticalAlign:"top",[r]:Object.assign({display:"inline-block",verticalAlign:"top",background:x},g(s)),[`${r}-circle`]:{borderRadius:"50%"},[`${r}-lg`]:Object.assign({},g(d)),[`${r}-sm`]:Object.assign({},g(u))},[`${t}-content`]:{display:"table-cell",width:"100%",verticalAlign:"top",[a]:{width:"100%",height:$,background:x,borderRadius:k,[`+ ${l}`]:{marginBlockStart:u}},[l]:{padding:0,"> li":{width:"100%",height:y,listStyle:"none",background:x,borderRadius:k,"+ li":{marginBlockStart:j}}},[`${l}> li:last-child:not(:first-child):not(:nth-child(2))`]:{width:"61%"}},[`&-round ${t}-content`]:{[`${a}, ${l} > li`]:{borderRadius:v}}},[`${t}-with-avatar ${t}-content`]:{[a]:{marginBlockStart:C,[`+ ${l}`]:{marginBlockStart:w}}},[`${t}${t}-element`]:Object.assign(Object.assign(Object.assign(Object.assign({display:"inline-block",width:"auto"},(e=>{let{borderRadiusSM:t,skeletonButtonCls:r,controlHeight:a,controlHeightLG:l,controlHeightSM:o,gradientFromColor:n,calc:i}=e;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({[r]:Object.assign({display:"inline-block",verticalAlign:"top",background:n,borderRadius:t,width:i(a).mul(2).equal(),minWidth:i(a).mul(2).equal()},b(a,i))},h(e,a,r)),{[`${r}-lg`]:Object.assign({},b(l,i))}),h(e,l,`${r}-lg`)),{[`${r}-sm`]:Object.assign({},b(o,i))}),h(e,o,`${r}-sm`))})(e)),(e=>{let{skeletonAvatarCls:t,gradientFromColor:r,controlHeight:a,controlHeightLG:l,controlHeightSM:o}=e;return{[t]:Object.assign({display:"inline-block",verticalAlign:"top",background:r},g(a)),[`${t}${t}-circle`]:{borderRadius:"50%"},[`${t}${t}-lg`]:Object.assign({},g(l)),[`${t}${t}-sm`]:Object.assign({},g(o))}})(e)),(e=>{let{controlHeight:t,borderRadiusSM:r,skeletonInputCls:a,controlHeightLG:l,controlHeightSM:o,gradientFromColor:n,calc:i}=e;return{[a]:Object.assign({display:"inline-block",verticalAlign:"top",background:n,borderRadius:r},m(t,i)),[`${a}-lg`]:Object.assign({},m(l,i)),[`${a}-sm`]:Object.assign({},m(o,i))}})(e)),(e=>{let{skeletonImageCls:t,imageSizeBase:r,gradientFromColor:a,borderRadiusSM:l,calc:o}=e;return{[t]:Object.assign(Object.assign({display:"inline-flex",alignItems:"center",justifyContent:"center",verticalAlign:"middle",background:a,borderRadius:l},p(o(r).mul(2).equal())),{[`${t}-path`]:{fill:"#bfbfbf"},[`${t}-svg`]:Object.assign(Object.assign({},p(r)),{maxWidth:o(r).mul(4).equal(),maxHeight:o(r).mul(4).equal()}),[`${t}-svg${t}-svg-circle`]:{borderRadius:"50%"}}),[`${t}${t}-circle`]:{borderRadius:"50%"}}})(e)),[`${t}${t}-block`]:{width:"100%",[o]:{width:"100%"},[n]:{width:"100%"}},[`${t}${t}-active`]:{[` - ${a}, - ${l} > li, - ${r}, - ${o}, - ${n}, - ${i} - `]:Object.assign({},{background:e.skeletonLoadingBackground,backgroundSize:"400% 100%",animationName:c,animationDuration:e.skeletonLoadingMotionDuration,animationTimingFunction:"ease",animationIterationCount:"infinite"})}}})((0,d.mergeToken)(e,{skeletonAvatarCls:`${t}-avatar`,skeletonTitleCls:`${t}-title`,skeletonParagraphCls:`${t}-paragraph`,skeletonButtonCls:`${t}-button`,skeletonInputCls:`${t}-input`,skeletonImageCls:`${t}-image`,imageSizeBase:r(e.controlHeight).mul(1.5).equal(),borderRadius:100,skeletonLoadingBackground:`linear-gradient(90deg, ${e.gradientFromColor} 25%, ${e.gradientToColor} 37%, ${e.gradientFromColor} 63%)`,skeletonLoadingMotionDuration:"1.4s"}))},e=>{let{colorFillContent:t,colorFill:r}=e;return{color:t,colorGradientEnd:r,gradientFromColor:t,gradientToColor:r,titleHeight:e.controlHeight/2,blockRadius:e.borderRadiusSM,paragraphMarginTop:e.marginLG+e.marginXXS,paragraphLiHeight:e.controlHeight/2}},{deprecatedTokens:[["color","gradientFromColor"],["colorGradientEnd","gradientToColor"]]}),f=e=>{let{prefixCls:a,className:l,style:o,rows:n=0}=e,i=Array.from({length:n}).map((r,a)=>t.createElement("li",{key:a,style:{width:((e,t)=>{let{width:r,rows:a=2}=t;return Array.isArray(r)?r[e]:a-1===e?r:void 0})(a,e)}}));return t.createElement("ul",{className:(0,r.default)(a,l),style:o},i)},C=({prefixCls:e,className:a,width:l,style:o})=>t.createElement("h3",{className:(0,r.default)(e,a),style:Object.assign({width:l},o)});function v(e){return e&&"object"==typeof e?e:{}}let $=e=>{let{prefixCls:l,loading:n,className:i,rootClassName:s,style:d,children:c,avatar:u=!1,title:g=!0,paragraph:m=!0,active:p,round:h}=e,{getPrefixCls:b,direction:$,className:k,style:y}=(0,a.useComponentConfig)("skeleton"),j=b("skeleton",l),[w,N,B]=x(j);if(n||!("loading"in e)){let e,a,l=!!u,n=!!g,c=!!m;if(l){let r=Object.assign(Object.assign({prefixCls:`${j}-avatar`},n&&!c?{size:"large",shape:"square"}:{size:"large",shape:"circle"}),v(u));e=t.createElement("div",{className:`${j}-header`},t.createElement(o,Object.assign({},r)))}if(n||c){let e,r;if(n){let r=Object.assign(Object.assign({prefixCls:`${j}-title`},!l&&c?{width:"38%"}:l&&c?{width:"50%"}:{}),v(g));e=t.createElement(C,Object.assign({},r))}if(c){let e,a=Object.assign(Object.assign({prefixCls:`${j}-paragraph`},(e={},l&&n||(e.width="61%"),!l&&n?e.rows=3:e.rows=2,e)),v(m));r=t.createElement(f,Object.assign({},a))}a=t.createElement("div",{className:`${j}-content`},e,r)}let b=(0,r.default)(j,{[`${j}-with-avatar`]:l,[`${j}-active`]:p,[`${j}-rtl`]:"rtl"===$,[`${j}-round`]:h},k,i,s,N,B);return w(t.createElement("div",{className:b,style:Object.assign(Object.assign({},y),d)},e,a))}return null!=c?c:null};$.Button=e=>{let{prefixCls:n,className:i,rootClassName:s,active:d,block:c=!1,size:u="default"}=e,{getPrefixCls:g}=t.useContext(a.ConfigContext),m=g("skeleton",n),[p,h,b]=x(m),f=(0,l.default)(e,["prefixCls"]),C=(0,r.default)(m,`${m}-element`,{[`${m}-active`]:d,[`${m}-block`]:c},i,s,h,b);return p(t.createElement("div",{className:C},t.createElement(o,Object.assign({prefixCls:`${m}-button`,size:u},f))))},$.Avatar=e=>{let{prefixCls:n,className:i,rootClassName:s,active:d,shape:c="circle",size:u="default"}=e,{getPrefixCls:g}=t.useContext(a.ConfigContext),m=g("skeleton",n),[p,h,b]=x(m),f=(0,l.default)(e,["prefixCls","className"]),C=(0,r.default)(m,`${m}-element`,{[`${m}-active`]:d},i,s,h,b);return p(t.createElement("div",{className:C},t.createElement(o,Object.assign({prefixCls:`${m}-avatar`,shape:c,size:u},f))))},$.Input=e=>{let{prefixCls:n,className:i,rootClassName:s,active:d,block:c,size:u="default"}=e,{getPrefixCls:g}=t.useContext(a.ConfigContext),m=g("skeleton",n),[p,h,b]=x(m),f=(0,l.default)(e,["prefixCls"]),C=(0,r.default)(m,`${m}-element`,{[`${m}-active`]:d,[`${m}-block`]:c},i,s,h,b);return p(t.createElement("div",{className:C},t.createElement(o,Object.assign({prefixCls:`${m}-input`,size:u},f))))},$.Image=e=>{let{prefixCls:l,className:o,rootClassName:n,style:i,active:s}=e,{getPrefixCls:d}=t.useContext(a.ConfigContext),c=d("skeleton",l),[u,g,m]=x(c),p=(0,r.default)(c,`${c}-element`,{[`${c}-active`]:s},o,n,g,m);return u(t.createElement("div",{className:p},t.createElement("div",{className:(0,r.default)(`${c}-image`,o),style:i},t.createElement("svg",{viewBox:"0 0 1098 1024",xmlns:"http://www.w3.org/2000/svg",className:`${c}-image-svg`},t.createElement("title",null,"Image placeholder"),t.createElement("path",{d:"M365.714286 329.142857q0 45.714286-32.036571 77.677714t-77.677714 32.036571-77.677714-32.036571-32.036571-77.677714 32.036571-77.677714 77.677714-32.036571 77.677714 32.036571 32.036571 77.677714zM950.857143 548.571429l0 256-804.571429 0 0-109.714286 182.857143-182.857143 91.428571 91.428571 292.571429-292.571429zM1005.714286 146.285714l-914.285714 0q-7.460571 0-12.873143 5.412571t-5.412571 12.873143l0 694.857143q0 7.460571 5.412571 12.873143t12.873143 5.412571l914.285714 0q7.460571 0 12.873143-5.412571t5.412571-12.873143l0-694.857143q0-7.460571-5.412571-12.873143t-12.873143-5.412571zM1097.142857 164.571429l0 694.857143q0 37.741714-26.843429 64.585143t-64.585143 26.843429l-914.285714 0q-37.741714 0-64.585143-26.843429t-26.843429-64.585143l0-694.857143q0-37.741714 26.843429-64.585143t64.585143-26.843429l914.285714 0q37.741714 0 64.585143 26.843429t26.843429 64.585143z",className:`${c}-image-path`})))))},$.Node=e=>{let{prefixCls:l,className:o,rootClassName:n,style:i,active:s,children:d}=e,{getPrefixCls:c}=t.useContext(a.ConfigContext),u=c("skeleton",l),[g,m,p]=x(u),h=(0,r.default)(u,`${u}-element`,{[`${u}-active`]:s},m,o,n,p);return g(t.createElement("div",{className:h},t.createElement("div",{className:(0,r.default)(`${u}-image`,o),style:i},d)))},e.s(["default",0,$],185793)},922611,e=>{"use strict";var t=e.i(271645),r=e.i(175066);function a(){}let l=t.createContext({add:a,remove:a});e.s(["usePanelRef",0,function(e){let a=t.useContext(l),o=t.useRef(null);return(0,r.default)(t=>{if(t){let r=e?t.querySelector(e):t;r&&(a.add(r),o.current=r)}else a.remove(o.current)})}])},500330,e=>{"use strict";var t=e.i(727749);let r=(e,t=0,r=!1,a=!0)=>{if(null==e||!Number.isFinite(e)||0===e&&!a)return"-";let l={minimumFractionDigits:t,maximumFractionDigits:t};if(!r)return e.toLocaleString("en-US",l);let o=e<0?"-":"",n=Math.abs(e),i=n,s="";return n>=1e6?(i=n/1e6,s="M"):n>=1e3&&(i=n/1e3,s="K"),`${o}${i.toLocaleString("en-US",l)}${s}`},a=async(e,r="Copied to clipboard")=>{if(!e)return!1;if(!navigator||!navigator.clipboard||!navigator.clipboard.writeText)return l(e,r);try{return await navigator.clipboard.writeText(e),t.default.success(r),!0}catch(t){return console.error("Clipboard API failed: ",t),l(e,r)}},l=(e,r)=>{try{let a=document.createElement("textarea");a.value=e,a.style.position="fixed",a.style.left="-999999px",a.style.top="-999999px",a.setAttribute("readonly",""),document.body.appendChild(a),a.focus(),a.select();let l=document.execCommand("copy");if(document.body.removeChild(a),l)return t.default.success(r),!0;throw Error("execCommand failed")}catch(e){return t.default.fromBackend("Failed to copy to clipboard"),console.error("Failed to copy: ",e),!1}};e.s(["copyToClipboard",0,a,"formatNumberWithCommas",0,r,"getSpendString",0,(e,t=6)=>{if(null==e||!Number.isFinite(e)||0===e)return"-";let a=r(e,t,!1,!1);if(0===Number(a.replace(/,/g,""))){let e=(1/10**t).toFixed(t);return`< $${e}`}return`$${a}`},"updateExistingKeys",0,function(e,t){let r=structuredClone(e);for(let[e,a]of Object.entries(t))e in r&&(r[e]=a);return r}])},112179,581070,e=>{"use strict";var t=e.i(843476),r=e.i(487486),a=e.i(115504),l=e.i(746798);function o({content:e,trigger:r}){return(0,t.jsx)(l.TooltipProvider,{delay:300,children:(0,t.jsxs)(l.Tooltip,{children:[(0,t.jsx)(l.TooltipTrigger,{render:r}),(0,t.jsx)(l.TooltipContent,{children:e})]})})}e.s(["CellTooltip",0,o],581070);let n={success:"border-green-200 bg-green-50 text-green-600",error:"border-red-200 bg-red-50 text-red-600",warning:"border-amber-200 bg-amber-50 text-amber-600",neutral:"border-gray-200 bg-gray-50 text-gray-600",info:"border-blue-200 bg-blue-50 text-blue-600"};e.s(["StatusBadge",0,function({tone:e,label:l,tooltip:i,dataTestId:s}){let d=(0,t.jsx)(r.Badge,{variant:"outline","data-testid":s,className:(0,a.cn)("whitespace-nowrap font-normal",n[e]),children:l});return i?(0,t.jsx)(o,{content:i,trigger:d}):d}],112179)},200208,399536,997422,146512,e=>{"use strict";var t=e.i(843476),r=e.i(581070);let a=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],l=e=>String(e).padStart(2,"0");e.s(["DateCell",0,function({value:e,precision:o="datetime",fallback:n="-"}){let i,s,d,c=e?new Date(e):null;return!c||Number.isNaN(c.getTime())?(0,t.jsx)("span",{className:"text-muted-foreground",children:n}):(0,t.jsx)(r.CellTooltip,{content:(i=Intl.DateTimeFormat().resolvedOptions().timeZone,s=`${a[c.getMonth()]} ${c.getDate()}, ${c.getFullYear()}`,d=`${l(c.getHours())}:${l(c.getMinutes())}:${l(c.getSeconds())}`,`${s}, ${d} (${i})`),trigger:(0,t.jsx)("span",{className:"whitespace-nowrap",children:"date"===o?`${a[c.getMonth()]} ${c.getDate()}, ${c.getFullYear()}`:`${a[c.getMonth()]} ${c.getDate()}, ${l(c.getHours())}:${l(c.getMinutes())}:${l(c.getSeconds())}`})})}],200208);var o=e.i(174886),n=e.i(115504),i=e.i(500330);let s={pill:{base:"font-mono text-xs font-normal px-2 py-0.5 rounded-md text-left bg-blue-50 text-blue-500",clickable:"hover:bg-blue-100 cursor-pointer"},plain:{base:"font-mono text-xs text-left",clickable:"hover:text-blue-600 cursor-pointer"}};e.s(["IdCell",0,function({value:e,variant:a="pill",onClick:l,copyable:d=!1,truncate:c=!0,fallback:u="-",tooltip:g,disabled:m=!1,dataTestId:p,className:h}){if(!e)return(0,t.jsx)("span",{className:"text-muted-foreground",children:u});let b=!!l&&!m,x=(0,n.cn)(s[a].base,b&&s[a].clickable,c&&"block max-w-[15ch] truncate",m&&"opacity-50",h),f=b?(0,t.jsx)("button",{type:"button",className:x,"data-testid":p,onClick:()=>l(e),children:e}):(0,t.jsx)("span",{className:x,"data-testid":p,children:e}),C=(0,t.jsx)(r.CellTooltip,{content:g??e,trigger:f});return d?(0,t.jsxs)("span",{className:"inline-flex max-w-full items-center gap-1",children:[C,(0,t.jsx)("button",{type:"button","aria-label":"Copy ID",className:"shrink-0 cursor-pointer text-muted-foreground hover:text-foreground",onClick:t=>{t.stopPropagation(),(0,i.copyToClipboard)(e)},children:(0,t.jsx)(o.Copy,{className:"size-3"})})]}):C}],399536);var d=e.i(463059);e.s(["IdentityCell",0,function({title:e,subtitle:r,badge:a,onClick:l,className:o,titleClassName:i}){let s=(0,t.jsxs)("div",{className:"flex min-w-0 flex-col gap-0.5",children:[(0,t.jsx)("span",{className:(0,n.cn)("truncate text-sm font-medium text-foreground",i),children:e}),(null!=r&&""!==r||null!=a)&&(0,t.jsxs)("span",{className:"flex min-w-0 items-center gap-2",children:[null!=r&&""!==r&&(0,t.jsx)("span",{className:"truncate font-mono text-xs text-muted-foreground",children:r}),a]})]});return null!=l?(0,t.jsxs)("button",{type:"button",onClick:l,className:(0,n.cn)("group -mx-2 flex w-[calc(100%+1rem)] cursor-pointer items-center gap-2 rounded-md px-2 py-1 text-left transition-colors hover:bg-muted",o),children:[s,(0,t.jsx)(d.ChevronRight,{className:"ml-auto size-4 shrink-0 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100"})]}):(0,t.jsx)("div",{className:(0,n.cn)("min-w-0",o),children:s})}],997422);let c={hasModelAccess:!1,label:"Management"},u={hasModelAccess:!1,label:"Read-only"},g={hasModelAccess:!1,label:"SCIM"},m={hasModelAccess:!0,label:null},p=e=>e.startsWith("/scim"),h=(e,t)=>1===e.length&&e[0]===t;e.s(["deriveKeyModelScope",0,(e,t)=>"management"===t?c:"read_only"===t?u:Array.isArray(e)&&0!==e.length?e.every(p)?g:h(e,"management_routes")?c:h(e,"info_routes")?u:m:m],146512)},355619,e=>{"use strict";var t=e.i(602869);let r=async(e,r,a)=>{try{if(null===e||null===r)return;if(null!==a){let l=(await (0,t.modelAvailableCall)(a,e,r,!0,null,!0)).data.map(e=>e.id),o=[],n=[];return l.forEach(e=>{e.endsWith("/*")?o.push(e):n.push(e)}),[...o,...n]}}catch(e){console.error("Error fetching user models:",e)}};e.s(["excludeProxyWideSentinel",0,e=>e.filter(e=>"all-proxy-models"!==e),"fetchAvailableModelsForTeamOrKey",0,r,"getModelDisplayName",0,e=>{if("all-proxy-models"===e)return"All Proxy Models";if(e.endsWith("/*")){let t=e.replace("/*","");return`All ${t} models`}return e},"hasAllModelsSentinel",0,e=>e.includes("all-proxy-models")||e.includes("all-team-models"),"unfurlWildcardModelsInList",0,(e,t)=>{let r=[],a=[];return e.forEach(e=>{if(e.endsWith("/*")){let l=e.replace("/*",""),o=t.filter(e=>e.startsWith(l+"/"));a.push(...o),r.push(e)}else a.push(e)}),[...r,...a].filter((e,t,r)=>r.indexOf(e)===t)}])},622826,547227,964471,630500,e=>{"use strict";var t=e.i(581070);e.i(200208),e.i(399536),e.i(997422);var r=e.i(843476),a=e.i(146512),l=e.i(355619),o=e.i(487486);let n="all-proxy-models",i=e=>{if(e===n)return"All Proxy Models";let t=(0,l.getModelDisplayName)(e);return t.length>30?`${t.slice(0,30)}...`:t};e.s(["ModelsCell",0,function({models:e,maxVisible:l=3,allowedRoutes:s,keyType:d}){if(!Array.isArray(e)||0===e.length){let e=(0,a.deriveKeyModelScope)(s,d);return e.hasModelAccess?(0,r.jsx)(o.Badge,{variant:"secondary",children:"All Proxy Models"}):(0,r.jsx)(t.CellTooltip,{content:`Scoped to ${e.label} routes; this key cannot call any models`,trigger:(0,r.jsx)(o.Badge,{variant:"secondary",className:"cursor-default",children:"No model access"})})}let c=e.slice(0,l),u=e.slice(l);return(0,r.jsxs)("div",{className:"flex flex-wrap items-center gap-1",children:[c.map((e,t)=>(0,r.jsx)(o.Badge,{variant:e===n?"secondary":"outline",children:i(e)},t)),u.length>0&&(0,r.jsx)(t.CellTooltip,{content:(0,r.jsx)("div",{className:"flex max-w-[280px] flex-col gap-0.5",children:u.map((e,t)=>(0,r.jsx)("span",{children:i(e)},t))}),trigger:(0,r.jsxs)(o.Badge,{variant:"outline",className:"cursor-default",children:["+",u.length," more"]})})]})}],547227);var s=e.i(500330);e.s(["MoneyCell",0,function({value:e,decimals:t=4,emptyText:a="-",showZero:l=!1}){return null==e||Number.isNaN(e)?(0,r.jsx)("span",{className:"text-muted-foreground",children:a}):0===e?l?(0,r.jsx)("span",{className:"whitespace-nowrap",children:`$${(0,s.formatNumberWithCommas)(0,t,!1,!0)}`}):(0,r.jsx)("span",{className:"text-muted-foreground",children:"-"}):(0,r.jsx)("span",{className:"whitespace-nowrap",children:(0,s.getSpendString)(e,t)})}],964471);var d=e.i(944835);e.s(["SpendBudgetCell",0,function({spend:e,maxBudget:t,teamMaxBudget:a}){let l="number"!=typeof e||Number.isNaN(e)?0:e,o=t??a??null,n=null==t&&null!=a,i="number"==typeof o&&o>0,c=i?l/o*100:0,u=l>0?(0,s.getSpendString)(l,4):"$0.00",g=null===o?"· Unlimited":`of $${(0,s.formatNumberWithCommas)(o)}${n?" (Team)":""}`;return(0,r.jsxs)("div",{className:"flex min-w-[130px] flex-col gap-1",children:[(0,r.jsxs)("div",{className:"whitespace-nowrap text-xs",children:[(0,r.jsx)("span",{className:"font-medium tabular-nums text-foreground",children:u})," ",(0,r.jsx)("span",{className:"text-muted-foreground",children:g})]}),i&&(0,r.jsx)(d.Meter,{value:l,max:o,"aria-valuetext":`${u} of $${(0,s.formatNumberWithCommas)(o)}`,children:(0,r.jsx)(d.MeterTrack,{children:(0,r.jsx)(d.MeterIndicator,{tone:c>100?"over":c>=80?"warning":"default"})})})]})}],630500),e.i(112179),e.s([],622826)},841947,e=>{"use strict";let t=(0,e.i(475254).default)("x",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]);e.s(["default",0,t])},37727,e=>{"use strict";var t=e.i(841947);e.s(["X",()=>t.default])},409797,e=>{"use strict";var t=e.i(631171);e.s(["ChevronDownIcon",()=>t.default])},233565,e=>{"use strict";var t=e.i(246349);e.s(["ChevronRightIcon",()=>t.default])}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/01reddhq423_f.js b/litellm/proxy/_experimental/out/_next/static/chunks/01reddhq423_f.js deleted file mode 100644 index 57b711e737c..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/01reddhq423_f.js +++ /dev/null @@ -1,17 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,244451,e=>{"use strict";let t;e.i(247167);var n=e.i(271645),i=e.i(343794),o=e.i(242064),l=e.i(763731),a=e.i(174428);let r=80*Math.PI,s=e=>{let{dotClassName:t,style:o,hasCircleCls:l}=e;return n.createElement("circle",{className:(0,i.default)(`${t}-circle`,{[`${t}-circle-bg`]:l}),r:40,cx:50,cy:50,strokeWidth:20,style:o})},d=({percent:e,prefixCls:t})=>{let o=`${t}-dot`,l=`${o}-holder`,d=`${l}-hidden`,[c,u]=n.useState(!1);(0,a.default)(()=>{0!==e&&u(!0)},[0!==e]);let b=Math.max(Math.min(e,100),0);if(!c)return null;let p={strokeDashoffset:`${r/4}`,strokeDasharray:`${r*b/100} ${r*(100-b)/100}`};return n.createElement("span",{className:(0,i.default)(l,`${o}-progress`,b<=0&&d)},n.createElement("svg",{viewBox:"0 0 100 100",role:"progressbar","aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":b},n.createElement(s,{dotClassName:o,hasCircleCls:!0}),n.createElement(s,{dotClassName:o,style:p})))};function c(e){let{prefixCls:t,percent:o=0}=e,l=`${t}-dot`,a=`${l}-holder`,r=`${a}-hidden`;return n.createElement(n.Fragment,null,n.createElement("span",{className:(0,i.default)(a,o>0&&r)},n.createElement("span",{className:(0,i.default)(l,`${t}-dot-spin`)},[1,2,3,4].map(e=>n.createElement("i",{className:`${t}-dot-item`,key:e})))),n.createElement(d,{prefixCls:t,percent:o}))}function u(e){var t;let{prefixCls:o,indicator:a,percent:r}=e,s=`${o}-dot`;return a&&n.isValidElement(a)?(0,l.cloneElement)(a,{className:(0,i.default)(null==(t=a.props)?void 0:t.className,s),percent:r}):n.createElement(c,{prefixCls:o,percent:r})}e.i(296059);var b=e.i(694758),p=e.i(183293),m=e.i(246422),g=e.i(838378);let f=new b.Keyframes("antSpinMove",{to:{opacity:1}}),h=new b.Keyframes("antRotate",{to:{transform:"rotate(405deg)"}}),$=(0,m.genStyleHooks)("Spin",e=>(e=>{let{componentCls:t,calc:n}=e;return{[t]:Object.assign(Object.assign({},(0,p.resetComponent)(e)),{position:"absolute",display:"none",color:e.colorPrimary,fontSize:0,textAlign:"center",verticalAlign:"middle",opacity:0,transition:`transform ${e.motionDurationSlow} ${e.motionEaseInOutCirc}`,"&-spinning":{position:"relative",display:"inline-block",opacity:1},[`${t}-text`]:{fontSize:e.fontSize,paddingTop:n(n(e.dotSize).sub(e.fontSize)).div(2).add(2).equal()},"&-fullscreen":{position:"fixed",width:"100vw",height:"100vh",backgroundColor:e.colorBgMask,zIndex:e.zIndexPopupBase,inset:0,display:"flex",alignItems:"center",flexDirection:"column",justifyContent:"center",opacity:0,visibility:"hidden",transition:`all ${e.motionDurationMid}`,"&-show":{opacity:1,visibility:"visible"},[t]:{[`${t}-dot-holder`]:{color:e.colorWhite},[`${t}-text`]:{color:e.colorTextLightSolid}}},"&-nested-loading":{position:"relative",[`> div > ${t}`]:{position:"absolute",top:0,insetInlineStart:0,zIndex:4,display:"block",width:"100%",height:"100%",maxHeight:e.contentHeight,[`${t}-dot`]:{position:"absolute",top:"50%",insetInlineStart:"50%",margin:n(e.dotSize).mul(-1).div(2).equal()},[`${t}-text`]:{position:"absolute",top:"50%",width:"100%",textShadow:`0 1px 2px ${e.colorBgContainer}`},[`&${t}-show-text ${t}-dot`]:{marginTop:n(e.dotSize).div(2).mul(-1).sub(10).equal()},"&-sm":{[`${t}-dot`]:{margin:n(e.dotSizeSM).mul(-1).div(2).equal()},[`${t}-text`]:{paddingTop:n(n(e.dotSizeSM).sub(e.fontSize)).div(2).add(2).equal()},[`&${t}-show-text ${t}-dot`]:{marginTop:n(e.dotSizeSM).div(2).mul(-1).sub(10).equal()}},"&-lg":{[`${t}-dot`]:{margin:n(e.dotSizeLG).mul(-1).div(2).equal()},[`${t}-text`]:{paddingTop:n(n(e.dotSizeLG).sub(e.fontSize)).div(2).add(2).equal()},[`&${t}-show-text ${t}-dot`]:{marginTop:n(e.dotSizeLG).div(2).mul(-1).sub(10).equal()}}},[`${t}-container`]:{position:"relative",transition:`opacity ${e.motionDurationSlow}`,"&::after":{position:"absolute",top:0,insetInlineEnd:0,bottom:0,insetInlineStart:0,zIndex:10,width:"100%",height:"100%",background:e.colorBgContainer,opacity:0,transition:`all ${e.motionDurationSlow}`,content:'""',pointerEvents:"none"}},[`${t}-blur`]:{clear:"both",opacity:.5,userSelect:"none",pointerEvents:"none","&::after":{opacity:.4,pointerEvents:"auto"}}},"&-tip":{color:e.spinDotDefault},[`${t}-dot-holder`]:{width:"1em",height:"1em",fontSize:e.dotSize,display:"inline-block",transition:`transform ${e.motionDurationSlow} ease, opacity ${e.motionDurationSlow} ease`,transformOrigin:"50% 50%",lineHeight:1,color:e.colorPrimary,"&-hidden":{transform:"scale(0.3)",opacity:0}},[`${t}-dot-progress`]:{position:"absolute",inset:0},[`${t}-dot`]:{position:"relative",display:"inline-block",fontSize:e.dotSize,width:"1em",height:"1em","&-item":{position:"absolute",display:"block",width:n(e.dotSize).sub(n(e.marginXXS).div(2)).div(2).equal(),height:n(e.dotSize).sub(n(e.marginXXS).div(2)).div(2).equal(),background:"currentColor",borderRadius:"100%",transform:"scale(0.75)",transformOrigin:"50% 50%",opacity:.3,animationName:f,animationDuration:"1s",animationIterationCount:"infinite",animationTimingFunction:"linear",animationDirection:"alternate","&:nth-child(1)":{top:0,insetInlineStart:0,animationDelay:"0s"},"&:nth-child(2)":{top:0,insetInlineEnd:0,animationDelay:"0.4s"},"&:nth-child(3)":{insetInlineEnd:0,bottom:0,animationDelay:"0.8s"},"&:nth-child(4)":{bottom:0,insetInlineStart:0,animationDelay:"1.2s"}},"&-spin":{transform:"rotate(45deg)",animationName:h,animationDuration:"1.2s",animationIterationCount:"infinite",animationTimingFunction:"linear"},"&-circle":{strokeLinecap:"round",transition:["stroke-dashoffset","stroke-dasharray","stroke","stroke-width","opacity"].map(t=>`${t} ${e.motionDurationSlow} ease`).join(","),fillOpacity:0,stroke:"currentcolor"},"&-circle-bg":{stroke:e.colorFillSecondary}},[`&-sm ${t}-dot`]:{"&, &-holder":{fontSize:e.dotSizeSM}},[`&-sm ${t}-dot-holder`]:{i:{width:n(n(e.dotSizeSM).sub(n(e.marginXXS).div(2))).div(2).equal(),height:n(n(e.dotSizeSM).sub(n(e.marginXXS).div(2))).div(2).equal()}},[`&-lg ${t}-dot`]:{"&, &-holder":{fontSize:e.dotSizeLG}},[`&-lg ${t}-dot-holder`]:{i:{width:n(n(e.dotSizeLG).sub(e.marginXXS)).div(2).equal(),height:n(n(e.dotSizeLG).sub(e.marginXXS)).div(2).equal()}},[`&${t}-show-text ${t}-text`]:{display:"block"}})}})((0,g.mergeToken)(e,{spinDotDefault:e.colorTextDescription})),e=>{let{controlHeightLG:t,controlHeight:n}=e;return{contentHeight:400,dotSize:t/2,dotSizeSM:.35*t,dotSizeLG:n}}),v=[[30,.05],[70,.03],[96,.01]];var y=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,i=Object.getOwnPropertySymbols(e);ot.indexOf(i[o])&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(n[i[o]]=e[i[o]]);return n};let S=e=>{var l;let{prefixCls:a,spinning:r=!0,delay:s=0,className:d,rootClassName:c,size:b="default",tip:p,wrapperClassName:m,style:g,children:f,fullscreen:h=!1,indicator:S,percent:x}=e,O=y(e,["prefixCls","spinning","delay","className","rootClassName","size","tip","wrapperClassName","style","children","fullscreen","indicator","percent"]),{getPrefixCls:C,direction:k,className:w,style:j,indicator:E}=(0,o.useComponentConfig)("spin"),z=C("spin",a),[N,I,P]=$(z),[R,B]=n.useState(()=>r&&(!r||!s||!!Number.isNaN(Number(s)))),T=function(e,t){let[i,o]=n.useState(0),l=n.useRef(null),a="auto"===t;return n.useEffect(()=>(a&&e&&(o(0),l.current=setInterval(()=>{o(e=>{let t=100-e;for(let n=0;n{l.current&&(clearInterval(l.current),l.current=null)}),[a,e]),a?i:t}(R,x);n.useEffect(()=>{if(r){let e=function(e,t,n){var i,o=n||{},l=o.noTrailing,a=void 0!==l&&l,r=o.noLeading,s=void 0!==r&&r,d=o.debounceMode,c=void 0===d?void 0:d,u=!1,b=0;function p(){i&&clearTimeout(i)}function m(){for(var n=arguments.length,o=Array(n),l=0;le?s?(b=Date.now(),a||(i=setTimeout(c?g:m,e))):m():!0!==a&&(i=setTimeout(c?g:m,void 0===c?e-d:e)))}return m.cancel=function(e){var t=(e||{}).upcomingOnly;p(),u=!(void 0!==t&&t)},m}(s,()=>{B(!0)},{debounceMode:false});return e(),()=>{var t;null==(t=null==e?void 0:e.cancel)||t.call(e)}}B(!1)},[s,r]);let M=n.useMemo(()=>void 0!==f&&!h,[f,h]),D=(0,i.default)(z,w,{[`${z}-sm`]:"small"===b,[`${z}-lg`]:"large"===b,[`${z}-spinning`]:R,[`${z}-show-text`]:!!p,[`${z}-rtl`]:"rtl"===k},d,!h&&c,I,P),L=(0,i.default)(`${z}-container`,{[`${z}-blur`]:R}),H=null!=(l=null!=S?S:E)?l:t,G=Object.assign(Object.assign({},j),g),q=n.createElement("div",Object.assign({},O,{style:G,className:D,"aria-live":"polite","aria-busy":R}),n.createElement(u,{prefixCls:z,indicator:H,percent:T}),p&&(M||h)?n.createElement("div",{className:`${z}-text`},p):null);return N(M?n.createElement("div",Object.assign({},O,{className:(0,i.default)(`${z}-nested-loading`,m,I,P)}),R&&n.createElement("div",{key:"loading"},q),n.createElement("div",{className:L,key:"container"},f)):h?n.createElement("div",{className:(0,i.default)(`${z}-fullscreen`,{[`${z}-fullscreen-show`]:R},c,I,P)},q):q)};S.setDefaultIndicator=e=>{t=e},e.s(["default",0,S],244451)},175712,e=>{"use strict";e.i(247167);var t=e.i(271645),n=e.i(343794),i=e.i(529681),o=e.i(242064),l=e.i(517455),a=e.i(185793),r=e.i(721369),s=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,i=Object.getOwnPropertySymbols(e);ot.indexOf(i[o])&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(n[i[o]]=e[i[o]]);return n};let d=e=>{var{prefixCls:i,className:l,hoverable:a=!0}=e,r=s(e,["prefixCls","className","hoverable"]);let{getPrefixCls:d}=t.useContext(o.ConfigContext),c=d("card",i),u=(0,n.default)(`${c}-grid`,l,{[`${c}-grid-hoverable`]:a});return t.createElement("div",Object.assign({},r,{className:u}))};e.i(296059);var c=e.i(915654),u=e.i(183293),b=e.i(246422),p=e.i(838378);let m=(0,b.genStyleHooks)("Card",e=>{let t=(0,p.mergeToken)(e,{cardShadow:e.boxShadowCard,cardHeadPadding:e.padding,cardPaddingBase:e.paddingLG,cardActionsIconSize:e.fontSize});return[(e=>{let{componentCls:t,cardShadow:n,cardHeadPadding:i,colorBorderSecondary:o,boxShadowTertiary:l,bodyPadding:a,extraColor:r}=e;return{[t]:Object.assign(Object.assign({},(0,u.resetComponent)(e)),{position:"relative",background:e.colorBgContainer,borderRadius:e.borderRadiusLG,[`&:not(${t}-bordered)`]:{boxShadow:l},[`${t}-head`]:(e=>{let{antCls:t,componentCls:n,headerHeight:i,headerPadding:o,tabsMarginBottom:l}=e;return Object.assign(Object.assign({display:"flex",justifyContent:"center",flexDirection:"column",minHeight:i,marginBottom:-1,padding:`0 ${(0,c.unit)(o)}`,color:e.colorTextHeading,fontWeight:e.fontWeightStrong,fontSize:e.headerFontSize,background:e.headerBg,borderBottom:`${(0,c.unit)(e.lineWidth)} ${e.lineType} ${e.colorBorderSecondary}`,borderRadius:`${(0,c.unit)(e.borderRadiusLG)} ${(0,c.unit)(e.borderRadiusLG)} 0 0`},(0,u.clearFix)()),{"&-wrapper":{width:"100%",display:"flex",alignItems:"center"},"&-title":Object.assign(Object.assign({display:"inline-block",flex:1},u.textEllipsis),{[` - > ${n}-typography, - > ${n}-typography-edit-content - `]:{insetInlineStart:0,marginTop:0,marginBottom:0}}),[`${t}-tabs-top`]:{clear:"both",marginBottom:l,color:e.colorText,fontWeight:"normal",fontSize:e.fontSize,"&-bar":{borderBottom:`${(0,c.unit)(e.lineWidth)} ${e.lineType} ${e.colorBorderSecondary}`}}})})(e),[`${t}-extra`]:{marginInlineStart:"auto",color:r,fontWeight:"normal",fontSize:e.fontSize},[`${t}-body`]:{padding:a,borderRadius:`0 0 ${(0,c.unit)(e.borderRadiusLG)} ${(0,c.unit)(e.borderRadiusLG)}`},[`${t}-grid`]:(e=>{let{cardPaddingBase:t,colorBorderSecondary:n,cardShadow:i,lineWidth:o}=e;return{width:"33.33%",padding:t,border:0,borderRadius:0,boxShadow:` - ${(0,c.unit)(o)} 0 0 0 ${n}, - 0 ${(0,c.unit)(o)} 0 0 ${n}, - ${(0,c.unit)(o)} ${(0,c.unit)(o)} 0 0 ${n}, - ${(0,c.unit)(o)} 0 0 0 ${n} inset, - 0 ${(0,c.unit)(o)} 0 0 ${n} inset; - `,transition:`all ${e.motionDurationMid}`,"&-hoverable:hover":{position:"relative",zIndex:1,boxShadow:i}}})(e),[`${t}-cover`]:{"> *":{display:"block",width:"100%",borderRadius:`${(0,c.unit)(e.borderRadiusLG)} ${(0,c.unit)(e.borderRadiusLG)} 0 0`}},[`${t}-actions`]:(e=>{let{componentCls:t,iconCls:n,actionsLiMargin:i,cardActionsIconSize:o,colorBorderSecondary:l,actionsBg:a}=e;return Object.assign(Object.assign({margin:0,padding:0,listStyle:"none",background:a,borderTop:`${(0,c.unit)(e.lineWidth)} ${e.lineType} ${l}`,display:"flex",borderRadius:`0 0 ${(0,c.unit)(e.borderRadiusLG)} ${(0,c.unit)(e.borderRadiusLG)}`},(0,u.clearFix)()),{"& > li":{margin:i,color:e.colorTextDescription,textAlign:"center","> span":{position:"relative",display:"block",minWidth:e.calc(e.cardActionsIconSize).mul(2).equal(),fontSize:e.fontSize,lineHeight:e.lineHeight,cursor:"pointer","&:hover":{color:e.colorPrimary,transition:`color ${e.motionDurationMid}`},[`a:not(${t}-btn), > ${n}`]:{display:"inline-block",width:"100%",color:e.colorIcon,lineHeight:(0,c.unit)(e.fontHeight),transition:`color ${e.motionDurationMid}`,"&:hover":{color:e.colorPrimary}},[`> ${n}`]:{fontSize:o,lineHeight:(0,c.unit)(e.calc(o).mul(e.lineHeight).equal())}},"&:not(:last-child)":{borderInlineEnd:`${(0,c.unit)(e.lineWidth)} ${e.lineType} ${l}`}}})})(e),[`${t}-meta`]:Object.assign(Object.assign({margin:`${(0,c.unit)(e.calc(e.marginXXS).mul(-1).equal())} 0`,display:"flex"},(0,u.clearFix)()),{"&-avatar":{paddingInlineEnd:e.padding},"&-detail":{overflow:"hidden",flex:1,"> div:not(:last-child)":{marginBottom:e.marginXS}},"&-title":Object.assign({color:e.colorTextHeading,fontWeight:e.fontWeightStrong,fontSize:e.fontSizeLG},u.textEllipsis),"&-description":{color:e.colorTextDescription}})}),[`${t}-bordered`]:{border:`${(0,c.unit)(e.lineWidth)} ${e.lineType} ${o}`,[`${t}-cover`]:{marginTop:-1,marginInlineStart:-1,marginInlineEnd:-1}},[`${t}-hoverable`]:{cursor:"pointer",transition:`box-shadow ${e.motionDurationMid}, border-color ${e.motionDurationMid}`,"&:hover":{borderColor:"transparent",boxShadow:n}},[`${t}-contain-grid`]:{borderRadius:`${(0,c.unit)(e.borderRadiusLG)} ${(0,c.unit)(e.borderRadiusLG)} 0 0 `,[`${t}-body`]:{display:"flex",flexWrap:"wrap"},[`&:not(${t}-loading) ${t}-body`]:{marginBlockStart:e.calc(e.lineWidth).mul(-1).equal(),marginInlineStart:e.calc(e.lineWidth).mul(-1).equal(),padding:0}},[`${t}-contain-tabs`]:{[`> div${t}-head`]:{minHeight:0,[`${t}-head-title, ${t}-extra`]:{paddingTop:i}}},[`${t}-type-inner`]:(e=>{let{componentCls:t,colorFillAlter:n,headerPadding:i,bodyPadding:o}=e;return{[`${t}-head`]:{padding:`0 ${(0,c.unit)(i)}`,background:n,"&-title":{fontSize:e.fontSize}},[`${t}-body`]:{padding:`${(0,c.unit)(e.padding)} ${(0,c.unit)(o)}`}}})(e),[`${t}-loading`]:(e=>{let{componentCls:t}=e;return{overflow:"hidden",[`${t}-body`]:{userSelect:"none"}}})(e),[`${t}-rtl`]:{direction:"rtl"}}})(t),(e=>{let{componentCls:t,bodyPaddingSM:n,headerPaddingSM:i,headerHeightSM:o,headerFontSizeSM:l}=e;return{[`${t}-small`]:{[`> ${t}-head`]:{minHeight:o,padding:`0 ${(0,c.unit)(i)}`,fontSize:l,[`> ${t}-head-wrapper`]:{[`> ${t}-extra`]:{fontSize:e.fontSize}}},[`> ${t}-body`]:{padding:n}},[`${t}-small${t}-contain-tabs`]:{[`> ${t}-head`]:{[`${t}-head-title, ${t}-extra`]:{paddingTop:0,display:"flex",alignItems:"center"}}}}})(t)]},e=>{var t,n;return{headerBg:"transparent",headerFontSize:e.fontSizeLG,headerFontSizeSM:e.fontSize,headerHeight:e.fontSizeLG*e.lineHeightLG+2*e.padding,headerHeightSM:e.fontSize*e.lineHeight+2*e.paddingXS,actionsBg:e.colorBgContainer,actionsLiMargin:`${e.paddingSM}px 0`,tabsMarginBottom:-e.padding-e.lineWidth,extraColor:e.colorText,bodyPaddingSM:12,headerPaddingSM:12,bodyPadding:null!=(t=e.bodyPadding)?t:e.paddingLG,headerPadding:null!=(n=e.headerPadding)?n:e.paddingLG}});var g=e.i(792812),f=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,i=Object.getOwnPropertySymbols(e);ot.indexOf(i[o])&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(n[i[o]]=e[i[o]]);return n};let h=e=>{let{actionClasses:n,actions:i=[],actionStyle:o}=e;return t.createElement("ul",{className:n,style:o},i.map((e,n)=>{let o=`action-${n}`;return t.createElement("li",{style:{width:`${100/i.length}%`},key:o},t.createElement("span",null,e))}))},$=t.forwardRef((e,s)=>{let c,{prefixCls:u,className:b,rootClassName:p,style:$,extra:v,headStyle:y={},bodyStyle:S={},title:x,loading:O,bordered:C,variant:k,size:w,type:j,cover:E,actions:z,tabList:N,children:I,activeTabKey:P,defaultActiveTabKey:R,tabBarExtraContent:B,hoverable:T,tabProps:M={},classNames:D,styles:L}=e,H=f(e,["prefixCls","className","rootClassName","style","extra","headStyle","bodyStyle","title","loading","bordered","variant","size","type","cover","actions","tabList","children","activeTabKey","defaultActiveTabKey","tabBarExtraContent","hoverable","tabProps","classNames","styles"]),{getPrefixCls:G,direction:q,card:W}=t.useContext(o.ConfigContext),[X]=(0,g.default)("card",k,C),F=e=>{var t;return(0,n.default)(null==(t=null==W?void 0:W.classNames)?void 0:t[e],null==D?void 0:D[e])},A=e=>{var t;return Object.assign(Object.assign({},null==(t=null==W?void 0:W.styles)?void 0:t[e]),null==L?void 0:L[e])},K=t.useMemo(()=>{let e=!1;return t.Children.forEach(I,t=>{(null==t?void 0:t.type)===d&&(e=!0)}),e},[I]),_=G("card",u),[V,U,J]=m(_),Q=t.createElement(a.default,{loading:!0,active:!0,paragraph:{rows:4},title:!1},I),Y=void 0!==P,Z=Object.assign(Object.assign({},M),{[Y?"activeKey":"defaultActiveKey"]:Y?P:R,tabBarExtraContent:B}),ee=(0,l.default)(w),et=ee&&"default"!==ee?ee:"large",en=N?t.createElement(r.default,Object.assign({size:et},Z,{className:`${_}-head-tabs`,onChange:t=>{var n;null==(n=e.onTabChange)||n.call(e,t)},items:N.map(e=>{var{tab:t}=e;return Object.assign({label:t},f(e,["tab"]))})})):null;if(x||v||en){let e=(0,n.default)(`${_}-head`,F("header")),i=(0,n.default)(`${_}-head-title`,F("title")),o=(0,n.default)(`${_}-extra`,F("extra")),l=Object.assign(Object.assign({},y),A("header"));c=t.createElement("div",{className:e,style:l},t.createElement("div",{className:`${_}-head-wrapper`},x&&t.createElement("div",{className:i,style:A("title")},x),v&&t.createElement("div",{className:o,style:A("extra")},v)),en)}let ei=(0,n.default)(`${_}-cover`,F("cover")),eo=E?t.createElement("div",{className:ei,style:A("cover")},E):null,el=(0,n.default)(`${_}-body`,F("body")),ea=Object.assign(Object.assign({},S),A("body")),er=t.createElement("div",{className:el,style:ea},O?Q:I),es=(0,n.default)(`${_}-actions`,F("actions")),ed=(null==z?void 0:z.length)?t.createElement(h,{actionClasses:es,actionStyle:A("actions"),actions:z}):null,ec=(0,i.default)(H,["onTabChange"]),eu=(0,n.default)(_,null==W?void 0:W.className,{[`${_}-loading`]:O,[`${_}-bordered`]:"borderless"!==X,[`${_}-hoverable`]:T,[`${_}-contain-grid`]:K,[`${_}-contain-tabs`]:null==N?void 0:N.length,[`${_}-${ee}`]:ee,[`${_}-type-${j}`]:!!j,[`${_}-rtl`]:"rtl"===q},b,p,U,J),eb=Object.assign(Object.assign({},null==W?void 0:W.style),$);return V(t.createElement("div",Object.assign({ref:s},ec,{className:eu,style:eb}),c,eo,er,ed))});var v=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,i=Object.getOwnPropertySymbols(e);ot.indexOf(i[o])&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(n[i[o]]=e[i[o]]);return n};$.Grid=d,$.Meta=e=>{let{prefixCls:i,className:l,avatar:a,title:r,description:s}=e,d=v(e,["prefixCls","className","avatar","title","description"]),{getPrefixCls:c}=t.useContext(o.ConfigContext),u=c("card",i),b=(0,n.default)(`${u}-meta`,l),p=a?t.createElement("div",{className:`${u}-meta-avatar`},a):null,m=r?t.createElement("div",{className:`${u}-meta-title`},r):null,g=s?t.createElement("div",{className:`${u}-meta-description`},s):null,f=m||g?t.createElement("div",{className:`${u}-meta-detail`},m,g):null;return t.createElement("div",Object.assign({},d,{className:b}),p,f)},e.s(["Card",0,$],175712)},869216,e=>{"use strict";e.i(247167);var t=e.i(271645),n=e.i(343794),i=e.i(908206),o=e.i(242064),l=e.i(517455),a=e.i(150073);let r={xxl:3,xl:3,lg:3,md:3,sm:2,xs:1},s=t.default.createContext({});var d=e.i(876556),c=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,i=Object.getOwnPropertySymbols(e);ot.indexOf(i[o])&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(n[i[o]]=e[i[o]]);return n},u=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,i=Object.getOwnPropertySymbols(e);ot.indexOf(i[o])&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(n[i[o]]=e[i[o]]);return n};let b=e=>{let{itemPrefixCls:i,component:o,span:l,className:a,style:r,labelStyle:d,contentStyle:c,bordered:u,label:b,content:p,colon:m,type:g,styles:f}=e,{classNames:h}=t.useContext(s),$=Object.assign(Object.assign({},d),null==f?void 0:f.label),v=Object.assign(Object.assign({},c),null==f?void 0:f.content);if(u)return t.createElement(o,{colSpan:l,style:r,className:(0,n.default)(a,{[`${i}-item-${g}`]:"label"===g||"content"===g,[null==h?void 0:h.label]:(null==h?void 0:h.label)&&"label"===g,[null==h?void 0:h.content]:(null==h?void 0:h.content)&&"content"===g})},null!=b&&t.createElement("span",{style:$},b),null!=p&&t.createElement("span",{style:v},p));return t.createElement(o,{colSpan:l,style:r,className:(0,n.default)(`${i}-item`,a)},t.createElement("div",{className:`${i}-item-container`},null!=b&&t.createElement("span",{style:$,className:(0,n.default)(`${i}-item-label`,null==h?void 0:h.label,{[`${i}-item-no-colon`]:!m})},b),null!=p&&t.createElement("span",{style:v,className:(0,n.default)(`${i}-item-content`,null==h?void 0:h.content)},p)))};function p(e,{colon:n,prefixCls:i,bordered:o},{component:l,type:a,showLabel:r,showContent:s,labelStyle:d,contentStyle:c,styles:u}){return e.map(({label:e,children:p,prefixCls:m=i,className:g,style:f,labelStyle:h,contentStyle:$,span:v=1,key:y,styles:S},x)=>"string"==typeof l?t.createElement(b,{key:`${a}-${y||x}`,className:g,style:f,styles:{label:Object.assign(Object.assign(Object.assign(Object.assign({},d),null==u?void 0:u.label),h),null==S?void 0:S.label),content:Object.assign(Object.assign(Object.assign(Object.assign({},c),null==u?void 0:u.content),$),null==S?void 0:S.content)},span:v,colon:n,component:l,itemPrefixCls:m,bordered:o,label:r?e:null,content:s?p:null,type:a}):[t.createElement(b,{key:`label-${y||x}`,className:g,style:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},d),null==u?void 0:u.label),f),h),null==S?void 0:S.label),span:1,colon:n,component:l[0],itemPrefixCls:m,bordered:o,label:e,type:"label"}),t.createElement(b,{key:`content-${y||x}`,className:g,style:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},c),null==u?void 0:u.content),f),$),null==S?void 0:S.content),span:2*v-1,component:l[1],itemPrefixCls:m,bordered:o,content:p,type:"content"})])}let m=e=>{let n=t.useContext(s),{prefixCls:i,vertical:o,row:l,index:a,bordered:r}=e;return o?t.createElement(t.Fragment,null,t.createElement("tr",{key:`label-${a}`,className:`${i}-row`},p(l,e,Object.assign({component:"th",type:"label",showLabel:!0},n))),t.createElement("tr",{key:`content-${a}`,className:`${i}-row`},p(l,e,Object.assign({component:"td",type:"content",showContent:!0},n)))):t.createElement("tr",{key:a,className:`${i}-row`},p(l,e,Object.assign({component:r?["th","td"]:"td",type:"item",showLabel:!0,showContent:!0},n)))};e.i(296059);var g=e.i(915654),f=e.i(183293),h=e.i(246422),$=e.i(838378);let v=(0,h.genStyleHooks)("Descriptions",e=>(e=>{let{componentCls:t,extraColor:n,itemPaddingBottom:i,itemPaddingEnd:o,colonMarginRight:l,colonMarginLeft:a,titleMarginBottom:r}=e;return{[t]:Object.assign(Object.assign(Object.assign({},(0,f.resetComponent)(e)),(e=>{let{componentCls:t,labelBg:n}=e;return{[`&${t}-bordered`]:{[`> ${t}-view`]:{border:`${(0,g.unit)(e.lineWidth)} ${e.lineType} ${e.colorSplit}`,"> table":{tableLayout:"auto"},[`${t}-row`]:{borderBottom:`${(0,g.unit)(e.lineWidth)} ${e.lineType} ${e.colorSplit}`,"&:first-child":{"> th:first-child, > td:first-child":{borderStartStartRadius:e.borderRadiusLG}},"&:last-child":{borderBottom:"none","> th:first-child, > td:first-child":{borderEndStartRadius:e.borderRadiusLG}},[`> ${t}-item-label, > ${t}-item-content`]:{padding:`${(0,g.unit)(e.padding)} ${(0,g.unit)(e.paddingLG)}`,borderInlineEnd:`${(0,g.unit)(e.lineWidth)} ${e.lineType} ${e.colorSplit}`,"&:last-child":{borderInlineEnd:"none"}},[`> ${t}-item-label`]:{color:e.colorTextSecondary,backgroundColor:n,"&::after":{display:"none"}}}},[`&${t}-middle`]:{[`${t}-row`]:{[`> ${t}-item-label, > ${t}-item-content`]:{padding:`${(0,g.unit)(e.paddingSM)} ${(0,g.unit)(e.paddingLG)}`}}},[`&${t}-small`]:{[`${t}-row`]:{[`> ${t}-item-label, > ${t}-item-content`]:{padding:`${(0,g.unit)(e.paddingXS)} ${(0,g.unit)(e.padding)}`}}}}}})(e)),{"&-rtl":{direction:"rtl"},[`${t}-header`]:{display:"flex",alignItems:"center",marginBottom:r},[`${t}-title`]:Object.assign(Object.assign({},f.textEllipsis),{flex:"auto",color:e.titleColor,fontWeight:e.fontWeightStrong,fontSize:e.fontSizeLG,lineHeight:e.lineHeightLG}),[`${t}-extra`]:{marginInlineStart:"auto",color:n,fontSize:e.fontSize},[`${t}-view`]:{width:"100%",borderRadius:e.borderRadiusLG,table:{width:"100%",tableLayout:"fixed",borderCollapse:"collapse"}},[`${t}-row`]:{"> th, > td":{paddingBottom:i,paddingInlineEnd:o},"> th:last-child, > td:last-child":{paddingInlineEnd:0},"&:last-child":{borderBottom:"none","> th, > td":{paddingBottom:0}}},[`${t}-item-label`]:{color:e.labelColor,fontWeight:"normal",fontSize:e.fontSize,lineHeight:e.lineHeight,textAlign:"start","&::after":{content:'":"',position:"relative",top:-.5,marginInline:`${(0,g.unit)(a)} ${(0,g.unit)(l)}`},[`&${t}-item-no-colon::after`]:{content:'""'}},[`${t}-item-no-label`]:{"&::after":{margin:0,content:'""'}},[`${t}-item-content`]:{display:"table-cell",flex:1,color:e.contentColor,fontSize:e.fontSize,lineHeight:e.lineHeight,wordBreak:"break-word",overflowWrap:"break-word"},[`${t}-item`]:{paddingBottom:0,verticalAlign:"top","&-container":{display:"flex",[`${t}-item-label`]:{display:"inline-flex",alignItems:"baseline"},[`${t}-item-content`]:{display:"inline-flex",alignItems:"baseline",minWidth:"1em"}}},"&-middle":{[`${t}-row`]:{"> th, > td":{paddingBottom:e.paddingSM}}},"&-small":{[`${t}-row`]:{"> th, > td":{paddingBottom:e.paddingXS}}}})}})((0,$.mergeToken)(e,{})),e=>({labelBg:e.colorFillAlter,labelColor:e.colorTextTertiary,titleColor:e.colorText,titleMarginBottom:e.fontSizeSM*e.lineHeightSM,itemPaddingBottom:e.padding,itemPaddingEnd:e.padding,colonMarginRight:e.marginXS,colonMarginLeft:e.marginXXS/2,contentColor:e.colorText,extraColor:e.colorText}));var y=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,i=Object.getOwnPropertySymbols(e);ot.indexOf(i[o])&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(n[i[o]]=e[i[o]]);return n};let S=e=>{let b,{prefixCls:p,title:g,extra:f,column:h,colon:$=!0,bordered:S,layout:x,children:O,className:C,rootClassName:k,style:w,size:j,labelStyle:E,contentStyle:z,styles:N,items:I,classNames:P}=e,R=y(e,["prefixCls","title","extra","column","colon","bordered","layout","children","className","rootClassName","style","size","labelStyle","contentStyle","styles","items","classNames"]),{getPrefixCls:B,direction:T,className:M,style:D,classNames:L,styles:H}=(0,o.useComponentConfig)("descriptions"),G=B("descriptions",p),q=(0,a.default)(),W=t.useMemo(()=>{var e;return"number"==typeof h?h:null!=(e=(0,i.matchScreen)(q,Object.assign(Object.assign({},r),h)))?e:3},[q,h]),X=(b=t.useMemo(()=>I||(0,d.default)(O).map(e=>Object.assign(Object.assign({},null==e?void 0:e.props),{key:e.key})),[I,O]),t.useMemo(()=>b.map(e=>{var{span:t}=e,n=c(e,["span"]);return"filled"===t?Object.assign(Object.assign({},n),{filled:!0}):Object.assign(Object.assign({},n),{span:"number"==typeof t?t:(0,i.matchScreen)(q,t)})}),[b,q])),F=(0,l.default)(j),A=((e,n)=>{let[i,o]=(0,t.useMemo)(()=>{let t,i,o,l;return t=[],i=[],o=!1,l=0,n.filter(e=>e).forEach(n=>{let{filled:a}=n,r=u(n,["filled"]);if(a){i.push(r),t.push(i),i=[],l=0;return}let s=e-l;(l+=n.span||1)>=e?(l>e?(o=!0,i.push(Object.assign(Object.assign({},r),{span:s}))):i.push(r),t.push(i),i=[],l=0):i.push(r)}),i.length>0&&t.push(i),[t=t.map(t=>{let n=t.reduce((e,t)=>e+(t.span||1),0);if(n({labelStyle:E,contentStyle:z,styles:{content:Object.assign(Object.assign({},H.content),null==N?void 0:N.content),label:Object.assign(Object.assign({},H.label),null==N?void 0:N.label)},classNames:{label:(0,n.default)(L.label,null==P?void 0:P.label),content:(0,n.default)(L.content,null==P?void 0:P.content)}}),[E,z,N,P,L,H]);return K(t.createElement(s.Provider,{value:U},t.createElement("div",Object.assign({className:(0,n.default)(G,M,L.root,null==P?void 0:P.root,{[`${G}-${F}`]:F&&"default"!==F,[`${G}-bordered`]:!!S,[`${G}-rtl`]:"rtl"===T},C,k,_,V),style:Object.assign(Object.assign(Object.assign(Object.assign({},D),H.root),null==N?void 0:N.root),w)},R),(g||f)&&t.createElement("div",{className:(0,n.default)(`${G}-header`,L.header,null==P?void 0:P.header),style:Object.assign(Object.assign({},H.header),null==N?void 0:N.header)},g&&t.createElement("div",{className:(0,n.default)(`${G}-title`,L.title,null==P?void 0:P.title),style:Object.assign(Object.assign({},H.title),null==N?void 0:N.title)},g),f&&t.createElement("div",{className:(0,n.default)(`${G}-extra`,L.extra,null==P?void 0:P.extra),style:Object.assign(Object.assign({},H.extra),null==N?void 0:N.extra)},f)),t.createElement("div",{className:`${G}-view`},t.createElement("table",null,t.createElement("tbody",null,A.map((e,n)=>t.createElement(m,{key:n,index:n,colon:$,prefixCls:G,vertical:"vertical"===x,bordered:S,row:e}))))))))};S.Item=({children:e})=>e,e.s(["Descriptions",0,S],869216)},91874,e=>{"use strict";var t=e.i(931067),n=e.i(209428),i=e.i(211577),o=e.i(392221),l=e.i(703923),a=e.i(343794),r=e.i(914949),s=e.i(271645),d=["prefixCls","className","style","checked","disabled","defaultChecked","type","title","onChange"],c=(0,s.forwardRef)(function(e,c){var u=e.prefixCls,b=void 0===u?"rc-checkbox":u,p=e.className,m=e.style,g=e.checked,f=e.disabled,h=e.defaultChecked,$=e.type,v=void 0===$?"checkbox":$,y=e.title,S=e.onChange,x=(0,l.default)(e,d),O=(0,s.useRef)(null),C=(0,s.useRef)(null),k=(0,r.default)(void 0!==h&&h,{value:g}),w=(0,o.default)(k,2),j=w[0],E=w[1];(0,s.useImperativeHandle)(c,function(){return{focus:function(e){var t;null==(t=O.current)||t.focus(e)},blur:function(){var e;null==(e=O.current)||e.blur()},input:O.current,nativeElement:C.current}});var z=(0,a.default)(b,p,(0,i.default)((0,i.default)({},"".concat(b,"-checked"),j),"".concat(b,"-disabled"),f));return s.createElement("span",{className:z,title:y,style:m,ref:C},s.createElement("input",(0,t.default)({},x,{className:"".concat(b,"-input"),ref:O,onChange:function(t){f||("checked"in e||E(t.target.checked),null==S||S({target:(0,n.default)((0,n.default)({},e),{},{type:v,checked:t.target.checked}),stopPropagation:function(){t.stopPropagation()},preventDefault:function(){t.preventDefault()},nativeEvent:t.nativeEvent}))},disabled:f,checked:!!j,type:v})),s.createElement("span",{className:"".concat(b,"-inner")}))});e.s(["default",0,c])},681216,e=>{"use strict";var t=e.i(271645),n=e.i(963188);e.s(["default",0,function(e){let i=t.default.useRef(null),o=()=>{n.default.cancel(i.current),i.current=null};return[()=>{o(),i.current=(0,n.default)(()=>{i.current=null})},t=>{i.current&&(t.stopPropagation(),o()),null==e||e(t)}]}])},421512,236836,e=>{"use strict";let t=e.i(271645).default.createContext(null);e.s(["default",0,t],421512),e.i(296059);var n=e.i(915654),i=e.i(183293),o=e.i(246422),l=e.i(838378);function a(e,t){return(e=>{let{checkboxCls:t}=e,o=`${t}-wrapper`;return[{[`${t}-group`]:Object.assign(Object.assign({},(0,i.resetComponent)(e)),{display:"inline-flex",flexWrap:"wrap",columnGap:e.marginXS,[`> ${e.antCls}-row`]:{flex:1}}),[o]:Object.assign(Object.assign({},(0,i.resetComponent)(e)),{display:"inline-flex",alignItems:"baseline",cursor:"pointer","&:after":{display:"inline-block",width:0,overflow:"hidden",content:"'\\a0'"},[`& + ${o}`]:{marginInlineStart:0},[`&${o}-in-form-item`]:{'input[type="checkbox"]':{width:14,height:14}}}),[t]:Object.assign(Object.assign({},(0,i.resetComponent)(e)),{position:"relative",whiteSpace:"nowrap",lineHeight:1,cursor:"pointer",borderRadius:e.borderRadiusSM,alignSelf:"center",[`${t}-input`]:{position:"absolute",inset:0,zIndex:1,cursor:"pointer",opacity:0,margin:0,[`&:focus-visible + ${t}-inner`]:(0,i.genFocusOutline)(e)},[`${t}-inner`]:{boxSizing:"border-box",display:"block",width:e.checkboxSize,height:e.checkboxSize,direction:"ltr",backgroundColor:e.colorBgContainer,border:`${(0,n.unit)(e.lineWidth)} ${e.lineType} ${e.colorBorder}`,borderRadius:e.borderRadiusSM,borderCollapse:"separate",transition:`all ${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:`${(0,n.unit)(e.lineWidthBold)} solid ${e.colorWhite}`,borderTop:0,borderInlineStart:0,transform:"rotate(45deg) scale(0) translate(-50%,-50%)",opacity:0,content:'""',transition:`all ${e.motionDurationFast} ${e.motionEaseInBack}, opacity ${e.motionDurationFast}`}},"& + span":{paddingInlineStart:e.paddingXS,paddingInlineEnd:e.paddingXS}})},{[` - ${o}:not(${o}-disabled), - ${t}:not(${t}-disabled) - `]:{[`&:hover ${t}-inner`]:{borderColor:e.colorPrimary}},[`${o}:not(${o}-disabled)`]:{[`&:hover ${t}-checked:not(${t}-disabled) ${t}-inner`]:{backgroundColor:e.colorPrimaryHover,borderColor:"transparent"},[`&:hover ${t}-checked:not(${t}-disabled):after`]:{borderColor:e.colorPrimaryHover}}},{[`${t}-checked`]:{[`${t}-inner`]:{backgroundColor:e.colorPrimary,borderColor:e.colorPrimary,"&:after":{opacity:1,transform:"rotate(45deg) scale(1) translate(-50%,-50%)",transition:`all ${e.motionDurationMid} ${e.motionEaseOutBack} ${e.motionDurationFast}`}}},[` - ${o}-checked:not(${o}-disabled), - ${t}-checked:not(${t}-disabled) - `]:{[`&:hover ${t}-inner`]:{backgroundColor:e.colorPrimaryHover,borderColor:"transparent"}}},{[t]:{"&-indeterminate":{"&":{[`${t}-inner`]:{backgroundColor:`${e.colorBgContainer}`,borderColor:`${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 ${t}-inner`]:{backgroundColor:`${e.colorBgContainer}`,borderColor:`${e.colorPrimary}`}}}}},{[`${o}-disabled`]:{cursor:"not-allowed"},[`${t}-disabled`]:{[`&, ${t}-input`]:{cursor:"not-allowed",pointerEvents:"none"},[`${t}-inner`]:{background:e.colorBgContainerDisabled,borderColor:e.colorBorder,"&:after":{borderColor:e.colorTextDisabled}},"&:after":{display:"none"},"& + span":{color:e.colorTextDisabled},[`&${t}-indeterminate ${t}-inner::after`]:{background:e.colorTextDisabled}}}]})((0,l.mergeToken)(t,{checkboxCls:`.${e}`,checkboxSize:t.controlInteractiveSize}))}let r=(0,o.genStyleHooks)("Checkbox",(e,{prefixCls:t})=>[a(t,e)]);e.s(["default",0,r,"getStyle",0,a],236836)},374276,e=>{"use strict";e.i(247167);var t=e.i(271645),n=e.i(343794),i=e.i(91874),o=e.i(611935),l=e.i(121872),a=e.i(26905),r=e.i(242064),s=e.i(937328),d=e.i(321883),c=e.i(62139),u=e.i(421512),b=e.i(236836),p=e.i(681216),m=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,i=Object.getOwnPropertySymbols(e);ot.indexOf(i[o])&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(n[i[o]]=e[i[o]]);return n};let g=t.forwardRef((e,g)=>{var f;let{prefixCls:h,className:$,rootClassName:v,children:y,indeterminate:S=!1,style:x,onMouseEnter:O,onMouseLeave:C,skipGroup:k=!1,disabled:w}=e,j=m(e,["prefixCls","className","rootClassName","children","indeterminate","style","onMouseEnter","onMouseLeave","skipGroup","disabled"]),{getPrefixCls:E,direction:z,checkbox:N}=t.useContext(r.ConfigContext),I=t.useContext(u.default),{isFormItemInput:P}=t.useContext(c.FormItemInputContext),R=t.useContext(s.default),B=null!=(f=(null==I?void 0:I.disabled)||w)?f:R,T=t.useRef(j.value),M=t.useRef(null),D=(0,o.composeRef)(g,M);t.useEffect(()=>{null==I||I.registerValue(j.value)},[]),t.useEffect(()=>{if(!k)return j.value!==T.current&&(null==I||I.cancelValue(T.current),null==I||I.registerValue(j.value),T.current=j.value),()=>null==I?void 0:I.cancelValue(j.value)},[j.value]),t.useEffect(()=>{var e;(null==(e=M.current)?void 0:e.input)&&(M.current.input.indeterminate=S)},[S]);let L=E("checkbox",h),H=(0,d.default)(L),[G,q,W]=(0,b.default)(L,H),X=Object.assign({},j);I&&!k&&(X.onChange=(...e)=>{j.onChange&&j.onChange.apply(j,e),I.toggleOption&&I.toggleOption({label:y,value:j.value})},X.name=I.name,X.checked=I.value.includes(j.value));let F=(0,n.default)(`${L}-wrapper`,{[`${L}-rtl`]:"rtl"===z,[`${L}-wrapper-checked`]:X.checked,[`${L}-wrapper-disabled`]:B,[`${L}-wrapper-in-form-item`]:P},null==N?void 0:N.className,$,v,W,H,q),A=(0,n.default)({[`${L}-indeterminate`]:S},a.TARGET_CLS,q),[K,_]=(0,p.default)(X.onClick);return G(t.createElement(l.default,{component:"Checkbox",disabled:B},t.createElement("label",{className:F,style:Object.assign(Object.assign({},null==N?void 0:N.style),x),onMouseEnter:O,onMouseLeave:C,onClick:K},t.createElement(i.default,Object.assign({},X,{onClick:_,prefixCls:L,className:A,disabled:B,ref:D})),null!=y&&t.createElement("span",{className:`${L}-label`},y))))});var f=e.i(8211),h=e.i(529681),$=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,i=Object.getOwnPropertySymbols(e);ot.indexOf(i[o])&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(n[i[o]]=e[i[o]]);return n};let v=t.forwardRef((e,i)=>{let{defaultValue:o,children:l,options:a=[],prefixCls:s,className:c,rootClassName:p,style:m,onChange:v}=e,y=$(e,["defaultValue","children","options","prefixCls","className","rootClassName","style","onChange"]),{getPrefixCls:S,direction:x}=t.useContext(r.ConfigContext),[O,C]=t.useState(y.value||o||[]),[k,w]=t.useState([]);t.useEffect(()=>{"value"in y&&C(y.value||[])},[y.value]);let j=t.useMemo(()=>a.map(e=>"string"==typeof e||"number"==typeof e?{label:e,value:e}:e),[a]),E=e=>{w(t=>t.filter(t=>t!==e))},z=e=>{w(t=>[].concat((0,f.default)(t),[e]))},N=e=>{let t=O.indexOf(e.value),n=(0,f.default)(O);-1===t?n.push(e.value):n.splice(t,1),"value"in y||C(n),null==v||v(n.filter(e=>k.includes(e)).sort((e,t)=>j.findIndex(t=>t.value===e)-j.findIndex(e=>e.value===t)))},I=S("checkbox",s),P=`${I}-group`,R=(0,d.default)(I),[B,T,M]=(0,b.default)(I,R),D=(0,h.default)(y,["value","disabled"]),L=a.length?j.map(e=>t.createElement(g,{prefixCls:I,key:e.value.toString(),disabled:"disabled"in e?e.disabled:y.disabled,value:e.value,checked:O.includes(e.value),onChange:e.onChange,className:(0,n.default)(`${P}-item`,e.className),style:e.style,title:e.title,id:e.id,required:e.required},e.label)):l,H=t.useMemo(()=>({toggleOption:N,value:O,disabled:y.disabled,name:y.name,registerValue:z,cancelValue:E}),[N,O,y.disabled,y.name,z,E]),G=(0,n.default)(P,{[`${P}-rtl`]:"rtl"===x},c,p,M,R,T);return B(t.createElement("div",Object.assign({className:G,style:m},D,{ref:i}),t.createElement(u.default.Provider,{value:H},L)))});g.Group=v,g.__ANT_CHECKBOX=!0,e.s(["default",0,g],374276)},544195,e=>{"use strict";var t=e.i(271645),n=e.i(343794),i=e.i(981444),o=e.i(914949),l=e.i(244009),a=e.i(242064),r=e.i(321883),s=e.i(517455);let d=t.createContext(null),c=d.Provider,u=t.createContext(null),b=u.Provider;e.i(247167);var p=e.i(91874),m=e.i(611935),g=e.i(121872),f=e.i(26905),h=e.i(681216),$=e.i(937328),v=e.i(62139);e.i(296059);var y=e.i(915654),S=e.i(183293),x=e.i(246422),O=e.i(838378);let C=(0,x.genStyleHooks)("Radio",e=>{let{controlOutline:t,controlOutlineWidth:n}=e,i=`0 0 0 ${(0,y.unit)(n)} ${t}`,o=(0,O.mergeToken)(e,{radioFocusShadow:i,radioButtonFocusShadow:i});return[(e=>{let{componentCls:t,antCls:n}=e,i=`${t}-group`;return{[i]:Object.assign(Object.assign({},(0,S.resetComponent)(e)),{display:"inline-block",fontSize:0,[`&${i}-rtl`]:{direction:"rtl"},[`&${i}-block`]:{display:"flex"},[`${n}-badge ${n}-badge-count`]:{zIndex:1},[`> ${n}-badge:not(:first-child) > ${n}-button-wrapper`]:{borderInlineStart:"none"}})}})(o),(e=>{let{componentCls:t,wrapperMarginInlineEnd:n,colorPrimary:i,radioSize:o,motionDurationSlow:l,motionDurationMid:a,motionEaseInOutCirc:r,colorBgContainer:s,colorBorder:d,lineWidth:c,colorBgContainerDisabled:u,colorTextDisabled:b,paddingXS:p,dotColorDisabled:m,lineType:g,radioColor:f,radioBgColor:h,calc:$}=e,v=`${t}-inner`,x=$(o).sub($(4).mul(2)),O=$(1).mul(o).equal({unit:!0});return{[`${t}-wrapper`]:Object.assign(Object.assign({},(0,S.resetComponent)(e)),{display:"inline-flex",alignItems:"baseline",marginInlineStart:0,marginInlineEnd:n,cursor:"pointer","&:last-child":{marginInlineEnd:0},[`&${t}-wrapper-rtl`]:{direction:"rtl"},"&-disabled":{cursor:"not-allowed",color:e.colorTextDisabled},"&::after":{display:"inline-block",width:0,overflow:"hidden",content:'"\\a0"'},"&-block":{flex:1,justifyContent:"center"},[`${t}-checked::after`]:{position:"absolute",insetBlockStart:0,insetInlineStart:0,width:"100%",height:"100%",border:`${(0,y.unit)(c)} ${g} ${i}`,borderRadius:"50%",visibility:"hidden",opacity:0,content:'""'},[t]:Object.assign(Object.assign({},(0,S.resetComponent)(e)),{position:"relative",display:"inline-block",outline:"none",cursor:"pointer",alignSelf:"center",borderRadius:"50%"}),[`${t}-wrapper:hover &, - &:hover ${v}`]:{borderColor:i},[`${t}-input:focus-visible + ${v}`]:(0,S.genFocusOutline)(e),[`${t}:hover::after, ${t}-wrapper:hover &::after`]:{visibility:"visible"},[`${t}-inner`]:{"&::after":{boxSizing:"border-box",position:"absolute",insetBlockStart:"50%",insetInlineStart:"50%",display:"block",width:O,height:O,marginBlockStart:$(1).mul(o).div(-2).equal({unit:!0}),marginInlineStart:$(1).mul(o).div(-2).equal({unit:!0}),backgroundColor:f,borderBlockStart:0,borderInlineStart:0,borderRadius:O,transform:"scale(0)",opacity:0,transition:`all ${l} ${r}`,content:'""'},boxSizing:"border-box",position:"relative",insetBlockStart:0,insetInlineStart:0,display:"block",width:O,height:O,backgroundColor:s,borderColor:d,borderStyle:"solid",borderWidth:c,borderRadius:"50%",transition:`all ${a}`},[`${t}-input`]:{position:"absolute",inset:0,zIndex:1,cursor:"pointer",opacity:0},[`${t}-checked`]:{[v]:{borderColor:i,backgroundColor:h,"&::after":{transform:`scale(${e.calc(e.dotSize).div(o).equal()})`,opacity:1,transition:`all ${l} ${r}`}}},[`${t}-disabled`]:{cursor:"not-allowed",[v]:{backgroundColor:u,borderColor:d,cursor:"not-allowed","&::after":{backgroundColor:m}},[`${t}-input`]:{cursor:"not-allowed"},[`${t}-disabled + span`]:{color:b,cursor:"not-allowed"},[`&${t}-checked`]:{[v]:{"&::after":{transform:`scale(${$(x).div(o).equal()})`}}}},[`span${t} + *`]:{paddingInlineStart:p,paddingInlineEnd:p}})}})(o),(e=>{let{buttonColor:t,controlHeight:n,componentCls:i,lineWidth:o,lineType:l,colorBorder:a,motionDurationMid:r,buttonPaddingInline:s,fontSize:d,buttonBg:c,fontSizeLG:u,controlHeightLG:b,controlHeightSM:p,paddingXS:m,borderRadius:g,borderRadiusSM:f,borderRadiusLG:h,buttonCheckedBg:$,buttonSolidCheckedColor:v,colorTextDisabled:x,colorBgContainerDisabled:O,buttonCheckedBgDisabled:C,buttonCheckedColorDisabled:k,colorPrimary:w,colorPrimaryHover:j,colorPrimaryActive:E,buttonSolidCheckedBg:z,buttonSolidCheckedHoverBg:N,buttonSolidCheckedActiveBg:I,calc:P}=e;return{[`${i}-button-wrapper`]:{position:"relative",display:"inline-block",height:n,margin:0,paddingInline:s,paddingBlock:0,color:t,fontSize:d,lineHeight:(0,y.unit)(P(n).sub(P(o).mul(2)).equal()),background:c,border:`${(0,y.unit)(o)} ${l} ${a}`,borderBlockStartWidth:P(o).add(.02).equal(),borderInlineEndWidth:o,cursor:"pointer",transition:`color ${r},background ${r},box-shadow ${r}`,a:{color:t},[`> ${i}-button`]:{position:"absolute",insetBlockStart:0,insetInlineStart:0,zIndex:-1,width:"100%",height:"100%"},"&:not(:last-child)":{marginInlineEnd:P(o).mul(-1).equal()},"&:first-child":{borderInlineStart:`${(0,y.unit)(o)} ${l} ${a}`,borderStartStartRadius:g,borderEndStartRadius:g},"&:last-child":{borderStartEndRadius:g,borderEndEndRadius:g},"&:first-child:last-child":{borderRadius:g},[`${i}-group-large &`]:{height:b,fontSize:u,lineHeight:(0,y.unit)(P(b).sub(P(o).mul(2)).equal()),"&:first-child":{borderStartStartRadius:h,borderEndStartRadius:h},"&:last-child":{borderStartEndRadius:h,borderEndEndRadius:h}},[`${i}-group-small &`]:{height:p,paddingInline:P(m).sub(o).equal(),paddingBlock:0,lineHeight:(0,y.unit)(P(p).sub(P(o).mul(2)).equal()),"&:first-child":{borderStartStartRadius:f,borderEndStartRadius:f},"&:last-child":{borderStartEndRadius:f,borderEndEndRadius:f}},"&:hover":{position:"relative",color:w},"&:has(:focus-visible)":(0,S.genFocusOutline)(e),[`${i}-inner, input[type='checkbox'], input[type='radio']`]:{width:0,height:0,opacity:0,pointerEvents:"none"},[`&-checked:not(${i}-button-wrapper-disabled)`]:{zIndex:1,color:w,background:$,borderColor:w,"&::before":{backgroundColor:w},"&:first-child":{borderColor:w},"&:hover":{color:j,borderColor:j,"&::before":{backgroundColor:j}},"&:active":{color:E,borderColor:E,"&::before":{backgroundColor:E}}},[`${i}-group-solid &-checked:not(${i}-button-wrapper-disabled)`]:{color:v,background:z,borderColor:z,"&:hover":{color:v,background:N,borderColor:N},"&:active":{color:v,background:I,borderColor:I}},"&-disabled":{color:x,backgroundColor:O,borderColor:a,cursor:"not-allowed","&:first-child, &:hover":{color:x,backgroundColor:O,borderColor:a}},[`&-disabled${i}-button-wrapper-checked`]:{color:k,backgroundColor:C,borderColor:a,boxShadow:"none"},"&-block":{flex:1,textAlign:"center"}}}})(o)]},e=>{let{wireframe:t,padding:n,marginXS:i,lineWidth:o,fontSizeLG:l,colorText:a,colorBgContainer:r,colorTextDisabled:s,controlItemBgActiveDisabled:d,colorTextLightSolid:c,colorPrimary:u,colorPrimaryHover:b,colorPrimaryActive:p,colorWhite:m}=e;return{radioSize:l,dotSize:t?l-8:l-(4+o)*2,dotColorDisabled:s,buttonSolidCheckedColor:c,buttonSolidCheckedBg:u,buttonSolidCheckedHoverBg:b,buttonSolidCheckedActiveBg:p,buttonBg:r,buttonCheckedBg:r,buttonColor:a,buttonCheckedBgDisabled:d,buttonCheckedColorDisabled:s,buttonPaddingInline:n-o,wrapperMarginInlineEnd:i,radioColor:t?u:m,radioBgColor:t?r:u}},{unitless:{radioSize:!0,dotSize:!0}});var k=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,i=Object.getOwnPropertySymbols(e);ot.indexOf(i[o])&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(n[i[o]]=e[i[o]]);return n};let w=t.forwardRef((e,i)=>{var o,l;let s=t.useContext(d),c=t.useContext(u),{getPrefixCls:b,direction:y,radio:S}=t.useContext(a.ConfigContext),x=t.useRef(null),O=(0,m.composeRef)(i,x),{isFormItemInput:w}=t.useContext(v.FormItemInputContext),{prefixCls:j,className:E,rootClassName:z,children:N,style:I,title:P}=e,R=k(e,["prefixCls","className","rootClassName","children","style","title"]),B=b("radio",j),T="button"===((null==s?void 0:s.optionType)||c),M=T?`${B}-button`:B,D=(0,r.default)(B),[L,H,G]=C(B,D),q=Object.assign({},R),W=t.useContext($.default);s&&(q.name=s.name,q.onChange=t=>{var n,i;null==(n=e.onChange)||n.call(e,t),null==(i=null==s?void 0:s.onChange)||i.call(s,t)},q.checked=e.value===s.value,q.disabled=null!=(o=q.disabled)?o:s.disabled),q.disabled=null!=(l=q.disabled)?l:W;let X=(0,n.default)(`${M}-wrapper`,{[`${M}-wrapper-checked`]:q.checked,[`${M}-wrapper-disabled`]:q.disabled,[`${M}-wrapper-rtl`]:"rtl"===y,[`${M}-wrapper-in-form-item`]:w,[`${M}-wrapper-block`]:!!(null==s?void 0:s.block)},null==S?void 0:S.className,E,z,H,G,D),[F,A]=(0,h.default)(q.onClick);return L(t.createElement(g.default,{component:"Radio",disabled:q.disabled},t.createElement("label",{className:X,style:Object.assign(Object.assign({},null==S?void 0:S.style),I),onMouseEnter:e.onMouseEnter,onMouseLeave:e.onMouseLeave,title:P,onClick:F},t.createElement(p.default,Object.assign({},q,{className:(0,n.default)(q.className,{[f.TARGET_CLS]:!T}),type:"radio",prefixCls:M,ref:O,onClick:A})),void 0!==N?t.createElement("span",{className:`${M}-label`},N):null)))});var j=e.i(286039);let E=t.forwardRef((e,d)=>{let{getPrefixCls:u,direction:b}=t.useContext(a.ConfigContext),{name:p}=t.useContext(v.FormItemInputContext),m=(0,i.default)((0,j.toNamePathStr)(p)),{prefixCls:g,className:f,rootClassName:h,options:$,buttonStyle:y="outline",disabled:S,children:x,size:O,style:k,id:E,optionType:z,name:N=m,defaultValue:I,value:P,block:R=!1,onChange:B,onMouseEnter:T,onMouseLeave:M,onFocus:D,onBlur:L}=e,[H,G]=(0,o.default)(I,{value:P}),q=t.useCallback(t=>{let n=t.target.value;"value"in e||G(n),n!==H&&(null==B||B(t))},[H,G,B]),W=u("radio",g),X=`${W}-group`,F=(0,r.default)(W),[A,K,_]=C(W,F),V=x;$&&$.length>0&&(V=$.map(e=>"string"==typeof e||"number"==typeof e?t.createElement(w,{key:e.toString(),prefixCls:W,disabled:S,value:e,checked:H===e},e):t.createElement(w,{key:`radio-group-value-options-${e.value}`,prefixCls:W,disabled:e.disabled||S,value:e.value,checked:H===e.value,title:e.title,style:e.style,className:e.className,id:e.id,required:e.required},e.label)));let U=(0,s.default)(O),J=(0,n.default)(X,`${X}-${y}`,{[`${X}-${U}`]:U,[`${X}-rtl`]:"rtl"===b,[`${X}-block`]:R},f,h,K,_,F),Q=t.useMemo(()=>({onChange:q,value:H,disabled:S,name:N,optionType:z,block:R}),[q,H,S,N,z,R]);return A(t.createElement("div",Object.assign({},(0,l.default)(e,{aria:!0,data:!0}),{className:J,style:k,onMouseEnter:T,onMouseLeave:M,onFocus:D,onBlur:L,id:E,ref:d}),t.createElement(c,{value:Q},V)))}),z=t.memo(E);var N=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,i=Object.getOwnPropertySymbols(e);ot.indexOf(i[o])&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(n[i[o]]=e[i[o]]);return n};let I=t.forwardRef((e,n)=>{let{getPrefixCls:i}=t.useContext(a.ConfigContext),{prefixCls:o}=e,l=N(e,["prefixCls"]),r=i("radio",o);return t.createElement(b,{value:"button"},t.createElement(w,Object.assign({prefixCls:r},l,{type:"radio",ref:n})))});w.Button=I,w.Group=z,w.__ANT_RADIO=!0,e.s(["default",0,w],544195)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/01y._o853f7le.js b/litellm/proxy/_experimental/out/_next/static/chunks/01y._o853f7le.js deleted file mode 100644 index cf74c1c9c1f..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/01y._o853f7le.js +++ /dev/null @@ -1,4 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,783222,433336,80758,402155,368578,544508,746725,835696,941444,914189,394487,e=>{"use strict";let t;e.i(247167);let r=e=>e?.ownerDocument??document,n=e=>e&&"window"in e&&e.window===e?e:r(e).defaultView||window;function o(e,t){return!!t&&!!e&&e.contains(t)}function s(e){return e.target}let a=null;"u">typeof Element&&Element.prototype;let i=["input:not([disabled]):not([type=hidden])","select:not([disabled])","textarea:not([disabled])","button:not([disabled])","a[href]","area[href]","summary","iframe","object","embed","audio[controls]","video[controls]",'[contenteditable]:not([contenteditable^="false"])',"permission"];i.join(":not([hidden]),"),i.push('[tabindex]:not([tabindex="-1"]):not([disabled])'),i.join(':not([hidden]):not([tabindex="-1"]),');var l=e.i(271645);let u="u">typeof document?l.default.useLayoutEffect:()=>{};function c(e){return e.nativeEvent=e,e.isDefaultPrevented=()=>e.defaultPrevented,e.isPropagationStopped=()=>e.cancelBubble,e.persist=()=>{},e}function d(e){let t=(0,l.useRef)({isFocused:!1,observer:null});return u(()=>{let e=t.current;return()=>{e.observer&&(e.observer.disconnect(),e.observer=null)}},[]),(0,l.useCallback)(r=>{let n=s(r);(n instanceof HTMLButtonElement||n instanceof HTMLInputElement||n instanceof HTMLTextAreaElement||n instanceof HTMLSelectElement)&&(t.current.isFocused=!0,n.addEventListener("focusout",r=>{if(t.current.isFocused=!1,n.disabled){let t=c(r);e?.(t)}t.current.observer&&(t.current.observer.disconnect(),t.current.observer=null)},{once:!0}),t.current.observer=new MutationObserver(()=>{if(t.current.isFocused&&n.disabled){t.current.observer?.disconnect();let e=n===((e=document)=>e.activeElement)()?null:((e=document)=>e.activeElement)();n.dispatchEvent(new FocusEvent("blur",{relatedTarget:e})),n.dispatchEvent(new FocusEvent("focusout",{bubbles:!0,relatedTarget:e}))}}),t.current.observer.observe(n,{attributes:!0,attributeFilter:["disabled"]}))},[e])}function f(e){if("u"e.test(t.brand))||e.test(window.navigator.userAgent)}function p(e){return"u">typeof window&&null!=window.navigator&&e.test(window.navigator.userAgentData?.platform||window.navigator.platform)}function m(e){let t=null;return()=>(null==t&&(t=e()),t)}let b=m(function(){return p(/^Mac/i)}),v=m(function(){return p(/^iPhone/i)}),h=m(function(){return p(/^iPad/i)||b()&&navigator.maxTouchPoints>1}),g=m(function(){return v()||h()});m(function(){return b()||g()});let y=m(function(){return f(/AppleWebKit/i)&&!E()}),E=m(function(){return f(/Chrome/i)}),T=m(function(){return f(/Android/i)}),w=m(function(){return f(/Firefox/i)});function x(e,t,r=!0){let{metaKey:n,ctrlKey:o,altKey:s,shiftKey:i}=t;w()&&window.event?.type?.startsWith("key")&&"_blank"===e.target&&(b()?n=!0:o=!0);let l=y()&&b()&&!h()&&1?new KeyboardEvent("keydown",{keyIdentifier:"Enter",metaKey:n,ctrlKey:o,altKey:s,shiftKey:i}):new MouseEvent("click",{metaKey:n,ctrlKey:o,altKey:s,shiftKey:i,detail:1,bubbles:!0,cancelable:!0});x.isOpening=r;if(function(){if(null==a){a=!1;try{document.createElement("div").focus({get preventScroll(){return a=!0,!0}})}catch{}}return a}())e.focus({preventScroll:!0});else{let t=function(e){let t=e.parentNode,r=[],n=document.scrollingElement||document.documentElement;for(;t instanceof HTMLElement&&t!==n;)(t.offsetHeighttypeof window&&window.document&&window.document.createElement,new WeakMap;l.default.useId;let P=null,k=new Set,L=new Map,N=!1,C=!1,I={Tab:!0,Escape:!0};function S(e,t){for(let r of k)r(e,t)}function A(e){N=!0,x.isOpening||e.metaKey||!b()&&e.altKey||e.ctrlKey||"Control"===e.key||"Shift"===e.key||"Meta"===e.key||(P="keyboard",S("keyboard",e))}function M(e){P="pointer","pointerType"in e&&e.pointerType,("mousedown"===e.type||"pointerdown"===e.type)&&(N=!0,S("pointer",e))}function R(e){x.isOpening||(""!==e.pointerType||!e.isTrusted)&&(T()&&e.pointerType?"click"!==e.type||1!==e.buttons:0!==e.detail||e.pointerType)||(N=!0,P="virtual")}function O(e){let t=n(s(e)),o=r(s(e));s(e)!==t&&s(e)!==o&&e.isTrusted&&(N||C||(P="virtual",S("virtual",e)),N=!1,C=!1)}function D(){N=!1,C=!0}function H(e){if("u"typeof PointerEvent&&(o.addEventListener("pointerdown",M,!0),o.addEventListener("pointermove",M,!0),o.addEventListener("pointerup",M,!0)),t.addEventListener("beforeunload",()=>{j(e)},{once:!0}),L.set(t,{focus:s})}let j=(e,t)=>{let o=n(e),s=r(e);t&&s.removeEventListener("DOMContentLoaded",t),L.has(o)&&(o.HTMLElement.prototype.focus=L.get(o).focus,s.removeEventListener("keydown",A,!0),s.removeEventListener("keyup",A,!0),s.removeEventListener("click",R,!0),o.removeEventListener("focus",O,!0),o.removeEventListener("blur",D,!1),"u">typeof PointerEvent&&(s.removeEventListener("pointerdown",M,!0),s.removeEventListener("pointermove",M,!0),s.removeEventListener("pointerup",M,!0)),L.delete(o))};function K(){return"pointer"!==P}"u">typeof document&&("loading"!==(t=r(void 0)).readyState?H(void 0):t.addEventListener("DOMContentLoaded",()=>{H(void 0)}));let W=new Set(["checkbox","radio","range","color","file","image","button","submit","reset"]);function B(){let e=(0,l.useRef)(new Map),t=(0,l.useCallback)((t,r,n,o)=>{let s=o?.once?(...t)=>{e.current.delete(n),n(...t)}:n;e.current.set(n,{type:r,eventTarget:t,fn:s,options:o}),t.addEventListener(r,s,o)},[]),r=(0,l.useCallback)((t,r,n,o)=>{let s=e.current.get(n)?.fn||n;t.removeEventListener(r,s,o),e.current.delete(n)},[]),n=(0,l.useCallback)(()=>{e.current.forEach((e,t)=>{r(e.eventTarget,e.type,t,e.options)})},[r]);return(0,l.useEffect)(()=>n,[n]),{addGlobalListener:t,removeGlobalListener:r,removeAllGlobalListeners:n}}e.s(["useFocusRing",0,function(e={}){var t;let{autoFocus:a=!1,isTextInput:i,within:u}=e,f=(0,l.useRef)({isFocused:!1,isFocusVisible:a||K()}),[p,m]=(0,l.useState)(!1),[b,v]=(0,l.useState)(()=>f.current.isFocused&&f.current.isFocusVisible),h=(0,l.useCallback)(()=>v(f.current.isFocused&&f.current.isFocusVisible),[]),g=(0,l.useCallback)(e=>{f.current.isFocused=e,f.current.isFocusVisible=K(),m(e),h()},[h]);t={enabled:p,isTextInput:i},H(),(0,l.useEffect)(()=>{if(t?.enabled===!1)return;let e=(e,o)=>{var a;let i,l,u,c,d,p,m,b;a=!!t?.isTextInput,l=r(i=o?s(o):void 0),c=void 0!==(u=n(i))?u.HTMLInputElement:HTMLInputElement,d=void 0!==u?u.HTMLTextAreaElement:HTMLTextAreaElement,p=void 0!==u?u.HTMLElement:HTMLElement,m=void 0!==u?u.KeyboardEvent:KeyboardEvent,b=((e=document)=>e.activeElement)(l),(a=a||b instanceof c&&!W.has(b.type)||b instanceof d||b instanceof p&&b.isContentEditable)&&"keyboard"===e&&o instanceof m&&!I[o.key]||(e=>{f.current.isFocusVisible=e,h()})(K())};return k.add(e),()=>{k.delete(e)}},[i,p]);let{focusProps:y}=function(e){let{isDisabled:t,onFocus:n,onBlur:o,onFocusChange:a}=e,i=(0,l.useCallback)(e=>{if(s(e)===e.currentTarget)return o&&o(e),a&&a(!1),!0},[o,a]),u=d(i),c=(0,l.useCallback)(e=>{let t=s(e),o=r(t),i=o?((e=document)=>e.activeElement)(o):((e=document)=>e.activeElement)();t===e.currentTarget&&t===i&&(n&&n(e),a&&a(!0),u(e))},[a,n,u]);return{focusProps:{onFocus:!t&&(n||a||o)?c:void 0,onBlur:!t&&(o||a)?i:void 0}}}({isDisabled:u,onFocusChange:g}),{focusWithinProps:E}=function(e){let{isDisabled:t,onBlurWithin:n,onFocusWithin:a,onFocusWithinChange:i}=e,u=(0,l.useRef)({isFocusWithin:!1}),{addGlobalListener:f,removeAllGlobalListeners:p}=B(),m=(0,l.useCallback)(e=>{o(e.currentTarget,s(e))&&u.current.isFocusWithin&&!o(e.currentTarget,e.relatedTarget)&&(u.current.isFocusWithin=!1,p(),n&&n(e),i&&i(!1))},[n,i,u,p]),b=d(m),v=(0,l.useCallback)(e=>{if(!o(e.currentTarget,s(e)))return;let t=s(e),n=r(t),l=((e=document)=>e.activeElement)(n);if(!u.current.isFocusWithin&&l===t){a&&a(e),i&&i(!0),u.current.isFocusWithin=!0,b(e);let t=e.currentTarget;f(n,"focus",e=>{let r=s(e);if(u.current.isFocusWithin&&!o(t,r)){let e=new n.defaultView.FocusEvent("blur",{relatedTarget:r});Object.defineProperty(e,"target",{value:t}),Object.defineProperty(e,"currentTarget",{value:t}),m(c(e))}},{capture:!0})}},[a,i,b,f,m]);return t?{focusWithinProps:{onFocus:void 0,onBlur:void 0}}:{focusWithinProps:{onFocus:v,onBlur:m}}}({isDisabled:!u,onFocusWithinChange:g});return{isFocused:p,isFocusVisible:b,focusProps:u?E:y}}],783222);let V=!1,_=0;function G(e){"touch"===e.pointerType&&(V=!0,setTimeout(()=>{V=!1},500))}function U(){let e=r(null);if(void 0!==e)return 0===_&&"u">typeof PointerEvent&&e.addEventListener("pointerup",G),_++,()=>{!(--_>0)&&"u">typeof PointerEvent&&e.removeEventListener("pointerup",G)}}e.s(["useHover",0,function(e){let{onHoverStart:t,onHoverChange:n,onHoverEnd:a,isDisabled:i}=e,[u,c]=(0,l.useState)(!1),d=(0,l.useRef)({isHovered:!1,ignoreEmulatedMouseEvents:!1,pointerType:"",target:null}).current;(0,l.useEffect)(U,[]);let{addGlobalListener:f,removeAllGlobalListeners:p}=B(),{hoverProps:m,triggerHoverEnd:b}=(0,l.useMemo)(()=>{let e=(e,t)=>{let r=d.target;d.pointerType="",d.target=null,"touch"!==t&&d.isHovered&&r&&(d.isHovered=!1,p(),a&&a({type:"hoverend",target:r,pointerType:t}),n&&n(!1),c(!1))},l={};return"u">typeof PointerEvent&&(l.onPointerEnter=a=>{V&&"mouse"===a.pointerType||((a,l)=>{if(d.pointerType=l,i||"touch"===l||d.isHovered||!o(a.currentTarget,s(a)))return;d.isHovered=!0;let u=a.currentTarget;d.target=u,f(r(s(a)),"pointerover",t=>{d.isHovered&&d.target&&!o(d.target,s(t))&&e(t,t.pointerType)},{capture:!0}),t&&t({type:"hoverstart",target:u,pointerType:l}),n&&n(!0),c(!0)})(a,a.pointerType)},l.onPointerLeave=t=>{!i&&o(t.currentTarget,s(t))&&e(t,t.pointerType)}),{hoverProps:l,triggerHoverEnd:e}},[t,n,a,i,d,f,p]);return(0,l.useEffect)(()=>{i&&b({currentTarget:d.target},d.pointerType)},[i]),{hoverProps:m,isHovered:u}}],433336);var $=Object.defineProperty,q=(e,t,r)=>{let n;return(n="symbol"!=typeof t?t+"":t)in e?$(e,n,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[n]=r,r};let X=new class{constructor(){q(this,"current",this.detect()),q(this,"handoffState","pending"),q(this,"currentId",0)}set(e){this.current!==e&&(this.handoffState="pending",this.currentId=0,this.current=e)}reset(){this.set(this.detect())}nextId(){return++this.currentId}get isServer(){return"server"===this.current}get isClient(){return"client"===this.current}detect(){return"u"setTimeout(()=>{throw e}))}function Z(){let e=[],t={addEventListener:(e,r,n,o)=>(e.addEventListener(r,n,o),t.add(()=>e.removeEventListener(r,n,o))),requestAnimationFrame(...e){let r=requestAnimationFrame(...e);return t.add(()=>cancelAnimationFrame(r))},nextFrame:(...e)=>t.requestAnimationFrame(()=>t.requestAnimationFrame(...e)),setTimeout(...e){let r=setTimeout(...e);return t.add(()=>clearTimeout(r))},microTask(...e){let r={current:!0};return z(()=>{r.current&&e[0]()}),t.add(()=>{r.current=!1})},style(e,t,r){let n=e.style.getPropertyValue(t);return Object.assign(e.style,{[t]:r}),this.add(()=>{Object.assign(e.style,{[t]:n})})},group(e){let t=Z();return e(t),this.add(()=>t.dispose())},add:t=>(e.includes(t)||e.push(t),()=>{let r=e.indexOf(t);if(r>=0)for(let t of e.splice(r,1))t()}),dispose(){for(let t of e.splice(0))t()}};return t}function J(){let[e]=(0,l.useState)(Z);return(0,l.useEffect)(()=>()=>e.dispose(),[e]),e}e.s(["env",0,X],80758),e.s(["getOwnerDocument",0,Y],402155),e.s(["microTask",0,z],368578),e.s(["disposables",0,Z],544508),e.s(["useDisposables",0,J],746725);let Q=(e,t)=>{X.isServer?(0,l.useEffect)(e,t):(0,l.useLayoutEffect)(e,t)};function ee(e){let t=(0,l.useRef)(e);return Q(()=>{t.current=e},[e]),t}e.s(["useIsoMorphicEffect",0,Q],835696),e.s(["useLatestValue",0,ee],941444);let et=function(e){let t=ee(e);return l.default.useCallback((...e)=>t.current(...e),[t])};e.s(["useEvent",0,et],914189),e.s(["useActivePress",0,function({disabled:e=!1}={}){let t=(0,l.useRef)(null),[r,n]=(0,l.useState)(!1),o=J(),s=et(()=>{t.current=null,n(!1),o.dispose()}),a=et(e=>{if(o.dispose(),null===t.current){t.current=e.currentTarget,n(!0);{let r=Y(e.currentTarget);o.addEventListener(r,"pointerup",s,!1),o.addEventListener(r,"pointermove",e=>{if(t.current){var r,o;let s,a;n((s=e.width/2,a=e.height/2,r={top:e.clientY-a,right:e.clientX+s,bottom:e.clientY+a,left:e.clientX-s},o=t.current.getBoundingClientRect(),!(!r||!o||r.righto.right||r.bottomo.bottom)))}},!1),o.addEventListener(r,"pointercancel",s,!1)}}});return{pressed:r,pressProps:e?{}:{onPointerDown:a,onPointerUp:s,onClick:s}}}],394487)},397701,e=>{"use strict";e.s(["match",0,function e(t,r,...n){if(t in r){let e=r[t];return"function"==typeof e?e(...n):e}let o=Error(`Tried to handle "${t}" but there is no handler defined. Only defined handlers are: ${Object.keys(r).map(e=>`"${e}"`).join(", ")}.`);throw Error.captureStackTrace&&Error.captureStackTrace(o,e),o}])},652265,e=>{"use strict";let t,r,n,o,s;e.i(544508);var a=e.i(397701),i=e.i(402155);let l=["[contentEditable=true]","[tabindex]","a[href]","area[href]","button:not([disabled])","iframe","input:not([disabled])","select:not([disabled])","textarea:not([disabled])"].map(e=>`${e}:not([tabindex='-1'])`).join(","),u=["[data-autofocus]"].map(e=>`${e}:not([tabindex='-1'])`).join(",");var c=((t=c||{})[t.First=1]="First",t[t.Previous=2]="Previous",t[t.Next=4]="Next",t[t.Last=8]="Last",t[t.WrapAround=16]="WrapAround",t[t.NoScroll=32]="NoScroll",t[t.AutoFocus=64]="AutoFocus",t),d=((r=d||{})[r.Error=0]="Error",r[r.Overflow=1]="Overflow",r[r.Success=2]="Success",r[r.Underflow=3]="Underflow",r),f=((n=f||{})[n.Previous=-1]="Previous",n[n.Next=1]="Next",n);function p(e=document.body){return null==e?[]:Array.from(e.querySelectorAll(l)).sort((e,t)=>Math.sign((e.tabIndex||Number.MAX_SAFE_INTEGER)-(t.tabIndex||Number.MAX_SAFE_INTEGER)))}var m=((o=m||{})[o.Strict=0]="Strict",o[o.Loose=1]="Loose",o),b=((s=b||{})[s.Keyboard=0]="Keyboard",s[s.Mouse=1]="Mouse",s);function v(e,t=e=>e){return e.slice().sort((e,r)=>{let n=t(e),o=t(r);if(null===n||null===o)return 0;let s=n.compareDocumentPosition(o);return s&Node.DOCUMENT_POSITION_FOLLOWING?-1:s&Node.DOCUMENT_POSITION_PRECEDING?1:0})}function h(e,t,{sorted:r=!0,relativeTo:n=null,skipElements:o=[]}={}){var s,a,i;let l=Array.isArray(e)?e.length>0?e[0].ownerDocument:document:e.ownerDocument,c=Array.isArray(e)?r?v(e):e:64&t?function(e=document.body){return null==e?[]:Array.from(e.querySelectorAll(u)).sort((e,t)=>Math.sign((e.tabIndex||Number.MAX_SAFE_INTEGER)-(t.tabIndex||Number.MAX_SAFE_INTEGER)))}(e):p(e);o.length>0&&c.length>1&&(c=c.filter(e=>!o.some(t=>null!=t&&"current"in t?(null==t?void 0:t.current)===e:t===e))),n=null!=n?n:l.activeElement;let d=(()=>{if(5&t)return 1;if(10&t)return -1;throw Error("Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last")})(),f=(()=>{if(1&t)return 0;if(2&t)return Math.max(0,c.indexOf(n))-1;if(4&t)return Math.max(0,c.indexOf(n))+1;if(8&t)return c.length-1;throw Error("Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last")})(),m=32&t?{preventScroll:!0}:{},b=0,g=c.length,y;do{if(b>=g||b+g<=0)return 0;let e=f+b;if(16&t)e=(e+g)%g;else{if(e<0)return 3;if(e>=g)return 1}null==(y=c[e])||y.focus(m),b+=d}while(y!==l.activeElement)return 6&t&&null!=(i=null==(a=null==(s=y)?void 0:s.matches)?void 0:a.call(s,"textarea,input"))&&i&&y.select(),2}"u">typeof window&&"u">typeof document&&(document.addEventListener("keydown",e=>{e.metaKey||e.altKey||e.ctrlKey||(document.documentElement.dataset.headlessuiFocusVisible="")},!0),document.addEventListener("click",e=>{1===e.detail?delete document.documentElement.dataset.headlessuiFocusVisible:0===e.detail&&(document.documentElement.dataset.headlessuiFocusVisible="")},!0)),e.s(["Focus",0,c,"FocusResult",0,d,"FocusableMode",0,m,"focusFrom",0,function(e,t){return h(p(),t,{relativeTo:e})},"focusIn",0,h,"getFocusableElements",0,p,"isFocusableElement",0,function(e,t=0){var r;return e!==(null==(r=(0,i.getOwnerDocument)(e))?void 0:r.body)&&(0,a.match)(t,{0:()=>e.matches(l),1(){let t=e;for(;null!==t;){if(t.matches(l))return!0;t=t.parentElement}return!1}})},"sortByDomNode",0,v])},144279,294316,e=>{"use strict";var t=e.i(271645);e.s(["useResolveButtonType",0,function(e,r){return(0,t.useMemo)(()=>{var t;if(e.type)return e.type;let n=null!=(t=e.as)?t:"button";if("string"==typeof n&&"button"===n.toLowerCase()||(null==r?void 0:r.tagName)==="BUTTON"&&!r.hasAttribute("type"))return"button"},[e.type,e.as,r])}],144279);var r=e.i(914189);let n=Symbol();e.s(["optionalRef",0,function(e,t=!0){return Object.assign(e,{[n]:t})},"useSyncRefs",0,function(...e){let o=(0,t.useRef)(e);(0,t.useEffect)(()=>{o.current=e},[e]);let s=(0,r.useEvent)(e=>{for(let t of o.current)null!=t&&("function"==typeof t?t(e):t.current=e)});return e.every(e=>null==e||(null==e?void 0:e[n]))?void 0:s}],294316)},732607,e=>{"use strict";e.s(["classNames",0,function(...e){return Array.from(new Set(e.flatMap(e=>"string"==typeof e?e.split(" "):[]))).filter(Boolean).join(" ")}])},700020,e=>{"use strict";let t,r;var n=e.i(271645),o=e.i(732607),s=e.i(397701),a=((t=a||{})[t.None=0]="None",t[t.RenderStrategy=1]="RenderStrategy",t[t.Static=2]="Static",t),i=((r=i||{})[r.Unmount=0]="Unmount",r[r.Hidden=1]="Hidden",r);function l(e,t={},r,s,a){let{as:i=r,children:u,refName:p="ref",...m}=f(e,["unmount","static"]),b=void 0!==e.ref?{[p]:e.ref}:{},v="function"==typeof u?u(t):u;"className"in m&&m.className&&"function"==typeof m.className&&(m.className=m.className(t)),m["aria-labelledby"]&&m["aria-labelledby"]===m.id&&(m["aria-labelledby"]=void 0);let h={};if(t){let e=!1,r=[];for(let[n,o]of Object.entries(t))"boolean"==typeof o&&(e=!0),!0===o&&r.push(n.replace(/([A-Z])/g,e=>`-${e.toLowerCase()}`));if(e)for(let e of(h["data-headlessui-state"]=r.join(" "),r))h[`data-${e}`]=""}if(i===n.Fragment&&(Object.keys(d(m)).length>0||Object.keys(d(h)).length>0))if(!(0,n.isValidElement)(v)||Array.isArray(v)&&v.length>1){if(Object.keys(d(m)).length>0)throw Error(['Passing props on "Fragment"!',"",`The current component <${s} /> is rendering a "Fragment".`,"However we need to passthrough the following props:",Object.keys(d(m)).concat(Object.keys(d(h))).map(e=>` - ${e}`).join(` -`),"","You can apply a few solutions:",['Add an `as="..."` prop, to ensure that we render an actual element instead of a "Fragment".',"Render a single element as the child so that we can forward the props onto that element."].map(e=>` - ${e}`).join(` -`)].join(` -`))}else{var g;let e=v.props,t=null==e?void 0:e.className,r="function"==typeof t?(...e)=>(0,o.classNames)(t(...e),m.className):(0,o.classNames)(t,m.className),s=c(v.props,d(f(m,["ref"])));for(let e in h)e in s&&delete h[e];return(0,n.cloneElement)(v,Object.assign({},s,h,b,{ref:a((g=v,n.default.version.split(".")[0]>="19"?g.props.ref:g.ref),b.ref)},r?{className:r}:{}))}return(0,n.createElement)(i,Object.assign({},f(m,["ref"]),i!==n.Fragment&&b,i!==n.Fragment&&h),v)}function u(...e){return e.every(e=>null==e)?void 0:t=>{for(let r of e)null!=r&&("function"==typeof r?r(t):r.current=t)}}function c(...e){if(0===e.length)return{};if(1===e.length)return e[0];let t={},r={};for(let n of e)for(let e in n)e.startsWith("on")&&"function"==typeof n[e]?(null!=r[e]||(r[e]=[]),r[e].push(n[e])):t[e]=n[e];if(t.disabled||t["aria-disabled"])for(let e in r)/^(on(?:Click|Pointer|Mouse|Key)(?:Down|Up|Press)?)$/.test(e)&&(r[e]=[e=>{var t;return null==(t=null==e?void 0:e.preventDefault)?void 0:t.call(e)}]);for(let e in r)Object.assign(t,{[e](t,...n){for(let o of r[e]){if((t instanceof Event||(null==t?void 0:t.nativeEvent)instanceof Event)&&t.defaultPrevented)return;o(t,...n)}}});return t}function d(e){let t=Object.assign({},e);for(let e in t)void 0===t[e]&&delete t[e];return t}function f(e,t=[]){let r=Object.assign({},e);for(let e of t)e in r&&delete r[e];return r}e.s(["RenderFeatures",0,a,"RenderStrategy",0,i,"compact",0,d,"forwardRefWithAs",0,function(e){var t;return Object.assign((0,n.forwardRef)(e),{displayName:null!=(t=e.displayName)?t:e.name})},"mergeProps",0,function(...e){if(0===e.length)return{};if(1===e.length)return e[0];let t={},r={};for(let n of e)for(let e in n)e.startsWith("on")&&"function"==typeof n[e]?(null!=r[e]||(r[e]=[]),r[e].push(n[e])):t[e]=n[e];for(let e in r)Object.assign(t,{[e](...t){for(let n of r[e])null==n||n(...t)}});return t},"useRender",0,function(){let e,t,r=(e=(0,n.useRef)([]),t=(0,n.useCallback)(t=>{for(let r of e.current)null!=r&&("function"==typeof r?r(t):r.current=t)},[]),(...r)=>{if(!r.every(e=>null==e))return e.current=r,t});return(0,n.useCallback)(e=>(function({ourProps:e,theirProps:t,slot:r,defaultTag:n,features:o,visible:a=!0,name:i,mergeRefs:d}){d=null!=d?d:u;let f=c(t,e);if(a)return l(f,r,n,i,d);let p=null!=o?o:0;if(2&p){let{static:e=!1,...t}=f;if(e)return l(t,r,n,i,d)}if(1&p){let{unmount:e=!0,...t}=f;return(0,s.match)(+!e,{0:()=>null,1:()=>l({...t,hidden:!0,style:{display:"none"}},r,n,i,d)})}return l(f,r,n,i,d)})({mergeRefs:r,...e}),[r])}])},2788,e=>{"use strict";let t;var r=e.i(700020),n=((t=n||{})[t.None=1]="None",t[t.Focusable=2]="Focusable",t[t.Hidden=4]="Hidden",t);let o=(0,r.forwardRefWithAs)(function(e,t){var n;let{features:o=1,...s}=e,a={ref:t,"aria-hidden":(2&o)==2||(null!=(n=s["aria-hidden"])?n:void 0),hidden:(4&o)==4||void 0,style:{position:"fixed",top:1,left:1,width:1,height:0,padding:0,margin:-1,overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",borderWidth:"0",...(4&o)==4&&(2&o)!=2&&{display:"none"}}};return(0,r.useRender)()({ourProps:a,theirProps:s,slot:{},defaultTag:"span",name:"Hidden"})});e.s(["Hidden",0,o,"HiddenFeatures",0,n])},998348,e=>{"use strict";let t;var r=((t=r||{}).Space=" ",t.Enter="Enter",t.Escape="Escape",t.Backspace="Backspace",t.Delete="Delete",t.ArrowLeft="ArrowLeft",t.ArrowUp="ArrowUp",t.ArrowRight="ArrowRight",t.ArrowDown="ArrowDown",t.Home="Home",t.End="End",t.PageUp="PageUp",t.PageDown="PageDown",t.Tab="Tab",t);e.s(["Keys",0,r])},553521,e=>{"use strict";var t=e.i(271645),r=e.i(835696);e.s(["useIsMounted",0,function(){let e=(0,t.useRef)(!1);return(0,r.useIsoMorphicEffect)(()=>(e.current=!0,()=>{e.current=!1}),[]),e}])},751734,e=>{"use strict";let t=(0,e.i(271645).createContext)(0);e.s(["default",0,t])},144582,e=>{"use strict";let t=(0,e.i(271645).createContext)({selectedValue:void 0,handleValueChange:void 0});e.s(["default",0,t])},404206,e=>{"use strict";var t=e.i(290571),r=e.i(751734),n=e.i(144582),o=e.i(444755),s=e.i(673706),a=e.i(271645);let i=(0,s.makeClassName)("TabPanel"),l=a.default.forwardRef((e,s)=>{let{children:l,className:u}=e,c=(0,t.__rest)(e,["children","className"]),{selectedValue:d}=(0,a.useContext)(n.default),f=d===(0,a.useContext)(r.default);return a.default.createElement("div",Object.assign({ref:s,className:(0,o.tremorTwMerge)(i("root"),"w-full mt-2",f?"":"hidden",u),"aria-selected":f?"true":"false"},c),l)});l.displayName="TabPanel",e.s(["TabPanel",0,l],404206)},640497,e=>{"use strict";var t=e.i(271645),r=e.i(553521),n=e.i(2788);e.s(["FocusSentinel",0,function({onFocus:e}){let[o,s]=(0,t.useState)(!0),a=(0,r.useIsMounted)();return o?t.default.createElement(n.Hidden,{as:"button",type:"button",features:n.HiddenFeatures.Focusable,onFocus:t=>{t.preventDefault();let r,n=50;r=requestAnimationFrame(function t(){if(n--<=0){r&&cancelAnimationFrame(r);return}if(e()){if(cancelAnimationFrame(r),!a.current)return;s(!1);return}r=requestAnimationFrame(t)})}}):null}])},963703,e=>{"use strict";var t=e.i(271645);let r=t.createContext(null);e.s(["StableCollection",0,function({children:e}){let n=t.useRef({groups:new Map,get(e,t){var r;let n=this.groups.get(e);n||(n=new Map,this.groups.set(e,n));let o=null!=(r=n.get(t))?r:0;return n.set(t,o+1),[Array.from(n.keys()).indexOf(t),function(){let e=n.get(t);e>1?n.set(t,e-1):n.delete(t)}]}});return t.createElement(r.Provider,{value:n},e)},"useStableCollectionIndex",0,function(e){let n=t.useContext(r);if(!n)throw Error("You must wrap your component in a ");let o=t.useId(),[s,a]=n.current.get(e,o);return t.useEffect(()=>a,[]),s}])},970554,e=>{"use strict";let t,r,n;var o=e.i(783222),s=e.i(433336),a=e.i(271645),i=e.i(394487),l=e.i(914189),u=e.i(835696),c=e.i(941444),d=e.i(144279),f=e.i(294316),p=e.i(640497),m=e.i(2788),b=e.i(652265),v=e.i(397701),h=e.i(368578),g=e.i(402155),y=e.i(700020),E=e.i(963703),T=e.i(998348),w=((t=w||{})[t.Forwards=0]="Forwards",t[t.Backwards=1]="Backwards",t),x=((r=x||{})[r.Less=-1]="Less",r[r.Equal=0]="Equal",r[r.Greater=1]="Greater",r),F=((n=F||{})[n.SetSelectedIndex=0]="SetSelectedIndex",n[n.RegisterTab=1]="RegisterTab",n[n.UnregisterTab=2]="UnregisterTab",n[n.RegisterPanel=3]="RegisterPanel",n[n.UnregisterPanel=4]="UnregisterPanel",n);let P={0(e,t){var r;let n=(0,b.sortByDomNode)(e.tabs,e=>e.current),o=(0,b.sortByDomNode)(e.panels,e=>e.current),s=n.filter(e=>{var t;return!(null!=(t=e.current)&&t.hasAttribute("disabled"))}),a={...e,tabs:n,panels:o};if(t.index<0||t.index>n.length-1){let r=(0,v.match)(Math.sign(t.index-e.selectedIndex),{[-1]:()=>1,0:()=>(0,v.match)(Math.sign(t.index),{[-1]:()=>0,0:()=>0,1:()=>1}),1:()=>0});if(0===s.length)return a;let o=(0,v.match)(r,{0:()=>n.indexOf(s[0]),1:()=>n.indexOf(s[s.length-1])});return{...a,selectedIndex:-1===o?e.selectedIndex:o}}let i=n.slice(0,t.index),l=[...n.slice(t.index),...i].find(e=>s.includes(e));if(!l)return a;let u=null!=(r=n.indexOf(l))?r:e.selectedIndex;return -1===u&&(u=e.selectedIndex),{...a,selectedIndex:u}},1(e,t){if(e.tabs.includes(t.tab))return e;let r=e.tabs[e.selectedIndex],n=(0,b.sortByDomNode)([...e.tabs,t.tab],e=>e.current),o=e.selectedIndex;return e.info.current.isControlled||-1===(o=n.indexOf(r))&&(o=e.selectedIndex),{...e,tabs:n,selectedIndex:o}},2:(e,t)=>({...e,tabs:e.tabs.filter(e=>e!==t.tab)}),3:(e,t)=>e.panels.includes(t.panel)?e:{...e,panels:(0,b.sortByDomNode)([...e.panels,t.panel],e=>e.current)},4:(e,t)=>({...e,panels:e.panels.filter(e=>e!==t.panel)})},k=(0,a.createContext)(null);function L(e){let t=(0,a.useContext)(k);if(null===t){let t=Error(`<${e} /> is missing a parent component.`);throw Error.captureStackTrace&&Error.captureStackTrace(t,L),t}return t}k.displayName="TabsDataContext";let N=(0,a.createContext)(null);function C(e){let t=(0,a.useContext)(N);if(null===t){let t=Error(`<${e} /> is missing a parent component.`);throw Error.captureStackTrace&&Error.captureStackTrace(t,C),t}return t}function I(e,t){return(0,v.match)(t.type,P,e,t)}N.displayName="TabsActionsContext";let S=y.RenderFeatures.RenderStrategy|y.RenderFeatures.Static,A=Object.assign((0,y.forwardRefWithAs)(function(e,t){var r,n;let c=(0,a.useId)(),{id:p=`headlessui-tabs-tab-${c}`,disabled:m=!1,autoFocus:w=!1,...x}=e,{orientation:F,activation:P,selectedIndex:k,tabs:N,panels:I}=L("Tab"),S=C("Tab"),A=L("Tab"),[M,R]=(0,a.useState)(null),O=(0,a.useRef)(null),D=(0,f.useSyncRefs)(O,t,R);(0,u.useIsoMorphicEffect)(()=>S.registerTab(O),[S,O]);let H=(0,E.useStableCollectionIndex)("tabs"),j=N.indexOf(O);-1===j&&(j=H);let K=j===k,W=(0,l.useEvent)(e=>{var t;let r=e();if(r===b.FocusResult.Success&&"auto"===P){let e=null==(t=(0,g.getOwnerDocument)(O))?void 0:t.activeElement,r=A.tabs.findIndex(t=>t.current===e);-1!==r&&S.change(r)}return r}),B=(0,l.useEvent)(e=>{let t=N.map(e=>e.current).filter(Boolean);if(e.key===T.Keys.Space||e.key===T.Keys.Enter){e.preventDefault(),e.stopPropagation(),S.change(j);return}switch(e.key){case T.Keys.Home:case T.Keys.PageUp:return e.preventDefault(),e.stopPropagation(),W(()=>(0,b.focusIn)(t,b.Focus.First));case T.Keys.End:case T.Keys.PageDown:return e.preventDefault(),e.stopPropagation(),W(()=>(0,b.focusIn)(t,b.Focus.Last))}if(W(()=>(0,v.match)(F,{vertical:()=>e.key===T.Keys.ArrowUp?(0,b.focusIn)(t,b.Focus.Previous|b.Focus.WrapAround):e.key===T.Keys.ArrowDown?(0,b.focusIn)(t,b.Focus.Next|b.Focus.WrapAround):b.FocusResult.Error,horizontal:()=>e.key===T.Keys.ArrowLeft?(0,b.focusIn)(t,b.Focus.Previous|b.Focus.WrapAround):e.key===T.Keys.ArrowRight?(0,b.focusIn)(t,b.Focus.Next|b.Focus.WrapAround):b.FocusResult.Error}))===b.FocusResult.Success)return e.preventDefault()}),V=(0,a.useRef)(!1),_=(0,l.useEvent)(()=>{var e;V.current||(V.current=!0,null==(e=O.current)||e.focus({preventScroll:!0}),S.change(j),(0,h.microTask)(()=>{V.current=!1}))}),G=(0,l.useEvent)(e=>{e.preventDefault()}),{isFocusVisible:U,focusProps:$}=(0,o.useFocusRing)({autoFocus:w}),{isHovered:q,hoverProps:X}=(0,s.useHover)({isDisabled:m}),{pressed:Y,pressProps:z}=(0,i.useActivePress)({disabled:m}),Z=(0,a.useMemo)(()=>({selected:K,hover:q,active:Y,focus:U,autofocus:w,disabled:m}),[K,q,U,Y,w,m]),J=(0,y.mergeProps)({ref:D,onKeyDown:B,onMouseDown:G,onClick:_,id:p,role:"tab",type:(0,d.useResolveButtonType)(e,M),"aria-controls":null==(n=null==(r=I[j])?void 0:r.current)?void 0:n.id,"aria-selected":K,tabIndex:K?0:-1,disabled:m||void 0,autoFocus:w},$,X,z);return(0,y.useRender)()({ourProps:J,theirProps:x,slot:Z,defaultTag:"button",name:"Tabs.Tab"})}),{Group:(0,y.forwardRefWithAs)(function(e,t){let{defaultIndex:r=0,vertical:n=!1,manual:o=!1,onChange:s,selectedIndex:i=null,...d}=e,m=n?"vertical":"horizontal",v=o?"manual":"auto",h=null!==i,g=(0,c.useLatestValue)({isControlled:h}),T=(0,f.useSyncRefs)(t),[w,x]=(0,a.useReducer)(I,{info:g,selectedIndex:null!=i?i:r,tabs:[],panels:[]}),F=(0,a.useMemo)(()=>({selectedIndex:w.selectedIndex}),[w.selectedIndex]),P=(0,c.useLatestValue)(s||(()=>{})),L=(0,c.useLatestValue)(w.tabs),C=(0,a.useMemo)(()=>({orientation:m,activation:v,...w}),[m,v,w]),S=(0,l.useEvent)(e=>(x({type:1,tab:e}),()=>x({type:2,tab:e}))),A=(0,l.useEvent)(e=>(x({type:3,panel:e}),()=>x({type:4,panel:e}))),M=(0,l.useEvent)(e=>{R.current!==e&&P.current(e),h||x({type:0,index:e})}),R=(0,c.useLatestValue)(h?e.selectedIndex:w.selectedIndex),O=(0,a.useMemo)(()=>({registerTab:S,registerPanel:A,change:M}),[]);(0,u.useIsoMorphicEffect)(()=>{x({type:0,index:null!=i?i:r})},[i]),(0,u.useIsoMorphicEffect)(()=>{if(void 0===R.current||w.tabs.length<=0)return;let e=(0,b.sortByDomNode)(w.tabs,e=>e.current);e.some((e,t)=>w.tabs[t]!==e)&&M(e.indexOf(w.tabs[R.current]))});let D=(0,y.useRender)();return a.default.createElement(E.StableCollection,null,a.default.createElement(N.Provider,{value:O},a.default.createElement(k.Provider,{value:C},C.tabs.length<=0&&a.default.createElement(p.FocusSentinel,{onFocus:()=>{var e,t;for(let r of L.current)if((null==(e=r.current)?void 0:e.tabIndex)===0)return null==(t=r.current)||t.focus(),!0;return!1}}),D({ourProps:{ref:T},theirProps:d,slot:F,defaultTag:"div",name:"Tabs"}))))}),List:(0,y.forwardRefWithAs)(function(e,t){let{orientation:r,selectedIndex:n}=L("Tab.List"),o=(0,f.useSyncRefs)(t),s=(0,a.useMemo)(()=>({selectedIndex:n}),[n]);return(0,y.useRender)()({ourProps:{ref:o,role:"tablist","aria-orientation":r},theirProps:e,slot:s,defaultTag:"div",name:"Tabs.List"})}),Panels:(0,y.forwardRefWithAs)(function(e,t){let{selectedIndex:r}=L("Tab.Panels"),n=(0,f.useSyncRefs)(t),o=(0,a.useMemo)(()=>({selectedIndex:r}),[r]);return(0,y.useRender)()({ourProps:{ref:n},theirProps:e,slot:o,defaultTag:"div",name:"Tabs.Panels"})}),Panel:(0,y.forwardRefWithAs)(function(e,t){var r,n,s,i;let l=(0,a.useId)(),{id:c=`headlessui-tabs-panel-${l}`,tabIndex:d=0,...p}=e,{selectedIndex:b,tabs:v,panels:h}=L("Tab.Panel"),g=C("Tab.Panel"),T=(0,a.useRef)(null),w=(0,f.useSyncRefs)(T,t);(0,u.useIsoMorphicEffect)(()=>g.registerPanel(T),[g,T]);let x=(0,E.useStableCollectionIndex)("panels"),F=h.indexOf(T);-1===F&&(F=x);let P=F===b,{isFocusVisible:k,focusProps:N}=(0,o.useFocusRing)(),I=(0,a.useMemo)(()=>({selected:P,focus:k}),[P,k]),A=(0,y.mergeProps)({ref:w,id:c,role:"tabpanel","aria-labelledby":null==(n=null==(r=v[F])?void 0:r.current)?void 0:n.id,tabIndex:P?d:-1},N),M=(0,y.useRender)();return P||null!=(s=p.unmount)&&!s||null!=(i=p.static)&&i?M({ourProps:A,theirProps:p,slot:I,defaultTag:"div",features:S,visible:P,name:"Tabs.Panel"}):a.default.createElement(m.Hidden,{"aria-hidden":"true",...A})})});e.s(["Tab",0,A])},723731,e=>{"use strict";var t=e.i(290571),r=e.i(970554),n=e.i(751734),o=e.i(144582),s=e.i(444755),a=e.i(673706),i=e.i(271645);let l=(0,a.makeClassName)("TabPanels"),u=i.default.forwardRef((e,a)=>{let{children:u,className:c}=e,d=(0,t.__rest)(e,["children","className"]);return i.default.createElement(r.Tab.Panels,Object.assign({as:"div",ref:a,className:(0,s.tremorTwMerge)(l("root"),"w-full",c)},d),({selectedIndex:e})=>i.default.createElement(o.default.Provider,{value:{selectedValue:e}},i.default.Children.map(u,(e,t)=>i.default.createElement(n.default.Provider,{value:t},e))))});u.displayName="TabPanels",e.s(["TabPanels",0,u],723731)},653824,e=>{"use strict";var t=e.i(290571),r=e.i(970554),n=e.i(444755),o=e.i(673706),s=e.i(271645);let a=(0,o.makeClassName)("TabGroup"),i=s.default.forwardRef((e,o)=>{let{defaultIndex:i,index:l,onIndexChange:u,children:c,className:d}=e,f=(0,t.__rest)(e,["defaultIndex","index","onIndexChange","children","className"]);return s.default.createElement(r.Tab.Group,Object.assign({as:"div",ref:o,defaultIndex:i,selectedIndex:l,onChange:u,className:(0,n.tremorTwMerge)(a("root"),"w-full",d)},f),c)});i.displayName="TabGroup",e.s(["TabGroup",0,i],653824)},405371,910342,e=>{"use strict";var t=e.i(290571),r=e.i(271645),n=e.i(480731);let o=(0,r.createContext)(n.BaseColors.Blue);e.s(["default",0,o],910342);var s=e.i(970554),a=e.i(444755);let i=(0,e.i(673706).makeClassName)("TabList"),l=(0,r.createContext)("line"),u={line:(0,a.tremorTwMerge)("flex border-b space-x-4","border-tremor-border","dark:border-dark-tremor-border"),solid:(0,a.tremorTwMerge)("inline-flex p-0.5 rounded-tremor-default space-x-1.5","bg-tremor-background-subtle","dark:bg-dark-tremor-background-subtle")},c=r.default.forwardRef((e,n)=>{let{color:c,variant:d="line",children:f,className:p}=e,m=(0,t.__rest)(e,["color","variant","children","className"]);return r.default.createElement(s.Tab.List,Object.assign({ref:n,className:(0,a.tremorTwMerge)(i("root"),"justify-start overflow-x-clip",u[d],p)},m),r.default.createElement(l.Provider,{value:d},r.default.createElement(o.Provider,{value:c},f)))});c.displayName="TabList",e.s(["TabVariantContext",0,l,"default",0,c],405371)},881073,e=>{"use strict";var t=e.i(405371);e.s(["TabList",()=>t.default])},197647,e=>{"use strict";var t=e.i(290571),r=e.i(970554),n=e.i(95779),o=e.i(444755),s=e.i(673706),a=e.i(271645),i=e.i(405371),l=e.i(910342);let u=(0,s.makeClassName)("Tab"),c=a.default.forwardRef((e,c)=>{let{icon:d,className:f,children:p}=e,m=(0,t.__rest)(e,["icon","className","children"]),b=(0,a.useContext)(i.TabVariantContext),v=(0,a.useContext)(l.default);return a.default.createElement(r.Tab,Object.assign({ref:c,className:(0,o.tremorTwMerge)(u("root"),"flex whitespace-nowrap truncate max-w-xs outline-none data-focus-visible:ring text-tremor-default transition duration-100",function(e,t){switch(e){case"line":return(0,o.tremorTwMerge)("data-[selected]:border-b-2 hover:border-b-2 border-transparent transition duration-100 -mb-px px-2 py-2","hover:border-tremor-content hover:text-tremor-content-emphasis text-tremor-content","[&:not([data-selected])]:dark:hover:border-dark-tremor-content-emphasis [&:not([data-selected])]:dark:hover:text-dark-tremor-content-emphasis [&:not([data-selected])]:dark:text-dark-tremor-content",t?(0,s.getColorClassNames)(t,n.colorPalette.border).selectBorderColor:["data-[selected]:border-tremor-brand data-[selected]:text-tremor-brand","data-[selected]:dark:border-dark-tremor-brand data-[selected]:dark:text-dark-tremor-brand"]);case"solid":return(0,o.tremorTwMerge)("border-transparent border rounded-tremor-small px-2.5 py-1","data-[selected]:border-tremor-border data-[selected]:bg-tremor-background data-[selected]:shadow-tremor-input [&:not([data-selected])]:hover:text-tremor-content-emphasis data-[selected]:text-tremor-brand [&:not([data-selected])]:text-tremor-content","dark:data-[selected]:border-dark-tremor-border dark:data-[selected]:bg-dark-tremor-background dark:data-[selected]:shadow-dark-tremor-input dark:[&:not([data-selected])]:hover:text-dark-tremor-content-emphasis dark:data-[selected]:text-dark-tremor-brand dark:[&:not([data-selected])]:text-dark-tremor-content",t?(0,s.getColorClassNames)(t,n.colorPalette.text).selectTextColor:"text-tremor-content dark:text-dark-tremor-content")}}(b,v),f,v&&(0,s.getColorClassNames)(v,n.colorPalette.text).selectTextColor)},m),d?a.default.createElement(d,{className:(0,o.tremorTwMerge)(u("icon"),"flex-none h-5 w-5",p?"mr-2":"")}):null,p?a.default.createElement("span",null,p):null)});c.displayName="Tab",e.s(["Tab",0,c],197647)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/01yk5y7rumzgt.js b/litellm/proxy/_experimental/out/_next/static/chunks/01yk5y7rumzgt.js deleted file mode 100644 index 6ba020fbb62..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/01yk5y7rumzgt.js +++ /dev/null @@ -1 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,841947,e=>{"use strict";let t=(0,e.i(475254).default)("x",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]);e.s(["default",0,t])},37727,e=>{"use strict";var t=e.i(841947);e.s(["X",()=>t.default])},409797,e=>{"use strict";var t=e.i(631171);e.s(["ChevronDownIcon",()=>t.default])},233565,e=>{"use strict";var t=e.i(246349);e.s(["ChevronRightIcon",()=>t.default])},678784,e=>{"use strict";var t=e.i(678745);e.s(["CheckIcon",()=>t.default])},590803,e=>{"use strict";e.s(["isElementDisabled",0,function(e){return null==e||e.hasAttribute("disabled")||"true"===e.getAttribute("aria-disabled")}])},545356,e=>{"use strict";var t=e.i(271645);let o=t.createContext({register:()=>{},unregister:()=>{},subscribeMapChange:()=>()=>{},elementsRef:{current:[]},nextIndexRef:{current:0}});e.s(["CompositeListContext",0,o,"useCompositeListContext",0,function(){return t.useContext(o)}])},53687,e=>{"use strict";var t=e.i(271645),o=e.i(921374),n=e.i(667865),a=e.i(146376),r=e.i(545356),i=e.i(843476);function s(){return new Map}function l(){return new Set}function u(e,t){let o=e.compareDocumentPosition(t);return o&Node.DOCUMENT_POSITION_FOLLOWING||o&Node.DOCUMENT_POSITION_CONTAINED_BY?-1:o&Node.DOCUMENT_POSITION_PRECEDING||o&Node.DOCUMENT_POSITION_CONTAINS?1:0}e.s(["CompositeList",0,function(e){let{children:d,elementsRef:c,labelsRef:p,onMapChange:f}=e,g=(0,n.useStableCallback)(f),m=t.useRef(0),b=(0,o.useRefWithInit)(l).current,v=(0,o.useRefWithInit)(s).current,[C,x]=t.useState(0),h=t.useRef(C),S=(0,n.useStableCallback)((e,t)=>{v.set(e,t??null),h.current+=1,x(h.current)}),D=(0,n.useStableCallback)(e=>{v.delete(e),h.current+=1,x(h.current)}),R=t.useMemo(()=>{let e=new Map;return Array.from(v.keys()).filter(e=>e.isConnected).sort(u).forEach((t,o)=>{let n=v.get(t)??{};e.set(t,{...n,index:o})}),e},[v,C]);(0,a.useIsoLayoutEffect)(()=>{if("function"!=typeof MutationObserver||0===R.size)return;let e=new MutationObserver(e=>{let t=new Set,o=e=>t.has(e)?t.delete(e):t.add(e);e.forEach(e=>{e.removedNodes.forEach(o),e.addedNodes.forEach(o)}),0===t.size&&(h.current+=1,x(h.current))});return R.forEach((t,o)=>{o.parentElement&&e.observe(o.parentElement,{childList:!0})}),()=>{e.disconnect()}},[R]),(0,a.useIsoLayoutEffect)(()=>{h.current===C&&(c.current.length!==R.size&&(c.current.length=R.size),p&&p.current.length!==R.size&&(p.current.length=R.size),m.current=R.size),g(R)},[g,R,c,p,C]),(0,a.useIsoLayoutEffect)(()=>()=>{c.current=[]},[c]),(0,a.useIsoLayoutEffect)(()=>()=>{p&&(p.current=[])},[p]);let w=(0,n.useStableCallback)(e=>(b.add(e),()=>{b.delete(e)}));(0,a.useIsoLayoutEffect)(()=>{b.forEach(e=>e(R))},[b,R]);let y=t.useMemo(()=>({register:S,unregister:D,subscribeMapChange:w,elementsRef:c,labelsRef:p,nextIndexRef:m}),[S,D,w,c,p,m]);return(0,i.jsx)(r.CompositeListContext.Provider,{value:y,children:d})}])},673553,e=>{"use strict";var t,o=e.i(271645),n=e.i(146376),a=e.i(545356);let r=((t={})[t.None=0]="None",t[t.GuessFromOrder=1]="GuessFromOrder",t);e.s(["IndexGuessBehavior",0,r,"useCompositeListItem",0,function(e={}){let{label:t,metadata:i,textRef:s,indexGuessBehavior:l,index:u}=e,{register:d,unregister:c,subscribeMapChange:p,elementsRef:f,labelsRef:g,nextIndexRef:m}=(0,a.useCompositeListContext)(),b=o.useRef(-1),[v,C]=o.useState(u??(l===r.GuessFromOrder?()=>{if(-1===b.current){let e=m.current;m.current+=1,b.current=e}return b.current}:-1)),x=o.useRef(null),h=o.useCallback(e=>{if(x.current=e,-1!==v&&null!==e&&(f.current[v]=e,g)){let o=void 0!==t;g.current[v]=o?t:s?.current?.textContent??e.textContent}},[v,f,g,t,s]);return(0,n.useIsoLayoutEffect)(()=>{if(null!=u)return;let e=x.current;if(e)return d(e,i),()=>{c(e)}},[u,d,c,i]),(0,n.useIsoLayoutEffect)(()=>{if(null==u)return p(e=>{let t=x.current?e.get(x.current)?.index:null;null!=t&&C(t)})},[u,p,C]),{ref:h,index:v}}])},395530,e=>{"use strict";var t=e.i(271645),o=e.i(828918),n=e.i(838452),a=e.i(673553);e.s(["useCompositeItem",0,function(e={}){let{highlightItemOnHover:r,highlightedIndex:i,onHighlightedIndexChange:s}=(0,n.useCompositeRootContext)(),{ref:l,index:u}=(0,a.useCompositeListItem)(e),d=i===u,c=t.useRef(null),p=(0,o.useMergedRefs)(l,c);return{compositeProps:{tabIndex:d?0:-1,onFocus(){s(u)},onMouseMove(){let e=c.current;if(!r||!e)return;let t=e.hasAttribute("disabled")||"true"===e.ariaDisabled;d||t||e.focus()}},compositeRef:p,index:u}}])},784774,e=>{"use strict";var t=e.i(843476),o=e.i(271645),n=e.i(115504);let a=o.forwardRef(({className:e,...o},a)=>(0,t.jsx)("div",{"data-slot":"table-container",className:"relative w-full overflow-x-auto",children:(0,t.jsx)("table",{ref:a,"data-slot":"table",className:(0,n.cn)("w-full caption-bottom text-sm",e),...o})}));a.displayName="Table";let r=o.forwardRef(({className:e,...o},a)=>(0,t.jsx)("thead",{ref:a,"data-slot":"table-header",className:(0,n.cn)("[&_tr]:border-b",e),...o}));r.displayName="TableHeader";let i=o.forwardRef(({className:e,...o},a)=>(0,t.jsx)("tbody",{ref:a,"data-slot":"table-body",className:(0,n.cn)("[&_tr:last-child]:border-0",e),...o}));i.displayName="TableBody";let s=o.forwardRef(({className:e,...o},a)=>(0,t.jsx)("tfoot",{ref:a,"data-slot":"table-footer",className:(0,n.cn)("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",e),...o}));s.displayName="TableFooter";let l=o.forwardRef(({className:e,...o},a)=>(0,t.jsx)("tr",{ref:a,"data-slot":"table-row",className:(0,n.cn)("border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",e),...o}));l.displayName="TableRow";let u=o.forwardRef(({className:e,...o},a)=>(0,t.jsx)("th",{ref:a,"data-slot":"table-head",className:(0,n.cn)("h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",e),...o}));u.displayName="TableHead";let d=o.forwardRef(({className:e,...o},a)=>(0,t.jsx)("td",{ref:a,"data-slot":"table-cell",className:(0,n.cn)("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",e),...o}));d.displayName="TableCell",o.forwardRef(({className:e,...o},a)=>(0,t.jsx)("caption",{ref:a,"data-slot":"table-caption",className:(0,n.cn)("mt-4 text-sm text-muted-foreground",e),...o})).displayName="TableCaption",e.s(["Table",0,a,"TableBody",0,i,"TableCell",0,d,"TableFooter",0,s,"TableHead",0,u,"TableHeader",0,r,"TableRow",0,l])},302747,e=>{"use strict";var t=e.i(843476),o=e.i(271645),n=e.i(115504);let a=o.forwardRef(({className:e,...o},a)=>(0,t.jsx)("div",{ref:a,"data-slot":"skeleton",className:(0,n.cn)("animate-pulse rounded-md bg-accent",e),...o}));a.displayName="Skeleton",e.s(["Skeleton",0,a])},108821,e=>{"use strict";var t=e.i(733332),o=e.i(271645);let n=o.createContext(!1),a=o.createContext(void 0);e.s(["DialogRootContext",0,a,"IsDrawerContext",0,n,"useDialogRootContext",0,function(e){let n=o.useContext(a);if(!1===e&&void 0===n)throw Error((0,t.default)(27));return n}])},402820,156736,209793,625834,784324,264951,e=>{"use strict";e.i(247167);var t,o,n=e.i(271645),a=e.i(108821),r=e.i(552245),i=e.i(405005),s=e.i(209407);let l={...i.popupStateMapping,...s.transitionStatusMapping},u=n.forwardRef(function(e,t){let{render:o,className:n,style:i,forceRender:s=!1,...u}=e,{store:d}=(0,a.useDialogRootContext)(),c=d.useState("open"),p=d.useState("nested"),f=d.useState("mounted"),g=d.useState("transitionStatus");return(0,r.useRenderElement)("div",e,{state:{open:c,transitionStatus:g},ref:[d.context.backdropRef,t],stateAttributesMapping:l,props:[{role:"presentation",hidden:!f,style:{userSelect:"none",WebkitUserSelect:"none"}},u],enabled:s||!p})});e.s(["DialogBackdrop",0,u],402820);var d=e.i(540886),c=e.i(675606),p=e.i(56434);let f=n.forwardRef(function(e,t){let{render:o,className:n,style:i,disabled:s=!1,nativeButton:l=!0,...u}=e,{store:f}=(0,a.useDialogRootContext)(),g=f.useState("open"),{getButtonProps:m,buttonRef:b}=(0,d.useButton)({disabled:s,native:l});return(0,r.useRenderElement)("button",e,{state:{disabled:s},ref:[t,b],props:[{onClick:function(e){g&&f.setOpen(!1,(0,c.createChangeEventDetails)(p.REASONS.closePress,e.nativeEvent))}},u,m]})});e.s(["DialogClose",0,f],156736);var g=e.i(788015);let m=n.forwardRef(function(e,t){let{render:o,className:n,style:i,id:s,...l}=e,{store:u}=(0,a.useDialogRootContext)(),d=(0,g.useBaseUiId)(s);return u.useSyncedValueWithCleanup("descriptionElementId",d),(0,r.useRenderElement)("p",e,{ref:t,props:[{id:d},l]})});e.s(["DialogDescription",0,m],209793);var b=e.i(61487);let v=((t={}).nestedDialogs="--nested-dialogs",t),C=((o={})[o.open=i.CommonPopupDataAttributes.open]="open",o[o.closed=i.CommonPopupDataAttributes.closed]="closed",o[o.startingStyle=i.CommonPopupDataAttributes.startingStyle]="startingStyle",o[o.endingStyle=i.CommonPopupDataAttributes.endingStyle]="endingStyle",o.nested="data-nested",o.nestedDialogOpen="data-nested-dialog-open",o);var x=e.i(733332);let h=n.createContext(void 0);function S(){let e=n.useContext(h);if(void 0===e)throw Error((0,x.default)(26));return e}e.s(["DialogPortalContext",0,h,"useDialogPortalContext",0,S],625834);var D=e.i(137584),R=e.i(673327),w=e.i(264111),y=e.i(843476);let O={...i.popupStateMapping,...s.transitionStatusMapping,nestedDialogOpen:e=>e?{[C.nestedDialogOpen]:""}:null},E=n.forwardRef(function(e,t){let{render:o,className:n,style:i,finalFocus:s,initialFocus:l,...u}=e,{store:d}=(0,a.useDialogRootContext)(),c=d.useState("descriptionElementId"),p=d.useState("disablePointerDismissal"),f=d.useState("floatingRootContext"),g=d.useState("popupProps"),m=d.useState("modal"),C=d.useState("mounted"),x=d.useState("nested"),h=d.useState("nestedOpenDialogCount"),E=d.useState("open"),I=d.useState("openMethod"),P=d.useState("titleElementId"),N=d.useState("transitionStatus"),T=d.useState("role"),M=f.useState("floatingId"),k=u.id??M;S(),(0,D.useOpenChangeComplete)({open:E,ref:d.context.popupRef,onComplete(){E&&d.context.onOpenChangeComplete?.(!0)}});let A=void 0===l?(0,w.createDefaultInitialFocus)(d.context.popupRef):l,j=d.useStateSetter("popupElement"),B=(0,r.useRenderElement)("div",e,{state:{open:E,nested:x,transitionStatus:N,nestedDialogOpen:h>0},props:[g,{id:k,"aria-labelledby":P??void 0,"aria-describedby":c??void 0,role:T,...w.FOCUSABLE_POPUP_PROPS,hidden:!C,onKeyDown(e){R.COMPOSITE_KEYS.has(e.key)&&e.stopPropagation()},style:{[v.nestedDialogs]:h}},u],ref:[t,d.context.popupRef,j],stateAttributesMapping:O});return(0,y.jsx)(b.FloatingFocusManager,{context:f,openInteractionType:I,disabled:!C,closeOnFocusOut:!p,initialFocus:A,returnFocus:s,modal:!1!==m,restoreFocus:"popup",children:B})});e.s(["DialogPopup",0,E],784324);var I=e.i(144394),P=e.i(726674),N=e.i(426);let T=n.forwardRef(function(e,t){let{keepMounted:o=!1,...n}=e,{store:r}=(0,a.useDialogRootContext)(),i=r.useState("mounted"),s=r.useState("modal"),l=r.useState("open");return i||o?(0,y.jsx)(h.Provider,{value:o,children:(0,y.jsxs)(P.FloatingPortal,{ref:t,...n,children:[i&&!0===s&&(0,y.jsx)(N.InternalBackdrop,{ref:r.context.internalBackdropRef,inert:(0,I.inertValue)(!l)}),e.children]})}):null});e.s(["DialogPortal",0,T],264951)},67530,e=>{"use strict";var t=e.i(271645),o=e.i(145484),n=e.i(956789),a=e.i(17989),r=e.i(647554),i=e.i(675606),s=e.i(56434),l=e.i(264111);e.s(["DialogInteractions",0,function({store:e,parentContext:i,isDrawer:s}){let u=e.useState("open"),d=e.useState("disablePointerDismissal"),c=e.useState("modal"),p=e.useState("popupElement"),f=e.useState("floatingRootContext"),[g,m]=t.useState(0),[b,v]=t.useState(0),C=0===g,x=(0,a.useDismiss)(f,{outsidePressEvent:()=>e.context.internalBackdropRef.current||e.context.backdropRef.current?"intentional":{mouse:"trap-focus"===c?"sloppy":"intentional",touch:"sloppy"},outsidePress(t){if(!e.context.outsidePressEnabledRef.current||"button"in t&&0!==t.button||"touches"in t&&1!==t.touches.length)return!1;let o=(0,r.getTarget)(t);return!!C&&!d&&(!c||!e.context.internalBackdropRef.current&&!e.context.backdropRef.current||e.context.internalBackdropRef.current===o||e.context.backdropRef.current===o||(0,r.contains)(o,p)&&!o?.hasAttribute("data-base-ui-portal"))},escapeKey:C});(0,o.useScrollLock)(u&&!0===c,p),e.useContextCallback("onNestedDialogOpen",(e,t)=>{m(e),v(t)}),e.useContextCallback("onNestedDialogClose",()=>{m(0),v(0)}),t.useEffect(()=>(i?.onNestedDialogOpen&&u&&i.onNestedDialogOpen(g+1,b+ +!!s),i?.onNestedDialogClose&&!u&&i.onNestedDialogClose(),()=>{i?.onNestedDialogClose&&u&&i.onNestedDialogClose()}),[s,u,g,b,i]);let h=x.reference??n.EMPTY_OBJECT,S=x.trigger??n.EMPTY_OBJECT,D=x.floating??n.EMPTY_OBJECT;return(0,l.usePopupInteractionProps)(e,{activeTriggerProps:h,inactiveTriggerProps:S,popupProps:D,nestedOpenDialogCount:g,nestedOpenDrawerCount:b}),null},"useDialogRoot",0,function(e){let{store:o,actionsRef:n}=e,a=o.useState("open");(0,l.usePopupRootSync)(o,a),(0,l.useImplicitActiveTrigger)(o);let{forceUnmount:r}=(0,l.useOpenStateTransitions)(a,o),u=t.useCallback(()=>{o.setOpen(!1,(0,i.createChangeEventDetails)(s.REASONS.imperativeAction))},[o]);t.useImperativeHandle(n,()=>({unmount:r,close:u}),[r,u])}])},366250,301807,e=>{"use strict";var t=e.i(271645),o=e.i(713203),n=e.i(67530),a=e.i(108821),r=e.i(616269),i=e.i(301252),s=e.i(116786),l=e.i(990627),u=e.i(264111);let d={...s.popupStoreSelectors,modal:(0,r.createSelector)(e=>e.modal),nested:(0,r.createSelector)(e=>e.nested),nestedOpenDialogCount:(0,r.createSelector)(e=>e.nestedOpenDialogCount),nestedOpenDrawerCount:(0,r.createSelector)(e=>e.nestedOpenDrawerCount),disablePointerDismissal:(0,r.createSelector)(e=>e.disablePointerDismissal),openMethod:(0,r.createSelector)(e=>e.openMethod),descriptionElementId:(0,r.createSelector)(e=>e.descriptionElementId),titleElementId:(0,r.createSelector)(e=>e.titleElementId),viewportElement:(0,r.createSelector)(e=>e.viewportElement),role:(0,r.createSelector)(e=>e.role)};class c extends i.ReactStore{constructor(e,o,n=!1){const a=new l.PopupTriggerMap,r=function(e={}){return{...(0,s.createInitialPopupStoreState)(),modal:!0,disablePointerDismissal:!1,popupElement:null,viewportElement:null,descriptionElementId:void 0,titleElementId:void 0,openMethod:null,nested:!1,nestedOpenDialogCount:0,nestedOpenDrawerCount:0,role:"dialog",...e}}(e);r.floatingRootContext=(0,s.createPopupFloatingRootContext)(a,o,n),super(r,{popupRef:t.createRef(),backdropRef:t.createRef(),internalBackdropRef:t.createRef(),outsidePressEnabledRef:{current:!0},triggerElements:a,onOpenChange:void 0,onOpenChangeComplete:void 0},d)}setOpen=(e,t)=>{if(t.preventUnmountOnClose=()=>{this.set("preventUnmountingOnClose",!0)},e||null!=t.trigger||null==this.state.activeTriggerId||(t.trigger=this.state.activeTriggerElement??void 0),this.context.onOpenChange?.(e,t),t.isCanceled)return;this.state.floatingRootContext.dispatchOpenChange(e,t);let o={open:e};(0,u.setPopupOpenState)(o,e,t.trigger),this.update(o)};static useStore(e,t){return(0,u.usePopupStore)(e,(e,o)=>new c(t,e,o),!0).store}}e.s(["DialogStore",0,c],301807);var p=e.i(843476);e.s(["useRenderDialogRoot",0,function(e,r="dialog"){let{children:i,open:s,defaultOpen:l=!1,onOpenChange:u,onOpenChangeComplete:d,disablePointerDismissal:f=!1,modal:g=!0,actionsRef:m,handle:b,triggerId:v,defaultTriggerId:C=null}=e,x="alert-dialog"===r,h=(0,a.useDialogRootContext)(!0),S={modal:!!x||g,disablePointerDismissal:x||f,nested:!!h,role:x?"alertdialog":"dialog"},D=c.useStore(b?.store,{open:l,openProp:s,activeTriggerId:C,triggerIdProp:v,...S});(0,o.useOnFirstRender)(()=>{let e=void 0===s&&!1===D.state.open&&!0===l?{open:!0,activeTriggerId:C}:null;x?D.update(e?{...S,...e}:S):e&&D.update(e)}),D.useControlledProp("openProp",s),D.useControlledProp("triggerIdProp",v),D.useSyncedValues(S),D.useContextCallback("onOpenChange",u),D.useContextCallback("onOpenChangeComplete",d);let R=D.useState("open"),w=D.useState("mounted"),y=D.useState("payload");(0,n.useDialogRoot)({store:D,actionsRef:m});let O=t.useMemo(()=>({store:D}),[D]);return(0,p.jsx)(a.IsDrawerContext.Provider,{value:!1,children:(0,p.jsxs)(a.DialogRootContext.Provider,{value:O,children:[(R||w)&&(0,p.jsx)(n.DialogInteractions,{store:D,parentContext:h?.store.context,isDrawer:"drawer"===r}),"function"==typeof i?i({payload:y}):i]})})}],366250)},974217,e=>{"use strict";e.i(247167);var t,o=e.i(271645),n=e.i(552245),a=e.i(405005),r=e.i(209407),i=e.i(108821),s=e.i(625834);let l=((t={})[t.open=a.CommonPopupDataAttributes.open]="open",t[t.closed=a.CommonPopupDataAttributes.closed]="closed",t[t.startingStyle=a.CommonPopupDataAttributes.startingStyle]="startingStyle",t[t.endingStyle=a.CommonPopupDataAttributes.endingStyle]="endingStyle",t.nested="data-nested",t.nestedDialogOpen="data-nested-dialog-open",t),u={...a.popupStateMapping,...r.transitionStatusMapping,nested:e=>e?{[l.nested]:""}:null,nestedDialogOpen:e=>e?{[l.nestedDialogOpen]:""}:null},d=o.forwardRef(function(e,t){let{render:o,className:a,style:r,children:l,...d}=e,c=(0,s.useDialogPortalContext)(),{store:p}=(0,i.useDialogRootContext)(),f=p.useState("open"),g=p.useState("nested"),m=p.useState("transitionStatus"),b=p.useState("nestedOpenDialogCount"),v=p.useState("mounted"),C=p.useStateSetter("viewportElement");return(0,n.useRenderElement)("div",e,{enabled:c||v,state:{open:f,nested:g,transitionStatus:m,nestedDialogOpen:b>0},ref:[t,C],stateAttributesMapping:u,props:[{role:"presentation",hidden:!v,style:{pointerEvents:f?void 0:"none"},children:l},d]})});e.s(["DialogViewport",0,d],974217)},77173,313488,e=>{"use strict";e.i(247167);var t=e.i(271645),o=e.i(108821),n=e.i(552245),a=e.i(788015);let r=t.forwardRef(function(e,t){let{render:r,className:i,style:s,id:l,...u}=e,{store:d}=(0,o.useDialogRootContext)(),c=(0,a.useBaseUiId)(l);return d.useSyncedValueWithCleanup("titleElementId",c),(0,n.useRenderElement)("h2",e,{ref:t,props:[{id:c},u]})});e.s(["DialogTitle",0,r],77173);var i=e.i(733332),s=e.i(540886),l=e.i(405005),u=e.i(638396),d=e.i(264111),c=e.i(385689),p=e.i(32199);let f=t.forwardRef(function(e,r){let{render:f,className:g,style:m,disabled:b=!1,nativeButton:v=!0,id:C,payload:x,handle:h,...S}=e,D=(0,o.useDialogRootContext)(!0),R=h?.store??D?.store;if(!R)throw Error((0,i.default)(79));let w=(0,a.useBaseUiId)(C),y=R.useState("floatingRootContext"),O=R.useState("isOpenedByTrigger",w),E=R.useState("triggerPopupId",w),I=t.useRef(null),{registerTrigger:P,isMountedByThisTrigger:N}=(0,d.useTriggerDataForwarding)(w,I,R,{payload:x}),{getButtonProps:T,buttonRef:M}=(0,s.useButton)({disabled:b,native:v}),k=(0,c.useClick)(y,{enabled:null!=y}),A=(0,p.useOpenMethodTriggerProps)(()=>R.select("open"),e=>{R.set("openMethod",e)}),j=R.useState("triggerProps",N);return(0,n.useRenderElement)("button",e,{state:{disabled:b,open:O},ref:[M,r,P,I],props:[k.reference,j,A,{[u.CLICK_TRIGGER_IDENTIFIER]:"",id:w,"aria-haspopup":"dialog","aria-expanded":O,"aria-controls":E},S,T],stateAttributesMapping:l.triggerOpenStateMapping})});e.s(["DialogTrigger",0,f],313488)},325326,e=>{"use strict";var t=e.i(301807),o=e.i(675606),n=e.i(56434);class a{constructor(e){this.store=e??new t.DialogStore}open(e){let t=e?this.store.context.triggerElements.getById(e):void 0;this.store.setOpen(!0,(0,o.createChangeEventDetails)(n.REASONS.imperativeAction,void 0,t))}openWithPayload(e){this.store.set("payload",e),this.store.setOpen(!0,(0,o.createChangeEventDetails)(n.REASONS.imperativeAction,void 0,void 0))}close(){this.store.setOpen(!1,(0,o.createChangeEventDetails)(n.REASONS.imperativeAction,void 0,void 0))}get isOpen(){return this.store.select("open")}}e.s(["DialogHandle",0,a,"createDialogHandle",0,function(){return new a}])},793479,e=>{"use strict";var t=e.i(843476),o=e.i(271645),n=e.i(115504);let a=o.forwardRef(({className:e,type:o,...a},r)=>(0,t.jsx)("input",{type:o,"data-slot":"input",className:(0,n.cn)("h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30","focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50","aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40",e),ref:r,...a}));a.displayName="Input",e.s(["Input",0,a])},353753,e=>{"use strict";e.s([],914651),e.i(914651);var t=e.i(402820),o=e.i(156736),n=e.i(209793),a=e.i(784324),r=e.i(264951),i=e.i(271645),s=e.i(108821),l=e.i(366250),u=e.i(974217),d=e.i(77173),c=e.i(313488),p=e.i(325326);e.s(["Backdrop",()=>t.DialogBackdrop,"Close",()=>o.DialogClose,"Description",()=>n.DialogDescription,"Handle",()=>p.DialogHandle,"Popup",()=>a.DialogPopup,"Portal",()=>r.DialogPortal,"Root",0,function(e){let t=i.useContext(s.IsDrawerContext)?"drawer":"dialog";return(0,l.useRenderDialogRoot)(e,t)},"Title",()=>d.DialogTitle,"Trigger",()=>c.DialogTrigger,"Viewport",()=>u.DialogViewport,"createHandle",()=>p.createDialogHandle],828376);var f=e.i(828376);e.s(["Dialog",0,f],353753)},995926,e=>{"use strict";var t=e.i(841947);e.s(["XIcon",()=>t.default])},110204,e=>{"use strict";var t=e.i(843476),o=e.i(271645),n=e.i(115504);let a=o.forwardRef(({className:e,...o},a)=>(0,t.jsx)("label",{ref:a,"data-slot":"label",className:(0,n.cn)("flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",e),...o}));a.displayName="Label",e.s(["Label",0,a])},16715,e=>{"use strict";let t=(0,e.i(475254).default)("refresh-cw",[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]]);e.s(["RefreshCw",0,t],16715)},541071,e=>{"use strict";let t=(0,e.i(475254).default)("ellipsis",[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"19",cy:"12",r:"1",key:"1wjl8i"}],["circle",{cx:"5",cy:"12",r:"1",key:"1pcz8c"}]]);e.s(["MoreHorizontal",0,t],541071)},755146,e=>{"use strict";var t=e.i(843476),o=e.i(451512),n=e.i(115504);e.i(233565),e.i(678784),e.s(["DropdownMenu",0,function({...e}){return(0,t.jsx)(o.Menu.Root,{"data-slot":"dropdown-menu",...e})},"DropdownMenuContent",0,function({align:e="start",alignOffset:a=0,side:r="bottom",sideOffset:i=4,className:s,...l}){return(0,t.jsx)(o.Menu.Portal,{children:(0,t.jsx)(o.Menu.Positioner,{className:"isolate z-50 outline-none",align:e,alignOffset:a,side:r,sideOffset:i,children:(0,t.jsx)(o.Menu.Popup,{"data-slot":"dropdown-menu-content",className:(0,n.cn)("z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95",s),...l})})})},"DropdownMenuItem",0,function({className:e,inset:a,variant:r="default",...i}){return(0,t.jsx)(o.Menu.Item,{"data-slot":"dropdown-menu-item","data-inset":a,"data-variant":r,className:(0,n.cn)("group/dropdown-menu-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive",e),...i})},"DropdownMenuSeparator",0,function({className:e,...a}){return(0,t.jsx)(o.Menu.Separator,{"data-slot":"dropdown-menu-separator",className:(0,n.cn)("-mx-1 my-1 h-px bg-border",e),...a})},"DropdownMenuTrigger",0,function({...e}){return(0,t.jsx)(o.Menu.Trigger,{"data-slot":"dropdown-menu-trigger",...e})}])}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/022.sz94ycw4x.js b/litellm/proxy/_experimental/out/_next/static/chunks/022.sz94ycw4x.js deleted file mode 100644 index 746b869a2c6..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/022.sz94ycw4x.js +++ /dev/null @@ -1,4 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,751734,e=>{"use strict";let t=(0,e.i(271645).createContext)(0);e.s(["default",0,t])},144582,e=>{"use strict";let t=(0,e.i(271645).createContext)({selectedValue:void 0,handleValueChange:void 0});e.s(["default",0,t])},404206,e=>{"use strict";var t=e.i(290571),r=e.i(751734),n=e.i(144582),o=e.i(444755),s=e.i(673706),a=e.i(271645);let i=(0,s.makeClassName)("TabPanel"),l=a.default.forwardRef((e,s)=>{let{children:l,className:u}=e,c=(0,t.__rest)(e,["children","className"]),{selectedValue:d}=(0,a.useContext)(n.default),f=d===(0,a.useContext)(r.default);return a.default.createElement("div",Object.assign({ref:s,className:(0,o.tremorTwMerge)(i("root"),"w-full mt-2",f?"":"hidden",u),"aria-selected":f?"true":"false"},c),l)});l.displayName="TabPanel",e.s(["TabPanel",0,l],404206)},783222,433336,80758,402155,368578,544508,746725,835696,941444,914189,394487,e=>{"use strict";let t;e.i(247167);let r=e=>e?.ownerDocument??document,n=e=>e&&"window"in e&&e.window===e?e:r(e).defaultView||window;function o(e,t){return!!t&&!!e&&e.contains(t)}function s(e){return e.target}let a=null;"u">typeof Element&&Element.prototype;let i=["input:not([disabled]):not([type=hidden])","select:not([disabled])","textarea:not([disabled])","button:not([disabled])","a[href]","area[href]","summary","iframe","object","embed","audio[controls]","video[controls]",'[contenteditable]:not([contenteditable^="false"])',"permission"];i.join(":not([hidden]),"),i.push('[tabindex]:not([tabindex="-1"]):not([disabled])'),i.join(':not([hidden]):not([tabindex="-1"]),');var l=e.i(271645);let u="u">typeof document?l.default.useLayoutEffect:()=>{};function c(e){return e.nativeEvent=e,e.isDefaultPrevented=()=>e.defaultPrevented,e.isPropagationStopped=()=>e.cancelBubble,e.persist=()=>{},e}function d(e){let t=(0,l.useRef)({isFocused:!1,observer:null});return u(()=>{let e=t.current;return()=>{e.observer&&(e.observer.disconnect(),e.observer=null)}},[]),(0,l.useCallback)(r=>{let n=s(r);(n instanceof HTMLButtonElement||n instanceof HTMLInputElement||n instanceof HTMLTextAreaElement||n instanceof HTMLSelectElement)&&(t.current.isFocused=!0,n.addEventListener("focusout",r=>{if(t.current.isFocused=!1,n.disabled){let t=c(r);e?.(t)}t.current.observer&&(t.current.observer.disconnect(),t.current.observer=null)},{once:!0}),t.current.observer=new MutationObserver(()=>{if(t.current.isFocused&&n.disabled){t.current.observer?.disconnect();let e=n===((e=document)=>e.activeElement)()?null:((e=document)=>e.activeElement)();n.dispatchEvent(new FocusEvent("blur",{relatedTarget:e})),n.dispatchEvent(new FocusEvent("focusout",{bubbles:!0,relatedTarget:e}))}}),t.current.observer.observe(n,{attributes:!0,attributeFilter:["disabled"]}))},[e])}function f(e){if("u"e.test(t.brand))||e.test(window.navigator.userAgent)}function p(e){return"u">typeof window&&null!=window.navigator&&e.test(window.navigator.userAgentData?.platform||window.navigator.platform)}function m(e){let t=null;return()=>(null==t&&(t=e()),t)}let b=m(function(){return p(/^Mac/i)}),v=m(function(){return p(/^iPhone/i)}),h=m(function(){return p(/^iPad/i)||b()&&navigator.maxTouchPoints>1}),g=m(function(){return v()||h()});m(function(){return b()||g()});let y=m(function(){return f(/AppleWebKit/i)&&!E()}),E=m(function(){return f(/Chrome/i)}),T=m(function(){return f(/Android/i)}),w=m(function(){return f(/Firefox/i)});function x(e,t,r=!0){let{metaKey:n,ctrlKey:o,altKey:s,shiftKey:i}=t;w()&&window.event?.type?.startsWith("key")&&"_blank"===e.target&&(b()?n=!0:o=!0);let l=y()&&b()&&!h()&&1?new KeyboardEvent("keydown",{keyIdentifier:"Enter",metaKey:n,ctrlKey:o,altKey:s,shiftKey:i}):new MouseEvent("click",{metaKey:n,ctrlKey:o,altKey:s,shiftKey:i,detail:1,bubbles:!0,cancelable:!0});x.isOpening=r;if(function(){if(null==a){a=!1;try{document.createElement("div").focus({get preventScroll(){return a=!0,!0}})}catch{}}return a}())e.focus({preventScroll:!0});else{let t=function(e){let t=e.parentNode,r=[],n=document.scrollingElement||document.documentElement;for(;t instanceof HTMLElement&&t!==n;)(t.offsetHeighttypeof window&&window.document&&window.document.createElement,new WeakMap;l.default.useId;let P=null,k=new Set,L=new Map,N=!1,C=!1,I={Tab:!0,Escape:!0};function S(e,t){for(let r of k)r(e,t)}function A(e){N=!0,x.isOpening||e.metaKey||!b()&&e.altKey||e.ctrlKey||"Control"===e.key||"Shift"===e.key||"Meta"===e.key||(P="keyboard",S("keyboard",e))}function M(e){P="pointer","pointerType"in e&&e.pointerType,("mousedown"===e.type||"pointerdown"===e.type)&&(N=!0,S("pointer",e))}function R(e){x.isOpening||(""!==e.pointerType||!e.isTrusted)&&(T()&&e.pointerType?"click"!==e.type||1!==e.buttons:0!==e.detail||e.pointerType)||(N=!0,P="virtual")}function O(e){let t=n(s(e)),o=r(s(e));s(e)!==t&&s(e)!==o&&e.isTrusted&&(N||C||(P="virtual",S("virtual",e)),N=!1,C=!1)}function D(){N=!1,C=!0}function H(e){if("u"typeof PointerEvent&&(o.addEventListener("pointerdown",M,!0),o.addEventListener("pointermove",M,!0),o.addEventListener("pointerup",M,!0)),t.addEventListener("beforeunload",()=>{j(e)},{once:!0}),L.set(t,{focus:s})}let j=(e,t)=>{let o=n(e),s=r(e);t&&s.removeEventListener("DOMContentLoaded",t),L.has(o)&&(o.HTMLElement.prototype.focus=L.get(o).focus,s.removeEventListener("keydown",A,!0),s.removeEventListener("keyup",A,!0),s.removeEventListener("click",R,!0),o.removeEventListener("focus",O,!0),o.removeEventListener("blur",D,!1),"u">typeof PointerEvent&&(s.removeEventListener("pointerdown",M,!0),s.removeEventListener("pointermove",M,!0),s.removeEventListener("pointerup",M,!0)),L.delete(o))};function K(){return"pointer"!==P}"u">typeof document&&("loading"!==(t=r(void 0)).readyState?H(void 0):t.addEventListener("DOMContentLoaded",()=>{H(void 0)}));let W=new Set(["checkbox","radio","range","color","file","image","button","submit","reset"]);function B(){let e=(0,l.useRef)(new Map),t=(0,l.useCallback)((t,r,n,o)=>{let s=o?.once?(...t)=>{e.current.delete(n),n(...t)}:n;e.current.set(n,{type:r,eventTarget:t,fn:s,options:o}),t.addEventListener(r,s,o)},[]),r=(0,l.useCallback)((t,r,n,o)=>{let s=e.current.get(n)?.fn||n;t.removeEventListener(r,s,o),e.current.delete(n)},[]),n=(0,l.useCallback)(()=>{e.current.forEach((e,t)=>{r(e.eventTarget,e.type,t,e.options)})},[r]);return(0,l.useEffect)(()=>n,[n]),{addGlobalListener:t,removeGlobalListener:r,removeAllGlobalListeners:n}}e.s(["useFocusRing",0,function(e={}){var t;let{autoFocus:a=!1,isTextInput:i,within:u}=e,f=(0,l.useRef)({isFocused:!1,isFocusVisible:a||K()}),[p,m]=(0,l.useState)(!1),[b,v]=(0,l.useState)(()=>f.current.isFocused&&f.current.isFocusVisible),h=(0,l.useCallback)(()=>v(f.current.isFocused&&f.current.isFocusVisible),[]),g=(0,l.useCallback)(e=>{f.current.isFocused=e,f.current.isFocusVisible=K(),m(e),h()},[h]);t={enabled:p,isTextInput:i},H(),(0,l.useEffect)(()=>{if(t?.enabled===!1)return;let e=(e,o)=>{var a;let i,l,u,c,d,p,m,b;a=!!t?.isTextInput,l=r(i=o?s(o):void 0),c=void 0!==(u=n(i))?u.HTMLInputElement:HTMLInputElement,d=void 0!==u?u.HTMLTextAreaElement:HTMLTextAreaElement,p=void 0!==u?u.HTMLElement:HTMLElement,m=void 0!==u?u.KeyboardEvent:KeyboardEvent,b=((e=document)=>e.activeElement)(l),(a=a||b instanceof c&&!W.has(b.type)||b instanceof d||b instanceof p&&b.isContentEditable)&&"keyboard"===e&&o instanceof m&&!I[o.key]||(e=>{f.current.isFocusVisible=e,h()})(K())};return k.add(e),()=>{k.delete(e)}},[i,p]);let{focusProps:y}=function(e){let{isDisabled:t,onFocus:n,onBlur:o,onFocusChange:a}=e,i=(0,l.useCallback)(e=>{if(s(e)===e.currentTarget)return o&&o(e),a&&a(!1),!0},[o,a]),u=d(i),c=(0,l.useCallback)(e=>{let t=s(e),o=r(t),i=o?((e=document)=>e.activeElement)(o):((e=document)=>e.activeElement)();t===e.currentTarget&&t===i&&(n&&n(e),a&&a(!0),u(e))},[a,n,u]);return{focusProps:{onFocus:!t&&(n||a||o)?c:void 0,onBlur:!t&&(o||a)?i:void 0}}}({isDisabled:u,onFocusChange:g}),{focusWithinProps:E}=function(e){let{isDisabled:t,onBlurWithin:n,onFocusWithin:a,onFocusWithinChange:i}=e,u=(0,l.useRef)({isFocusWithin:!1}),{addGlobalListener:f,removeAllGlobalListeners:p}=B(),m=(0,l.useCallback)(e=>{o(e.currentTarget,s(e))&&u.current.isFocusWithin&&!o(e.currentTarget,e.relatedTarget)&&(u.current.isFocusWithin=!1,p(),n&&n(e),i&&i(!1))},[n,i,u,p]),b=d(m),v=(0,l.useCallback)(e=>{if(!o(e.currentTarget,s(e)))return;let t=s(e),n=r(t),l=((e=document)=>e.activeElement)(n);if(!u.current.isFocusWithin&&l===t){a&&a(e),i&&i(!0),u.current.isFocusWithin=!0,b(e);let t=e.currentTarget;f(n,"focus",e=>{let r=s(e);if(u.current.isFocusWithin&&!o(t,r)){let e=new n.defaultView.FocusEvent("blur",{relatedTarget:r});Object.defineProperty(e,"target",{value:t}),Object.defineProperty(e,"currentTarget",{value:t}),m(c(e))}},{capture:!0})}},[a,i,b,f,m]);return t?{focusWithinProps:{onFocus:void 0,onBlur:void 0}}:{focusWithinProps:{onFocus:v,onBlur:m}}}({isDisabled:!u,onFocusWithinChange:g});return{isFocused:p,isFocusVisible:b,focusProps:u?E:y}}],783222);let V=!1,_=0;function G(e){"touch"===e.pointerType&&(V=!0,setTimeout(()=>{V=!1},500))}function U(){let e=r(null);if(void 0!==e)return 0===_&&"u">typeof PointerEvent&&e.addEventListener("pointerup",G),_++,()=>{!(--_>0)&&"u">typeof PointerEvent&&e.removeEventListener("pointerup",G)}}e.s(["useHover",0,function(e){let{onHoverStart:t,onHoverChange:n,onHoverEnd:a,isDisabled:i}=e,[u,c]=(0,l.useState)(!1),d=(0,l.useRef)({isHovered:!1,ignoreEmulatedMouseEvents:!1,pointerType:"",target:null}).current;(0,l.useEffect)(U,[]);let{addGlobalListener:f,removeAllGlobalListeners:p}=B(),{hoverProps:m,triggerHoverEnd:b}=(0,l.useMemo)(()=>{let e=(e,t)=>{let r=d.target;d.pointerType="",d.target=null,"touch"!==t&&d.isHovered&&r&&(d.isHovered=!1,p(),a&&a({type:"hoverend",target:r,pointerType:t}),n&&n(!1),c(!1))},l={};return"u">typeof PointerEvent&&(l.onPointerEnter=a=>{V&&"mouse"===a.pointerType||((a,l)=>{if(d.pointerType=l,i||"touch"===l||d.isHovered||!o(a.currentTarget,s(a)))return;d.isHovered=!0;let u=a.currentTarget;d.target=u,f(r(s(a)),"pointerover",t=>{d.isHovered&&d.target&&!o(d.target,s(t))&&e(t,t.pointerType)},{capture:!0}),t&&t({type:"hoverstart",target:u,pointerType:l}),n&&n(!0),c(!0)})(a,a.pointerType)},l.onPointerLeave=t=>{!i&&o(t.currentTarget,s(t))&&e(t,t.pointerType)}),{hoverProps:l,triggerHoverEnd:e}},[t,n,a,i,d,f,p]);return(0,l.useEffect)(()=>{i&&b({currentTarget:d.target},d.pointerType)},[i]),{hoverProps:m,isHovered:u}}],433336);var $=Object.defineProperty,q=(e,t,r)=>{let n;return(n="symbol"!=typeof t?t+"":t)in e?$(e,n,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[n]=r,r};let X=new class{constructor(){q(this,"current",this.detect()),q(this,"handoffState","pending"),q(this,"currentId",0)}set(e){this.current!==e&&(this.handoffState="pending",this.currentId=0,this.current=e)}reset(){this.set(this.detect())}nextId(){return++this.currentId}get isServer(){return"server"===this.current}get isClient(){return"client"===this.current}detect(){return"u"setTimeout(()=>{throw e}))}function Z(){let e=[],t={addEventListener:(e,r,n,o)=>(e.addEventListener(r,n,o),t.add(()=>e.removeEventListener(r,n,o))),requestAnimationFrame(...e){let r=requestAnimationFrame(...e);return t.add(()=>cancelAnimationFrame(r))},nextFrame:(...e)=>t.requestAnimationFrame(()=>t.requestAnimationFrame(...e)),setTimeout(...e){let r=setTimeout(...e);return t.add(()=>clearTimeout(r))},microTask(...e){let r={current:!0};return z(()=>{r.current&&e[0]()}),t.add(()=>{r.current=!1})},style(e,t,r){let n=e.style.getPropertyValue(t);return Object.assign(e.style,{[t]:r}),this.add(()=>{Object.assign(e.style,{[t]:n})})},group(e){let t=Z();return e(t),this.add(()=>t.dispose())},add:t=>(e.includes(t)||e.push(t),()=>{let r=e.indexOf(t);if(r>=0)for(let t of e.splice(r,1))t()}),dispose(){for(let t of e.splice(0))t()}};return t}function J(){let[e]=(0,l.useState)(Z);return(0,l.useEffect)(()=>()=>e.dispose(),[e]),e}e.s(["env",0,X],80758),e.s(["getOwnerDocument",0,Y],402155),e.s(["microTask",0,z],368578),e.s(["disposables",0,Z],544508),e.s(["useDisposables",0,J],746725);let Q=(e,t)=>{X.isServer?(0,l.useEffect)(e,t):(0,l.useLayoutEffect)(e,t)};function ee(e){let t=(0,l.useRef)(e);return Q(()=>{t.current=e},[e]),t}e.s(["useIsoMorphicEffect",0,Q],835696),e.s(["useLatestValue",0,ee],941444);let et=function(e){let t=ee(e);return l.default.useCallback((...e)=>t.current(...e),[t])};e.s(["useEvent",0,et],914189),e.s(["useActivePress",0,function({disabled:e=!1}={}){let t=(0,l.useRef)(null),[r,n]=(0,l.useState)(!1),o=J(),s=et(()=>{t.current=null,n(!1),o.dispose()}),a=et(e=>{if(o.dispose(),null===t.current){t.current=e.currentTarget,n(!0);{let r=Y(e.currentTarget);o.addEventListener(r,"pointerup",s,!1),o.addEventListener(r,"pointermove",e=>{if(t.current){var r,o;let s,a;n((s=e.width/2,a=e.height/2,r={top:e.clientY-a,right:e.clientX+s,bottom:e.clientY+a,left:e.clientX-s},o=t.current.getBoundingClientRect(),!(!r||!o||r.righto.right||r.bottomo.bottom)))}},!1),o.addEventListener(r,"pointercancel",s,!1)}}});return{pressed:r,pressProps:e?{}:{onPointerDown:a,onPointerUp:s,onClick:s}}}],394487)},397701,e=>{"use strict";e.s(["match",0,function e(t,r,...n){if(t in r){let e=r[t];return"function"==typeof e?e(...n):e}let o=Error(`Tried to handle "${t}" but there is no handler defined. Only defined handlers are: ${Object.keys(r).map(e=>`"${e}"`).join(", ")}.`);throw Error.captureStackTrace&&Error.captureStackTrace(o,e),o}])},652265,e=>{"use strict";let t,r,n,o,s;e.i(544508);var a=e.i(397701),i=e.i(402155);let l=["[contentEditable=true]","[tabindex]","a[href]","area[href]","button:not([disabled])","iframe","input:not([disabled])","select:not([disabled])","textarea:not([disabled])"].map(e=>`${e}:not([tabindex='-1'])`).join(","),u=["[data-autofocus]"].map(e=>`${e}:not([tabindex='-1'])`).join(",");var c=((t=c||{})[t.First=1]="First",t[t.Previous=2]="Previous",t[t.Next=4]="Next",t[t.Last=8]="Last",t[t.WrapAround=16]="WrapAround",t[t.NoScroll=32]="NoScroll",t[t.AutoFocus=64]="AutoFocus",t),d=((r=d||{})[r.Error=0]="Error",r[r.Overflow=1]="Overflow",r[r.Success=2]="Success",r[r.Underflow=3]="Underflow",r),f=((n=f||{})[n.Previous=-1]="Previous",n[n.Next=1]="Next",n);function p(e=document.body){return null==e?[]:Array.from(e.querySelectorAll(l)).sort((e,t)=>Math.sign((e.tabIndex||Number.MAX_SAFE_INTEGER)-(t.tabIndex||Number.MAX_SAFE_INTEGER)))}var m=((o=m||{})[o.Strict=0]="Strict",o[o.Loose=1]="Loose",o),b=((s=b||{})[s.Keyboard=0]="Keyboard",s[s.Mouse=1]="Mouse",s);function v(e,t=e=>e){return e.slice().sort((e,r)=>{let n=t(e),o=t(r);if(null===n||null===o)return 0;let s=n.compareDocumentPosition(o);return s&Node.DOCUMENT_POSITION_FOLLOWING?-1:s&Node.DOCUMENT_POSITION_PRECEDING?1:0})}function h(e,t,{sorted:r=!0,relativeTo:n=null,skipElements:o=[]}={}){var s,a,i;let l=Array.isArray(e)?e.length>0?e[0].ownerDocument:document:e.ownerDocument,c=Array.isArray(e)?r?v(e):e:64&t?function(e=document.body){return null==e?[]:Array.from(e.querySelectorAll(u)).sort((e,t)=>Math.sign((e.tabIndex||Number.MAX_SAFE_INTEGER)-(t.tabIndex||Number.MAX_SAFE_INTEGER)))}(e):p(e);o.length>0&&c.length>1&&(c=c.filter(e=>!o.some(t=>null!=t&&"current"in t?(null==t?void 0:t.current)===e:t===e))),n=null!=n?n:l.activeElement;let d=(()=>{if(5&t)return 1;if(10&t)return -1;throw Error("Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last")})(),f=(()=>{if(1&t)return 0;if(2&t)return Math.max(0,c.indexOf(n))-1;if(4&t)return Math.max(0,c.indexOf(n))+1;if(8&t)return c.length-1;throw Error("Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last")})(),m=32&t?{preventScroll:!0}:{},b=0,g=c.length,y;do{if(b>=g||b+g<=0)return 0;let e=f+b;if(16&t)e=(e+g)%g;else{if(e<0)return 3;if(e>=g)return 1}null==(y=c[e])||y.focus(m),b+=d}while(y!==l.activeElement)return 6&t&&null!=(i=null==(a=null==(s=y)?void 0:s.matches)?void 0:a.call(s,"textarea,input"))&&i&&y.select(),2}"u">typeof window&&"u">typeof document&&(document.addEventListener("keydown",e=>{e.metaKey||e.altKey||e.ctrlKey||(document.documentElement.dataset.headlessuiFocusVisible="")},!0),document.addEventListener("click",e=>{1===e.detail?delete document.documentElement.dataset.headlessuiFocusVisible:0===e.detail&&(document.documentElement.dataset.headlessuiFocusVisible="")},!0)),e.s(["Focus",0,c,"FocusResult",0,d,"FocusableMode",0,m,"focusFrom",0,function(e,t){return h(p(),t,{relativeTo:e})},"focusIn",0,h,"getFocusableElements",0,p,"isFocusableElement",0,function(e,t=0){var r;return e!==(null==(r=(0,i.getOwnerDocument)(e))?void 0:r.body)&&(0,a.match)(t,{0:()=>e.matches(l),1(){let t=e;for(;null!==t;){if(t.matches(l))return!0;t=t.parentElement}return!1}})},"sortByDomNode",0,v])},144279,294316,e=>{"use strict";var t=e.i(271645);e.s(["useResolveButtonType",0,function(e,r){return(0,t.useMemo)(()=>{var t;if(e.type)return e.type;let n=null!=(t=e.as)?t:"button";if("string"==typeof n&&"button"===n.toLowerCase()||(null==r?void 0:r.tagName)==="BUTTON"&&!r.hasAttribute("type"))return"button"},[e.type,e.as,r])}],144279);var r=e.i(914189);let n=Symbol();e.s(["optionalRef",0,function(e,t=!0){return Object.assign(e,{[n]:t})},"useSyncRefs",0,function(...e){let o=(0,t.useRef)(e);(0,t.useEffect)(()=>{o.current=e},[e]);let s=(0,r.useEvent)(e=>{for(let t of o.current)null!=t&&("function"==typeof t?t(e):t.current=e)});return e.every(e=>null==e||(null==e?void 0:e[n]))?void 0:s}],294316)},732607,e=>{"use strict";e.s(["classNames",0,function(...e){return Array.from(new Set(e.flatMap(e=>"string"==typeof e?e.split(" "):[]))).filter(Boolean).join(" ")}])},700020,e=>{"use strict";let t,r;var n=e.i(271645),o=e.i(732607),s=e.i(397701),a=((t=a||{})[t.None=0]="None",t[t.RenderStrategy=1]="RenderStrategy",t[t.Static=2]="Static",t),i=((r=i||{})[r.Unmount=0]="Unmount",r[r.Hidden=1]="Hidden",r);function l(e,t={},r,s,a){let{as:i=r,children:u,refName:p="ref",...m}=f(e,["unmount","static"]),b=void 0!==e.ref?{[p]:e.ref}:{},v="function"==typeof u?u(t):u;"className"in m&&m.className&&"function"==typeof m.className&&(m.className=m.className(t)),m["aria-labelledby"]&&m["aria-labelledby"]===m.id&&(m["aria-labelledby"]=void 0);let h={};if(t){let e=!1,r=[];for(let[n,o]of Object.entries(t))"boolean"==typeof o&&(e=!0),!0===o&&r.push(n.replace(/([A-Z])/g,e=>`-${e.toLowerCase()}`));if(e)for(let e of(h["data-headlessui-state"]=r.join(" "),r))h[`data-${e}`]=""}if(i===n.Fragment&&(Object.keys(d(m)).length>0||Object.keys(d(h)).length>0))if(!(0,n.isValidElement)(v)||Array.isArray(v)&&v.length>1){if(Object.keys(d(m)).length>0)throw Error(['Passing props on "Fragment"!',"",`The current component <${s} /> is rendering a "Fragment".`,"However we need to passthrough the following props:",Object.keys(d(m)).concat(Object.keys(d(h))).map(e=>` - ${e}`).join(` -`),"","You can apply a few solutions:",['Add an `as="..."` prop, to ensure that we render an actual element instead of a "Fragment".',"Render a single element as the child so that we can forward the props onto that element."].map(e=>` - ${e}`).join(` -`)].join(` -`))}else{var g;let e=v.props,t=null==e?void 0:e.className,r="function"==typeof t?(...e)=>(0,o.classNames)(t(...e),m.className):(0,o.classNames)(t,m.className),s=c(v.props,d(f(m,["ref"])));for(let e in h)e in s&&delete h[e];return(0,n.cloneElement)(v,Object.assign({},s,h,b,{ref:a((g=v,n.default.version.split(".")[0]>="19"?g.props.ref:g.ref),b.ref)},r?{className:r}:{}))}return(0,n.createElement)(i,Object.assign({},f(m,["ref"]),i!==n.Fragment&&b,i!==n.Fragment&&h),v)}function u(...e){return e.every(e=>null==e)?void 0:t=>{for(let r of e)null!=r&&("function"==typeof r?r(t):r.current=t)}}function c(...e){if(0===e.length)return{};if(1===e.length)return e[0];let t={},r={};for(let n of e)for(let e in n)e.startsWith("on")&&"function"==typeof n[e]?(null!=r[e]||(r[e]=[]),r[e].push(n[e])):t[e]=n[e];if(t.disabled||t["aria-disabled"])for(let e in r)/^(on(?:Click|Pointer|Mouse|Key)(?:Down|Up|Press)?)$/.test(e)&&(r[e]=[e=>{var t;return null==(t=null==e?void 0:e.preventDefault)?void 0:t.call(e)}]);for(let e in r)Object.assign(t,{[e](t,...n){for(let o of r[e]){if((t instanceof Event||(null==t?void 0:t.nativeEvent)instanceof Event)&&t.defaultPrevented)return;o(t,...n)}}});return t}function d(e){let t=Object.assign({},e);for(let e in t)void 0===t[e]&&delete t[e];return t}function f(e,t=[]){let r=Object.assign({},e);for(let e of t)e in r&&delete r[e];return r}e.s(["RenderFeatures",0,a,"RenderStrategy",0,i,"compact",0,d,"forwardRefWithAs",0,function(e){var t;return Object.assign((0,n.forwardRef)(e),{displayName:null!=(t=e.displayName)?t:e.name})},"mergeProps",0,function(...e){if(0===e.length)return{};if(1===e.length)return e[0];let t={},r={};for(let n of e)for(let e in n)e.startsWith("on")&&"function"==typeof n[e]?(null!=r[e]||(r[e]=[]),r[e].push(n[e])):t[e]=n[e];for(let e in r)Object.assign(t,{[e](...t){for(let n of r[e])null==n||n(...t)}});return t},"useRender",0,function(){let e,t,r=(e=(0,n.useRef)([]),t=(0,n.useCallback)(t=>{for(let r of e.current)null!=r&&("function"==typeof r?r(t):r.current=t)},[]),(...r)=>{if(!r.every(e=>null==e))return e.current=r,t});return(0,n.useCallback)(e=>(function({ourProps:e,theirProps:t,slot:r,defaultTag:n,features:o,visible:a=!0,name:i,mergeRefs:d}){d=null!=d?d:u;let f=c(t,e);if(a)return l(f,r,n,i,d);let p=null!=o?o:0;if(2&p){let{static:e=!1,...t}=f;if(e)return l(t,r,n,i,d)}if(1&p){let{unmount:e=!0,...t}=f;return(0,s.match)(+!e,{0:()=>null,1:()=>l({...t,hidden:!0,style:{display:"none"}},r,n,i,d)})}return l(f,r,n,i,d)})({mergeRefs:r,...e}),[r])}])},2788,e=>{"use strict";let t;var r=e.i(700020),n=((t=n||{})[t.None=1]="None",t[t.Focusable=2]="Focusable",t[t.Hidden=4]="Hidden",t);let o=(0,r.forwardRefWithAs)(function(e,t){var n;let{features:o=1,...s}=e,a={ref:t,"aria-hidden":(2&o)==2||(null!=(n=s["aria-hidden"])?n:void 0),hidden:(4&o)==4||void 0,style:{position:"fixed",top:1,left:1,width:1,height:0,padding:0,margin:-1,overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",borderWidth:"0",...(4&o)==4&&(2&o)!=2&&{display:"none"}}};return(0,r.useRender)()({ourProps:a,theirProps:s,slot:{},defaultTag:"span",name:"Hidden"})});e.s(["Hidden",0,o,"HiddenFeatures",0,n])},998348,e=>{"use strict";let t;var r=((t=r||{}).Space=" ",t.Enter="Enter",t.Escape="Escape",t.Backspace="Backspace",t.Delete="Delete",t.ArrowLeft="ArrowLeft",t.ArrowUp="ArrowUp",t.ArrowRight="ArrowRight",t.ArrowDown="ArrowDown",t.Home="Home",t.End="End",t.PageUp="PageUp",t.PageDown="PageDown",t.Tab="Tab",t);e.s(["Keys",0,r])},553521,e=>{"use strict";var t=e.i(271645),r=e.i(835696);e.s(["useIsMounted",0,function(){let e=(0,t.useRef)(!1);return(0,r.useIsoMorphicEffect)(()=>(e.current=!0,()=>{e.current=!1}),[]),e}])},640497,e=>{"use strict";var t=e.i(271645),r=e.i(553521),n=e.i(2788);e.s(["FocusSentinel",0,function({onFocus:e}){let[o,s]=(0,t.useState)(!0),a=(0,r.useIsMounted)();return o?t.default.createElement(n.Hidden,{as:"button",type:"button",features:n.HiddenFeatures.Focusable,onFocus:t=>{t.preventDefault();let r,n=50;r=requestAnimationFrame(function t(){if(n--<=0){r&&cancelAnimationFrame(r);return}if(e()){if(cancelAnimationFrame(r),!a.current)return;s(!1);return}r=requestAnimationFrame(t)})}}):null}])},963703,e=>{"use strict";var t=e.i(271645);let r=t.createContext(null);e.s(["StableCollection",0,function({children:e}){let n=t.useRef({groups:new Map,get(e,t){var r;let n=this.groups.get(e);n||(n=new Map,this.groups.set(e,n));let o=null!=(r=n.get(t))?r:0;return n.set(t,o+1),[Array.from(n.keys()).indexOf(t),function(){let e=n.get(t);e>1?n.set(t,e-1):n.delete(t)}]}});return t.createElement(r.Provider,{value:n},e)},"useStableCollectionIndex",0,function(e){let n=t.useContext(r);if(!n)throw Error("You must wrap your component in a ");let o=t.useId(),[s,a]=n.current.get(e,o);return t.useEffect(()=>a,[]),s}])},970554,e=>{"use strict";let t,r,n;var o=e.i(783222),s=e.i(433336),a=e.i(271645),i=e.i(394487),l=e.i(914189),u=e.i(835696),c=e.i(941444),d=e.i(144279),f=e.i(294316),p=e.i(640497),m=e.i(2788),b=e.i(652265),v=e.i(397701),h=e.i(368578),g=e.i(402155),y=e.i(700020),E=e.i(963703),T=e.i(998348),w=((t=w||{})[t.Forwards=0]="Forwards",t[t.Backwards=1]="Backwards",t),x=((r=x||{})[r.Less=-1]="Less",r[r.Equal=0]="Equal",r[r.Greater=1]="Greater",r),F=((n=F||{})[n.SetSelectedIndex=0]="SetSelectedIndex",n[n.RegisterTab=1]="RegisterTab",n[n.UnregisterTab=2]="UnregisterTab",n[n.RegisterPanel=3]="RegisterPanel",n[n.UnregisterPanel=4]="UnregisterPanel",n);let P={0(e,t){var r;let n=(0,b.sortByDomNode)(e.tabs,e=>e.current),o=(0,b.sortByDomNode)(e.panels,e=>e.current),s=n.filter(e=>{var t;return!(null!=(t=e.current)&&t.hasAttribute("disabled"))}),a={...e,tabs:n,panels:o};if(t.index<0||t.index>n.length-1){let r=(0,v.match)(Math.sign(t.index-e.selectedIndex),{[-1]:()=>1,0:()=>(0,v.match)(Math.sign(t.index),{[-1]:()=>0,0:()=>0,1:()=>1}),1:()=>0});if(0===s.length)return a;let o=(0,v.match)(r,{0:()=>n.indexOf(s[0]),1:()=>n.indexOf(s[s.length-1])});return{...a,selectedIndex:-1===o?e.selectedIndex:o}}let i=n.slice(0,t.index),l=[...n.slice(t.index),...i].find(e=>s.includes(e));if(!l)return a;let u=null!=(r=n.indexOf(l))?r:e.selectedIndex;return -1===u&&(u=e.selectedIndex),{...a,selectedIndex:u}},1(e,t){if(e.tabs.includes(t.tab))return e;let r=e.tabs[e.selectedIndex],n=(0,b.sortByDomNode)([...e.tabs,t.tab],e=>e.current),o=e.selectedIndex;return e.info.current.isControlled||-1===(o=n.indexOf(r))&&(o=e.selectedIndex),{...e,tabs:n,selectedIndex:o}},2:(e,t)=>({...e,tabs:e.tabs.filter(e=>e!==t.tab)}),3:(e,t)=>e.panels.includes(t.panel)?e:{...e,panels:(0,b.sortByDomNode)([...e.panels,t.panel],e=>e.current)},4:(e,t)=>({...e,panels:e.panels.filter(e=>e!==t.panel)})},k=(0,a.createContext)(null);function L(e){let t=(0,a.useContext)(k);if(null===t){let t=Error(`<${e} /> is missing a parent component.`);throw Error.captureStackTrace&&Error.captureStackTrace(t,L),t}return t}k.displayName="TabsDataContext";let N=(0,a.createContext)(null);function C(e){let t=(0,a.useContext)(N);if(null===t){let t=Error(`<${e} /> is missing a parent component.`);throw Error.captureStackTrace&&Error.captureStackTrace(t,C),t}return t}function I(e,t){return(0,v.match)(t.type,P,e,t)}N.displayName="TabsActionsContext";let S=y.RenderFeatures.RenderStrategy|y.RenderFeatures.Static,A=Object.assign((0,y.forwardRefWithAs)(function(e,t){var r,n;let c=(0,a.useId)(),{id:p=`headlessui-tabs-tab-${c}`,disabled:m=!1,autoFocus:w=!1,...x}=e,{orientation:F,activation:P,selectedIndex:k,tabs:N,panels:I}=L("Tab"),S=C("Tab"),A=L("Tab"),[M,R]=(0,a.useState)(null),O=(0,a.useRef)(null),D=(0,f.useSyncRefs)(O,t,R);(0,u.useIsoMorphicEffect)(()=>S.registerTab(O),[S,O]);let H=(0,E.useStableCollectionIndex)("tabs"),j=N.indexOf(O);-1===j&&(j=H);let K=j===k,W=(0,l.useEvent)(e=>{var t;let r=e();if(r===b.FocusResult.Success&&"auto"===P){let e=null==(t=(0,g.getOwnerDocument)(O))?void 0:t.activeElement,r=A.tabs.findIndex(t=>t.current===e);-1!==r&&S.change(r)}return r}),B=(0,l.useEvent)(e=>{let t=N.map(e=>e.current).filter(Boolean);if(e.key===T.Keys.Space||e.key===T.Keys.Enter){e.preventDefault(),e.stopPropagation(),S.change(j);return}switch(e.key){case T.Keys.Home:case T.Keys.PageUp:return e.preventDefault(),e.stopPropagation(),W(()=>(0,b.focusIn)(t,b.Focus.First));case T.Keys.End:case T.Keys.PageDown:return e.preventDefault(),e.stopPropagation(),W(()=>(0,b.focusIn)(t,b.Focus.Last))}if(W(()=>(0,v.match)(F,{vertical:()=>e.key===T.Keys.ArrowUp?(0,b.focusIn)(t,b.Focus.Previous|b.Focus.WrapAround):e.key===T.Keys.ArrowDown?(0,b.focusIn)(t,b.Focus.Next|b.Focus.WrapAround):b.FocusResult.Error,horizontal:()=>e.key===T.Keys.ArrowLeft?(0,b.focusIn)(t,b.Focus.Previous|b.Focus.WrapAround):e.key===T.Keys.ArrowRight?(0,b.focusIn)(t,b.Focus.Next|b.Focus.WrapAround):b.FocusResult.Error}))===b.FocusResult.Success)return e.preventDefault()}),V=(0,a.useRef)(!1),_=(0,l.useEvent)(()=>{var e;V.current||(V.current=!0,null==(e=O.current)||e.focus({preventScroll:!0}),S.change(j),(0,h.microTask)(()=>{V.current=!1}))}),G=(0,l.useEvent)(e=>{e.preventDefault()}),{isFocusVisible:U,focusProps:$}=(0,o.useFocusRing)({autoFocus:w}),{isHovered:q,hoverProps:X}=(0,s.useHover)({isDisabled:m}),{pressed:Y,pressProps:z}=(0,i.useActivePress)({disabled:m}),Z=(0,a.useMemo)(()=>({selected:K,hover:q,active:Y,focus:U,autofocus:w,disabled:m}),[K,q,U,Y,w,m]),J=(0,y.mergeProps)({ref:D,onKeyDown:B,onMouseDown:G,onClick:_,id:p,role:"tab",type:(0,d.useResolveButtonType)(e,M),"aria-controls":null==(n=null==(r=I[j])?void 0:r.current)?void 0:n.id,"aria-selected":K,tabIndex:K?0:-1,disabled:m||void 0,autoFocus:w},$,X,z);return(0,y.useRender)()({ourProps:J,theirProps:x,slot:Z,defaultTag:"button",name:"Tabs.Tab"})}),{Group:(0,y.forwardRefWithAs)(function(e,t){let{defaultIndex:r=0,vertical:n=!1,manual:o=!1,onChange:s,selectedIndex:i=null,...d}=e,m=n?"vertical":"horizontal",v=o?"manual":"auto",h=null!==i,g=(0,c.useLatestValue)({isControlled:h}),T=(0,f.useSyncRefs)(t),[w,x]=(0,a.useReducer)(I,{info:g,selectedIndex:null!=i?i:r,tabs:[],panels:[]}),F=(0,a.useMemo)(()=>({selectedIndex:w.selectedIndex}),[w.selectedIndex]),P=(0,c.useLatestValue)(s||(()=>{})),L=(0,c.useLatestValue)(w.tabs),C=(0,a.useMemo)(()=>({orientation:m,activation:v,...w}),[m,v,w]),S=(0,l.useEvent)(e=>(x({type:1,tab:e}),()=>x({type:2,tab:e}))),A=(0,l.useEvent)(e=>(x({type:3,panel:e}),()=>x({type:4,panel:e}))),M=(0,l.useEvent)(e=>{R.current!==e&&P.current(e),h||x({type:0,index:e})}),R=(0,c.useLatestValue)(h?e.selectedIndex:w.selectedIndex),O=(0,a.useMemo)(()=>({registerTab:S,registerPanel:A,change:M}),[]);(0,u.useIsoMorphicEffect)(()=>{x({type:0,index:null!=i?i:r})},[i]),(0,u.useIsoMorphicEffect)(()=>{if(void 0===R.current||w.tabs.length<=0)return;let e=(0,b.sortByDomNode)(w.tabs,e=>e.current);e.some((e,t)=>w.tabs[t]!==e)&&M(e.indexOf(w.tabs[R.current]))});let D=(0,y.useRender)();return a.default.createElement(E.StableCollection,null,a.default.createElement(N.Provider,{value:O},a.default.createElement(k.Provider,{value:C},C.tabs.length<=0&&a.default.createElement(p.FocusSentinel,{onFocus:()=>{var e,t;for(let r of L.current)if((null==(e=r.current)?void 0:e.tabIndex)===0)return null==(t=r.current)||t.focus(),!0;return!1}}),D({ourProps:{ref:T},theirProps:d,slot:F,defaultTag:"div",name:"Tabs"}))))}),List:(0,y.forwardRefWithAs)(function(e,t){let{orientation:r,selectedIndex:n}=L("Tab.List"),o=(0,f.useSyncRefs)(t),s=(0,a.useMemo)(()=>({selectedIndex:n}),[n]);return(0,y.useRender)()({ourProps:{ref:o,role:"tablist","aria-orientation":r},theirProps:e,slot:s,defaultTag:"div",name:"Tabs.List"})}),Panels:(0,y.forwardRefWithAs)(function(e,t){let{selectedIndex:r}=L("Tab.Panels"),n=(0,f.useSyncRefs)(t),o=(0,a.useMemo)(()=>({selectedIndex:r}),[r]);return(0,y.useRender)()({ourProps:{ref:n},theirProps:e,slot:o,defaultTag:"div",name:"Tabs.Panels"})}),Panel:(0,y.forwardRefWithAs)(function(e,t){var r,n,s,i;let l=(0,a.useId)(),{id:c=`headlessui-tabs-panel-${l}`,tabIndex:d=0,...p}=e,{selectedIndex:b,tabs:v,panels:h}=L("Tab.Panel"),g=C("Tab.Panel"),T=(0,a.useRef)(null),w=(0,f.useSyncRefs)(T,t);(0,u.useIsoMorphicEffect)(()=>g.registerPanel(T),[g,T]);let x=(0,E.useStableCollectionIndex)("panels"),F=h.indexOf(T);-1===F&&(F=x);let P=F===b,{isFocusVisible:k,focusProps:N}=(0,o.useFocusRing)(),I=(0,a.useMemo)(()=>({selected:P,focus:k}),[P,k]),A=(0,y.mergeProps)({ref:w,id:c,role:"tabpanel","aria-labelledby":null==(n=null==(r=v[F])?void 0:r.current)?void 0:n.id,tabIndex:P?d:-1},N),M=(0,y.useRender)();return P||null!=(s=p.unmount)&&!s||null!=(i=p.static)&&i?M({ourProps:A,theirProps:p,slot:I,defaultTag:"div",features:S,visible:P,name:"Tabs.Panel"}):a.default.createElement(m.Hidden,{"aria-hidden":"true",...A})})});e.s(["Tab",0,A])},405371,910342,e=>{"use strict";var t=e.i(290571),r=e.i(271645),n=e.i(480731);let o=(0,r.createContext)(n.BaseColors.Blue);e.s(["default",0,o],910342);var s=e.i(970554),a=e.i(444755);let i=(0,e.i(673706).makeClassName)("TabList"),l=(0,r.createContext)("line"),u={line:(0,a.tremorTwMerge)("flex border-b space-x-4","border-tremor-border","dark:border-dark-tremor-border"),solid:(0,a.tremorTwMerge)("inline-flex p-0.5 rounded-tremor-default space-x-1.5","bg-tremor-background-subtle","dark:bg-dark-tremor-background-subtle")},c=r.default.forwardRef((e,n)=>{let{color:c,variant:d="line",children:f,className:p}=e,m=(0,t.__rest)(e,["color","variant","children","className"]);return r.default.createElement(s.Tab.List,Object.assign({ref:n,className:(0,a.tremorTwMerge)(i("root"),"justify-start overflow-x-clip",u[d],p)},m),r.default.createElement(l.Provider,{value:d},r.default.createElement(o.Provider,{value:c},f)))});c.displayName="TabList",e.s(["TabVariantContext",0,l,"default",0,c],405371)},197647,e=>{"use strict";var t=e.i(290571),r=e.i(970554),n=e.i(95779),o=e.i(444755),s=e.i(673706),a=e.i(271645),i=e.i(405371),l=e.i(910342);let u=(0,s.makeClassName)("Tab"),c=a.default.forwardRef((e,c)=>{let{icon:d,className:f,children:p}=e,m=(0,t.__rest)(e,["icon","className","children"]),b=(0,a.useContext)(i.TabVariantContext),v=(0,a.useContext)(l.default);return a.default.createElement(r.Tab,Object.assign({ref:c,className:(0,o.tremorTwMerge)(u("root"),"flex whitespace-nowrap truncate max-w-xs outline-none data-focus-visible:ring text-tremor-default transition duration-100",function(e,t){switch(e){case"line":return(0,o.tremorTwMerge)("data-[selected]:border-b-2 hover:border-b-2 border-transparent transition duration-100 -mb-px px-2 py-2","hover:border-tremor-content hover:text-tremor-content-emphasis text-tremor-content","[&:not([data-selected])]:dark:hover:border-dark-tremor-content-emphasis [&:not([data-selected])]:dark:hover:text-dark-tremor-content-emphasis [&:not([data-selected])]:dark:text-dark-tremor-content",t?(0,s.getColorClassNames)(t,n.colorPalette.border).selectBorderColor:["data-[selected]:border-tremor-brand data-[selected]:text-tremor-brand","data-[selected]:dark:border-dark-tremor-brand data-[selected]:dark:text-dark-tremor-brand"]);case"solid":return(0,o.tremorTwMerge)("border-transparent border rounded-tremor-small px-2.5 py-1","data-[selected]:border-tremor-border data-[selected]:bg-tremor-background data-[selected]:shadow-tremor-input [&:not([data-selected])]:hover:text-tremor-content-emphasis data-[selected]:text-tremor-brand [&:not([data-selected])]:text-tremor-content","dark:data-[selected]:border-dark-tremor-border dark:data-[selected]:bg-dark-tremor-background dark:data-[selected]:shadow-dark-tremor-input dark:[&:not([data-selected])]:hover:text-dark-tremor-content-emphasis dark:data-[selected]:text-dark-tremor-brand dark:[&:not([data-selected])]:text-dark-tremor-content",t?(0,s.getColorClassNames)(t,n.colorPalette.text).selectTextColor:"text-tremor-content dark:text-dark-tremor-content")}}(b,v),f,v&&(0,s.getColorClassNames)(v,n.colorPalette.text).selectTextColor)},m),d?a.default.createElement(d,{className:(0,o.tremorTwMerge)(u("icon"),"flex-none h-5 w-5",p?"mr-2":"")}):null,p?a.default.createElement("span",null,p):null)});c.displayName="Tab",e.s(["Tab",0,c],197647)},653824,e=>{"use strict";var t=e.i(290571),r=e.i(970554),n=e.i(444755),o=e.i(673706),s=e.i(271645);let a=(0,o.makeClassName)("TabGroup"),i=s.default.forwardRef((e,o)=>{let{defaultIndex:i,index:l,onIndexChange:u,children:c,className:d}=e,f=(0,t.__rest)(e,["defaultIndex","index","onIndexChange","children","className"]);return s.default.createElement(r.Tab.Group,Object.assign({as:"div",ref:o,defaultIndex:i,selectedIndex:l,onChange:u,className:(0,n.tremorTwMerge)(a("root"),"w-full",d)},f),c)});i.displayName="TabGroup",e.s(["TabGroup",0,i],653824)},881073,e=>{"use strict";var t=e.i(405371);e.s(["TabList",()=>t.default])},723731,e=>{"use strict";var t=e.i(290571),r=e.i(970554),n=e.i(751734),o=e.i(144582),s=e.i(444755),a=e.i(673706),i=e.i(271645);let l=(0,a.makeClassName)("TabPanels"),u=i.default.forwardRef((e,a)=>{let{children:u,className:c}=e,d=(0,t.__rest)(e,["children","className"]);return i.default.createElement(r.Tab.Panels,Object.assign({as:"div",ref:a,className:(0,s.tremorTwMerge)(l("root"),"w-full",c)},d),({selectedIndex:e})=>i.default.createElement(o.default.Provider,{value:{selectedValue:e}},i.default.Children.map(u,(e,t)=>i.default.createElement(n.default.Provider,{value:t},e))))});u.displayName="TabPanels",e.s(["TabPanels",0,u],723731)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/023jsye4cz4a7.js b/litellm/proxy/_experimental/out/_next/static/chunks/023jsye4cz4a7.js deleted file mode 100644 index bf0033a1f49..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/023jsye4cz4a7.js +++ /dev/null @@ -1 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,916925,e=>{"use strict";var t,a=e.i(555987),l=((t={}).A2A_Agent="A2A Agent",t.AI21="Ai21",t.AI21_CHAT="Ai21 Chat",t.AIML="AI/ML API",t.AIOHTTP_OPENAI="Aiohttp Openai",t.Anthropic="Anthropic",t.ANTHROPIC_TEXT="Anthropic Text",t.AssemblyAI="AssemblyAI",t.AUTO_ROUTER="Auto Router",t.Bedrock="Amazon Bedrock",t.BedrockMantle="Amazon Bedrock Mantle",t.SageMaker="AWS SageMaker",t.Azure="Azure",t.Azure_AI_Studio="Azure AI Foundry (Studio)",t.AZURE_TEXT="Azure Text",t.BASETEN="Baseten",t.BYTEZ="Bytez",t.Cerebras="Cerebras",t.CLARIFAI="Clarifai",t.CLOUDFLARE="Cloudflare",t.CODESTRAL="Codestral",t.Cohere="Cohere",t.COHERE_CHAT="Cohere Chat",t.COMETAPI="Cometapi",t.COMPACTIFAI="Compactifai",t.Cursor="Cursor",t.Dashscope="Dashscope",t.Databricks="Databricks (Qwen API)",t.DATAROBOT="Datarobot",t.DeepInfra="DeepInfra",t.Deepgram="Deepgram",t.Deepseek="Deepseek",t.DOCKER_MODEL_RUNNER="Docker Model Runner",t.DOTPROMPT="Dotprompt",t.ElevenLabs="ElevenLabs",t.EMPOWER="Empower",t.FalAI="Fal AI",t.FEATHERLESS_AI="Featherless Ai",t.FireworksAI="Fireworks AI",t.FRIENDLIAI="Friendliai",t.GALADRIEL="Galadriel",t.GITHUB_COPILOT="Github Copilot",t.Google_AI_Studio="Google AI Studio",t.GradientAI="GradientAI",t.Groq="Groq",t.HEROKU="Heroku",t.Hosted_Vllm="vllm",t.HUGGINGFACE="Huggingface",t.HYPERBOLIC="Hyperbolic",t.Infinity="Infinity",t.JinaAI="Jina AI",t.LAMBDA_AI="Lambda Ai",t.LEMONADE="Lemonade",t.LLAMAFILE="Llamafile",t.LM_STUDIO="Lm Studio",t.LLAMA="Meta Llama",t.MARITALK="Maritalk",t.MiniMax="MiniMax",t.MistralAI="Mistral AI",t.MOONSHOT="Moonshot",t.MORPH="Morph",t.NEBIUS="Nebius",t.NLP_CLOUD="Nlp Cloud",t.NOVITA="Novita",t.NSCALE="Nscale",t.NVIDIA_NIM="Nvidia Nim",t.Ollama="Ollama",t.OLLAMA_CHAT="Ollama Chat",t.OOBABOOGA="Oobabooga",t.OpenAI="OpenAI",t.OPENAI_LIKE="Openai Like",t.OpenAI_Compatible="OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)",t.OpenAI_Text="OpenAI Text Completion",t.OpenAI_Text_Compatible="OpenAI-Compatible Completions (legacy /v1/completions)",t.Openrouter="Openrouter",t.Oracle="Oracle Cloud Infrastructure (OCI)",t.OVHCLOUD="Ovhcloud",t.Perplexity="Perplexity",t.PETALS="Petals",t.PG_VECTOR="Pg Vector",t.PREDIBASE="Predibase",t.RECRAFT="Recraft",t.REPLICATE="Replicate",t.RunwayML="RunwayML",t.SAGEMAKER_LEGACY="Sagemaker",t.Sambanova="Sambanova",t.SAP="SAP Generative AI Hub",t.Snowflake="Snowflake",t.Soniox="Soniox",t.TEXT_COMPLETION_CODESTRAL="Text-Completion-Codestral",t.TogetherAI="TogetherAI",t.TOPAZ="Topaz",t.Triton="Triton",t.V0="V0",t.VERCEL_AI_GATEWAY="Vercel Ai Gateway",t.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)",t.VERTEX_AI_BETA="Vertex Ai Beta",t.VLLM="Vllm",t.VolcEngine="VolcEngine",t.Voyage="Voyage AI",t.WANDB="Wandb",t.WATSONX="Watsonx",t.WATSONX_TEXT="Watsonx Text",t.xAI="xAI",t.XINFERENCE="Xinference",t.ZAI="Z.AI (Zhipu AI)",t);let n={A2A_Agent:"a2a_agent",AI21:"ai21",AI21_CHAT:"ai21_chat",AIML:"aiml",AIOHTTP_OPENAI:"aiohttp_openai",Anthropic:"anthropic",ANTHROPIC_TEXT:"anthropic_text",AssemblyAI:"assemblyai",AUTO_ROUTER:"auto_router",Azure:"azure",Azure_AI_Studio:"azure_ai",AZURE_TEXT:"azure_text",BASETEN:"baseten",Bedrock:"bedrock",BedrockMantle:"bedrock_mantle",BYTEZ:"bytez",Cerebras:"cerebras",CLARIFAI:"clarifai",CLOUDFLARE:"cloudflare",CODESTRAL:"codestral",Cohere:"cohere",COHERE_CHAT:"cohere_chat",COMETAPI:"cometapi",COMPACTIFAI:"compactifai",Cursor:"cursor",Dashscope:"dashscope",Databricks:"databricks",DATAROBOT:"datarobot",DeepInfra:"deepinfra",Deepgram:"deepgram",Deepseek:"deepseek",DOCKER_MODEL_RUNNER:"docker_model_runner",DOTPROMPT:"dotprompt",ElevenLabs:"elevenlabs",EMPOWER:"empower",FalAI:"fal_ai",FEATHERLESS_AI:"featherless_ai",FireworksAI:"fireworks_ai",FRIENDLIAI:"friendliai",GALADRIEL:"galadriel",GITHUB_COPILOT:"github_copilot",Google_AI_Studio:"gemini",GradientAI:"gradient_ai",Groq:"groq",HEROKU:"heroku",Hosted_Vllm:"hosted_vllm",HUGGINGFACE:"huggingface",HYPERBOLIC:"hyperbolic",Infinity:"infinity",JinaAI:"jina_ai",LAMBDA_AI:"lambda_ai",LEMONADE:"lemonade",LLAMAFILE:"llamafile",LLAMA:"meta_llama",LM_STUDIO:"lm_studio",MARITALK:"maritalk",MiniMax:"minimax",MistralAI:"mistral",MOONSHOT:"moonshot",MORPH:"morph",NEBIUS:"nebius",NLP_CLOUD:"nlp_cloud",NOVITA:"novita",NSCALE:"nscale",NVIDIA_NIM:"nvidia_nim",Ollama:"ollama",OLLAMA_CHAT:"ollama_chat",OOBABOOGA:"oobabooga",OpenAI:"openai",OPENAI_LIKE:"openai_like",OpenAI_Compatible:"openai",OpenAI_Text:"text-completion-openai",OpenAI_Text_Compatible:"text-completion-openai",Openrouter:"openrouter",Oracle:"oci",OVHCLOUD:"ovhcloud",Perplexity:"perplexity",PETALS:"petals",PG_VECTOR:"pg_vector",PREDIBASE:"predibase",RECRAFT:"recraft",REPLICATE:"replicate",RunwayML:"runwayml",SAGEMAKER_LEGACY:"sagemaker",SageMaker:"sagemaker_chat",Sambanova:"sambanova",SAP:"sap",Snowflake:"snowflake",Soniox:"soniox",TEXT_COMPLETION_CODESTRAL:"text-completion-codestral",TogetherAI:"together_ai",TOPAZ:"topaz",Triton:"triton",V0:"v0",VERCEL_AI_GATEWAY:"vercel_ai_gateway",Vertex_AI:"vertex_ai",VERTEX_AI_BETA:"vertex_ai_beta",VLLM:"vllm",VolcEngine:"volcengine",Voyage:"voyage",WANDB:"wandb",WATSONX:"watsonx",WATSONX_TEXT:"watsonx_text",xAI:"xai",XINFERENCE:"xinference",ZAI:"zai"},o=new Set(["bedrock_mantle"]),i="/ui/assets/logos/",r={"A2A Agent":`${i}a2a_agent.png`,Ai21:`${i}ai21.svg`,"Ai21 Chat":`${i}ai21.svg`,"AI/ML API":`${i}aiml_api.svg`,"Aiohttp Openai":`${i}openai_small.svg`,Anthropic:`${i}anthropic.svg`,"Anthropic Text":`${i}anthropic.svg`,AssemblyAI:`${i}assemblyai_small.png`,Azure:`${i}microsoft_azure.svg`,"Azure AI Foundry (Studio)":`${i}microsoft_azure.svg`,"Azure Text":`${i}microsoft_azure.svg`,Baseten:`${i}baseten.svg`,"Amazon Bedrock":`${i}bedrock.svg`,"Amazon Bedrock Mantle":`${i}bedrock.svg`,"AWS SageMaker":`${i}bedrock.svg`,Cerebras:`${i}cerebras.svg`,Cloudflare:`${i}cloudflare.svg`,Codestral:`${i}mistral.svg`,Cohere:`${i}cohere.svg`,"Cohere Chat":`${i}cohere.svg`,Cometapi:`${i}cometapi.svg`,Cursor:`${i}cursor.svg`,"Databricks (Qwen API)":`${i}databricks.svg`,Dashscope:`${i}dashscope.svg`,Deepseek:`${i}deepseek.svg`,Deepgram:`${i}deepgram.png`,DeepInfra:`${i}deepinfra.png`,ElevenLabs:`${i}elevenlabs.png`,"Fal AI":`${i}fal_ai.jpg`,"Featherless Ai":`${i}featherless.svg`,"Fireworks AI":`${i}fireworks.svg`,Friendliai:`${i}friendli.svg`,"Github Copilot":`${i}github_copilot.svg`,"Google AI Studio":`${i}google.svg`,GradientAI:`${i}gradientai.svg`,Groq:`${i}groq.svg`,vllm:`${i}vllm.png`,Huggingface:`${i}huggingface.svg`,Hyperbolic:`${i}hyperbolic.svg`,Infinity:`${i}infinity.png`,"Jina AI":`${i}jina.png`,"Lambda Ai":`${i}lambda.svg`,"Lm Studio":`${i}lmstudio.svg`,"Meta Llama":`${i}meta_llama.svg`,MiniMax:`${i}minimax.svg`,"Mistral AI":`${i}mistral.svg`,Moonshot:`${i}moonshot.svg`,Morph:`${i}morph.svg`,Nebius:`${i}nebius.svg`,Novita:`${i}novita.svg`,"Nvidia Nim":`${i}nvidia_nim.svg`,Ollama:`${i}ollama.svg`,"Ollama Chat":`${i}ollama.svg`,Oobabooga:`${i}openai_small.svg`,OpenAI:`${i}openai_small.svg`,"Openai Like":`${i}openai_small.svg`,"OpenAI Text Completion":`${i}openai_small.svg`,"OpenAI-Compatible Completions (legacy /v1/completions)":`${i}openai_small.svg`,"OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)":`${i}openai_small.svg`,Openrouter:`${i}openrouter.svg`,"Oracle Cloud Infrastructure (OCI)":`${i}oracle.svg`,Perplexity:`${i}perplexity-ai.svg`,Recraft:`${i}recraft.svg`,Replicate:`${i}replicate.svg`,RunwayML:`${i}runwayml.png`,Sagemaker:`${i}bedrock.svg`,Sambanova:`${i}sambanova.svg`,"SAP Generative AI Hub":`${i}sap.png`,Snowflake:`${i}snowflake.svg`,Soniox:`${i}soniox.svg`,"Text-Completion-Codestral":`${i}mistral.svg`,TogetherAI:`${i}togetherai.svg`,Topaz:`${i}topaz.svg`,Triton:`${i}nvidia_triton.png`,V0:`${i}v0.svg`,"Vercel Ai Gateway":`${i}vercel.svg`,"Vertex AI (Anthropic, Gemini, etc.)":`${i}google.svg`,"Vertex Ai Beta":`${i}google.svg`,Vllm:`${i}vllm.png`,VolcEngine:`${i}volcengine.png`,"Voyage AI":`${i}voyage.webp`,Watsonx:`${i}watsonx.svg`,"Watsonx Text":`${i}watsonx.svg`,xAI:`${i}xai.svg`,Xinference:`${i}xinference.svg`};e.s(["Providers",()=>l,"getPlaceholder",0,e=>{if("AI/ML API"===e)return"aiml/flux-pro/v1.1";if("Vertex AI (Anthropic, Gemini, etc.)"===e)return"gemini-pro";if("Anthropic"==e)return"claude-3-opus";if("Amazon Bedrock"==e)return"claude-3-opus";if("AWS SageMaker"==e)return"sagemaker/jumpstart-dft-meta-textgeneration-llama-2-7b";else if("Google AI Studio"==e)return"gemini-pro";else if("Azure AI Foundry (Studio)"==e)return"azure_ai/command-r-plus";else if("Azure"==e)return"my-deployment";else if("Oracle Cloud Infrastructure (OCI)"==e)return"oci/xai.grok-4";else if("Snowflake"==e)return"snowflake/mistral-7b";else if("Voyage AI"==e)return"voyage/";else if("Jina AI"==e)return"jina_ai/";else if("VolcEngine"==e)return"volcengine/";else if("DeepInfra"==e)return"deepinfra/";else if("Fal AI"==e)return"fal_ai/fal-ai/flux-pro/v1.1-ultra";else if("RunwayML"==e)return"runwayml/gen4_turbo";else if("Watsonx"===e)return"watsonx/ibm/granite-3-3-8b-instruct";else if("Cursor"===e)return"cursor/claude-4-sonnet";else if("Z.AI (Zhipu AI)"===e)return"zai/glm-4.5";else return"gpt-3.5-turbo"},"getProviderLogoAndName",0,e=>{if(!e)return{logo:"",displayName:"-"};if("gemini"===e.toLowerCase()){let e="Google AI Studio";return{logo:(0,a.resolveLogoSrc)(r[e])??"",displayName:e}}let t=Object.keys(n).find(t=>n[t].toLowerCase()===e.toLowerCase())??Object.keys(n).find(t=>t.toLowerCase()===e.toLowerCase());if(!t)return{logo:"",displayName:e};let o=l[t];return{logo:(0,a.resolveLogoSrc)(r[o])??"",displayName:o}},"getProviderModels",0,(e,t)=>{let a=n[e],l=[];return e&&"object"==typeof t&&(Object.entries(t).forEach(([e,t])=>{if(null!==t&&"object"==typeof t&&"litellm_provider"in t){let n=t.litellm_provider,i="string"==typeof n&&(n.startsWith(`${a}_`)||n.startsWith(`${a}-`));(n===a||i&&!o.has(n))&&l.push(e)}}),"Cohere"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"cohere_chat"===t.litellm_provider&&l.push(e)}),"AWS SageMaker"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"sagemaker_chat"===t.litellm_provider&&l.push(e)})),l},"providerLogoMap",0,r,"provider_map",0,n])},608856,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(343794),l=e.i(209428),n=e.i(392221),o=e.i(951160),i=e.i(174428),r=t.createContext(null),s=t.createContext({}),c=e.i(211577),d=e.i(931067),u=e.i(361275),m=e.i(404948),p=e.i(244009),g=e.i(703923),h=e.i(611935),f=["prefixCls","className","containerRef"];let b=function(e){var l=e.prefixCls,n=e.className,o=e.containerRef,i=(0,g.default)(e,f),r=t.useContext(s).panel,c=(0,h.useComposeRef)(r,o);return t.createElement("div",(0,d.default)({className:(0,a.default)("".concat(l,"-content"),n),role:"dialog",ref:c},(0,p.default)(e,{aria:!0}),{"aria-modal":"true"},i))};var x=e.i(883110);function v(e){return"string"==typeof e&&String(Number(e))===e?((0,x.default)(!1,"Invalid value type of `width` or `height` which should be number type instead."),Number(e)):e}var y={width:0,height:0,overflow:"hidden",outline:"none",position:"absolute"},w=t.forwardRef(function(e,o){var i,s,g,h=e.prefixCls,f=e.open,x=e.placement,w=e.inline,C=e.push,A=e.forceRender,j=e.autoFocus,k=e.keyboard,N=e.classNames,_=e.rootClassName,S=e.rootStyle,O=e.zIndex,I=e.className,E=e.id,$=e.style,T=e.motion,L=e.width,M=e.height,R=e.children,D=e.mask,P=e.maskClosable,H=e.maskMotion,z=e.maskClassName,B=e.maskStyle,F=e.afterOpenChange,V=e.onClose,U=e.onMouseEnter,W=e.onMouseOver,G=e.onMouseLeave,K=e.onClick,q=e.onKeyDown,X=e.onKeyUp,Y=e.styles,Z=e.drawerRender,Q=t.useRef(),J=t.useRef(),ee=t.useRef();t.useImperativeHandle(o,function(){return Q.current}),t.useEffect(function(){if(f&&j){var e;null==(e=Q.current)||e.focus({preventScroll:!0})}},[f]);var et=t.useState(!1),ea=(0,n.default)(et,2),el=ea[0],en=ea[1],eo=t.useContext(r),ei=null!=(i=null!=(s=null==(g="boolean"==typeof C?C?{}:{distance:0}:C||{})?void 0:g.distance)?s:null==eo?void 0:eo.pushDistance)?i:180,er=t.useMemo(function(){return{pushDistance:ei,push:function(){en(!0)},pull:function(){en(!1)}}},[ei]);t.useEffect(function(){var e,t;f?null==eo||null==(e=eo.push)||e.call(eo):null==eo||null==(t=eo.pull)||t.call(eo)},[f]),t.useEffect(function(){return function(){var e;null==eo||null==(e=eo.pull)||e.call(eo)}},[]);var es=t.createElement(u.default,(0,d.default)({key:"mask"},H,{visible:D&&f}),function(e,n){var o=e.className,i=e.style;return t.createElement("div",{className:(0,a.default)("".concat(h,"-mask"),o,null==N?void 0:N.mask,z),style:(0,l.default)((0,l.default)((0,l.default)({},i),B),null==Y?void 0:Y.mask),onClick:P&&f?V:void 0,ref:n})}),ec="function"==typeof T?T(x):T,ed={};if(el&&ei)switch(x){case"top":ed.transform="translateY(".concat(ei,"px)");break;case"bottom":ed.transform="translateY(".concat(-ei,"px)");break;case"left":ed.transform="translateX(".concat(ei,"px)");break;default:ed.transform="translateX(".concat(-ei,"px)")}"left"===x||"right"===x?ed.width=v(L):ed.height=v(M);var eu={onMouseEnter:U,onMouseOver:W,onMouseLeave:G,onClick:K,onKeyDown:q,onKeyUp:X},em=t.createElement(u.default,(0,d.default)({key:"panel"},ec,{visible:f,forceRender:A,onVisibleChanged:function(e){null==F||F(e)},removeOnLeave:!1,leavedClassName:"".concat(h,"-content-wrapper-hidden")}),function(n,o){var i=n.className,r=n.style,s=t.createElement(b,(0,d.default)({id:E,containerRef:o,prefixCls:h,className:(0,a.default)(I,null==N?void 0:N.content),style:(0,l.default)((0,l.default)({},$),null==Y?void 0:Y.content)},(0,p.default)(e,{aria:!0}),eu),R);return t.createElement("div",(0,d.default)({className:(0,a.default)("".concat(h,"-content-wrapper"),null==N?void 0:N.wrapper,i),style:(0,l.default)((0,l.default)((0,l.default)({},ed),r),null==Y?void 0:Y.wrapper)},(0,p.default)(e,{data:!0})),Z?Z(s):s)}),ep=(0,l.default)({},S);return O&&(ep.zIndex=O),t.createElement(r.Provider,{value:er},t.createElement("div",{className:(0,a.default)(h,"".concat(h,"-").concat(x),_,(0,c.default)((0,c.default)({},"".concat(h,"-open"),f),"".concat(h,"-inline"),w)),style:ep,tabIndex:-1,ref:Q,onKeyDown:function(e){var t,a,l=e.keyCode,n=e.shiftKey;switch(l){case m.default.TAB:l===m.default.TAB&&(n||document.activeElement!==ee.current?n&&document.activeElement===J.current&&(null==(a=ee.current)||a.focus({preventScroll:!0})):null==(t=J.current)||t.focus({preventScroll:!0}));break;case m.default.ESC:V&&k&&(e.stopPropagation(),V(e))}}},es,t.createElement("div",{tabIndex:0,ref:J,style:y,"aria-hidden":"true","data-sentinel":"start"}),em,t.createElement("div",{tabIndex:0,ref:ee,style:y,"aria-hidden":"true","data-sentinel":"end"})))});let C=function(e){var a=e.open,r=e.prefixCls,c=e.placement,d=e.autoFocus,u=e.keyboard,m=e.width,p=e.mask,g=void 0===p||p,h=e.maskClosable,f=e.getContainer,b=e.forceRender,x=e.afterOpenChange,v=e.destroyOnClose,y=e.onMouseEnter,C=e.onMouseOver,A=e.onMouseLeave,j=e.onClick,k=e.onKeyDown,N=e.onKeyUp,_=e.panelRef,S=t.useState(!1),O=(0,n.default)(S,2),I=O[0],E=O[1],$=t.useState(!1),T=(0,n.default)($,2),L=T[0],M=T[1];(0,i.default)(function(){M(!0)},[]);var R=!!L&&void 0!==a&&a,D=t.useRef(),P=t.useRef();(0,i.default)(function(){R&&(P.current=document.activeElement)},[R]);var H=t.useMemo(function(){return{panel:_}},[_]);if(!b&&!I&&!R&&v)return null;var z=(0,l.default)((0,l.default)({},e),{},{open:R,prefixCls:void 0===r?"rc-drawer":r,placement:void 0===c?"right":c,autoFocus:void 0===d||d,keyboard:void 0===u||u,width:void 0===m?378:m,mask:g,maskClosable:void 0===h||h,inline:!1===f,afterOpenChange:function(e){var t,a;E(e),null==x||x(e),e||!P.current||null!=(t=D.current)&&t.contains(P.current)||null==(a=P.current)||a.focus({preventScroll:!0})},ref:D},{onMouseEnter:y,onMouseOver:C,onMouseLeave:A,onClick:j,onKeyDown:k,onKeyUp:N});return t.createElement(s.Provider,{value:H},t.createElement(o.default,{open:R||b||I,autoDestroy:!1,getContainer:f,autoLock:g&&(R||I)},t.createElement(w,z)))};var A=e.i(981444),j=e.i(617206),k=e.i(122767),N=e.i(613541),_=e.i(340010),S=e.i(242064),O=e.i(922611),I=e.i(563113),E=e.i(185793);let $=e=>{var l,n,o,i;let r,{prefixCls:s,ariaId:c,title:d,footer:u,extra:m,closable:p,loading:g,onClose:h,headerStyle:f,bodyStyle:b,footerStyle:x,children:v,classNames:y,styles:w}=e,C=(0,S.useComponentConfig)("drawer");r=!1===p?void 0:void 0===p||!0===p?"start":(null==p?void 0:p.placement)==="end"?"end":"start";let A=t.useCallback(e=>t.createElement("button",{type:"button",onClick:h,className:(0,a.default)(`${s}-close`,{[`${s}-close-${r}`]:"end"===r})},e),[h,s,r]),[j,k]=(0,I.useClosable)((0,I.pickClosable)(e),(0,I.pickClosable)(C),{closable:!0,closeIconRender:A});return t.createElement(t.Fragment,null,d||j?t.createElement("div",{style:Object.assign(Object.assign(Object.assign({},null==(o=C.styles)?void 0:o.header),f),null==w?void 0:w.header),className:(0,a.default)(`${s}-header`,{[`${s}-header-close-only`]:j&&!d&&!m},null==(i=C.classNames)?void 0:i.header,null==y?void 0:y.header)},t.createElement("div",{className:`${s}-header-title`},"start"===r&&k,d&&t.createElement("div",{className:`${s}-title`,id:c},d)),m&&t.createElement("div",{className:`${s}-extra`},m),"end"===r&&k):null,t.createElement("div",{className:(0,a.default)(`${s}-body`,null==y?void 0:y.body,null==(l=C.classNames)?void 0:l.body),style:Object.assign(Object.assign(Object.assign({},null==(n=C.styles)?void 0:n.body),b),null==w?void 0:w.body)},g?t.createElement(E.default,{active:!0,title:!1,paragraph:{rows:5},className:`${s}-body-skeleton`}):v),(()=>{var e,l;if(!u)return null;let n=`${s}-footer`;return t.createElement("div",{className:(0,a.default)(n,null==(e=C.classNames)?void 0:e.footer,null==y?void 0:y.footer),style:Object.assign(Object.assign(Object.assign({},null==(l=C.styles)?void 0:l.footer),x),null==w?void 0:w.footer)},u)})())};e.i(296059);var T=e.i(915654),L=e.i(183293),M=e.i(246422),R=e.i(838378);let D=(e,t)=>({"&-enter, &-appear":Object.assign(Object.assign({},e),{"&-active":t}),"&-leave":Object.assign(Object.assign({},t),{"&-active":e})}),P=(e,t)=>Object.assign({"&-enter, &-appear, &-leave":{"&-start":{transition:"none"},"&-active":{transition:`all ${t}`}}},D({opacity:e},{opacity:1})),H=(0,M.genStyleHooks)("Drawer",e=>{let t=(0,R.mergeToken)(e,{});return[(e=>{let{borderRadiusSM:t,componentCls:a,zIndexPopup:l,colorBgMask:n,colorBgElevated:o,motionDurationSlow:i,motionDurationMid:r,paddingXS:s,padding:c,paddingLG:d,fontSizeLG:u,lineHeightLG:m,lineWidth:p,lineType:g,colorSplit:h,marginXS:f,colorIcon:b,colorIconHover:x,colorBgTextHover:v,colorBgTextActive:y,colorText:w,fontWeightStrong:C,footerPaddingBlock:A,footerPaddingInline:j,calc:k}=e,N=`${a}-content-wrapper`;return{[a]:{position:"fixed",inset:0,zIndex:l,pointerEvents:"none",color:w,"&-pure":{position:"relative",background:o,display:"flex",flexDirection:"column",[`&${a}-left`]:{boxShadow:e.boxShadowDrawerLeft},[`&${a}-right`]:{boxShadow:e.boxShadowDrawerRight},[`&${a}-top`]:{boxShadow:e.boxShadowDrawerUp},[`&${a}-bottom`]:{boxShadow:e.boxShadowDrawerDown}},"&-inline":{position:"absolute"},[`${a}-mask`]:{position:"absolute",inset:0,zIndex:l,background:n,pointerEvents:"auto"},[N]:{position:"absolute",zIndex:l,maxWidth:"100vw",transition:`all ${i}`,"&-hidden":{display:"none"}},[`&-left > ${N}`]:{top:0,bottom:0,left:{_skip_check_:!0,value:0},boxShadow:e.boxShadowDrawerLeft},[`&-right > ${N}`]:{top:0,right:{_skip_check_:!0,value:0},bottom:0,boxShadow:e.boxShadowDrawerRight},[`&-top > ${N}`]:{top:0,insetInline:0,boxShadow:e.boxShadowDrawerUp},[`&-bottom > ${N}`]:{bottom:0,insetInline:0,boxShadow:e.boxShadowDrawerDown},[`${a}-content`]:{display:"flex",flexDirection:"column",width:"100%",height:"100%",overflow:"auto",background:o,pointerEvents:"auto"},[`${a}-header`]:{display:"flex",flex:0,alignItems:"center",padding:`${(0,T.unit)(c)} ${(0,T.unit)(d)}`,fontSize:u,lineHeight:m,borderBottom:`${(0,T.unit)(p)} ${g} ${h}`,"&-title":{display:"flex",flex:1,alignItems:"center",minWidth:0,minHeight:0}},[`${a}-extra`]:{flex:"none"},[`${a}-close`]:Object.assign({display:"inline-flex",width:k(u).add(s).equal(),height:k(u).add(s).equal(),borderRadius:t,justifyContent:"center",alignItems:"center",color:b,fontWeight:C,fontSize:u,fontStyle:"normal",lineHeight:1,textAlign:"center",textTransform:"none",textDecoration:"none",background:"transparent",border:0,cursor:"pointer",transition:`all ${r}`,textRendering:"auto",[`&${a}-close-end`]:{marginInlineStart:f},[`&:not(${a}-close-end)`]:{marginInlineEnd:f},"&:hover":{color:x,backgroundColor:v,textDecoration:"none"},"&:active":{backgroundColor:y}},(0,L.genFocusStyle)(e)),[`${a}-title`]:{flex:1,margin:0,fontWeight:e.fontWeightStrong,fontSize:u,lineHeight:m},[`${a}-body`]:{flex:1,minWidth:0,minHeight:0,padding:d,overflow:"auto",[`${a}-body-skeleton`]:{width:"100%",height:"100%",display:"flex",justifyContent:"center"}},[`${a}-footer`]:{flexShrink:0,padding:`${(0,T.unit)(A)} ${(0,T.unit)(j)}`,borderTop:`${(0,T.unit)(p)} ${g} ${h}`},"&-rtl":{direction:"rtl"}}}})(t),(e=>{let{componentCls:t,motionDurationSlow:a}=e;return{[t]:{[`${t}-mask-motion`]:P(0,a),[`${t}-panel-motion`]:["left","right","top","bottom"].reduce((e,t)=>{let l;return Object.assign(Object.assign({},e),{[`&-${t}`]:[P(.7,a),D({transform:(l="100%",({left:`translateX(-${l})`,right:`translateX(${l})`,top:`translateY(-${l})`,bottom:`translateY(${l})`})[t])},{transform:"none"})]})},{})}}})(t)]},e=>({zIndexPopup:e.zIndexPopupBase,footerPaddingBlock:e.paddingXS,footerPaddingInline:e.padding}));var z=function(e,t){var a={};for(var l in e)Object.prototype.hasOwnProperty.call(e,l)&&0>t.indexOf(l)&&(a[l]=e[l]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var n=0,l=Object.getOwnPropertySymbols(e);nt.indexOf(l[n])&&Object.prototype.propertyIsEnumerable.call(e,l[n])&&(a[l[n]]=e[l[n]]);return a};let B={distance:180},F=e=>{let{rootClassName:l,width:n,height:o,size:i="default",mask:r=!0,push:s=B,open:c,afterOpenChange:d,onClose:u,prefixCls:m,getContainer:p,panelRef:g=null,style:f,className:b,"aria-labelledby":x,visible:v,afterVisibleChange:y,maskStyle:w,drawerStyle:I,contentWrapperStyle:E,destroyOnClose:T,destroyOnHidden:L}=e,M=z(e,["rootClassName","width","height","size","mask","push","open","afterOpenChange","onClose","prefixCls","getContainer","panelRef","style","className","aria-labelledby","visible","afterVisibleChange","maskStyle","drawerStyle","contentWrapperStyle","destroyOnClose","destroyOnHidden"]),R=(0,A.default)(),D=M.title?R:void 0,{getPopupContainer:P,getPrefixCls:F,direction:V,className:U,style:W,classNames:G,styles:K}=(0,S.useComponentConfig)("drawer"),q=F("drawer",m),[X,Y,Z]=H(q),Q=void 0===p&&P?()=>P(document.body):p,J=(0,a.default)({"no-mask":!r,[`${q}-rtl`]:"rtl"===V},l,Y,Z),ee=t.useMemo(()=>null!=n?n:"large"===i?736:378,[n,i]),et=t.useMemo(()=>null!=o?o:"large"===i?736:378,[o,i]),ea={motionName:(0,N.getTransitionName)(q,"mask-motion"),motionAppear:!0,motionEnter:!0,motionLeave:!0,motionDeadline:500},el=(0,O.usePanelRef)(),en=(0,h.composeRef)(g,el),[eo,ei]=(0,k.useZIndex)("Drawer",M.zIndex),{classNames:er={},styles:es={}}=M;return X(t.createElement(j.default,{form:!0,space:!0},t.createElement(_.default.Provider,{value:ei},t.createElement(C,Object.assign({prefixCls:q,onClose:u,maskMotion:ea,motion:e=>({motionName:(0,N.getTransitionName)(q,`panel-motion-${e}`),motionAppear:!0,motionEnter:!0,motionLeave:!0,motionDeadline:500})},M,{classNames:{mask:(0,a.default)(er.mask,G.mask),content:(0,a.default)(er.content,G.content),wrapper:(0,a.default)(er.wrapper,G.wrapper)},styles:{mask:Object.assign(Object.assign(Object.assign({},es.mask),w),K.mask),content:Object.assign(Object.assign(Object.assign({},es.content),I),K.content),wrapper:Object.assign(Object.assign(Object.assign({},es.wrapper),E),K.wrapper)},open:null!=c?c:v,mask:r,push:s,width:ee,height:et,style:Object.assign(Object.assign({},W),f),className:(0,a.default)(U,b),rootClassName:J,getContainer:Q,afterOpenChange:null!=d?d:y,panelRef:en,zIndex:eo,"aria-labelledby":null!=x?x:D,destroyOnClose:null!=L?L:T}),t.createElement($,Object.assign({prefixCls:q},M,{ariaId:D,onClose:u}))))))};F._InternalPanelDoNotUseOrYouWillBeFired=e=>{let{prefixCls:l,style:n,className:o,placement:i="right"}=e,r=z(e,["prefixCls","style","className","placement"]),{getPrefixCls:s}=t.useContext(S.ConfigContext),c=s("drawer",l),[d,u,m]=H(c),p=(0,a.default)(c,`${c}-pure`,`${c}-${i}`,u,m,o);return d(t.createElement("div",{className:p,style:n},t.createElement($,Object.assign({prefixCls:c},r))))},e.s(["Drawer",0,F],608856)},560025,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(343794),l=e.i(931067),n=e.i(392221),o=e.i(703923),i=e.i(211577),r=e.i(209428),s=e.i(410160),c=e.i(914949),d=e.i(529681),u=e.i(611935),m=e.i(361275),p=e.i(174428),g=function(e,t){if(!e)return null;var a={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:a.top,bottom:a.bottom,height:a.height}:{left:a.left,right:a.right,width:a.width,top:0,bottom:0,height:0}},h=function(e){return void 0!==e?"".concat(e,"px"):void 0};function f(e){var l=e.prefixCls,o=e.containerRef,i=e.value,s=e.getValueIndex,c=e.motionName,d=e.onMotionStart,f=e.onMotionEnd,b=e.direction,x=e.vertical,v=void 0!==x&&x,y=t.useRef(null),w=t.useState(i),C=(0,n.default)(w,2),A=C[0],j=C[1],k=function(e){var t,a=s(e),n=null==(t=o.current)?void 0:t.querySelectorAll(".".concat(l,"-item"))[a];return(null==n?void 0:n.offsetParent)&&n},N=t.useState(null),_=(0,n.default)(N,2),S=_[0],O=_[1],I=t.useState(null),E=(0,n.default)(I,2),$=E[0],T=E[1];(0,p.default)(function(){if(A!==i){var e=k(A),t=k(i),a=g(e,v),l=g(t,v);j(i),O(a),T(l),e&&t?d():f()}},[i]);var L=t.useMemo(function(){if(v){var e;return h(null!=(e=null==S?void 0:S.top)?e:0)}return"rtl"===b?h(-(null==S?void 0:S.right)):h(null==S?void 0:S.left)},[v,b,S]),M=t.useMemo(function(){if(v){var e;return h(null!=(e=null==$?void 0:$.top)?e:0)}return"rtl"===b?h(-(null==$?void 0:$.right)):h(null==$?void 0:$.left)},[v,b,$]);return S&&$?t.createElement(m.default,{visible:!0,motionName:c,motionAppear:!0,onAppearStart:function(){return v?{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 v?{transform:"translateY(var(--thumb-active-top))",height:"var(--thumb-active-height)"}:{transform:"translateX(var(--thumb-active-left))",width:"var(--thumb-active-width)"}},onVisibleChanged:function(){O(null),T(null),f()}},function(e,n){var o=e.className,i=e.style,s=(0,r.default)((0,r.default)({},i),{},{"--thumb-start-left":L,"--thumb-start-width":h(null==S?void 0:S.width),"--thumb-active-left":M,"--thumb-active-width":h(null==$?void 0:$.width),"--thumb-start-top":L,"--thumb-start-height":h(null==S?void 0:S.height),"--thumb-active-top":M,"--thumb-active-height":h(null==$?void 0:$.height)}),c={ref:(0,u.composeRef)(y,n),style:s,className:(0,a.default)("".concat(l,"-thumb"),o)};return t.createElement("div",c)}):null}var b=["prefixCls","direction","vertical","options","disabled","defaultValue","value","name","onChange","className","motionName"],x=function(e){var l=e.prefixCls,n=e.className,o=e.disabled,r=e.checked,s=e.label,c=e.title,d=e.value,u=e.name,m=e.onChange,p=e.onFocus,g=e.onBlur,h=e.onKeyDown,f=e.onKeyUp,b=e.onMouseDown;return t.createElement("label",{className:(0,a.default)(n,(0,i.default)({},"".concat(l,"-item-disabled"),o)),onMouseDown:b},t.createElement("input",{name:u,className:"".concat(l,"-item-input"),type:"radio",disabled:o,checked:r,onChange:function(e){o||m(e,d)},onFocus:p,onBlur:g,onKeyDown:h,onKeyUp:f}),t.createElement("div",{className:"".concat(l,"-item-label"),title:c},s))},v=t.forwardRef(function(e,m){var p,g=e.prefixCls,h=void 0===g?"rc-segmented":g,v=e.direction,y=e.vertical,w=e.options,C=void 0===w?[]:w,A=e.disabled,j=e.defaultValue,k=e.value,N=e.name,_=e.onChange,S=e.className,O=e.motionName,I=(0,o.default)(e,b),E=t.useRef(null),$=t.useMemo(function(){return(0,u.composeRef)(E,m)},[E,m]),T=t.useMemo(function(){return C.map(function(e){if("object"===(0,s.default)(e)&&null!==e){var t=function(e){if(void 0!==e.title)return e.title;if("object"!==(0,s.default)(e.label)){var t;return null==(t=e.label)?void 0:t.toString()}}(e);return(0,r.default)((0,r.default)({},e),{},{title:t})}return{label:null==e?void 0:e.toString(),title:null==e?void 0:e.toString(),value:e}})},[C]),L=(0,c.default)(null==(p=T[0])?void 0:p.value,{value:k,defaultValue:j}),M=(0,n.default)(L,2),R=M[0],D=M[1],P=t.useState(!1),H=(0,n.default)(P,2),z=H[0],B=H[1],F=function(e,t){D(t),null==_||_(t)},V=(0,d.default)(I,["children"]),U=t.useState(!1),W=(0,n.default)(U,2),G=W[0],K=W[1],q=t.useState(!1),X=(0,n.default)(q,2),Y=X[0],Z=X[1],Q=function(){Z(!0)},J=function(){Z(!1)},ee=function(){K(!1)},et=function(e){"Tab"===e.key&&K(!0)},ea=function(e){var t=T.findIndex(function(e){return e.value===R}),a=T.length,l=T[(t+e+a)%a];l&&(D(l.value),null==_||_(l.value))},el=function(e){switch(e.key){case"ArrowLeft":case"ArrowUp":ea(-1);break;case"ArrowRight":case"ArrowDown":ea(1)}};return t.createElement("div",(0,l.default)({role:"radiogroup","aria-label":"segmented control",tabIndex:A?void 0:0,"aria-orientation":y?"vertical":"horizontal"},V,{className:(0,a.default)(h,(0,i.default)((0,i.default)((0,i.default)({},"".concat(h,"-rtl"),"rtl"===v),"".concat(h,"-disabled"),A),"".concat(h,"-vertical"),y),void 0===S?"":S),ref:$}),t.createElement("div",{className:"".concat(h,"-group")},t.createElement(f,{vertical:y,prefixCls:h,value:R,containerRef:E,motionName:"".concat(h,"-").concat(void 0===O?"thumb-motion":O),direction:v,getValueIndex:function(e){return T.findIndex(function(t){return t.value===e})},onMotionStart:function(){B(!0)},onMotionEnd:function(){B(!1)}}),T.map(function(e){return t.createElement(x,(0,l.default)({},e,{name:N,key:e.value,prefixCls:h,className:(0,a.default)(e.className,"".concat(h,"-item"),(0,i.default)((0,i.default)({},"".concat(h,"-item-selected"),e.value===R&&!z),"".concat(h,"-item-focused"),Y&&G&&e.value===R)),checked:e.value===R,onChange:F,onFocus:Q,onBlur:J,onKeyDown:el,onKeyUp:et,onMouseDown:ee,disabled:!!A||!!e.disabled}))})))}),y=e.i(981444),w=e.i(242064),C=e.i(517455);e.i(296059);var A=e.i(915654),j=e.i(183293),k=e.i(246422),N=e.i(838378);function _(e,t){return{[`${e}, ${e}:hover, ${e}:focus`]:{color:t.colorTextDisabled,cursor:"not-allowed"}}}function S(e){return{background:e.itemSelectedBg,boxShadow:e.boxShadowTertiary}}let O=Object.assign({overflow:"hidden"},j.textEllipsis),I=(0,k.genStyleHooks)("Segmented",e=>{let{lineWidth:t,calc:a}=e;return(e=>{let{componentCls:t}=e,a=e.calc(e.controlHeight).sub(e.calc(e.trackPadding).mul(2)).equal(),l=e.calc(e.controlHeightLG).sub(e.calc(e.trackPadding).mul(2)).equal(),n=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,j.resetComponent)(e)),{display:"inline-block",padding:e.trackPadding,color:e.itemColor,background:e.trackBg,borderRadius:e.borderRadius,transition:`all ${e.motionDurationMid}`}),(0,j.genFocusStyle)(e)),{[`${t}-group`]:{position:"relative",display:"flex",alignItems:"stretch",justifyItems:"flex-start",flexDirection:"row",width:"100%"},[`&${t}-rtl`]:{direction:"rtl"},[`&${t}-vertical`]:{[`${t}-group`]:{flexDirection:"column"},[`${t}-thumb`]:{width:"100%",height:0,padding:`0 ${(0,A.unit)(e.paddingXXS)}`}},[`&${t}-block`]:{display:"flex"},[`&${t}-block ${t}-item`]:{flex:1,minWidth:0},[`${t}-item`]:{position:"relative",textAlign:"center",cursor:"pointer",transition:`color ${e.motionDurationMid}`,borderRadius:e.borderRadiusSM,transform:"translateZ(0)","&-selected":Object.assign(Object.assign({},S(e)),{color:e.itemSelectedColor}),"&-focused":(0,j.genFocusOutline)(e),"&::after":{content:'""',position:"absolute",zIndex:-1,width:"100%",height:"100%",top:0,insetInlineStart:0,borderRadius:"inherit",opacity:0,transition:`opacity ${e.motionDurationMid}, background-color ${e.motionDurationMid}`,pointerEvents:"none"},[`&:not(${t}-item-selected):not(${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:a,lineHeight:(0,A.unit)(a),padding:`0 ${(0,A.unit)(e.segmentedPaddingHorizontal)}`},O),"&-icon + *":{marginInlineStart:e.calc(e.marginSM).div(2).equal()},"&-input":{position:"absolute",insetBlockStart:0,insetInlineStart:0,width:0,height:0,opacity:0,pointerEvents:"none"}},[`${t}-thumb`]:Object.assign(Object.assign({},S(e)),{position:"absolute",insetBlockStart:0,insetInlineStart:0,width:0,height:"100%",padding:`${(0,A.unit)(e.paddingXXS)} 0`,borderRadius:e.borderRadiusSM,[`& ~ ${t}-item:not(${t}-item-selected):not(${t}-item-disabled)::after`]:{backgroundColor:"transparent"}}),[`&${t}-lg`]:{borderRadius:e.borderRadiusLG,[`${t}-item-label`]:{minHeight:l,lineHeight:(0,A.unit)(l),padding:`0 ${(0,A.unit)(e.segmentedPaddingHorizontal)}`,fontSize:e.fontSizeLG},[`${t}-item, ${t}-thumb`]:{borderRadius:e.borderRadius}},[`&${t}-sm`]:{borderRadius:e.borderRadiusSM,[`${t}-item-label`]:{minHeight:n,lineHeight:(0,A.unit)(n),padding:`0 ${(0,A.unit)(e.segmentedPaddingHorizontalSM)}`},[`${t}-item, ${t}-thumb`]:{borderRadius:e.borderRadiusXS}}}),_(`&-disabled ${t}-item`,e)),_(`${t}-item-disabled`,e)),{[`${t}-thumb-motion-appear-active`]:{transition:`transform ${e.motionDurationSlow} ${e.motionEaseInOut}, width ${e.motionDurationSlow} ${e.motionEaseInOut}`,willChange:"transform, width"},[`&${t}-shape-round`]:{borderRadius:9999,[`${t}-item, ${t}-thumb`]:{borderRadius:9999}}})}})((0,N.mergeToken)(e,{segmentedPaddingHorizontal:a(e.controlPaddingHorizontal).sub(t).equal(),segmentedPaddingHorizontalSM:a(e.controlPaddingHorizontalSM).sub(t).equal()}))},e=>{let{colorTextLabel:t,colorText:a,colorFillSecondary:l,colorBgElevated:n,colorFill:o,lineWidthBold:i,colorBgLayout:r}=e;return{trackPadding:i,trackBg:r,itemColor:t,itemHoverColor:a,itemHoverBg:l,itemSelectedBg:n,itemActiveBg:o,itemSelectedColor:a}});var E=function(e,t){var a={};for(var l in e)Object.prototype.hasOwnProperty.call(e,l)&&0>t.indexOf(l)&&(a[l]=e[l]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var n=0,l=Object.getOwnPropertySymbols(e);nt.indexOf(l[n])&&Object.prototype.propertyIsEnumerable.call(e,l[n])&&(a[l[n]]=e[l[n]]);return a};let $=t.forwardRef((e,l)=>{let n=(0,y.default)(),{prefixCls:o,className:i,rootClassName:r,block:s,options:c=[],size:d="middle",style:u,vertical:m,shape:p="default",name:g=n}=e,h=E(e,["prefixCls","className","rootClassName","block","options","size","style","vertical","shape","name"]),{getPrefixCls:f,direction:b,className:x,style:A}=(0,w.useComponentConfig)("segmented"),j=f("segmented",o),[k,N,_]=I(j),S=(0,C.default)(d),O=t.useMemo(()=>c.map(e=>{if("object"==typeof e&&(null==e?void 0:e.icon)){let{icon:a,label:l}=e;return Object.assign(Object.assign({},E(e,["icon","label"])),{label:t.createElement(t.Fragment,null,t.createElement("span",{className:`${j}-item-icon`},a),l&&t.createElement("span",null,l))})}return e}),[c,j]),$=(0,a.default)(i,r,x,{[`${j}-block`]:s,[`${j}-sm`]:"small"===S,[`${j}-lg`]:"large"===S,[`${j}-vertical`]:m,[`${j}-shape-${p}`]:"round"===p},N,_),T=Object.assign(Object.assign({},A),u);return k(t.createElement(v,Object.assign({},h,{name:g,className:$,style:T,options:O,ref:l,prefixCls:j,direction:b,vertical:m})))});e.s(["Segmented",0,$],560025)},94629,e=>{"use strict";var t=e.i(271645);let a=t.forwardRef(function(e,a){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:a},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4"}))});e.s(["SwitchVerticalIcon",0,a],94629)},836991,e=>{"use strict";var t=e.i(271645);let a=t.forwardRef(function(e,a){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:a},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"}))});e.s(["XIcon",0,a],836991)},446891,e=>{"use strict";var t=e.i(843476),a=e.i(464571),l=e.i(326373),n=e.i(94629),o=e.i(360820),i=e.i(871943),r=e.i(836991);e.s(["TableHeaderSortDropdown",0,({sortState:e,onSortChange:s})=>{let c=[{key:"asc",label:"Ascending",icon:(0,t.jsx)(o.ChevronUpIcon,{className:"h-4 w-4"})},{key:"desc",label:"Descending",icon:(0,t.jsx)(i.ChevronDownIcon,{className:"h-4 w-4"})},{key:"reset",label:"Reset",icon:(0,t.jsx)(r.XIcon,{className:"h-4 w-4"})}];return(0,t.jsx)(l.Dropdown,{menu:{items:c,onClick:({key:e})=>{"asc"===e?s("asc"):"desc"===e?s("desc"):"reset"===e&&s(!1)},selectable:!0,selectedKeys:e?[e]:[]},trigger:["click"],autoAdjustOverflow:!0,children:(0,t.jsx)(a.Button,{type:"text",onClick:e=>e.stopPropagation(),icon:"asc"===e?(0,t.jsx)(o.ChevronUpIcon,{className:"h-4 w-4"}):"desc"===e?(0,t.jsx)(i.ChevronDownIcon,{className:"h-4 w-4"}):(0,t.jsx)(n.SwitchVerticalIcon,{className:"h-4 w-4"}),className:e?"text-blue-500 hover:text-blue-600":"text-gray-400 hover:text-blue-500"})})}])},366308,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let l={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M876.6 239.5c-.5-.9-1.2-1.8-2-2.5-5-5-13.1-5-18.1 0L684.2 409.3l-67.9-67.9L788.7 169c.8-.8 1.4-1.6 2-2.5 3.6-6.1 1.6-13.9-4.5-17.5-98.2-58-226.8-44.7-311.3 39.7-67 67-89.2 162-66.5 247.4l-293 293c-3 3-2.8 7.9.3 11l169.7 169.7c3.1 3.1 8.1 3.3 11 .3l292.9-292.9c85.5 22.8 180.5.7 247.6-66.4 84.4-84.5 97.7-213.1 39.7-311.3zM786 499.8c-58.1 58.1-145.3 69.3-214.6 33.6l-8.8 8.8-.1-.1-274 274.1-79.2-79.2 230.1-230.1s0 .1.1.1l52.8-52.8c-35.7-69.3-24.5-156.5 33.6-214.6a184.2 184.2 0 01144-53.5L537 318.9a32.05 32.05 0 000 45.3l124.5 124.5a32.05 32.05 0 0045.3 0l132.8-132.8c3.7 51.8-14.4 104.8-53.6 143.9z"}}]},name:"tool",theme:"outlined"};var n=e.i(9583),o=a.forwardRef(function(e,o){return a.createElement(n.default,(0,t.default)({},e,{ref:o,icon:l}))});e.s(["ToolOutlined",0,o],366308)},518617,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let l={icon:{tag:"svg",attrs:{"fill-rule":"evenodd",viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64c247.4 0 448 200.6 448 448S759.4 960 512 960 64 759.4 64 512 264.6 64 512 64zm0 76c-205.4 0-372 166.6-372 372s166.6 372 372 372 372-166.6 372-372-166.6-372-372-372zm128.01 198.83c.03 0 .05.01.09.06l45.02 45.01a.2.2 0 01.05.09.12.12 0 010 .07c0 .02-.01.04-.05.08L557.25 512l127.87 127.86a.27.27 0 01.05.06v.02a.12.12 0 010 .07c0 .03-.01.05-.05.09l-45.02 45.02a.2.2 0 01-.09.05.12.12 0 01-.07 0c-.02 0-.04-.01-.08-.05L512 557.25 384.14 685.12c-.04.04-.06.05-.08.05a.12.12 0 01-.07 0c-.03 0-.05-.01-.09-.05l-45.02-45.02a.2.2 0 01-.05-.09.12.12 0 010-.07c0-.02.01-.04.06-.08L466.75 512 338.88 384.14a.27.27 0 01-.05-.06l-.01-.02a.12.12 0 010-.07c0-.03.01-.05.05-.09l45.02-45.02a.2.2 0 01.09-.05.12.12 0 01.07 0c.02 0 .04.01.08.06L512 466.75l127.86-127.86c.04-.05.06-.06.08-.06a.12.12 0 01.07 0z"}}]},name:"close-circle",theme:"outlined"};var n=e.i(9583),o=a.forwardRef(function(e,o){return a.createElement(n.default,(0,t.default)({},e,{ref:o,icon:l}))});e.s(["CloseCircleOutlined",0,o],518617)},245704,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let l={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M699 353h-46.9c-10.2 0-19.9 4.9-25.9 13.3L469 584.3l-71.2-98.8c-6-8.3-15.6-13.3-25.9-13.3H325c-6.5 0-10.3 7.4-6.5 12.7l124.6 172.8a31.8 31.8 0 0051.7 0l210.6-292c3.9-5.3.1-12.7-6.4-12.7z"}},{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"}}]},name:"check-circle",theme:"outlined"};var n=e.i(9583),o=a.forwardRef(function(e,o){return a.createElement(n.default,(0,t.default)({},e,{ref:o,icon:l}))});e.s(["CheckCircleOutlined",0,o],245704)},149192,e=>{"use strict";var t=e.i(864517);e.s(["CloseOutlined",()=>t.default])},19732,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let l={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 472a40 40 0 1080 0 40 40 0 10-80 0zm367 352.9L696.3 352V178H768v-68H256v68h71.7v174L145 824.9c-2.8 7.4-4.3 15.2-4.3 23.1 0 35.3 28.7 64 64 64h614.6c7.9 0 15.7-1.5 23.1-4.3 33-12.7 49.4-49.8 36.6-82.8zM395.7 364.7V180h232.6v184.7L719.2 600c-20.7-5.3-42.1-8-63.9-8-61.2 0-119.2 21.5-165.3 60a188.78 188.78 0 01-121.3 43.9c-32.7 0-64.1-8.3-91.8-23.7l118.8-307.5zM210.5 844l41.7-107.8c35.7 18.1 75.4 27.8 116.6 27.8 61.2 0 119.2-21.5 165.3-60 33.9-28.2 76.3-43.9 121.3-43.9 35 0 68.4 9.5 97.6 27.1L813.5 844h-603z"}}]},name:"experiment",theme:"outlined"};var n=e.i(9583),o=a.forwardRef(function(e,o){return a.createElement(n.default,(0,t.default)({},e,{ref:o,icon:l}))});e.s(["ExperimentOutlined",0,o],19732)},362024,e=>{"use strict";var t=e.i(988122);e.s(["Collapse",()=>t.default])},240647,e=>{"use strict";var t=e.i(286612);e.s(["RightOutlined",()=>t.default])},313603,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let l={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"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"};var n=e.i(9583),o=a.forwardRef(function(e,o){return a.createElement(n.default,(0,t.default)({},e,{ref:o,icon:l}))});e.s(["SettingOutlined",0,o],313603)},782273,793916,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let l={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M625.9 115c-5.9 0-11.9 1.6-17.4 5.3L254 352H90c-8.8 0-16 7.2-16 16v288c0 8.8 7.2 16 16 16h164l354.5 231.7c5.5 3.6 11.6 5.3 17.4 5.3 16.7 0 32.1-13.3 32.1-32.1V147.1c0-18.8-15.4-32.1-32.1-32.1zM586 803L293.4 611.7l-18-11.7H146V424h129.4l17.9-11.7L586 221v582zm348-327H806c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16h128c8.8 0 16-7.2 16-16v-40c0-8.8-7.2-16-16-16zm-41.9 261.8l-110.3-63.7a15.9 15.9 0 00-21.7 5.9l-19.9 34.5c-4.4 7.6-1.8 17.4 5.8 21.8L856.3 800a15.9 15.9 0 0021.7-5.9l19.9-34.5c4.4-7.6 1.7-17.4-5.8-21.8zM760 344a15.9 15.9 0 0021.7 5.9L892 286.2c7.6-4.4 10.2-14.2 5.8-21.8L878 230a15.9 15.9 0 00-21.7-5.9L746 287.8a15.99 15.99 0 00-5.8 21.8L760 344z"}}]},name:"sound",theme:"outlined"};var n=e.i(9583),o=a.forwardRef(function(e,o){return a.createElement(n.default,(0,t.default)({},e,{ref:o,icon:l}))});e.s(["SoundOutlined",0,o],782273);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M842 454c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8 0 140.3-113.7 254-254 254S258 594.3 258 454c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8 0 168.7 126.6 307.9 290 327.6V884H326.7c-13.7 0-24.7 14.3-24.7 32v36c0 4.4 2.8 8 6.2 8h407.6c3.4 0 6.2-3.6 6.2-8v-36c0-17.7-11-32-24.7-32H548V782.1c165.3-18 294-158 294-328.1zM512 624c93.9 0 170-75.2 170-168V232c0-92.8-76.1-168-170-168s-170 75.2-170 168v224c0 92.8 76.1 168 170 168zm-94-392c0-50.6 41.9-92 94-92s94 41.4 94 92v224c0 50.6-41.9 92-94 92s-94-41.4-94-92V232z"}}]},name:"audio",theme:"outlined"};var r=a.forwardRef(function(e,l){return a.createElement(n.default,(0,t.default)({},e,{ref:l,icon:i}))});e.s(["AudioOutlined",0,r],793916)},969550,e=>{"use strict";var t=e.i(843476),a=e.i(741466),l=e.i(271645);let n=l.forwardRef(function(e,t){return l.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),l.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"}))});var o=e.i(343488),i=e.i(464571),r=e.i(311451),s=e.i(199133);e.s(["default",0,({options:e,onApplyFilters:c,onResetFilters:d,initialValues:u={},buttonLabel:m="Filters"})=>{let[p,g]=(0,l.useState)(!1),[h,f]=(0,l.useState)(u),[b,x]=(0,l.useState)({}),[v,y]=(0,l.useState)({}),[w,C]=(0,l.useState)({}),[A,j]=(0,l.useState)({}),k=(0,o.useDebouncedCallback)(async(e,t)=>{if(t.isSearchable&&t.searchFn){y(e=>({...e,[t.name]:!0}));try{let a=await t.searchFn(e);x(e=>({...e,[t.name]:a}))}catch(e){console.error("Error searching:",e),x(e=>({...e,[t.name]:[]}))}finally{y(e=>({...e,[t.name]:!1}))}}},{wait:a.DEBOUNCE_WAIT_MS}),N=(0,l.useCallback)(async e=>{if(e.isSearchable&&e.searchFn&&!e.loading&&!A[e.name]){y(t=>({...t,[e.name]:!0})),j(t=>({...t,[e.name]:!0}));try{let t=await e.searchFn("");x(a=>({...a,[e.name]:t}))}catch(t){console.error("Error loading initial options:",t),x(t=>({...t,[e.name]:[]}))}finally{y(t=>({...t,[e.name]:!1}))}}},[A]);(0,l.useEffect)(()=>{p&&e.forEach(e=>{e.isSearchable&&!A[e.name]&&N(e)})},[p,e,N,A]);let _=(e,t)=>{let a={...h,[e]:t};f(a),c(a)};return(0,t.jsxs)("div",{className:"w-full",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 mb-6",children:[(0,t.jsx)(i.Button,{icon:(0,t.jsx)(n,{className:"h-4 w-4"}),onClick:()=>g(!p),className:"flex items-center gap-2",children:m}),(0,t.jsx)(i.Button,{onClick:()=>{let t={};e.forEach(e=>{t[e.name]=""}),f(t),d()},children:"Reset Filters"})]}),p&&(0,t.jsx)("div",{className:"grid grid-cols-3 gap-x-6 gap-y-4 mb-6",children:e.map(e=>{let a,l=v[e.name]||e.loading;return(0,t.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,t.jsx)("label",{className:"text-sm text-gray-600",children:e.label||e.name}),e.isSearchable?(0,t.jsx)(s.Select,{showSearch:!0,className:"w-full",placeholder:`Search ${e.label||e.name}...`,value:h[e.name]||void 0,onChange:t=>_(e.name,t),onOpenChange:t=>{t&&e.isSearchable&&!A[e.name]&&N(e)},onSearch:t=>{C(a=>({...a,[e.name]:t})),e.searchFn&&k(t,e)},filterOption:!1,loading:l,options:b[e.name]||[],allowClear:!0,notFoundContent:l?"Loading...":"No results found"}):e.options?(0,t.jsx)(s.Select,{className:"w-full",placeholder:`Select ${e.label||e.name}...`,value:h[e.name]||void 0,onChange:t=>_(e.name,t),allowClear:!0,children:e.options.map(e=>(0,t.jsx)(s.Select.Option,{value:e.value,children:e.label},e.value))}):e.customComponent?(a=e.customComponent,(0,t.jsx)(a,{value:h[e.name]||void 0,onChange:t=>_(e.name,t??""),placeholder:`Select ${e.label||e.name}...`,allFilters:h})):(0,t.jsx)(r.Input,{className:"w-full",placeholder:`Enter ${e.label||e.name}...`,value:h[e.name]||"",onChange:t=>_(e.name,t.target.value),allowClear:!0})]},e.name)})})]})}],969550)},318842,972680,e=>{"use strict";var t=e.i(843476),a=e.i(245704),l=e.i(149192),n=e.i(755151),o=e.i(285027),i=e.i(266027),r=e.i(166540),s=e.i(464571),c=e.i(482725),d=e.i(271645),u=e.i(602869);e.i(3565);var m=e.i(502626);let p={blocked:{icon:l.CloseOutlined,color:"text-red-600",bg:"bg-red-50",border:"border-red-200",label:"Blocked"},passed:{icon:a.CheckCircleOutlined,color:"text-green-600",bg:"bg-green-50",border:"border-green-200",label:"Passed"},flagged:{icon:o.WarningOutlined,color:"text-amber-600",bg:"bg-amber-50",border:"border-amber-200",label:"Flagged"}};e.s(["LogViewer",0,function({guardrailName:e,filterAction:a="all",logs:l=[],logsLoading:o=!1,totalLogs:g,accessToken:h=null,startDate:f="",endDate:b=""}){let[x,v]=(0,d.useState)(10),[y,w]=(0,d.useState)(a),[C,A]=(0,d.useState)(null),[j,k]=(0,d.useState)(!1),N=l.filter(e=>"all"===y||e.action===y).slice(0,x),_=g??l.length,S=f?(0,r.default)(f).utc().format("YYYY-MM-DD HH:mm:ss"):(0,r.default)().subtract(24,"hours").utc().format("YYYY-MM-DD HH:mm:ss"),O=b?(0,r.default)(b).utc().endOf("day").format("YYYY-MM-DD HH:mm:ss"):(0,r.default)().utc().format("YYYY-MM-DD HH:mm:ss"),{data:I}=(0,i.useQuery)({queryKey:["spend-log-by-request",C,S,O],queryFn:async()=>h&&C?await (0,u.uiSpendLogsCall)({accessToken:h,start_date:S,end_date:O,page:1,page_size:10,params:{request_id:C}}):null,enabled:!!(h&&C&&j)}),E=I?.data?.[0]??null;return(0,t.jsxs)("div",{className:"bg-white border border-gray-200 rounded-lg",children:[(0,t.jsx)("div",{className:"p-4 border-b border-gray-200",children:(0,t.jsxs)("div",{className:"flex items-center justify-between flex-wrap gap-3",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("h3",{className:"text-base font-semibold text-gray-900",children:e?`Logs — ${e}`:"Request Logs"}),(0,t.jsx)("p",{className:"text-xs text-gray-500 mt-0.5",children:o?"Loading…":l.length>0?`Showing ${N.length} of ${_} entries`:"No logs for this period. Select a guardrail and date range."})]}),l.length>0&&(0,t.jsxs)("div",{className:"flex items-center gap-4",children:[(0,t.jsx)("div",{className:"flex items-center gap-1",children:["all","blocked","flagged","passed"].map(e=>(0,t.jsx)(s.Button,{type:y===e?"primary":"default",size:"small",onClick:()=>w(e),children:e.charAt(0).toUpperCase()+e.slice(1)},e))}),(0,t.jsx)("div",{className:"h-4 w-px bg-gray-200"}),(0,t.jsxs)("div",{className:"flex items-center gap-1",children:[(0,t.jsx)("span",{className:"text-xs text-gray-500 mr-1",children:"Sample:"}),[10,50,100].map(e=>(0,t.jsx)(s.Button,{type:x===e?"primary":"default",size:"small",onClick:()=>v(e),children:e},e))]})]})]})}),o&&(0,t.jsx)("div",{className:"flex items-center justify-center py-12",children:(0,t.jsx)(c.Spin,{})}),!o&&0===N.length&&(0,t.jsx)("div",{className:"py-12 text-center text-sm text-gray-500",children:"No logs to display. Adjust filters or date range."}),!o&&N.length>0&&(0,t.jsx)("div",{className:"divide-y divide-gray-100",children:N.map(e=>{let a=p[e.action],l=a.icon;return(0,t.jsxs)("button",{type:"button",onClick:()=>{A(e.id),k(!0)},className:"w-full text-left px-4 py-3 hover:bg-gray-50 transition-colors flex items-start gap-3",children:[(0,t.jsx)(l,{className:`w-4 h-4 mt-0.5 shrink-0 ${a.color}`}),(0,t.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[(0,t.jsx)("span",{className:`inline-flex items-center px-2 py-0.5 text-xs font-medium rounded-sm border ${a.bg} ${a.color} ${a.border}`,children:a.label}),(0,t.jsx)("span",{className:"text-xs text-gray-400",children:e.timestamp}),(0,t.jsx)("span",{className:"text-xs text-gray-400",children:"·"}),e.model&&(0,t.jsx)("span",{className:"text-xs text-gray-500",children:e.model})]}),(0,t.jsx)("p",{className:"text-sm text-gray-800 truncate",children:e.input_snippet??e.input??"—"})]}),(0,t.jsx)(n.DownOutlined,{className:"w-4 h-4 text-gray-400 shrink-0 mt-1"})]},e.id)})}),(0,t.jsx)(m.LogDetailsDrawer,{open:j,onClose:()=>{k(!1),A(null)},logEntry:E,accessToken:h,allLogs:E?[E]:[],startTime:S})]})}],318842),e.s(["MetricCard",0,function({label:e,value:a,valueColor:l="text-gray-900",icon:n,subtitle:o}){return(0,t.jsxs)("div",{className:"h-full bg-white border border-gray-200 rounded-lg p-5 flex flex-col",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-1",children:[(0,t.jsx)("span",{className:"text-sm font-medium text-gray-600",children:e}),n&&(0,t.jsx)("span",{className:"text-gray-400",children:n})]}),(0,t.jsx)("div",{className:`text-3xl font-semibold ${l} tracking-tight`,children:a}),o&&(0,t.jsx)("p",{className:"text-xs text-gray-500 mt-1",children:o})]})}],972680)},752754,e=>{"use strict";var t=e.i(843476),a=e.i(271645),l=e.i(447566);e.i(247167);var n=e.i(931067);let o={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M536.1 273H488c-4.4 0-8 3.6-8 8v275.3c0 2.6 1.2 5 3.3 6.5l165.3 120.7c3.6 2.6 8.6 1.9 11.2-1.7l28.6-39c2.7-3.7 1.9-8.7-1.7-11.2L544.1 528.5V281c0-4.4-3.6-8-8-8zm219.8 75.2l156.8 38.3c5 1.2 9.9-2.6 9.9-7.7l.8-161.5c0-6.7-7.7-10.5-12.9-6.3L752.9 334.1a8 8 0 003 14.1zm167.7 301.1l-56.7-19.5a8 8 0 00-10.1 4.8c-1.9 5.1-3.9 10.1-6 15.1-17.8 42.1-43.3 80-75.9 112.5a353 353 0 01-112.5 75.9 352.18 352.18 0 01-137.7 27.8c-47.8 0-94.1-9.3-137.7-27.8a353 353 0 01-112.5-75.9c-32.5-32.5-58-70.4-75.9-112.5A353.44 353.44 0 01171 512c0-47.8 9.3-94.2 27.8-137.8 17.8-42.1 43.3-80 75.9-112.5a353 353 0 01112.5-75.9C430.6 167.3 477 158 524.8 158s94.1 9.3 137.7 27.8A353 353 0 01775 261.7c10.2 10.3 19.8 21 28.6 32.3l59.8-46.8C784.7 146.6 662.2 81.9 524.6 82 285 82.1 92.6 276.7 95 516.4 97.4 751.9 288.9 942 524.8 942c185.5 0 343.5-117.6 403.7-282.3 1.5-4.2-.7-8.9-4.9-10.4z"}}]},name:"history",theme:"outlined"};var i=e.i(9583),r=a.forwardRef(function(e,t){return a.createElement(i.default,(0,n.default)({},e,{ref:t,icon:o}))}),s=e.i(366308),c=e.i(266027),d=e.i(912598),u=e.i(464571),m=e.i(199133),p=e.i(482725),g=e.i(663435),h=e.i(318842);let f=[{value:"untrusted",label:"untrusted",color:"#92400e",bg:"#fef3c7",border:"#fcd34d"},{value:"trusted",label:"trusted",color:"#065f46",bg:"#d1fae5",border:"#6ee7b7"},{value:"blocked",label:"blocked",color:"#991b1b",bg:"#fee2e2",border:"#fca5a5"}],b=[{value:"untrusted",label:"untrusted",color:"#92400e",bg:"#fef3c7",border:"#fcd34d"},{value:"trusted",label:"trusted",color:"#065f46",bg:"#d1fae5",border:"#6ee7b7"}],x=({value:e,toolName:a,saving:l,onChange:n,policyType:o="input",size:i="small",minWidth:r=110,stopPropagation:s=!0})=>{let c="output"===o?b:f,d=f.find(t=>t.value===e)??f[0];return(0,t.jsx)(m.Select,{size:i,value:e,disabled:l,loading:l,onChange:e=>n(a,e),onClick:e=>s&&e.stopPropagation(),style:{minWidth:r,fontWeight:500,backgroundColor:d.bg,borderColor:d.border,color:d.color,borderRadius:999,fontSize:"small"===i?11:12},popupMatchSelectWidth:!1,options:c.map(e=>({value:e.value,label:(0,t.jsxs)("span",{style:{display:"inline-flex",alignItems:"center",gap:6,fontSize:12,fontWeight:500,color:e.color},children:[(0,t.jsx)("span",{style:{width:8,height:8,borderRadius:"50%",backgroundColor:e.color,display:"inline-block",flexShrink:0}}),e.label]})}))})};var v=e.i(602869);let y="tool-detail";function w({toolName:e,onBack:n,accessToken:o}){let i=(0,d.useQueryClient)(),[f,b]=(0,a.useState)(!1),[C,A]=(0,a.useState)(!1),[j,k]=(0,a.useState)(!1),[N,_]=(0,a.useState)("team"),[S,O]=(0,a.useState)(null),[I,E]=(0,a.useState)(null),$=(0,a.useMemo)(()=>{let e,t,a;return e=new Date,(t=new Date).setDate(t.getDate()-90),{start:(a=e=>e.toISOString().slice(0,19).replace("T"," "))(t),end:a(e)}},[]),{data:T,isLoading:L,error:M}=(0,c.useQuery)({queryKey:[y,e],queryFn:()=>(0,v.fetchToolDetail)(o,e),enabled:!!o&&!!e}),{data:R}=(0,c.useQuery)({queryKey:["tool-policy-options"],queryFn:()=>(0,v.fetchToolPolicyOptions)(o),enabled:!!o,staleTime:6e4}),{data:D}=(0,c.useQuery)({queryKey:["teams-list-tool-detail"],queryFn:()=>(0,v.teamListCall)(o,null,null),enabled:!!o}),{data:P}=(0,c.useQuery)({queryKey:["keys-list-tool-detail"],queryFn:()=>(0,v.keyListCall)(o,null,null,null,null,null,1,100),enabled:!!o}),{data:H,isLoading:z}=(0,c.useQuery)({queryKey:["tool-usage-logs",e,$.start,$.end],queryFn:()=>(0,v.getToolUsageLogs)(o,e,{page:1,pageSize:50,startDate:$.start,endDate:$.end}),enabled:!!o&&!!e}),B=(0,a.useMemo)(()=>(H?.logs??[]).map(e=>({id:e.id,timestamp:e.timestamp,action:"passed",model:e.model??void 0,input_snippet:e.input_snippet??void 0})),[H?.logs]);(0,a.useMemo)(()=>(Array.isArray(D)?D:D?.data??[]).map(e=>({team_id:e.team_id??e.id??"",team_alias:e.team_alias??e.team_id??"",models:[],max_budget:null,budget_duration:null,tpm_limit:null,rpm_limit:null,organization_id:"",created_at:"",keys:[],members_with_roles:[],spend:0})),[D]);let F=(0,a.useMemo)(()=>(P?.keys??P?.data??[]).map(e=>({token:e.token??e.api_key??e.key_hash??"",key_alias:e.key_alias??(e.token??e.api_key??e.key_hash)?.toString?.()?.substring?.(0,8)})),[P]),V=(0,a.useCallback)(()=>{i.invalidateQueries({queryKey:[y,e]})},[i,e]),U=(0,a.useCallback)(async(t,a)=>{if(o){A(!0);try{await (0,v.updateToolPolicy)(o,e,{input_policy:a}),V()}catch(e){alert(`Failed to update input policy: ${e instanceof Error?e.message:String(e)}`)}finally{A(!1)}}},[o,e,V]),W=(0,a.useCallback)(async(t,a)=>{if(o){k(!0);try{await (0,v.updateToolPolicy)(o,e,{output_policy:a}),V()}catch(e){alert(`Failed to update output policy: ${e instanceof Error?e.message:String(e)}`)}finally{k(!1)}}},[o,e,V]),G=(0,a.useCallback)(async()=>{if(!o||!e)return;let t="team"===N;if((!t||S)&&(t||I?.token)){b(!0);try{await (0,v.updateToolPolicy)(o,e,{input_policy:"blocked"},{team_id:t?S:void 0,key_hash:t?void 0:I.token,key_alias:t?void 0:I.key_alias}),V(),O(null),E(null)}catch(e){alert(`Failed to add override: ${e instanceof Error?e.message:String(e)}`)}finally{b(!1)}}},[o,e,N,S,I,V]),K=(0,a.useCallback)(async t=>{if(o&&e){b(!0);try{await (0,v.deleteToolPolicyOverride)(o,e,{team_id:t.team_id??void 0,key_hash:t.key_hash??void 0}),V()}catch(e){alert(`Failed to remove override: ${e instanceof Error?e.message:String(e)}`)}finally{b(!1)}}},[o,e,V]);if(L&&!T)return(0,t.jsx)("div",{className:"flex items-center justify-center py-12",children:(0,t.jsx)(p.Spin,{size:"large"})});if(M&&!T)return(0,t.jsxs)("div",{children:[(0,t.jsx)(u.Button,{type:"link",icon:(0,t.jsx)(l.ArrowLeftOutlined,{}),onClick:n,className:"pl-0 mb-4",children:"Back to Tool Policies"}),(0,t.jsx)("p",{className:"text-red-600",children:"Failed to load tool details."})]});if(!T)return null;let{tool:q,overrides:X}=T,Y=R?.input_policies?.find(e=>e.value===q.input_policy)?.description,Z=R?.output_policies?.find(e=>e.value===q.output_policy)?.description;return(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"mb-6",children:[(0,t.jsx)(u.Button,{type:"link",icon:(0,t.jsx)(l.ArrowLeftOutlined,{}),onClick:n,className:"pl-0 mb-4",children:"Back to Tool Policies"}),(0,t.jsx)("div",{className:"flex items-start justify-between",children:(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center gap-3 mb-1 flex-wrap",children:[(0,t.jsx)(s.ToolOutlined,{className:"text-xl text-gray-400"}),(0,t.jsx)("h1",{className:"text-xl font-semibold text-gray-900 font-mono",children:q.tool_name}),(0,t.jsx)("span",{className:"inline-flex items-center px-2.5 py-1 text-xs font-medium rounded-md bg-gray-100 text-gray-700 border border-gray-200",children:q.origin??"—"}),(0,t.jsxs)("span",{className:"inline-flex items-center px-2.5 py-1 text-xs font-medium rounded-md bg-indigo-50 text-indigo-700 border border-indigo-200",children:[(q.call_count??0).toLocaleString()," calls"]})]}),(0,t.jsxs)("dl",{className:"mt-3 flex flex-wrap gap-x-6 gap-y-1 text-sm text-gray-600",children:[q.user_agent&&(0,t.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,t.jsx)("dt",{className:"font-medium text-gray-500 whitespace-nowrap",children:"User Agent:"}),(0,t.jsx)("dd",{className:"font-mono truncate max-w-[40ch]",title:q.user_agent,children:q.user_agent})]}),q.created_at&&(0,t.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,t.jsx)("dt",{className:"font-medium text-gray-500 whitespace-nowrap",children:"First Discovered:"}),(0,t.jsx)("dd",{children:new Date(q.created_at).toLocaleString()})]}),q.last_used_at&&(0,t.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,t.jsx)("dt",{className:"font-medium text-gray-500 whitespace-nowrap",children:"Last Used:"}),(0,t.jsx)("dd",{children:new Date(q.last_used_at).toLocaleString()})]})]})]})})]}),(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,t.jsxs)("section",{className:"bg-white rounded-lg border border-gray-200 p-5 shadow-xs",children:[(0,t.jsx)("h2",{className:"text-sm font-semibold text-gray-700 mb-1",children:"Input Policy"}),(0,t.jsx)("p",{className:"text-xs text-gray-500 mb-3",children:Y??"Controls what data this tool is allowed to accept."}),(0,t.jsx)(x,{value:q.input_policy,toolName:q.tool_name,saving:C,onChange:U,policyType:"input",size:"middle",minWidth:140,stopPropagation:!1})]}),(0,t.jsxs)("section",{className:"bg-white rounded-lg border border-gray-200 p-5 shadow-xs",children:[(0,t.jsx)("h2",{className:"text-sm font-semibold text-gray-700 mb-1",children:"Output Policy"}),(0,t.jsx)("p",{className:"text-xs text-gray-500 mb-3",children:Z??"Controls how this tool's output is trusted by downstream tools."}),(0,t.jsx)(x,{value:q.output_policy,toolName:q.tool_name,saving:j,onChange:W,policyType:"output",size:"middle",minWidth:140,stopPropagation:!1})]})]}),X.length>0&&(0,t.jsxs)("section",{className:"bg-white rounded-lg border border-gray-200 p-5 shadow-xs",children:[(0,t.jsx)("h2",{className:"text-sm font-semibold text-gray-700 mb-3",children:"Blocked for team or key"}),(0,t.jsx)("ul",{className:"border rounded-md divide-y divide-gray-100 bg-red-50/30",children:X.map(e=>(0,t.jsxs)("li",{className:"flex items-center justify-between px-3 py-2.5 text-sm",children:[(0,t.jsxs)("span",{className:"text-gray-700",children:[e.team_id?`Team: ${e.team_id}`:"",e.team_id&&e.key_hash?" · ":"",e.key_hash?`Key: ${e.key_alias||e.key_hash.substring(0,8)}`:"",e.team_id||e.key_hash?"":"—"]}),(0,t.jsx)(u.Button,{type:"link",danger:!0,size:"small",disabled:f,onClick:()=>K(e),children:"Remove"})]},e.override_id))})]}),(0,t.jsxs)("section",{className:"bg-white rounded-lg border border-gray-200 p-5 shadow-xs",children:[(0,t.jsx)("h2",{className:"text-sm font-semibold text-gray-700 mb-3",children:"Block for team or key"}),(0,t.jsxs)("div",{className:"flex flex-col gap-4 max-w-md",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"text-sm font-medium text-gray-700 block mb-2",children:"Scope"}),(0,t.jsxs)("div",{className:"flex items-center gap-6",children:[(0,t.jsxs)("label",{className:"flex items-center gap-2 cursor-pointer text-sm text-gray-700",children:[(0,t.jsx)("input",{type:"radio",checked:"team"===N,onChange:()=>_("team"),className:"align-middle"}),"Team"]}),(0,t.jsxs)("label",{className:"flex items-center gap-2 cursor-pointer text-sm text-gray-700",children:[(0,t.jsx)("input",{type:"radio",checked:"key"===N,onChange:()=>_("key"),className:"align-middle"}),"Key"]})]})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"text-sm font-medium text-gray-700 block mb-2",children:"team"===N?"Team":"Key"}),"team"===N?(0,t.jsx)(g.default,{value:S??void 0,onChange:e=>O(e||null)}):(0,t.jsx)(m.Select,{placeholder:"Select key",allowClear:!0,showSearch:!0,optionFilterProp:"label",value:I?I.token:void 0,onChange:e=>{E(F.find(t=>t.token===e)??null)},options:F.map(e=>({value:e.token,label:e.key_alias||e.token?.substring?.(0,12)||e.token})),className:"w-full",style:{minWidth:200}})]}),(0,t.jsxs)(u.Button,{type:"primary",danger:!0,disabled:f||("team"===N?!S:!I?.token),loading:f,onClick:G,children:["Block for ",N]})]})]}),(0,t.jsxs)("section",{className:"bg-white rounded-lg border border-gray-200 p-5 shadow-xs",children:[(0,t.jsxs)("h2",{className:"text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2",children:[(0,t.jsx)(r,{}),"Recent logs"]}),(0,t.jsx)(h.LogViewer,{guardrailName:q.tool_name,filterAction:"passed",logs:B,logsLoading:z,totalLogs:H?.total??0,accessToken:o,startDate:$.start,endDate:$.end})]})]})]})}var C=e.i(790848),A=e.i(592968),j=e.i(269200),k=e.i(427612),N=e.i(64848),_=e.i(942232),S=e.i(496020),O=e.i(977572);e.i(622826);var I=e.i(200208),E=e.i(399536),$=e.i(446891),T=e.i(969550),L=e.i(972680);function M(e){return`${e.getUTCFullYear()}-${String(e.getUTCMonth()+1).padStart(2,"0")}-${String(e.getUTCDate()).padStart(2,"0")}`}function R(e,t){if(!e)return!1;try{let a=new Date(e);return M(a)===t}catch{return!1}}function D(e,t){return e.filter(e=>R(e.created_at,t)).length}let P=({accessToken:e,onSelectTool:l})=>{let[n,o]=(0,a.useState)([]),[i,r]=(0,a.useState)(!0),[s,c]=(0,a.useState)(!1),[d,u]=(0,a.useState)(null),[m,p]=(0,a.useState)(null),[g,h]=(0,a.useState)(null),[y,w]=(0,a.useState)(""),[P,H]=(0,a.useState)("created_at"),[z,B]=(0,a.useState)("desc"),[F,V]=(0,a.useState)(1),[U,W]=(0,a.useState)(!0),[G,K]=(0,a.useState)({}),q=(0,a.useDeferredValue)(s),X=s||q,Y=(0,a.useCallback)(async()=>{if(e){c(!0),u(null);try{let t=await (0,v.fetchToolsList)(e);o(t)}catch(e){u(e.message??"Failed to load tools")}finally{c(!1),r(!1)}}},[e]);(0,a.useEffect)(()=>{Y()},[Y]),(0,a.useEffect)(()=>{if(!U)return;let e=setInterval(Y,15e3);return()=>clearInterval(e)},[U,Y]);let Z=async(t,a)=>{if(e){p(t);try{await (0,v.updateToolPolicy)(e,t,{input_policy:a}),o(e=>e.map(e=>e.tool_name===t?{...e,input_policy:a}:e))}catch(e){alert(`Failed to update input policy: ${e.message}`)}finally{p(null)}}},Q=async(t,a)=>{if(e){h(t);try{await (0,v.updateToolPolicy)(e,t,{output_policy:a}),o(e=>e.map(e=>e.tool_name===t?{...e,output_policy:a}:e))}catch(e){alert(`Failed to update output policy: ${e.message}`)}finally{h(null)}}},J=Array.from(new Set(n.map(e=>e.team_id).filter(Boolean))).map(e=>({label:e,value:e})),ee=Array.from(new Set(n.map(e=>e.key_alias).filter(Boolean))).map(e=>({label:e,value:e})),et=[{name:"Input Policy",label:"Input Policy",options:f.map(e=>({label:e.label,value:e.value}))},{name:"Output Policy",label:"Output Policy",options:b.map(e=>({label:e.label,value:e.value}))},{name:"Team Name",label:"Team Name",options:J},{name:"Key Name",label:"Key Name",options:ee}],{newToday:ea,newYesterday:el,trendSubtitle:en,totalTools:eo,blockedCount:ei,activeTeamsCount:er,needsReviewTools:es}=(0,a.useMemo)(()=>{let e=new Date,t=M(e),a=new Date(e);a.setUTCDate(a.getUTCDate()-1);let l=M(a),o=D(n,t),i=D(n,l),r=function(e,t){let a=e-t;if(0!==a)return a>0?`+${a} since yesterday`:`${a} since yesterday`}(o,i),s=n.length,c=n.filter(e=>"blocked"===e.input_policy).length;return{newToday:o,newYesterday:i,trendSubtitle:r,totalTools:s,blockedCount:c,activeTeamsCount:new Set(n.map(e=>e.team_id).filter(Boolean)).size,needsReviewTools:n.filter(e=>R(e.created_at,t)&&"untrusted"===e.input_policy)}},[n]),ec=({label:e,field:a})=>(0,t.jsxs)("div",{className:"flex items-center gap-1",children:[(0,t.jsx)("span",{children:e}),(0,t.jsx)($.TableHeaderSortDropdown,{sortState:P===a&&z,onSortChange:e=>{!1===e?(H("created_at"),B("desc")):(H(a),B(e)),V(1)}})]}),ed=n.filter(e=>{if(y){let t=y.toLowerCase();if(!(e.tool_name.toLowerCase().includes(t)||(e.team_id??"").toLowerCase().includes(t)||(e.key_alias??"").toLowerCase().includes(t)||(e.key_hash??"").toLowerCase().includes(t)||e.input_policy.toLowerCase().includes(t)||e.output_policy.toLowerCase().includes(t)))return!1}return(!G["Input Policy"]||e.input_policy===G["Input Policy"])&&(!G["Output Policy"]||e.output_policy===G["Output Policy"])&&(!G["Team Name"]||e.team_id===G["Team Name"])&&(!G["Key Name"]||e.key_alias===G["Key Name"])}),eu=[...ed].sort((e,t)=>{let a=e[P]??"",l=t[P]??"";return al?"desc"===z?-1:1:0}),em=Math.max(1,Math.ceil(eu.length/50)),ep=eu.slice((F-1)*50,50*F);return(0,t.jsxs)("div",{className:"w-full",children:[(0,t.jsx)("h1",{className:"text-2xl font-semibold text-gray-900 mb-6",children:"Tool Policies"}),(0,t.jsxs)("div",{className:"grid grid-cols-2 lg:grid-cols-4 gap-4 mb-6",children:[(0,t.jsx)(L.MetricCard,{label:"New Today",value:ea,valueColor:"text-green-600",subtitle:en,icon:(0,t.jsx)("svg",{className:"w-4 h-4 text-green-500",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"})})}),(0,t.jsx)(L.MetricCard,{label:"Total Tools Discovered",value:eo}),(0,t.jsx)(L.MetricCard,{label:"Blocked Tools",value:ei,valueColor:ei>0?"text-red-600":void 0}),(0,t.jsx)(L.MetricCard,{label:"Active Teams",value:er>0?er:"—"})]}),es.length>0&&(0,t.jsxs)("div",{className:"bg-amber-50 border border-amber-200 rounded-lg p-4 mb-6",children:[(0,t.jsx)("h2",{className:"text-sm font-semibold text-amber-900 mb-1",children:"Needs Review"}),(0,t.jsxs)("p",{className:"text-sm text-amber-800 mb-3",children:[es.length," new tool",1!==es.length?"s":""," discovered that require policy decisions."]}),(0,t.jsx)("div",{className:"flex flex-wrap gap-2",children:es.map(e=>(0,t.jsxs)("span",{className:"inline-flex items-center gap-2 px-3 py-1.5 bg-white border border-amber-200 rounded-md text-sm",children:[(0,t.jsx)("span",{className:"font-mono text-amber-900 truncate max-w-[200px]",title:e.tool_name,children:e.tool_name}),(0,t.jsx)("button",{type:"button",onClick:()=>(e=>{let t=eu.findIndex(t=>t.tool_id===e);if(t>=0){let a=Math.floor(t/50)+1;a!==F&&V(a),requestAnimationFrame(()=>{setTimeout(()=>{document.getElementById(`tool-row-${e}`)?.scrollIntoView({behavior:"smooth",block:"center"})},100)})}})(e.tool_id),className:"text-amber-700 hover:text-amber-900 font-medium text-xs whitespace-nowrap",children:"Review"})]},e.tool_id))})]}),(0,t.jsxs)("div",{className:"bg-white rounded-lg shadow-sm w-full max-w-full box-border",children:[(0,t.jsxs)("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",children:[(0,t.jsxs)("div",{className:"relative w-64",children:[(0,t.jsx)("input",{type:"text",placeholder:"Search by Tool Name",className:"w-full px-3 py-2 pl-8 border rounded-md text-sm focus:outline-hidden focus:ring-2 focus:ring-blue-500 focus:border-blue-500",value:y,onChange:e=>{w(e.target.value),V(1)}}),(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",children:[(0,t.jsx)("span",{className:"text-sm font-medium text-gray-900",children:"Live Tail"}),(0,t.jsx)(C.Switch,{checked:U,onChange:W})]}),(0,t.jsxs)("button",{onClick:Y,disabled:X,className:"flex items-center gap-1.5 px-3 py-2 text-sm border rounded-md hover:bg-gray-50 disabled:opacity-60",children:[(0,t.jsx)("svg",{className:`w-4 h-4 ${X?"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"})}),X?"Fetching":"Fetch"]})]}),(0,t.jsxs)("div",{className:"flex items-center gap-4 text-sm text-gray-600 whitespace-nowrap",children:[(0,t.jsxs)("span",{children:["Showing ",0===ed.length?0:(F-1)*50+1," -"," ",Math.min(50*F,ed.length)," of ",ed.length," results"]}),(0,t.jsxs)("span",{children:["Page ",F," of ",em]}),(0,t.jsxs)("div",{className:"flex gap-1",children:[(0,t.jsx)("button",{onClick:()=>V(e=>Math.max(1,e-1)),disabled:1===F,className:"px-3 py-1.5 border rounded-md text-sm hover:bg-gray-50 disabled:opacity-40",children:"Previous"}),(0,t.jsx)("button",{onClick:()=>V(e=>Math.min(em,e+1)),disabled:F===em,className:"px-3 py-1.5 border rounded-md text-sm hover:bg-gray-50 disabled:opacity-40",children:"Next"})]})]})]}),(0,t.jsx)("div",{className:"mt-3",children:(0,t.jsx)(T.default,{options:et,onApplyFilters:e=>{K(e),V(1)},onResetFilters:()=>{K({}),V(1)},buttonLabel:"Filters"})})]}),U&&(0,t.jsxs)("div",{className:"bg-green-50 border-b border-green-100 px-6 py-2 flex items-center justify-between",children:[(0,t.jsx)("span",{className:"text-sm text-green-700",children:"Auto-refreshing every 15 seconds"}),(0,t.jsx)("button",{onClick:()=>W(!1),className:"text-xs text-green-600 underline",children:"Stop"})]}),d&&(0,t.jsx)("div",{className:"mx-6 mt-4 p-3 bg-red-50 border border-red-200 rounded-sm text-sm text-red-700",children:d}),(0,t.jsxs)(j.Table,{className:"[&_td]:py-0.5 [&_th]:py-1 w-full",children:[(0,t.jsx)(k.TableHead,{children:(0,t.jsxs)(S.TableRow,{children:[(0,t.jsx)(N.TableHeaderCell,{className:"py-1 h-8",children:(0,t.jsx)(ec,{label:"Discovered",field:"created_at"})}),(0,t.jsx)(N.TableHeaderCell,{className:"py-1 h-8",children:(0,t.jsx)(ec,{label:"Tool Name",field:"tool_name"})}),(0,t.jsx)(N.TableHeaderCell,{className:"py-1 h-8",children:(0,t.jsx)(ec,{label:"Input Policy",field:"input_policy"})}),(0,t.jsx)(N.TableHeaderCell,{className:"py-1 h-8",children:(0,t.jsx)(ec,{label:"Output Policy",field:"output_policy"})}),(0,t.jsx)(N.TableHeaderCell,{className:"py-1 h-8",children:(0,t.jsx)(ec,{label:"# Calls",field:"call_count"})}),(0,t.jsx)(N.TableHeaderCell,{className:"py-1 h-8",children:(0,t.jsx)(ec,{label:"Team Name",field:"team_id"})}),(0,t.jsx)(N.TableHeaderCell,{className:"py-1 h-8",children:"Key Hash"}),(0,t.jsx)(N.TableHeaderCell,{className:"py-1 h-8",children:(0,t.jsx)(ec,{label:"Key Name",field:"key_alias"})}),(0,t.jsx)(N.TableHeaderCell,{className:"py-1 h-8",children:"User Agent"})]})}),(0,t.jsx)(_.TableBody,{children:i?(0,t.jsx)(S.TableRow,{children:(0,t.jsx)(O.TableCell,{colSpan:9,className:"h-8 text-center text-gray-500",children:"Loading tools…"})}):0===ep.length?(0,t.jsx)(S.TableRow,{children:(0,t.jsx)(O.TableCell,{colSpan:9,className:"h-8 text-center text-gray-500",children:"No tools discovered yet. Make a chat completion that returns tool_calls to start auto-discovery."})}):ep.map(e=>(0,t.jsxs)(S.TableRow,{id:`tool-row-${e.tool_id}`,className:"h-8 hover:bg-gray-50",children:[(0,t.jsx)(O.TableCell,{className:"py-0.5 max-h-8 overflow-hidden whitespace-nowrap",children:(0,t.jsx)(I.DateCell,{value:e.created_at})}),(0,t.jsx)(O.TableCell,{className:"py-0.5 max-h-8 overflow-hidden",children:(0,t.jsx)("button",{type:"button",onClick:()=>l?.(e.tool_name),className:"text-left w-full font-mono text-xs max-w-[20ch] truncate block font-medium text-blue-600 hover:text-blue-800 hover:underline focus:outline-hidden focus:ring-0",children:(0,t.jsx)(A.Tooltip,{title:l?"Click to view details and block for team/key":e.tool_name,children:(0,t.jsx)("span",{children:e.tool_name})})})}),(0,t.jsx)(O.TableCell,{className:"py-0.5 max-h-8",children:(0,t.jsx)(x,{value:e.input_policy,toolName:e.tool_name,saving:m===e.tool_name,onChange:Z,policyType:"input"})}),(0,t.jsx)(O.TableCell,{className:"py-0.5 max-h-8",children:(0,t.jsx)(x,{value:e.output_policy,toolName:e.tool_name,saving:g===e.tool_name,onChange:Q,policyType:"output"})}),(0,t.jsx)(O.TableCell,{className:"py-0.5 max-h-8",children:(0,t.jsx)("div",{className:"flex items-center justify-end h-8 tabular-nums text-sm font-mono text-gray-700",children:(e.call_count??0).toLocaleString()})}),(0,t.jsx)(O.TableCell,{className:"py-0.5 max-h-8 overflow-hidden whitespace-nowrap",children:(0,t.jsx)(E.IdCell,{value:e.team_id,variant:"plain"})}),(0,t.jsx)(O.TableCell,{className:"py-0.5 max-h-8 overflow-hidden whitespace-nowrap",children:(0,t.jsx)(E.IdCell,{value:e.key_hash})}),(0,t.jsx)(O.TableCell,{className:"py-0.5 max-h-8 overflow-hidden whitespace-nowrap",children:(0,t.jsx)(A.Tooltip,{title:e.key_alias??"-",children:(0,t.jsx)("span",{className:"max-w-[15ch] truncate block",children:e.key_alias??"-"})})}),(0,t.jsx)(O.TableCell,{className:"py-0.5 max-h-8 overflow-hidden whitespace-nowrap",children:(0,t.jsx)(A.Tooltip,{title:e.user_agent??"-",children:(0,t.jsx)("span",{className:"font-mono max-w-[20ch] truncate block text-xs text-gray-500",children:e.user_agent??"-"})})})]},e.tool_id))})]}),em>1&&(0,t.jsxs)("div",{className:"border-t px-6 py-3 flex items-center justify-between text-sm text-gray-600",children:[(0,t.jsxs)("span",{children:["Showing ",(F-1)*50+1," - ",Math.min(50*F,eu.length)," of"," ",eu.length]}),(0,t.jsxs)("div",{className:"flex gap-1",children:[(0,t.jsx)("button",{onClick:()=>V(e=>Math.max(1,e-1)),disabled:1===F,className:"px-3 py-1.5 border rounded-md hover:bg-gray-50 disabled:opacity-40",children:"Previous"}),(0,t.jsx)("button",{onClick:()=>V(e=>Math.min(em,e+1)),disabled:F===em,className:"px-3 py-1.5 border rounded-md hover:bg-gray-50 disabled:opacity-40",children:"Next"})]})]})]})]})};function H({accessToken:e,userRole:l}){let[n,o]=(0,a.useState)({type:"overview"});return(0,t.jsx)("div",{className:"p-6 w-full min-w-0 flex-1",children:"detail"===n.type?(0,t.jsx)(w,{toolName:n.toolName,onBack:()=>{o({type:"overview"})},accessToken:e}):(0,t.jsx)(P,{accessToken:e,userRole:l,onSelectTool:e=>{o({type:"detail",toolName:e})}})})}var z=e.i(135214);e.s(["default",0,function(){let{accessToken:e,userRole:a}=(0,z.default)();return(0,t.jsx)(H,{accessToken:e,userRole:a})}],752754)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/025ocjcb8e481.js b/litellm/proxy/_experimental/out/_next/static/chunks/025ocjcb8e481.js new file mode 100644 index 00000000000..d45da443d18 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/025ocjcb8e481.js @@ -0,0 +1,7 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,244451,e=>{"use strict";let t;e.i(247167);var r=e.i(271645),a=e.i(343794),i=e.i(242064),o=e.i(763731),l=e.i(174428);let n=80*Math.PI,s=e=>{let{dotClassName:t,style:i,hasCircleCls:o}=e;return r.createElement("circle",{className:(0,a.default)(`${t}-circle`,{[`${t}-circle-bg`]:o}),r:40,cx:50,cy:50,strokeWidth:20,style:i})},c=({percent:e,prefixCls:t})=>{let i=`${t}-dot`,o=`${i}-holder`,c=`${o}-hidden`,[d,u]=r.useState(!1);(0,l.default)(()=>{0!==e&&u(!0)},[0!==e]);let f=Math.max(Math.min(e,100),0);if(!d)return null;let m={strokeDashoffset:`${n/4}`,strokeDasharray:`${n*f/100} ${n*(100-f)/100}`};return r.createElement("span",{className:(0,a.default)(o,`${i}-progress`,f<=0&&c)},r.createElement("svg",{viewBox:"0 0 100 100",role:"progressbar","aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":f},r.createElement(s,{dotClassName:i,hasCircleCls:!0}),r.createElement(s,{dotClassName:i,style:m})))};function d(e){let{prefixCls:t,percent:i=0}=e,o=`${t}-dot`,l=`${o}-holder`,n=`${l}-hidden`;return r.createElement(r.Fragment,null,r.createElement("span",{className:(0,a.default)(l,i>0&&n)},r.createElement("span",{className:(0,a.default)(o,`${t}-dot-spin`)},[1,2,3,4].map(e=>r.createElement("i",{className:`${t}-dot-item`,key:e})))),r.createElement(c,{prefixCls:t,percent:i}))}function u(e){var t;let{prefixCls:i,indicator:l,percent:n}=e,s=`${i}-dot`;return l&&r.isValidElement(l)?(0,o.cloneElement)(l,{className:(0,a.default)(null==(t=l.props)?void 0:t.className,s),percent:n}):r.createElement(d,{prefixCls:i,percent:n})}e.i(296059);var f=e.i(694758),m=e.i(183293),p=e.i(246422),v=e.i(838378);let h=new f.Keyframes("antSpinMove",{to:{opacity:1}}),g=new f.Keyframes("antRotate",{to:{transform:"rotate(405deg)"}}),b=(0,p.genStyleHooks)("Spin",e=>(e=>{let{componentCls:t,calc:r}=e;return{[t]:Object.assign(Object.assign({},(0,m.resetComponent)(e)),{position:"absolute",display:"none",color:e.colorPrimary,fontSize:0,textAlign:"center",verticalAlign:"middle",opacity:0,transition:`transform ${e.motionDurationSlow} ${e.motionEaseInOutCirc}`,"&-spinning":{position:"relative",display:"inline-block",opacity:1},[`${t}-text`]:{fontSize:e.fontSize,paddingTop:r(r(e.dotSize).sub(e.fontSize)).div(2).add(2).equal()},"&-fullscreen":{position:"fixed",width:"100vw",height:"100vh",backgroundColor:e.colorBgMask,zIndex:e.zIndexPopupBase,inset:0,display:"flex",alignItems:"center",flexDirection:"column",justifyContent:"center",opacity:0,visibility:"hidden",transition:`all ${e.motionDurationMid}`,"&-show":{opacity:1,visibility:"visible"},[t]:{[`${t}-dot-holder`]:{color:e.colorWhite},[`${t}-text`]:{color:e.colorTextLightSolid}}},"&-nested-loading":{position:"relative",[`> div > ${t}`]:{position:"absolute",top:0,insetInlineStart:0,zIndex:4,display:"block",width:"100%",height:"100%",maxHeight:e.contentHeight,[`${t}-dot`]:{position:"absolute",top:"50%",insetInlineStart:"50%",margin:r(e.dotSize).mul(-1).div(2).equal()},[`${t}-text`]:{position:"absolute",top:"50%",width:"100%",textShadow:`0 1px 2px ${e.colorBgContainer}`},[`&${t}-show-text ${t}-dot`]:{marginTop:r(e.dotSize).div(2).mul(-1).sub(10).equal()},"&-sm":{[`${t}-dot`]:{margin:r(e.dotSizeSM).mul(-1).div(2).equal()},[`${t}-text`]:{paddingTop:r(r(e.dotSizeSM).sub(e.fontSize)).div(2).add(2).equal()},[`&${t}-show-text ${t}-dot`]:{marginTop:r(e.dotSizeSM).div(2).mul(-1).sub(10).equal()}},"&-lg":{[`${t}-dot`]:{margin:r(e.dotSizeLG).mul(-1).div(2).equal()},[`${t}-text`]:{paddingTop:r(r(e.dotSizeLG).sub(e.fontSize)).div(2).add(2).equal()},[`&${t}-show-text ${t}-dot`]:{marginTop:r(e.dotSizeLG).div(2).mul(-1).sub(10).equal()}}},[`${t}-container`]:{position:"relative",transition:`opacity ${e.motionDurationSlow}`,"&::after":{position:"absolute",top:0,insetInlineEnd:0,bottom:0,insetInlineStart:0,zIndex:10,width:"100%",height:"100%",background:e.colorBgContainer,opacity:0,transition:`all ${e.motionDurationSlow}`,content:'""',pointerEvents:"none"}},[`${t}-blur`]:{clear:"both",opacity:.5,userSelect:"none",pointerEvents:"none","&::after":{opacity:.4,pointerEvents:"auto"}}},"&-tip":{color:e.spinDotDefault},[`${t}-dot-holder`]:{width:"1em",height:"1em",fontSize:e.dotSize,display:"inline-block",transition:`transform ${e.motionDurationSlow} ease, opacity ${e.motionDurationSlow} ease`,transformOrigin:"50% 50%",lineHeight:1,color:e.colorPrimary,"&-hidden":{transform:"scale(0.3)",opacity:0}},[`${t}-dot-progress`]:{position:"absolute",inset:0},[`${t}-dot`]:{position:"relative",display:"inline-block",fontSize:e.dotSize,width:"1em",height:"1em","&-item":{position:"absolute",display:"block",width:r(e.dotSize).sub(r(e.marginXXS).div(2)).div(2).equal(),height:r(e.dotSize).sub(r(e.marginXXS).div(2)).div(2).equal(),background:"currentColor",borderRadius:"100%",transform:"scale(0.75)",transformOrigin:"50% 50%",opacity:.3,animationName:h,animationDuration:"1s",animationIterationCount:"infinite",animationTimingFunction:"linear",animationDirection:"alternate","&:nth-child(1)":{top:0,insetInlineStart:0,animationDelay:"0s"},"&:nth-child(2)":{top:0,insetInlineEnd:0,animationDelay:"0.4s"},"&:nth-child(3)":{insetInlineEnd:0,bottom:0,animationDelay:"0.8s"},"&:nth-child(4)":{bottom:0,insetInlineStart:0,animationDelay:"1.2s"}},"&-spin":{transform:"rotate(45deg)",animationName:g,animationDuration:"1.2s",animationIterationCount:"infinite",animationTimingFunction:"linear"},"&-circle":{strokeLinecap:"round",transition:["stroke-dashoffset","stroke-dasharray","stroke","stroke-width","opacity"].map(t=>`${t} ${e.motionDurationSlow} ease`).join(","),fillOpacity:0,stroke:"currentcolor"},"&-circle-bg":{stroke:e.colorFillSecondary}},[`&-sm ${t}-dot`]:{"&, &-holder":{fontSize:e.dotSizeSM}},[`&-sm ${t}-dot-holder`]:{i:{width:r(r(e.dotSizeSM).sub(r(e.marginXXS).div(2))).div(2).equal(),height:r(r(e.dotSizeSM).sub(r(e.marginXXS).div(2))).div(2).equal()}},[`&-lg ${t}-dot`]:{"&, &-holder":{fontSize:e.dotSizeLG}},[`&-lg ${t}-dot-holder`]:{i:{width:r(r(e.dotSizeLG).sub(e.marginXXS)).div(2).equal(),height:r(r(e.dotSizeLG).sub(e.marginXXS)).div(2).equal()}},[`&${t}-show-text ${t}-text`]:{display:"block"}})}})((0,v.mergeToken)(e,{spinDotDefault:e.colorTextDescription})),e=>{let{controlHeightLG:t,controlHeight:r}=e;return{contentHeight:400,dotSize:t/2,dotSizeSM:.35*t,dotSizeLG:r}}),y=[[30,.05],[70,.03],[96,.01]];var $=function(e,t){var r={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&0>t.indexOf(a)&&(r[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,a=Object.getOwnPropertySymbols(e);it.indexOf(a[i])&&Object.prototype.propertyIsEnumerable.call(e,a[i])&&(r[a[i]]=e[a[i]]);return r};let S=e=>{var o;let{prefixCls:l,spinning:n=!0,delay:s=0,className:c,rootClassName:d,size:f="default",tip:m,wrapperClassName:p,style:v,children:h,fullscreen:g=!1,indicator:S,percent:C}=e,x=$(e,["prefixCls","spinning","delay","className","rootClassName","size","tip","wrapperClassName","style","children","fullscreen","indicator","percent"]),{getPrefixCls:w,direction:k,className:E,style:z,indicator:O}=(0,i.useComponentConfig)("spin"),N=w("spin",l),[M,D,j]=b(N),[P,I]=r.useState(()=>n&&(!n||!s||!!Number.isNaN(Number(s)))),T=function(e,t){let[a,i]=r.useState(0),o=r.useRef(null),l="auto"===t;return r.useEffect(()=>(l&&e&&(i(0),o.current=setInterval(()=>{i(e=>{let t=100-e;for(let r=0;r{o.current&&(clearInterval(o.current),o.current=null)}),[l,e]),l?a:t}(P,C);r.useEffect(()=>{if(n){let e=function(e,t,r){var a,i=r||{},o=i.noTrailing,l=void 0!==o&&o,n=i.noLeading,s=void 0!==n&&n,c=i.debounceMode,d=void 0===c?void 0:c,u=!1,f=0;function m(){a&&clearTimeout(a)}function p(){for(var r=arguments.length,i=Array(r),o=0;oe?s?(f=Date.now(),l||(a=setTimeout(d?v:p,e))):p():!0!==l&&(a=setTimeout(d?v:p,void 0===d?e-c:e)))}return p.cancel=function(e){var t=(e||{}).upcomingOnly;m(),u=!(void 0!==t&&t)},p}(s,()=>{I(!0)},{debounceMode:false});return e(),()=>{var t;null==(t=null==e?void 0:e.cancel)||t.call(e)}}I(!1)},[s,n]);let _=r.useMemo(()=>void 0!==h&&!g,[h,g]),H=(0,a.default)(N,E,{[`${N}-sm`]:"small"===f,[`${N}-lg`]:"large"===f,[`${N}-spinning`]:P,[`${N}-show-text`]:!!m,[`${N}-rtl`]:"rtl"===k},c,!g&&d,D,j),R=(0,a.default)(`${N}-container`,{[`${N}-blur`]:P}),B=null!=(o=null!=S?S:O)?o:t,L=Object.assign(Object.assign({},z),v),q=r.createElement("div",Object.assign({},x,{style:L,className:H,"aria-live":"polite","aria-busy":P}),r.createElement(u,{prefixCls:N,indicator:B,percent:T}),m&&(_||g)?r.createElement("div",{className:`${N}-text`},m):null);return M(_?r.createElement("div",Object.assign({},x,{className:(0,a.default)(`${N}-nested-loading`,p,D,j)}),P&&r.createElement("div",{key:"loading"},q),r.createElement("div",{className:R,key:"container"},h)):g?r.createElement("div",{className:(0,a.default)(`${N}-fullscreen`,{[`${N}-fullscreen-show`]:P},d,D,j)},q):q)};S.setDefaultIndicator=e=>{t=e},e.s(["default",0,S],244451)},482725,e=>{"use strict";var t=e.i(244451);e.s(["Spin",()=>t.default])},184163,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M505.7 661a8 8 0 0012.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.8zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"}}]},name:"download",theme:"outlined"};var i=e.i(9583),o=r.forwardRef(function(e,o){return r.createElement(i.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["default",0,o],184163)},737434,e=>{"use strict";var t=e.i(184163);e.s(["DownloadOutlined",()=>t.default])},107233,603908,e=>{"use strict";let t=(0,e.i(475254).default)("plus",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]]);e.s(["default",0,t],603908),e.s(["Plus",0,t],107233)},695411,e=>{"use strict";var t=e.i(602869);let r=async e=>{try{let r=await (0,t.modelHubCall)(e);if(r?.data.length>0){let e=r.data.map(e=>({model_group:e.model_group,mode:e?.mode}));return e.sort((e,t)=>e.model_group.localeCompare(t.model_group)),e}return[]}catch(e){throw console.error("Error fetching model info:",e),e}};e.s(["fetchAvailableModels",0,r])},343488,e=>{"use strict";var t=e.i(540626),r=e.i(271645);e.s(["useDebouncedCallback",0,function(e,a){let i=(0,t.useDebouncer)(e,a).maybeExecute;return(0,r.useCallback)((...e)=>i(...e),[i])}])},983561,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"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"};var i=e.i(9583),o=r.forwardRef(function(e,o){return r.createElement(i.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["RobotOutlined",0,o],983561)},916940,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(199133),i=e.i(602869);e.s(["default",0,({onChange:e,value:o,className:l,accessToken:n,placeholder:s="Select vector stores",disabled:c=!1})=>{let[d,u]=(0,r.useState)([]),[f,m]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{(async()=>{if(n){m(!0);try{let e=await (0,i.vectorStoreListCall)(n);e.data&&u(e.data)}catch(e){console.error("Error fetching vector stores:",e)}finally{m(!1)}}})()},[n]),(0,t.jsx)("div",{children:(0,t.jsx)(a.Select,{mode:"multiple",placeholder:s,onChange:e,value:o,loading:f,className:l,allowClear:!0,options:d.map(e=>({label:`${e.vector_store_name||e.vector_store_id} (${e.vector_store_id})`,value:e.vector_store_id,title:e.vector_store_description||e.vector_store_id})),optionFilterProp:"label",showSearch:!0,style:{width:"100%"},disabled:c})})}])},245704,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M699 353h-46.9c-10.2 0-19.9 4.9-25.9 13.3L469 584.3l-71.2-98.8c-6-8.3-15.6-13.3-25.9-13.3H325c-6.5 0-10.3 7.4-6.5 12.7l124.6 172.8a31.8 31.8 0 0051.7 0l210.6-292c3.9-5.3.1-12.7-6.4-12.7z"}},{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"}}]},name:"check-circle",theme:"outlined"};var i=e.i(9583),o=r.forwardRef(function(e,o){return r.createElement(i.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["CheckCircleOutlined",0,o],245704)},637235,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"}},{tag:"path",attrs:{d:"M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z"}}]},name:"clock-circle",theme:"outlined"};var i=e.i(9583),o=r.forwardRef(function(e,o){return r.createElement(i.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["ClockCircleOutlined",0,o],637235)},646563,e=>{"use strict";var t=e.i(959013);e.s(["PlusOutlined",()=>t.default])},597440,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z"}}]},name:"delete",theme:"outlined"};var i=e.i(9583),o=r.forwardRef(function(e,o){return r.createElement(i.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["default",0,o],597440)},955135,e=>{"use strict";var t=e.i(597440);e.s(["DeleteOutlined",()=>t.default])},166406,e=>{"use strict";var t=e.i(190144);e.s(["CopyOutlined",()=>t.default])},447566,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M872 474H286.9l350.2-304c5.6-4.9 2.2-14-5.2-14h-88.5c-3.9 0-7.6 1.4-10.5 3.9L155 487.8a31.96 31.96 0 000 48.3L535.1 866c1.5 1.3 3.3 2 5.2 2h91.5c7.4 0 10.8-9.2 5.2-14L286.9 550H872c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"}}]},name:"arrow-left",theme:"outlined"};var i=e.i(9583),o=r.forwardRef(function(e,o){return r.createElement(i.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["ArrowLeftOutlined",0,o],447566)},653496,e=>{"use strict";var t=e.i(721369);e.s(["Tabs",()=>t.default])},629569,e=>{"use strict";var t=e.i(290571),r=e.i(95779),a=e.i(444755),i=e.i(673706),o=e.i(271645);let l=o.default.forwardRef((e,l)=>{let{color:n,children:s,className:c}=e,d=(0,t.__rest)(e,["color","children","className"]);return o.default.createElement("p",Object.assign({ref:l,className:(0,a.tremorTwMerge)("font-medium text-tremor-title",n?(0,i.getColorClassNames)(n,r.colorPalette.darkText).textColor:"text-tremor-content-strong dark:text-dark-tremor-content-strong",c)},d),s)});l.displayName="Title",e.s(["Title",0,l],629569)},304967,e=>{"use strict";var t=e.i(290571),r=e.i(271645),a=e.i(480731),i=e.i(95779),o=e.i(444755),l=e.i(673706);let n=(0,l.makeClassName)("Card"),s=r.default.forwardRef((e,s)=>{let{decoration:c="",decorationColor:d,children:u,className:f}=e,m=(0,t.__rest)(e,["decoration","decorationColor","children","className"]);return r.default.createElement("div",Object.assign({ref:s,className:(0,o.tremorTwMerge)(n("root"),"relative w-full text-left ring-1 rounded-tremor-default p-6","bg-tremor-background ring-tremor-ring shadow-tremor-card","dark:bg-dark-tremor-background dark:ring-dark-tremor-ring dark:shadow-dark-tremor-card",d?(0,l.getColorClassNames)(d,i.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand",(e=>{if(!e)return"";switch(e){case a.HorizontalPositions.Left:return"border-l-4";case a.VerticalPositions.Top:return"border-t-4";case a.HorizontalPositions.Right:return"border-r-4";case a.VerticalPositions.Bottom:return"border-b-4";default:return""}})(c),f)},m),u)});s.displayName="Card",e.s(["Card",0,s],304967)},91874,681216,e=>{"use strict";var t=e.i(931067),r=e.i(209428),a=e.i(211577),i=e.i(392221),o=e.i(703923),l=e.i(343794),n=e.i(914949),s=e.i(271645),c=["prefixCls","className","style","checked","disabled","defaultChecked","type","title","onChange"],d=(0,s.forwardRef)(function(e,d){var u=e.prefixCls,f=void 0===u?"rc-checkbox":u,m=e.className,p=e.style,v=e.checked,h=e.disabled,g=e.defaultChecked,b=e.type,y=void 0===b?"checkbox":b,$=e.title,S=e.onChange,C=(0,o.default)(e,c),x=(0,s.useRef)(null),w=(0,s.useRef)(null),k=(0,n.default)(void 0!==g&&g,{value:v}),E=(0,i.default)(k,2),z=E[0],O=E[1];(0,s.useImperativeHandle)(d,function(){return{focus:function(e){var t;null==(t=x.current)||t.focus(e)},blur:function(){var e;null==(e=x.current)||e.blur()},input:x.current,nativeElement:w.current}});var N=(0,l.default)(f,m,(0,a.default)((0,a.default)({},"".concat(f,"-checked"),z),"".concat(f,"-disabled"),h));return s.createElement("span",{className:N,title:$,style:p,ref:w},s.createElement("input",(0,t.default)({},C,{className:"".concat(f,"-input"),ref:x,onChange:function(t){h||("checked"in e||O(t.target.checked),null==S||S({target:(0,r.default)((0,r.default)({},e),{},{type:y,checked:t.target.checked}),stopPropagation:function(){t.stopPropagation()},preventDefault:function(){t.preventDefault()},nativeEvent:t.nativeEvent}))},disabled:h,checked:!!z,type:y})),s.createElement("span",{className:"".concat(f,"-inner")}))});e.s(["default",0,d],91874);var u=e.i(963188);e.s(["default",0,function(e){let t=s.default.useRef(null),r=()=>{u.default.cancel(t.current),t.current=null};return[()=>{r(),t.current=(0,u.default)(()=>{t.current=null})},a=>{t.current&&(a.stopPropagation(),r()),null==e||e(a)}]}],681216)},374276,236836,e=>{"use strict";e.i(247167);var t=e.i(271645),r=e.i(343794),a=e.i(91874),i=e.i(611935),o=e.i(121872),l=e.i(26905),n=e.i(242064),s=e.i(937328),c=e.i(321883),d=e.i(62139);let u=t.default.createContext(null);e.i(296059);var f=e.i(915654),m=e.i(183293),p=e.i(246422),v=e.i(838378);function h(e,t){return(e=>{let{checkboxCls:t}=e,r=`${t}-wrapper`;return[{[`${t}-group`]:Object.assign(Object.assign({},(0,m.resetComponent)(e)),{display:"inline-flex",flexWrap:"wrap",columnGap:e.marginXS,[`> ${e.antCls}-row`]:{flex:1}}),[r]:Object.assign(Object.assign({},(0,m.resetComponent)(e)),{display:"inline-flex",alignItems:"baseline",cursor:"pointer","&:after":{display:"inline-block",width:0,overflow:"hidden",content:"'\\a0'"},[`& + ${r}`]:{marginInlineStart:0},[`&${r}-in-form-item`]:{'input[type="checkbox"]':{width:14,height:14}}}),[t]:Object.assign(Object.assign({},(0,m.resetComponent)(e)),{position:"relative",whiteSpace:"nowrap",lineHeight:1,cursor:"pointer",borderRadius:e.borderRadiusSM,alignSelf:"center",[`${t}-input`]:{position:"absolute",inset:0,zIndex:1,cursor:"pointer",opacity:0,margin:0,[`&:focus-visible + ${t}-inner`]:(0,m.genFocusOutline)(e)},[`${t}-inner`]:{boxSizing:"border-box",display:"block",width:e.checkboxSize,height:e.checkboxSize,direction:"ltr",backgroundColor:e.colorBgContainer,border:`${(0,f.unit)(e.lineWidth)} ${e.lineType} ${e.colorBorder}`,borderRadius:e.borderRadiusSM,borderCollapse:"separate",transition:`all ${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:`${(0,f.unit)(e.lineWidthBold)} solid ${e.colorWhite}`,borderTop:0,borderInlineStart:0,transform:"rotate(45deg) scale(0) translate(-50%,-50%)",opacity:0,content:'""',transition:`all ${e.motionDurationFast} ${e.motionEaseInBack}, opacity ${e.motionDurationFast}`}},"& + span":{paddingInlineStart:e.paddingXS,paddingInlineEnd:e.paddingXS}})},{[` + ${r}:not(${r}-disabled), + ${t}:not(${t}-disabled) + `]:{[`&:hover ${t}-inner`]:{borderColor:e.colorPrimary}},[`${r}:not(${r}-disabled)`]:{[`&:hover ${t}-checked:not(${t}-disabled) ${t}-inner`]:{backgroundColor:e.colorPrimaryHover,borderColor:"transparent"},[`&:hover ${t}-checked:not(${t}-disabled):after`]:{borderColor:e.colorPrimaryHover}}},{[`${t}-checked`]:{[`${t}-inner`]:{backgroundColor:e.colorPrimary,borderColor:e.colorPrimary,"&:after":{opacity:1,transform:"rotate(45deg) scale(1) translate(-50%,-50%)",transition:`all ${e.motionDurationMid} ${e.motionEaseOutBack} ${e.motionDurationFast}`}}},[` + ${r}-checked:not(${r}-disabled), + ${t}-checked:not(${t}-disabled) + `]:{[`&:hover ${t}-inner`]:{backgroundColor:e.colorPrimaryHover,borderColor:"transparent"}}},{[t]:{"&-indeterminate":{"&":{[`${t}-inner`]:{backgroundColor:`${e.colorBgContainer}`,borderColor:`${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 ${t}-inner`]:{backgroundColor:`${e.colorBgContainer}`,borderColor:`${e.colorPrimary}`}}}}},{[`${r}-disabled`]:{cursor:"not-allowed"},[`${t}-disabled`]:{[`&, ${t}-input`]:{cursor:"not-allowed",pointerEvents:"none"},[`${t}-inner`]:{background:e.colorBgContainerDisabled,borderColor:e.colorBorder,"&:after":{borderColor:e.colorTextDisabled}},"&:after":{display:"none"},"& + span":{color:e.colorTextDisabled},[`&${t}-indeterminate ${t}-inner::after`]:{background:e.colorTextDisabled}}}]})((0,v.mergeToken)(t,{checkboxCls:`.${e}`,checkboxSize:t.controlInteractiveSize}))}let g=(0,p.genStyleHooks)("Checkbox",(e,{prefixCls:t})=>[h(t,e)]);e.s(["default",0,g,"getStyle",0,h],236836);var b=e.i(681216),y=function(e,t){var r={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&0>t.indexOf(a)&&(r[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,a=Object.getOwnPropertySymbols(e);it.indexOf(a[i])&&Object.prototype.propertyIsEnumerable.call(e,a[i])&&(r[a[i]]=e[a[i]]);return r};let $=t.forwardRef((e,f)=>{var m;let{prefixCls:p,className:v,rootClassName:h,children:$,indeterminate:S=!1,style:C,onMouseEnter:x,onMouseLeave:w,skipGroup:k=!1,disabled:E}=e,z=y(e,["prefixCls","className","rootClassName","children","indeterminate","style","onMouseEnter","onMouseLeave","skipGroup","disabled"]),{getPrefixCls:O,direction:N,checkbox:M}=t.useContext(n.ConfigContext),D=t.useContext(u),{isFormItemInput:j}=t.useContext(d.FormItemInputContext),P=t.useContext(s.default),I=null!=(m=(null==D?void 0:D.disabled)||E)?m:P,T=t.useRef(z.value),_=t.useRef(null),H=(0,i.composeRef)(f,_);t.useEffect(()=>{null==D||D.registerValue(z.value)},[]),t.useEffect(()=>{if(!k)return z.value!==T.current&&(null==D||D.cancelValue(T.current),null==D||D.registerValue(z.value),T.current=z.value),()=>null==D?void 0:D.cancelValue(z.value)},[z.value]),t.useEffect(()=>{var e;(null==(e=_.current)?void 0:e.input)&&(_.current.input.indeterminate=S)},[S]);let R=O("checkbox",p),B=(0,c.default)(R),[L,q,X]=g(R,B),G=Object.assign({},z);D&&!k&&(G.onChange=(...e)=>{z.onChange&&z.onChange.apply(z,e),D.toggleOption&&D.toggleOption({label:$,value:z.value})},G.name=D.name,G.checked=D.value.includes(z.value));let V=(0,r.default)(`${R}-wrapper`,{[`${R}-rtl`]:"rtl"===N,[`${R}-wrapper-checked`]:G.checked,[`${R}-wrapper-disabled`]:I,[`${R}-wrapper-in-form-item`]:j},null==M?void 0:M.className,v,h,X,B,q),F=(0,r.default)({[`${R}-indeterminate`]:S},l.TARGET_CLS,q),[A,W]=(0,b.default)(G.onClick);return L(t.createElement(o.default,{component:"Checkbox",disabled:I},t.createElement("label",{className:V,style:Object.assign(Object.assign({},null==M?void 0:M.style),C),onMouseEnter:x,onMouseLeave:w,onClick:A},t.createElement(a.default,Object.assign({},G,{onClick:W,prefixCls:R,className:F,disabled:I,ref:H})),null!=$&&t.createElement("span",{className:`${R}-label`},$))))});var S=e.i(8211),C=e.i(529681),x=function(e,t){var r={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&0>t.indexOf(a)&&(r[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,a=Object.getOwnPropertySymbols(e);it.indexOf(a[i])&&Object.prototype.propertyIsEnumerable.call(e,a[i])&&(r[a[i]]=e[a[i]]);return r};let w=t.forwardRef((e,a)=>{let{defaultValue:i,children:o,options:l=[],prefixCls:s,className:d,rootClassName:f,style:m,onChange:p}=e,v=x(e,["defaultValue","children","options","prefixCls","className","rootClassName","style","onChange"]),{getPrefixCls:h,direction:b}=t.useContext(n.ConfigContext),[y,w]=t.useState(v.value||i||[]),[k,E]=t.useState([]);t.useEffect(()=>{"value"in v&&w(v.value||[])},[v.value]);let z=t.useMemo(()=>l.map(e=>"string"==typeof e||"number"==typeof e?{label:e,value:e}:e),[l]),O=e=>{E(t=>t.filter(t=>t!==e))},N=e=>{E(t=>[].concat((0,S.default)(t),[e]))},M=e=>{let t=y.indexOf(e.value),r=(0,S.default)(y);-1===t?r.push(e.value):r.splice(t,1),"value"in v||w(r),null==p||p(r.filter(e=>k.includes(e)).sort((e,t)=>z.findIndex(t=>t.value===e)-z.findIndex(e=>e.value===t)))},D=h("checkbox",s),j=`${D}-group`,P=(0,c.default)(D),[I,T,_]=g(D,P),H=(0,C.default)(v,["value","disabled"]),R=l.length?z.map(e=>t.createElement($,{prefixCls:D,key:e.value.toString(),disabled:"disabled"in e?e.disabled:v.disabled,value:e.value,checked:y.includes(e.value),onChange:e.onChange,className:(0,r.default)(`${j}-item`,e.className),style:e.style,title:e.title,id:e.id,required:e.required},e.label)):o,B=t.useMemo(()=>({toggleOption:M,value:y,disabled:v.disabled,name:v.name,registerValue:N,cancelValue:O}),[M,y,v.disabled,v.name,N,O]),L=(0,r.default)(j,{[`${j}-rtl`]:"rtl"===b},d,f,_,P,T);return I(t.createElement("div",Object.assign({className:L,style:m},H,{ref:a}),t.createElement(u.Provider,{value:B},R)))});$.Group=w,$.__ANT_CHECKBOX=!0,e.s(["default",0,$],374276)},536916,e=>{"use strict";var t=e.i(374276);e.s(["Checkbox",()=>t.default])},921511,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(199133),i=e.i(602869);function o(e){return e.filter(e=>(e.version_status??"draft")!=="draft").map(e=>{var t;let r=e.version_number??1,a=e.version_status??"draft";return{label:`${e.policy_name} — v${r} (${a})${e.description?` — ${e.description}`:""}`,value:"production"===a?e.policy_name:e.policy_id?(t=e.policy_id,`policy_${t}`):e.policy_name}})}e.s(["default",0,({onChange:e,value:l,className:n,accessToken:s,disabled:c,onPoliciesLoaded:d})=>{let[u,f]=(0,r.useState)([]),[m,p]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{(async()=>{if(s){p(!0);try{let e=await (0,i.getPoliciesList)(s);e.policies&&(f(e.policies),d?.(e.policies))}catch(e){console.error("Error fetching policies:",e)}finally{p(!1)}}})()},[s,d]),(0,t.jsx)("div",{children:(0,t.jsx)(a.Select,{mode:"multiple",disabled:c,placeholder:c?"Setting policies is a premium feature.":"Select policies (production or published versions)",onChange:t=>{e(t)},value:l,loading:m,className:n,allowClear:!0,options:o(u),optionFilterProp:"label",showSearch:!0,style:{width:"100%"}})})},"getPolicyOptionEntries",0,o])},891547,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(199133),i=e.i(602869);e.s(["default",0,({onChange:e,value:o,className:l,accessToken:n,disabled:s})=>{let[c,d]=(0,r.useState)([]),[u,f]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{(async()=>{if(n){f(!0);try{let e=await (0,i.getGuardrailsList)(n);e.guardrails&&d(e.guardrails)}catch(e){console.error("Error fetching guardrails:",e)}finally{f(!1)}}})()},[n]),(0,t.jsx)("div",{children:(0,t.jsx)(a.Select,{mode:"multiple",disabled:s,placeholder:s?"Setting guardrails is a premium feature.":"Select guardrails",onChange:t=>{e(t)},value:o,loading:u,className:l,allowClear:!0,options:c.map(e=>({label:`${e.guardrail_name}`,value:e.guardrail_name})),optionFilterProp:"label",showSearch:!0,style:{width:"100%"}})})}])}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/026n9mracjd5k.js b/litellm/proxy/_experimental/out/_next/static/chunks/026n9mracjd5k.js deleted file mode 100644 index 6f38ec8643c..00000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/026n9mracjd5k.js +++ /dev/null @@ -1,2 +0,0 @@ -(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,285027,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let n={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"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"};var i=e.i(9583),s=r.forwardRef(function(e,s){return r.createElement(i.default,(0,t.default)({},e,{ref:s,icon:n}))});e.s(["WarningOutlined",0,s],285027)},743151,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.CopyToClipboard=void 0;var n=a(e.r(844343)),i=a(e.r(271645)),s=["text","onCopy","options","children"];function a(e){return e&&e.__esModule?e:{default:e}}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 o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function c(e){for(var t=1;t{"use strict";var n=e.r(743151).CopyToClipboard;n.CopyToClipboard=n,t.exports=n},184163,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let n={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M505.7 661a8 8 0 0012.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.8zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"}}]},name:"download",theme:"outlined"};var i=e.i(9583),s=r.forwardRef(function(e,s){return r.createElement(i.default,(0,t.default)({},e,{ref:s,icon:n}))});e.s(["default",0,s],184163)},309821,e=>{"use strict";e.i(247167);var t=e.i(271645),r=e.i(135551),n=e.i(201072),i=e.i(121229),s=e.i(726289),a=e.i(864517),l=e.i(343794),o=e.i(529681),c=e.i(242064),u=e.i(931067),d=e.i(209428),m=e.i(703923),f={percent:0,prefixCls:"rc-progress",strokeColor:"#2db7f5",strokeLinecap:"round",strokeWidth:1,trailColor:"#D9D9D9",trailWidth:1,gapPosition:"bottom"},h=function(){var e=(0,t.useRef)([]),r=(0,t.useRef)(null);return(0,t.useEffect)(function(){var t=Date.now(),n=!1;e.current.forEach(function(e){if(e){n=!0;var i=e.style;i.transitionDuration=".3s, .3s, .3s, .06s",r.current&&t-r.current<100&&(i.transitionDuration="0s, 0s")}}),n&&(r.current=Date.now())}),e.current},p=e.i(410160),g=e.i(392221),x=e.i(654310),y=0,v=(0,x.default)();let b=function(e){var r=t.useState(),n=(0,g.default)(r,2),i=n[0],s=n[1];return t.useEffect(function(){var e;s("rc_progress_".concat((v?(e=y,y+=1):e="TEST_OR_SSR",e)))},[]),e||i};var _=function(e){var r=e.bg,n=e.children;return t.createElement("div",{style:{width:"100%",height:"100%",background:r}},n)};function j(e,t){return Object.keys(e).map(function(r){var n=parseFloat(r),i="".concat(Math.floor(n*t),"%");return"".concat(e[r]," ").concat(i)})}var k=t.forwardRef(function(e,r){var n=e.prefixCls,i=e.color,s=e.gradientId,a=e.radius,l=e.style,o=e.ptg,c=e.strokeLinecap,u=e.strokeWidth,d=e.size,m=e.gapDegree,f=i&&"object"===(0,p.default)(i),h=d/2,g=t.createElement("circle",{className:"".concat(n,"-circle-path"),r:a,cx:h,cy:h,stroke:f?"#FFF":void 0,strokeLinecap:c,strokeWidth:u,opacity:+(0!==o),style:l,ref:r});if(!f)return g;var x="".concat(s,"-conic"),y=j(i,(360-m)/360),v=j(i,1),b="conic-gradient(from ".concat(m?"".concat(180+m/2,"deg"):"0deg",", ").concat(y.join(", "),")"),k="linear-gradient(to ".concat(m?"bottom":"top",", ").concat(v.join(", "),")");return t.createElement(t.Fragment,null,t.createElement("mask",{id:x},g),t.createElement("foreignObject",{x:0,y:0,width:d,height:d,mask:"url(#".concat(x,")")},t.createElement(_,{bg:k},t.createElement(_,{bg:b}))))}),w=function(e,t,r,n,i,s,a,l,o,c){var u=arguments.length>10&&void 0!==arguments[10]?arguments[10]:0,d=(100-n)/100*t;return"round"===o&&100!==n&&(d+=c/2)>=t&&(d=t-.01),{stroke:"string"==typeof l?l:void 0,strokeDasharray:"".concat(t,"px ").concat(e),strokeDashoffset:d+u,transform:"rotate(".concat(i+r/100*360*((360-s)/360)+(0===s?0:({bottom:0,top:180,left:90,right:-90})[a]),"deg)"),transformOrigin:"".concat(50,"px ").concat(50,"px"),transition:"stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s",fillOpacity:0}},C=["id","prefixCls","steps","strokeWidth","trailWidth","gapDegree","gapPosition","trailColor","strokeLinecap","style","className","strokeColor","percent"];function S(e){var t=null!=e?e:[];return Array.isArray(t)?t:[t]}let E=function(e){var r,n,i,s,a=(0,d.default)((0,d.default)({},f),e),o=a.id,c=a.prefixCls,g=a.steps,x=a.strokeWidth,y=a.trailWidth,v=a.gapDegree,_=void 0===v?0:v,j=a.gapPosition,E=a.trailColor,O=a.strokeLinecap,N=a.style,I=a.className,T=a.strokeColor,R=a.percent,P=(0,m.default)(a,C),$=b(o),D="".concat($,"-gradient"),A=50-x/2,F=2*Math.PI*A,L=_>0?90+_/2:-90,M=(360-_)/360*F,B="object"===(0,p.default)(g)?g:{count:g,gap:2},z=B.count,U=B.gap,V=S(R),H=S(T),W=H.find(function(e){return e&&"object"===(0,p.default)(e)}),q=W&&"object"===(0,p.default)(W)?"butt":O,K=w(F,M,0,100,L,_,j,E,q,x),X=h();return t.createElement("svg",(0,u.default)({className:(0,l.default)("".concat(c,"-circle"),I),viewBox:"0 0 ".concat(100," ").concat(100),style:N,id:o,role:"presentation"},P),!z&&t.createElement("circle",{className:"".concat(c,"-circle-trail"),r:A,cx:50,cy:50,stroke:E,strokeLinecap:q,strokeWidth:y||x,style:K}),z?(r=Math.round(z*(V[0]/100)),n=100/z,i=0,Array(z).fill(null).map(function(e,s){var a=s<=r-1?H[0]:E,l=a&&"object"===(0,p.default)(a)?"url(#".concat(D,")"):void 0,o=w(F,M,i,n,L,_,j,a,"butt",x,U);return i+=(M-o.strokeDashoffset+U)*100/M,t.createElement("circle",{key:s,className:"".concat(c,"-circle-path"),r:A,cx:50,cy:50,stroke:l,strokeWidth:x,opacity:1,style:o,ref:function(e){X[s]=e}})})):(s=0,V.map(function(e,r){var n=H[r]||H[H.length-1],i=w(F,M,s,e,L,_,j,n,q,x);return s+=e,t.createElement(k,{key:r,color:n,ptg:e,radius:A,prefixCls:c,gradientId:D,style:i,strokeLinecap:q,strokeWidth:x,gapDegree:_,ref:function(e){X[r]=e},size:100})}).reverse()))};var O=e.i(491816);e.i(765846);var N=e.i(896091);function I(e){return!e||e<0?0:e>100?100:e}function T({success:e,successPercent:t}){let r=t;return e&&"progress"in e&&(r=e.progress),e&&"percent"in e&&(r=e.percent),r}let R=(e,t,r)=>{var n,i,s,a;let l=-1,o=-1;if("step"===t){let t=r.steps,n=r.strokeWidth;"string"==typeof e||void 0===e?(l="small"===e?2:14,o=null!=n?n:8):"number"==typeof e?[l,o]=[e,e]:[l=14,o=8]=Array.isArray(e)?e:[e.width,e.height],l*=t}else if("line"===t){let t=null==r?void 0:r.strokeWidth;"string"==typeof e||void 0===e?o=t||("small"===e?6:8):"number"==typeof e?[l,o]=[e,e]:[l=-1,o=8]=Array.isArray(e)?e:[e.width,e.height]}else("circle"===t||"dashboard"===t)&&("string"==typeof e||void 0===e?[l,o]="small"===e?[60,60]:[120,120]:"number"==typeof e?[l,o]=[e,e]:Array.isArray(e)&&(l=null!=(i=null!=(n=e[0])?n:e[1])?i:120,o=null!=(a=null!=(s=e[0])?s:e[1])?a:120));return[l,o]},P=e=>{let{prefixCls:r,trailColor:n=null,strokeLinecap:i="round",gapPosition:s,gapDegree:a,width:o=120,type:c,children:u,success:d,size:m=o,steps:f}=e,[h,p]=R(m,"circle"),{strokeWidth:g}=e;void 0===g&&(g=Math.max(3/h*100,6));let x=t.useMemo(()=>a||0===a?a:"dashboard"===c?75:void 0,[a,c]),y=(({percent:e,success:t,successPercent:r})=>{let n=I(T({success:t,successPercent:r}));return[n,I(I(e)-n)]})(e),v="[object Object]"===Object.prototype.toString.call(e.strokeColor),b=(({success:e={},strokeColor:t})=>{let{strokeColor:r}=e;return[r||N.presetPrimaryColors.green,t||null]})({success:d,strokeColor:e.strokeColor}),_=(0,l.default)(`${r}-inner`,{[`${r}-circle-gradient`]:v}),j=t.createElement(E,{steps:f,percent:f?y[1]:y,strokeWidth:g,trailWidth:g,strokeColor:f?b[1]:b,strokeLinecap:i,trailColor:n,prefixCls:r,gapDegree:x,gapPosition:s||"dashboard"===c&&"bottom"||void 0}),k=h<=20,w=t.createElement("div",{className:_,style:{width:h,height:p,fontSize:.15*h+6}},j,!k&&u);return k?t.createElement(O.default,{title:u},w):w};e.i(296059);var $=e.i(694758),D=e.i(915654),A=e.i(183293),F=e.i(246422),L=e.i(838378);let M="--progress-line-stroke-color",B="--progress-percent",z=e=>{let t=e?"100%":"-100%";return new $.Keyframes(`antProgress${e?"RTL":"LTR"}Active`,{"0%":{transform:`translateX(${t}) scaleX(0)`,opacity:.1},"20%":{transform:`translateX(${t}) scaleX(0)`,opacity:.5},to:{transform:"translateX(0) scaleX(1)",opacity:0}})},U=(0,F.genStyleHooks)("Progress",e=>{let t=e.calc(e.marginXXS).div(2).equal(),r=(0,L.mergeToken)(e,{progressStepMarginInlineEnd:t,progressStepMinWidth:t,progressActiveMotionDuration:"2.4s"});return[(e=>{let{componentCls:t,iconCls:r}=e;return{[t]:Object.assign(Object.assign({},(0,A.resetComponent)(e)),{display:"inline-block","&-rtl":{direction:"rtl"},"&-line":{position:"relative",width:"100%",fontSize:e.fontSize},[`${t}-outer`]:{display:"inline-flex",alignItems:"center",width:"100%"},[`${t}-inner`]:{position:"relative",display:"inline-block",width:"100%",flex:1,overflow:"hidden",verticalAlign:"middle",backgroundColor:e.remainingColor,borderRadius:e.lineBorderRadius},[`${t}-inner:not(${t}-circle-gradient)`]:{[`${t}-circle-path`]:{stroke:e.defaultColor}},[`${t}-success-bg, ${t}-bg`]:{position:"relative",background:e.defaultColor,borderRadius:e.lineBorderRadius,transition:`all ${e.motionDurationSlow} ${e.motionEaseInOutCirc}`},[`${t}-layout-bottom`]:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",[`${t}-text`]:{width:"max-content",marginInlineStart:0,marginTop:e.marginXXS}},[`${t}-bg`]:{overflow:"hidden","&::after":{content:'""',background:{_multi_value_:!0,value:["inherit",`var(${M})`]},height:"100%",width:`calc(1 / var(${B}) * 100%)`,display:"block"},[`&${t}-bg-inner`]:{minWidth:"max-content","&::after":{content:"none"},[`${t}-text-inner`]:{color:e.colorWhite,[`&${t}-text-bright`]:{color:"rgba(0, 0, 0, 0.45)"}}}},[`${t}-success-bg`]:{position:"absolute",insetBlockStart:0,insetInlineStart:0,backgroundColor:e.colorSuccess},[`${t}-text`]:{display:"inline-block",marginInlineStart:e.marginXS,color:e.colorText,lineHeight:1,width:"2em",whiteSpace:"nowrap",textAlign:"start",verticalAlign:"middle",wordBreak:"normal",[r]:{fontSize:e.fontSize},[`&${t}-text-outer`]:{width:"max-content"},[`&${t}-text-outer${t}-text-start`]:{width:"max-content",marginInlineStart:0,marginInlineEnd:e.marginXS}},[`${t}-text-inner`]:{display:"flex",justifyContent:"center",alignItems:"center",width:"100%",height:"100%",marginInlineStart:0,padding:`0 ${(0,D.unit)(e.paddingXXS)}`,[`&${t}-text-start`]:{justifyContent:"start"},[`&${t}-text-end`]:{justifyContent:"end"}},[`&${t}-status-active`]:{[`${t}-bg::before`]:{position:"absolute",inset:0,backgroundColor:e.colorBgContainer,borderRadius:e.lineBorderRadius,opacity:0,animationName:z(),animationDuration:e.progressActiveMotionDuration,animationTimingFunction:e.motionEaseOutQuint,animationIterationCount:"infinite",content:'""'}},[`&${t}-rtl${t}-status-active`]:{[`${t}-bg::before`]:{animationName:z(!0)}},[`&${t}-status-exception`]:{[`${t}-bg`]:{backgroundColor:e.colorError},[`${t}-text`]:{color:e.colorError}},[`&${t}-status-exception ${t}-inner:not(${t}-circle-gradient)`]:{[`${t}-circle-path`]:{stroke:e.colorError}},[`&${t}-status-success`]:{[`${t}-bg`]:{backgroundColor:e.colorSuccess},[`${t}-text`]:{color:e.colorSuccess}},[`&${t}-status-success ${t}-inner:not(${t}-circle-gradient)`]:{[`${t}-circle-path`]:{stroke:e.colorSuccess}}})}})(r),(e=>{let{componentCls:t,iconCls:r}=e;return{[t]:{[`${t}-circle-trail`]:{stroke:e.remainingColor},[`&${t}-circle ${t}-inner`]:{position:"relative",lineHeight:1,backgroundColor:"transparent"},[`&${t}-circle ${t}-text`]:{position:"absolute",insetBlockStart:"50%",insetInlineStart:0,width:"100%",margin:0,padding:0,color:e.circleTextColor,fontSize:e.circleTextFontSize,lineHeight:1,whiteSpace:"normal",textAlign:"center",transform:"translateY(-50%)",[r]:{fontSize:e.circleIconFontSize}},[`${t}-circle&-status-exception`]:{[`${t}-text`]:{color:e.colorError}},[`${t}-circle&-status-success`]:{[`${t}-text`]:{color:e.colorSuccess}}},[`${t}-inline-circle`]:{lineHeight:1,[`${t}-inner`]:{verticalAlign:"bottom"}}}})(r),(e=>{let{componentCls:t}=e;return{[t]:{[`${t}-steps`]:{display:"inline-block","&-outer":{display:"flex",flexDirection:"row",alignItems:"center"},"&-item":{flexShrink:0,minWidth:e.progressStepMinWidth,marginInlineEnd:e.progressStepMarginInlineEnd,backgroundColor:e.remainingColor,transition:`all ${e.motionDurationSlow}`,"&-active":{backgroundColor:e.defaultColor}}}}}})(r),(e=>{let{componentCls:t,iconCls:r}=e;return{[t]:{[`${t}-small&-line, ${t}-small&-line ${t}-text ${r}`]:{fontSize:e.fontSizeSM}}}})(r)]},e=>({circleTextColor:e.colorText,defaultColor:e.colorInfo,remainingColor:e.colorFillSecondary,lineBorderRadius:100,circleTextFontSize:"1em",circleIconFontSize:`${e.fontSize/e.fontSizeSM}em`}));var V=function(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&0>t.indexOf(n)&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,n=Object.getOwnPropertySymbols(e);it.indexOf(n[i])&&Object.prototype.propertyIsEnumerable.call(e,n[i])&&(r[n[i]]=e[n[i]]);return r};let H=e=>{let{prefixCls:r,direction:n,percent:i,size:s,strokeWidth:a,strokeColor:o,strokeLinecap:c="round",children:u,trailColor:d=null,percentPosition:m,success:f}=e,{align:h,type:p}=m,g=o&&"string"!=typeof o?((e,t)=>{let{from:r=N.presetPrimaryColors.blue,to:n=N.presetPrimaryColors.blue,direction:i="rtl"===t?"to left":"to right"}=e,s=V(e,["from","to","direction"]);if(0!==Object.keys(s).length){let e,t=(e=[],Object.keys(s).forEach(t=>{let r=Number.parseFloat(t.replace(/%/g,""));Number.isNaN(r)||e.push({key:r,value:s[t]})}),(e=e.sort((e,t)=>e.key-t.key)).map(({key:e,value:t})=>`${t} ${e}%`).join(", ")),r=`linear-gradient(${i}, ${t})`;return{background:r,[M]:r}}let a=`linear-gradient(${i}, ${r}, ${n})`;return{background:a,[M]:a}})(o,n):{[M]:o,background:o},x="square"===c||"butt"===c?0:void 0,[y,v]=R(null!=s?s:[-1,a||("small"===s?6:8)],"line",{strokeWidth:a}),b=Object.assign(Object.assign({width:`${I(i)}%`,height:v,borderRadius:x},g),{[B]:I(i)/100}),_=T(e),j={width:`${I(_)}%`,height:v,borderRadius:x,backgroundColor:null==f?void 0:f.strokeColor},k=t.createElement("div",{className:`${r}-inner`,style:{backgroundColor:d||void 0,borderRadius:x}},t.createElement("div",{className:(0,l.default)(`${r}-bg`,`${r}-bg-${p}`),style:b},"inner"===p&&u),void 0!==_&&t.createElement("div",{className:`${r}-success-bg`,style:j})),w="outer"===p&&"start"===h,C="outer"===p&&"end"===h;return"outer"===p&&"center"===h?t.createElement("div",{className:`${r}-layout-bottom`},k,u):t.createElement("div",{className:`${r}-outer`,style:{width:y<0?"100%":y}},w&&u,k,C&&u)},W=e=>{let{size:r,steps:n,rounding:i=Math.round,percent:s=0,strokeWidth:a=8,strokeColor:o,trailColor:c=null,prefixCls:u,children:d}=e,m=i(s/100*n),[f,h]=R(null!=r?r:["small"===r?2:14,a],"step",{steps:n,strokeWidth:a}),p=f/n,g=Array.from({length:n});for(let e=0;et.indexOf(n)&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,n=Object.getOwnPropertySymbols(e);it.indexOf(n[i])&&Object.prototype.propertyIsEnumerable.call(e,n[i])&&(r[n[i]]=e[n[i]]);return r};let K=["normal","exception","active","success"],X=t.forwardRef((e,u)=>{let d,{prefixCls:m,className:f,rootClassName:h,steps:p,strokeColor:g,percent:x=0,size:y="default",showInfo:v=!0,type:b="line",status:_,format:j,style:k,percentPosition:w={}}=e,C=q(e,["prefixCls","className","rootClassName","steps","strokeColor","percent","size","showInfo","type","status","format","style","percentPosition"]),{align:S="end",type:E="outer"}=w,O=Array.isArray(g)?g[0]:g,N="string"==typeof g||Array.isArray(g)?g:void 0,$=t.useMemo(()=>{if(O){let e="string"==typeof O?O:Object.values(O)[0];return new r.FastColor(e).isLight()}return!1},[g]),D=t.useMemo(()=>{var t,r;let n=T(e);return Number.parseInt(void 0!==n?null==(t=null!=n?n:0)?void 0:t.toString():null==(r=null!=x?x:0)?void 0:r.toString(),10)},[x,e.success,e.successPercent]),A=t.useMemo(()=>!K.includes(_)&&D>=100?"success":_||"normal",[_,D]),{getPrefixCls:F,direction:L,progress:M}=t.useContext(c.ConfigContext),B=F("progress",m),[z,V,X]=U(B),Q="line"===b,J=Q&&!p,Y=t.useMemo(()=>{let r;if(!v)return null;let o=T(e),c=j||(e=>`${e}%`),u=Q&&$&&"inner"===E;return"inner"===E||j||"exception"!==A&&"success"!==A?r=c(I(x),I(o)):"exception"===A?r=Q?t.createElement(s.default,null):t.createElement(a.default,null):"success"===A&&(r=Q?t.createElement(n.default,null):t.createElement(i.default,null)),t.createElement("span",{className:(0,l.default)(`${B}-text`,{[`${B}-text-bright`]:u,[`${B}-text-${S}`]:J,[`${B}-text-${E}`]:J}),title:"string"==typeof r?r:void 0},r)},[v,x,D,A,b,B,j]);"line"===b?d=p?t.createElement(W,Object.assign({},e,{strokeColor:N,prefixCls:B,steps:"object"==typeof p?p.count:p}),Y):t.createElement(H,Object.assign({},e,{strokeColor:O,prefixCls:B,direction:L,percentPosition:{align:S,type:E}}),Y):("circle"===b||"dashboard"===b)&&(d=t.createElement(P,Object.assign({},e,{strokeColor:O,prefixCls:B,progressStatus:A}),Y));let G=(0,l.default)(B,`${B}-status-${A}`,{[`${B}-${"dashboard"===b&&"circle"||b}`]:"line"!==b,[`${B}-inline-circle`]:"circle"===b&&R(y,"circle")[0]<=20,[`${B}-line`]:J,[`${B}-line-align-${S}`]:J,[`${B}-line-position-${E}`]:J,[`${B}-steps`]:p,[`${B}-show-info`]:v,[`${B}-${y}`]:"string"==typeof y,[`${B}-rtl`]:"rtl"===L},null==M?void 0:M.className,f,h,V,X);return z(t.createElement("div",Object.assign({ref:u,style:Object.assign(Object.assign({},null==M?void 0:M.style),k),className:G,role:"progressbar","aria-valuenow":D,"aria-valuemin":0,"aria-valuemax":100},(0,o.default)(C,["trailColor","strokeWidth","width","gapDegree","gapPosition","strokeLinecap","success","successPercent"])),d))});e.s(["default",0,X],309821)},519756,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let n={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M400 317.7h73.9V656c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V317.7H624c6.7 0 10.4-7.7 6.3-12.9L518.3 163a8 8 0 00-12.6 0l-112 141.7c-4.1 5.3-.4 13 6.3 13zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"}}]},name:"upload",theme:"outlined"};var i=e.i(9583),s=r.forwardRef(function(e,s){return r.createElement(i.default,(0,t.default)({},e,{ref:s,icon:n}))});e.s(["UploadOutlined",0,s],519756)},663435,e=>{"use strict";var t=e.i(843476),r=e.i(271645),n=e.i(199133),i=e.i(898586),s=e.i(56456),a=e.i(399029),l=e.i(785242),o=e.i(741466);let{Text:c}=i.Typography;e.s(["default",0,({value:e,onChange:i,onTeamSelect:u,disabled:d,organizationId:m,pageSize:f=20})=>{let[h,p]=(0,r.useState)(""),[g,x]=(0,a.useDebouncedState)("",{wait:o.DEBOUNCE_WAIT_MS}),{data:y,fetchNextPage:v,hasNextPage:b,isFetchingNextPage:_,isLoading:j}=(0,l.useInfiniteTeams)(f,g||void 0,m),k=(0,r.useMemo)(()=>{if(!y?.pages)return[];let e=new Set,t=[];for(let r of y.pages)for(let n of r.teams)e.has(n.team_id)||(e.add(n.team_id),t.push(n));return t},[y]);return(0,t.jsx)(n.Select,{showSearch:!0,placeholder:"Search or select a team",value:e||void 0,onChange:e=>{i?.(e??""),u&&u(e?k.find(t=>t.team_id===e)??null:null)},disabled:d,allowClear:!0,filterOption:!1,onSearch:e=>{p(e),x(e)},searchValue:h,onPopupScroll:e=>{let t=e.currentTarget;(t.scrollTop+t.clientHeight)/t.scrollHeight>=.8&&b&&!_&&v()},loading:j,notFoundContent:j?(0,t.jsx)(s.LoadingOutlined,{spin:!0}):"No teams found","data-testid":"team-dropdown",popupRender:e=>(0,t.jsxs)(t.Fragment,{children:[e,_&&(0,t.jsx)("div",{style:{textAlign:"center",padding:8},children:(0,t.jsx)(s.LoadingOutlined,{spin:!0})})]}),children:k.map(e=>(0,t.jsxs)(n.Select.Option,{value:e.team_id,children:[(0,t.jsx)("span",{className:"font-medium",children:e.team_alias})," ",(0,t.jsxs)(c,{type:"secondary",children:["(",e.team_id,")"]})]},e.team_id))})}])},741466,e=>{"use strict";e.s(["DEBOUNCE_WAIT_MS",0,300])},399029,e=>{"use strict";var t=e.i(540626),r=e.i(271645);e.s(["useDebouncedState",0,function(e,n,i){let[s,a]=(0,r.useState)(e),l=(0,t.useDebouncer)(a,n,i);return[s,l.maybeExecute,l]}])},993914,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let n={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"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"};var i=e.i(9583),s=r.forwardRef(function(e,s){return r.createElement(i.default,(0,t.default)({},e,{ref:s,icon:n}))});e.s(["FileTextOutlined",0,s],993914)},233538,e=>{"use strict";e.s(["isDisabledReactIssue7711",0,function(e){let t=e.parentElement,r=null;for(;t&&!(t instanceof HTMLFieldSetElement);)t instanceof HTMLLegendElement&&(r=t),t=t.parentElement;let n=(null==t?void 0:t.getAttribute("disabled"))==="";return!(n&&function(e){if(!e)return!1;let t=e.previousElementSibling;for(;null!==t;){if(t instanceof HTMLLegendElement)return!1;t=t.previousElementSibling}return!0}(r))&&n}])},83733,233137,e=>{"use strict";let t,r;var n,i,s=e.i(247167),a=e.i(271645),l=e.i(544508),o=e.i(746725),c=e.i(835696);void 0!==s.default&&"u">typeof globalThis&&"u">typeof Element&&(null==(n=null==s.default?void 0:s.default.env)?void 0:n.NODE_ENV)==="test"&&void 0===(null==(i=null==Element?void 0:Element.prototype)?void 0:i.getAnimations)&&(Element.prototype.getAnimations=function(){return console.warn(["Headless UI has polyfilled `Element.prototype.getAnimations` for your tests.","Please install a proper polyfill e.g. `jsdom-testing-mocks`, to silence these warnings.","","Example usage:","```js","import { mockAnimationsApi } from 'jsdom-testing-mocks'","mockAnimationsApi()","```"].join(` -`)),[]});var u=((t=u||{})[t.None=0]="None",t[t.Closed=1]="Closed",t[t.Enter=2]="Enter",t[t.Leave=4]="Leave",t);e.s(["transitionDataAttributes",0,function(e){let t={};for(let r in e)!0===e[r]&&(t[`data-${r}`]="");return t},"useTransition",0,function(e,t,r,n){let[i,s]=(0,a.useState)(r),{hasFlag:u,addFlag:d,removeFlag:m}=function(e=0){let[t,r]=(0,a.useState)(e),n=(0,a.useCallback)(e=>r(e),[t]),i=(0,a.useCallback)(e=>r(t=>t|e),[t]),s=(0,a.useCallback)(e=>(t&e)===e,[t]);return{flags:t,setFlag:n,addFlag:i,hasFlag:s,removeFlag:(0,a.useCallback)(e=>r(t=>t&~e),[r]),toggleFlag:(0,a.useCallback)(e=>r(t=>t^e),[r])}}(e&&i?3:0),f=(0,a.useRef)(!1),h=(0,a.useRef)(!1),p=(0,o.useDisposables)();return(0,c.useIsoMorphicEffect)(()=>{var i;if(e){if(r&&s(!0),!t){r&&d(3);return}return null==(i=null==n?void 0:n.start)||i.call(n,r),function(e,{prepare:t,run:r,done:n,inFlight:i}){let s=(0,l.disposables)();return function(e,{inFlight:t,prepare:r}){if(null!=t&&t.current)return r();let n=e.style.transition;e.style.transition="none",r(),e.offsetHeight,e.style.transition=n}(e,{prepare:t,inFlight:i}),s.nextFrame(()=>{r(),s.requestAnimationFrame(()=>{s.add(function(e,t){var r,n;let i=(0,l.disposables)();if(!e)return i.dispose;let s=!1;i.add(()=>{s=!0});let a=null!=(n=null==(r=e.getAnimations)?void 0:r.call(e).filter(e=>e instanceof CSSTransition))?n:[];return 0===a.length?t():Promise.allSettled(a.map(e=>e.finished)).then(()=>{s||t()}),i.dispose}(e,n))})}),s.dispose}(t,{inFlight:f,prepare(){h.current?h.current=!1:h.current=f.current,f.current=!0,h.current||(r?(d(3),m(4)):(d(4),m(2)))},run(){h.current?r?(m(3),d(4)):(m(4),d(3)):r?m(1):d(1)},done(){var e;h.current&&"function"==typeof t.getAnimations&&t.getAnimations().length>0||(f.current=!1,m(7),r||s(!1),null==(e=null==n?void 0:n.end)||e.call(n,r))}})}},[e,r,t,p]),e?[i,{closed:u(1),enter:u(2),leave:u(4),transition:u(2)||u(4)}]:[r,{closed:void 0,enter:void 0,leave:void 0,transition:void 0}]}],83733);let d=(0,a.createContext)(null);d.displayName="OpenClosedContext";var m=((r=m||{})[r.Open=1]="Open",r[r.Closed=2]="Closed",r[r.Closing=4]="Closing",r[r.Opening=8]="Opening",r);e.s(["OpenClosedProvider",0,function({value:e,children:t}){return a.default.createElement(d.Provider,{value:e},t)},"ResetOpenClosedProvider",0,function({children:e}){return a.default.createElement(d.Provider,{value:null},e)},"State",0,m,"useOpenClosed",0,function(){return(0,a.useContext)(d)}],233137)},677667,674175,886148,543086,e=>{"use strict";let t,r;var n,i=e.i(290571),s=e.i(783222),a=e.i(433336),l=e.i(271645),o=e.i(394487),c=e.i(914189),u=e.i(144279),d=e.i(294316),m=e.i(83733);let f=(0,l.createContext)(()=>{});function h({value:e,children:t}){return l.default.createElement(f.Provider,{value:e},t)}e.s(["CloseProvider",0,h],674175);var p=e.i(233137),g=e.i(233538),x=e.i(397701),y=e.i(402155),v=e.i(700020);let b=null!=(n=l.default.startTransition)?n:function(e){e()};var _=e.i(998348),j=((t=j||{})[t.Open=0]="Open",t[t.Closed=1]="Closed",t),k=((r=k||{})[r.ToggleDisclosure=0]="ToggleDisclosure",r[r.CloseDisclosure=1]="CloseDisclosure",r[r.SetButtonId=2]="SetButtonId",r[r.SetPanelId=3]="SetPanelId",r[r.SetButtonElement=4]="SetButtonElement",r[r.SetPanelElement=5]="SetPanelElement",r);let w={0:e=>({...e,disclosureState:(0,x.match)(e.disclosureState,{0:1,1:0})}),1:e=>1===e.disclosureState?e:{...e,disclosureState:1},2:(e,t)=>e.buttonId===t.buttonId?e:{...e,buttonId:t.buttonId},3:(e,t)=>e.panelId===t.panelId?e:{...e,panelId:t.panelId},4:(e,t)=>e.buttonElement===t.element?e:{...e,buttonElement:t.element},5:(e,t)=>e.panelElement===t.element?e:{...e,panelElement:t.element}},C=(0,l.createContext)(null);function S(e){let t=(0,l.useContext)(C);if(null===t){let t=Error(`<${e} /> is missing a parent component.`);throw Error.captureStackTrace&&Error.captureStackTrace(t,S),t}return t}C.displayName="DisclosureContext";let E=(0,l.createContext)(null);E.displayName="DisclosureAPIContext";let O=(0,l.createContext)(null);function N(e,t){return(0,x.match)(t.type,w,e,t)}O.displayName="DisclosurePanelContext";let I=l.Fragment,T=v.RenderFeatures.RenderStrategy|v.RenderFeatures.Static,R=Object.assign((0,v.forwardRefWithAs)(function(e,t){let{defaultOpen:r=!1,...n}=e,i=(0,l.useRef)(null),s=(0,d.useSyncRefs)(t,(0,d.optionalRef)(e=>{i.current=e},void 0===e.as||e.as===l.Fragment)),a=(0,l.useReducer)(N,{disclosureState:+!r,buttonElement:null,panelElement:null,buttonId:null,panelId:null}),[{disclosureState:o,buttonId:u},m]=a,f=(0,c.useEvent)(e=>{m({type:1});let t=(0,y.getOwnerDocument)(i);if(!t||!u)return;let r=e?e instanceof HTMLElement?e:e.current instanceof HTMLElement?e.current:t.getElementById(u):t.getElementById(u);null==r||r.focus()}),g=(0,l.useMemo)(()=>({close:f}),[f]),b=(0,l.useMemo)(()=>({open:0===o,close:f}),[o,f]),_=(0,v.useRender)();return l.default.createElement(C.Provider,{value:a},l.default.createElement(E.Provider,{value:g},l.default.createElement(h,{value:f},l.default.createElement(p.OpenClosedProvider,{value:(0,x.match)(o,{0:p.State.Open,1:p.State.Closed})},_({ourProps:{ref:s},theirProps:n,slot:b,defaultTag:I,name:"Disclosure"})))))}),{Button:(0,v.forwardRefWithAs)(function(e,t){let r=(0,l.useId)(),{id:n=`headlessui-disclosure-button-${r}`,disabled:i=!1,autoFocus:m=!1,...f}=e,[h,p]=S("Disclosure.Button"),x=(0,l.useContext)(O),y=null!==x&&x===h.panelId,b=(0,l.useRef)(null),j=(0,d.useSyncRefs)(b,t,(0,c.useEvent)(e=>{if(!y)return p({type:4,element:e})}));(0,l.useEffect)(()=>{if(!y)return p({type:2,buttonId:n}),()=>{p({type:2,buttonId:null})}},[n,p,y]);let k=(0,c.useEvent)(e=>{var t;if(y){if(1===h.disclosureState)return;switch(e.key){case _.Keys.Space:case _.Keys.Enter:e.preventDefault(),e.stopPropagation(),p({type:0}),null==(t=h.buttonElement)||t.focus()}}else switch(e.key){case _.Keys.Space:case _.Keys.Enter:e.preventDefault(),e.stopPropagation(),p({type:0})}}),w=(0,c.useEvent)(e=>{e.key===_.Keys.Space&&e.preventDefault()}),C=(0,c.useEvent)(e=>{var t;(0,g.isDisabledReactIssue7711)(e.currentTarget)||i||(y?(p({type:0}),null==(t=h.buttonElement)||t.focus()):p({type:0}))}),{isFocusVisible:E,focusProps:N}=(0,s.useFocusRing)({autoFocus:m}),{isHovered:I,hoverProps:T}=(0,a.useHover)({isDisabled:i}),{pressed:R,pressProps:P}=(0,o.useActivePress)({disabled:i}),$=(0,l.useMemo)(()=>({open:0===h.disclosureState,hover:I,active:R,disabled:i,focus:E,autofocus:m}),[h,I,R,E,i,m]),D=(0,u.useResolveButtonType)(e,h.buttonElement),A=y?(0,v.mergeProps)({ref:j,type:D,disabled:i||void 0,autoFocus:m,onKeyDown:k,onClick:C},N,T,P):(0,v.mergeProps)({ref:j,id:n,type:D,"aria-expanded":0===h.disclosureState,"aria-controls":h.panelElement?h.panelId:void 0,disabled:i||void 0,autoFocus:m,onKeyDown:k,onKeyUp:w,onClick:C},N,T,P);return(0,v.useRender)()({ourProps:A,theirProps:f,slot:$,defaultTag:"button",name:"Disclosure.Button"})}),Panel:(0,v.forwardRefWithAs)(function(e,t){let r=(0,l.useId)(),{id:n=`headlessui-disclosure-panel-${r}`,transition:i=!1,...s}=e,[a,o]=S("Disclosure.Panel"),{close:u}=function e(t){let r=(0,l.useContext)(E);if(null===r){let r=Error(`<${t} /> is missing a parent component.`);throw Error.captureStackTrace&&Error.captureStackTrace(r,e),r}return r}("Disclosure.Panel"),[f,h]=(0,l.useState)(null),g=(0,d.useSyncRefs)(t,(0,c.useEvent)(e=>{b(()=>o({type:5,element:e}))}),h);(0,l.useEffect)(()=>(o({type:3,panelId:n}),()=>{o({type:3,panelId:null})}),[n,o]);let x=(0,p.useOpenClosed)(),[y,_]=(0,m.useTransition)(i,f,null!==x?(x&p.State.Open)===p.State.Open:0===a.disclosureState),j=(0,l.useMemo)(()=>({open:0===a.disclosureState,close:u}),[a.disclosureState,u]),k={ref:g,id:n,...(0,m.transitionDataAttributes)(_)},w=(0,v.useRender)();return l.default.createElement(p.ResetOpenClosedProvider,null,l.default.createElement(O.Provider,{value:a.panelId},w({ourProps:k,theirProps:s,slot:j,defaultTag:"div",features:T,visible:y,name:"Disclosure.Panel"})))})});e.s(["Disclosure",0,R],886148);let P=(0,l.createContext)(void 0);var $=e.i(444755);let D=(0,e.i(673706).makeClassName)("Accordion"),A=(0,l.createContext)({isOpen:!1}),F=l.default.forwardRef((e,t)=>{var r;let{defaultOpen:n=!1,children:s,className:a}=e,o=(0,i.__rest)(e,["defaultOpen","children","className"]),c=null!=(r=(0,l.useContext)(P))?r:(0,$.tremorTwMerge)("rounded-tremor-default border");return l.default.createElement(R,Object.assign({as:"div",ref:t,className:(0,$.tremorTwMerge)(D("root"),"overflow-hidden","bg-tremor-background border-tremor-border","dark:bg-dark-tremor-background dark:border-dark-tremor-border",c,a),defaultOpen:n},o),({open:e})=>l.default.createElement(A.Provider,{value:{isOpen:e}},s))});F.displayName="Accordion",e.s(["OpenContext",0,A,"default",0,F],543086),e.s(["Accordion",0,F],677667)},898667,e=>{"use strict";var t=e.i(290571),r=e.i(271645),n=e.i(886148);let i=e=>{var n=(0,t.__rest)(e,[]);return r.default.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"},n),r.default.createElement("path",{d:"M11.9999 10.8284L7.0502 15.7782L5.63599 14.364L11.9999 8L18.3639 14.364L16.9497 15.7782L11.9999 10.8284Z"}))};var s=e.i(543086),a=e.i(444755);let l=(0,e.i(673706).makeClassName)("AccordionHeader"),o=r.default.forwardRef((e,o)=>{let{children:c,className:u}=e,d=(0,t.__rest)(e,["children","className"]),{isOpen:m}=(0,r.useContext)(s.OpenContext);return r.default.createElement(n.Disclosure.Button,Object.assign({ref:o,className:(0,a.tremorTwMerge)(l("root"),"w-full flex items-center justify-between px-4 py-3","text-tremor-content-emphasis","dark:text-dark-tremor-content-emphasis",u)},d),r.default.createElement("div",{className:(0,a.tremorTwMerge)(l("children"),"flex flex-1 text-inherit mr-4")},c),r.default.createElement("div",null,r.default.createElement(i,{className:(0,a.tremorTwMerge)(l("arrowIcon"),"h-5 w-5 -mr-1","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle",m?"transition-all":"transition-all -rotate-180")})))});o.displayName="AccordionHeader",e.s(["AccordionHeader",0,o],898667)},130643,e=>{"use strict";var t=e.i(290571),r=e.i(271645),n=e.i(886148),i=e.i(444755);let s=(0,e.i(673706).makeClassName)("AccordionBody"),a=r.default.forwardRef((e,a)=>{let{children:l,className:o}=e,c=(0,t.__rest)(e,["children","className"]);return r.default.createElement(n.Disclosure.Panel,Object.assign({ref:a,className:(0,i.tremorTwMerge)(s("root"),"w-full text-tremor-default px-4 pb-3","text-tremor-content","dark:text-dark-tremor-content",o)},c),l)});a.displayName="AccordionBody",e.s(["AccordionBody",0,a],130643)},220508,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"}))});e.s(["CheckCircleIcon",0,r],220508)},503269,214520,601893,694421,140721,942803,35889,722678,e=>{"use strict";var t=e.i(271645),r=e.i(914189);e.s(["useControllable",0,function(e,n,i){let[s,a]=(0,t.useState)(i),l=void 0!==e,o=(0,t.useRef)(l),c=(0,t.useRef)(!1),u=(0,t.useRef)(!1);return!l||o.current||c.current?l||!o.current||u.current||(u.current=!0,o.current=l,console.error("A component is changing from controlled to uncontrolled. This may be caused by the value changing from a defined value to undefined, which should not happen.")):(c.current=!0,o.current=l,console.error("A component is changing from uncontrolled to controlled. This may be caused by the value changing from undefined to a defined value, which should not happen.")),[l?e:s,(0,r.useEvent)(e=>(l||a(e),null==n?void 0:n(e)))]}],503269),e.s(["useDefaultValue",0,function(e){let[r]=(0,t.useState)(e);return r}],214520);let n=(0,t.createContext)(void 0);function i(){return(0,t.useContext)(n)}e.s(["useDisabled",0,i],601893);var s=e.i(174080),a=e.i(746725);function l(e={},t=null,r=[]){for(let[n,i]of Object.entries(e))!function e(t,r,n){if(Array.isArray(n))for(let[i,s]of n.entries())e(t,o(r,i.toString()),s);else n instanceof Date?t.push([r,n.toISOString()]):"boolean"==typeof n?t.push([r,n?"1":"0"]):"string"==typeof n?t.push([r,n]):"number"==typeof n?t.push([r,`${n}`]):null==n?t.push([r,""]):l(n,r,t)}(r,o(t,n),i);return r}function o(e,t){return e?e+"["+t+"]":t}e.s(["attemptSubmit",0,function(e){var t,r;let n=null!=(t=null==e?void 0:e.form)?t:e.closest("form");if(n){for(let t of n.elements)if(t!==e&&("INPUT"===t.tagName&&"submit"===t.type||"BUTTON"===t.tagName&&"submit"===t.type||"INPUT"===t.nodeName&&"image"===t.type))return void t.click();null==(r=n.requestSubmit)||r.call(n)}},"objectToFormEntries",0,l],694421);var c=e.i(700020),u=e.i(2788);let d=(0,t.createContext)(null);function m({children:e}){let r=(0,t.useContext)(d);if(!r)return t.default.createElement(t.default.Fragment,null,e);let{target:n}=r;return n?(0,s.createPortal)(t.default.createElement(t.default.Fragment,null,e),n):null}function f({setForm:e,formId:r}){return(0,t.useEffect)(()=>{if(r){let t=document.getElementById(r);t&&e(t)}},[e,r]),r?null:t.default.createElement(u.Hidden,{features:u.HiddenFeatures.Hidden,as:"input",type:"hidden",hidden:!0,readOnly:!0,ref:t=>{if(!t)return;let r=t.closest("form");r&&e(r)}})}e.s(["FormFields",0,function({data:e,form:r,disabled:n,onReset:i,overrides:s}){let[o,d]=(0,t.useState)(null),h=(0,a.useDisposables)();return(0,t.useEffect)(()=>{if(i&&o)return h.addEventListener(o,"reset",i)},[o,r,i]),t.default.createElement(m,null,t.default.createElement(f,{setForm:d,formId:r}),l(e).map(([e,i])=>t.default.createElement(u.Hidden,{features:u.HiddenFeatures.Hidden,...(0,c.compact)({key:e,as:"input",type:"hidden",hidden:!0,readOnly:!0,form:r,disabled:n,name:e,value:i,...s})})))}],140721);let h=(0,t.createContext)(void 0);function p(){return(0,t.useContext)(h)}e.s(["useProvidedId",0,p],942803);var g=e.i(835696),x=e.i(294316);let y=(0,t.createContext)(null);y.displayName="DescriptionContext";let v=Object.assign((0,c.forwardRefWithAs)(function(e,r){let n=(0,t.useId)(),s=i(),{id:a=`headlessui-description-${n}`,...l}=e,o=function e(){let r=(0,t.useContext)(y);if(null===r){let t=Error("You used a component, but it is not inside a relevant parent.");throw Error.captureStackTrace&&Error.captureStackTrace(t,e),t}return r}(),u=(0,x.useSyncRefs)(r);(0,g.useIsoMorphicEffect)(()=>o.register(a),[a,o.register]);let d=s||!1,m=(0,t.useMemo)(()=>({...o.slot,disabled:d}),[o.slot,d]),f={ref:u,...o.props,id:a};return(0,c.useRender)()({ourProps:f,theirProps:l,slot:m,defaultTag:"p",name:o.name||"Description"})}),{});e.s(["Description",0,v,"useDescribedBy",0,function(){var e,r;return null!=(r=null==(e=(0,t.useContext)(y))?void 0:e.value)?r:void 0},"useDescriptions",0,function(){let[e,n]=(0,t.useState)([]);return[e.length>0?e.join(" "):void 0,(0,t.useMemo)(()=>function(e){let i=(0,r.useEvent)(e=>(n(t=>[...t,e]),()=>n(t=>{let r=t.slice(),n=r.indexOf(e);return -1!==n&&r.splice(n,1),r}))),s=(0,t.useMemo)(()=>({register:i,slot:e.slot,name:e.name,props:e.props,value:e.value}),[i,e.slot,e.name,e.props,e.value]);return t.default.createElement(y.Provider,{value:s},e.children)},[n])]}],35889);let b=(0,t.createContext)(null);function _(e){var r,n,i;let s=null!=(n=null==(r=(0,t.useContext)(b))?void 0:r.value)?n:void 0;return(null!=(i=null==e?void 0:e.length)?i:0)>0?[s,...e].filter(Boolean).join(" "):s}b.displayName="LabelContext";let j=Object.assign((0,c.forwardRefWithAs)(function(e,n){var s;let a=(0,t.useId)(),l=function e(){let r=(0,t.useContext)(b);if(null===r){let t=Error("You used a