Skip to content

fix(gateway): add media download retry to Mattermost, Slack, and base cache#3323

Merged
teknium1 merged 2 commits intomainfrom
hermes/hermes-140430f8
Mar 27, 2026
Merged

fix(gateway): add media download retry to Mattermost, Slack, and base cache#3323
teknium1 merged 2 commits intomainfrom
hermes/hermes-140430f8

Conversation

@teknium1
Copy link
Copy Markdown
Contributor

Summary

Salvaged from PR #2982 by @dieutx.

Media downloads on Mattermost, Slack, Signal, and Matrix failed permanently on transient errors (timeouts, 429 rate limits, 5xx). Telegram, WhatsApp, and Discord already had retry logic — these platforms were the gap.

Changes

File Change
gateway/platforms/base.py cache_image_from_url() — retry with exponential backoff (1.5s, 3s). Covers Signal/Matrix.
gateway/platforms/mattermost.py _send_url_as_file() — retry on 429/5xx/timeout, falls back to URL-as-text
gateway/platforms/slack.py _download_slack_file() + _download_slack_file_bytes() — same retry pattern
tests/gateway/test_media_download_retry.py 20 tests covering all retry paths

Retry behavior

  • 3 attempts total (1 initial + 2 retries)
  • Exponential backoff: 1.5s, 3s
  • Retries on: timeout, 429, 5xx
  • Does NOT retry on: 4xx client errors (except 429)
  • Mattermost falls back to URL-as-text on exhaustion

Test plan

  • 122 related tests passed (new retry tests + existing mattermost/slack tests)
  • Clean cherry-pick, no conflicts
dieutx added 2 commits March 26, 2026 19:28
… cache

Media downloads on Mattermost and Slack fail permanently on transient
errors (timeouts, 429 rate limits, 5xx server errors). Telegram and
WhatsApp already have retry logic, but these platforms had single-attempt
downloads with hardcoded 30s timeouts.

Changes:
- base.py cache_image_from_url: add retry with exponential backoff
  (covers Signal and any platform using the shared cache helper)
- mattermost.py _send_media_url: retry on 429/5xx/timeout (3 attempts)
- slack.py _download_slack_file: retry on timeout/5xx (3 attempts)
- slack.py _download_slack_file_bytes: same retry pattern
@teknium1 teknium1 merged commit a2847ea into main Mar 27, 2026
2 checks passed
binhnt92 added a commit to binhnt92/hermes-agent that referenced this pull request Mar 27, 2026
…from_url

PR NousResearch#3323 added retry with exponential backoff to cache_image_from_url
but missed the sibling function cache_audio_from_url 18 lines below in
the same file. A single transient 429/5xx/timeout loses voice messages
while image downloads now survive them.

Apply the same retry pattern: 3 attempts with 1.5s exponential backoff,
immediate raise on non-retryable 4xx.
teknium1 pushed a commit that referenced this pull request Mar 29, 2026
…from_url (#3401)

PR #3323 added retry with exponential backoff to cache_image_from_url
but missed the sibling function cache_audio_from_url 18 lines below in
the same file. A single transient 429/5xx/timeout loses voice messages
while image downloads now survive them.

Apply the same retry pattern: 3 attempts with 1.5s exponential backoff,
immediate raise on non-retryable 4xx.
StreamOfRon pushed a commit to StreamOfRon/hermes-agent that referenced this pull request Mar 29, 2026
… cache (NousResearch#3323)

* fix(gateway): add media download retry to Mattermost, Slack, and base cache

Media downloads on Mattermost and Slack fail permanently on transient
errors (timeouts, 429 rate limits, 5xx server errors). Telegram and
WhatsApp already have retry logic, but these platforms had single-attempt
downloads with hardcoded 30s timeouts.

Changes:
- base.py cache_image_from_url: add retry with exponential backoff
  (covers Signal and any platform using the shared cache helper)
- mattermost.py _send_media_url: retry on 429/5xx/timeout (3 attempts)
- slack.py _download_slack_file: retry on timeout/5xx (3 attempts)
- slack.py _download_slack_file_bytes: same retry pattern

* test: add tests for media download retry

---------

Co-authored-by: dieutx <dangtc94@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants