feat(v2): PR 1/7 - Core infrastructure with registry-based architecture#2018
feat(v2): PR 1/7 - Core infrastructure with registry-based architecture#2018
Conversation
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
instructor | 64b7a3e | Commit Preview URL Branch Preview URL |
Jan 18 2026, 06:48 PM |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
instructor/v2/core/retry.py
Outdated
| ) | ||
| + "\n" | ||
| ) | ||
| # endregion agent log |
There was a problem hiding this comment.
Debug logging writes to hardcoded local file path
High Severity
Debug logging code writes to a hardcoded local path /Users/jasonliu/dev/instructor/.cursor/debug.log. This will cause FileNotFoundError on any machine where this directory doesn't exist, breaking all async retry operations. The blocks are marked with # region agent log comments indicating they were meant to be temporary debugging statements.
Additional Locations (1)
instructor/mode.py
Outdated
| GENAI_TOOLS = "genai_tools" | ||
| GENAI_STRUCTURED_OUTPUTS = "genai_structured_outputs" | ||
| GENAI_JSON = "genai_json" | ||
| GENAI_STRUCTURED_OUTPUTS = "genai_json" # Backwards compatibility alias |
There was a problem hiding this comment.
Enum alias changes value breaking backwards compatibility
Medium Severity
GENAI_STRUCTURED_OUTPUTS and GENAI_JSON share the same value "genai_json", making GENAI_STRUCTURED_OUTPUTS an alias for GENAI_JSON in Python's enum. This changes Mode.GENAI_STRUCTURED_OUTPUTS.value from "genai_structured_outputs" to "genai_json" and Mode.GENAI_STRUCTURED_OUTPUTS.name returns "GENAI_JSON". Code serializing or comparing mode values will break.
instructor/v2/core/retry.py
Outdated
| response_model=response_model, | ||
| validation_context=context, | ||
| strict=strict, | ||
| stream=False, |
There was a problem hiding this comment.
Sync retry ignores stream parameter causing parse mismatch
Medium Severity
The retry_sync_v2 function hardcodes stream=False when calling response_parser, ignoring any stream=True passed in kwargs. The async version correctly extracts stream = kwargs.get("stream", False) and passes it through. If a caller uses the sync wrapper with stream=True, the API will return a streaming response, but the parser will be told it's non-streaming, causing incorrect parsing behavior or failures.
- Add ModeRegistry for O(1) handler lookups via (Provider, Mode) tuples - Add ModeHandler base class and protocol interfaces - Add patch_v2() function for unified provider patching - Add registry-based retry logic with handler integration - Add exception hierarchy (RegistryError, ValidationContextError) - Add mode normalization with deprecation warnings - Add @register_mode_handler decorator for handler registration - Add registry unit tests This PR was written by [Cursor](https://cursor.com)
8b77563 to
d0a96e2
Compare
- Remove debug logging blocks in retry.py that wrote to hardcoded local path - Fix GENAI_STRUCTURED_OUTPUTS enum value to avoid alias collision - Fix sync retry to extract stream parameter from kwargs like async version

Description
This is PR 1 of 7 in the stacked PR series implementing Instructor V2 registry-based architecture.
Core Infrastructure
This PR introduces the foundational v2 infrastructure:
ModeRegistry (
instructor/v2/core/registry.py)(Provider, Mode)tuplesHandler System (
instructor/v2/core/handler.py,protocols.py)ModeHandlerabstract base classRequestHandler,ResponseParser,ReaskHandler@register_mode_handlerdecorator for registrationPatch Mechanism (
instructor/v2/core/patch.py)patch_v2()functionRetry Logic (
instructor/v2/core/retry.py)handle_reask()for retry preparationException Handling (
instructor/v2/core/exceptions.py)RegistryError: Mode not registered or handler lookup failureValidationContextError: Conflictingcontext/validation_contextparametersInstructorRetryException: Max retries exceededMode System (
instructor/mode.py)DEPRECATED_TO_COREmapping for legacy mode normalizationChanges
instructor/v2/core/with 7 new filesinstructor/v2/__init__.pywith core exportsinstructor/mode.pywith deprecation mappingtests/v2/test_registry.pyandconftest.pyTesting
Stacked PRs
This PR was written by Cursor
Note
Establishes the foundational v2 architecture centered on a queryable, lazy-loaded mode registry and handler contracts.
ModeRegistrywith O(1)(Provider, Mode)lookups, lazy registration on import, discovery APIs, andnormalize_modefor legacy-to-core mappingModeHandlerbase class plus type-safeRequestHandler/ReaskHandler/ResponseParserprotocols and a@register_mode_handlerdecoratorpatch_v2()with sync/async wrappers, default model injection, templating integration, and validated mode dispatch via registryreaskandresponse_parser, with streaming short-circuit for iterable/partial modelsvalidation_contextin favor ofcontextModewith GENAI alias, adds single-shot deprecation warnings andDEPRECATED_TO_COREmapping; exposes reset helpersWritten by Cursor Bugbot for commit 8b77563. Configure here.