Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Versioning: [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
## [1.15.5] - 2026-08-02

### Fixed
- **Package metadata**: Point the published distribution's repository URL at the current `567-labs/instructor` organization and validate it before release.
- **Retry usage accounting**: Accumulate nested and newly added numeric usage fields across OpenAI and Anthropic retries, including prediction, cache-write, cache-creation, and server-tool counters, without treating boolean metadata as billable usage. ([#2493](https://github.com/567-labs/instructor/issues/2493), [#2500](https://github.com/567-labs/instructor/pull/2500))
- **OpenAI Responses reask**: Add a fallback correction message when a `RESPONSES_TOOLS` response contains no tool calls (e.g. reasoning-only output), so retries carry validation feedback instead of resending the identical request. ([#2498](https://github.com/567-labs/instructor/pull/2498))
- **v2 parallel tools**: Preserve raw iterable type hints through the sync and async patch wrappers so parallel tool schemas and results retain every requested model type. ([#2501](https://github.com/567-labs/instructor/pull/2501))
Expand Down
8 changes: 8 additions & 0 deletions docs/concepts/from_provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,14 @@ client = instructor.from_provider(
"openai/gpt-4o-mini", organization="org-your-org-id", timeout=30.0
)

# OpenAI-compatible multi-model gateways (same client pattern via base_url)
# Example: DaoXE at https://api.daoxe.com/v1
client = instructor.from_provider(
"openai/gpt-4o-mini",
api_key="YOUR_GATEWAY_KEY",
base_url="https://api.daoxe.com/v1",
)

# For Anthropic
client = instructor.from_provider("anthropic/claude-3-5-sonnet", max_tokens=4096)

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ build-backend = "hatchling.build"
package = true

[project.urls]
repository = "https://github.com/instructor-ai/instructor"
repository = "https://github.com/567-labs/instructor"

[tool.pytest.ini_options]
markers = [
Expand Down
12 changes: 12 additions & 0 deletions scripts/prepare_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ def _project_version(root: Path) -> str:
return str(data["project"]["version"])


def _repository_url(root: Path) -> str:
data = _load_toml(root / "pyproject.toml")
return str(data["project"]["urls"]["repository"])


def _lock_version(root: Path) -> str:
data = _load_toml(root / "uv.lock")
matches = [
Expand Down Expand Up @@ -86,10 +91,17 @@ def prepare_release(
"""Validate version metadata and write the matching changelog section."""
version = _project_version(root)
lock_version = _lock_version(root)
repository_url = _repository_url(root)
if lock_version != version:
raise ValueError(
f"version mismatch: pyproject.toml={version}, uv.lock={lock_version}"
)
expected_repository_url = f"https://github.com/{REPOSITORY}"
if repository_url != expected_repository_url:
raise ValueError(
"repository URL mismatch: "
f"pyproject.toml={repository_url}, expected={expected_repository_url}"
)
if expected_version and expected_version != version:
raise ValueError(
f"expected version {expected_version}, but source declares {version}"
Expand Down
22 changes: 21 additions & 1 deletion tests/test_prepare_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@

def _write_release_files(root: Path, changelog: str) -> None:
(root / "pyproject.toml").write_text(
'[project]\nname = "instructor"\nversion = "1.2.3"\n', encoding="utf-8"
'[project]\nname = "instructor"\nversion = "1.2.3"\n'
'[project.urls]\nrepository = "https://github.com/567-labs/instructor"\n',
encoding="utf-8",
)
(root / "uv.lock").write_text(
'version = 1\n[[package]]\nname = "instructor"\nversion = "1.2.3"\n',
Expand Down Expand Up @@ -118,3 +120,21 @@ def test_prepare_release_requires_comparison_link(tmp_path: Path) -> None:

assert result.returncode == 2
assert "missing the [1.2.3] comparison link" in result.stderr


def test_prepare_release_rejects_stale_repository_url(tmp_path: Path) -> None:
_write_release_files(tmp_path, _changelog())
pyproject = tmp_path / "pyproject.toml"
pyproject.write_text(
pyproject.read_text(encoding="utf-8").replace(
"https://github.com/567-labs/instructor",
"https://github.com/instructor-ai/instructor",
),
encoding="utf-8",
)

result = _run(tmp_path)

assert result.returncode == 2
assert "repository URL mismatch" in result.stderr
assert "expected=https://github.com/567-labs/instructor" in result.stderr
Loading