diff --git a/litellm/proxy/memory/store.py b/litellm/proxy/memory/store.py index ee540b3e234..049c36dde24 100644 --- a/litellm/proxy/memory/store.py +++ b/litellm/proxy/memory/store.py @@ -29,20 +29,22 @@ def memory_entry(row: "LiteLLM_MemoryTable") -> MemoryEntry: ) title: Final = metadata.get("title") evidence: Final = metadata.get("evidence") - return MemoryEntry( - memory_id=row.memory_id, - key=row.key.rsplit(":", 1)[-1], - title=title if isinstance(title, str) else row.key, - content=row.value, - evidence=evidence if isinstance(evidence, str) else "", - updated_at=row.updated_at, - created_at=row.created_at, - actor=row.created_by, - **{ # mutable-ok: Pydantic accepts native keyword argument dictionaries. - name: value - for name in ("when_to_use", "scope", "kind", "certainty", "source") - if isinstance(value := metadata.get(name), str) - }, + return MemoryEntry.model_validate( + { # mutable-ok: Pydantic validates stored JSON metadata and database fields together. + "memory_id": row.memory_id, + "key": row.key.rsplit(":", 1)[-1], + "title": title if isinstance(title, str) else row.key, + "content": row.value, + "evidence": evidence if isinstance(evidence, str) else "", + "updated_at": row.updated_at, + "created_at": row.created_at, + "actor": row.created_by, + **{ # mutable-ok: Pydantic validates these stored JSON metadata fields. + name: value + for name in ("when_to_use", "scope", "kind", "certainty", "source") + if isinstance(value := metadata.get(name), str) + }, + } ) diff --git a/litellm/types/memory_v2.py b/litellm/types/memory_v2.py index 6accafe849f..8a2e02de3b4 100644 --- a/litellm/types/memory_v2.py +++ b/litellm/types/memory_v2.py @@ -7,6 +7,8 @@ from typing_extensions import Self MemoryTarget: TypeAlias = Literal["gateway", "organization", "team", "project", "user", "key"] MemoryScope: TypeAlias = Literal["key", "user", "team", "project", "organization"] MemoryActivation: TypeAlias = Literal["disabled", "opt_in", "automatic"] +MemoryKind: TypeAlias = Literal["workflow", "decision", "correction", "learning", "context", "disagreement"] +MemoryCertainty: TypeAlias = Literal["user_stated", "observed", "inferred"] class MemoryPolicyInput(BaseModel): @@ -60,8 +62,8 @@ class MemoryCapture(BaseModel): expected_revision: datetime | None = None when_to_use: str = Field(default="", max_length=700) scope: str = Field(default="", max_length=200) - kind: Literal["workflow", "decision", "correction", "learning", "context", "disagreement"] = "context" - certainty: Literal["user_stated", "observed", "inferred"] = "observed" + kind: MemoryKind = "context" + certainty: MemoryCertainty = "observed" source: str = Field(default="", max_length=1000) @@ -78,8 +80,8 @@ class MemoryEntry(BaseModel): actor: str | None = None when_to_use: str = "" scope: str = "" - kind: str = "context" - certainty: str = "observed" + kind: MemoryKind = "context" + certainty: MemoryCertainty = "observed" source: str = "" @@ -103,9 +105,9 @@ class MemoryObservation(BaseModel): title: str = Field(min_length=3, max_length=180) when_to_use: str = Field(min_length=5, max_length=700) content: str = Field(min_length=10, max_length=6000) - kind: Literal["workflow", "decision", "correction", "learning", "context", "disagreement"] + kind: MemoryKind scope: str = Field(min_length=1, max_length=200) - certainty: Literal["user_stated", "observed", "inferred"] + certainty: MemoryCertainty evidence: str = Field(min_length=5, max_length=2000) source: str = Field(min_length=3, max_length=1000) diff --git a/ui/litellm-dashboard/src/lib/http/schema.d.ts b/ui/litellm-dashboard/src/lib/http/schema.d.ts index 32dd8a03864..331a9f28785 100644 --- a/ui/litellm-dashboard/src/lib/http/schema.d.ts +++ b/ui/litellm-dashboard/src/lib/http/schema.d.ts @@ -31990,8 +31990,9 @@ export interface components { /** * Certainty * @default observed + * @enum {string} */ - certainty: string; + certainty: "user_stated" | "observed" | "inferred"; /** Content */ content: string; /** Created At */ @@ -32003,8 +32004,9 @@ export interface components { /** * Kind * @default context + * @enum {string} */ - kind: string; + kind: "workflow" | "decision" | "correction" | "learning" | "context" | "disagreement"; /** Memory Id */ memory_id: string; /**