Summary
When the agent is actively processing (mid-turn, tool calls in flight), exec-type quick commands (type: exec) are not executed by the gateway's quick command dispatcher. Instead, the command text is routed to the agent as a regular incoming message.
Expected Behavior
Exec quick commands should always execute their shell command immediately, regardless of agent state. They bypass the LLM entirely by design — the gateway intercepts them, runs the subprocess, and returns the output directly.
Actual Behavior
If the agent is mid-turn (tool calls active, gateway is processing), the quick command falls through to the agent loop and appears as raw text in the conversation (e.g., the agent sees /note remember to buy milk as a user message instead of the gateway executing daily-note.sh "remember to buy milk").
Reproduction
- Set up an exec quick command in
config.yaml:
quick_commands:
note:
type: exec
command: bash ~/.hermes/scripts/daily-note.sh "{args}"
- Start a conversation with the agent and trigger a multi-tool-call turn
- While the agent is actively processing tool calls, type
/note test message in Discord/CLI
- Observe: the agent receives
/note test message as a plain text message instead of the script executing
Impact
- Notes/commands silently fail (no execution, no error)
- Agent sees raw command text that it shouldn't see
- User gets no feedback that the command was swallowed
Environment
- Hermes v0.13.0
- Discord gateway
- Config:
quick_commands.<name>.type: exec
Suggested Fix
The quick command dispatch in _process_event() (gateway/run.py) should happen before any agent-turn queuing logic, or at minimum, exec-type quick commands should be short-circuited regardless of _draining or active session state. Since exec commands don't touch the LLM or the session, there's no reason they should be blocked by agent activity.
The relevant dispatch code is around line 6479 in gateway/run.py:
# User-defined quick commands (bypass agent loop, no LLM call)
if command:
quick_commands = ...
if command in quick_commands:
qcmd = quick_commands[command]
if qcmd.get("type") == "exec":
# This block should be unreachable by agent state
# but appears to be bypassed when agent is mid-turn
Summary
When the agent is actively processing (mid-turn, tool calls in flight), exec-type quick commands (
type: exec) are not executed by the gateway's quick command dispatcher. Instead, the command text is routed to the agent as a regular incoming message.Expected Behavior
Exec quick commands should always execute their shell command immediately, regardless of agent state. They bypass the LLM entirely by design — the gateway intercepts them, runs the subprocess, and returns the output directly.
Actual Behavior
If the agent is mid-turn (tool calls active, gateway is processing), the quick command falls through to the agent loop and appears as raw text in the conversation (e.g., the agent sees
/note remember to buy milkas a user message instead of the gateway executingdaily-note.sh "remember to buy milk").Reproduction
config.yaml:/note test messagein Discord/CLI/note test messageas a plain text message instead of the script executingImpact
Environment
quick_commands.<name>.type: execSuggested Fix
The quick command dispatch in
_process_event()(gateway/run.py) should happen before any agent-turn queuing logic, or at minimum, exec-type quick commands should be short-circuited regardless of_drainingor active session state. Since exec commands don't touch the LLM or the session, there's no reason they should be blocked by agent activity.The relevant dispatch code is around line 6479 in
gateway/run.py: