fix(v2): consolidate release-readiness correctness fixes - #2502
Conversation
…ol calls When a Responses API completion fails validation but contains no function_call items (e.g. a reasoning-only or plain message output), reask_responses_tools returned the kwargs unchanged, so every retry resent the identical request with no corrective feedback and burned the full retry budget. Append a plain user correction message in that case, mirroring the no-tool-call fallbacks already present in reask_tools (#2448) and the Anthropic reask handler (#2485).
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
instructor | bbddca1 | Commit Preview URL Branch Preview URL |
Aug 03 2026, 12:43 AM |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue. You can view the agent here.
Reviewed by Cursor Bugbot for commit bbddca1. Configure here.
| response_model=response_model, kwargs=kwargs | ||
| ) | ||
| if mode not in Mode.parallel_modes(): | ||
| response_model = prepared_model |
There was a problem hiding this comment.
Vertex parallel parse loses ParallelBase
Medium Severity
For Vertex parallel tool modes, the v2 patch wrapper keeps the caller’s raw Iterable[...] type and drops the handler’s prepared VertexAIParallelModel, while Vertex parse_response only runs parallel parsing when response_model is a ParallelBase instance, so wrapped from_vertexai parallel calls mis-parse multi-tool responses.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit bbddca1. Configure here.
## Summary - reconcile all pending changelog entries into one unpublished `1.15.5` section - validate that `pyproject.toml`, `uv.lock`, the changelog section, and comparison link agree - replace the mutating scheduled release with a read-only weekly and PR readiness workflow - build once, validate and smoke-test the exact wheel on Python 3.9 and 3.13, then require an explicit version plus `publish=true` before creating a release - make PyPI publication consume the exact wheel and sdist attached to the release instead of rebuilding from a moving branch ## Release safety The default and scheduled paths cannot create a tag, GitHub release, or PyPI publication. Publication is available only through a manual dispatch on `main` with the exact declared version and `publish=true`, after release checks and both wheel smokes pass. This PR does not dispatch that path. ## Validation - `uv run --frozen pytest tests/test_prepare_release.py -q`: 5 passed - Ruff check and format: passed - full source and test `ty`: passed - `uv lock --check`: passed - both workflow files parse as YAML - `scripts/prepare_release.py --expected-version 1.15.5`: passed - `uv build`: built `instructor-1.15.5.tar.gz` and `instructor-1.15.5-py3-none-any.whl` - `twine==6.2.0 check`: passed for wheel and sdist - clean installed-wheel smoke: passed on Python 3.9 and 3.13 - `git diff --check`: passed ## Included / superseded This follows merged consolidation PR #2502 and makes its release boundary coherent. It supersedes the previous automatic version-bump, changelog-overwrite, and branch-rebuild release paths in these workflows. ## Skipped - no tag or GitHub release creation - no PyPI publication - no dependency/provider additions - no broad feature or architecture changes - no social post <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes how packages reach PyPI and when releases are created; mistakes in workflow gates could block or mis-publish, but publication requires explicit manual dispatch and uses pre-tested artifacts rather than live branch builds. > > **Overview** > Replaces **automatic version bumps and branch rebuilds** with a **read-only release pipeline** that builds once, validates metadata, smoke-tests the exact wheel, and only publishes when someone explicitly opts in. > > **Release Readiness** (formerly scheduled release) now runs weekly and on PRs touching release files: it checks `pyproject.toml`, `uv.lock`, changelog, and tags via new `scripts/prepare_release.py`, runs lint/type/offline tests, builds distributions, uploads artifacts, and smoke-installs the wheel on Python 3.9 and 3.13. **GitHub release creation** is limited to manual `workflow_dispatch` on `main` with the declared version and `publish=true`, after smoke tests pass. > > **PyPI upload** no longer rebuilds at publish time; it downloads the **wheel and sdist attached to the GitHub release**, re-validates tag/metadata with `prepare_release.py`, runs `twine check`, then publishes those files. > > **CHANGELOG** consolidates pending work into a single dated **1.15.5** section and documents the new release-safety checks under Tests / CI. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 47107a9. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->


Summary
Consolidated and superseded items
model_extracountersValidation
110 passed2368 passed, 91 skipped, 73 deselectedty check: passeduv lock --check: passedgit diff --check: passedThe 73 deselected tests require live provider credentials. An unfiltered local run confirmed its 22 failures were provider network connections in the restricted environment; GitHub provider jobs remain the authoritative validation for those paths.
Intentionally skipped
These remain open because they need dedicated product, architecture, provider, security, dependency, or editorial review and are not required for the
1.15.5patch release.Note
Medium Risk
Changes retry usage totals and reask message content on failure paths; scope is limited and heavily covered by tests, with no auth or data-store changes.
Overview
Bundles three v2 retry and wrapper fixes for a patch release.
Retry usage accounting replaces hand-maintained token field sums with generic
_accumulate_modelson Pydantic usage objects. Numeric fields (including nested models andmodel_extracounters) add across retries; booleans and other non-numeric metadata are not treated as billable. OpenAI and Anthropic paths share this logic.OpenAI Responses reask appends a user correction when
RESPONSES_TOOLSvalidation fails but the output has no tool calls (e.g. reasoning-only), so retries include feedback instead of repeating the same request.Parallel tools in
patch_v2skipsprepare_response_modeland does not replaceresponse_modelwith the handler’s prepared wrapper for parallel modes, keeping rawIterable[...]hints so schemas and parsed results include every member type.Reviewed by Cursor Bugbot for commit bbddca1. Configure here.