openclaw - ✅(Solved) Fix [Feature]: Adaptive session reset mode — daily reset gated by idle time (AND logic) [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#43738Fetched 2026-04-08 00:17:39
View on GitHub
Comments
1
Participants
2
Timeline
6
Reactions
0
Participants
Timeline (top)
referenced ×3cross-referenced ×2commented ×1

A new mode: "adaptive" session reset that requires BOTH atHour to have passed AND the session to have been idle for idleMinutes before resetting. Currently when both are configured, whichever fires first wins (OR logic).

Root Cause

A new mode: "adaptive" session reset that requires BOTH atHour to have passed AND the session to have been idle for idleMinutes before resetting. Currently when both are configured, whichever fires first wins (OR logic).

Fix Action

Fix / Workaround

For users who regularly cross the atHour boundary while active (early birds, night owls, cross-timezone users), the only workaround is bumping atHour later — which shifts the problem rather than solving it.

PR fix notes

PR #44489: feat(sessions): add adaptive reset mode with AND logic (atHour + idleMinutes)

Description (problem / solution / changelog)

Summary

Adds mode: "adaptive" to SessionResetMode. Unlike the existing daily + idleMinutes combination (OR logic — whichever fires first resets), adaptive mode requires both conditions before resetting:

  1. atHour has passed (same daily boundary check as mode: "daily")
  2. Session has been idle for at least idleMinutes

This allows active conversations that cross the atHour boundary to survive until the user goes quiet, preventing mid-workflow context loss.

Config example:

{
  session: {
    reset: {
      mode: "adaptive",
      atHour: 4,
      idleMinutes: 120
    }
  }
}

Works naturally with resetByType and resetByChannel overrides — no additional wiring needed as they flow through the same resolveSessionResetPolicy function.

Closes #43738


Change Type

  • Feature

Scope

  • Gateway

Root Cause / Code Path

All reset logic lives in src/config/sessions/reset.ts:

  • resolveSessionResetPolicy() — reads config, resolves mode/atHour/idleMinutes into policy
  • evaluateSessionFreshness() — core decision: computes staleDaily and staleIdle, returns fresh

The existing daily + idleMinutes combination uses OR logic (staleDaily || staleIdle). adaptive branches to AND (staleDaily && staleIdle).

Changes (3 files, ~15 lines):

  1. src/config/sessions/reset.ts — add "adaptive" to SessionResetMode, compute dailyResetAt for adaptive mode, branch freshness logic
  2. src/config/types.base.ts — add "adaptive" to the exported SessionResetMode union
  3. src/config/sessions/sessions.test.ts — 4 new tests for adaptive mode covering: both conditions met (resets), only daily passed (fresh), only idle passed (fresh), return values

Behavior Changes

  • New config value mode: "adaptive" is accepted (previously unknown modes would fall through)
  • Existing mode: "daily" and mode: "idle" behavior is unchanged
  • When mode: "adaptive" is set without idleMinutes, defaults to DEFAULT_IDLE_MINUTES (same as mode: "idle")

Security Impact

None — config parsing only, no network, no file access, no token handling.


Alternatives Considered

See #43738 for full analysis. Key alternatives:

  • mode: "daily" with later atHour: shifts the problem, doesn't solve it
  • mode: "idle" only: loses daily cadence, sessions can grow unbounded
  • Current daily+idle (OR): makes resets more aggressive, not less
  • before_reset hook (#21155): programmatic, shifts logic to consumers

Human Verification

Tested against installed gateway (dist/sessions-*.js) — compiled logic matches source changes. Unit tests cover the three meaningful state combinations.

Changed files

  • src/auto-reply/reply/session.ts (modified, +5/-0)
  • src/config/schema.help.ts (modified, +1/-1)
  • src/config/sessions/reset.ts (modified, +10/-4)
  • src/config/sessions/sessions.test.ts (modified, +51/-1)
  • src/config/types.base.ts (modified, +1/-1)
  • src/config/zod-schema.session.ts (modified, +1/-1)
  • src/plugins/types.ts (modified, +1/-0)

Code Example

{
  session: {
    reset: {
      mode: "adaptive",
      atHour: 4,
      idleMinutes: 120
    }
  }
}

---

{
  session: {
    resetByType: {
      direct: { mode: "adaptive", atHour: 4, idleMinutes: 120 },
      group: { mode: "idle", idleMinutes: 10080 }
    }
  }
}
RAW_BUFFERClick to expand / collapse

Summary

A new mode: "adaptive" session reset that requires BOTH atHour to have passed AND the session to have been idle for idleMinutes before resetting. Currently when both are configured, whichever fires first wins (OR logic).

Problem to solve

Current reset modes are either time-based (daily — hard reset at atHour) or activity-based (idle — reset after N minutes of silence). When both are configured, the docs state: "whichever expires first wins" — OR logic.

This means an active late-night or early-morning conversation gets cut on the next message after atHour, even if the user was chatting minutes ago. There is no way to say "reset daily, but not if we're mid-conversation."

For users who regularly cross the atHour boundary while active (early birds, night owls, cross-timezone users), the only workaround is bumping atHour later — which shifts the problem rather than solving it.

Proposed solution

A new reset mode that combines daily and idle with AND logic:

{
  session: {
    reset: {
      mode: "adaptive",
      atHour: 4,
      idleMinutes: 120
    }
  }
}

Behavior: session resets on the first inbound message where atHour has passed (same as daily) and the session has been idle for at least idleMinutes. An active conversation crossing atHour survives until the user goes quiet for the configured idle window.

This would also work naturally with resetByType:

{
  session: {
    resetByType: {
      direct: { mode: "adaptive", atHour: 4, idleMinutes: 120 },
      group: { mode: "idle", idleMinutes: 10080 }
    }
  }
}

Optional stretch: a "soft reset" variant that injects a system message ("session continued from yesterday") instead of clearing history — giving the agent awareness that the daily boundary passed without losing context.

Alternatives considered

  • mode: "daily" with later atHour: Shifts the cutoff but doesn't solve it — any fixed hour will catch someone mid-conversation eventually.
  • mode: "idle" only: Loses the daily cadence entirely. Sessions could persist for weeks if there's regular activity, growing unbounded.
  • Current daily+idle (OR): Makes resets more aggressive, not less. Adding idleMinutes to a daily config means the session resets sooner, not later.
  • mode: "off" (#29544 / #23505): Disables auto-reset entirely, requiring manual /new. Too much burden on the user.
  • before_reset guard hook (#21155): Programmatic cancellation could theoretically implement AND logic, but requires hook infrastructure and shifts the logic to consumers instead of the config layer.

Impact

Affected: Users who regularly cross the atHour boundary while actively chatting (early morning / late night users, cross-timezone setups) Severity: Medium — conversation context is lost mid-workflow, requiring re-establishing context in a new session Frequency: Daily for affected users Consequence: Context loss at the worst possible time — when the user is actively engaged

Evidence/examples

Related but distinct from:

  • #32109 / PR #32221 — changes default mode per session type (daily to idle for groups), does not combine conditions
  • #29544 / #23505 — mode: "off" (no auto-reset), opposite extreme
  • #20633 — mode: "on-demand" (agent-driven), manual not automatic
  • #42867 — turn-count TTL with heartbeat-aware staleness, different mechanism
  • #21155 — before_reset guard hook, programmatic not config-based

No existing issue or PR proposes AND logic for combining daily and idle conditions.

Additional information

The name "adaptive" reflects that the reset adapts to user activity patterns rather than enforcing a rigid boundary. It reuses both existing config fields (atHour, idleMinutes) with no new parameters — the only new concept is the combination logic.

extent analysis

Fix Plan

To implement the new mode: "adaptive" session reset, follow these steps:

  • Update the session reset configuration to support the new mode:
{
  session: {
    reset: {
      mode: "adaptive",
      atHour: 4,
      idleMinutes: 120
    }
  }
}
  • Modify the session reset logic to use AND logic for combining daily and idle conditions:
if (session.reset.mode === 'adaptive') {
  const hasPassedAtHour = getCurrentHour() >= session.reset.atHour;
  const hasBeenIdle = getSessionIdleTime() >= session.reset.idleMinutes;
  if (hasPassedAtHour && hasBeenIdle) {
    // Reset the session
  }
}
  • Update the resetByType configuration to support the new mode:
{
  session: {
    resetByType: {
      direct: { mode: "adaptive", atHour: 4, idleMinutes: 120 },
      group: { mode: "idle", idleMinutes: 10080 }
    }
  }
}
  • Implement a "soft reset" variant that injects a system message instead of clearing history (optional):
if (session.reset.mode === 'adaptive' && session.reset.softReset) {
  const systemMessage = 'Session continued from yesterday';
  // Inject the system message into the conversation
}

Verification

To verify that the fix worked, test the following scenarios:

  • A session that crosses the atHour boundary while active should not reset until the user has been idle for the configured idleMinutes.
  • A session that has been idle for the configured idleMinutes should reset on the first inbound message after the atHour boundary has passed.
  • The "soft reset" variant should inject a system message into the conversation instead of clearing history.

Extra Tips

  • Make sure to update the documentation to reflect the new mode: "adaptive" and its behavior.
  • Consider adding logging or monitoring to track the number of sessions that are reset using the new mode.
  • Review the existing issues and PRs related to session reset to ensure that this fix does not introduce any regressions.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix [Feature]: Adaptive session reset mode — daily reset gated by idle time (AND logic) [1 pull requests, 1 comments, 2 participants]