fix(cron): name the home-channel target when a non-push session's deliver=origin job is rerouted
With a home channel configured, a deliver=origin job created over api_server rerouted there silently and the create response said nothing, so the agent could still promise "I'll report back here" to the HTTP client. _local_delivery_notice now returns a one-line note naming the origin_fallback target when the session cannot receive async delivery. hermes_cli/suggestions_cmd._resolve_origin used its own env mirror without the async_delivery guard, so /suggestions accept still stamped platform=api_server; it now delegates to tools.cronjob_job_args._origin_from_env.
This commit is contained in:
@@ -28,18 +28,12 @@ def _fmt_pending(pending: list) -> str:
|
||||
|
||||
|
||||
def _resolve_origin() -> Optional[Dict[str, Any]]:
|
||||
"""Best-effort current-chat origin from session env (mirrors cron's ``_origin_from_env``) so an
|
||||
accepted job delivers back to the accepting chat; None lets create_job use the home channel."""
|
||||
"""Best-effort current-chat origin from session env (cron's ``_origin_from_env``, which also
|
||||
withholds non-push surfaces such as api_server) so an accepted job delivers back to the
|
||||
accepting chat; None lets create_job use the home channel."""
|
||||
try:
|
||||
from gateway.session_context import get_session_env
|
||||
platform = get_session_env("HERMES_SESSION_PLATFORM")
|
||||
chat_id = get_session_env("HERMES_SESSION_CHAT_ID")
|
||||
if platform and chat_id:
|
||||
return {
|
||||
"platform": platform,
|
||||
"chat_id": chat_id,
|
||||
"chat_name": get_session_env("HERMES_SESSION_CHAT_NAME") or None,
|
||||
"thread_id": get_session_env("HERMES_SESSION_THREAD_ID") or None}
|
||||
from tools.cronjob_job_args import _origin_from_env
|
||||
return _origin_from_env()
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
@@ -42,3 +42,41 @@ def test_stamped_api_server_origin_falls_back_to_home_channel(monkeypatch):
|
||||
# Control: a push-capable origin is delivered as written.
|
||||
job["origin"] = {"platform": "discord", "chat_id": "42"}
|
||||
assert sd._resolve_delivery_targets(job)[0]["platform"] == "discord"
|
||||
|
||||
|
||||
def test_non_push_session_creation_notice_names_home_channel_fallback(monkeypatch):
|
||||
"""With a home channel configured the rerouted job must still tell the creating client where
|
||||
the report goes (the api_server client never sees it); a push-capable session stays silent."""
|
||||
from tools.cronjob_job_args import _local_delivery_notice, _origin_from_env
|
||||
|
||||
monkeypatch.setenv("TELEGRAM_HOME_CHANNEL", "12345")
|
||||
tokens = set_session_vars(platform="api_server", chat_id="desk-1", session_key="desk-1",
|
||||
async_delivery=False)
|
||||
try:
|
||||
notice = _local_delivery_notice({"id": "j", "deliver": "origin", "origin": _origin_from_env()}, None)
|
||||
finally:
|
||||
clear_session_vars(tokens)
|
||||
assert notice and "telegram:12345" in notice and "instead of back here" in notice
|
||||
|
||||
tokens = set_session_vars(platform="telegram", chat_id="777", session_key="tg", async_delivery=True)
|
||||
try:
|
||||
assert _local_delivery_notice(
|
||||
{"id": "j", "deliver": "origin", "origin": _origin_from_env()}, None) is None
|
||||
finally:
|
||||
clear_session_vars(tokens)
|
||||
|
||||
|
||||
def test_suggestions_accept_origin_shares_the_non_push_guard():
|
||||
from hermes_cli.suggestions_cmd import _resolve_origin
|
||||
|
||||
tokens = set_session_vars(platform="api_server", chat_id="desk-1", session_key="desk-1",
|
||||
async_delivery=False)
|
||||
try:
|
||||
assert _resolve_origin() is None
|
||||
finally:
|
||||
clear_session_vars(tokens)
|
||||
tokens = set_session_vars(platform="telegram", chat_id="777", session_key="tg", async_delivery=True)
|
||||
try:
|
||||
assert _resolve_origin()["chat_id"] == "777"
|
||||
finally:
|
||||
clear_session_vars(tokens)
|
||||
|
||||
@@ -63,7 +63,16 @@ def _local_delivery_notice(job: Dict[str, Any], user_deliver: Optional[str]) ->
|
||||
return None
|
||||
try:
|
||||
from cron.scheduler import _resolve_delivery_targets
|
||||
if _resolve_delivery_targets(job):
|
||||
targets = _resolve_delivery_targets(job)
|
||||
if targets:
|
||||
# _origin_from_env() dropped a non-push origin (api_server) and the job rerouted to a
|
||||
# home channel: tell the creating client where the report goes (#69304).
|
||||
from gateway.session_context import async_delivery_supported, get_session_env
|
||||
fallback = [t for t in targets if t.get("_resolved_from") == "origin_fallback"]
|
||||
if fallback and get_session_env("HERMES_SESSION_PLATFORM") and not async_delivery_supported():
|
||||
return ("Note: this stateless HTTP API session cannot receive cron delivery, so this "
|
||||
f"job will report to the home channel {fallback[0]['platform']}:"
|
||||
f"{fallback[0]['chat_id']} instead of back here.")
|
||||
return None
|
||||
except Exception: # resolution unavailable — fall back to the origin signal
|
||||
if job.get("origin"):
|
||||
|
||||
Reference in New Issue
Block a user