Skip to content

[Bug] Redundant session completion notifications due to lack of session ID. #22

Description

@cylixlee

Description

When open-mem falls back to the OpenCode session bridge for AI compression (i.e., no direct API key configured), it creates a background session titled [open-mem] AI compression via sdk.session.create() without specifying a parentID. This background session is treated by OpenCode as a top-level session rather than a subagent.

If the user also has a session-notification plugin (e.g., mohak34/opencode-notifier) that triggers on session.idle events, every AI compression call on this background session triggers a false "session completed" notification. This happens repeatedly:

  1. After every user turn (when session.idle triggers processBatch())
  2. Every 30 seconds (the periodic queue timer calls processBatch())
  3. On session completion (when summarizeSession() runs)

Steps to Reproduce

  1. Install open-mem without configuring a direct API key (so it falls back to the OpenCode bridge)
  2. Install opencode-notifier (or any plugin that notifies on session.idle for non-subagent sessions)
  3. Start OpenCode, send a message, wait for the agent to finish
  4. Observe: a "session completed" notification appears after each turn
  5. Wait 30+ seconds without doing anything
  6. Observe: another "session completed" notification appears every ~30 seconds

Expected Behavior

Background AI compression sessions should be invisible to session-lifecycle notification plugins. They should be created as subagent/child sessions (with parentID), so that:

  • Notifiers correctly classify them as subagent_complete (silent by default)
  • They don't generate false "session started" / "session completed" events

Actual Behavior

Every busy→idle cycle of the [open-mem] AI compression session produces a top-level session.idle event. Notifiers see isChild: false (because no parentID was set) and fire a full "complete" notification with sound and popup.

Root Cause

src/ai/opencode-bridge.ts line 46–48:

const result = await sdk.session.create({
    body: { title: "[open-mem] AI compression" },
});

The body does not include parentID, so the session is created as a top-level session.

Suggested Fix

Pass a parentID when creating the background session. The challenge is that getOrCreateSession() may be called from daemon/periodic-timer contexts where there is no active "current" session. Consider:

  1. Accepting an optional parentID parameter in bridgeGenerateText() / getOrCreateSession()
  2. Capturing the current session ID from the event hook context (e.g., in session.idle and session.completed handlers) and threading it into the queue processor → compressor → bridge chain
  3. Alternatively, falling back to a daemon session or omitting parentID only when no parent context is available

Environment

  • open-mem version: v0.14.2
  • Bun version: 1.3.14
  • OS: Windows 11 25H2 x86_64
  • OpenCode version: 1.17.4

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions