feat(agent_teams): spill message/task content into session files - #546
feat(agent_teams): spill message/task content into session files#546openjiuwen-sync-bot[bot] wants to merge 2 commits into
Conversation
Message and task bodies that exceed inline storage spill to files under the session workspace root; the SQLite ``content`` column keeps only the ``#file#`` placeholder and the DAOs transparently dereference it on read. The file path is derived from the row's own fields (kind + object id + to-member), never stored as a pointer. - SessionFileStore: session-scoped content store; atomic tmp+replace writes, path-traversal rejected, remove_session reclaims the whole spill directory (best-effort). - TeamWorkspacePaths.session_root is the single root source. - MessageDao/TaskDao: _is_placeholder + _deref_row hydrate rows on read; multicast writes one file per row; update_task overwrites the same task file in place and always counts the content path as a change; empty content stays inline (no file, no placeholder). - create_direct_messages spills all files before the SQLite write transaction to avoid file IO under the write lock. - _to_stored catches (OSError, ValueError) to match _deref_row: a path-escape ValueError degrades to inline content like any spill failure instead of propagating. - FileAddress.kind uses exported KIND_DIRECT / KIND_BROADCAST / KIND_TASK constants instead of raw strings. - delete_team / release_session reclaim the session spill directory via SessionFileStore.remove_session (best-effort, narrowed except). - Hydration gap fixed in list readers (get_messages / get_broadcast_messages / get_team_messages / get_tasks_by_assignee were returning #file# rows). - UT: tests/unit_tests/agent_teams/team_workspace/test_session_file_store.py (store round-trip, path derivation, traversal rejection, session cleanup, DAO placeholder round-trip, multicast per-row files, task update overwrite, failed-insert orphan reclaim, templated empty content stays inline).
F_81 (feature) + S_23 (spec): message/task content spills to session files, the DB keeps the ``#file#`` placeholder, and paths are derived from row fields. Records the SessionFileStore naming, 9 decisions, 5 rejected options, 10 invariants, the interface contract, and the session lifecycle.
|
|
|
head_sha: 变更摘要本 PR 将 主要改动
|
|
head_sha: 代码审查✅ 未发现问题 |
Paired: GitHub #546 ↔ GitCode !2338
What type of PR is this?
/kind
Self-checklist:(请自检,在[ ]内打上x,我们将检视你的完成情况,否则会导致pr无法合入)