mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-30 00:22:10 -04:00
feat(tasks): assign folder='Tasks' at creation + backfill migration (#2834)
* feat: assign folder='Tasks' to task sessions at creation Task sessions (LLM, action, research) now set folder='Tasks' on their DbSession row, matching the pattern used by the Assistant folder. This enables sidebar lens filtering without changing existing session behaviour. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add backfill script for task session folders One-shot script to set folder='Tasks' on existing [Task]/[Research] sessions that predate the folder assignment in task_scheduler.py. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: replace standalone backfill script with automatic migration Convert scripts/backfill_task_folders.py into _migrate_backfill_task_folders() in core/database.py, called from init_db(). The migration is idempotent (only touches rows where folder IS NULL/empty) and runs automatically on upgrade, so operators no longer need a manual step to tag pre-existing task sessions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1631,6 +1631,33 @@ def init_db():
|
|||||||
_migrate_encrypt_email_passwords()
|
_migrate_encrypt_email_passwords()
|
||||||
_migrate_encrypt_signatures()
|
_migrate_encrypt_signatures()
|
||||||
_migrate_encrypt_endpoint_keys()
|
_migrate_encrypt_endpoint_keys()
|
||||||
|
_migrate_backfill_task_folders()
|
||||||
|
|
||||||
|
|
||||||
|
def _migrate_backfill_task_folders():
|
||||||
|
"""Backfill folder='Tasks' on pre-existing task/research sessions.
|
||||||
|
|
||||||
|
Sessions created by the task scheduler (LLM tasks, action tasks, research
|
||||||
|
runs) now set folder='Tasks' at creation time. This migration tags any
|
||||||
|
older sessions that predate that assignment. Idempotent — only touches
|
||||||
|
rows where folder is NULL or empty and the title matches known prefixes.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with engine.connect() as conn:
|
||||||
|
cols = [r[1] for r in conn.execute(text("PRAGMA table_info(sessions)"))]
|
||||||
|
if "folder" not in cols:
|
||||||
|
return
|
||||||
|
res = conn.execute(text(
|
||||||
|
"UPDATE sessions SET folder = 'Tasks' "
|
||||||
|
"WHERE (folder IS NULL OR folder = '') "
|
||||||
|
"AND (name LIKE '[Task] %' OR name LIKE '[Research] %')"
|
||||||
|
))
|
||||||
|
conn.commit()
|
||||||
|
if res.rowcount:
|
||||||
|
logging.getLogger(__name__).info(
|
||||||
|
f"Backfilled folder='Tasks' on {res.rowcount} task/research sessions")
|
||||||
|
except Exception as e:
|
||||||
|
logging.getLogger(__name__).warning(f"task folder backfill: {e}")
|
||||||
|
|
||||||
|
|
||||||
def _migrate_chat_messages_fts():
|
def _migrate_chat_messages_fts():
|
||||||
|
|||||||
@@ -1315,6 +1315,7 @@ class TaskScheduler:
|
|||||||
endpoint_url=endpoint_url,
|
endpoint_url=endpoint_url,
|
||||||
model=model,
|
model=model,
|
||||||
owner=task.owner,
|
owner=task.owner,
|
||||||
|
folder="Tasks",
|
||||||
created_at=_utcnow(),
|
created_at=_utcnow(),
|
||||||
updated_at=_utcnow(),
|
updated_at=_utcnow(),
|
||||||
)
|
)
|
||||||
@@ -1463,6 +1464,7 @@ class TaskScheduler:
|
|||||||
endpoint_url=endpoint_url or "",
|
endpoint_url=endpoint_url or "",
|
||||||
model=model_name or "",
|
model=model_name or "",
|
||||||
owner=task.owner,
|
owner=task.owner,
|
||||||
|
folder="Tasks",
|
||||||
created_at=_utcnow(),
|
created_at=_utcnow(),
|
||||||
updated_at=_utcnow(),
|
updated_at=_utcnow(),
|
||||||
)
|
)
|
||||||
@@ -1755,6 +1757,7 @@ class TaskScheduler:
|
|||||||
endpoint_url=endpoint_url,
|
endpoint_url=endpoint_url,
|
||||||
model=model,
|
model=model,
|
||||||
owner=task.owner,
|
owner=task.owner,
|
||||||
|
folder="Tasks",
|
||||||
created_at=_utcnow(),
|
created_at=_utcnow(),
|
||||||
updated_at=_utcnow(),
|
updated_at=_utcnow(),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
"""Task sessions must be assigned folder='Tasks' at creation time."""
|
||||||
|
import inspect
|
||||||
|
from src.task_scheduler import TaskScheduler
|
||||||
|
|
||||||
|
|
||||||
|
def test_llm_task_session_gets_tasks_folder():
|
||||||
|
"""_execute_llm_task must create sessions with folder='Tasks'."""
|
||||||
|
source = inspect.getsource(TaskScheduler._execute_llm_task)
|
||||||
|
assert 'folder="Tasks"' in source or "folder='Tasks'" in source, (
|
||||||
|
"LLM task session creation must set folder='Tasks'"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_action_task_session_gets_tasks_folder():
|
||||||
|
"""_deliver_task_result must create sessions with folder='Tasks'."""
|
||||||
|
source = inspect.getsource(TaskScheduler._deliver_task_result)
|
||||||
|
assert 'folder="Tasks"' in source or "folder='Tasks'" in source, (
|
||||||
|
"Action task session delivery must set folder='Tasks'"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_research_task_session_gets_tasks_folder():
|
||||||
|
"""_execute_research_task must create sessions with folder='Tasks'."""
|
||||||
|
source = inspect.getsource(TaskScheduler._execute_research_task)
|
||||||
|
assert 'folder="Tasks"' in source or "folder='Tasks'" in source, (
|
||||||
|
"Research task session creation must set folder='Tasks'"
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user