Skip to content

fix(conversation): retain custom stuck thresholds when forking - #6239

Draft
yuhengcai1 wants to merge 1 commit into
OpenHands:mainfrom
yuhengcai1:codex/fork-preserve-stuck-thresholds
Draft

yuhengcai1 wants to merge 1 commit into
OpenHands:mainfrom
yuhengcai1:codex/fork-preserve-stuck-thresholds

Conversation

@yuhengcai1

@yuhengcai1 yuhengcai1 commented Oct 26, 2026 •

Copy link
Copy Markdown

HUMAN:


AGENT:

Why

LocalConversation.fork() copies the stuck-detection enable flag but drops custom thresholds. A fork can therefore stop earlier or later than its source on the same sequence of model responses. For example, a source configured for six repeated observations stops at six, but its fork stops at the default four.

Summary

Pass an independent copy of the source detector's threshold configuration into the fork constructor. Add native source/fork run-loop comparisons for lower and higher observation thresholds, error recovery, monologues, and alternating calls, plus default and disabled-detector controls.

This is based directly on main and independent of #6238's scan-window correction. Companion documentation: OpenHands/docs#1011.

Issue Number

No matching existing issue or PR identified for the forked threshold reset.

How to Test

OH_PERSISTENCE_DIR=/tmp/openhands-fork-check LITELLM_LOCAL_MODEL_COST_MAP=True \
  uv run --frozen pytest tests/sdk/conversation/local/test_fork.py \
  tests/sdk/conversation/local/test_fork_stuck_thresholds.py \
  tests/cross/test_stuck_detector.py tests/cross/test_stuck_detector_config.py \
  tests/sdk/conversation/local/test_stuck_detector_nudge.py -q

On main ce5716a3c0a955a85bb0cc4dcfaa94d5fefcda50, the new native suite has 5 failed, 2 passed. Each source run obeys its configured threshold, but each custom-threshold fork uses defaults. With this fix, all 42 tests in the command above pass, including 7 source/fork behavior comparisons. Applicable pre-commit formatting, lint, typing, and repository checks pass.

The source and fork are created through the supported API with on-disk persistence and real event copying. Each receives the same bounded sequence through a stubbed LLM.completion boundary backed by TestLLM; native Agent, ThinkTool execution/validation, and Conversation.run() are exercised. Each script has seven responses plus a finish fallback. No paid inference or model-behavior benchmark was run.

Environment: macOS arm64, Python 3.13.17, committed uv lock.

Video/Screenshots

Non-visual change; native source/fork counts are asserted by the regression tests.

Design Doc

Small constructor propagation fix; no separate design document.

Type

  • Bug fix
  • Feature
  • Refactor
  • Breaking change
  • Docs / chore

Notes

The fix applies to local SDK forks. Defaults, disabled detection, and public/serialized schemas are unchanged. Remote custom-threshold propagation is a separate path and is not claimed fixed here.

The HUMAN section remains for the contributor. A maintainer must apply integration-test; this contributor account lacks permission to add labels.

Co-authored-by: openhands <openhands@all-hands.dev>
@github-actions

Copy link
Copy Markdown
Contributor

📁 PR Artifacts Notice

This PR contains a .pr/ directory with temporary PR-specific documents. The directory will be automatically removed after this PR merges to main through a cleanup PR.

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.

1 participant