Skip to content

fix: cron and local DMs reach an open Desktop Bot Chat - #105442

Merged
teknium1 merged 2 commits into
mainfrom
hermes/hermes-ae078a6a
Sep 7, 2026
Merged

teknium1 merged 2 commits into
mainfrom
hermes/hermes-ae078a6a

Conversation

@teknium1

@teknium1 teknium1 commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Cron output and local agent DMs now reach a canonical Bot Chat that stays open in Desktop, without starting a second transcript writer.

Changes

  • Reuse the receiving backend's existing notification poller and normal prompt-turn admission: idle deliveries start immediately; busy deliveries wait until the running turn and queued human prompts finish.
  • Add durable cross-process ingress only, with stable IDs, conflicting-payload rejection, ordered admission and retained terminal receipts. No second execution loop, steering injection or lease release.
  • Require explicit live-consumer capability on lease acquisition and transfer; pin profile home, lease/live identity and compression lineage.
  • Preserve ambiguous/started delivery evidence instead of falling back to CLI or blindly replaying after restart. Unowned chats retain their CLI delivery lane.
  • Report cron admission as delivery_queued / delivery_outcome=queued, not completed delivery or failure. Document that historical job status records admission; terminal receipts are authoritative.

Root cause: the separate cron/DM CLI tried to resume a session whose valid lease belonged to a permanently open Desktop backend.

Validation

Live repro: on main 2237be355906fbe6065ce1815711eee52b2d646e, real isolated Electron → production serve backend plus separate cron helper/CLI returned SESSION_NOT_OWNED for both idle and busy owners. After the fix, idle cron, busy cron, local DM runner and mounted-chat cron each settled exactly once without releasing the same owner lease.

Check Result
Native Desktop IO Real Electron main/preload/renderer, actual Bot Chat row and composer, real gateway client and backend; separate producer processes
Busy queue Provider request held; incoming cron stayed pending; queued human turn ran before imported delivery
Authoritative transcript 4 settled receipts, each input once; 18 messages matching live transcript
Cache and alternation 9 primary inference requests; prior message prefixes, system prompt and tool schemas unchanged; strict user/assistant alternation
Final focused directory run scripts/run_tests.sh tests/cron/ tests/tui_gateway/ tests/tools/test_daytona_environment.py tests/tools/test_web_tools_config.py tests/tools/test_bot_live_owner_delivery.py tests/tools/test_bot_mode_dm.py: 2422 passed, 0 failed, 3 skipped, 224 files
Static gates Ruff, Windows footguns, compatibility pointers, subprocess stdin and diff whitespace passed
Independent review Fixed known-preprocessing-rejection receipt hole and clock-dependent FIFO ordering; regression probes failed before and passed after

Inference was a deterministic loopback wire stub, not a real-model quality/cost/cache-hit test. No paid model requests. Private native test artifacts and request captures are not published.

The broader five-directory run was exercised. Its introduced assertion/signature drift and two missing optional SDKs were corrected and rerun green above. One unrelated existing native sort --compress-program marker assertion in tests/tools/test_execution_flag_detection.py fails identically on the pristine main snapshot on this host; this PR does not change that file or claim a fully green broad suite.

Credit and scope

Adapted @FalconOrtiz's #101564 owner-mailbox proposal onto current topical modules, preserving contributor authorship. Credits earlier owner-routing work by @fangliquanflq (#100544) and durable ingress work by @686f6c61 (#100319). The stale facade hunks and expiring protocol were rebuilt rather than copied wholesale. #103437's process-local registry and #102659's bounded ownership retries do not cover this separate-process permanent-owner case.

Queued ingress is fenced to its admitted live owner. If that owner exits before consumption, the record remains inspectable rather than being silently adopted by a new session; claimed/failed/cancelled turns are never automatically replayed. Older running backends need restarting after upgrade to advertise support.

Fixes #99956
Fixes #101060
Fixes #103030

Infographic

Bot Chat delivery through the existing owner

FalconOrtiz and others added 2 commits September 7, 2026 16:41
Adapt FalconOrtiz's owner-mailbox proposal from #101564 onto the current
notification poller and topical modules. The durable mailbox is cross-process
ingress only: the existing owner admits its normal prompt turn after the
current turn and human FIFO clear. Retain immutable receipts, stable admission
identities, capability and lease fencing, compression lineage, and disable
blind recovery replay of imported turns.

The original stale server hunks and expiring receipt protocol were rebuilt
rather than cherry-picked: the current facade decomposition and durable busy
admission contract differ. Credit the earlier owner-mailbox work in #100544
and durable producer work in #100319.

Co-authored-by: fangliquanflq <fangliquan@qq.com>
Co-authored-by: 686f6c61 <github@00b.tech>
Route local producers to durable owner ingress before attempting the unowned
CLI lane. Preserve per-run/per-message IDs and receipt-first retry handling;
never fall back after ambiguous admission. Report cron admission as queued,
not completed or failed, in job status, the execution ledger and CLI/tool UX.

Native isolated Electron validation reproduces SESSION_NOT_OWNED on main for
both idle and busy owners. Fixed owner consumes idle cron, busy cron, local
DM and mounted-chat cron exactly once, keeps its lease, yields to queued
human input, and preserves the prior model-request prefix and tool schema.
Inference alone used a deterministic loopback wire stub; no paid model call.
@github-actions

github-actions Bot commented Sep 7, 2026 •

Copy link
Copy Markdown

૮ >ﻌ< ა ci review

ran on e8125a5 — fix: cron and local DMs reach an open Desktop Bot Chat

⚠️ Warnings

OSV vulnerability scan · View job

28 known vulnerabilities found in pinned dependencies.

How to fix:

Review the findings in the Security tab. Update the affected dependencies if a patched version is available.


debug info

CI timings

CI timings · View report · View job

Wall time 5m16s vs 5m26s (-3.1%). 5 job(s) slower, 9 faster, 1 unchanged.

  • Docs Site / docs-site-checks: -11.0s
  • OS-specific tests / Windows-only tests: -8.0s
  • OS-specific tests / macOS-only tests: +7.0s
  • Check no case-colliding filenames / check-case-collisions: -5.0s
  • Python lints / ruff enforcement (blocking): -3.0s

@alt-glitch alt-glitch added type/bug Something isn't working P1 High — major feature broken, no workaround comp/cron Cron scheduler and job management comp/tui Terminal UI (ui-tui/ + tui_gateway/) comp/desktop Electron desktop app (apps/desktop/*) comp/tools Tool registry, model_tools, toolsets sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Sep 7, 2026
@teknium1
teknium1 merged commit 5280fe9 into main Sep 7, 2026
40 checks passed
@teknium1
teknium1 deleted the hermes/hermes-ae078a6a branch September 7, 2026 23:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cron Cron scheduler and job management comp/desktop Electron desktop app (apps/desktop/*) comp/tools Tool registry, model_tools, toolsets comp/tui Terminal UI (ui-tui/ + tui_gateway/) P1 High — major feature broken, no workaround sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

3 participants