memory.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. from datetime import datetime
  2. from typing import TYPE_CHECKING, Generic, TypeVar
  3. from core_domain import (
  4. MemoryCreateContract,
  5. MemoryItemContract,
  6. MemoryScopeType,
  7. MemorySearchRequestContract,
  8. MemorySearchResultContract,
  9. MemoryStatus,
  10. )
  11. from core_shared import JSONValue
  12. from pydantic import BaseModel, Field
  13. if TYPE_CHECKING:
  14. from app.db.models import MemoryItem
  15. T = TypeVar("T")
  16. class ApiErrorResponse(BaseModel):
  17. errorType: str
  18. message: str
  19. details: dict[str, JSONValue] = Field(default_factory=dict)
  20. class ApiResponse(BaseModel, Generic[T]):
  21. success: bool = True
  22. data: T | None = None
  23. error: ApiErrorResponse | None = None
  24. requestId: str
  25. serverTime: datetime
  26. class PageRequest(BaseModel):
  27. page: int = Field(default=1, ge=1)
  28. pageSize: int = Field(default=20, ge=1, le=200)
  29. keyword: str | None = None
  30. @property
  31. def offset(self) -> int:
  32. return (self.page - 1) * self.pageSize
  33. class PageResult(BaseModel, Generic[T]):
  34. items: list[T]
  35. total: int
  36. page: int
  37. pageSize: int
  38. hasMore: bool
  39. @classmethod
  40. def from_items(
  41. cls,
  42. *,
  43. items: list[T],
  44. total: int,
  45. page: int,
  46. page_size: int) -> "PageResult[T]":
  47. return cls(
  48. items=items,
  49. total=total,
  50. page=page,
  51. pageSize=page_size,
  52. hasMore=page * page_size < total)
  53. class MemoryCreateRequest(MemoryCreateContract):
  54. pass
  55. class MemoryStatusUpdateRequest(BaseModel):
  56. status: MemoryStatus
  57. class MemorySearchRequest(MemorySearchRequestContract):
  58. pass
  59. class MemoryResponse(MemoryItemContract):
  60. @classmethod
  61. def from_entity(cls, entity: "MemoryItem") -> "MemoryResponse":
  62. return cls.model_validate(entity, from_attributes=True)
  63. class MemorySearchResultResponse(MemorySearchResultContract):
  64. item: MemoryResponse
  65. @classmethod
  66. def from_entity(
  67. cls,
  68. entity: "MemoryItem",
  69. score: float,
  70. score_json: dict[str, JSONValue]) -> "MemorySearchResultResponse":
  71. return cls(
  72. item=MemoryResponse.from_entity(entity),
  73. score=score,
  74. score_json=score_json)
  75. class MemoryItemDto(BaseModel):
  76. id: str
  77. scopeType: MemoryScopeType
  78. scopeId: str
  79. memoryType: str
  80. contentText: str
  81. content: dict[str, JSONValue] | None = None
  82. metadata: dict[str, JSONValue] = Field(default_factory=dict)
  83. embeddingModel: str | None = None
  84. embedding: list[float] | None = None
  85. ownerAgentId: str | None = None
  86. userId: str | None = None
  87. sessionId: str | None = None
  88. sourceRef: str | None = None
  89. importanceScore: int
  90. status: MemoryStatus
  91. lastAccessedTime: datetime | None = None
  92. expiresTime: datetime | None = None
  93. createdTime: datetime
  94. @classmethod
  95. def from_entity(cls, entity: "MemoryItem") -> "MemoryItemDto":
  96. return cls(
  97. id=entity.id,
  98. scopeType=entity.scope_type,
  99. scopeId=entity.scope_id,
  100. memoryType=entity.memory_type,
  101. contentText=entity.content_text,
  102. content=entity.content_json,
  103. metadata=entity.metadata_json or {},
  104. embeddingModel=entity.embedding_model,
  105. embedding=entity.embedding_json,
  106. ownerAgentId=entity.owner_agent_id,
  107. userId=entity.user_id,
  108. sessionId=entity.session_id,
  109. sourceRef=entity.source_ref,
  110. importanceScore=entity.importance_score,
  111. status=entity.status,
  112. lastAccessedTime=entity.last_accessed_time,
  113. expiresTime=entity.expires_time,
  114. createdTime=entity.created_time)
  115. class MemoryListRequestDto(PageRequest):
  116. scopeType: MemoryScopeType | None = None
  117. scopeId: str | None = None
  118. memoryType: str | None = None
  119. status: MemoryStatus | None = "active"
  120. ownerAgentId: str | None = None
  121. userId: str | None = None
  122. sessionId: str | None = None
  123. includeExpired: bool = True
  124. class MemoryCreateRequestDto(BaseModel):
  125. scopeType: MemoryScopeType
  126. scopeId: str
  127. memoryType: str = "fact"
  128. contentText: str
  129. content: dict[str, JSONValue] | None = None
  130. metadata: dict[str, JSONValue] = Field(default_factory=dict)
  131. ownerAgentId: str | None = None
  132. userId: str | None = None
  133. sessionId: str | None = None
  134. sourceRef: str | None = None
  135. importanceScore: int = Field(default=0, ge=0, le=100)
  136. expiresTime: datetime | None = None
  137. class MemoryDetailRequestDto(BaseModel):
  138. memoryId: str
  139. class MemoryUpdateRequestDto(BaseModel):
  140. memoryId: str
  141. scopeType: MemoryScopeType | None = None
  142. scopeId: str | None = None
  143. memoryType: str | None = None
  144. contentText: str | None = None
  145. content: dict[str, JSONValue] | None = None
  146. metadata: dict[str, JSONValue] | None = None
  147. ownerAgentId: str | None = None
  148. userId: str | None = None
  149. sessionId: str | None = None
  150. sourceRef: str | None = None
  151. importanceScore: int | None = Field(default=None, ge=0, le=100)
  152. expiresTime: datetime | None = None
  153. class MemoryStatusRequestDto(BaseModel):
  154. memoryId: str
  155. status: MemoryStatus
  156. class MemoryDeleteRequestDto(BaseModel):
  157. memoryId: str
  158. class MemorySearchRequestDto(BaseModel):
  159. query: str
  160. scopeType: MemoryScopeType | None = None
  161. scopeId: str | None = None
  162. ownerAgentId: str | None = None
  163. userId: str | None = None
  164. sessionId: str | None = None
  165. memoryType: str | None = None
  166. limit: int = Field(default=8, ge=1, le=100)
  167. class MemorySearchResultDto(BaseModel):
  168. item: MemoryItemDto
  169. score: float
  170. scoreDetails: dict[str, JSONValue] = Field(default_factory=dict)
  171. class DeleteData(BaseModel):
  172. deleted: bool
  173. memoryId: str