core/memory: bind sessions to workspace path with SQLite migrate

Add session.workspace column, create/list filters, and ALTER TABLE
migration for existing chat databases.
This commit is contained in:
2026-07-15 00:00:50 +08:00
parent 566a06c996
commit 0a2dac2561
3 changed files with 112 additions and 7 deletions
+60
View File
@@ -59,3 +59,63 @@ async def test_list_sessions(store: MemoryStore) -> None:
ids = {s.sid for s in sessions}
assert s1.sid in ids
assert s2.sid in ids
async def test_session_workspace_binding(store: MemoryStore, tmp_path: object) -> None:
from pathlib import Path
assert isinstance(tmp_path, Path)
a = tmp_path / "proj-a"
b = tmp_path / "proj-b"
a.mkdir()
b.mkdir()
sa = await store.create_session(name="a", workspace=a)
sb = await store.create_session(name="b", workspace=b)
assert sa.workspace == str(a.resolve())
listed_a = await store.list_sessions(workspace=a)
assert {s.sid for s in listed_a} == {sa.sid}
listed_b = await store.list_sessions(workspace=b)
assert {s.sid for s in listed_b} == {sb.sid}
async def test_workspace_column_migration(tmp_path: object) -> None:
"""Existing DBs without session.workspace get the column via ALTER."""
from pathlib import Path
from sqlalchemy import text
from sqlalchemy.ext.asyncio import create_async_engine
assert isinstance(tmp_path, Path)
db_path = tmp_path / "legacy.db"
engine = create_async_engine(f"sqlite+aiosqlite:///{db_path}")
async with engine.begin() as conn:
_ = await conn.execute(
text(
"CREATE TABLE user ("
"uid INTEGER PRIMARY KEY, name VARCHAR(48) UNIQUE, "
"email VARCHAR(255) UNIQUE, password_hash VARCHAR(256), "
"created_at DATETIME)"
)
)
_ = await conn.execute(
text(
"CREATE TABLE session ("
"sid INTEGER PRIMARY KEY, uid INTEGER, name VARCHAR(64), "
"created_at DATETIME, updated_at DATETIME)"
)
)
_ = await conn.execute(
text(
"CREATE TABLE message ("
"mid INTEGER PRIMARY KEY, sid INTEGER, seq INTEGER, "
"data JSON, created_at DATETIME, updated_at DATETIME)"
)
)
await engine.dispose()
store = await MemoryStore.open(DatabaseConfig(url=str(db_path)))
session = await store.create_session(name="migrated", workspace=tmp_path)
from plyngent.memory.database.store import normalize_workspace
assert session.workspace == normalize_workspace(tmp_path)
await store.close()