Skip to content

feat(session): inject debugging-loop hint when the same shell command keeps failing - #39990

Open
openchat-ai wants to merge 2 commits into
anomalyco:devfrom
openchat-ai:hypothesis-loop-detection
Open

feat(session): inject debugging-loop hint when the same shell command keeps failing#39990
openchat-ai wants to merge 2 commits into
anomalyco:devfrom
openchat-ai:hypothesis-loop-detection

Conversation

@openchat-ai

Copy link
Copy Markdown

Issue for this PR

Closes #39772

Type of change

  • New feature

What does this PR do?

Part of #39772 (debugging loop detection). When the same shell command fails repeatedly (non-zero exit code) across a conversation, the model is likely cycling through hypotheses at the same layer - edit source, re-run, see the same failure - without descending to the actual evidence.

This PR adds a session-loop detector that runs alongside the existing reminders in the main prompt loop. After a shell command has failed 2+ times, it injects a synthetic hint into the last user message telling the model to stop proposing another hypothesis and instead examine the concrete evidence: the command's own error output, logs, core dumps, or traces.

Detection is keyed on the exact command string, only counts completed (non-aborted) shell tool calls, ignores successful runs, and is idempotent (the hint is only injected once).

How did you verify your code works?

Added a unit test suite in \ est/session/loop-detection.test.ts\ covering: injection at 2 failures, no injection at 1 failure, no re-injection on later steps, ignoring successful commands, independent per-command tracking, and the no-user-message case. All 6 pass. \�un typecheck\ passes.

The pre-existing failures in \ est/session/instruction.test.ts\ and compaction tests reproduce on clean \origin/dev\ and are unrelated.

Screenshots / recordings

N/A

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Copilot AI review requested due to automatic review settings August 1, 2026 02:20
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Based on my search results, here are potentially related PRs:

Related PR:

Adjacent Feature:

The current PR (#39990) appears to be the primary implementation for this feature. PR #37110 may have related logic worth cross-referencing, and #39982 appears to be a complementary enhancement for shell command error handling.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a session-level loop detector to inject a debugging hint when repeated shell command failures indicate the model may be stuck iterating at the same hypothesis layer, integrating it into the main session prompt loop and covering the behavior with unit tests.

Changes:

  • Introduces LoopDetection.apply(...) to scan prior tool calls and inject a synthetic “examine the evidence” hint after repeated failures of the same command.
  • Wires loop detection into the session prompt loop alongside existing reminder injection.
  • Adds a unit test suite exercising the injection/no-injection and idempotence behaviors.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
packages/opencode/src/session/loop-detection.ts Implements failure counting and synthetic hint injection logic.
packages/opencode/src/session/prompt.ts Invokes loop detection during prompt construction.
packages/opencode/test/session/loop-detection.test.ts Adds tests for repeated-failure detection and injection behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +49 to +52
type: "tool",
callID: `call_${id}`,
tool: "shell",
state: {
Comment thread packages/opencode/src/session/prompt.ts Outdated
Effect.provideService(FSUtil.Service, fsys),
Effect.provideService(Session.Service, sessions),
)
LoopDetection.apply(msgs)
for (const msg of messages) {
if (msg.info.role !== "assistant") continue
for (const part of msg.parts) {
if (part.type !== "tool" || part.tool !== "shell" || part.state.status !== "completed") continue
LoopDetection checked part.tool === "shell" but the shell tool's real
id is "bash" (ShellID.ToolID), so the detector never counted real shell
failures and the hint was never injected. Test fixtures had the same
wrong id, so the suite passed while the feature was broken in production.

- match on ShellID.ToolID in loop-detection.ts
- assign the apply() return value at the prompt call site
- use "bash" in loop-detection test fixtures
@openchat-ai

Copy link
Copy Markdown
Author

Hi there! First-time contributor here, and I noticed the CI checks on this PR are currently waiting for approval to run (they show as action_required). I'd be grateful if you could approve the workflow run whenever you have a moment — no rush at all. Happy to make any adjustments if needed, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE]: Debugging loop detection and cross-session memory

2 participants