Add generic memory gateway v1
This commit is contained in:
227
memory_gateway/schemas.py
Normal file
227
memory_gateway/schemas.py
Normal file
@ -0,0 +1,227 @@
|
||||
"""Core schemas for the generic Memory Gateway v1 API."""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from enum import Enum
|
||||
from typing import Any, Literal, Optional
|
||||
from uuid import uuid4
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
def utc_now() -> datetime:
|
||||
return datetime.now(timezone.utc)
|
||||
|
||||
|
||||
class Visibility(str, Enum):
|
||||
PRIVATE = "private"
|
||||
AGENT_ONLY = "agent-only"
|
||||
WORKSPACE_SHARED = "workspace-shared"
|
||||
GLOBAL = "global"
|
||||
|
||||
|
||||
class MemoryType(str, Enum):
|
||||
PROFILE = "profile"
|
||||
PREFERENCE = "preference"
|
||||
FACT = "fact"
|
||||
DECISION = "decision"
|
||||
SUMMARY = "summary"
|
||||
EPISODIC = "episodic"
|
||||
PROCEDURE = "procedure"
|
||||
EXPERIENCE = "experience"
|
||||
KNOWLEDGE = "knowledge"
|
||||
|
||||
|
||||
class SourceType(str, Enum):
|
||||
CONVERSATION = "conversation"
|
||||
TASK = "task"
|
||||
AGENT = "agent"
|
||||
OBSIDIAN = "obsidian"
|
||||
OPENVIKING = "openviking"
|
||||
EVERMEMOS = "evermemos"
|
||||
MANUAL = "manual"
|
||||
|
||||
|
||||
class UserRecord(BaseModel):
|
||||
id: str = Field(default_factory=lambda: f"user_{uuid4().hex[:12]}")
|
||||
display_name: str
|
||||
status: Literal["active", "disabled"] = "active"
|
||||
profile_namespace: Optional[str] = None
|
||||
preferences: dict[str, Any] = Field(default_factory=dict)
|
||||
created_at: datetime = Field(default_factory=utc_now)
|
||||
updated_at: datetime = Field(default_factory=utc_now)
|
||||
|
||||
|
||||
class AgentRecord(BaseModel):
|
||||
id: str
|
||||
name: str
|
||||
framework: str
|
||||
owner_user_id: Optional[str] = None
|
||||
created_at: datetime = Field(default_factory=utc_now)
|
||||
|
||||
|
||||
class WorkspaceRecord(BaseModel):
|
||||
id: str
|
||||
name: str
|
||||
owner_user_id: str
|
||||
member_user_ids: list[str] = Field(default_factory=list)
|
||||
allowed_agent_ids: list[str] = Field(default_factory=list)
|
||||
created_at: datetime = Field(default_factory=utc_now)
|
||||
|
||||
|
||||
class SessionRecord(BaseModel):
|
||||
id: str = Field(default_factory=lambda: f"sess_{uuid4().hex[:12]}")
|
||||
user_id: str
|
||||
agent_id: Optional[str] = None
|
||||
workspace_id: Optional[str] = None
|
||||
status: Literal["open", "committed", "expired"] = "open"
|
||||
expires_at: Optional[datetime] = None
|
||||
created_at: datetime = Field(default_factory=utc_now)
|
||||
updated_at: datetime = Field(default_factory=utc_now)
|
||||
|
||||
|
||||
class ACLRule(BaseModel):
|
||||
visibility: Visibility = Visibility.PRIVATE
|
||||
allowed_user_ids: list[str] = Field(default_factory=list)
|
||||
allowed_agent_ids: list[str] = Field(default_factory=list)
|
||||
allowed_workspace_ids: list[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
class MemoryRecord(BaseModel):
|
||||
id: str = Field(default_factory=lambda: f"mem_{uuid4().hex[:16]}")
|
||||
user_id: str
|
||||
agent_id: Optional[str] = None
|
||||
workspace_id: Optional[str] = None
|
||||
session_id: Optional[str] = None
|
||||
namespace: str
|
||||
memory_type: MemoryType = MemoryType.FACT
|
||||
content: str
|
||||
summary: Optional[str] = None
|
||||
tags: list[str] = Field(default_factory=list)
|
||||
importance: float = Field(default=0.5, ge=0, le=1)
|
||||
confidence: float = Field(default=0.8, ge=0, le=1)
|
||||
visibility: Visibility = Visibility.PRIVATE
|
||||
acl: ACLRule = Field(default_factory=ACLRule)
|
||||
source: SourceType = SourceType.MANUAL
|
||||
source_ref: Optional[str] = None
|
||||
embedding_ref: Optional[str] = None
|
||||
created_at: datetime = Field(default_factory=utc_now)
|
||||
updated_at: datetime = Field(default_factory=utc_now)
|
||||
expires_at: Optional[datetime] = None
|
||||
archived_at: Optional[datetime] = None
|
||||
version: int = 1
|
||||
|
||||
|
||||
class EpisodeRecord(BaseModel):
|
||||
id: str = Field(default_factory=lambda: f"epi_{uuid4().hex[:16]}")
|
||||
user_id: str
|
||||
agent_id: Optional[str] = None
|
||||
workspace_id: Optional[str] = None
|
||||
session_id: str
|
||||
namespace: str
|
||||
content: str
|
||||
summary: Optional[str] = None
|
||||
events: list[dict[str, Any]] = Field(default_factory=list)
|
||||
tags: list[str] = Field(default_factory=list)
|
||||
source: SourceType = SourceType.CONVERSATION
|
||||
created_at: datetime = Field(default_factory=utc_now)
|
||||
expires_at: Optional[datetime] = None
|
||||
|
||||
|
||||
class ProfileRecord(BaseModel):
|
||||
id: str = Field(default_factory=lambda: f"profile_{uuid4().hex[:12]}")
|
||||
user_id: str
|
||||
namespace: str
|
||||
display_name: Optional[str] = None
|
||||
stable_facts: list[str] = Field(default_factory=list)
|
||||
preferences: dict[str, Any] = Field(default_factory=dict)
|
||||
working_style: list[str] = Field(default_factory=list)
|
||||
updated_from_memory_ids: list[str] = Field(default_factory=list)
|
||||
version: int = 1
|
||||
updated_at: datetime = Field(default_factory=utc_now)
|
||||
|
||||
|
||||
class AuditLog(BaseModel):
|
||||
id: str = Field(default_factory=lambda: f"audit_{uuid4().hex[:16]}")
|
||||
actor_user_id: Optional[str] = None
|
||||
actor_agent_id: Optional[str] = None
|
||||
action: str
|
||||
target_type: str
|
||||
target_id: Optional[str] = None
|
||||
namespace: Optional[str] = None
|
||||
decision: Literal["allow", "deny"] = "allow"
|
||||
reason: Optional[str] = None
|
||||
metadata: dict[str, Any] = Field(default_factory=dict)
|
||||
created_at: datetime = Field(default_factory=utc_now)
|
||||
|
||||
|
||||
class AccessContext(BaseModel):
|
||||
user_id: str
|
||||
agent_id: Optional[str] = None
|
||||
workspace_id: Optional[str] = None
|
||||
session_id: Optional[str] = None
|
||||
|
||||
|
||||
class CreateUserRequest(BaseModel):
|
||||
display_name: str
|
||||
user_id: Optional[str] = None
|
||||
preferences: dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class MemorySearchRequest(AccessContext):
|
||||
query: str
|
||||
namespaces: list[str] = Field(default_factory=list)
|
||||
memory_types: list[MemoryType] = Field(default_factory=list)
|
||||
tags: list[str] = Field(default_factory=list)
|
||||
limit: int = Field(default=10, ge=1, le=100)
|
||||
|
||||
|
||||
class MemoryUpsertRequest(AccessContext):
|
||||
namespace: Optional[str] = None
|
||||
memory_type: MemoryType = MemoryType.FACT
|
||||
content: str
|
||||
summary: Optional[str] = None
|
||||
tags: list[str] = Field(default_factory=list)
|
||||
importance: float = Field(default=0.5, ge=0, le=1)
|
||||
confidence: float = Field(default=0.8, ge=0, le=1)
|
||||
visibility: Visibility = Visibility.PRIVATE
|
||||
source: SourceType = SourceType.MANUAL
|
||||
expires_at: Optional[datetime] = None
|
||||
|
||||
|
||||
class MemoryPatchRequest(BaseModel):
|
||||
content: Optional[str] = None
|
||||
summary: Optional[str] = None
|
||||
tags: Optional[list[str]] = None
|
||||
importance: Optional[float] = Field(default=None, ge=0, le=1)
|
||||
confidence: Optional[float] = Field(default=None, ge=0, le=1)
|
||||
visibility: Optional[Visibility] = None
|
||||
expires_at: Optional[datetime] = None
|
||||
|
||||
|
||||
class EpisodeAppendRequest(AccessContext):
|
||||
content: str
|
||||
namespace: Optional[str] = None
|
||||
events: list[dict[str, Any]] = Field(default_factory=list)
|
||||
tags: list[str] = Field(default_factory=list)
|
||||
source: SourceType = SourceType.CONVERSATION
|
||||
expires_at: Optional[datetime] = None
|
||||
|
||||
|
||||
class CommitSessionRequest(AccessContext):
|
||||
promote: bool = True
|
||||
min_importance: float = Field(default=0.6, ge=0, le=1)
|
||||
target_namespace: Optional[str] = None
|
||||
|
||||
|
||||
class MemoryFeedbackRequest(AccessContext):
|
||||
feedback: Literal["useful", "not_useful", "incorrect", "duplicate", "outdated"]
|
||||
comment: Optional[str] = None
|
||||
|
||||
|
||||
class NamespaceInfo(BaseModel):
|
||||
namespace: str
|
||||
owner_user_id: Optional[str] = None
|
||||
visibility: Visibility
|
||||
description: str
|
||||
|
||||
Reference in New Issue
Block a user