mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-10-22 06:49:52 +00:00
* feat(core): add model.loopProtection and remind before loop stops Add the model.loopProtection setting (stop, warn, off). Under the default stop, every stop point stays where it is; the always-on guards (identical calls, shell inspection, daemon invalid tool parameters, stuck repetition past the adaptive cap) first send the model one reminder with the next tool results. warn only reminds, except for content and thought repetition; off neither reminds nor stops. Budgets stop in every mode. A new loop_protection telemetry event records each reminded, stopped and observed decision. Loop stop hints and the TUI dialog note name the setting. Refs #14828 * feat(core): default model.loopProtection to warn A firing loop guard now reminds the model once and lets the turn continue by default. Budgets still stop every mode, and content and thought repetition still stops. Set model.loopProtection to "stop" to keep the previous stop points. Refs #14828 * fix(core): keep side queries out of the running turn's loop decisions A concurrent /btw side query shares the client's loop detector. Its retry dropped the turn's pending reminders, its stateful tool results could queue a global-duplicate reminder into the turn, and under `off` it marked patterns observed under the turn's prompt id. Route recordToolResult through the same ownership gate, drop pending reminders once on the owner's Retry only, and skip observed decisions for side queries. Warn once when model.loopProtection is not a valid mode instead of silently using the default, and update the consecutive-identical comment that still described an unconditional halt. * fix(core): keep reminders across side queries and guard unknown modes A concurrent /btw side query starts as a UserQuery, so its reset cleared the running turn's queued reminders and reminded/observed decisions. Under `warn` the stuck turn then got no reminder at all. Keep that state on a side query's reset, and log each reminder under the prompt id that queued it. Validate model.loopProtection in core Config as well, since SDK and serve embedders bypass the CLI check and an unknown mode acted as `off`. For a stateful read tool with no recorded results, `warn` now records an observed decision at the stop point instead of a reminder claiming the result will not change; `stop` still fails safe and stops. * fix(core): let late stateful results earn the warn reminder Under `warn`, a stateful read that reached the stop point before its results were recorded was observed under the 'identical' key, which then blocked the reminder for the rest of the streak even after the results came back unchanged. Record that case under its own key so the reminder can still be sent once the evidence is in. In daemon sessions, leave queued loop reminders untaken when the repeated tool failure guard stops the batch, so they are not logged as `reminded` without being sent. Update the telemetry docs for `observed` under `warn`, note in model.skipLoopDetection that model.loopProtection decides whether the always-on guards remind or stop, and drop the stale DashScope #5019 rationale. |
||
|---|---|---|
| .. | ||
| _meta.ts | ||
| ci-variables.md | ||
| deployment.md | ||
| integration-tests.md | ||
| issue-and-pr-automation.md | ||
| npm.md | ||
| telemetry.md | ||