refac
This commit is contained in:
1 parent
70e4ffcc65
commit
b0487dd6dd
1 file changed
+38
-3
@@ -4,11 +4,11 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import time
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
from typing import Literal, Optional
|
from typing import Literal
|
||||||
|
|
||||||
from open_webui.internal.db import Base, get_async_db_context
|
from open_webui.internal.db import Base, get_async_db_context
|
||||||
from pydantic import BaseModel, ConfigDict
|
from pydantic import BaseModel, ConfigDict
|
||||||
from sqlalchemy import BigInteger, Column, String, Text, delete, select
|
from sqlalchemy import JSON, BigInteger, Column, String, Text, delete, select
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
|
||||||
@@ -20,7 +20,9 @@ class Memory(Base): # user memory store
|
|||||||
id = Column(String, primary_key=True, unique=True)
|
id = Column(String, primary_key=True, unique=True)
|
||||||
user_id = Column(String, index=True)
|
user_id = Column(String, index=True)
|
||||||
type = Column(String, default='context', server_default='context', index=True)
|
type = Column(String, default='context', server_default='context', index=True)
|
||||||
|
path = Column(Text, nullable=True)
|
||||||
content = Column(Text) # free-form text learned from conversation
|
content = Column(Text) # free-form text learned from conversation
|
||||||
|
meta = Column(JSON, nullable=True)
|
||||||
updated_at = Column(BigInteger) # epoch seconds
|
updated_at = Column(BigInteger) # epoch seconds
|
||||||
created_at = Column(BigInteger) # epoch seconds
|
created_at = Column(BigInteger) # epoch seconds
|
||||||
|
|
||||||
@@ -31,7 +33,9 @@ class MemoryModel(BaseModel):
|
|||||||
id: str
|
id: str
|
||||||
user_id: str
|
user_id: str
|
||||||
type: Literal['user', 'context'] = 'context'
|
type: Literal['user', 'context'] = 'context'
|
||||||
|
path: str | None = None
|
||||||
content: str
|
content: str
|
||||||
|
meta: dict | None = None
|
||||||
updated_at: int # timestamp in epoch
|
updated_at: int # timestamp in epoch
|
||||||
created_at: int # timestamp in epoch
|
created_at: int # timestamp in epoch
|
||||||
model_config = ConfigDict(from_attributes=True) # allows ORM mapping
|
model_config = ConfigDict(from_attributes=True) # allows ORM mapping
|
||||||
@@ -47,6 +51,8 @@ class MemoriesTable:
|
|||||||
user_id: str,
|
user_id: str,
|
||||||
content: str,
|
content: str,
|
||||||
memory_type: str | None = None,
|
memory_type: str | None = None,
|
||||||
|
path: str | None = None,
|
||||||
|
meta: dict | None = None,
|
||||||
db: AsyncSession | None = None,
|
db: AsyncSession | None = None,
|
||||||
) -> MemoryModel | None:
|
) -> MemoryModel | None:
|
||||||
"""Persist a new memory entry and return the created model."""
|
"""Persist a new memory entry and return the created model."""
|
||||||
@@ -56,7 +62,9 @@ class MemoriesTable:
|
|||||||
id=str(uuid.uuid4()),
|
id=str(uuid.uuid4()),
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
type=self.normalize_memory_type(memory_type),
|
type=self.normalize_memory_type(memory_type),
|
||||||
|
path=path,
|
||||||
content=content,
|
content=content,
|
||||||
|
meta=meta,
|
||||||
created_at=now,
|
created_at=now,
|
||||||
updated_at=now,
|
updated_at=now,
|
||||||
)
|
)
|
||||||
@@ -71,6 +79,9 @@ class MemoriesTable:
|
|||||||
user_id: str,
|
user_id: str,
|
||||||
content: str | None,
|
content: str | None,
|
||||||
memory_type: str | None = None,
|
memory_type: str | None = None,
|
||||||
|
path: str | None = None,
|
||||||
|
update_path: bool = False,
|
||||||
|
meta: dict | None = None,
|
||||||
db: AsyncSession | None = None,
|
db: AsyncSession | None = None,
|
||||||
) -> MemoryModel | None:
|
) -> MemoryModel | None:
|
||||||
async with get_async_db_context(db) as db:
|
async with get_async_db_context(db) as db:
|
||||||
@@ -83,6 +94,10 @@ class MemoriesTable:
|
|||||||
memory.content = content
|
memory.content = content
|
||||||
if memory_type is not None:
|
if memory_type is not None:
|
||||||
memory.type = self.normalize_memory_type(memory_type)
|
memory.type = self.normalize_memory_type(memory_type)
|
||||||
|
if update_path:
|
||||||
|
memory.path = path
|
||||||
|
if meta is not None:
|
||||||
|
memory.meta = {**(memory.meta or {}), **meta}
|
||||||
memory.updated_at = int(time.time())
|
memory.updated_at = int(time.time())
|
||||||
|
|
||||||
await db.commit()
|
await db.commit()
|
||||||
@@ -167,8 +182,9 @@ class MemoriesTable:
|
|||||||
if action == 'add':
|
if action == 'add':
|
||||||
content = operation.get('content', '').strip()
|
content = operation.get('content', '').strip()
|
||||||
memory_type = self.normalize_memory_type(operation.get('type'))
|
memory_type = self.normalize_memory_type(operation.get('type'))
|
||||||
|
path = operation.get('path')
|
||||||
result = await db.execute(
|
result = await db.execute(
|
||||||
select(Memory).filter_by(user_id=user_id, content=content, type=memory_type)
|
select(Memory).filter_by(user_id=user_id, content=content, type=memory_type, path=path)
|
||||||
)
|
)
|
||||||
existing = result.scalars().first()
|
existing = result.scalars().first()
|
||||||
if existing:
|
if existing:
|
||||||
@@ -186,7 +202,9 @@ class MemoriesTable:
|
|||||||
id=str(uuid.uuid4()),
|
id=str(uuid.uuid4()),
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
type=memory_type,
|
type=memory_type,
|
||||||
|
path=path,
|
||||||
content=content,
|
content=content,
|
||||||
|
meta=operation.get('meta'),
|
||||||
created_at=now,
|
created_at=now,
|
||||||
updated_at=now,
|
updated_at=now,
|
||||||
)
|
)
|
||||||
@@ -204,6 +222,23 @@ class MemoriesTable:
|
|||||||
memory.content = content
|
memory.content = content
|
||||||
if operation.get('type') is not None:
|
if operation.get('type') is not None:
|
||||||
memory.type = self.normalize_memory_type(operation.get('type'))
|
memory.type = self.normalize_memory_type(operation.get('type'))
|
||||||
|
if 'path' in operation:
|
||||||
|
memory.path = operation.get('path')
|
||||||
|
if operation.get('meta') is not None:
|
||||||
|
memory.meta = {**(memory.meta or {}), **operation.get('meta')}
|
||||||
|
memory.updated_at = now
|
||||||
|
await db.flush()
|
||||||
|
results.append({'action': action, 'status': 'updated', 'memory': MemoryModel.model_validate(memory)})
|
||||||
|
|
||||||
|
elif action == 'move':
|
||||||
|
memory_id = operation.get('id')
|
||||||
|
memory = await db.get(Memory, memory_id)
|
||||||
|
if not memory or memory.user_id != user_id:
|
||||||
|
raise ValueError(f'Memory not found: {memory_id}')
|
||||||
|
|
||||||
|
memory.path = operation.get('path')
|
||||||
|
if operation.get('meta') is not None:
|
||||||
|
memory.meta = {**(memory.meta or {}), **operation.get('meta')}
|
||||||
memory.updated_at = now
|
memory.updated_at = now
|
||||||
await db.flush()
|
await db.flush()
|
||||||
results.append({'action': action, 'status': 'updated', 'memory': MemoryModel.model_validate(memory)})
|
results.append({'action': action, 'status': 'updated', 'memory': MemoryModel.model_validate(memory)})
|
||||||
|
|||||||
Reference in new issue
Block a user