Features: - Three-tier memory architecture (short/mid/long-term) - PostgreSQL schema for conversations, events, memories - Qdrant vector database for semantic search - Cohere embeddings (embed-multilingual-v3.0, 1024 dims) - FastAPI Memory Service with full CRUD - External Secrets integration with Vault - Kubernetes deployment manifests Components: - infrastructure/database/agent-memory-schema.sql - infrastructure/kubernetes/apps/qdrant/ - infrastructure/kubernetes/apps/memory-service/ - services/memory-service/ (FastAPI app) Also includes: - External Secrets Operator - Traefik Ingress Controller - Cert-Manager with Let's Encrypt - ArgoCD for GitOps
250 lines
6.2 KiB
Python
250 lines
6.2 KiB
Python
"""
|
|
DAARION Memory Service - Pydantic Models
|
|
"""
|
|
from datetime import datetime
|
|
from typing import Optional, List, Any
|
|
from uuid import UUID
|
|
from enum import Enum
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
# ============================================================================
|
|
# ENUMS
|
|
# ============================================================================
|
|
|
|
class EventType(str, Enum):
|
|
MESSAGE = "message"
|
|
TOOL_CALL = "tool_call"
|
|
TOOL_RESULT = "tool_result"
|
|
DECISION = "decision"
|
|
SUMMARY = "summary"
|
|
MEMORY_WRITE = "memory_write"
|
|
MEMORY_RETRACT = "memory_retract"
|
|
ERROR = "error"
|
|
|
|
|
|
class MessageRole(str, Enum):
|
|
USER = "user"
|
|
ASSISTANT = "assistant"
|
|
SYSTEM = "system"
|
|
TOOL = "tool"
|
|
|
|
|
|
class MemoryCategory(str, Enum):
|
|
PREFERENCE = "preference"
|
|
IDENTITY = "identity"
|
|
CONSTRAINT = "constraint"
|
|
PROJECT_FACT = "project_fact"
|
|
RELATIONSHIP = "relationship"
|
|
SKILL = "skill"
|
|
GOAL = "goal"
|
|
CONTEXT = "context"
|
|
FEEDBACK = "feedback"
|
|
|
|
|
|
class RetentionPolicy(str, Enum):
|
|
PERMANENT = "permanent"
|
|
SESSION = "session"
|
|
TTL_DAYS = "ttl_days"
|
|
UNTIL_REVOKED = "until_revoked"
|
|
|
|
|
|
class FeedbackAction(str, Enum):
|
|
CONFIRM = "confirm"
|
|
REJECT = "reject"
|
|
EDIT = "edit"
|
|
DELETE = "delete"
|
|
|
|
|
|
# ============================================================================
|
|
# REQUEST MODELS
|
|
# ============================================================================
|
|
|
|
class CreateThreadRequest(BaseModel):
|
|
"""Create new conversation thread"""
|
|
org_id: UUID
|
|
workspace_id: Optional[UUID] = None
|
|
user_id: UUID
|
|
agent_id: Optional[UUID] = None
|
|
title: Optional[str] = None
|
|
tags: List[str] = []
|
|
metadata: dict = {}
|
|
|
|
|
|
class AddEventRequest(BaseModel):
|
|
"""Add event to conversation"""
|
|
thread_id: UUID
|
|
event_type: EventType
|
|
role: Optional[MessageRole] = None
|
|
content: Optional[str] = None
|
|
tool_name: Optional[str] = None
|
|
tool_input: Optional[dict] = None
|
|
tool_output: Optional[dict] = None
|
|
payload: dict = {}
|
|
token_count: Optional[int] = None
|
|
model_used: Optional[str] = None
|
|
latency_ms: Optional[int] = None
|
|
metadata: dict = {}
|
|
|
|
|
|
class CreateMemoryRequest(BaseModel):
|
|
"""Create long-term memory item"""
|
|
org_id: UUID
|
|
workspace_id: Optional[UUID] = None
|
|
user_id: UUID
|
|
agent_id: Optional[UUID] = None # null = global
|
|
category: MemoryCategory
|
|
fact_text: str
|
|
confidence: float = Field(default=0.8, ge=0, le=1)
|
|
source_event_id: Optional[UUID] = None
|
|
source_thread_id: Optional[UUID] = None
|
|
extraction_method: str = "explicit"
|
|
is_sensitive: bool = False
|
|
retention: RetentionPolicy = RetentionPolicy.UNTIL_REVOKED
|
|
ttl_days: Optional[int] = None
|
|
tags: List[str] = []
|
|
metadata: dict = {}
|
|
|
|
|
|
class MemoryFeedbackRequest(BaseModel):
|
|
"""User feedback on memory"""
|
|
memory_id: UUID
|
|
user_id: UUID
|
|
action: FeedbackAction
|
|
new_value: Optional[str] = None
|
|
reason: Optional[str] = None
|
|
|
|
|
|
class RetrievalRequest(BaseModel):
|
|
"""Semantic retrieval request"""
|
|
org_id: UUID
|
|
user_id: UUID
|
|
agent_id: Optional[UUID] = None
|
|
workspace_id: Optional[UUID] = None
|
|
queries: List[str]
|
|
top_k: int = 10
|
|
min_confidence: float = 0.5
|
|
include_global: bool = True
|
|
categories: Optional[List[MemoryCategory]] = None
|
|
|
|
|
|
class SummaryRequest(BaseModel):
|
|
"""Generate summary for thread"""
|
|
thread_id: UUID
|
|
force: bool = False # force even if under token threshold
|
|
|
|
|
|
# ============================================================================
|
|
# RESPONSE MODELS
|
|
# ============================================================================
|
|
|
|
class ThreadResponse(BaseModel):
|
|
thread_id: UUID
|
|
org_id: UUID
|
|
workspace_id: Optional[UUID]
|
|
user_id: UUID
|
|
agent_id: Optional[UUID]
|
|
title: Optional[str]
|
|
status: str
|
|
message_count: int
|
|
total_tokens: int
|
|
created_at: datetime
|
|
last_activity_at: datetime
|
|
|
|
|
|
class EventResponse(BaseModel):
|
|
event_id: UUID
|
|
thread_id: UUID
|
|
event_type: EventType
|
|
role: Optional[MessageRole]
|
|
content: Optional[str]
|
|
tool_name: Optional[str]
|
|
tool_input: Optional[dict]
|
|
tool_output: Optional[dict]
|
|
payload: dict
|
|
token_count: Optional[int]
|
|
sequence_num: int
|
|
created_at: datetime
|
|
|
|
|
|
class MemoryResponse(BaseModel):
|
|
memory_id: UUID
|
|
org_id: UUID
|
|
workspace_id: Optional[UUID]
|
|
user_id: UUID
|
|
agent_id: Optional[UUID]
|
|
category: MemoryCategory
|
|
fact_text: str
|
|
confidence: float
|
|
is_verified: bool
|
|
is_sensitive: bool
|
|
retention: RetentionPolicy
|
|
valid_from: datetime
|
|
valid_to: Optional[datetime]
|
|
last_used_at: Optional[datetime]
|
|
use_count: int
|
|
created_at: datetime
|
|
|
|
|
|
class SummaryResponse(BaseModel):
|
|
summary_id: UUID
|
|
thread_id: UUID
|
|
version: int
|
|
summary_text: str
|
|
state: dict
|
|
events_count: int
|
|
compression_ratio: Optional[float]
|
|
created_at: datetime
|
|
|
|
|
|
class RetrievalResult(BaseModel):
|
|
"""Single retrieval result"""
|
|
memory_id: UUID
|
|
fact_text: str
|
|
category: MemoryCategory
|
|
confidence: float
|
|
relevance_score: float
|
|
agent_id: Optional[UUID]
|
|
is_global: bool
|
|
|
|
|
|
class RetrievalResponse(BaseModel):
|
|
"""Retrieval response with results"""
|
|
results: List[RetrievalResult]
|
|
query_count: int
|
|
total_results: int
|
|
|
|
|
|
class ContextResponse(BaseModel):
|
|
"""Full context for agent prompt"""
|
|
thread_id: UUID
|
|
summary: Optional[SummaryResponse]
|
|
recent_messages: List[EventResponse]
|
|
retrieved_memories: List[RetrievalResult]
|
|
token_estimate: int
|
|
|
|
|
|
# ============================================================================
|
|
# INTERNAL MODELS
|
|
# ============================================================================
|
|
|
|
class EmbeddingRequest(BaseModel):
|
|
"""Internal embedding request"""
|
|
texts: List[str]
|
|
input_type: str = "search_document" # or "search_query"
|
|
|
|
|
|
class QdrantPayload(BaseModel):
|
|
"""Qdrant point payload"""
|
|
org_id: str
|
|
workspace_id: Optional[str]
|
|
user_id: str
|
|
agent_id: Optional[str]
|
|
thread_id: Optional[str]
|
|
memory_id: Optional[str]
|
|
event_id: Optional[str]
|
|
type: str # "memory", "summary", "message"
|
|
category: Optional[str]
|
|
text: str
|
|
created_at: str
|