diff --git a/ui/litellm-dashboard/src/components/settings.test.tsx b/ui/litellm-dashboard/src/components/settings.test.tsx
index 7776d0c7082..ebc1a5a7a6c 100644
--- a/ui/litellm-dashboard/src/components/settings.test.tsx
+++ b/ui/litellm-dashboard/src/components/settings.test.tsx
@@ -1,4 +1,5 @@
-import { act, fireEvent, render, waitFor } from "@testing-library/react";
+import { act, render, screen, waitFor } from "@testing-library/react";
+import userEvent from "@testing-library/user-event";
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { alertingSettingsCall, getCallbackConfigsCall, getCallbacksCall } from "./networking";
import Settings from "./settings";
@@ -160,7 +161,8 @@ describe("Settings", () => {
mockGetCallbackConfigsCall.mockResolvedValue([mockCallbackConfig]);
- const { getByText, container } = render(
);
+ const user = userEvent.setup();
+ const { getByText } = render(
);
await waitFor(() => {
expect(getByText("Active Logging Callbacks")).toBeInTheDocument();
@@ -170,18 +172,8 @@ describe("Settings", () => {
expect(getByText("Langfuse")).toBeInTheDocument();
});
- const actionsCell = container.querySelector('[class*="flex justify-end gap-2"]');
- expect(actionsCell).toBeTruthy();
-
- const icons = actionsCell?.querySelectorAll("svg");
- expect(icons?.length).toBeGreaterThanOrEqual(2);
-
- const editIconParent = icons?.[1]?.closest('[class*="cursor-pointer"]');
- expect(editIconParent).toBeTruthy();
-
- act(() => {
- fireEvent.click(editIconParent!);
- });
+ await user.click(screen.getByTestId("callback-actions-langfuse-success"));
+ await user.click(await screen.findByTestId("callback-action-edit"));
await waitFor(() => {
expect(getByText("Edit Callback Settings")).toBeInTheDocument();
@@ -194,6 +186,42 @@ describe("Settings", () => {
});
});
+ it("should hold the callbacks table in loading state until the fetch settles", async () => {
+ let resolveCallbacks: (value: {
+ callbacks: never[];
+ available_callbacks: never[];
+ alerts: never[];
+ }) => void = () => {};
+ mockGetCallbacksCall.mockReturnValue(
+ new Promise((resolve) => {
+ resolveCallbacks = resolve;
+ }),
+ );
+
+ render(
);
+
+ expect(screen.getAllByTestId("skeleton-row").length).toBeGreaterThan(0);
+
+ await act(async () => {
+ resolveCallbacks({ callbacks: [], available_callbacks: [], alerts: [] });
+ });
+
+ await waitFor(() => {
+ expect(screen.queryByTestId("skeleton-row")).not.toBeInTheDocument();
+ });
+ expect(screen.getByText("No callbacks configured")).toBeInTheDocument();
+ });
+
+ it("should resolve loading without fetching when the user id is missing", async () => {
+ render(
);
+
+ await waitFor(() => {
+ expect(screen.queryByTestId("skeleton-row")).not.toBeInTheDocument();
+ });
+ expect(mockGetCallbacksCall).not.toHaveBeenCalled();
+ expect(screen.getByText("No callbacks configured")).toBeInTheDocument();
+ });
+
it("should display CloudZero Cost Tracking tab", async () => {
const { getByText } = render(
);
diff --git a/ui/litellm-dashboard/src/components/settings.tsx b/ui/litellm-dashboard/src/components/settings.tsx
index 46811e0106b..b3f33133a80 100644
--- a/ui/litellm-dashboard/src/components/settings.tsx
+++ b/ui/litellm-dashboard/src/components/settings.tsx
@@ -217,6 +217,7 @@ const buildCallbackPayload = (formValues: Record
, callbackName: str
const Settings: React.FC = ({ accessToken, userRole, userID, premiumUser }) => {
const [callbacks, setCallbacks] = useState([]);
+ const [isLoadingCallbacks, setIsLoadingCallbacks] = useState(true);
const [alerts, setAlerts] = useState([]);
const [isModalVisible, setIsModalVisible] = useState(false);
const [addForm] = Form.useForm();
@@ -293,29 +294,35 @@ const Settings: React.FC = ({ accessToken, userRole, userID,
};
useEffect(() => {
- if (!accessToken || !userRole || !userID) {
- return;
- }
- getCallbacksCall(accessToken, userID, userRole).then((data) => {
- setCallbacks(data.callbacks);
- setAllCallbacks(data.available_callbacks);
- // setCallbacks(callbacks_data);
-
- let alerts_data = data.alerts;
- if (alerts_data) {
- if (alerts_data.length > 0) {
- let _alert_info = alerts_data[0];
- let catch_all_webhook = _alert_info.variables.SLACK_WEBHOOK_URL;
-
- let active_alerts = _alert_info.active_alerts;
- setActiveAlerts(active_alerts);
- setCatchAllWebhookURL(catch_all_webhook);
- setAlertToWebhooks(_alert_info.alerts_to_webhook);
- }
+ const fetchCallbacks = async () => {
+ if (!accessToken || !userRole || !userID) {
+ setIsLoadingCallbacks(false);
+ return;
}
+ try {
+ const data = await getCallbacksCall(accessToken, userID, userRole);
+ setCallbacks(data.callbacks);
+ setAllCallbacks(data.available_callbacks);
- setAlerts(alerts_data);
- });
+ let alerts_data = data.alerts;
+ if (alerts_data) {
+ if (alerts_data.length > 0) {
+ let _alert_info = alerts_data[0];
+ let catch_all_webhook = _alert_info.variables.SLACK_WEBHOOK_URL;
+
+ let active_alerts = _alert_info.active_alerts;
+ setActiveAlerts(active_alerts);
+ setCatchAllWebhookURL(catch_all_webhook);
+ setAlertToWebhooks(_alert_info.alerts_to_webhook);
+ }
+ }
+
+ setAlerts(alerts_data);
+ } finally {
+ setIsLoadingCallbacks(false);
+ }
+ };
+ fetchCallbacks();
}, [accessToken, userRole, userID]);
const isAlertOn = (alertName: string) => {
@@ -581,6 +588,7 @@ const Settings: React.FC = ({ accessToken, userRole, userID,
setShowAddCallbacksModal(true)}
onEdit={(cb) => {
setSelectedEditCallback(cb);
diff --git a/ui/litellm-dashboard/src/components/skill_hub_table_columns.tsx b/ui/litellm-dashboard/src/components/skill_hub_table_columns.tsx
deleted file mode 100644
index 8fc9adc75a2..00000000000
--- a/ui/litellm-dashboard/src/components/skill_hub_table_columns.tsx
+++ /dev/null
@@ -1,114 +0,0 @@
-import { ColumnDef } from "@tanstack/react-table";
-import { Badge, Text } from "@tremor/react";
-import { Tooltip } from "antd";
-import { CopyOutlined, LinkOutlined } from "@ant-design/icons";
-import { Plugin } from "./claude_code_plugins/types";
-import { StatusBadge } from "@/components/shared/table_cells";
-
-export const skillHubColumns = (
- showModal: (skill: Plugin) => void,
- copyToClipboard: (text: string) => void,
- publicPage: boolean = false,
-): ColumnDef[] => [
- {
- header: "Skill Name",
- accessorKey: "name",
- enableSorting: true,
- sortingFn: "alphanumeric",
- cell: ({ row }) => {
- const skill = row.original;
- return (
-
-
-
-
- copyToClipboard(skill.name)}
- className="cursor-pointer text-gray-500 hover:text-blue-500 text-xs"
- />
-
-
- {skill.description && (
-
{skill.description}
- )}
-
- );
- },
- },
- {
- header: "Description",
- accessorKey: "description",
- enableSorting: false,
- cell: ({ row }) => {row.original.description || "-"},
- },
- {
- header: "Category",
- accessorKey: "category",
- enableSorting: true,
- cell: ({ row }) => {
- const cat = row.original.category;
- if (!cat) return -;
- return (
-
- {cat}
-
- );
- },
- },
- {
- header: "Domain",
- accessorKey: "domain",
- enableSorting: true,
- cell: ({ row }) => {row.original.domain || "-"},
- },
- {
- header: "Source",
- accessorKey: "source",
- enableSorting: false,
- cell: ({ row }) => {
- const src = row.original.source;
- let url: string | null = null;
- let label = "-";
- if (src?.source === "github" && src.repo) {
- url = `https://github.com/${src.repo}`;
- label = src.repo;
- } else if (src?.source === "git-subdir" && src.url) {
- url = src.path ? `${src.url}/tree/main/${src.path}` : src.url;
- label = url.replace("https://github.com/", "");
- } else if (src?.source === "url" && src.url) {
- url = src.url;
- label = src.url.replace(/^https?:\/\//, "");
- }
- if (!url) return -;
- return (
-
- {label}
-
-
- );
- },
- },
- {
- header: "Status",
- accessorKey: "enabled",
- enableSorting: true,
- cell: ({ row }) => (
-
- ),
- },
-];
diff --git a/ui/litellm-dashboard/src/lib/http/schema.d.ts b/ui/litellm-dashboard/src/lib/http/schema.d.ts
index 87c760257d1..9ad0b8d1101 100644
--- a/ui/litellm-dashboard/src/lib/http/schema.d.ts
+++ b/ui/litellm-dashboard/src/lib/http/schema.d.ts
@@ -21690,7 +21690,7 @@ export interface components {
* CallTypes
* @enum {string}
*/
- CallTypes: "embedding" | "aembedding" | "completion" | "acompletion" | "atext_completion" | "text_completion" | "image_generation" | "aimage_generation" | "image_edit" | "aimage_edit" | "moderation" | "amoderation" | "atranscription" | "transcription" | "aspeech" | "speech" | "rerank" | "arerank" | "search" | "asearch" | "_arealtime" | "_aresponses_websocket" | "create_batch" | "acreate_batch" | "aretrieve_batch" | "retrieve_batch" | "acancel_batch" | "cancel_batch" | "pass_through_endpoint" | "anthropic_messages" | "get_assistants" | "aget_assistants" | "create_assistants" | "acreate_assistants" | "delete_assistant" | "adelete_assistant" | "acreate_thread" | "create_thread" | "aget_thread" | "get_thread" | "a_add_message" | "add_message" | "aget_messages" | "get_messages" | "arun_thread" | "run_thread" | "arun_thread_stream" | "run_thread_stream" | "afile_retrieve" | "file_retrieve" | "afile_delete" | "file_delete" | "afile_list" | "file_list" | "acreate_file" | "create_file" | "afile_content" | "file_content" | "create_fine_tuning_job" | "acreate_fine_tuning_job" | "create_video" | "acreate_video" | "avideo_retrieve" | "video_retrieve" | "avideo_content" | "video_content" | "video_remix" | "avideo_remix" | "video_list" | "avideo_list" | "video_retrieve_job" | "avideo_retrieve_job" | "video_delete" | "avideo_delete" | "video_create_character" | "avideo_create_character" | "video_get_character" | "avideo_get_character" | "video_edit" | "avideo_edit" | "video_extension" | "avideo_extension" | "vector_store_file_create" | "avector_store_file_create" | "vector_store_file_list" | "avector_store_file_list" | "vector_store_file_retrieve" | "avector_store_file_retrieve" | "vector_store_file_content" | "avector_store_file_content" | "vector_store_file_update" | "avector_store_file_update" | "vector_store_file_delete" | "avector_store_file_delete" | "vector_store_create" | "avector_store_create" | "vector_store_search" | "avector_store_search" | "create_container" | "acreate_container" | "list_containers" | "alist_containers" | "retrieve_container" | "aretrieve_container" | "delete_container" | "adelete_container" | "list_container_files" | "alist_container_files" | "upload_container_file" | "aupload_container_file" | "create_sandbox" | "acreate_sandbox" | "delete_sandbox" | "adelete_sandbox" | "run_code" | "arun_code" | "code_interpreter_tool" | "acode_interpreter_tool" | "acancel_fine_tuning_job" | "cancel_fine_tuning_job" | "alist_fine_tuning_jobs" | "list_fine_tuning_jobs" | "aretrieve_fine_tuning_job" | "retrieve_fine_tuning_job" | "responses" | "aresponses" | "alist_input_items" | "llm_passthrough_route" | "allm_passthrough_route" | "generate_content" | "agenerate_content" | "generate_content_stream" | "agenerate_content_stream" | "ocr" | "aocr" | "call_mcp_tool" | "list_mcp_tools" | "asend_message" | "send_message" | "acreate_skill";
+ CallTypes: "embedding" | "aembedding" | "completion" | "acompletion" | "atext_completion" | "text_completion" | "image_generation" | "aimage_generation" | "image_edit" | "aimage_edit" | "moderation" | "amoderation" | "atranscription" | "transcription" | "aspeech" | "speech" | "rerank" | "arerank" | "search" | "asearch" | "_arealtime" | "_aresponses_websocket" | "create_batch" | "acreate_batch" | "aretrieve_batch" | "retrieve_batch" | "acancel_batch" | "cancel_batch" | "pass_through_endpoint" | "anthropic_messages" | "aanthropic_messages" | "get_assistants" | "aget_assistants" | "create_assistants" | "acreate_assistants" | "delete_assistant" | "adelete_assistant" | "acreate_thread" | "create_thread" | "aget_thread" | "get_thread" | "a_add_message" | "add_message" | "aget_messages" | "get_messages" | "arun_thread" | "run_thread" | "arun_thread_stream" | "run_thread_stream" | "afile_retrieve" | "file_retrieve" | "afile_delete" | "file_delete" | "afile_list" | "file_list" | "acreate_file" | "create_file" | "afile_content" | "file_content" | "create_fine_tuning_job" | "acreate_fine_tuning_job" | "create_video" | "acreate_video" | "avideo_retrieve" | "video_retrieve" | "avideo_content" | "video_content" | "video_remix" | "avideo_remix" | "video_list" | "avideo_list" | "video_retrieve_job" | "avideo_retrieve_job" | "video_delete" | "avideo_delete" | "video_create_character" | "avideo_create_character" | "video_get_character" | "avideo_get_character" | "video_edit" | "avideo_edit" | "video_extension" | "avideo_extension" | "vector_store_file_create" | "avector_store_file_create" | "vector_store_file_list" | "avector_store_file_list" | "vector_store_file_retrieve" | "avector_store_file_retrieve" | "vector_store_file_content" | "avector_store_file_content" | "vector_store_file_update" | "avector_store_file_update" | "vector_store_file_delete" | "avector_store_file_delete" | "vector_store_create" | "avector_store_create" | "vector_store_search" | "avector_store_search" | "create_container" | "acreate_container" | "list_containers" | "alist_containers" | "retrieve_container" | "aretrieve_container" | "delete_container" | "adelete_container" | "list_container_files" | "alist_container_files" | "upload_container_file" | "aupload_container_file" | "create_sandbox" | "acreate_sandbox" | "delete_sandbox" | "adelete_sandbox" | "run_code" | "arun_code" | "code_interpreter_tool" | "acode_interpreter_tool" | "acancel_fine_tuning_job" | "cancel_fine_tuning_job" | "alist_fine_tuning_jobs" | "list_fine_tuning_jobs" | "aretrieve_fine_tuning_job" | "retrieve_fine_tuning_job" | "responses" | "aresponses" | "alist_input_items" | "llm_passthrough_route" | "allm_passthrough_route" | "generate_content" | "agenerate_content" | "generate_content_stream" | "agenerate_content_stream" | "ocr" | "aocr" | "call_mcp_tool" | "list_mcp_tools" | "asend_message" | "send_message" | "acreate_skill";
/** CallbackDelete */
CallbackDelete: {
/** Callback Name */
@@ -22504,6 +22504,11 @@ export interface components {
* @description connect to a postgres db - needed for generating temporary keys + tracking spend / key
*/
database_url?: string | null;
+ /**
+ * Disable Auto Add Proxy Admin To Teams
+ * @description By default, the user calling /team/new is automatically added to the new team as a team admin. If True, proxy admins are no longer auto-added; members explicitly listed in members_with_roles are unaffected. Default is False.
+ */
+ disable_auto_add_proxy_admin_to_teams?: boolean | null;
/**
* Disable Budget Reservation
* @description If True, disables the optimistic per-request budget reservation introduced in v1.84.0. WARNING: This weakens hard budget enforcement. Without the reservation, a burst of concurrent requests from a single key can each pass the read-time spend check before any of them is charged, allowing a configured budget to be exceeded under high concurrency. Budgets are still evaluated on every request at read time, so an already-exhausted budget is still rejected. Enable only if your deployment is experiencing phantom BudgetExceededError responses caused by leaked reservations (see GitHub issue #27639). A proxy-level WARNING is logged on every request while this flag is active as a reminder that hard enforcement is relaxed.
@@ -32245,6 +32250,8 @@ export interface components {
}[] | null;
/** Cooldown Time */
cooldown_time?: number | null;
+ /** Enable Tag Filtering */
+ enable_tag_filtering?: boolean | null;
/** Fallbacks */
fallbacks?: {
[key: string]: unknown;
diff --git a/ui/litellm-dashboard/src/utils/returnUrlUtils.test.ts b/ui/litellm-dashboard/src/utils/returnUrlUtils.test.ts
index 56de299049c..0f3a8b4bf69 100644
--- a/ui/litellm-dashboard/src/utils/returnUrlUtils.test.ts
+++ b/ui/litellm-dashboard/src/utils/returnUrlUtils.test.ts
@@ -3,6 +3,7 @@ import {
clearStoredReturnUrl,
consumeReturnUrl,
getCurrentUrl,
+ getLoginUrl,
getReturnUrl,
getReturnUrlFromParams,
getStoredReturnUrl,
@@ -98,6 +99,29 @@ describe("returnUrlUtils", () => {
});
});
+ describe("getLoginUrl", () => {
+ it("should build a relative login URL with a trailing slash", () => {
+ expect(getLoginUrl()).toBe("/ui/login/");
+ });
+
+ it("should prepend the given base URL and keep the trailing slash", () => {
+ expect(getLoginUrl("http://proxy.example")).toBe("http://proxy.example/ui/login/");
+ });
+
+ it("should keep the trailing slash before the query when composed with buildLoginUrlWithReturn", () => {
+ Object.defineProperty(window, "location", {
+ value: {
+ ...window.location,
+ href: "http://localhost:3000/ui?page=api-keys",
+ },
+ writable: true,
+ });
+
+ const loginUrl = buildLoginUrlWithReturn(getLoginUrl());
+ expect(loginUrl).toBe("/ui/login/?redirect_to=http%3A%2F%2Flocalhost%3A3000%2Fui%3Fpage%3Dapi-keys");
+ });
+ });
+
describe("buildLoginUrlWithReturn", () => {
it("should build login URL with return URL parameter", () => {
Object.defineProperty(window, "location", {
diff --git a/ui/litellm-dashboard/src/utils/returnUrlUtils.ts b/ui/litellm-dashboard/src/utils/returnUrlUtils.ts
index 76562a0122a..b3cc5345bb1 100644
--- a/ui/litellm-dashboard/src/utils/returnUrlUtils.ts
+++ b/ui/litellm-dashboard/src/utils/returnUrlUtils.ts
@@ -13,6 +13,10 @@
const RETURN_URL_COOKIE_NAME = "litellm_return_url";
const RETURN_URL_PARAM = "redirect_to";
+export function getLoginUrl(baseUrl: string = ""): string {
+ return `${baseUrl}/ui/login/`;
+}
+
/**
* Gets the current URL with all query parameters.
* Returns null if running on server-side.
diff --git a/ui/litellm-dashboard/tests/CreateKeyPage.expiredToken.test.tsx b/ui/litellm-dashboard/tests/CreateKeyPage.expiredToken.test.tsx
index 62346eff057..211a754dad4 100644
--- a/ui/litellm-dashboard/tests/CreateKeyPage.expiredToken.test.tsx
+++ b/ui/litellm-dashboard/tests/CreateKeyPage.expiredToken.test.tsx
@@ -232,7 +232,7 @@ describe("CreateKeyPage auth behavior", () => {
// Assert: we eventually redirect to SSO login with return URL (single replace, not assign/href)
await waitFor(() => {
expect(window.location.replace).toHaveBeenCalledWith(
- expect.stringContaining("https://example.com/ui/login?redirect_to="),
+ expect.stringContaining("https://example.com/ui/login/?redirect_to="),
);
});
diff --git a/uv.lock b/uv.lock
index 22e3a3feece..8dfc4bd5fcc 100644
--- a/uv.lock
+++ b/uv.lock
@@ -10,7 +10,7 @@ resolution-markers = [
]
[options]
-exclude-newer = "2026-07-13T03:38:04.421387Z"
+exclude-newer = "2026-07-13T21:03:01.672393Z"
exclude-newer-span = "P3D"
[manifest]
@@ -222,9 +222,9 @@ name = "aiologic"
version = "0.17.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "sniffio" },
+ { name = "sniffio", marker = "python_full_version < '3.13'" },
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
- { name = "wrapt" },
+ { name = "wrapt", marker = "python_full_version < '3.13'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/53/a7/809482759f40079f4c4328c7318bf569ae25d457f5017aad30a1b9aafedc/aiologic-0.17.0.tar.gz", hash = "sha256:65aa058e858c94cd208badb188e7f00b54dcabb3ba85b34f794db98074d108b9", size = 251625, upload-time = "2026-06-14T12:24:35.367Z" }
wheels = [
@@ -516,14 +516,14 @@ name = "aurelio-sdk"
version = "0.0.19"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "aiofiles" },
- { name = "aiohttp" },
- { name = "colorlog" },
- { name = "pydantic" },
- { name = "python-dotenv" },
- { name = "requests" },
- { name = "requests-toolbelt" },
- { name = "tornado" },
+ { name = "aiofiles", marker = "python_full_version < '3.14'" },
+ { name = "aiohttp", marker = "python_full_version < '3.14'" },
+ { name = "colorlog", marker = "python_full_version < '3.14'" },
+ { name = "pydantic", marker = "python_full_version < '3.14'" },
+ { name = "python-dotenv", marker = "python_full_version < '3.14'" },
+ { name = "requests", marker = "python_full_version < '3.14'" },
+ { name = "requests-toolbelt", marker = "python_full_version < '3.14'" },
+ { name = "tornado", marker = "python_full_version < '3.14'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/27/0e/c2e369ad173fb3d76448e46d10beb3dcc53388318933ddf8169a3f21a810/aurelio_sdk-0.0.19.tar.gz", hash = "sha256:14107e7440ff2efd0b4a08c52fb595e7680bd4bc973a0ddfb3b64157c6666b91", size = 15258, upload-time = "2025-03-24T14:37:32.203Z" }
wheels = [
@@ -1047,7 +1047,7 @@ name = "coloredlogs"
version = "15.0.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "humanfriendly" },
+ { name = "humanfriendly", marker = "python_full_version < '3.14'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/cc/c7/eed8f27100517e8c0e6b923d5f0845d0cb99763da6fdee00478f91db7325/coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0", size = 278520, upload-time = "2021-06-11T10:22:45.202Z" }
wheels = [
@@ -1059,7 +1059,7 @@ name = "colorlog"
version = "6.10.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "colorama", marker = "sys_platform == 'win32'" },
+ { name = "colorama", marker = "python_full_version < '3.14' and sys_platform == 'win32'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a2/61/f083b5ac52e505dfc1c624eafbf8c7589a0d7f32daa398d2e7590efa5fda/colorlog-6.10.1.tar.gz", hash = "sha256:eb4ae5cb65fe7fec7773c2306061a8e63e02efc2c72eba9d27b0fa23c94f1321", size = 17162, upload-time = "2025-10-16T16:14:11.978Z" }
wheels = [
@@ -1420,7 +1420,7 @@ name = "culsans"
version = "0.11.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "aiologic" },
+ { name = "aiologic", marker = "python_full_version < '3.13'" },
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/d9/e3/49afa1bc180e0d28008ec6bcdf82a4072d1c7a41032b5b759b60814ca4b0/culsans-0.11.0.tar.gz", hash = "sha256:0b43d0d05dce6106293d114c86e3fb4bfc63088cfe8ff08ed3fe36891447fe33", size = 107546, upload-time = "2025-12-31T23:15:38.196Z" }
@@ -2966,7 +2966,7 @@ name = "humanfriendly"
version = "10.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "pyreadline3", marker = "sys_platform == 'win32'" },
+ { name = "pyreadline3", marker = "python_full_version < '3.14' and sys_platform == 'win32'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/cc/3f/2c29224acb2e2df4d2046e4c73ee2662023c58ff5b113c4c1adac0886c43/humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc", size = 360702, upload-time = "2021-09-17T21:40:43.31Z" }
wheels = [
@@ -3293,10 +3293,10 @@ name = "jsonschema-path"
version = "0.3.4"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "pathable" },
- { name = "pyyaml" },
- { name = "referencing" },
- { name = "requests" },
+ { name = "pathable", marker = "python_full_version < '3.14'" },
+ { name = "pyyaml", marker = "python_full_version < '3.14'" },
+ { name = "referencing", marker = "python_full_version < '3.14'" },
+ { name = "requests", marker = "python_full_version < '3.14'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/6e/45/41ebc679c2a4fced6a722f624c18d658dee42612b83ea24c1caf7c0eb3a8/jsonschema_path-0.3.4.tar.gz", hash = "sha256:8365356039f16cc65fddffafda5f58766e34bebab7d6d105616ab52bc4297001", size = 11159, upload-time = "2025-01-24T14:33:16.547Z" }
wheels = [
@@ -4122,12 +4122,12 @@ proxy-dev = [
[[package]]
name = "litellm-enterprise"
-version = "0.1.50"
+version = "0.1.51"
source = { editable = "enterprise" }
[[package]]
name = "litellm-proxy-extras"
-version = "0.4.77"
+version = "0.4.78"
source = { editable = "litellm-proxy-extras" }
[[package]]
@@ -4481,7 +4481,7 @@ version = "0.4.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "numpy", version = "1.26.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" },
- { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
+ { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' and python_full_version < '3.14'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/fd/15/76f86faa0902836cc133939732f7611ace68cf54148487a99c539c272dc8/ml_dtypes-0.4.1.tar.gz", hash = "sha256:fad5f2de464fd09127e49b7fd1252b9006fb43d2edc1ff112d390c324af5ca7a", size = 692594, upload-time = "2024-09-13T19:07:11.624Z" }
wheels = [
@@ -4980,14 +4980,14 @@ name = "openapi-core"
version = "0.22.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "isodate" },
- { name = "jsonschema" },
- { name = "jsonschema-path" },
- { name = "more-itertools" },
- { name = "openapi-schema-validator" },
- { name = "openapi-spec-validator" },
- { name = "typing-extensions" },
- { name = "werkzeug" },
+ { name = "isodate", marker = "python_full_version < '3.14'" },
+ { name = "jsonschema", marker = "python_full_version < '3.14'" },
+ { name = "jsonschema-path", marker = "python_full_version < '3.14'" },
+ { name = "more-itertools", marker = "python_full_version < '3.14'" },
+ { name = "openapi-schema-validator", marker = "python_full_version < '3.14'" },
+ { name = "openapi-spec-validator", marker = "python_full_version < '3.14'" },
+ { name = "typing-extensions", marker = "python_full_version < '3.14'" },
+ { name = "werkzeug", marker = "python_full_version < '3.14'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/fd/65/ee75f25b9459a02df6f713f8ffde5dacb57b8b4e45145cde4cab28b5abba/openapi_core-0.22.0.tar.gz", hash = "sha256:b30490dfa74e3aac2276105525590135212352f5dd7e5acf8f62f6a89ed6f2d0", size = 109242, upload-time = "2025-12-22T19:19:49.608Z" }
wheels = [
@@ -4999,9 +4999,9 @@ name = "openapi-schema-validator"
version = "0.6.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "jsonschema" },
- { name = "jsonschema-specifications" },
- { name = "rfc3339-validator" },
+ { name = "jsonschema", marker = "python_full_version < '3.14'" },
+ { name = "jsonschema-specifications", marker = "python_full_version < '3.14'" },
+ { name = "rfc3339-validator", marker = "python_full_version < '3.14'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/8b/f3/5507ad3325169347cd8ced61c232ff3df70e2b250c49f0fe140edb4973c6/openapi_schema_validator-0.6.3.tar.gz", hash = "sha256:f37bace4fc2a5d96692f4f8b31dc0f8d7400fd04f3a937798eaf880d425de6ee", size = 11550, upload-time = "2025-01-10T18:08:22.268Z" }
wheels = [
@@ -5013,10 +5013,10 @@ name = "openapi-spec-validator"
version = "0.7.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "jsonschema" },
- { name = "jsonschema-path" },
- { name = "lazy-object-proxy" },
- { name = "openapi-schema-validator" },
+ { name = "jsonschema", marker = "python_full_version < '3.14'" },
+ { name = "jsonschema-path", marker = "python_full_version < '3.14'" },
+ { name = "lazy-object-proxy", marker = "python_full_version < '3.14'" },
+ { name = "openapi-schema-validator", marker = "python_full_version < '3.14'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/82/af/fe2d7618d6eae6fb3a82766a44ed87cd8d6d82b4564ed1c7cfb0f6378e91/openapi_spec_validator-0.7.2.tar.gz", hash = "sha256:cc029309b5c5dbc7859df0372d55e9d1ff43e96d678b9ba087f7c56fc586f734", size = 36855, upload-time = "2025-06-07T14:48:56.299Z" }
wheels = [
@@ -7163,16 +7163,16 @@ name = "redisvl"
version = "0.4.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "coloredlogs" },
- { name = "ml-dtypes" },
+ { name = "coloredlogs", marker = "python_full_version < '3.14'" },
+ { name = "ml-dtypes", marker = "python_full_version < '3.14'" },
{ name = "numpy", version = "1.26.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" },
- { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
- { name = "pydantic" },
- { name = "python-ulid" },
- { name = "pyyaml" },
- { name = "redis" },
- { name = "tabulate" },
- { name = "tenacity" },
+ { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' and python_full_version < '3.14'" },
+ { name = "pydantic", marker = "python_full_version < '3.14'" },
+ { name = "python-ulid", marker = "python_full_version < '3.14'" },
+ { name = "pyyaml", marker = "python_full_version < '3.14'" },
+ { name = "redis", marker = "python_full_version < '3.14'" },
+ { name = "tabulate", marker = "python_full_version < '3.14'" },
+ { name = "tenacity", marker = "python_full_version < '3.14'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/21/33/ab14865a0b2a31b1d003c29e7e8ea3a7a2f2c8ecb24e58e58d606e1f031b/redisvl-0.4.1.tar.gz", hash = "sha256:fd6a36426ba94792c0efca20915c31232d4ee3cc58eb23794a62c142696401e6", size = 77688, upload-time = "2025-02-21T22:51:41.389Z" }
wheels = [
@@ -7406,7 +7406,7 @@ name = "rfc3339-validator"
version = "0.1.4"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "six" },
+ { name = "six", marker = "python_full_version < '3.14'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/28/ea/a9387748e2d111c3c2b275ba970b735e04e15cdb1eb30693b6b5708c4dbd/rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", size = 5513, upload-time = "2021-05-12T16:37:54.178Z" }
wheels = [
@@ -7855,20 +7855,20 @@ name = "semantic-router"
version = "0.1.15"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "aiohttp" },
- { name = "aurelio-sdk" },
- { name = "colorama" },
- { name = "colorlog" },
- { name = "litellm" },
+ { name = "aiohttp", marker = "python_full_version < '3.14'" },
+ { name = "aurelio-sdk", marker = "python_full_version < '3.14'" },
+ { name = "colorama", marker = "python_full_version < '3.14'" },
+ { name = "colorlog", marker = "python_full_version < '3.14'" },
+ { name = "litellm", marker = "python_full_version < '3.14'" },
{ name = "numpy", version = "1.26.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" },
- { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
- { name = "openai" },
- { name = "pydantic" },
- { name = "pyyaml" },
- { name = "regex" },
- { name = "tiktoken" },
- { name = "tornado" },
- { name = "urllib3" },
+ { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' and python_full_version < '3.14'" },
+ { name = "openai", marker = "python_full_version < '3.14'" },
+ { name = "pydantic", marker = "python_full_version < '3.14'" },
+ { name = "pyyaml", marker = "python_full_version < '3.14'" },
+ { name = "regex", marker = "python_full_version < '3.14'" },
+ { name = "tiktoken", marker = "python_full_version < '3.14'" },
+ { name = "tornado", marker = "python_full_version < '3.14'" },
+ { name = "urllib3", marker = "python_full_version < '3.14'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/dc/a9/1a689e916e8b280f1fd8fb335cc059be626a22fe4533baa045d32fcd6de5/semantic_router-0.1.15.tar.gz", hash = "sha256:328256ddc3c2b713101ec69561d6585aecbf1198ea3461e1486289d8c3a35288", size = 95605, upload-time = "2026-05-23T12:58:15.444Z" }
wheels = [
@@ -8958,16 +8958,16 @@ wheels = [
[[package]]
name = "uvicorn"
-version = "0.33.0"
+version = "0.51.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "click" },
{ name = "h11" },
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/cb/81/a083ae41716b00df56d45d4b5f6ca8e90fc233a62e6c04ab3ad3c476b6c4/uvicorn-0.33.0.tar.gz", hash = "sha256:3577119f82b7091cf4d3d4177bfda0bae4723ed92ab1439e8d779de880c9cc59", size = 76590, upload-time = "2024-12-14T11:14:46.526Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/a2/65/b7c6c443ccc58678c91e1e973bbe2a878591538655d6e1d47f24ba1c51f3/uvicorn-0.51.0.tar.gz", hash = "sha256:f6f4b69b657c312f516dd2d268ab9ae6f254b11e4bac504f37b2ab58b24dd0b0", size = 94412, upload-time = "2026-07-08T10:59:05.962Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/98/79/2e2620337ef1e4ef7a058b351603b765f59ac28e6e3ac7c5e7cdee9ea1ab/uvicorn-0.33.0-py3-none-any.whl", hash = "sha256:2c30de4aeea83661a520abab179b24084a0019c0c1bbe137e5409f741cbde5f8", size = 62297, upload-time = "2024-12-14T11:14:43.408Z" },
+ { url = "https://files.pythonhosted.org/packages/45/ec/dbb7e5a6b91f86bfb9eb7d2988a2730907b6a729875b949c7f022e8b88fa/uvicorn-0.51.0-py3-none-any.whl", hash = "sha256:5d38af6cd620f2ae3849fb44fd4879e0890aa1febe8d47eb355fb45d93fe6a5b", size = 73219, upload-time = "2026-07-08T10:59:04.44Z" },
]
[[package]]