Skip to content

feat(shell): correct known shell-dialect errors in the tool output - #4141

Merged
trungutt merged 1 commit into
docker:mainfrom
trungutt:feat/shell-dialect-error-correction
Sep 3, 2026
Merged

feat(shell): correct known shell-dialect errors in the tool output#4141
trungutt merged 1 commit into
docker:mainfrom
trungutt:feat/shell-dialect-error-correction

Conversation

@trungutt

@trungutt trungutt commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Why

The shell tool description already tells the model which interpreter runs its commands (shellToolDescription), but observed session traces show the model still emits POSIX syntax turn after turn under Windows PowerShell — every attempt produces a fresh parse or parameter error, the model re-derives the dialect from scratch, and the same wrong syntax gets emitted again.

A representative trace across three consecutive turns in one session:

Turn 1: pwd && ls -la
        → The token '&&' is not a valid statement separator in this version.
Turn 2: docker ps | grep foo
        → grep : The term 'grep' is not recognized as the name of a cmdlet...
Turn 3: docker logs foo | tail -20
        → tail : The term 'tail' is not recognized as the name of a cmdlet...

The description hint prevents turn 1 in some sessions but does not recover the sessions where the model ignores it. Long agentic sessions burn many tool calls this way.

What changes for the model

Scan the shell-tool output for well-known dialect-error signatures and prepend a terse imperative hint above the raw output:

[shell-hint] You are on PowerShell: POSIX utilities are not available.
Use `Select-String` (grep), `Select-Object -First N` (head), ...

grep : The term 'grep' is not recognized as the name of a cmdlet...

The hint lands at the top so the model sees it first; the original output is preserved verbatim below so nothing about the debugging path is hidden.

Why gated on the resolved shell, not on a raw substring match

Without gating, a docker logs pull from a Windows container, a grep against a repo, or a cat of a docs page that quotes the error string would all trip false positives on macOS/Linux hosts. Gating also makes each hint truthful — a "chain with ; not &&" nudge is actively wrong when the resolved shell is PowerShell 7 (pwsh) or when the failure came from a child cmd.exe invocation under a PowerShell parent.

@aheritier aheritier added the area/tools For features/issues/fixes related to the usage of built-in and MCP tools label Sep 3, 2026
@trungutt
trungutt marked this pull request as ready for review September 3, 2026 09:38
@trungutt
trungutt requested a review from a team as a code owner September 3, 2026 09:38
@aheritier aheritier added the kind/feat PR adds a new feature (maps to feat:). Use on PRs only. label Sep 3, 2026
dgageot
dgageot previously approved these changes Sep 3, 2026
@aheritier aheritier added the status/needs-rebase PR has merge conflicts or is out of date with main label Sep 3, 2026
@aheritier

Copy link
Copy Markdown
Collaborator

👋 This PR has merge conflicts with the base branch. Please rebase or merge the latest base branch and resolve them. I've moved it to draft and added status/needs-rebase; it'll be picked back up automatically once the conflicts are cleared.

The shell tool description already tells the model which interpreter
runs its commands, but haiku-class models still emit POSIX syntax
(`&&`, `grep`, `head`, `2>/dev/null`, `ls -la`) turn after turn
under Windows PowerShell 5.1 — every attempt produces a fresh parse or
parameter error, the model re-derives the dialect from scratch, and the
same wrong syntax gets emitted again. Long agentic sessions burn dozens
of tool calls this way before recovering.

Scan the shell-tool output for the well-known error signatures those
POSIX-isms produce and prepend a terse imperative hint above the raw
output. The hint lands at the top of the tool result so the model sees
it first, and the original output is preserved verbatim below so nothing
about the debugging path is hidden.

The hint is gated on the resolved shell (powershell / pwsh / cmd), not
on a raw substring match: without that gate a docker logs pull from a
Windows container, a grep against this repo, or a cat of a docs page
that quotes the error string would all trip false positives on
macOS/Linux hosts. Gating also makes each hint truthful — a "chain with
&&" nudge is actively wrong when the resolved shell is PowerShell and
the failure came from a child cmd.exe invocation.
@trungutt
trungutt force-pushed the feat/shell-dialect-error-correction branch from 437b143 to b3915a6 Compare September 3, 2026 11:23
@aheritier aheritier removed the status/needs-rebase PR has merge conflicts or is out of date with main label Sep 3, 2026
@trungutt
trungutt merged commit 321067c into docker:main Sep 3, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/tools For features/issues/fixes related to the usage of built-in and MCP tools kind/feat PR adds a new feature (maps to feat:). Use on PRs only.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants