You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: auto-stop idle sessions and preserve git repo state across restarts (#651)
## Summary
- Add configurable inactivity timeout that automatically stops idle
sessions, reclaiming cluster resources
- Preserve git repo state (local branches, uncommitted/staged changes)
to S3 on pod shutdown and restore on resume, so work is never lost when
pods are stopped or recycled
- Three-tier timeout resolution: session-level `spec.inactivityTimeout`
> project-level `ProjectSettings.spec.inactivityTimeoutSeconds` >
default 24h; set to 0 to disable
## What changed
**CRDs:**
- `AgenticSession`: added `spec.inactivityTimeout`,
`status.lastActivityTime`, `status.stoppedReason`
- `ProjectSettings`: added `spec.inactivityTimeoutSeconds`
**Backend:**
- Debounced activity tracking in `agui_proxy.go` updates
`status.lastActivityTime` on AG-UI events (RUN_STARTED,
TEXT_MESSAGE_START, TEXT_MESSAGE_CONTENT, TOOL_CALL_START)
- `parseStatus()` extracts new status fields for API responses
**Operator:**
- New `inactivity.go` with `shouldAutoStop()`,
`resolveInactivityTimeout()`, `triggerInactivityStop()`, and
per-namespace ProjectSettings cache
- `monitorPod()` checks inactivity on each tick; re-reads CR before
stopping to avoid races
- `reconciler.go` reads `stop-reason` annotation to set
`status.stoppedReason` and condition reason
**Frontend:**
- "Stopped (idle)" badge on session cards
- Inactivity alert banner in session header (full/actions-only modes)
- "This session was automatically stopped after being idle" message in
hibernated section
**State-sync:**
- `sync.sh`: on SIGTERM, creates git bundles, uncommitted/staged
patches, and metadata.json per repo
- `hydrate.sh`: restores repos from bundles, checks out saved branch,
applies patches (best-effort)
- `TerminationGracePeriodSeconds` increased from 30 to 60
**Tests:**
- `inactivity_test.go`: 16 tests covering `shouldAutoStop`,
`resolveInactivityTimeout`, `triggerInactivityStop`,
`getProjectInactivityTimeout`
- `agui_proxy_test.go`: 18 subtests for `isActivityEvent`
## Test plan
- [x] Operator and backend unit tests pass (`go test -race ./...`)
- [x] Frontend builds with zero errors/warnings (`npm run build`)
- [x] Create session with 180s inactivity timeout, verify auto-stop
after idle period
- [x] Verify `status.stoppedReason=inactivity` and "Stopped (idle)"
badge in UI
- [x] Verify git repo with local branch + uncommitted changes survives
stop/resume cycle
- [x] Verify `inactivityTimeout: 0` disables auto-stop
- [x] Verify sessions without explicit timeout fall back to project
settings, then 24h default
Fixes: RHOAIENG-49782
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
0 commit comments