From 866071af6f27ae5d3ac7f7d7302511de16687cf0 Mon Sep 17 00:00:00 2001 From: moe-berri Date: Mon, 14 Sep 2026 18:20:55 -0700 Subject: [PATCH] refactor(memory): align management routes and dashboard controls --- backend/routes/allowlist.py | 2 +- gateway/routes/allowlist.py | 5 +- litellm/proxy/_types.py | 16 +- litellm/proxy/memory/management.py | 2 +- tests/e2e/management/memory_client.py | 20 +- tests/e2e/management/test_memory_v2_e2e.py | 2 +- tests/e2e/transport.py | 2 +- .../proxy/memory/test_memory_v2_management.py | 10 +- .../proxy/test_component_allowlists.py | 6 +- .../_components/AutomaticMemoryEntries.tsx | 26 +- .../memory/_components/MemoryEntriesTable.tsx | 4 +- .../memory/_components/MemorySettings.tsx | 24 +- .../memory/page.integration.test.tsx | 35 +- .../team/permission_definitions.tsx | 4 +- ui/litellm-dashboard/src/lib/http/schema.d.ts | 622 +++++++++--------- 15 files changed, 396 insertions(+), 384 deletions(-) diff --git a/backend/routes/allowlist.py b/backend/routes/allowlist.py index c04bbb92a37..10f807d31e1 100644 --- a/backend/routes/allowlist.py +++ b/backend/routes/allowlist.py @@ -71,7 +71,7 @@ BACKEND_PATH_PREFIXES: tuple[str, ...] = ( "/v1/workflows/", "/project/", "/memory/", - "/v2/memory/", + "/memory/v2/", "/mcp/", # Control plane (see the List Endpoints + Tables standard). Every resource # eventually moves under this prefix, so allowlist it once rather than diff --git a/gateway/routes/allowlist.py b/gateway/routes/allowlist.py index 44583c168f2..403fb709529 100644 --- a/gateway/routes/allowlist.py +++ b/gateway/routes/allowlist.py @@ -74,7 +74,7 @@ GATEWAY_PATH_PREFIXES: tuple[str, ...] = ( "/containers", "/v1/evals", "/v1/memory", - "/v2/memory/entries", + "/memory/v2/entries", "/queue/chat/", # Google data plane (v1beta is the Google AI Studio version) "/v1beta/", @@ -124,8 +124,7 @@ GATEWAY_EXACT_PATHS: frozenset[str] = frozenset( "/redoc", "/test", "/debug/memory/summary", - "/v2/memory/status", - "/v2/memory/preference", + "/memory/v2/status", } ) diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py index 772c549a407..d51895ab9be 100644 --- a/litellm/proxy/_types.py +++ b/litellm/proxy/_types.py @@ -300,7 +300,7 @@ class KeyManagementRoutes(str, enum.Enum): # team spend-log viewing SPEND_LOGS = "/spend/logs" SPEND_LOGS_V2 = "/spend/logs/v2" - MEMORY_READ = "/v2/memory/entries" + MEMORY_READ = "/memory/v2/entries" class LiteLLMRoutes(enum.Enum): @@ -838,10 +838,10 @@ class LiteLLMRoutes(enum.Enum): ) self_managed_routes = [ - "/v2/memory/settings", - "/v2/memory/status", - "/v2/memory/entries", - "/v2/memory/entries/{memory_id}", + "/memory/v2/settings", + "/memory/v2/status", + "/memory/v2/entries", + "/memory/v2/entries/{memory_id}", "/team/member_add", "/team/member_delete", "/team/member_update", @@ -930,9 +930,9 @@ class LiteLLMRoutes(enum.Enum): # updating this list — the default-allow behavior covers it automatically. admin_viewer_routes = ( [ - "/v2/memory/settings", - "/v2/memory/status", - "/v2/memory/entries", + "/memory/v2/settings", + "/memory/v2/status", + "/memory/v2/entries", "/user/list", "/user/available_users", "/user/available_roles", diff --git a/litellm/proxy/memory/management.py b/litellm/proxy/memory/management.py index 696ab15710e..30e018a0d83 100644 --- a/litellm/proxy/memory/management.py +++ b/litellm/proxy/memory/management.py @@ -30,7 +30,7 @@ from litellm.types.memory_v2 import ( ) _AUTH: Final = Depends(user_api_key_auth) -router: Final = APIRouter(prefix="/v2/memory", tags=["memory management"]) # mutable-ok: FastAPI requires native tags. +router: Final = APIRouter(prefix="/memory/v2", tags=["memory management"]) # mutable-ok: FastAPI requires native tags. def require_memory_admin(auth: UserAPIKeyAuth, *, write: bool = False) -> None: diff --git a/tests/e2e/management/memory_client.py b/tests/e2e/management/memory_client.py index 4e52423947a..7321f5f32e7 100644 --- a/tests/e2e/management/memory_client.py +++ b/tests/e2e/management/memory_client.py @@ -19,7 +19,7 @@ class MemoryClient: def settings(self) -> MemorySettingsBody: return unwrap( self.proxy.transport.get( - "/v2/memory/settings", + "/memory/v2/settings", headers=self.proxy.transport.master, params=NoBody(), response_type=MemorySettingsBody, @@ -28,7 +28,7 @@ class MemoryClient: def set_settings(self, body: MemorySettingsBody, *, caller: str | None = None) -> Result[MemorySettingsBody]: return self.proxy.transport.put( - "/v2/memory/settings", + "/memory/v2/settings", headers=self.proxy.transport.bearer(caller) if caller else self.proxy.transport.master, json=body, response_type=MemorySettingsBody, @@ -36,7 +36,7 @@ class MemoryClient: def read(self, key: str, memory_id: str) -> Result[MemoryEntryData]: return self.proxy.transport.get( - f"/v2/memory/entries/{memory_id}", + f"/memory/v2/entries/{memory_id}", headers=self.proxy.transport.bearer(key), params=NoBody(), response_type=MemoryEntryData, @@ -44,7 +44,7 @@ class MemoryClient: def update(self, key: str, memory_id: str, body: MemoryCaptureBody) -> Result[MemoryEntryData]: return self.proxy.transport.put( - f"/v2/memory/entries/{memory_id}", + f"/memory/v2/entries/{memory_id}", headers=self.proxy.transport.bearer(key), json=body, response_type=MemoryEntryData, @@ -53,7 +53,7 @@ class MemoryClient: def status(self, key: str) -> MemoryStatusData: return unwrap( self.proxy.transport.get( - "/v2/memory/status", + "/memory/v2/status", headers=self.proxy.transport.bearer(key), params=NoBody(), response_type=MemoryStatusData, @@ -63,7 +63,7 @@ class MemoryClient: def entries(self, key: str, params: MemoryEntryParams = MemoryEntryParams()) -> list[MemoryEntryData]: return unwrap( self.proxy.transport.get( - "/v2/memory/entries", + "/memory/v2/entries", headers=self.proxy.transport.bearer(key), params=params, response_type=MemoryEntriesData, @@ -72,7 +72,7 @@ class MemoryClient: def capture(self, key: str, body: MemoryCaptureBody) -> Result[MemoryEntryData]: return self.proxy.transport.post( - "/v2/memory/entries", + "/memory/v2/entries", headers=self.proxy.transport.bearer(key), json=body, response_type=MemoryEntryData, @@ -80,7 +80,7 @@ class MemoryClient: def delete_entry(self, key: str, memory_id: str) -> Result[NoBody]: return self.proxy.transport.delete( - f"/v2/memory/entries/{memory_id}", + f"/memory/v2/entries/{memory_id}", headers=self.proxy.transport.bearer(key), json=NoBody(), response_type=NoBody, @@ -90,7 +90,7 @@ class MemoryClient: while True: page = unwrap( self.proxy.transport.get( - "/v2/memory/entries", + "/memory/v2/entries", headers=self.proxy.transport.master, params=MemoryEntryParams(user_id=user_id), response_type=MemoryEntriesData, @@ -101,7 +101,7 @@ class MemoryClient: for entry in page: unwrap( self.proxy.transport.delete( - f"/v2/memory/entries/{entry.memory_id}", + f"/memory/v2/entries/{entry.memory_id}", headers=self.proxy.transport.master, json=NoBody(), response_type=NoBody, diff --git a/tests/e2e/management/test_memory_v2_e2e.py b/tests/e2e/management/test_memory_v2_e2e.py index 6e5c2c1228e..9f3083dfbf3 100644 --- a/tests/e2e/management/test_memory_v2_e2e.py +++ b/tests/e2e/management/test_memory_v2_e2e.py @@ -281,7 +281,7 @@ class TestMemoryV2: marker = f"team-{unique_marker()}" saved = unwrap(memory.capture(subjects.owner, _fact(marker))) assert memory.entries(subjects.outsider) == [] - for permissions, visible in ((["/spend/logs"], False), (["/v2/memory/entries"], True), ([], False)): + for permissions, visible in ((["/spend/logs"], False), (["/memory/v2/entries"], True), ([], False)): unwrap( client.proxy.transport.post( "/team/permissions_update", diff --git a/tests/e2e/transport.py b/tests/e2e/transport.py index 37e758e149f..bb1102bbb55 100644 --- a/tests/e2e/transport.py +++ b/tests/e2e/transport.py @@ -306,7 +306,7 @@ CONTROL_PLANE_PREFIXES: tuple[str, ...] = ( "/global", "/config", "/guardrails", - "/v2/memory/policies", + "/memory/v2/settings", "/openapi.json", ) diff --git a/tests/test_litellm/proxy/memory/test_memory_v2_management.py b/tests/test_litellm/proxy/memory/test_memory_v2_management.py index cedd9f8cdbd..90b068345fd 100644 --- a/tests/test_litellm/proxy/memory/test_memory_v2_management.py +++ b/tests/test_litellm/proxy/memory/test_memory_v2_management.py @@ -174,9 +174,9 @@ async def test_everyone_clears_stale_selection_and_includes_service_keys(databas [ ("owner", "user", None, LitellmUserRoles.INTERNAL_USER, ()), ("owner", "user", "/spend/logs", LitellmUserRoles.INTERNAL_USER, ()), - ("owner", "user", "/v2/memory/entries", LitellmUserRoles.INTERNAL_USER, ("team",)), + ("owner", "user", "/memory/v2/entries", LitellmUserRoles.INTERNAL_USER, ("team",)), ("owner", "admin", None, LitellmUserRoles.INTERNAL_USER, ("team",)), - ("other", "admin", "/v2/memory/entries", LitellmUserRoles.INTERNAL_USER, ()), + ("other", "admin", "/memory/v2/entries", LitellmUserRoles.INTERNAL_USER, ()), ("owner", "user", None, LitellmUserRoles.ORG_ADMIN, ()), ], ) @@ -197,7 +197,7 @@ async def test_team_memory_access_reuses_membership_but_not_log_permission( @pytest.mark.parametrize( - "permission,log_read,memory_read", [("/spend/logs", True, False), ("/v2/memory/entries", False, True)] + "permission,log_read,memory_read", [("/spend/logs", True, False), ("/memory/v2/entries", False, True)] ) def test_common_helper_keeps_resource_permissions_independent( permission: str, log_read: bool, memory_read: bool @@ -266,7 +266,7 @@ async def test_service_key_write_ownership_never_matches_all_unowned_rows(databa @pytest.mark.asyncio async def test_revocation_blocks_existing_store_and_private_continuation(database: MagicMock) -> None: configure(database) - database.db.litellm_teamtable.find_many.return_value = [team(permissions=("/v2/memory/entries",))] + database.db.litellm_teamtable.find_many.return_value = [team(permissions=("/memory/v2/entries",))] original = await management.memory_store(auth()) patch = MemoryContinuation( replaces=1, @@ -383,6 +383,6 @@ def test_invalid_queries_are_rejected_before_database_work(database: MagicMock, app.include_router(management.router) app.dependency_overrides[user_api_key_auth] = auth with TestClient(app) as client: - response = client.get("/v2/memory/entries", params=params) + response = client.get("/memory/v2/entries", params=params) assert response.status_code == 422 database.db.litellm_memorytable.find_many.assert_not_awaited() diff --git a/tests/test_litellm/proxy/test_component_allowlists.py b/tests/test_litellm/proxy/test_component_allowlists.py index 5c504521fad..4e76a4f7c52 100644 --- a/tests/test_litellm/proxy/test_component_allowlists.py +++ b/tests/test_litellm/proxy/test_component_allowlists.py @@ -240,8 +240,8 @@ def test_every_app_mount_is_assigned_to_a_component(): def test_memory_v2_settings_stay_on_backend_while_entries_are_available_on_gateway(): gateway = _component_paths(app.router.routes, GATEWAY_EXACT_PATHS, GATEWAY_PATH_PREFIXES) backend = _component_paths(app.router.routes, BACKEND_EXACT_PATHS, BACKEND_PATH_PREFIXES) - assert "/v2/memory/settings" in backend - assert "/v2/memory/settings" not in gateway - for path in ("/v2/memory/status", "/v2/memory/entries", "/v2/memory/entries/{memory_id}"): + assert "/memory/v2/settings" in backend + assert "/memory/v2/settings" not in gateway + for path in ("/memory/v2/status", "/memory/v2/entries", "/memory/v2/entries/{memory_id}"): assert path in gateway assert path in backend diff --git a/ui/litellm-dashboard/src/app/(dashboard)/memory/_components/AutomaticMemoryEntries.tsx b/ui/litellm-dashboard/src/app/(dashboard)/memory/_components/AutomaticMemoryEntries.tsx index 635df1b8e23..25fec459d5c 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/memory/_components/AutomaticMemoryEntries.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/memory/_components/AutomaticMemoryEntries.tsx @@ -34,7 +34,7 @@ export function AutomaticMemoryEntries({ const [deleting, setDeleting] = useState(null); const status = useQuery({ queryKey: ["memoryStatus", userId, readOnly, proxyAdmin], - queryFn: async ({ signal }) => (await fetchClient.GET("/v2/memory/status", { signal })).data, + queryFn: async ({ signal }) => (await fetchClient.GET("/memory/v2/status", { signal })).data, }); const entries = useInfiniteQuery({ queryKey: ["memoryEntries", userId, query, teamId, filterUserId, status.data?.team_ids, status.data?.admin_view], @@ -42,7 +42,7 @@ export function AutomaticMemoryEntries({ initialPageParam: null as Cursor, queryFn: async ({ signal, pageParam }) => ( - await fetchClient.GET("/v2/memory/entries", { + await fetchClient.GET("/memory/v2/entries", { params: { query: { query, @@ -64,7 +64,7 @@ export function AutomaticMemoryEntries({ }); const save = useMutation({ mutationFn: ({ memory_id, body }: { memory_id: string; body: Capture }) => - fetchClient.PUT("/v2/memory/entries/{memory_id}", { params: { path: { memory_id } }, body }), + fetchClient.PUT("/memory/v2/entries/{memory_id}", { params: { path: { memory_id } }, body }), onSuccess: () => { setEditing(null); toast.success("Memory updated"); @@ -74,7 +74,7 @@ export function AutomaticMemoryEntries({ }); const remove = useMutation({ mutationFn: (memory_id: string) => - fetchClient.DELETE("/v2/memory/entries/{memory_id}", { params: { path: { memory_id } } }), + fetchClient.DELETE("/memory/v2/entries/{memory_id}", { params: { path: { memory_id } } }), onSuccess: () => { setDeleting(null); toast.success("Memory deleted"); @@ -105,7 +105,12 @@ export function AutomaticMemoryEntries({ }, }); }; - const filtered = Boolean(query || teamId || filterUserId); + const filtered = Boolean(search || teamId || filterUserId); + const clearFilters = () => { + setTeamId(""); + setFilterUserId(""); + setSearch(""); + }; const accessDescription = status.data?.active ? "Your assistant can save and search memories using your gateway permissions." : "Automatic memory is off. Your administrator can enable it; saved memories remain available here."; @@ -155,14 +160,8 @@ export function AutomaticMemoryEntries({ /> )} - {(teamId || filterUserId) && ( - )} @@ -173,7 +172,6 @@ export function AutomaticMemoryEntries({ onQueryChange={setSearch} loading={entries.isPending || status.isPending} readOnly={readOnly} - canEdit={true} busy={busy} onEdit={setEditing} onDelete={setDeleting} diff --git a/ui/litellm-dashboard/src/app/(dashboard)/memory/_components/MemoryEntriesTable.tsx b/ui/litellm-dashboard/src/app/(dashboard)/memory/_components/MemoryEntriesTable.tsx index 9a08cbb9e44..89b6241b315 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/memory/_components/MemoryEntriesTable.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/memory/_components/MemoryEntriesTable.tsx @@ -44,7 +44,6 @@ export function MemoryEntriesTable({ empty, footer, readOnly, - canEdit, busy, onEdit, onDelete, @@ -56,7 +55,6 @@ export function MemoryEntriesTable({ empty: React.ReactNode; footer: React.ReactNode; readOnly: boolean; - canEdit: boolean; busy: boolean; onEdit: (entry: Entry) => void; onDelete: (entry: Entry) => void; @@ -171,7 +169,7 @@ export function MemoryEntriesTable({ {!readOnly && selected.can_edit && (
-
- + + {current.everyone ? "Everyone" : "Selected users"} + + + Everyone + Selected users + +
{!current.everyone && (
@@ -148,7 +152,7 @@ export function MemoryAdministration({

Who can see memories?

Users see their own memories. Team admins can also see their team's memories, and proxy admins can see - all. To give ordinary members access to their team's memories, allow “Read team memories” in Member + all. To give ordinary members access to their team's memories, enable team memory access in Member Permissions.

diff --git a/ui/litellm-dashboard/src/app/(dashboard)/memory/page.integration.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/memory/page.integration.test.tsx index e4390451f62..0825fa3aa12 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/memory/page.integration.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/memory/page.integration.test.tsx @@ -55,18 +55,18 @@ beforeEach(async () => { const text = request.method === "GET" ? "" : await request.text(); const call = { path, method: request.method, body: text ? JSON.parse(text) : undefined, params: url.search }; calls.push(call); - if (failure === path && (path !== "/v2/memory/settings" || request.method === "PUT")) { + if (failure === path && (path !== "/memory/v2/settings" || request.method === "PUT")) { return new Response(JSON.stringify({ detail: "Memory service unavailable" }), { status: 503, headers: { "Content-Type": "application/json" }, }); } const response = () => { - if (path === "/v2/memory/settings") { + if (path === "/memory/v2/settings") { if (request.method === "PUT") settings = JSON.parse(text); return { ...settings, user_names: { u1: "Alex Rivera" } }; } - if (path === "/v2/memory/status") + if (path === "/memory/v2/status") return { active: settings.enabled && (settings.everyone || settings.user_ids?.includes("u1")), enabled: settings.enabled, @@ -75,7 +75,7 @@ beforeEach(async () => { team_ids: ["engineering"], admin_view: false, }; - if (path === "/v2/memory/entries") { + if (path === "/memory/v2/entries") { if (paginated) { const offset = url.searchParams.get("before_memory_id") === "entry-19" ? 20 : 0; return Array.from({ length: offset ? 1 : 20 }, (_, i) => ({ @@ -87,7 +87,7 @@ beforeEach(async () => { } return [{ ...entry, can_edit: canEdit }]; } - if (path === "/v2/memory/entries/entry-1") return { ...entry, can_edit: canEdit }; + if (path === "/memory/v2/entries/entry-1") return { ...entry, can_edit: canEdit }; if (path === "/v1/memory") return { memories: [], total: 0 }; if (path === "/v2/team/list") return { teams: [{ team_id: "engineering", team_alias: "Engineering" }], page: 1, total_pages: 1, total: 1 }; @@ -111,7 +111,7 @@ describe("Memory dashboard", () => { expect(screen.getByText("Engineering")).toBeVisible(); expect(screen.queryByRole("switch")).not.toBeInTheDocument(); expect(screen.queryByRole("tab", { name: "Administration" })).not.toBeInTheDocument(); - expect(calls.some(({ path }) => path === "/v2/memory/settings")).toBe(false); + expect(calls.some(({ path }) => path === "/memory/v2/settings")).toBe(false); }); it("lets a proxy admin enable everyone through one configuration", async () => { @@ -138,7 +138,8 @@ describe("Memory dashboard", () => { renderWithProviders(); await user.click(screen.getByRole("tab", { name: "Administration" })); await user.click(await screen.findByRole("switch", { name: "Gateway memory" })); - await user.selectOptions(screen.getByLabelText("Enable for"), "selected"); + await user.click(screen.getByRole("combobox", { name: "Enable for" })); + await user.click(screen.getByRole("option", { name: "Selected users" })); await user.click(screen.getByLabelText("Add a user")); await user.click(await screen.findByRole("option", { name: "alex@example.test" })); expect(screen.getByRole("button", { name: "Remove alex@example.test" })).toBeVisible(); @@ -160,7 +161,7 @@ describe("Memory dashboard", () => { it("keeps an unsuccessful activation unsaved and shows the error", async () => { session("proxy_admin"); - failure = "/v2/memory/settings"; + failure = "/memory/v2/settings"; const user = userEvent.setup(); renderWithProviders(); await user.click(screen.getByRole("tab", { name: "Administration" })); @@ -203,7 +204,7 @@ describe("Memory dashboard", () => { fireEvent.change(screen.getByLabelText("Correct this memory"), { target: { value: "Use port 8124" } }); await user.click(screen.getByRole("button", { name: "Save correction" })); const expectedCall = { - path: "/v2/memory/entries/entry-1", + path: "/memory/v2/entries/entry-1", method: "PUT", params: "", body: { @@ -222,19 +223,31 @@ describe("Memory dashboard", () => { await waitFor(() => expect(calls).toContainEqual(expectedCall)); }); - it("filters permitted memories by team and can clear the filter", async () => { + it("clears the search and team filter together", async () => { session("internal_user"); const user = userEvent.setup(); renderWithProviders(); await screen.findByText("Off · Managed by your admin"); + fireEvent.change(screen.getByRole("textbox", { name: "Search memories" }), { target: { value: "demo" } }); await user.click(screen.getByLabelText("Team")); await user.click(await screen.findByRole("option", { name: "Engineering" })); await waitFor(() => expect(calls.some(({ params }) => params.includes("team_id=engineering"))).toBe(true)); await user.click(screen.getByRole("button", { name: "Clear filters" })); + expect(screen.getByRole("textbox", { name: "Search memories" })).toHaveValue(""); expect(screen.queryByRole("button", { name: "Clear filters" })).not.toBeInTheDocument(); expect(calls.some(({ params }) => params.includes("key_id"))).toBe(false); }); + it("labels the contributor picker and sends its selected user filter", async () => { + session("proxy_admin"); + const user = userEvent.setup(); + renderWithProviders(); + await screen.findByText("Off · Managed by your admin"); + await user.click(screen.getByRole("combobox", { name: "Contributor" })); + await user.click(await screen.findByRole("option", { name: "alex@example.test" })); + await waitFor(() => expect(calls.some(({ params }) => params.includes("user_id=u1"))).toBe(true)); + }); + it("searches and paginates without replacing the visible first page", async () => { session("internal_user"); paginated = true; @@ -250,7 +263,7 @@ describe("Memory dashboard", () => { it("shows a loading failure instead of claiming an empty collection", async () => { session("internal_user"); - failure = "/v2/memory/entries"; + failure = "/memory/v2/entries"; renderWithProviders(); expect(await screen.findByRole("alert")).toHaveTextContent("Memory service unavailable"); expect(screen.queryByText("No memories yet")).not.toBeInTheDocument(); diff --git a/ui/litellm-dashboard/src/components/team/permission_definitions.tsx b/ui/litellm-dashboard/src/components/team/permission_definitions.tsx index 72f62adfdf7..c398f08114e 100644 --- a/ui/litellm-dashboard/src/components/team/permission_definitions.tsx +++ b/ui/litellm-dashboard/src/components/team/permission_definitions.tsx @@ -23,7 +23,7 @@ export const PERMISSION_DESCRIPTIONS: Record = { "/key/access_group_assignment": "Member can assign access groups to virtual keys for this team", "/team/daily/activity": "Member can view all team usage data (not just their own)", "/spend/logs": "Member can view spend logs for the entire team (not just their own)", - "/v2/memory/entries": "Read team memories: members can search and read memories contributed within this team", + "/memory/v2/entries": "Member can view memories for the entire team (not just their own)", }; /** @@ -35,7 +35,7 @@ export const getMethodForEndpoint = (endpoint: string): string => { endpoint.includes("/list") || endpoint.includes("/activity") || endpoint === "/spend/logs" || - endpoint === "/v2/memory/entries" + endpoint === "/memory/v2/entries" ) { return "GET"; } diff --git a/ui/litellm-dashboard/src/lib/http/schema.d.ts b/ui/litellm-dashboard/src/lib/http/schema.d.ts index cde713bba6e..5d99f4adfcf 100644 --- a/ui/litellm-dashboard/src/lib/http/schema.d.ts +++ b/ui/litellm-dashboard/src/lib/http/schema.d.ts @@ -8746,6 +8746,78 @@ export interface paths { patch?: never; trace?: never; }; + "/memory/v2/entries": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** List Entries */ + get: operations["list_entries_memory_v2_entries_get"]; + put?: never; + /** Capture Entry */ + post: operations["capture_entry_memory_v2_entries_post"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/memory/v2/entries/{memory_id}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Read Entry */ + get: operations["read_entry_memory_v2_entries__memory_id__get"]; + /** Update Entry */ + put: operations["update_entry_memory_v2_entries__memory_id__put"]; + post?: never; + /** Delete Entry */ + delete: operations["delete_entry_memory_v2_entries__memory_id__delete"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/memory/v2/settings": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Get Settings */ + get: operations["get_settings_memory_v2_settings_get"]; + /** Set Settings */ + put: operations["set_settings_memory_v2_settings_put"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/memory/v2/status": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Get Status */ + get: operations["get_status_memory_v2_status_get"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/milvus/{endpoint}": { parameters: { query?: never; @@ -21284,78 +21356,6 @@ export interface paths { patch?: never; trace?: never; }; - "/v2/memory/entries": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** List Entries */ - get: operations["list_entries_v2_memory_entries_get"]; - put?: never; - /** Capture Entry */ - post: operations["capture_entry_v2_memory_entries_post"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v2/memory/entries/{memory_id}": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Read Entry */ - get: operations["read_entry_v2_memory_entries__memory_id__get"]; - /** Update Entry */ - put: operations["update_entry_v2_memory_entries__memory_id__put"]; - post?: never; - /** Delete Entry */ - delete: operations["delete_entry_v2_memory_entries__memory_id__delete"]; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v2/memory/settings": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Get Settings */ - get: operations["get_settings_v2_memory_settings_get"]; - /** Set Settings */ - put: operations["set_settings_v2_memory_settings_put"]; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/v2/memory/status": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Get Status */ - get: operations["get_status_v2_memory_status_get"]; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; "/v2/model/info": { parameters: { query?: never; @@ -28649,7 +28649,7 @@ export interface components { * @description Enum for key management routes * @enum {string} */ - KeyManagementRoutes: "/key/generate" | "/key/update" | "/key/delete" | "/key/regenerate" | "/key/service-account/generate" | "/key/{key_id}/regenerate" | "/key/block" | "/key/unblock" | "/key/bulk_update" | "/team/key/bulk_update" | "/key/{key_id}/reset_spend" | "/key/access_group_assignment" | "/key/info" | "/key/health" | "/key/list" | "/key/aliases" | "/team/daily/activity" | "/team/daily/activity/aggregated" | "/spend/logs" | "/spend/logs/v2" | "/v2/memory/entries"; + KeyManagementRoutes: "/key/generate" | "/key/update" | "/key/delete" | "/key/regenerate" | "/key/service-account/generate" | "/key/{key_id}/regenerate" | "/key/block" | "/key/unblock" | "/key/bulk_update" | "/team/key/bulk_update" | "/key/{key_id}/reset_spend" | "/key/access_group_assignment" | "/key/info" | "/key/health" | "/key/list" | "/key/aliases" | "/team/daily/activity" | "/team/daily/activity/aggregated" | "/spend/logs" | "/spend/logs/v2" | "/memory/v2/entries"; /** * KeyManagementSystem * @enum {string} @@ -51968,6 +51968,244 @@ export interface operations { }; }; }; + list_entries_memory_v2_entries_get: { + parameters: { + query?: { + query?: string; + limit?: number; + offset?: number; + before_updated_at?: string | null; + before_memory_id?: string | null; + team_id?: string | null; + user_id?: string | null; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["MemoryEntry"][]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + capture_entry_memory_v2_entries_post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["MemoryCapture"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["MemoryEntry"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + read_entry_memory_v2_entries__memory_id__get: { + parameters: { + query?: never; + header?: never; + path: { + memory_id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["MemoryEntry"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + update_entry_memory_v2_entries__memory_id__put: { + parameters: { + query?: never; + header?: never; + path: { + memory_id: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["MemoryCapture"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["MemoryEntry"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + delete_entry_memory_v2_entries__memory_id__delete: { + parameters: { + query?: never; + header?: never; + path: { + memory_id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + get_settings_memory_v2_settings_get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["MemorySettingsView"]; + }; + }; + }; + }; + set_settings_memory_v2_settings_put: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["MemorySettings"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["MemorySettingsView"]; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + get_status_memory_v2_status_get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["MemoryStatus"]; + }; + }; + }; + }; milvus_proxy_route_milvus__endpoint__get: { parameters: { query?: never; @@ -67616,244 +67854,6 @@ export interface operations { }; }; }; - list_entries_v2_memory_entries_get: { - parameters: { - query?: { - query?: string; - limit?: number; - offset?: number; - before_updated_at?: string | null; - before_memory_id?: string | null; - team_id?: string | null; - user_id?: string | null; - }; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Successful Response */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["MemoryEntry"][]; - }; - }; - /** @description Validation Error */ - 422: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["HTTPValidationError"]; - }; - }; - }; - }; - capture_entry_v2_memory_entries_post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["MemoryCapture"]; - }; - }; - responses: { - /** @description Successful Response */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["MemoryEntry"]; - }; - }; - /** @description Validation Error */ - 422: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["HTTPValidationError"]; - }; - }; - }; - }; - read_entry_v2_memory_entries__memory_id__get: { - parameters: { - query?: never; - header?: never; - path: { - memory_id: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Successful Response */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["MemoryEntry"]; - }; - }; - /** @description Validation Error */ - 422: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["HTTPValidationError"]; - }; - }; - }; - }; - update_entry_v2_memory_entries__memory_id__put: { - parameters: { - query?: never; - header?: never; - path: { - memory_id: string; - }; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["MemoryCapture"]; - }; - }; - responses: { - /** @description Successful Response */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["MemoryEntry"]; - }; - }; - /** @description Validation Error */ - 422: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["HTTPValidationError"]; - }; - }; - }; - }; - delete_entry_v2_memory_entries__memory_id__delete: { - parameters: { - query?: never; - header?: never; - path: { - memory_id: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Successful Response */ - 204: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Validation Error */ - 422: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["HTTPValidationError"]; - }; - }; - }; - }; - get_settings_v2_memory_settings_get: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Successful Response */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["MemorySettingsView"]; - }; - }; - }; - }; - set_settings_v2_memory_settings_put: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["MemorySettings"]; - }; - }; - responses: { - /** @description Successful Response */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["MemorySettingsView"]; - }; - }; - /** @description Validation Error */ - 422: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["HTTPValidationError"]; - }; - }; - }; - }; - get_status_v2_memory_status_get: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Successful Response */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["MemoryStatus"]; - }; - }; - }; - }; model_info_v2_v2_model_info_get: { parameters: { query?: {