Skip to content

fix(cli): preserve image interrupts when re-queueing - #5202

Open
mattsegura wants to merge 1 commit into
NousResearch:mainfrom
mattsegura:fix/interrupt-image-payload-merge
Open

fix(cli): preserve image interrupts when re-queueing#5202
mattsegura wants to merge 1 commit into
NousResearch:mainfrom
mattsegura:fix/interrupt-image-payload-merge

Conversation

@mattsegura

@mattsegura mattsegura commented Apr 5, 2026

Copy link
Copy Markdown

Summary

  • preserve multimodal (text, [Path, ...]) CLI payloads when merging interrupted input back into _pending_input
  • avoid "\n".join(...) on tuple payloads, which crashed when a running turn was interrupted with attached clipboard images
  • add regression coverage for tuple/image payload splitting, merging, and preview formatting

Reproduction (before fix)

Interactive CLI repro:

  1. Start hermes in interactive mode.
  2. Ask it to do something long-running so the agent stays busy for a bit.
  3. While it is still running, paste or attach an image from the clipboard so the input is queued as an image payload.
  4. Hit Enter to interrupt the current turn.
  5. Let Hermes re-queue the interrupted input for the next turn.

Before this patch, the re-queue path treated every queued item as a string and attempted "\n".join(all_parts). If one of those items was the image payload tuple, Hermes crashed with:

TypeError: sequence item 0: expected str instance, tuple found

The exact failing payload shape looked like:

("", [PosixPath("/Users/.../.hermes/images/clip_*.png")])

Minimal code-level repro:

all_parts = [('', [Path('/tmp/clip.png')]), 'retry']
'\n'.join(all_parts)

Root cause

The interactive CLI queues image attachments as (text, images) tuples. When a turn was interrupted, the requeue path treated every pending item as a string and did "\n".join(all_parts), which raised the TypeError above.

Validation

  • ~/.hermes/hermes-agent/venv/bin/python -m pytest -o addopts='' tests/test_cli_interrupt_payloads.py tests/test_cli_file_drop.py tests/tools/test_interrupt.py -q
  • ~/.hermes/hermes-agent/venv/bin/python -m py_compile cli.py tests/test_cli_interrupt_payloads.py
  • git diff --check

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard labels May 1, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Likely duplicate of #12751 — same root cause: Ctrl+C requeue crashes on multimodal tuples due to join() on mixed str/tuple payloads.

@alt-glitch

Copy link
Copy Markdown
Collaborator

Likely duplicate of #12751

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tracing this to the interrupt requeue path. The underlying defect remains on current main: attached images are queued as (text, images) at cli.py:13500-13531, while the requeue branch still executes "\n".join(all_parts) at cli.py:12716-12732.

Problems

  • tests/test_cli_interrupt_payloads.py tests the proposed helpers in isolation, but does not exercise the live HermesCLI.chat() requeue branch. The existing acknowledged-interrupt test at tests/cli/test_cli_interrupt_ack_race.py:155-193 covers that branch only for text payloads.

Suggested changes

  • Add a tuple/image case to that live-path test and assert the queued next-turn payload retains (text, [Path, ...]).
  • When salvaging onto current main, keep the focused type-aware merge at cli.py:12716-12732; current process_loop already consumes that tuple format at cli.py:15186-15189.

Automated hermes-sweeper review.

Comment thread cli.py
@@ -6578,14 +6666,15 @@ def run_agent():
all_parts.append(extra)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a regression through HermesCLI.chat() as well as helper tests. tests/cli/test_cli_interrupt_ack_race.py:155-193 already drives the acknowledged requeue branch; queue an ("", [tmp_path / "clip.png"]) payload there and assert _pending_input retains the tuple.

@teknium1 teknium1 added sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform 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.

3 participants