refactor(memory): align management routes and dashboard controls

This commit is contained in:
moe-berri 2026-09-14 18:20:55 -07:00
parent 6d05a83f0e
commit 866071af6f
15 changed files with 396 additions and 384 deletions

View file

@ -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

View file

@ -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",
}
)

View file

@ -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",

View file

@ -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:

View file

@ -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,

View file

@ -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",

View file

@ -306,7 +306,7 @@ CONTROL_PLANE_PREFIXES: tuple[str, ...] = (
"/global",
"/config",
"/guardrails",
"/v2/memory/policies",
"/memory/v2/settings",
"/openapi.json",
)

View file

@ -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()

View file

@ -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

View file

@ -34,7 +34,7 @@ export function AutomaticMemoryEntries({
const [deleting, setDeleting] = useState<Entry | null>(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({
/>
</div>
)}
{(teamId || filterUserId) && (
<Button
variant="ghost"
onClick={() => {
setTeamId("");
setFilterUserId("");
}}
>
{filtered && (
<Button variant="ghost" onClick={clearFilters}>
Clear filters
</Button>
)}
@ -173,7 +172,6 @@ export function AutomaticMemoryEntries({
onQueryChange={setSearch}
loading={entries.isPending || status.isPending}
readOnly={readOnly}
canEdit={true}
busy={busy}
onEdit={setEditing}
onDelete={setDeleting}

View file

@ -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({
</Collapsible>
{!readOnly && selected.can_edit && (
<div className="flex gap-2 border-t pt-4">
<Button variant="outline" size="sm" disabled={busy || !canEdit} onClick={() => onEdit(selected)}>
<Button variant="outline" size="sm" disabled={busy} onClick={() => onEdit(selected)}>
Edit memory
</Button>
<Button variant="ghost" size="sm" disabled={busy} onClick={() => onDelete(selected)}>

View file

@ -5,6 +5,7 @@ import Link from "next/link";
import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import { fetchClient } from "@/lib/http/api";
import type { components } from "@/lib/http/schema";
@ -25,12 +26,12 @@ export function MemoryAdministration({
const settings = useQuery({
queryKey: ["memorySettings", userId],
enabled: proxyAdmin,
queryFn: async ({ signal }) => (await fetchClient.GET("/v2/memory/settings", { signal })).data,
queryFn: async ({ signal }) => (await fetchClient.GET("/memory/v2/settings", { signal })).data,
});
const current = draft ?? settings.data;
const save = useMutation({
mutationFn: ({ enabled, everyone, user_ids }: Settings) =>
fetchClient.PUT("/v2/memory/settings", { body: { enabled, everyone, user_ids } }),
fetchClient.PUT("/memory/v2/settings", { body: { enabled, everyone, user_ids } }),
onSuccess: async ({ data }) => {
cache.setQueryData(["memorySettings", userId], data);
setDraft(null);
@ -82,16 +83,19 @@ export function MemoryAdministration({
</div>
<div className="space-y-2">
<Label htmlFor="memory-enrollment">Enable for</Label>
<select
id="memory-enrollment"
className="h-9 w-full rounded-md border bg-background px-3 text-sm sm:max-w-sm"
<Select
value={current.everyone ? "everyone" : "selected"}
disabled={busy}
onChange={(event) => setDraft({ ...current, everyone: event.target.value === "everyone" })}
onValueChange={(value) => setDraft({ ...current, everyone: value === "everyone" })}
>
<option value="everyone">Everyone</option>
<option value="selected">Selected users</option>
</select>
<SelectTrigger id="memory-enrollment" className="w-full sm:max-w-sm">
<SelectValue>{current.everyone ? "Everyone" : "Selected users"}</SelectValue>
</SelectTrigger>
<SelectContent>
<SelectItem value="everyone">Everyone</SelectItem>
<SelectItem value="selected">Selected users</SelectItem>
</SelectContent>
</Select>
</div>
{!current.everyone && (
<div className="space-y-3">
@ -148,7 +152,7 @@ export function MemoryAdministration({
<h3 className="font-medium">Who can see memories?</h3>
<p className="text-sm text-muted-foreground">
Users see their own memories. Team admins can also see their team&apos;s memories, and proxy admins can see
all. To give ordinary members access to their team&apos;s memories, allow “Read team memories” in Member
all. To give ordinary members access to their team&apos;s memories, enable team memory access in Member
Permissions.
</p>
<Link className="inline-block text-sm underline underline-offset-4" href={uiHref("teams")}>

View file

@ -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(<Memory />);
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(<Memory />);
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(<Memory />);
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(<Memory />);
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(<Memory />);
expect(await screen.findByRole("alert")).toHaveTextContent("Memory service unavailable");
expect(screen.queryByText("No memories yet")).not.toBeInTheDocument();

View file

@ -23,7 +23,7 @@ export const PERMISSION_DESCRIPTIONS: Record<string, string> = {
"/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";
}

View file

@ -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?: {