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
Adds an opt-in per-route session_key template so conversational webhook sources can reuse a Hermes session instead of creating a fresh delivery-ID session for every POST. Default behavior remains per-delivery.
This supersedes the stale/conflicting implementation path in #57972 and covers the narrower constant-route proposal in #71570. It intentionally does not address cross-session approval routing (#71571).
Safety and behavior
A successfully rendered session_key creates a persistent conversation identity; unresolved templates safely fall back to the existing one-shot delivery session and still auto-close.
Persistent (session:<key>) and fallback (delivery:<delivery-id>) identities use disjoint namespaces, so a delivery ID cannot collide with, reuse, or auto-close a persistent conversation.
Conversation identity is separate from delivery routing: each delivery retains its own rendered deliver_extra, preventing concurrent turns from redirecting another turn’s response.
Persistent deliveries use the gateway FIFO rather than the adapter’s single pending slot, so multiple arrivals keep their own turns, delivery IDs, and response targets without text merging, interrupting, or steering.
Multiplexed profiles remain separate even if the route and rendered key match.
The full tests/gateway suite was also exercised locally. The targeted webhook coverage is green; remaining failures are existing macOS/environmental Discord/AF_UNIX/DNS isolation failures outside this diff.
Credit
This branch preserves the authored commits from Gilles Gameiro and Atroci; the additional commits add profile-isolation, multi-delivery FIFO, and persistent-vs-fallback namespace-collision regression coverage.
AI code review — automated review for reference; please use your judgment.
Excellent feature design: session_key cleanly separates conversation identity from delivery identity, per-delivery deliver_extra storage means an overlapping second POST cannot redirect an in-flight turn's response target (proven by the two-event interleaving test with exact send args), the busy-input path deliberately FIFOs persistent deliveries instead of interrupting/merging, fallback one-shot deliveries keep their own lifecycle including session-close, profile multiplexing namespaces automatically, and the docs' behavior-notes section (idempotency unchanged, sender-controlled keys scoped to route+HMAC, ordering-vs-concurrency guidance) is genuinely thorough.
gateway/platforms/webhook.py (send resolution chain, ~380–386) — for persistent turns the chain is ContextVar delivery-id → reply_to → chat_id, but chat_id is now webhook:<route>:session:<key> which is never a key in _delivery_info — why it matters: any send() that runs outside the ContextVar's async context and without reply_to (e.g., an interim status emitted from a different task, or after context teardown) finds nothing and silently downgrades to deliver="log" — suggestion: enumerate the gateway's send paths for webhook sessions and add a test where the final response fires from a fresh task; alternatively fall back to scanning _delivery_info_order for this session's most recent entry.
~928–931 — unresolved-template detection is "{" in session_key; a successfully rendered key whose value legitimately contains { also degrades to one-shot — safe direction, but worth documenting next to the fallback bullet since it's non-obvious.
Nit (:~1003–1005): _active_delivery_id.set(...) is never reset in on_processing_complete; task contexts are usually discarded, but a pooled/reused task would carry a stale delivery id into an unrelated turn — consider resetting with the ContextVar token in a finally.
Thanks — I checked the send paths and addressed the actionable items in 8da05c6.
Added a regression that sends from a child asyncio.create_task() during each active persistent turn. Task context propagation retains the delivery ID, and the test proves both status and final responses reach their own rendered targets under overlapping turns.
Restored the delivery ContextVar with its token in on_processing_complete (including the persistent-session early return), with regression coverage for restoring an inherited prior context.
Documented the conservative { fallback behavior for rendered keys.
A task created after a run has completed has no turn/delivery identity to route safely; selecting the newest delivery for that persistent conversation would reintroduce the cross-turn misrouting this PR prevents, so that case intentionally remains log-only rather than guessing.
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
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.
Summary
Adds an opt-in per-route
session_keytemplate so conversational webhook sources can reuse a Hermes session instead of creating a fresh delivery-ID session for every POST. Default behavior remains per-delivery.This supersedes the stale/conflicting implementation path in #57972 and covers the narrower constant-route proposal in #71570. It intentionally does not address cross-session approval routing (#71571).
Safety and behavior
session_keycreates a persistent conversation identity; unresolved templates safely fall back to the existing one-shot delivery session and still auto-close.session:<key>) and fallback (delivery:<delivery-id>) identities use disjoint namespaces, so a delivery ID cannot collide with, reuse, or auto-close a persistent conversation.deliver_extra, preventing concurrent turns from redirecting another turn’s response.Validation
The full
tests/gatewaysuite was also exercised locally. The targeted webhook coverage is green; remaining failures are existing macOS/environmental Discord/AF_UNIX/DNS isolation failures outside this diff.Credit
This branch preserves the authored commits from Gilles Gameiro and Atroci; the additional commits add profile-isolation, multi-delivery FIFO, and persistent-vs-fallback namespace-collision regression coverage.