Repository navigation
fix(learning): read lesson JSON from reasoning-model replies - #2375
Merged
Merged
Conversation
Prepare Lesson parsed the model reply with json.loads after stripping only a leading code fence. Reasoning models add <think> blocks or a prose preface, and at high effort can spend the 1800-token budget on hidden reasoning, so every attempt failed as an invalid source-selection response. Assessment requests share the same parser. Strip closed <think>/<thinking> blocks, treat a reply that still opens with reasoning as unanswered, and scan for the first JSON object with JSONDecoder.raw_decode. Truncated JSON still fails instead of being repaired into a partial object. When the reply is unusable, retry once at RETRY_REASONING_EFFORT, the project rule in structured_retry, for both lesson preparation and semantic assessment. Fixes HKUDS#2367 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Prepare Lesson and semantic assessment parsed the model reply with
json.loadsafter stripping only a leading fence. With a reasoning model at high effort, this broke in two ways:<think>block or a prose preface made parsing fail.Changes:
_json_responseparses a complete reply first. If that fails, it:<think>/<thinking>blocksJSONDecoder.raw_decodescanning, so fences and prose anywhere are handledRETRY_REASONING_EFFORT. This is the project rule inservices/llm/structured_retry.py, applied here to lesson preparation and semantic assessment. Provider errors are not retried.I did not reuse
parse_json_responseorextract_json_object:parse_json_responseruns json_repair, which turns a truncated payload into a partial object.extract_json_objectdoesn't strip<thinking>, so it can return a JSON draft from inside the reasoning.Here, both outcomes would hide the failure.
Related Issues
Module(s) Affected
learningtestsChecklist
dev(notmain— see the base-branch selector above).pre-commit run --all-filesand fixed any issues.deeptutor-repo-hygienecallspython3, which Windows lacks.python scripts/check_repo_hygiene.pypasses.mypychecks against win32 and flagsfcntl/os.killpg. With--platform linux, it reports 3 errors, all in files this PR does not touch (capability_registry.py,capabilities/mastery/tools.py).Additional Notes
deeptutor/learning/tests/test_lesson_json_response.py:dev. The invalid-input cases pass on both, which confirms the error type is the same.test_old_submission_retry_cannot_overwrite_newer_answer) also fails ondevon Windows.max_tokensas well, I can add that.🤖 Generated with Claude Code