Add generic memory gateway v1

This commit is contained in:
2026-05-05 16:18:31 +08:00
parent ba84b1ddb3
commit e65731a273
54 changed files with 4082 additions and 49 deletions

227
memory_gateway/schemas.py Normal file
View 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