feat(retry): propagate failed attempts through reask handlers#1804
feat(retry): propagate failed attempts through reask handlers#1804
Conversation
- Update handle_reask_kwargs to accept and use failed_attempts parameter - Add InstructorError.from_exception method with Jinja templating for failed attempts - Enrich exceptions with retry history and attempt numbers - Update sync/async retry functions to pass failed attempts context - Improve comprehensive documentation for reask process - Add XML-structured formatting for failed attempts display This enables LLMs to learn from previous validation failures by providing full retry context in subsequent attempts, improving error recovery rates.
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
instructor | 21ccf32 | Sep 04 2025, 09:20 PM |
|
Claude finished @jxnl's task —— View job PR Code ReviewI'll provide a comprehensive code review of this PR focusing on code quality, best practices, potential bugs, performance considerations, security concerns, and test coverage. Review Checklist
Analysis of Changesexceptions.py (
retry.py (
response.py (
utils.py (
Code Quality Assessment✅ Strengths
|
There was a problem hiding this comment.
Caution
Changes requested ❌
Reviewed everything up to 1c1c48b in 2 minutes and 17 seconds. Click for details.
- Reviewed
292lines of code in4files - Skipped
0files when reviewing. - Skipped posting
3draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. instructor/core/exceptions.py:25
- Draft comment:
SUGGESTION: Consider defaulting 'failed_attempts' to an empty list instead of leaving it as None. This can prevent potential iteration issues in the Jinja template in str. - Reason this comment was not posted:
Confidence changes required:80%<= threshold85%None
2. instructor/core/retry.py:277
- Draft comment:
IMPROVEMENT: In the RetryError exception block, the InstructorRetryException is constructed using 'attempt.retry_state.attempt_number'. For clarity and safety, consider using 'e.last_attempt.retry_state.attempt_number' instead, as it directly references the last attempt from the RetryError. - Reason this comment was not posted:
Confidence changes required:80%<= threshold85%None
3. instructor/providers/openai/utils.py:26
- Draft comment:
NOTE: The 'failed_attempts' parameter is accepted in the reask functions (e.g. reask_tools) but is never used. If this is intended solely for signature consistency, please add a comment to clarify its purpose; otherwise, consider integrating it. - Reason this comment was not posted:
Confidence changes required:70%<= threshold85%None
Workflow ID: wflow_mxpEKZkRnikekZEM
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
| ) | ||
| ) | ||
| return template.render( | ||
| exception=self.exception, failed_attempts=self.failed_attempts |
There was a problem hiding this comment.
BUG: str references 'self.exception' but the constructor (init) never assigns it. This can lead to an AttributeError. Consider assigning 'self.exception = args[0]' in init.
|
|
||
| def __init__( | ||
| self, | ||
| *args: list[Any], |
There was a problem hiding this comment.
IMPROVEMENT: The type hint for *args is declared as 'list[Any]' but should be more generic (e.g. '*args: Any'). This ensures proper typing of arbitrary positional arguments.
| *args: list[Any], | |
| *args: Any, |
…s documentation - Fix AttributeError in InstructorError.__str__ method by using super().__str__() for base exception message - Add comprehensive documentation for failed attempts tracking in retry mechanisms - Update docs/concepts/retrying.md with enhanced error context examples and reask behavior improvements 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
|
Claude finished @jxnl's task —— View job PR Code ReviewI'll provide a comprehensive code review of this PR focusing on code quality, best practices, potential bugs, performance considerations, security concerns, and test coverage. Review Checklist
Code Quality Assessment✅ Strengths
|
There was a problem hiding this comment.
Important
Looks good to me! 👍
Reviewed b798036 in 59 seconds. Click for details.
- Reviewed
109lines of code in3files - Skipped
0files when reviewing. - Skipped posting
3draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. docs/concepts/retrying.md:315
- Draft comment:
Excellent documentation addition for failed attempts tracking. The XML-structured example clearly demonstrates enriched exception context. - Reason this comment was not posted:
Confidence changes required:0%<= threshold85%None
2. instructor/core/exceptions.py:27
- Draft comment:
Using a fallback to super().str() when no failed_attempts exist is a clear improvement. Ensure that failed_attempts is always initialized as an empty list to prevent attribute issues. - Reason this comment was not posted:
Confidence changes required:0%<= threshold85%None
3. uv.lock:3
- Draft comment:
Version bump to 1.11.3 noted. Ensure corresponding changelog and documentation updates if applicable. - Reason this comment was not posted:
Confidence changes required:0%<= threshold85%None
Workflow ID: wflow_gjr2BFvDSBq5BgWu
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
…s documentation - Fix AttributeError in InstructorError.__str__ method by using super().__str__() for base exception message - Add comprehensive documentation for failed attempts tracking in retry mechanisms - Update docs/concepts/retrying.md with enhanced error context examples and reask behavior improvements 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
|
Claude finished @jxnl's task —— View job PR Code ReviewReviewing this PR for code quality, potential bugs, performance considerations, security concerns, and test coverage. Review Checklist
Code Quality Assessment✅ Strengths
|
There was a problem hiding this comment.
Important
Looks good to me! 👍
Reviewed 21ccf32 in 1 minute and 48 seconds. Click for details.
- Reviewed
456lines of code in2files - Skipped
0files when reviewing. - Skipped posting
2draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. instructor/core/exceptions.py:17
- Draft comment:
Consider that converting the original exception to string in from_exception (using str(exception)) may lose valuable context (e.g. additional attributes or stack trace). If extra details are needed later, consider preserving the original exception as an attribute. - Reason this comment was not posted:
Confidence changes required:66%<= threshold85%None
2. instructor/core/exceptions.py:101
- Draft comment:
Passing 'failed_attempts' as a keyword to super().init may cause a TypeError since Exception.init does not accept unexpected keyword arguments. Remove 'failed_attempts' from the super call. - Reason this comment was not posted:
Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 0% vs. threshold = 85% The comment is incorrect because it assumes the parent class is Exception, but it's actually InstructorError which does accept failed_attempts. Looking at line 19-26 in the file, InstructorError's init explicitly handles the failed_attempts parameter. The inheritance chain is InstructorRetryException -> InstructorError -> Exception, and InstructorError properly handles the failed_attempts before calling Exception.init. Could there be a case where kwargs contains another failed_attempts that would conflict? Could this cause unexpected behavior in some edge cases? No, because the failed_attempts is explicitly pulled out as a named parameter in the method signature, so it won't be in kwargs. The parent class handles this parameter pattern correctly. The comment should be deleted because it is incorrect - the parent class InstructorError explicitly accepts and handles the failed_attempts parameter.
Workflow ID: wflow_5GKajDRVjG2KyRG8
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
Description
This PR implements failed attempts propagation through the reask handler system, enabling LLMs to learn from previous validation failures and improve error recovery rates.
Changes
Core Functionality
InstructorError.from_exception()method that enriches exceptions with failed attempts datahandle_reask_kwargs()to accept and processfailed_attemptsparameterKey Features
exception.failed_attempts: List of previous failuresexception.retry_attempt_number: Current attempt numberDocumentation
handle_reask_kwargs()with detailed provider strategiesBenefits
Example Usage
Testing
The implementation maintains backward compatibility and includes:
This PR was written by Cursor
Important
Enhances retry mechanism by propagating failed attempts through reask handlers, enriching exceptions with retry context for improved LLM error recovery.
InstructorError.from_exception()to enrich exceptions with failed attempts data inexceptions.py.handle_reask_kwargs()inresponse.pyto processfailed_attempts.retry_sync()andretry_async()inretry.pyto pass failed attempts context.InstructorErrorto includefailed_attemptsand XML-structured output.InstructorRetryExceptionto inherit failed attempts functionality.handle_reask_kwargs().retrying.mdwith failed attempts tracking and reask behavior.test_exceptions.pyfor exception handling and failed attempts propagation.This description was created by
for 21ccf32. You can customize this summary. It will automatically update as commits are pushed.