fix(gateway): relay semantic thread rename — register eagerly, poll send-result feedback at fire time - #75581
Merged
Conversation
…end-result feedback at fire time Staging re-test (2026-07-31, post-74482 image roll): auto-created threads still stuck on their initial titles; connector telemetry shows zero thread_rename ops. Root cause is an ordering flaw in the 74482 consume path: BOTH the title-callback registration gate and the schedule gate read the send-result feedback cache (_relay_auto_thread_info) — but registration runs BEFORE delivery on the non-streaming lane, and the auto-title thread races delivery even when registration survives. The cache read can only succeed AFTER the connector answers the send, so the rename lane deterministically disqualified itself on the title turn. Fix — decide shape early, facts late: - New _is_relay_discord_channel_lane: SHAPE-only predicate (relay Discord channel event, no thread) used by the registration and schedule gates; no cache read before delivery. - _rename_discord_auto_thread_for_session_title: on the relay lane, poll the adapter's feedback cache (0.5s ticks, ≤10s) — delivery is typically right behind the title. True miss (connector didn't auto-thread: policy off, DM, send failed) no-ops exactly as before. Tests: shape-gate matrix; late-arriving feedback -> rename fires with only_if_current_name guard; never-arriving feedback -> no-op. Relay suite 174 passed.
Contributor
૮ >ﻌ< ა ci reviewran on 0672c8f ℹ️ InfoDesktop E2E visual evidence · View test artifacts · View job3 visual diffs. inline evidence is publishing... |
benbarclay
added a commit
that referenced
this pull request
Aug 1, 2026
…ename + trace logs (#75912) Live staging (2026-08-01): relay semantic thread rename still declined silently despite both #74482 and #75581 deployed — thread kept its initial-words name, session title generated fine. Root cause is the no-clobber guard string mismatch (see paired gateway-gateway PR): the gateway can't reproduce the thread's initial name byte-for-byte, so the connector's only_if_current_name check always failed. - relay rename lane now passes prefer_connector_created=True instead of the fragile initial-name string; the connector resolves the guard from its own created-name memory. Native-marker lane keeps the legacy only_if_current_name string (source carries the real initial name). - rename_thread: prefer_connector_created param -> only_if_connector_created on the wire, precedence over the legacy string. - INFO logs at rename dispatch (thread/lane/new_title) and result (applied=bool): the whole failure hunt needed telemetry the gateway never emitted — this makes the outcome visible in fly logs. Tests: connector-guard wire shape + precedence over legacy string; the title-turn race test updated to assert the connector-owned guard. Relay suite 149 passed; ruff + footguns clean.
bbasketballer75
added a commit
to bbasketballer75/hermes-agent
that referenced
this pull request
Aug 10, 2026
The memo was keyed on (path, st_mtime_ns), so an edit to honcho.json landing inside one mtime tick on a coarse-mtime filesystem kept serving the previously parsed identity config. Add st_size to the key — it comes from the single stat() call the memo already makes, so any same-tick rewrite that changes the file's size is now detected at zero added I/O on this hot path (it feeds the per-turn agent-cache signature). Deliberately NOT content-hashed. An equal-size rewrite inside one mtime tick can still reuse stale parsed state for one cache generation; that edge is vanishingly rare and self-heals on the next change. Hashing the file on every lookup would defeat the memo's no-I/O purpose — this is the exact design the maintainer resolution on NousResearch#46385 declined, naming st_size as the right-shaped discriminator. A test pins the documented tradeoff so a future change that silently adds per-lookup I/O surfaces as a deliberate decision rather than an accident. Tests cover: same-mtime size-changing rewrite invalidates (verified to fail against the old key), identical stat reuses the memo without re-parsing, the equal-size edge stays memoized by design, and stat failure still returns a parsed config. Supersedes the earlier content-hash version of this branch, which also accidentally reverted NousResearch#75581's relay rename behavior via a whole-file checkout across divergent bases — this rewrite touches only the memo.
randlee
pushed a commit
to randlee/hermes-agent
that referenced
this pull request
Aug 11, 2026
…end-result feedback at fire time (NousResearch#75581) Staging re-test (2026-07-31, post-74482 image roll): auto-created threads still stuck on their initial titles; connector telemetry shows zero thread_rename ops. Root cause is an ordering flaw in the 74482 consume path: BOTH the title-callback registration gate and the schedule gate read the send-result feedback cache (_relay_auto_thread_info) — but registration runs BEFORE delivery on the non-streaming lane, and the auto-title thread races delivery even when registration survives. The cache read can only succeed AFTER the connector answers the send, so the rename lane deterministically disqualified itself on the title turn. Fix — decide shape early, facts late: - New _is_relay_discord_channel_lane: SHAPE-only predicate (relay Discord channel event, no thread) used by the registration and schedule gates; no cache read before delivery. - _rename_discord_auto_thread_for_session_title: on the relay lane, poll the adapter's feedback cache (0.5s ticks, ≤10s) — delivery is typically right behind the title. True miss (connector didn't auto-thread: policy off, DM, send failed) no-ops exactly as before. Tests: shape-gate matrix; late-arriving feedback -> rename fires with only_if_current_name guard; never-arriving feedback -> no-op. Relay suite 174 passed.
randlee
pushed a commit
to randlee/hermes-agent
that referenced
this pull request
Aug 11, 2026
…ename + trace logs (NousResearch#75912) Live staging (2026-08-01): relay semantic thread rename still declined silently despite both NousResearch#74482 and NousResearch#75581 deployed — thread kept its initial-words name, session title generated fine. Root cause is the no-clobber guard string mismatch (see paired gateway-gateway PR): the gateway can't reproduce the thread's initial name byte-for-byte, so the connector's only_if_current_name check always failed. - relay rename lane now passes prefer_connector_created=True instead of the fragile initial-name string; the connector resolves the guard from its own created-name memory. Native-marker lane keeps the legacy only_if_current_name string (source carries the real initial name). - rename_thread: prefer_connector_created param -> only_if_connector_created on the wire, precedence over the legacy string. - INFO logs at rename dispatch (thread/lane/new_title) and result (applied=bool): the whole failure hunt needed telemetry the gateway never emitted — this makes the outcome visible in fly logs. Tests: connector-guard wire shape + precedence over legacy string; the title-turn race test updated to assert the connector-owned guard. Relay suite 149 passed; ruff + footguns clean.
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.
Relay semantic thread rename — register eagerly, poll send-result feedback at fire time
Staging re-test (2026-07-31, after the fleet box rolled to an image containing #74482): auto-created threads still stuck on their initial "first few words" titles; connector telemetry shows zero
thread_renameops ever sent.Root cause — an ordering flaw in #74482's consume path. Both gates that decide whether the semantic-rename callback runs read the connector's send-result feedback cache (
_relay_auto_thread_info):run_sync, pre-delivery), andBut the cache is only populated when the connector answers the send — which happens after registration on the non-streaming lane, and typically after the title generator has already fired. The rename lane deterministically disqualified itself on exactly the turn it exists for. (#74482's unit tests exercised the cache and the rename in isolation; the gap was the cross-component ordering, which needed the live lane to expose.)
Fix — decide shape early, facts late
_is_relay_discord_channel_lane: shape-only predicate (relay-delivered Discord channel event, not already threaded) for the registration + schedule gates. No cache read before delivery can have happened._rename_discord_auto_thread_for_session_title: on the relay lane, poll the adapter's feedback cache (0.5s ticks, ≤10s) — delivery lands right behind the title in practice. A true miss (connector didn't auto-thread: delivery policy off, DM, already threaded, send failed) no-ops exactly as before.only_if_current_nameno-clobber guard (human rename wins) preserved — fed from the connector's reported initial name.Tests
Relay + Discord-adjacent suites 174 passed · ruff clean · Windows-footguns clean.
No ops flags. Connector half (gg#188) is already deployed; this completes the pair for real this time — verified against the actual live-lane ordering rather than component tests alone.