hermes - 💡(How to fix) Fix [Feature]: Allow queued messages to participate in ongoing agent loop execution [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#17298Fetched 2026-04-30 06:48:35
View on GitHub
Comments
0
Participants
1
Timeline
4
Reactions
0
Participants
Timeline (top)
labeled ×4

Fix Action

Fix / Workaround

Medium — touches run_agent.py, gateway message dispatch, and potentially prompt builder

Code Example

# Pseudocode
while not task_complete:
    # 1. Execute current step
    result = execute_next_step(state)
    
    # 2. Check queue for new messages (non-blocking, lightweight query)
    queued_messages = check_queue_non_blocking()
    
    # 3. If new messages exist, inject into next prompt
    if queued_messages:
        state.context += format_queued_messages(queued_messages)
        # Optional: decide whether to interrupt based on message content
        if should_interrupt(queued_messages):
            state = handle_interrupt(state, queued_messages)
    
    # 4. Continue or terminate
    if state.interrupted:
        break
RAW_BUFFERClick to expand / collapse

Problem or Use Case

Currently, Hermes Agent's queued messages (e.g., from Telegram/Discord gateway platforms) follow a strict "queue-and-wait" model:

  • Messages enter the queue and wait until the current agent loop execution fully completes
  • If the agent is executing a long-running task (e.g., code generation, multi-step debugging), new messages in the queue are blocked
  • User follow-up messages, clarifications, or urgent instructions cannot interrupt or participate in the ongoing loop execution

This creates two specific pain points:

Pain Point 1 — Conversation Breakage When a user sees the agent outputting lengthy content and wants to add "stop, try a different approach", that message must wait until the current loop finishes. By the time the agent finally reads it, the context has already diverged.

Pain Point 2 — Inefficient Multi-turn Collaboration In complex tasks (e.g., "help me write a scraper" → agent starts writing → user wants to add "include proxy support"), the user's supplementary message cannot real-time influence the ongoing code generation. The user must wait for the first draft to complete before making revisions, wasting tokens and time.

Proposed Solution

Introduce a Queue Message Interruption / Participation mechanism that allows queued messages to participate in an ongoing agent loop execution.

Option A: Soft Interrupt + Context Injection (Recommended)

At each tool-call return point (or after each LLM call) in the agent loop, check if the queue has new messages:

# Pseudocode
while not task_complete:
    # 1. Execute current step
    result = execute_next_step(state)
    
    # 2. Check queue for new messages (non-blocking, lightweight query)
    queued_messages = check_queue_non_blocking()
    
    # 3. If new messages exist, inject into next prompt
    if queued_messages:
        state.context += format_queued_messages(queued_messages)
        # Optional: decide whether to interrupt based on message content
        if should_interrupt(queued_messages):
            state = handle_interrupt(state, queued_messages)
    
    # 4. Continue or terminate
    if state.interrupted:
        break

Key Design Points:

  • Check Timing: Check the queue after each tool call returns and before the next LLM call — never interrupt a running tool
  • Injection Format: Format queued messages as [New message from user_id] content and inject into the prompt
  • Interrupt Strategy: User-configurable — always (any new message interrupts), keyword (specific keywords like "stop"/"halt" trigger interrupt), never (inject only, no interrupt)
  • State Preservation: Save current state on interrupt, allowing resume or discard

Option B: Parallel Sub-session (Alternative)

Spawn queued messages as independent subagent sessions. The main session and sub-session communicate via shared state:

  • Main session continues executing the current task
  • Sub-session handles user clarifications/supplements
  • Sub-session can optionally merge results back into main session or be discarded

Drawback: Increases concurrency complexity, and two sessions may compete for the same resources (e.g., editing the same file).

Alternatives Considered

OptionProsCons
A. Soft interrupt + injectionSimple to implement, coherent user experience, token-efficientRequires core loop modification
B. Parallel sub-sessionDoes not block main taskConcurrency complexity, resource contention, context splitting
C. Status quoNo implementation costPoor UX, conversation breakage

Feature Type

Core agent loop enhancement

Scope

Medium — touches run_agent.py, gateway message dispatch, and potentially prompt builder

Contribution

  • I'd like to implement this myself and submit a PR

Additional Context

Implementation references:

  • Similar to Claude Code's interrupt handling (user presses Ctrl+C and enters a new instruction)
  • Similar to ChatGPT web's "edit and resend" (allows user to modify a sent message and regenerate)
  • Complements Hermes' existing delegate_task: delegate is "I assign someone else", this is "someone interrupts me"

extent analysis

TL;DR

Implement a queue message interruption mechanism, such as the proposed "Soft Interrupt + Context Injection" option, to allow queued messages to participate in an ongoing agent loop execution.

Guidance

  • Identify the core loop in run_agent.py where the queue can be checked for new messages after each tool call returns and before the next LLM call.
  • Determine the best approach for formatting and injecting queued messages into the prompt, such as using [New message from user_id] content.
  • Decide on an interrupt strategy, such as always, keyword, or never, and implement the corresponding logic.
  • Consider the trade-offs between the proposed options, including the simplicity of "Soft Interrupt + Context Injection" versus the potential benefits and complexity of "Parallel Sub-session".

Example

# Pseudocode example of checking the queue and injecting new messages
while not task_complete:
    result = execute_next_step(state)
    queued_messages = check_queue_non_blocking()
    if queued_messages:
        state.context += format_queued_messages(queued_messages)
        if should_interrupt(queued_messages):
            state = handle_interrupt(state, queued_messages)

Notes

The implementation should carefully consider the potential impact on the agent's state and the user experience, including how to handle interrupts, preserve state, and manage concurrency.

Recommendation

Apply the "Soft Interrupt + Context Injection" workaround, as it appears to be the most straightforward and efficient solution, requiring minimal modifications to the core loop and providing a coherent user experience.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix [Feature]: Allow queued messages to participate in ongoing agent loop execution [1 participants]