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:
teknium1
2026-09-19 01:13:21 -07:00
committed by Teknium
parent dc30eb1618
commit 0502f35d2b
3 changed files with 53 additions and 12 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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"):