Conversation
helix4u
marked this pull request as ready for review
August 28, 2026 00:35
This was referenced Aug 28, 2026
perf(serve): move Desktop runtime services after bind — verified local-only deferral, with 503 guard for transient plugin 404s.
|
Collaborator
Author
teknium1
added a commit
that referenced
this pull request
Sep 2, 2026
…y imports the SDK `cmd_dashboard` started the background MCP discovery thread before importing `hermes_cli.web_server`. The thread's first act is the ~350ms `mcp` SDK import, which holds the GIL against the main thread's own web_server import, so the HERMES_BACKEND_READY sentinel — and every renderer paint behind it — moved ~300ms later on every Desktop cold start with any MCP server configured. Desktop `serve` (headless + HERMES_DESKTOP=1) now arms discovery one second after the sentinel instead. Starting it AT the bind was measured to give back most of the gain (the renderer's WebSocket connect + first hydration reads contend on the same loop). An agent build inside that window pulls the deferred start forward itself via `wait_for_mcp_discovery`, so the bounded join and the late-binding tool refresh behave exactly as before. Dashboard and non-Desktop `serve` keep the eager pre-import ordering. Minimal reimplementation of the MCP-deferral slice of #96751 by @helix4u; the plugin-route deferral / 503 middleware / cron-after-bind slices were measured at ~0-10ms each and are not taken. Co-authored-by: Gille <4317663+helix4u@users.noreply.github.com>
Collaborator
|
Thanks — the measured win in this PR (the mcp SDK import on the discovery thread holding the GIL during web_server import) landed on main via #101298 as a minimal slice with you co-authored: discovery armed after bind, wait_for_mcp_discovery pulls it forward. Real Desktop cold start READY 1667→1397ms. The other service moves measured no gain so were left out. Closing in favor of the merged slice. |
melon-xf
added a commit
to melon-xf/hermes-agent
that referenced
this pull request
Sep 3, 2026
…y imports the SDK `cmd_dashboard` started the background MCP discovery thread before importing `hermes_cli.web_server`. The thread's first act is the ~350ms `mcp` SDK import, which holds the GIL against the main thread's own web_server import, so the HERMES_BACKEND_READY sentinel — and every renderer paint behind it — moved ~300ms later on every Desktop cold start with any MCP server configured. Desktop `serve` (headless + HERMES_DESKTOP=1) now arms discovery one second after the sentinel instead. Starting it AT the bind was measured to give back most of the gain (the renderer's WebSocket connect + first hydration reads contend on the same loop). An agent build inside that window pulls the deferred start forward itself via `wait_for_mcp_discovery`, so the bounded join and the late-binding tool refresh behave exactly as before. Dashboard and non-Desktop `serve` keep the eager pre-import ordering. Minimal reimplementation of the MCP-deferral slice of NousResearch#96751 by @helix4u; the plugin-route deferral / 503 middleware / cron-after-bind slices were measured at ~0-10ms each and are not taken. Co-authored-by: Gille <4317663+helix4u@users.noreply.github.com>
github-actions Bot
pushed a commit
to RecursiveIntell/Ares
that referenced
this pull request
Sep 8, 2026
…y imports the SDK `cmd_dashboard` started the background MCP discovery thread before importing `hermes_cli.web_server`. The thread's first act is the ~350ms `mcp` SDK import, which holds the GIL against the main thread's own web_server import, so the HERMES_BACKEND_READY sentinel — and every renderer paint behind it — moved ~300ms later on every Desktop cold start with any MCP server configured. Desktop `serve` (headless + HERMES_DESKTOP=1) now arms discovery one second after the sentinel instead. Starting it AT the bind was measured to give back most of the gain (the renderer's WebSocket connect + first hydration reads contend on the same loop). An agent build inside that window pulls the deferred start forward itself via `wait_for_mcp_discovery`, so the bounded join and the late-binding tool refresh behave exactly as before. Dashboard and non-Desktop `serve` keep the eager pre-import ordering. Minimal reimplementation of the MCP-deferral slice of NousResearch#96751 by @helix4u; the plugin-route deferral / 503 middleware / cron-after-bind slices were measured at ~0-10ms each and are not taken. Co-authored-by: Gille <4317663+helix4u@users.noreply.github.com> (cherry picked from commit 4155ea9)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

What does this PR do?
The packaged Desktop only needs its authenticated loopback
hermes servesocket before the renderer can connect and paint, but agent plugin discovery, plugin API loading, MCP startup, cron initialization, and orphan-gateway cleanup currently run ahead of that ready point.This moves those Desktop-only runtime services behind the bound-socket event. The optimization is deliberately unavailable to ordinary Dashboard launches, non-headless serves, non-loopback binds, non-Desktop processes, or any configuration with a public dashboard URL, because those paths may require plugin-provided authentication before bind.
Plugin API requests arriving during the short deferred window wait for route mounting instead of receiving a transient 404. Agent construction continues to use the existing plugin and MCP readiness gates before snapshotting tools.
Desktop performance series
This change is one independently reviewable layer of the same Desktop startup and first-interaction performance pass.
hermes serveentry path.The three Python backend PRs share startup files but solve separate stages. Recommended landing order is #96749, then #96750, then #96751, rebasing the next PR only after the preceding one lands. #97032 is an independently reviewable Electron ordering change. The remaining renderer and Bot Mode PRs can also land independently; their effects compose without making cached state authoritative.
This PR owns the backend readiness boundary: the verified local Desktop socket binds before nonessential runtime services finish loading.
Related Issue
N/A
Type of Change
Changes Made
How to Test
scripts/run_tests.sh tests/hermes_cli/test_desktop_post_bind_runtime_discovery.py tests/hermes_cli/test_plugin_api_compat.py tests/hermes_cli/test_web_server_cron_profiles.py tests/hermes_cli/test_dashboard_auth_plugin_hook.py -q -j 4.scripts/run_tests.sh tests/hermes_cli/test_web_server_boot_handshake.py tests/tui_gateway/test_cold_start_gil_stall.py tests/hermes_cli/test_windows_gateway_cold_start_desktop_lifecycle.py -q -j 4.Checklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passDocumentation & Housekeeping
docs/, docstrings) — or N/Acli-config.yaml.exampleif I added/changed config keys — or N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — or N/AScreenshots / Logs
Focused results: 66 tests passed across the two explicit groups.