services.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. from datetime import datetime
  2. from core_domain import MemoryScopeType, MemoryStatus
  3. from app.db.models import MemoryItem
  4. from app.domain.repositories import MemoryItemRepository
  5. from app.schemas.memory import (
  6. MemoryCreateRequest,
  7. MemorySearchRequest,
  8. MemoryStatusUpdateRequest,
  9. )
  10. class MemoryApplicationService:
  11. def __init__(self, *, memory_repository: MemoryItemRepository) -> None:
  12. self.memory_repository = memory_repository
  13. def create_memory(self, payload: MemoryCreateRequest) -> MemoryItem:
  14. return self.memory_repository.create(
  15. tenant_id=payload.tenant_id,
  16. scope_type=payload.scope_type,
  17. scope_id=payload.scope_id,
  18. memory_type=payload.memory_type,
  19. content_text=payload.content_text,
  20. content_json=payload.content_json,
  21. metadata_json=payload.metadata_json,
  22. owner_agent_id=payload.owner_agent_id,
  23. user_id=payload.user_id,
  24. session_id=payload.session_id,
  25. source_ref=payload.source_ref,
  26. importance_score=payload.importance_score,
  27. expires_time=payload.expires_time,
  28. )
  29. def list_memories(
  30. self,
  31. *,
  32. tenant_id: str,
  33. scope_type: MemoryScopeType | None = None,
  34. scope_id: str | None = None,
  35. status: MemoryStatus | None = "active",
  36. limit: int = 100,
  37. ) -> list[MemoryItem]:
  38. return self.memory_repository.list_by_scope(
  39. tenant_id=tenant_id,
  40. scope_type=scope_type,
  41. scope_id=scope_id,
  42. status=status,
  43. limit=limit,
  44. )
  45. def search_memories(self, payload: MemorySearchRequest) -> list[tuple[MemoryItem, float]]:
  46. items = self.memory_repository.search(
  47. tenant_id=payload.tenant_id,
  48. query=payload.query,
  49. scope_type=payload.scope_type,
  50. scope_id=payload.scope_id,
  51. owner_agent_id=payload.owner_agent_id,
  52. user_id=payload.user_id,
  53. session_id=payload.session_id,
  54. limit=payload.limit,
  55. )
  56. now = datetime.utcnow()
  57. self.memory_repository.touch_many(memory_ids=[item.id for item in items], accessed_time=now)
  58. return [(item, self._score(item=item, query=payload.query)) for item in items]
  59. def update_memory_status(
  60. self,
  61. *,
  62. memory_id: str,
  63. payload: MemoryStatusUpdateRequest,
  64. ) -> MemoryItem | None:
  65. return self.memory_repository.update_status(
  66. tenant_id=payload.tenant_id,
  67. memory_id=memory_id,
  68. status=payload.status,
  69. )
  70. def _score(self, *, item: MemoryItem, query: str) -> float:
  71. lowered_content = item.content_text.lower()
  72. lowered_query = query.lower()
  73. exact_bonus = 1.0 if lowered_query in lowered_content else 0.0
  74. importance_bonus = min(item.importance_score, 100) / 100
  75. return round(exact_bonus + importance_bonus, 4)