fix: prevent /no_think tag from leaking into user message content

The /no_think directive was appended directly to the user's message text,
causing the LLM to interpret it as user input (e.g., referencing it as a
directory path). Now injected as a separate system message after the last
user message. Also adds which, jq, type, and file to shell allowed_commands
(were mistakenly placed in permissions.auto_approve).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-11 20:04:47 -05:00
parent 9273d14845
commit 7705008b9c
2 changed files with 12 additions and 9 deletions

View File

@@ -94,24 +94,23 @@ class AgentLoop:
def _get_messages_with_system_prompt(self) -> list[Message]:
"""Prepend the system prompt to conversation history.
When thinking is disabled, injects a /no_think tag into the last user
message so Qwen 3.x (and similar) chat templates see it regardless of
where tool-result messages fall in the history.
When thinking is disabled, appends a system-level /no_think directive
after the last user message so Qwen 3.x (and similar) chat templates
see it, without polluting the user's actual message content.
"""
system_msg = Message(role="system", content=self._system_prompt)
history = self._ctx.get_history()
if not self._config.llm.thinking and history:
history = list(history)
# Find last user message and insert a system hint after it
for i in range(len(history) - 1, -1, -1):
if history[i].role == "user":
original = history[i]
history[i] = Message(
role="user",
content=(original.content or "") + " /no_think",
tool_call_id=original.tool_call_id,
name=original.name,
no_think_msg = Message(
role="system",
content="/no_think",
)
history.insert(i + 1, no_think_msg)
break
return [system_msg] + history

View File

@@ -56,6 +56,10 @@ tools:
- grep
- find
- echo
- which
- jq
- type
- file
denied_commands:
- rm -rf /
- sudo