Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
59c5ccb
fix(web-shell): surface loop detection turn errors
Aug 10, 2026
c004d55
fix(cli): expect loop-detected turn error in invalid-params stop test…
Aug 10, 2026
54cfa0f
Merge branch 'main' into fix/web-shell-loop-detection-error
qwen-code-dev-bot Aug 10, 2026
0fe2ef9
fix(cli): reject loop-detected stops only for foreground ACP turns
qwen-code-dev-bot Aug 11, 2026
1d32541
fix(acp-bridge): harden loop-detected turn errors per review feedback
qwen-code-dev-bot Aug 11, 2026
e4e2ed2
Merge remote-tracking branch 'origin/main' into fix/web-shell-loop-de…
qwen-code-dev-bot Aug 11, 2026
4960ac1
Merge remote-tracking branch 'origin/main' into fix/web-shell-loop-de…
qwen-code-dev-bot Aug 11, 2026
3a338ce
fix(cli): keep channel-prompt turns graceful on loop-detected stops
qwen-code-dev-bot Aug 11, 2026
c862d3f
fix(acp-bridge): keep loop turn error on refresh after idle bookkeepi…
qwen-code-dev-bot Aug 11, 2026
f4f18fe
chore: merge main into fix/web-shell-loop-detection-error
qwen-code-dev-bot Aug 12, 2026
6e4c182
Merge branch 'main' into fix/web-shell-loop-detection-error
qwen-code-dev-bot Aug 13, 2026
6efa3ca
fix(acp-bridge): harden loop-protection turn state per review feedbac…
qwen-code-dev-bot Aug 13, 2026
209a28e
Merge remote-tracking branch 'origin/main' into fix/web-shell-loop-de…
qwen-code-dev-bot Aug 13, 2026
91ba419
fix(acp): gate channel-turn classification and harden loop-error refr…
qwen-code-dev-bot Aug 13, 2026
a47e0b5
fix(acp): close loop-protection bypasses in delivery classification a…
qwen-code-dev-bot Aug 13, 2026
8af27d0
Merge remote-tracking branch 'origin/main' into fix/web-shell-loop-de…
qwen-code-dev-bot Aug 14, 2026
c8fe629
fix(acp): cover idle workspace fan-out events in the refresh-append a…
qwen-code-dev-bot Aug 14, 2026
f291d23
Merge remote-tracking branch 'origin/main' into fix/web-shell-loop-de…
qwen-code-dev-bot Aug 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions docs/design/web-shell-loop-detection-turn-error.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Web Shell loop-detection turn errors

## Problem

ACP loop protection currently records unstarted tool calls as failures and then completes the prompt with `stopReason: end_turn`. Web Shell therefore presents the internal tool skip text as the only explanation and treats the turn as successful.

## Design

When a foreground ACP prompt is stopped by loop protection, preserve completed and skipped tool results as today, then reject that prompt with a structured ACP request error. The bridge publishes the existing `turn_error` terminal with `errorKind: loop_detected` and the detector's `loopType`. Cancellation continues to take precedence when it races the loop stop.

Web Shell renders `loop_detected` from the structured kind, using localized plain language: the model repeated tool use or reached a safety limit, only the current turn stopped, and the user can continue with a more specific instruction. No client matches the internal English tool error.

Skipped tools keep their existing failed terminal update and error details so they cannot remain pending and their display behavior does not change. The additional `turn_error` provides the user-facing explanation for the stopped turn.

The session remains alive and the per-turn loop state is recreated for the next prompt. Cron, background-notification, channel-classified, and goal turns keep their existing non-interactive handling: only interactive foreground prompts reject. Channel classification comes from the authenticated channel-prompt marker alone; the caller-requested delivery meta still schedules the delivery but keeps the foreground rejection, so it cannot opt a turn out of loop protection. Goal turns bypass the bridge entirely, so rejecting one would settle it as failed and pause the goal without publishing any `turn_error`; they resolve `end_turn` like the other automatic turn types. A loop-detected rejection still drains the cron/notification queues, preserving the invariant that a loop-stopped turn never strands queued automatic work.

When Web Shell reloads a live session from paginated persisted history, the bridge appends the current in-memory `turn_error` to that replay. This keeps the terminal error visible across a page refresh while the session remains idle; newer turn content — including automatic turns the rejection itself drains — supersedes it by design.

## Compatibility

`turn_error` already terminates prompts and returns the UI to idle. Adding a known error kind and optional metadata is backward-compatible: older clients show the daemon message, while updated clients show localized guidance.
Loading
Loading