diff --git a/agent/claude_runtime.py b/agent/claude_runtime.py index 57c3759..7246ed8 100644 --- a/agent/claude_runtime.py +++ b/agent/claude_runtime.py @@ -206,6 +206,17 @@ class ClaudeCodeRuntime: """Clean up stale sessions. Returns count removed.""" return self._sessions.cleanup(self._config.session_ttl_hours) + def reset_session(self, conversation_id: str) -> bool: + """Clear the persistent session mapping for a conversation. + + Returns ``True`` if a session was cleared. + """ + had = self._sessions.get(conversation_id) is not None + if had: + self._sessions.remove(conversation_id) + logger.info(f"Session reset: {conversation_id}") + return had + # ------------------------------------------------------------------- # Core: Run claude CLI # ------------------------------------------------------------------- diff --git a/agent/opencode_runtime.py b/agent/opencode_runtime.py index ba4ebd8..95bab9e 100644 --- a/agent/opencode_runtime.py +++ b/agent/opencode_runtime.py @@ -711,6 +711,20 @@ class OpenCodeRuntime: """Clean up stale sessions. Returns count removed.""" return self._sessions.cleanup(self._config.session_ttl_hours) + def reset_session(self, conversation_id: str) -> bool: + """Clear both the persistent session mapping and the live session. + + Returns ``True`` if anything was cleared. + """ + had_live = self.close_session(conversation_id) + had_persistent = self._sessions.get(conversation_id) is not None + if had_persistent: + self._sessions.remove(conversation_id) + cleared = had_live or had_persistent + if cleared: + logger.info(f"Session reset: {conversation_id}") + return cleared + # ------------------------------------------------------------------- # CLI Mode: Subprocess execution # (mirrors OpenClaw's runCliAgent → runCommandWithTimeout pattern) diff --git a/docs/project/commands.md b/docs/project/commands.md index 0b15aaf..30bbe72 100644 --- a/docs/project/commands.md +++ b/docs/project/commands.md @@ -16,6 +16,7 @@ Type these as regular messages in any channel or DM. No `/` prefix needed — ju | `help` | Show all available commands | | `time` | Current server time | | `sessions` | Active session count + cleanup stale | +| `new` / `reset` | Start a fresh conversation (clears session for this channel) | | `reload` | Reload config.json and skills | | `subagents` | List active background tasks | diff --git a/main.py b/main.py index 0f6e8ef..6b674c2 100644 --- a/main.py +++ b/main.py @@ -214,6 +214,15 @@ def ai_handler(msg: IncomingMessage) -> str: if cmd in ("sessions",): return _format_sessions() + # Reset session for this conversation + if cmd in ("new", "reset"): + cleared = _runtime.reset_session(msg.conversation_id) + if _hook_mgr: + _hook_mgr.trigger(HookEvent(type="command", action="new")) + if cleared: + return "🆕 Session cleared — next message starts a fresh conversation." + return "🆕 No active session to clear — already starting fresh." + # Cron management commands if cmd.startswith("cron"): return _handle_cron_command(cmd) @@ -1606,6 +1615,7 @@ def _format_help() -> str: "• `help` — This help message\n" "• `time` — Server time\n" "• `sessions` — Active session count\n" + "• `new` / `reset` — Start a fresh conversation (clears session)\n" "• `reload` — Reload config and skills\n" "\n" "*Runtime:*\n"