Skip to content

Bug: Session reset leaves Hindsight OpenClaw plugin state uncleared — causes duplicate retains #1303

@jlin53882

Description

@jlin53882

Bug Description

When the Hermes/OpenClaw agent fires a `/reset` (or `/new`) command, the agent framework correctly emits a `on_session_reset` hook via `_notify_session_boundary("on_session_reset")`. However, the `@vectorize-io/hindsight-openclaw` plugin only subscribes to 4 hooks:

```
before_dispatch
before_agent_start
before_prompt_build
agent_end
```

`on_session_reset` and `on_session_finalize` are not subscribed. As a result, all session-scoped in-memory state in the plugin persists across resets:

State variable Purpose Impact when uncleared on reset
`turnCountBySession` (Map) Tracks turn count per session for `retainEveryNTurns` Turn counter continues from previous session; first N turns may be skipped entirely
`documentSequenceBySession` (Map) Per-session document ID sequence New session documents get IDs that continue from prior session sequence
`sessionIdentityBySession` (Map) Cached identity resolution per session Stale identity metadata may leak into new session context
`skipHindsightTurnBySession` (Map) Identity-skip reasons per session Old skip decisions persist; new session incorrectly skips retain
Hermes-side `_session_turns` buffer Accumulates turns before calling `retain()` Turns from old conversation are retained again in new session, causing duplicate memory entries

Steps to Reproduce

  1. Have Hindsight plugin active with `autoRetain: true`
  2. Have a multi-turn conversation that gets retained to Hindsight
  3. Run `/reset` in the agent (or `/new` — same code path)
  4. Continue a new, unrelated conversation
  5. Observe that previous turns are retained again under the new session (duplicate entries)
  6. Alternatively: observe turn counting is off because `turnCountBySession` never resets

Expected Behavior

When `/reset` fires, the Hindsight plugin should clear all session-scoped state, either by:

  • Subscribing to the `on_session_reset` hook and clearing its Maps there
  • Subscribing to `on_session_finalize` (which is also emitted by Hermes on full session end)
  • Providing a `reset()` / `clearSessionState()` method that Hermes calls on reset

Root Cause Analysis

The OpenClaw plugin architecture defines session boundary hooks (`on_session_reset`, `on_session_finalize`) but the Hindsight plugin never subscribes to them. The plugin only handles per-turn retain via `agent_end` and recall via `before_prompt_build`, with no concept of session lifecycle.

Additionally, `shutdown_memory_provider()` is only called on true session end (not on reset), so `on_session_end()` is never triggered either.

Environment

  • hindsight-openclaw: 0.6.6
  • @vectorize-io/hindsight-all: ^0.1.0
  • @vectorize-io/hindsight-client: ^0.5.0
  • Hermes Agent (OpenClaw-compatible)

Suggested Fix

In `hindsight-integrations/openclaw/src/index.ts`:

  1. Subscribe to `on_session_reset`:

```ts
api.on("on_session_reset", async (event: any, ctx?: PluginHookAgentContext) => {
const sessionKey = ctx?.sessionKey ?? event?.sessionKey;
if (sessionKey) {
turnCountBySession.delete(sessionKey);
documentSequenceBySession.delete(sessionKey);
sessionIdentityBySession.delete(sessionKey);
skipHindsightTurnBySession.delete(sessionKey);
}
});
```

  1. Also subscribe to `on_session_finalize` for proper cleanup on true session end.

  2. (Hermes Agent side) Consider calling `shutdown_memory_provider()` on reset as well, not only on true session end, so `on_session_end()` fires too.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions