Skip to content

fix(gateway): preserve async side-task attachment delivery#6225

Closed
Kolektori wants to merge 1 commit into
NousResearch:mainfrom
Kolektori:fix/gateway-async-media-delivery
Closed

fix(gateway): preserve async side-task attachment delivery#6225
Kolektori wants to merge 1 commit into
NousResearch:mainfrom
Kolektori:fix/gateway-async-media-delivery

Conversation

@Kolektori

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes attachment delivery in the async gateway side-task paths used by
/background and /btw.

Those paths had drifted away from the main gateway response flow, which already
has a dedicated attachment-delivery path. That left the async variants with two
bugs:

  • follow-up attachments were sent without thread metadata, so threaded chats
    could receive the text reply in the right thread and the attachments in the
    parent chat
  • extract_media() returns (path, is_voice) tuples, but /background and
    /btw treated those values as plain file paths; /btw also called
    adapter.send_file(...), which is not part of the platform adapter contract

This keeps the fix narrow. The side-task paths now reuse a shared attachment
sender instead of maintaining their own partial copy.

Related Issue

None

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • Added _deliver_extracted_attachments() in gateway/run.py
  • Reused that helper from _deliver_media_from_response() so streamed and
    side-task delivery share the same media/file sending logic where it matters
  • Updated _run_background_task() to preserve thread metadata for image and
    MEDIA: attachment sends
  • Updated _run_btw_task() to preserve thread metadata and remove the
    non-existent adapter.send_file(...) path
  • Added two targeted regression tests in
    tests/gateway/test_background_command.py

How to Test

  1. Start from a threaded gateway chat and trigger /background with a response
    that includes both a markdown image and a MEDIA:/tmp/file attachment.
  2. Trigger /btw with a response that includes a MEDIA:/tmp/file attachment.
  3. Verify that the follow-up attachments stay in the same thread as the text
    reply and that MEDIA: attachments are delivered using the real file path,
    not the raw tuple returned by extract_media().

Automated regression checks:

uv run pytest -q -n 0 tests/gateway/test_background_command.py
uvx ruff check tests/gateway/test_background_command.py
uv run python -m py_compile gateway/run.py tests/gateway/test_background_command.py

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS

Notes:

  • Duplicate PR search via gh pr list --repo NousResearch/hermes-agent --state all
    did not find an obvious open or closed PR for this exact async attachment bug.
  • Targeted validation passed:
    • uv run pytest -q -n 0 tests/gateway/test_background_command.py
    • uvx ruff check tests/gateway/test_background_command.py
    • uv run python -m py_compile gateway/run.py tests/gateway/test_background_command.py
  • pytest tests/ -q was not run for this draft.

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

Screenshots / Logs

Targeted regression checks:

$ uv run pytest -q -n 0 tests/gateway/test_background_command.py
....................
20 passed in 1.62s

$ uvx ruff check tests/gateway/test_background_command.py
All checks passed!

$ uv run python -m py_compile gateway/run.py tests/gateway/test_background_command.py

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery labels Apr 30, 2026
@teknium1

teknium1 commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Merged via #37613 (commit 082025a on main).

This fixed the same /background + /btw media-delivery bug as #12091 — you submitted first. Since both branches were filed, the tuple-unpacking and the send_file issue were resolved independently on main; the surviving gap was type-routing in _run_background_task, now reimplemented on current main (both branches too stale to cherry-pick cleanly). Your authorship is preserved via a Co-authored-by trailer on the merge commit, alongside @truenorth-lj. Both contributors credited. Thanks!

@teknium1 teknium1 closed this Jun 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants