diff --git a/.github/workflows/openapi-bundle.yml b/.github/workflows/openapi-bundle.yml new file mode 100644 index 000000000..f88e2c370 --- /dev/null +++ b/.github/workflows/openapi-bundle.yml @@ -0,0 +1,55 @@ +name: OpenAPI Bundle + +on: + push: + branches: ["main"] + paths: + - "docs/openapi/**" + - "!docs/openapi/openapi.json" + pull_request: + paths: + - "docs/openapi/**" + - "!docs/openapi/openapi.json" + +permissions: + contents: write + +jobs: + bundle-openapi: + name: Bundle OpenAPI Spec + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install dependencies + run: pip install pyyaml + + - name: Bundle OpenAPI spec + working-directory: ./docs/openapi + run: python bundle.py + + - name: Check for changes + id: changes + run: | + if git diff --quiet docs/openapi/openapi.json; then + echo "changed=false" >> $GITHUB_OUTPUT + else + echo "changed=true" >> $GITHUB_OUTPUT + fi + + - name: Commit and push changes + if: steps.changes.outputs.changed == 'true' && github.event_name == 'push' + run: | + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git add docs/openapi/openapi.json + git commit -m "chore: regenerate openapi.json --skip-pipeline" + git push diff --git a/docs/features/mcp/agent-mode.mdx b/docs/features/mcp/agent-mode.mdx index 3ac51f57f..97a32d935 100644 --- a/docs/features/mcp/agent-mode.mdx +++ b/docs/features/mcp/agent-mode.mdx @@ -13,6 +13,10 @@ This feature is only available on `v1.4.0-prerelease1` and above. Please check t **Agent Mode** enables Bifrost to automatically execute tool calls without requiring explicit execution API calls for each tool. This transforms Bifrost from a simple gateway into an autonomous agent runtime. + +**Streaming Not Supported**: Agent Mode is not compatible with streaming operations (`chat_stream` and `responses_stream`). Due to architectural limitations, the autonomous tool execution loop requires complete responses before proceeding to the next iteration (we cannot store all streaming chunks in memory just "in case" we get any tool calls, this would be a big anti-pattern). Use non-streaming endpoints (`chat` and `responses`) when Agent Mode is enabled. + + When Agent Mode is enabled: 1. LLM returns tool calls in its response 2. Bifrost automatically executes **auto-executable** tools diff --git a/docs/openapi/openapi.json b/docs/openapi/openapi.json index 3f95ba6a4..e180866cd 100644 --- a/docs/openapi/openapi.json +++ b/docs/openapi/openapi.json @@ -164,7 +164,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] } }, @@ -372,7 +373,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -503,7 +505,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -583,7 +586,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -1786,7 +1790,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -2491,7 +2496,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -2619,7 +2625,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -2699,7 +2706,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -3407,7 +3415,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -4053,7 +4062,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -4181,7 +4191,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -4261,7 +4272,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -5815,7 +5827,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -6815,7 +6828,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -7538,7 +7552,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -7666,7 +7681,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -7746,7 +7762,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -7999,7 +8016,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -8127,7 +8145,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -8207,7 +8226,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -8456,7 +8476,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -8576,7 +8597,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -8704,7 +8726,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -8784,7 +8807,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -9026,7 +9050,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -9189,7 +9214,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -9317,7 +9343,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -9397,7 +9424,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -9999,7 +10027,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -10127,7 +10156,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -10207,7 +10237,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -10425,7 +10456,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -10553,7 +10585,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -10633,7 +10666,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -10685,7 +10719,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] } }, @@ -10910,7 +10945,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -11013,7 +11049,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -11141,7 +11178,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -11221,7 +11259,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -11284,7 +11323,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] } } @@ -11476,7 +11516,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -11604,7 +11645,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -11684,7 +11726,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -11747,7 +11790,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] } } @@ -11843,7 +11887,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -11971,7 +12016,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -12051,7 +12097,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -12114,7 +12161,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] } } @@ -12212,7 +12260,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -12340,7 +12389,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -12420,7 +12470,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -12473,7 +12524,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] } } @@ -12527,7 +12579,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] } } @@ -12625,7 +12678,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -12753,7 +12807,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -12833,7 +12888,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -12885,7 +12941,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] } }, @@ -13038,7 +13095,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -13166,7 +13224,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -13246,7 +13305,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -13309,7 +13369,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] } } @@ -13404,7 +13465,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -13532,7 +13594,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -13612,7 +13675,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -13673,7 +13737,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] } } @@ -13724,7 +13789,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -13852,7 +13918,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -13932,7 +13999,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -13995,7 +14063,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] } } @@ -14076,7 +14145,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -14156,7 +14226,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -15300,7 +15371,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -16005,7 +16077,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -16133,7 +16206,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -16213,7 +16287,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -17377,7 +17452,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -18082,7 +18158,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -18210,7 +18287,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -18290,7 +18368,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -19013,7 +19092,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -19659,7 +19739,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -19787,7 +19868,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -19867,7 +19949,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -20608,7 +20691,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -21254,7 +21338,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -21382,7 +21467,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -21462,7 +21548,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -22990,7 +23077,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -23990,7 +24078,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -24713,7 +24802,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -24841,7 +24931,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -24921,7 +25012,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -26467,7 +26559,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -27467,7 +27560,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -28190,7 +28284,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -28318,7 +28413,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -28398,7 +28494,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -29183,7 +29280,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -29311,7 +29409,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -29391,7 +29490,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -29634,7 +29734,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -29762,7 +29863,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -29842,7 +29944,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -30103,7 +30206,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -30231,7 +30335,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -30311,7 +30416,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -30490,7 +30596,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -30618,7 +30725,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -30698,7 +30806,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -30895,7 +31004,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -31023,7 +31133,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -31103,7 +31214,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -31360,7 +31472,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -31523,7 +31636,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -31651,7 +31765,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -31731,7 +31846,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -32006,7 +32122,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -32169,7 +32286,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -32297,7 +32415,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -32377,7 +32496,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -32516,7 +32636,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -32596,7 +32717,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -32753,7 +32875,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -32833,7 +32956,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -33051,7 +33175,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -33179,7 +33304,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -33259,7 +33385,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -33506,7 +33633,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -33609,7 +33737,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -33737,7 +33866,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -33817,7 +33947,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -34050,7 +34181,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -34178,7 +34310,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -34258,7 +34391,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -34395,7 +34529,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -34523,7 +34658,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -34603,7 +34739,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -34802,7 +34939,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -34930,7 +35068,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -35010,7 +35149,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -35181,7 +35321,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -35309,7 +35450,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -35389,7 +35531,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -35525,7 +35668,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -35653,7 +35797,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -35733,7 +35878,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -35823,7 +35969,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -35951,7 +36098,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -36031,7 +36179,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -36153,7 +36302,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -36233,7 +36383,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -51562,7 +51713,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -52208,7 +52360,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -52336,7 +52489,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -52416,7 +52570,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -53560,7 +53715,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -54265,7 +54421,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -54393,7 +54550,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -54473,7 +54631,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -54716,7 +54875,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -54844,7 +55004,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -54924,7 +55085,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -55063,7 +55225,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -55143,7 +55306,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -56671,7 +56835,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -57671,7 +57836,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -58394,7 +58560,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -58522,7 +58689,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -58602,7 +58770,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -59387,7 +59556,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -59515,7 +59685,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -59595,7 +59766,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -59756,7 +59928,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -59884,7 +60057,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -59964,7 +60138,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -60221,7 +60396,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -60384,7 +60560,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -60512,7 +60689,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -60592,7 +60770,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -69687,7 +69866,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -70333,7 +70513,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -70461,7 +70642,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -70541,7 +70723,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -71685,7 +71868,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -72390,7 +72574,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -72518,7 +72703,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -72598,7 +72784,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -72841,7 +73028,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -72969,7 +73157,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -73049,7 +73238,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -73188,7 +73378,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -73268,7 +73459,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -74796,7 +74988,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -75796,7 +75989,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -76519,7 +76713,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -76647,7 +76842,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -76727,7 +76923,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -77512,7 +77709,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -77640,7 +77838,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -77720,7 +77919,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -77881,7 +78081,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -78009,7 +78210,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -78089,7 +78291,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -78346,7 +78549,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -78509,7 +78713,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -78637,7 +78842,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -78717,7 +78923,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -88435,7 +88642,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -89081,7 +89289,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -89209,7 +89418,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -89289,7 +89499,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -90433,7 +90644,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -91138,7 +91350,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -91266,7 +91479,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -91346,7 +91560,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -91589,7 +91804,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -91717,7 +91933,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -91797,7 +92014,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -91936,7 +92154,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -92016,7 +92235,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -93544,7 +93764,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -94544,7 +94765,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -95267,7 +95489,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -95395,7 +95618,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -95475,7 +95699,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -96260,7 +96485,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -96388,7 +96614,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -96468,7 +96695,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -96629,7 +96857,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -96757,7 +96986,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -96837,7 +97067,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -97094,7 +97325,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -97257,7 +97489,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -97385,7 +97618,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -97465,7 +97699,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -106176,7 +106411,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -106412,7 +106648,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -106492,7 +106729,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -106662,7 +106900,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -106835,7 +107074,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -106915,7 +107155,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -107028,7 +107269,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -107183,7 +107425,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -107380,7 +107623,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -107443,7 +107687,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "keys": { @@ -107697,7 +107942,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "allowed_requests": { @@ -107867,7 +108113,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -107924,7 +108171,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "keys": { @@ -108178,7 +108426,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "allowed_requests": { @@ -108299,7 +108548,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "keys": { @@ -108553,7 +108803,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "allowed_requests": { @@ -108717,7 +108968,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -108816,7 +109068,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -108884,7 +109137,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "keys": { @@ -109138,7 +109392,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "allowed_requests": { @@ -109302,7 +109557,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -109401,7 +109657,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -109696,7 +109953,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "allowed_requests": { @@ -109817,7 +110075,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "keys": { @@ -110071,7 +110330,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "allowed_requests": { @@ -110235,7 +110495,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -110315,7 +110576,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -110381,7 +110643,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "keys": { @@ -110635,7 +110898,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "allowed_requests": { @@ -110799,7 +111063,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -110898,7 +111163,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -111138,7 +111404,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -111302,7 +111569,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -111462,7 +111730,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -111646,7 +111915,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -111745,7 +112015,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -111904,7 +112175,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -112003,7 +112275,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -112192,7 +112465,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -112291,7 +112565,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -112408,7 +112683,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -112507,7 +112783,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -112641,7 +112918,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -112721,7 +112999,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -112920,7 +113199,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -113103,7 +113383,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -113183,7 +113464,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -113377,7 +113659,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -113457,7 +113740,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -113579,7 +113863,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -113659,7 +113944,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -113783,7 +114069,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -113863,7 +114150,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -114186,7 +114474,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -114650,7 +114939,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -114730,7 +115020,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -115076,7 +115367,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -115546,7 +115838,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -115645,7 +115938,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -115781,7 +116075,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -115949,7 +116244,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -116140,7 +116436,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -116220,7 +116517,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -116401,7 +116699,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -116596,7 +116895,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -116695,7 +116995,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -116831,7 +117132,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -116986,7 +117288,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -117171,7 +117474,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -117251,7 +117555,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -117429,7 +117734,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -117618,7 +117924,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -117717,7 +118024,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -117853,7 +118161,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -118222,7 +118531,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -118302,7 +118612,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -118430,7 +118741,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -118510,7 +118822,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -118774,7 +119087,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -118854,7 +119168,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -119016,7 +119331,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -119221,7 +119537,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -119301,7 +119618,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -119421,7 +119739,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -119501,7 +119820,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -119621,7 +119941,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -119701,7 +120022,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -119787,7 +120109,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -119867,7 +120190,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -119906,7 +120230,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "Fallback": { @@ -119938,7 +120263,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model": { @@ -120007,7 +120333,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -120064,7 +120391,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -120104,7 +120432,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -120538,7 +120867,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -121912,7 +122242,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -122990,7 +123321,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -124566,7 +124898,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -124897,7 +125230,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -125162,7 +125496,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -125426,7 +125761,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -126050,7 +126386,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -126290,7 +126627,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -126541,7 +126879,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -126644,7 +126983,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -126887,7 +127227,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -126993,7 +127334,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] } } @@ -127083,7 +127425,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -127240,7 +127583,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "model_requested": { @@ -135366,7 +135710,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "keys": { @@ -135620,7 +135965,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "allowed_requests": { @@ -135748,7 +136094,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "keys": { @@ -136002,7 +136349,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "allowed_requests": { @@ -136133,7 +136481,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "keys": { @@ -136387,7 +136736,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "allowed_requests": { @@ -136730,7 +137080,8 @@ "openrouter", "elevenlabs", "huggingface", - "nebius" + "nebius", + "xai" ] }, "allowed_requests": { diff --git a/docs/quickstart/gateway/cli-agents.mdx b/docs/quickstart/gateway/cli-agents.mdx index f35e6e2fb..b7387c325 100644 --- a/docs/quickstart/gateway/cli-agents.mdx +++ b/docs/quickstart/gateway/cli-agents.mdx @@ -54,7 +54,7 @@ It is a modern, open-source chat client that supports multiple providers. ### [Claude Code](https://www.claude.com/product/claude-code) -It brings Sonnet 4.5 directly to your terminal with powerful coding capabilities. +It brings AI-powered coding capabilities directly to your terminal. **Setup:** @@ -80,6 +80,99 @@ Now all Claude Code traffic flows through Bifrost, giving you access to any prov This setup automatically detects if you're using Anthropic MAX account instead of a regular API key authentication :) +#### Model Configuration + +Claude Code uses three model tiers: **Sonnet** (default), **Opus** (complex tasks), and **Haiku** (fast, lightweight). With Bifrost, you can override these defaults to use any model from any provider. + +**Override Default Models:** + +Set environment variables to replace Claude Code's default model tiers with any Bifrost-configured model: + +```bash +# Replace Sonnet tier with GPT-5 +export ANTHROPIC_DEFAULT_SONNET_MODEL="openai/gpt-5" + +# Replace Opus tier with Claude Opus 4.5 +export ANTHROPIC_DEFAULT_OPUS_MODEL="anthropic/claude-opus-4-5-20251101" + +# Replace Haiku tier with Azure-hosted Claude +export ANTHROPIC_DEFAULT_HAIKU_MODEL="azure/claude-haiku-4-5" +``` + + +Alternative models must support **tool use capabilities** for file operations, terminal commands, and code editing to work properly with Claude Code. + + +**Start with a Specific Model:** + +Launch Claude Code with a specific model using the `--model` flag: + +```bash +# Start with Opus +claude --model claude-opus-4-5-20251101 + +# Start with Haiku for lightweight tasks +claude --model claude-haiku-4-5-20251001 +``` + +#### Switching Models Mid-Session + +Use the `/model` command to switch models during an active session: + +```bash +# Using shorthand +/model opus +/model sonnet +/model haiku + +# Using full model names +/model claude-opus-4-5-20251101 +/model claude-sonnet-4-5-20250929 + +# Using different providers dynamically via Bifrost +/model vertex/claude-haiku-4-5 +/model azure/claude-sonnet-4-5 +/model bedrock/claude-sonnet-4-5 +``` + + +Run `/model` without arguments to check your current model. The switch is instantaneous and Claude Code seamlessly continues your conversation context with the new model. + + + +If you use Claude-specific features like **web search**, **computer use**, or **citations**, ensure the model you switch to also supports these capabilities. Non-Claude models or Claude models on certain providers may not support all features. + + +#### Model Selection Guide + +| Model | Best For | Cost | +|-------|----------|------| +| **Sonnet 4.5** | Daily development, general coding tasks | Medium | +| **Opus 4.5** | Complex reasoning, architectural decisions, state-of-the-art engineering | High | +| **Haiku 4.5** | Lightweight agents, high-frequency tasks, quick iterations | Low | + +#### Example: Full Bifrost Setup + +Here's a complete setup using Bifrost with custom model overrides: + +```bash +# Core Bifrost configuration +export ANTHROPIC_API_KEY=your-bifrost-virtual-key +export ANTHROPIC_BASE_URL=http://localhost:8080/anthropic + +# Custom model tiers (optional) +export ANTHROPIC_DEFAULT_SONNET_MODEL="anthropic/claude-sonnet-4-5-20250929" +export ANTHROPIC_DEFAULT_OPUS_MODEL="openai/gpt-5" +export ANTHROPIC_DEFAULT_HAIKU_MODEL="azure/claude-haiku-4-5" + +# Start Claude Code +claude +``` + + +Add these exports to your `~/.bashrc` or `~/.zshrc` for persistent configuration across terminal sessions. + + ### [Codex CLI](https://developers.openai.com/codex/cli/) It provides powerful code generation and completion capabilities. diff --git a/docs/quickstart/gateway/provider-configuration.mdx b/docs/quickstart/gateway/provider-configuration.mdx index f1e012b01..ad0819425 100644 --- a/docs/quickstart/gateway/provider-configuration.mdx +++ b/docs/quickstart/gateway/provider-configuration.mdx @@ -335,7 +335,7 @@ Customize the network configuration for each provider, including custom base URL -![Network Configuration Interface](../../media/ui-proxy-setup.png) +![Network Configuration Interface](../../media/ui-concurrency-timeout.png) 1. Navigate to **"Providers"** → **"OpenAI"** → **"Advanced"** 2. Set **Base URL**: `http://localhost:8000/v1` diff --git a/docs/quickstart/gateway/setting-up-auth.mdx b/docs/quickstart/gateway/setting-up-auth.mdx index 7ed35f283..71147d07b 100644 --- a/docs/quickstart/gateway/setting-up-auth.mdx +++ b/docs/quickstart/gateway/setting-up-auth.mdx @@ -45,7 +45,7 @@ This option is useful if you want to protect your dashboard and admin functions ### Step 4: Save Changes 1. Click **Save Changes** to apply your authentication settings -2. You may need to **restart Bifrost** for the changes to take effect (a warning will be displayed if a restart is required) +2. Changes take effect immediately - no restart required ## Logging In @@ -90,7 +90,7 @@ curl -X POST http://localhost:8080/v1/chat/completions \ ## Important Notes -- **Restart Required**: After enabling or changing authentication settings, you may need to restart Bifrost for changes to take effect +- **No Restart Required**: Authentication changes take effect immediately without requiring a server restart - **Session Duration**: Login sessions last for 30 days - **Password Security**: Passwords are hashed and stored securely in the database - **Inference Calls**: If you disable authentication on inference calls, only dashboard and admin API endpoints will be protected @@ -102,6 +102,5 @@ To disable authentication: 1. Navigate to **Workspace** → **Config** → **Security** 2. Toggle off the **Password protect the dashboard** switch 3. Click **Save Changes** -4. Restart Bifrost if prompted -After disabling, the dashboard will be accessible without authentication. \ No newline at end of file +After disabling, the dashboard will be accessible without authentication immediately. \ No newline at end of file diff --git a/framework/changelog.md b/framework/changelog.md index e69de29bb..e4d4aaa71 100644 --- a/framework/changelog.md +++ b/framework/changelog.md @@ -0,0 +1 @@ +- feat: added flush session functionality to config store to clear all existing sessions \ No newline at end of file diff --git a/framework/configstore/clientconfig.go b/framework/configstore/clientconfig.go index 6c1275365..08352f811 100644 --- a/framework/configstore/clientconfig.go +++ b/framework/configstore/clientconfig.go @@ -34,20 +34,20 @@ type EnvKeyInfo struct { // ClientConfig represents the core configuration for Bifrost HTTP transport and the Bifrost Client. // It includes settings for excess request handling, Prometheus metrics, and initial pool size. type ClientConfig struct { - DropExcessRequests bool `json:"drop_excess_requests"` // Drop excess requests if the provider queue is full - InitialPoolSize int `json:"initial_pool_size"` // The initial pool size for the bifrost client - PrometheusLabels []string `json:"prometheus_labels"` // The labels to be used for prometheus metrics - EnableLogging bool `json:"enable_logging"` // Enable logging of requests and responses - DisableContentLogging bool `json:"disable_content_logging"` // Disable logging of content - LogRetentionDays int `json:"log_retention_days" validate:"min=1"` // Number of days to retain logs (minimum 1 day) - EnableGovernance bool `json:"enable_governance"` // Enable governance on all requests - EnforceGovernanceHeader bool `json:"enforce_governance_header"` // Enforce governance on all requests - AllowDirectKeys bool `json:"allow_direct_keys"` // Allow direct keys to be used for requests - AllowedOrigins []string `json:"allowed_origins,omitempty"` // Additional allowed origins for CORS and WebSocket (localhost is always allowed) - MaxRequestBodySizeMB int `json:"max_request_body_size_mb"` // The maximum request body size in MB - EnableLiteLLMFallbacks bool `json:"enable_litellm_fallbacks"` // Enable litellm-specific fallbacks for text completion for Groq + DropExcessRequests bool `json:"drop_excess_requests"` // Drop excess requests if the provider queue is full + InitialPoolSize int `json:"initial_pool_size"` // The initial pool size for the bifrost client + PrometheusLabels []string `json:"prometheus_labels"` // The labels to be used for prometheus metrics + EnableLogging bool `json:"enable_logging"` // Enable logging of requests and responses + DisableContentLogging bool `json:"disable_content_logging"` // Disable logging of content + LogRetentionDays int `json:"log_retention_days" validate:"min=1"` // Number of days to retain logs (minimum 1 day) + EnableGovernance bool `json:"enable_governance"` // Enable governance on all requests + EnforceGovernanceHeader bool `json:"enforce_governance_header"` // Enforce governance on all requests + AllowDirectKeys bool `json:"allow_direct_keys"` // Allow direct keys to be used for requests + AllowedOrigins []string `json:"allowed_origins,omitempty"` // Additional allowed origins for CORS and WebSocket (localhost is always allowed) + MaxRequestBodySizeMB int `json:"max_request_body_size_mb"` // The maximum request body size in MB + EnableLiteLLMFallbacks bool `json:"enable_litellm_fallbacks"` // Enable litellm-specific fallbacks for text completion for Groq HeaderFilterConfig *tables.GlobalHeaderFilterConfig `json:"header_filter_config,omitempty"` // Global header filtering configuration for x-bf-eh-* headers - ConfigHash string `json:"-"` // Config hash for reconciliation (not serialized) + ConfigHash string `json:"-"` // Config hash for reconciliation (not serialized) } // GenerateClientConfigHash generates a SHA256 hash of the client configuration. diff --git a/framework/configstore/rdb.go b/framework/configstore/rdb.go index 9900c2062..bb4444a73 100644 --- a/framework/configstore/rdb.go +++ b/framework/configstore/rdb.go @@ -325,7 +325,7 @@ func (s *RDBConfigStore) UpdateProvidersConfig(ctx context.Context, providers ma if result.Error == nil { // Found by name - update existing key, preserve original KeyID dbKey.ID = existingKey.ID - dbKey.KeyID = existingKey.KeyID // Preserve original KeyID + dbKey.KeyID = existingKey.KeyID // Preserve original KeyID dbKey.ProviderID = existingKey.ProviderID dbKey.Enabled = existingKey.Enabled if err := txDB.WithContext(ctx).Save(&dbKey).Error; err != nil { @@ -704,7 +704,7 @@ func (s *RDBConfigStore) GetProvidersConfig(ctx context.Context) (map[schemas.Mo if processedARN, err := envutils.ProcessEnvValue(*bedrockConfig.ARN); err == nil { bedrockConfigCopy.ARN = &processedARN } - } + } bedrockConfig = &bedrockConfigCopy } @@ -2149,6 +2149,11 @@ func (s *RDBConfigStore) DeleteSession(ctx context.Context, token string) error return s.db.WithContext(ctx).Delete(&tables.SessionsTable{}, "token = ?", token).Error } +// FlushSessions flushes all sessions from the database. +func (s *RDBConfigStore) FlushSessions(ctx context.Context) error { + return s.db.WithContext(ctx).Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&tables.SessionsTable{}).Error +} + // ExecuteTransaction executes a transaction. func (s *RDBConfigStore) ExecuteTransaction(ctx context.Context, fn func(tx *gorm.DB) error) error { return s.db.WithContext(ctx).Transaction(fn) diff --git a/framework/configstore/store.go b/framework/configstore/store.go index 2585e1971..781e72014 100644 --- a/framework/configstore/store.go +++ b/framework/configstore/store.go @@ -132,6 +132,7 @@ type ConfigStore interface { GetSession(ctx context.Context, token string) (*tables.SessionsTable, error) CreateSession(ctx context.Context, session *tables.SessionsTable) error DeleteSession(ctx context.Context, token string) error + FlushSessions(ctx context.Context) error // Model pricing CRUD GetModelPrices(ctx context.Context) ([]tables.TableModelPricing, error) diff --git a/framework/configstore/tables/config.go b/framework/configstore/tables/config.go index 1fff5b084..c265b8084 100644 --- a/framework/configstore/tables/config.go +++ b/framework/configstore/tables/config.go @@ -19,8 +19,6 @@ type RestartRequiredConfig struct { Reason string `json:"reason,omitempty"` } - - // GlobalProxyConfig represents the global proxy configuration type GlobalProxyConfig struct { Enabled bool `json:"enabled"` diff --git a/framework/version b/framework/version index 8c1a6bbc6..29c1447b4 100644 --- a/framework/version +++ b/framework/version @@ -1 +1 @@ -1.1.58 \ No newline at end of file +1.1.59 \ No newline at end of file diff --git a/plugins/governance/changelog.md b/plugins/governance/changelog.md index e69de29bb..1427ab323 100644 --- a/plugins/governance/changelog.md +++ b/plugins/governance/changelog.md @@ -0,0 +1 @@ +- chore: update framework version to 1.1.59 \ No newline at end of file diff --git a/plugins/governance/version b/plugins/governance/version index 94f8697dc..0629a7403 100644 --- a/plugins/governance/version +++ b/plugins/governance/version @@ -1 +1 @@ -1.3.59 \ No newline at end of file +1.3.60 \ No newline at end of file diff --git a/plugins/jsonparser/changelog.md b/plugins/jsonparser/changelog.md index e69de29bb..1427ab323 100644 --- a/plugins/jsonparser/changelog.md +++ b/plugins/jsonparser/changelog.md @@ -0,0 +1 @@ +- chore: update framework version to 1.1.59 \ No newline at end of file diff --git a/plugins/jsonparser/version b/plugins/jsonparser/version index 94f8697dc..0629a7403 100644 --- a/plugins/jsonparser/version +++ b/plugins/jsonparser/version @@ -1 +1 @@ -1.3.59 \ No newline at end of file +1.3.60 \ No newline at end of file diff --git a/plugins/logging/changelog.md b/plugins/logging/changelog.md index e69de29bb..1427ab323 100644 --- a/plugins/logging/changelog.md +++ b/plugins/logging/changelog.md @@ -0,0 +1 @@ +- chore: update framework version to 1.1.59 \ No newline at end of file diff --git a/plugins/logging/version b/plugins/logging/version index 94f8697dc..0629a7403 100644 --- a/plugins/logging/version +++ b/plugins/logging/version @@ -1 +1 @@ -1.3.59 \ No newline at end of file +1.3.60 \ No newline at end of file diff --git a/plugins/maxim/changelog.md b/plugins/maxim/changelog.md index e69de29bb..1427ab323 100644 --- a/plugins/maxim/changelog.md +++ b/plugins/maxim/changelog.md @@ -0,0 +1 @@ +- chore: update framework version to 1.1.59 \ No newline at end of file diff --git a/plugins/maxim/version b/plugins/maxim/version index fa553416f..a6a0eccbc 100644 --- a/plugins/maxim/version +++ b/plugins/maxim/version @@ -1 +1 @@ -1.4.60 \ No newline at end of file +1.4.61 \ No newline at end of file diff --git a/plugins/otel/changelog.md b/plugins/otel/changelog.md index e69de29bb..1427ab323 100644 --- a/plugins/otel/changelog.md +++ b/plugins/otel/changelog.md @@ -0,0 +1 @@ +- chore: update framework version to 1.1.59 \ No newline at end of file diff --git a/plugins/otel/version b/plugins/otel/version index 4ded4f901..1b5deead0 100644 --- a/plugins/otel/version +++ b/plugins/otel/version @@ -1 +1 @@ -1.0.58 \ No newline at end of file +1.0.59 \ No newline at end of file diff --git a/plugins/semanticcache/changelog.md b/plugins/semanticcache/changelog.md index e69de29bb..1427ab323 100644 --- a/plugins/semanticcache/changelog.md +++ b/plugins/semanticcache/changelog.md @@ -0,0 +1 @@ +- chore: update framework version to 1.1.59 \ No newline at end of file diff --git a/plugins/semanticcache/version b/plugins/semanticcache/version index f33f3c631..94f8697dc 100644 --- a/plugins/semanticcache/version +++ b/plugins/semanticcache/version @@ -1 +1 @@ -1.3.58 \ No newline at end of file +1.3.59 \ No newline at end of file diff --git a/plugins/telemetry/changelog.md b/plugins/telemetry/changelog.md index e69de29bb..1427ab323 100644 --- a/plugins/telemetry/changelog.md +++ b/plugins/telemetry/changelog.md @@ -0,0 +1 @@ +- chore: update framework version to 1.1.59 \ No newline at end of file diff --git a/plugins/telemetry/version b/plugins/telemetry/version index f33f3c631..94f8697dc 100644 --- a/plugins/telemetry/version +++ b/plugins/telemetry/version @@ -1 +1 @@ -1.3.58 \ No newline at end of file +1.3.59 \ No newline at end of file diff --git a/transports/bifrost-http/handlers/config.go b/transports/bifrost-http/handlers/config.go index 0348bdc87..26ad2b6a3 100644 --- a/transports/bifrost-http/handlers/config.go +++ b/transports/bifrost-http/handlers/config.go @@ -413,7 +413,7 @@ func (h *ConfigHandler) updateConfig(ctx *fasthttp.RequestCtx) { } } - // Check if auth config has changed (for restart required flag) + // Check if auth config has changed authChanged := false if authConfig == nil { // No existing config, any enabled state is a change @@ -424,14 +424,10 @@ func (h *ConfigHandler) updateConfig(ctx *fasthttp.RequestCtx) { // Compare with existing config if payload.AuthConfig.IsEnabled != authConfig.IsEnabled || payload.AuthConfig.AdminUserName != authConfig.AdminUserName || - payload.AuthConfig.DisableAuthOnInference != authConfig.DisableAuthOnInference || (payload.AuthConfig.AdminPassword != "" && payload.AuthConfig.AdminPassword != "") { authChanged = true } } - if authChanged { - restartReasons = append(restartReasons, "Authentication") - } if payload.AuthConfig.IsEnabled { if authConfig == nil && (payload.AuthConfig.AdminUserName == "" || payload.AuthConfig.AdminPassword == "") { @@ -459,17 +455,38 @@ func (h *ConfigHandler) updateConfig(ctx *fasthttp.RequestCtx) { payload.AuthConfig.AdminPassword = string(hashedPassword) } } - } - // Get auth config from store - authConfig, _ = h.store.ConfigStore.GetAuthConfig(ctx) - if authConfig != nil { + // Save auth config - this handles both first-time creation and updates err = h.configManager.UpdateAuthConfig(ctx, payload.AuthConfig) if err != nil { logger.Warn(fmt.Sprintf("failed to update auth config: %v", err)) SendError(ctx, fasthttp.StatusInternalServerError, fmt.Sprintf("failed to update auth config: %v", err)) return } + } else if authConfig != nil { + // Auth is being disabled but there's an existing config - preserve credentials and update disabled state + if payload.AuthConfig.AdminPassword == "" || payload.AuthConfig.AdminPassword == "" { + payload.AuthConfig.AdminPassword = authConfig.AdminPassword + } + if payload.AuthConfig.AdminUserName == "" { + payload.AuthConfig.AdminUserName = authConfig.AdminUserName + } + err = h.configManager.UpdateAuthConfig(ctx, payload.AuthConfig) + if err != nil { + logger.Warn(fmt.Sprintf("failed to update auth config: %v", err)) + SendError(ctx, fasthttp.StatusInternalServerError, fmt.Sprintf("failed to update auth config: %v", err)) + return + } + } + + // Flush all existing sessions if auth details have been changed + if authChanged { + if err := h.store.ConfigStore.FlushSessions(ctx); err != nil { + logger.Warn(fmt.Sprintf("updated auth config but failed to flush existing sessions, please restart the server: %v", err)) + SendError(ctx, fasthttp.StatusInternalServerError, fmt.Sprintf("updated auth config but failed to flush existing sessions, please restart the server: %v", err)) + return + } } + // Note: AuthMiddleware is updated via ServerCallbacks.UpdateAuthConfig (handled by BifrostHTTPServer) } // Set restart required flag if any restart-requiring configs changed diff --git a/transports/bifrost-http/handlers/middlewares.go b/transports/bifrost-http/handlers/middlewares.go index e981ef2c9..4fc255a5e 100644 --- a/transports/bifrost-http/handlers/middlewares.go +++ b/transports/bifrost-http/handlers/middlewares.go @@ -7,6 +7,7 @@ import ( "fmt" "slices" "strings" + "sync/atomic" "time" "github.com/maximhq/bifrost/core/schemas" @@ -156,23 +157,40 @@ func validateSession(_ *fasthttp.RequestCtx, store configstore.ConfigStore, toke return true } -// AuthMiddleware if authConfig is set, it will verify the auth cookie in the header -// This uses basic auth style username + password based authentication -// No session tracking is used, so this is not suitable for production environments -// These basicauth routes are only used for the dashboard and API routes -func AuthMiddleware(store configstore.ConfigStore) lib.BifrostHTTPMiddleware { +type AuthMiddleware struct { + store configstore.ConfigStore + authConfig atomic.Pointer[configstore.AuthConfig] +} + +func InitAuthMiddleware(store configstore.ConfigStore) (*AuthMiddleware, error) { if store == nil { - logger.Info("auth middleware is disabled because store is not present") - return func(next fasthttp.RequestHandler) fasthttp.RequestHandler { - return next - } + return nil, fmt.Errorf("store is not present") } authConfig, err := store.GetAuthConfig(context.Background()) - if err != nil || authConfig == nil || !authConfig.IsEnabled { - return func(next fasthttp.RequestHandler) fasthttp.RequestHandler { - return next - } + if err != nil { + return nil, fmt.Errorf("failed to get auth config from store: %v", err) + } + am := &AuthMiddleware{ + store: store, + authConfig: atomic.Pointer[configstore.AuthConfig]{}, } + am.authConfig.Store(authConfig) + return am, nil +} + +func (m *AuthMiddleware) UpdateAuthConfig(authConfig *configstore.AuthConfig) { + m.authConfig.Store(authConfig) +} + +// AuthMiddleware if authConfig is set, it will verify authentication based on the request type. +// Three authentication methods are supported: +// - Basic auth: Uses username + password validation (no session tracking). Used for inference API calls. +// - Bearer token: Uses session validation via validateSession(). Used for dashboard calls. +// - WebSocket: Uses session validation via validateSession() with token from query parameters. +// +// Basic auth may be acceptable for limited use cases, while Bearer and WebSocket flows provide +// session-based authentication suitable for production environments. +func (m *AuthMiddleware) Middleware() lib.BifrostHTTPMiddleware { whitelistedRoutes := []string{ "/api/session/is-auth-enabled", "/api/session/login", @@ -181,6 +199,12 @@ func AuthMiddleware(store configstore.ConfigStore) lib.BifrostHTTPMiddleware { } return func(next fasthttp.RequestHandler) fasthttp.RequestHandler { return func(ctx *fasthttp.RequestCtx) { + authConfig := m.authConfig.Load() + if authConfig == nil || !authConfig.IsEnabled { + logger.Debug("auth middleware is disabled because auth config is not present or not enabled") + next(ctx) + return + } // We skip authorization for the login route if slices.Contains(whitelistedRoutes, string(ctx.Request.URI().RequestURI())) { next(ctx) @@ -198,7 +222,7 @@ func AuthMiddleware(store configstore.ConfigStore) lib.BifrostHTTPMiddleware { return } // Verify the session - if !validateSession(ctx, store, token) { + if !validateSession(ctx, m.store, token) { SendError(ctx, fasthttp.StatusUnauthorized, "Unauthorized") return } @@ -250,7 +274,7 @@ func AuthMiddleware(store configstore.ConfigStore) lib.BifrostHTTPMiddleware { // Checking bearer auth for dashboard calls if scheme == "Bearer" { // Verify the session - if !validateSession(ctx, store, token) { + if !validateSession(ctx, m.store, token) { SendError(ctx, fasthttp.StatusUnauthorized, "Unauthorized") return } diff --git a/transports/bifrost-http/handlers/middlewares_test.go b/transports/bifrost-http/handlers/middlewares_test.go index 395beb2ba..16e05ee9e 100644 --- a/transports/bifrost-http/handlers/middlewares_test.go +++ b/transports/bifrost-http/handlers/middlewares_test.go @@ -525,3 +525,222 @@ func TestChainMiddlewares_ShortCircuitMiddlePosition(t *testing.T) { t.Errorf("Expected body 'Unauthorized', got '%s'", string(ctx.Response.Body())) } } + +// TestAuthMiddleware_NilAuthConfig tests that auth middleware allows requests when auth config is nil +func TestAuthMiddleware_NilAuthConfig(t *testing.T) { + SetLogger(&mockLogger{}) + + am := &AuthMiddleware{} + // authConfig is nil by default (simulates app start with no auth config) + + ctx := &fasthttp.RequestCtx{} + ctx.Request.SetRequestURI("/api/some-endpoint") + + nextCalled := false + next := func(ctx *fasthttp.RequestCtx) { + nextCalled = true + } + + middleware := am.Middleware() + handler := middleware(next) + handler(ctx) + + // When auth config is nil, requests should be allowed through + if !nextCalled { + t.Error("Next handler should be called when auth config is nil") + } +} + +// TestAuthMiddleware_DisabledAuthConfig tests that auth middleware allows requests when auth is disabled +func TestAuthMiddleware_DisabledAuthConfig(t *testing.T) { + SetLogger(&mockLogger{}) + + am := &AuthMiddleware{} + am.UpdateAuthConfig(&configstore.AuthConfig{ + AdminUserName: "admin", + AdminPassword: "password", + IsEnabled: false, + }) + + ctx := &fasthttp.RequestCtx{} + ctx.Request.SetRequestURI("/api/some-endpoint") + + nextCalled := false + next := func(ctx *fasthttp.RequestCtx) { + nextCalled = true + } + + middleware := am.Middleware() + handler := middleware(next) + handler(ctx) + + // When auth is disabled, requests should be allowed through + if !nextCalled { + t.Error("Next handler should be called when auth is disabled") + } +} + +// TestAuthMiddleware_EnabledAuthConfig_NoAuth tests that auth middleware blocks unauthenticated requests +func TestAuthMiddleware_EnabledAuthConfig_NoAuth(t *testing.T) { + SetLogger(&mockLogger{}) + + am := &AuthMiddleware{} + am.UpdateAuthConfig(&configstore.AuthConfig{ + AdminUserName: "admin", + AdminPassword: "hashedpassword", + IsEnabled: true, + }) + + ctx := &fasthttp.RequestCtx{} + ctx.Request.SetRequestURI("/api/some-endpoint") + + nextCalled := false + next := func(ctx *fasthttp.RequestCtx) { + nextCalled = true + } + + middleware := am.Middleware() + handler := middleware(next) + handler(ctx) + + // When auth is enabled and no auth header is provided, request should be blocked + if nextCalled { + t.Error("Next handler should NOT be called when auth is enabled and no credentials provided") + } + if ctx.Response.StatusCode() != fasthttp.StatusUnauthorized { + t.Errorf("Expected status code %d, got %d", fasthttp.StatusUnauthorized, ctx.Response.StatusCode()) + } +} + +// TestAuthMiddleware_WhitelistedRoutes tests that whitelisted routes bypass auth +func TestAuthMiddleware_WhitelistedRoutes(t *testing.T) { + SetLogger(&mockLogger{}) + + am := &AuthMiddleware{} + am.UpdateAuthConfig(&configstore.AuthConfig{ + AdminUserName: "admin", + AdminPassword: "hashedpassword", + IsEnabled: true, + }) + + whitelistedRoutes := []string{ + "/api/session/is-auth-enabled", + "/api/session/login", + "/api/session/logout", + "/health", + } + + for _, route := range whitelistedRoutes { + t.Run(route, func(t *testing.T) { + ctx := &fasthttp.RequestCtx{} + ctx.Request.SetRequestURI(route) + + nextCalled := false + next := func(ctx *fasthttp.RequestCtx) { + nextCalled = true + } + + middleware := am.Middleware() + handler := middleware(next) + handler(ctx) + + if !nextCalled { + t.Errorf("Next handler should be called for whitelisted route %s", route) + } + }) + } +} + +// TestAuthMiddleware_UpdateAuthConfig_NilToEnabled tests updating auth config from nil to enabled +func TestAuthMiddleware_UpdateAuthConfig_NilToEnabled(t *testing.T) { + SetLogger(&mockLogger{}) + + am := &AuthMiddleware{} + // Initially auth config is nil + + ctx := &fasthttp.RequestCtx{} + ctx.Request.SetRequestURI("/api/some-endpoint") + + // First request should pass (nil config) + nextCalled := false + next := func(ctx *fasthttp.RequestCtx) { + nextCalled = true + } + + middleware := am.Middleware() + handler := middleware(next) + handler(ctx) + + if !nextCalled { + t.Error("First request should pass when auth config is nil") + } + + // Now enable auth + am.UpdateAuthConfig(&configstore.AuthConfig{ + AdminUserName: "admin", + AdminPassword: "hashedpassword", + IsEnabled: true, + }) + + // Second request should be blocked (auth enabled, no credentials) + ctx2 := &fasthttp.RequestCtx{} + ctx2.Request.SetRequestURI("/api/some-endpoint") + + nextCalled = false + handler(ctx2) + + if nextCalled { + t.Error("Second request should be blocked after auth is enabled") + } + if ctx2.Response.StatusCode() != fasthttp.StatusUnauthorized { + t.Errorf("Expected status code %d, got %d", fasthttp.StatusUnauthorized, ctx2.Response.StatusCode()) + } +} + +// TestAuthMiddleware_UpdateAuthConfig_EnabledToDisabled tests disabling auth after it was enabled +func TestAuthMiddleware_UpdateAuthConfig_EnabledToDisabled(t *testing.T) { + SetLogger(&mockLogger{}) + + am := &AuthMiddleware{} + // Start with auth enabled + am.UpdateAuthConfig(&configstore.AuthConfig{ + AdminUserName: "admin", + AdminPassword: "hashedpassword", + IsEnabled: true, + }) + + ctx := &fasthttp.RequestCtx{} + ctx.Request.SetRequestURI("/api/some-endpoint") + + // First request should be blocked (auth enabled, no credentials) + nextCalled := false + next := func(ctx *fasthttp.RequestCtx) { + nextCalled = true + } + + middleware := am.Middleware() + handler := middleware(next) + handler(ctx) + + if nextCalled { + t.Error("First request should be blocked when auth is enabled") + } + + // Now disable auth + am.UpdateAuthConfig(&configstore.AuthConfig{ + AdminUserName: "admin", + AdminPassword: "hashedpassword", + IsEnabled: false, + }) + + // Second request should pass (auth disabled) + ctx2 := &fasthttp.RequestCtx{} + ctx2.Request.SetRequestURI("/api/some-endpoint") + + nextCalled = false + handler(ctx2) + + if !nextCalled { + t.Error("Second request should pass after auth is disabled") + } +} diff --git a/transports/bifrost-http/lib/config.go b/transports/bifrost-http/lib/config.go index 1e31c2ab2..8d4b9b634 100644 --- a/transports/bifrost-http/lib/config.go +++ b/transports/bifrost-http/lib/config.go @@ -1405,7 +1405,6 @@ func loadAuthConfigFromFile(ctx context.Context, config *Config, configData *Con return } - var err error if config.ConfigStore != nil { configStoreAuthConfig, err := config.ConfigStore.GetAuthConfig(ctx) if err == nil && configStoreAuthConfig == nil { @@ -1413,19 +1412,8 @@ func loadAuthConfigFromFile(ctx context.Context, config *Config, configData *Con logger.Warn("failed to update auth config: %v", err) } } - } else if config.GovernanceConfig != nil && config.GovernanceConfig.AuthConfig == nil { - config.GovernanceConfig.AuthConfig = configData.AuthConfig - // Resolve username and password if they contain env.VAR_NAME - if configData.AuthConfig.AdminUserName != "" { - if configData.AuthConfig.AdminUserName, _, err = config.processEnvValue(configData.AuthConfig.AdminUserName); err != nil { - logger.Warn("failed to resolve username: %v", err) - } - } - if configData.AuthConfig.AdminPassword != "" { - if configData.AuthConfig.AdminPassword, _, err = config.processEnvValue(configData.AuthConfig.AdminPassword); err != nil { - logger.Warn("failed to resolve admin password from environment") - } - } + } else { + logger.Warn("config store is required to load auth config from file") } } diff --git a/transports/bifrost-http/server/server.go b/transports/bifrost-http/server/server.go index 7f050c4ae..cdd891c6b 100644 --- a/transports/bifrost-http/server/server.go +++ b/transports/bifrost-http/server/server.go @@ -108,6 +108,7 @@ type BifrostHTTPServer struct { Router *router.Router WebSocketHandler *handlers.WebSocketHandler LogsCleaner *logstore.LogsCleaner + AuthMiddleware *handlers.AuthMiddleware } var logger schemas.Logger @@ -678,18 +679,35 @@ func (s *BifrostHTTPServer) ReloadClientConfigFromConfigStore(ctx context.Contex return nil } -// UpdateAuthConfig updates auth config +// UpdateAuthConfig updates auth config in the config store and updates the AuthMiddleware's in-memory config func (s *BifrostHTTPServer) UpdateAuthConfig(ctx context.Context, authConfig *configstore.AuthConfig) error { if authConfig == nil { - return fmt.Errorf("config store not found") + return fmt.Errorf("auth config is nil") } if s.Config == nil || s.Config.ConfigStore == nil { return fmt.Errorf("config store not found") } - if authConfig.AdminUserName == "" || authConfig.AdminPassword == "" { - return fmt.Errorf("username and password are required") + // Allow disabling auth without credentials, but require them when enabling + if authConfig.IsEnabled && (authConfig.AdminUserName == "" || authConfig.AdminPassword == "") { + return fmt.Errorf("username and password are required when auth is enabled") + } + // Update the config store + if err := s.Config.ConfigStore.UpdateAuthConfig(ctx, authConfig); err != nil { + return err } - return s.Config.ConfigStore.UpdateAuthConfig(ctx, authConfig) + // Update the AuthMiddleware's in-memory config + if s.AuthMiddleware != nil { + // Fetch the updated config from the store to ensure we have the latest + updatedAuthConfig, err := s.Config.ConfigStore.GetAuthConfig(ctx) + if err != nil { + logger.Warn("failed to get auth config from store after update: %v", err) + // Still update with what we have + s.AuthMiddleware.UpdateAuthConfig(authConfig) + } else { + s.AuthMiddleware.UpdateAuthConfig(updatedAuthConfig) + } + } + return nil } // UpdateDropExcessRequests updates excess requests config @@ -1171,18 +1189,12 @@ func (s *BifrostHTTPServer) Bootstrap(ctx context.Context) error { commonMiddlewares := s.PrepareCommonMiddlewares() apiMiddlewares := commonMiddlewares inferenceMiddlewares := commonMiddlewares - var authConfig *configstore.AuthConfig - if s.Config.ConfigStore != nil { - authConfig, err = s.Config.ConfigStore.GetAuthConfig(ctx) - if err != nil { - logger.Error("failed to get auth config: %v", err) - return fmt.Errorf("failed to get auth config: %v", err) - } - } else if s.Config.GovernanceConfig != nil && s.Config.GovernanceConfig.AuthConfig != nil { - authConfig = s.Config.GovernanceConfig.AuthConfig + s.AuthMiddleware, err = handlers.InitAuthMiddleware(s.Config.ConfigStore) + if err != nil { + return fmt.Errorf("failed to initialize auth middleware: %v", err) } - if ctx.Value("isEnterprise") == nil && authConfig != nil && authConfig.IsEnabled { - apiMiddlewares = append(apiMiddlewares, handlers.AuthMiddleware(s.Config.ConfigStore)) + if ctx.Value("isEnterprise") == nil { + apiMiddlewares = append(apiMiddlewares, s.AuthMiddleware.Middleware()) } // Register routes err = s.RegisterAPIRoutes(s.ctx, s, apiMiddlewares...) @@ -1190,8 +1202,8 @@ func (s *BifrostHTTPServer) Bootstrap(ctx context.Context) error { return fmt.Errorf("failed to initialize routes: %v", err) } // Registering inference routes - if ctx.Value("isEnterprise") == nil && authConfig != nil && authConfig.IsEnabled && !authConfig.DisableAuthOnInference { - inferenceMiddlewares = append(inferenceMiddlewares, handlers.AuthMiddleware(s.Config.ConfigStore)) + if ctx.Value("isEnterprise") == nil { + inferenceMiddlewares = append(inferenceMiddlewares, s.AuthMiddleware.Middleware()) } // Registering inference middlewares inferenceMiddlewares = append([]lib.BifrostHTTPMiddleware{handlers.TransportInterceptorMiddleware(s.Config)}, inferenceMiddlewares...) diff --git a/transports/changelog.md b/transports/changelog.md index e69de29bb..41ba47c96 100644 --- a/transports/changelog.md +++ b/transports/changelog.md @@ -0,0 +1,3 @@ +- feat: remove restart required for auth config changes +- fix: resolved issue where new auth configs were not being created +- ci: added workflow to auto-generate openapi.json documentation when openapi yaml files change \ No newline at end of file diff --git a/transports/version b/transports/version index 94f8697dc..0629a7403 100644 --- a/transports/version +++ b/transports/version @@ -1 +1 @@ -1.3.59 \ No newline at end of file +1.3.60 \ No newline at end of file diff --git a/ui/app/workspace/config/views/securityView.tsx b/ui/app/workspace/config/views/securityView.tsx index 2b0e98c70..5200af136 100644 --- a/ui/app/workspace/config/views/securityView.tsx +++ b/ui/app/workspace/config/views/securityView.tsx @@ -40,7 +40,6 @@ export default function SecurityView() { const [updateCoreConfig, { isLoading }] = useUpdateCoreConfigMutation(); const [localConfig, setLocalConfig] = useState(defaultConfig); const [needsRestart, setNeedsRestart] = useState(false); - const [authNeedsRestart, setAuthNeedsRestart] = useState(false); const hideAuthDashboard = IS_ENTERPRISE; const [localValues, setLocalValues] = useState<{ @@ -100,44 +99,25 @@ export default function SecurityView() { setLocalConfig((prev) => ({ ...prev, [field]: value })); }, []); - const checkAuthNeedsRestart = useCallback( - (newAuthConfig: AuthConfig) => { - const originalAuth = bifrostConfig?.auth_config; - const hasChanged = - newAuthConfig.is_enabled !== (originalAuth?.is_enabled ?? false) || - newAuthConfig.admin_username !== (originalAuth?.admin_username ?? "") || - newAuthConfig.admin_password !== (originalAuth?.admin_password ?? "") || - newAuthConfig.disable_auth_on_inference !== (originalAuth?.disable_auth_on_inference ?? false); - setAuthNeedsRestart(hasChanged); - }, - [bifrostConfig?.auth_config], - ); - const handleAuthToggle = useCallback( (checked: boolean) => { - const newAuthConfig = { ...authConfig, is_enabled: checked }; - setAuthConfig(newAuthConfig); - checkAuthNeedsRestart(newAuthConfig); + setAuthConfig((prev) => ({ ...prev, is_enabled: checked })); }, - [authConfig, checkAuthNeedsRestart], + [], ); const handleDisableAuthOnInferenceToggle = useCallback( (checked: boolean) => { - const newAuthConfig = { ...authConfig, disable_auth_on_inference: checked }; - setAuthConfig(newAuthConfig); - checkAuthNeedsRestart(newAuthConfig); + setAuthConfig((prev) => ({ ...prev, disable_auth_on_inference: checked })); }, - [authConfig, checkAuthNeedsRestart], + [], ); const handleAuthFieldChange = useCallback( (field: "admin_username" | "admin_password", value: string) => { - const newAuthConfig = { ...authConfig, [field]: value }; - setAuthConfig(newAuthConfig); - checkAuthNeedsRestart(newAuthConfig); + setAuthConfig((prev) => ({ ...prev, [field]: value })); }, - [authConfig, checkAuthNeedsRestart], + [], ); const handleSave = useCallback(async () => { @@ -159,7 +139,6 @@ export default function SecurityView() { : { ...authConfig, is_enabled: false }, }).unwrap(); toast.success("Security settings updated successfully."); - setAuthNeedsRestart(false); setNeedsRestart(false); } catch (error) { toast.error(getErrorMessage(error)); @@ -179,7 +158,6 @@ export default function SecurityView() {
- {authNeedsRestart && } {authConfig.is_enabled && !authConfig.disable_auth_on_inference && ( diff --git a/ui/lib/store/apis/baseApi.ts b/ui/lib/store/apis/baseApi.ts index 754f826e2..3b6c6880f 100644 --- a/ui/lib/store/apis/baseApi.ts +++ b/ui/lib/store/apis/baseApi.ts @@ -172,7 +172,7 @@ export const baseApi = createApi({ // Helper function to extract error message from RTK Query error export const getErrorMessage = (error: unknown): string => { - if(error === undefined || error === null) { + if (error === undefined || error === null) { return "An unexpected error occurred"; } if (error instanceof Error) { diff --git a/ui/lib/types/config.ts b/ui/lib/types/config.ts index b707cc3d8..54b183837 100644 --- a/ui/lib/types/config.ts +++ b/ui/lib/types/config.ts @@ -329,7 +329,7 @@ export interface BifrostConfig { client_config: CoreConfig; framework_config: FrameworkConfig; auth_config?: AuthConfig; - proxy_config?: GlobalProxyConfig; + proxy_config?: GlobalProxyConfig; restart_required?: RestartRequiredConfig; is_db_connected: boolean; is_cache_connected: boolean;