Skip to content

fix(scheduler): treat /api/email/unread-state as passive UI poll - #6009

Draft
michaelxer wants to merge 1 commit into
odysseus-dev:devfrom
michaelxer:michaelxer/fix-email-unread-state-passive-5981-20260812
Draft

fix(scheduler): treat /api/email/unread-state as passive UI poll#6009
michaelxer wants to merge 1 commit into
odysseus-dev:devfrom
michaelxer:michaelxer/fix-email-unread-state-passive-5981-20260812

Conversation

@michaelxer

Copy link
Copy Markdown
Contributor

Summary

With the web UI open, scheduled/background agent runs were being aborted within about a minute and logged as Stopped by user, even though no real user interaction happened. The idle poll GET /api/email/unread-state was treated as foreground activity by _InteractiveActivityMiddleware, which calls stop_background_tasks_for_foreground(). Its sibling GET /api/email/urgency-state was already on the passive exact-path list; unread-state was missing.

This PR adds /api/email/unread-state to _PASSIVE_EXACT_PATHS in src/interactive_gate.py so the UI timer poll no longer pre-empts background work, and adds focused regression tests for the passive/interactive path classification.

Target branch

  • This PR targets dev, not main.

Linked Issue

Fixes #5981

Type of Change

  • Bug fix (non-breaking — fixes a confirmed issue)
  • New feature (non-breaking — adds new behaviour)
  • Breaking change (changes or removes existing behaviour)
  • Refactor / cleanup (behaviour unchanged)
  • Documentation only
  • CI / tooling / configuration

What changed

  1. src/interactive_gate.py: add /api/email/unread-state next to /api/email/urgency-state in _PASSIVE_EXACT_PATHS.
  2. tests/test_interactive_gate_passive_paths.py: assert unread-state and urgency-state are passive; real interactive paths still track; OPTIONS still untracked.

No change to the foreground-gate design itself — only the passive allowlist for idle email polls.

How to Test

python -m pytest tests/test_interactive_gate_passive_paths.py -q
# 3 passed
python -m py_compile src/interactive_gate.py tests/test_interactive_gate_passive_paths.py

Manual (with web UI open):

  1. Create a scheduled agent task that runs longer than ~60s.
  2. Leave the Odysseus UI open so it polls /api/email/unread-state.
  3. Force-run the task.
  4. Expect the run to complete (or fail for real reasons), not abort as Stopped by user from foreground request GET /api/email/unread-state.

Checklist

Visual / UI changes

None — backend gate classification only.

Limitations / notes

  • Secondary suggestion from the issue (clearer abort message than Stopped by user) is intentionally out of scope here so the PR stays one-line + tests.

@github-actions github-actions Bot added the ready for review Description complete — ready for maintainer review label Aug 12, 2026
Background scheduled agent runs were aborted as "Stopped by user" when
the web UI was merely open, because the idle /api/email/unread-state
poll was counted as foreground activity while its sibling
/api/email/urgency-state was already excluded.

Fixes odysseus-dev#5981
@michaelxer
michaelxer force-pushed the michaelxer/fix-email-unread-state-passive-5981-20260812 branch from 8218ad9 to 8be5784 Compare August 12, 2026 17:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready for review Description complete — ready for maintainer review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Scheduled/background agent runs are cancelled by the UI's own idle poll (/api/email/unread-state), logged as "Stopped by user"

1 participant