fix(loop): restore /new immediate return with safe background consolidation
PR #881 (commit 755e424) fixed the race condition between normal consolidation
and /new consolidation, but did so by making /new wait for consolidation to
complete before returning. This hurts user experience - /new should be instant.
This PR restores the original immediate-return behavior while keeping safety:
1. **Immediate return**: Session clears and user sees "New session started" right away
2. **Background archival**: Consolidation runs in background via asyncio.create_task
3. **Serialized consolidation**: Uses the same lock as normal consolidation via
`memory_consolidator.get_lock()` to prevent concurrent writes
If consolidation fails after session clear, archived messages may be lost.
This is acceptable because:
- User already sees the new session and can continue working
- Failure is logged for debugging
- The alternative (blocking /new on every call) hurts UX for all users
This commit is contained in:
@@ -380,24 +380,29 @@ class AgentLoop:
|
||||
# Slash commands
|
||||
cmd = msg.content.strip().lower()
|
||||
if cmd == "/new":
|
||||
try:
|
||||
if not await self.memory_consolidator.archive_unconsolidated(session):
|
||||
return OutboundMessage(
|
||||
channel=msg.channel,
|
||||
chat_id=msg.chat_id,
|
||||
content="Memory archival failed, session not cleared. Please try again.",
|
||||
)
|
||||
except Exception:
|
||||
logger.exception("/new archival failed for {}", session.key)
|
||||
return OutboundMessage(
|
||||
channel=msg.channel,
|
||||
chat_id=msg.chat_id,
|
||||
content="Memory archival failed, session not cleared. Please try again.",
|
||||
)
|
||||
# Capture messages before clearing for background archival
|
||||
messages_to_archive = session.messages[session.last_consolidated:]
|
||||
|
||||
# Immediately clear session and return
|
||||
session.clear()
|
||||
self.sessions.save(session)
|
||||
self.sessions.invalidate(session.key)
|
||||
|
||||
# Schedule background archival (serialized with normal consolidation via lock)
|
||||
if messages_to_archive:
|
||||
|
||||
async def _archive_in_background():
|
||||
lock = self.memory_consolidator.get_lock(session.key)
|
||||
async with lock:
|
||||
try:
|
||||
success = await self.memory_consolidator.consolidate_messages(messages_to_archive)
|
||||
if not success:
|
||||
logger.warning("/new background archival failed for {}", session.key)
|
||||
except Exception:
|
||||
logger.exception("/new background archival error for {}", session.key)
|
||||
|
||||
asyncio.create_task(_archive_in_background())
|
||||
|
||||
return OutboundMessage(channel=msg.channel, chat_id=msg.chat_id,
|
||||
content="New session started.")
|
||||
if cmd == "/help":
|
||||
|
||||
Reference in New Issue
Block a user