Skip to content

fix(cron): surface api_server origin delivery gap at create time (#69304) - #69384

Closed
Enough1122 wants to merge 1 commit into
NousResearch:mainfrom
Enough1122:fix/69304-cron-origin-api-server-fallback
Closed

fix(cron): surface api_server origin delivery gap at create time (#69304)#69384
Enough1122 wants to merge 1 commit into
NousResearch:mainfrom
Enough1122:fix/69304-cron-origin-api-server-fallback

Conversation

@Enough1122

Copy link
Copy Markdown
Contributor

Summary

A cron job's origin is captured from the creating session's platform (_origin_from_env). When the conversation ran on the api_server platform, the job gets origin.platform="api_server" — but api_server is deliberately non-delivering (its adapter send() is a no-op because the HTTP path is request/response and can never wake the agent after a turn). The default deliver=origin then fails silently at fire time:

live adapter send failed: API server uses HTTP request/response, not send();

The job runs and succeeds (last_status: ok, output written to cron/output/...), but the report is never delivered. This is invisible unless the creator inspects last_delivery_error.

Fix

Add a thin wrapper _origin_platform_can_deliver(platform) that defers to cron.scheduler._is_known_delivery_platform (single source of truth), and extend _local_delivery_notice() to surface a clear user-actionable message at create time when the origin platform is non-delivering. The notice flows through the existing create_hermes_cronjob tool return path, so the creator sees it at creation time rather than only at fire time.

The fire-time resolver already gates on known delivery platforms; this fix adds a matching create-time surface so the gap is visible immediately. Resolves the general case behind #14959.

Files touched

  • tools/cronjob_tools.py — new _origin_platform_can_deliver(platform) helper; extended _local_delivery_notice() to surface the create-time message.
  • cron/scheduler.py — read-only inspection of _is_known_delivery_platform (no behavioural change to the fire-time path).
  • tests/cron/test_scheduler.py — new tests covering the notice path.
  • tests/tools/test_cronjob_tools.py — new tests covering the wrapper.

Test plan

cd /c/Users/admin/AppData/Local/hermes/hermes-agent
./venv/Scripts/python.exe -m pytest tests/cron/test_scheduler.py tests/tools/test_cronjob_tools.py -v
# 304 passed (1 unrelated pre-existing failure in test_all_token_case_insensitive)

What this does NOT do

  • No change to the fire-time delivery path itself — that resolver already gates on known delivery platforms.
  • No change to the api_server adapter (still non-delivering by design).
  • No change to _origin_from_env itself.
  • No public API change.

Refs: #14959 (the api_server no-delivery general case). Fixes #69304.

— written by Hermes Agent on behalf of @Enough1122

@Enough1122

Copy link
Copy Markdown
Contributor Author

cc @teknium1 @alt-glitch — fix pushed for #69304.

Verification on head 351792d7:

Check Result
pytest tests/cron/test_scheduler.py tests/tools/test_cronjob_tools.py -v 304 passed (1 unrelated pre-existing failure: test_all_token_case_insensitive)
git diff --check ✅ clean
git diff --stat origin/main..HEAD ✅ 4 files, +168/-4

Implementation summary (CC-implemented via Claude Opus 4.8):

  • New helper _origin_platform_can_deliver(platform) in tools/cronjob_tools.py that defers to the existing cron.scheduler._is_known_delivery_platform — single source of truth.
  • Extended _local_delivery_notice() to surface a clear, user-actionable message at create time when origin.platform is non-delivering (the motivating case is api_server).
  • The notice flows through the existing create_hermes_cronjob tool return path, so the creator sees it at creation time rather than only at fire time.

NOT doing: not changing the fire-time delivery path (the resolver already gates on known delivery platforms); not changing the api_server adapter (still non-delivering by design); not changing _origin_from_env itself; no public API change.

Refs: #14959 (the api_server no-delivery general case). Fixes #69304.

— written by Hermes Agent on behalf of @Enough1122

@alt-glitch alt-glitch added type/bug Something isn't working comp/cron Cron scheduler and job management comp/tools Tool registry, model_tools, toolsets P2 Medium — degraded but workaround exists needs-decision Awaiting maintainer decision before any implementation sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages labels Jul 22, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related to #69350 and #69304: #69384 surfaces and falls back from a non-deliverable api_server origin, while #69350 routes an explicitly supplied delivery-platform hint. These are competing delivery-policy choices, not duplicate patches.

…sResearch#69304)

A cron job's `origin` is captured from the creating session's platform
(`_origin_from_env`). When the conversation ran on the api_server
platform, the job gets `origin.platform="api_server"` — but
api_server is deliberately non-delivering (its adapter send() is a
no-op because the HTTP path is request/response and can never wake
the agent after a turn). The default `deliver=origin` then fails
silently at fire time:

    live adapter send failed: API server uses HTTP request/response, not send();

The job runs and succeeds (`last_status: ok`), but the report is
never delivered. This is invisible unless the creator inspects
`last_delivery_error`.

Add a thin wrapper `_origin_platform_can_deliver(platform)` that
defers to `cron.scheduler._is_known_delivery_platform`, and extend
`_local_delivery_notice` to surface a clear user-actionable message
at create time when the origin platform is non-delivering. The notice
flows through the existing `create_hermes_cronjob` tool return path,
so the creator sees it immediately rather than only at fire time.

- **No** change to the fire-time delivery path itself — the fire-time
  resolver already gates on known delivery platforms; this fix adds
  a matching create-time surface so the gap is visible at job creation
  rather than only at fire time.
- **No** change to the api_server adapter — api_server is still
  non-delivering by design (the HTTP path is request/response only).
- **No** change to `_origin_from_env` itself.
- **No** public API change.

```
cd /c/Users/admin/AppData/Local/hermes/hermes-agent
./venv/Scripts/python.exe -m pytest tests/cron/test_scheduler.py tests/tools/test_cronjob_tools.py -v
```

Refs: NousResearch#14959 (the api_server no-delivery general case). Fixes NousResearch#69304.
@Enough1122
Enough1122 force-pushed the fix/69304-cron-origin-api-server-fallback branch from 351792d to f64c779 Compare July 24, 2026 12:11
@Enough1122

Copy link
Copy Markdown
Contributor Author

cc @teknium1 @alt-glitch — rebased onto current upstream main. The conflict in \cron/scheduler.py\ was a clean merge of both branches: upstream added a _get_home_target_chat_id\ fast-path, this PR added the _is_known_delivery_platform\ guard. Resolved version keeps both — the guard now gates the home-target fast-path too. \pytest\ 320 passed.

@Enough1122

Copy link
Copy Markdown
Contributor Author

Update: rebase + conflict resolution verified. MERGEABLE on upstream main. Awaiting maintainer review.

@Enough1122

Copy link
Copy Markdown
Contributor Author

Closing this stale PR for now: it has had no substantive human review/action and is unlikely to be merged in its current state. Reopen or submit a fresh PR if the issue remains relevant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cron Cron scheduler and job management comp/tools Tool registry, model_tools, toolsets needs-decision Awaiting maintainer decision before any implementation P2 Medium — degraded but workaround exists sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cron deliver=origin silently fails for jobs created in an api_server session (origin platform can't send)

2 participants