hermes - ✅(Solved) Fix copilot-acp: thinking-only empty responses when tool-call permission is denied [1 pull requests, 1 comments, 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#17284Fetched 2026-04-30 06:48:39
View on GitHub
Comments
1
Participants
1
Timeline
7
Reactions
0
Author
Participants
Timeline (top)
labeled ×5commented ×1cross-referenced ×1

When using provider: copilot-acp with model: claude-sonnet-4.6, many queries that cause the Copilot CLI to attempt a tool call (e.g. shell commands to read config files) result in empty responses delivered to the user as (empty).

Root Cause

The Copilot CLI, when running in --acp --stdio mode, is a full agent that:

  1. Generates agent_thought_chunk events (internal reasoning) while thinking
  2. Sends a session/update with sessionUpdate: "tool_call" to announce a tool it wants to run
  3. Sends session/request_permission to request execution approval

Hermes currently always denies session/request_permission with outcome: cancelled. When the CLI receives a cancellation, it terminates the turn with stopReason: end_turn — emitting zero agent_message_chunk events (no visible text output).

Hermes then receives:

  • content = "" (empty)
  • reasoning = "<thoughts>" (non-empty)

This triggers run_agent.py's thinking-only response detection, which prefill-retries twice, exhausts its budget, and delivers (empty) to the user.

Fix Action

Fix

After a session/prompt turn that produces only thought chunks (tool denied), send a follow-up session/prompt in the same session asking the model to answer from existing knowledge without running commands. If the follow-up also produces no text, surface the original reasoning as the reply text. This ensures run_agent.py always receives a non-empty response and the thinking-only loop never fires.

PR fix notes

PR #17285: fix(copilot-acp): recover from tool-permission-denied thinking-only responses

Description (problem / solution / changelog)

⚠️ This PR has been superseded by #17604, which implements a proper root-cause fix instead of the follow-up prompt workaround described here. Please review and merge #17604 instead.


Fixes #17284

Problem

When using provider: copilot-acp, any query that causes the Copilot CLI to attempt a tool call (e.g. reading config files via shell) results in (empty) being delivered to the user. The UI shows the characteristic loop:

↻ Thinking-only response — prefilling to continue (1/2)
↻ Thinking-only response — prefilling to continue (2/2)
⚠️ Empty response from model — retrying (1/3)

Root cause: Hermes always denies session/request_permission with outcome: cancelled. When the Copilot CLI's tool call is denied, it ends the turn with stopReason: end_turn having emitted only agent_thought_chunk events — zero agent_message_chunk text. The empty-content + non-empty-reasoning combination triggers run_agent.py's thinking-only detection, which exhausts its prefill retry budget and delivers (empty).

Fix (workaround — see #17604 for root-cause fix)

In agent/copilot_acp_client.py, after a session/prompt turn that produces only thought chunks, sends a follow-up prompt asking the model to answer from existing knowledge. Falls back to surfacing reasoning as reply text if still empty.

Changed files

  • agent/copilot_acp_client.py — follow-up prompt retry logic in _run_prompt

Changed files

  • agent/copilot_acp_client.py (modified, +40/-0)

Code Example

[0] role=user   content='Help me configure matrix access, based on openclaw matrix config'
[1] role=assistant  finish=incomplete  content=''   ← prefill retry 1
[2] role=assistant  finish=incomplete  content=''   ← prefill retry 2  
[3] role=assistant  finish=stop        content='(empty)'  ← exhausted

---

Thinking-only response — prefilling to continue (1/2)
Thinking-only response — prefilling to continue (2/2)
⚠️ Empty response from model — retrying (1/3)

---

# config.yaml
model:
  default: claude-sonnet-4.6
  provider: copilot-acp
RAW_BUFFERClick to expand / collapse

Summary

When using provider: copilot-acp with model: claude-sonnet-4.6, many queries that cause the Copilot CLI to attempt a tool call (e.g. shell commands to read config files) result in empty responses delivered to the user as (empty).

Root Cause

The Copilot CLI, when running in --acp --stdio mode, is a full agent that:

  1. Generates agent_thought_chunk events (internal reasoning) while thinking
  2. Sends a session/update with sessionUpdate: "tool_call" to announce a tool it wants to run
  3. Sends session/request_permission to request execution approval

Hermes currently always denies session/request_permission with outcome: cancelled. When the CLI receives a cancellation, it terminates the turn with stopReason: end_turn — emitting zero agent_message_chunk events (no visible text output).

Hermes then receives:

  • content = "" (empty)
  • reasoning = "<thoughts>" (non-empty)

This triggers run_agent.py's thinking-only response detection, which prefill-retries twice, exhausts its budget, and delivers (empty) to the user.

Observed session log

[0] role=user   content='Help me configure matrix access, based on openclaw matrix config'
[1] role=assistant  finish=incomplete  content=''   ← prefill retry 1
[2] role=assistant  finish=incomplete  content=''   ← prefill retry 2  
[3] role=assistant  finish=stop        content='(empty)'  ← exhausted

And in the UI:

↻ Thinking-only response — prefilling to continue (1/2)
↻ Thinking-only response — prefilling to continue (2/2)
⚠️ Empty response from model — retrying (1/3)

Reproducer

# config.yaml
model:
  default: claude-sonnet-4.6
  provider: copilot-acp

Send any message that causes the CLI to try a shell/file-system tool, e.g.:

"Help me configure matrix access based on openclaw config at ~/.openclaw"

Fix

After a session/prompt turn that produces only thought chunks (tool denied), send a follow-up session/prompt in the same session asking the model to answer from existing knowledge without running commands. If the follow-up also produces no text, surface the original reasoning as the reply text. This ensures run_agent.py always receives a non-empty response and the thinking-only loop never fires.

extent analysis

TL;DR

Modify the Copilot CLI to send a follow-up session/prompt after a tool call is denied, asking the model to answer from existing knowledge without running commands.

Guidance

  • Identify when a session/request_permission is denied by Hermes and the CLI receives a cancellation.
  • Send a follow-up session/prompt in the same session to ask the model to provide an answer without running commands.
  • If the follow-up prompt also produces no text, use the original reasoning as the reply text to prevent the thinking-only loop.
  • Verify that run_agent.py receives a non-empty response and the thinking-only loop is avoided.

Example

No code snippet is provided as the issue suggests a modification to the Copilot CLI's behavior rather than a specific code change.

Notes

This fix assumes that the model can provide a useful response without running commands. If the model relies heavily on tool calls, this fix may not be effective.

Recommendation

Apply the workaround by modifying the Copilot CLI to send a follow-up session/prompt after a tool call is denied, as this ensures that run_agent.py always receives a non-empty response and the thinking-only loop is avoided.

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 - ✅(Solved) Fix copilot-acp: thinking-only empty responses when tool-call permission is denied [1 pull requests, 1 comments, 1 participants]