Commit Graph

50 Commits

Author SHA1 Message Date
Gustavo Madeira Santana
e19a23520c fix: unify session maintenance and cron run pruning (#13083)
* fix: prune stale session entries, cap entry count, and rotate sessions.json

The sessions.json file grows unbounded over time. Every heartbeat tick (default: 30m)
triggers multiple full rewrites, and session keys from groups, threads, and DMs
accumulate indefinitely with large embedded objects (skillsSnapshot,
systemPromptReport). At >50MB the synchronous JSON parse blocks the event loop,
causing Telegram webhook timeouts and effectively taking the bot down.

Three mitigations, all running inside saveSessionStoreUnlocked() on every write:

1. Prune stale entries: remove entries with updatedAt older than 30 days
   (configurable via session.maintenance.pruneDays in openclaw.json)

2. Cap entry count: keep only the 500 most recently updated entries
   (configurable via session.maintenance.maxEntries). Entries without updatedAt
   are evicted first.

3. File rotation: if the existing sessions.json exceeds 10MB before a write,
   rename it to sessions.json.bak.{timestamp} and keep only the 3 most recent
   backups (configurable via session.maintenance.rotateBytes).

All three thresholds are configurable under session.maintenance in openclaw.json
with Zod validation. No env vars.

Existing tests updated to use Date.now() instead of epoch-relative timestamps
(1, 2, 3) that would be incorrectly pruned as stale.

27 new tests covering pruning, capping, rotation, and integration scenarios.

* feat: auto-prune expired cron run sessions (#12289)

Add TTL-based reaper for isolated cron run sessions that accumulate
indefinitely in sessions.json.

New config option:
  cron.sessionRetention: string | false  (default: '24h')

The reaper runs piggy-backed on the cron timer tick, self-throttled
to sweep at most every 5 minutes. It removes session entries matching
the pattern cron:<jobId>:run:<uuid> whose updatedAt + retention < now.

Design follows the Kubernetes ttlSecondsAfterFinished pattern:
- Sessions are persisted normally (observability/debugging)
- A periodic reaper prunes expired entries
- Configurable retention with sensible default
- Set to false to disable pruning entirely

Files changed:
- src/config/types.cron.ts: Add sessionRetention to CronConfig
- src/config/zod-schema.ts: Add Zod validation for sessionRetention
- src/cron/session-reaper.ts: New reaper module (sweepCronRunSessions)
- src/cron/session-reaper.test.ts: 12 tests covering all paths
- src/cron/service/state.ts: Add cronConfig/sessionStorePath to deps
- src/cron/service/timer.ts: Wire reaper into onTimer tick
- src/gateway/server-cron.ts: Pass config and session store path to deps

Closes #12289

* fix: sweep cron session stores per agent

* docs: add changelog for session maintenance (#13083) (thanks @skyfallsin, @Glucksberg)

* fix: add warn-only session maintenance mode

* fix: warn-only maintenance defaults to active session

* fix: deliver maintenance warnings to active session

* docs: add session maintenance examples

* fix: accept duration and size maintenance thresholds

* refactor: share cron run session key check

* fix: format issues and replace defaultRuntime.warn with console.warn

---------

Co-authored-by: Pradeep Elankumaran <pradeepe@gmail.com>
Co-authored-by: Glucksberg <markuscontasul@gmail.com>
Co-authored-by: max <40643627+quotentiroler@users.noreply.github.com>
Co-authored-by: quotentiroler <max.nussbaumer@maxhealth.tech>
2026-02-09 20:42:35 -08:00
Ayaan Zaidi
d85f0566a9 fix: tighten thread-clear and telegram retry guards 2026-02-09 08:59:21 +05:30
Ayaan Zaidi
d7bd68ff24 fix: recover telegram sends from stale thread ids 2026-02-09 08:59:21 +05:30
max
223eee0a20 refactor: unify peer kind to ChatType, rename dm to direct (#11881)
* fix: use .js extension for ESM imports of RoutePeerKind

The imports incorrectly used .ts extension which doesn't resolve
with moduleResolution: NodeNext. Changed to .js and added 'type'
import modifier.

* fix tsconfig

* refactor: unify peer kind to ChatType, rename dm to direct

- Replace RoutePeerKind with ChatType throughout codebase
- Change 'dm' literal values to 'direct' in routing/session keys
- Keep backward compat: normalizeChatType accepts 'dm' -> 'direct'
- Add ChatType export to plugin-sdk, deprecate RoutePeerKind
- Update session key parsing to accept both 'dm' and 'direct' markers
- Update all channel monitors and extensions to use ChatType

BREAKING CHANGE: Session keys now use 'direct' instead of 'dm'.
Existing 'dm' keys still work via backward compat layer.

* fix tests

* test: update session key expectations for dmdirect migration

- Fix test expectations to expect :direct: in generated output
- Add explicit backward compat test for normalizeChatType('dm')
- Keep input test data with :dm: keys to verify backward compat

* fix: accept legacy 'dm' in session key parsing for backward compat

getDmHistoryLimitFromSessionKey now accepts both :dm: and :direct:
to ensure old session keys continue to work correctly.

* test: add explicit backward compat tests for dmdirect migration

- session-key.test.ts: verify both :dm: and :direct: keys are valid
- getDmHistoryLimitFromSessionKey: verify both formats work

* feat: backward compat for resetByType.dm config key

* test: skip unix-path Nix tests on Windows
2026-02-09 09:20:52 +09:00
Seb Slight
db137dd65d fix(paths): respect OPENCLAW_HOME for all internal path resolution (#12091)
* fix(paths): respect OPENCLAW_HOME for all internal path resolution (#11995)

Add home-dir module (src/infra/home-dir.ts) that centralizes home
directory resolution with precedence: OPENCLAW_HOME > HOME > USERPROFILE > os.homedir().

Migrate all path-sensitive callsites: config IO, agent dirs, session
transcripts, pairing store, cron store, doctor, CLI profiles.

Add envHomedir() helper in config/paths.ts to reduce lambda noise.
Document OPENCLAW_HOME in docs/help/environment.md.

* fix(paths): handle OPENCLAW_HOME '~' fallback (#12091) (thanks @sebslight)

* docs: mention OPENCLAW_HOME in install and getting started (#12091) (thanks @sebslight)

* fix(status): show OPENCLAW_HOME in shortened paths (#12091) (thanks @sebslight)

* docs(changelog): clarify OPENCLAW_HOME and HOME precedence (#12091) (thanks @sebslight)
2026-02-08 16:20:13 -05:00
cpojer
f06dd8df06 chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
cpojer
5ceff756e1 chore: Enable "curly" rule to avoid single-statement if confusion/errors. 2026-01-31 16:19:20 +09:00
cpojer
15792b153f chore: Enable more lint rules, disable some that trigger a lot. Will clean up later. 2026-01-31 16:04:04 +09:00
Ayaan Zaidi
310eed825e fix: preserve delivery thread fallback (#4911) (thanks @yevhen) 2026-01-31 09:31:40 +05:30
Yevhen Bobrov
a642ca4ea8 Fix telegram threadId in deliveryContext 2026-01-31 09:31:40 +05:30
Peter Steinberger
9a7160786a refactor: rename to openclaw 2026-01-30 03:16:21 +01:00
Peter Steinberger
6d16a658e5 refactor: rename clawdbot to moltbot with legacy compat 2026-01-27 12:21:02 +00:00
Seb Slight
d4f60bf16a TTS: gate auto audio on inbound voice notes (#1667)
Co-authored-by: Sebastian <sebslight@gmail.com>
2026-01-25 04:35:20 +00:00
Peter Steinberger
4b6cdd1d3c fix: normalize session keys and outbound mirroring 2026-01-24 11:57:11 +00:00
Peter Steinberger
975f5a5284 fix: guard session store against array corruption 2026-01-24 04:51:46 +00:00
Echo
c415ccaed5 feat(sessions): add channelIdleMinutes config for per-channel session idle durations (#1353)
* feat(sessions): add channelIdleMinutes config for per-channel session idle durations

Add new `channelIdleMinutes` config option to allow different session idle
timeouts per channel. For example, Discord sessions can now be configured
to last 7 days (10080 minutes) while other channels use shorter defaults.

Config example:
  sessions:
    channelIdleMinutes:
      discord: 10080  # 7 days

The channel-specific idle is passed as idleMinutesOverride to the existing
resolveSessionResetPolicy, integrating cleanly with the new reset policy
architecture.

* fix

* feat: add per-channel session reset overrides (#1353) (thanks @cash-echo-bot)

---------

Co-authored-by: Cash Williams <cashwilliams@gmail.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-01-21 19:10:31 +00:00
Peter Steinberger
02ca148583 fix: preserve subagent thread routing (#1241)
Thanks @gnarco.

Co-authored-by: gnarco <gnarco@users.noreply.github.com>
2026-01-20 17:22:07 +00:00
Peter Steinberger
404c373153 feat: add agent targeting + reply overrides 2026-01-18 22:50:51 +00:00
Peter Steinberger
744d1329cb feat: make inbound envelopes configurable
Co-authored-by: Shiva Prasad <shiv19@users.noreply.github.com>
2026-01-18 18:50:37 +00:00
Peter Steinberger
f5c84768ff chore(format): oxfmt 2026-01-18 07:14:40 +00:00
Peter Steinberger
f86b24c511 refactor(session): centralize thread reset detection
Co-authored-by: Austin Mudd <austinm911@gmail.com>
2026-01-18 06:55:04 +00:00
Peter Steinberger
367826f6e4 feat(session): add daily reset policy
Co-authored-by: Austin Mudd <austinm911@gmail.com>
2026-01-18 06:37:37 +00:00
Peter Steinberger
8f7f7ee7dc feat: add /exec session overrides 2026-01-18 06:12:54 +00:00
Peter Steinberger
2dabce59ce feat(slash-commands): usage footer modes 2026-01-18 05:35:35 +00:00
Peter Steinberger
82e49af5a7 fix: resolve plugin tool meta typing 2026-01-18 04:24:16 +00:00
Peter Steinberger
0d9172d761 fix: persist session origin metadata 2026-01-18 03:41:51 +00:00
Peter Steinberger
5f22b68268 feat: add session origin metadata helpers 2026-01-18 02:42:11 +00:00
Peter Steinberger
34590d2144 feat: persist session origin metadata across connectors 2026-01-18 02:42:10 +00:00
Peter Steinberger
0e49dca53c feat: add experimental session memory source 2026-01-17 18:53:52 +00:00
Peter Steinberger
bbb71c9198 refactor: prune legacy group targets 2026-01-17 09:01:47 +00:00
Peter Steinberger
13b931c006 refactor: prune legacy group prefixes 2026-01-17 08:47:25 +00:00
Peter Steinberger
1f3a09b43b fix: persist deliveryContext on last-route updates
Co-authored-by: Adam Holt <mail@adamholt.co.nz>
2026-01-17 06:54:31 +00:00
Peter Steinberger
37a2eee837 refactor: drop legacy session store keys 2026-01-17 06:48:44 +00:00
Peter Steinberger
65a8a93854 fix: normalize delivery routing context
Co-authored-by: adam91holt <adam91holt@users.noreply.github.com>
2026-01-17 06:38:33 +00:00
Peter Steinberger
285ed8bac3 fix: sync delivery routing context
Co-authored-by: adam91holt <adam91holt@users.noreply.github.com>
2026-01-17 06:02:27 +00:00
Peter Steinberger
8b42902cee refactor: drop legacy room chatType 2026-01-17 05:46:40 +00:00
Peter Steinberger
f4f20c6762 refactor: normalize session route fields
Co-authored-by: adam91holt <adam91holt@users.noreply.github.com>
2026-01-17 05:29:06 +00:00
Peter Steinberger
a2b5b1f0cb refactor: normalize inbound context 2026-01-17 04:05:33 +00:00
Peter Steinberger
fdaeada3ec feat: mirror delivered outbound messages (#1031)
Co-authored-by: T Savo <TSavo@users.noreply.github.com>
2026-01-17 02:03:18 +00:00
Yurii Chukhlib
cf72b9db3c fix(sessions): preserve 0600 permissions on sessions.json writes 2026-01-16 23:14:33 +00:00
Peter Steinberger
b2b331230b feat: mac node exec policy + remote skills hot reload 2026-01-16 03:45:06 +00:00
Peter Steinberger
8c3cdba21c feat: sticky auth profile rotation + usage headers 2026-01-16 00:25:49 +00:00
void
e274b5a040 fix: heartbeat prompt + dedupe (#980) (thanks @voidserf)
- tighten default heartbeat prompt guidance
- suppress duplicate heartbeat alerts within 24h

Co-authored-by: void <voidserf@users.noreply.github.com>
2026-01-16 00:24:52 +00:00
Peter Steinberger
688a0ce439 refactor: harden session store updates
Co-authored-by: Tyler Yust <tyler6204@users.noreply.github.com>
2026-01-15 23:41:34 +00:00
Peter Steinberger
725a6b71dc feat: add matrix channel plugin 2026-01-15 08:40:37 +00:00
Peter Steinberger
1c96477686 fix: harden session cache + heartbeat restore
Co-authored-by: Ronak Guliani <ronak-guliani@users.noreply.github.com>
2026-01-15 07:07:12 +00:00
Peter Steinberger
2b4a68e276 feat: load channel plugins 2026-01-15 02:42:44 +00:00
Peter Steinberger
bcde09ae91 feat: add /context prompt breakdown 2026-01-15 01:06:35 +00:00
Peter Steinberger
c379191f80 chore: migrate to oxlint and oxfmt
Co-authored-by: Christoph Nakazawa <christoph.pojer@gmail.com>
2026-01-14 15:02:19 +00:00
Peter Steinberger
bcbfb357be refactor(src): split oversized modules 2026-01-14 01:17:56 +00:00