Files
memory-gateway/memory_gateway/backend_contracts.py

135 lines
4.2 KiB
Python

"""Backend adapter contracts for Memory Gateway v2."""
from __future__ import annotations
from datetime import datetime
from enum import Enum
from typing import Any, Optional
from uuid import uuid4
from pydantic import BaseModel, Field
from .schemas import utc_now
from .schemas_v2 import BackendType, MemoryRefType, OperationStatus
class BackendOperation(str, Enum):
INGEST_TURN = "ingest_turn"
COMMIT_SESSION = "commit_session"
RETRIEVE_CONTEXT = "retrieve_context"
CREATE_REVIEW_DRAFT = "create_review_draft"
class BackendResultStatus(str, Enum):
SUCCESS = "success"
FAILED = "failed"
SKIPPED = "skipped"
PENDING = "pending"
class OutboxEventStatus(str, Enum):
PENDING = "pending"
PROCESSING = "processing"
SUCCESS = "success"
SKIPPED = "skipped"
FAILED = "failed"
DEAD_LETTER = "dead_letter"
class BackendWriteResult(BaseModel):
backend_type: BackendType
operation: BackendOperation
status: BackendResultStatus
native_id: Optional[str] = None
native_uri: Optional[str] = None
retryable: bool = False
error_code: Optional[str] = None
error_message: Optional[str] = None
latency_ms: Optional[float] = None
metadata: dict[str, Any] = Field(default_factory=dict)
class BackendProducedRef(BaseModel):
ref_type: MemoryRefType
native_id: Optional[str] = None
native_uri: Optional[str] = None
metadata: dict[str, Any] = Field(default_factory=dict)
class BackendCommitResult(BaseModel):
backend_type: BackendType
operation: BackendOperation = BackendOperation.COMMIT_SESSION
status: BackendResultStatus
native_id: Optional[str] = None
native_uri: Optional[str] = None
retryable: bool = False
error_code: Optional[str] = None
error_message: Optional[str] = None
latency_ms: Optional[float] = None
created_refs: list[str] = Field(default_factory=list)
refs: list[BackendProducedRef] = Field(default_factory=list)
metadata: dict[str, Any] = Field(default_factory=dict)
class BackendRetrieveItem(BaseModel):
text: Optional[str] = None
source_backend: BackendType
ref_id: Optional[str] = None
score: float = 0.0
memory_type: Optional[str] = None
metadata: dict[str, Any] = Field(default_factory=dict)
class BackendRetrieveResult(BaseModel):
backend_type: BackendType
operation: BackendOperation = BackendOperation.RETRIEVE_CONTEXT
status: BackendResultStatus
native_id: Optional[str] = None
native_uri: Optional[str] = None
retryable: bool = False
error_code: Optional[str] = None
error_message: Optional[str] = None
latency_ms: Optional[float] = None
items: list[BackendRetrieveItem] = Field(default_factory=list)
metadata: dict[str, Any] = Field(default_factory=dict)
class OutboxEvent(BaseModel):
id: str = Field(default_factory=lambda: f"outbox_{uuid4().hex[:16]}")
event_type: str
gateway_id: str
workspace_id: str
user_id: str
agent_id: Optional[str] = None
session_id: Optional[str] = None
backend_type: BackendType
operation: BackendOperation
payload_ref: Optional[str] = None
status: OutboxEventStatus = OutboxEventStatus.PENDING
attempt_count: int = 0
max_attempts: int = 3
next_retry_at: Optional[datetime] = None
last_error: Optional[str] = None
locked_by: Optional[str] = None
locked_at: Optional[datetime] = None
lease_expires_at: Optional[datetime] = None
metadata: dict[str, Any] = Field(default_factory=dict)
created_at: datetime = Field(default_factory=utc_now)
updated_at: datetime = Field(default_factory=utc_now)
class CommitJob(BaseModel):
job_id: str = Field(default_factory=lambda: f"job_{uuid4().hex[:16]}")
workspace_id: str
user_id: str
agent_id: Optional[str] = None
session_id: str
namespace: Optional[str] = None
status: OperationStatus = OperationStatus.ACCEPTED
requested_by: Optional[str] = None
created_refs_count: int = 0
error_message: Optional[str] = None
created_at: datetime = Field(default_factory=utc_now)
updated_at: datetime = Field(default_factory=utc_now)
started_at: Optional[datetime] = None
finished_at: Optional[datetime] = None