Théo Deschamps
83f81d65af
fix(langchain): allow Gemini 3 models to use ProviderStrategy with tools ( #34464 )
2026-02-18 21:14:16 -05:00
ccurme
8f1bc0d3ae
feat(openai): support automatic server-side compaction ( #35212 )
2026-02-17 10:48:52 -05:00
Mason Daugherty
65c224a3da
chore(core): raise more descriptive model error in init_chat_model ( #35167 )
2026-02-11 11:09:06 -05:00
dependabot[bot]
de05838fca
chore(deps): bump the langchain-deps group across 3 directories with 40 updates ( #35129 )
...
Bumps the langchain-deps group with 10 updates in the /libs/core
directory:
| Package | From | To |
| --- | --- | --- |
| [langsmith](https://github.com/langchain-ai/langsmith-sdk ) | `0.6.0` |
`0.7.1` |
| [tenacity](https://github.com/jd/tenacity ) | `9.1.2` | `9.1.4` |
| [packaging](https://github.com/pypa/packaging ) | `25.0` | `26.0` |
| [uuid-utils](https://github.com/aminalaee/uuid-utils ) | `0.12.0` |
`0.14.0` |
| [ruff](https://github.com/astral-sh/ruff ) | `0.14.11` | `0.15.0` |
| [types-requests](https://github.com/typeshed-internal/stub_uploader ) |
`2.31.0.6` | `2.32.4.20260107` |
| [setuptools](https://github.com/pypa/setuptools ) | `78.1.1` | `82.0.0`
|
| [pytest](https://github.com/pytest-dev/pytest ) | `8.4.2` | `9.0.2` |
| [pytest-watcher](https://github.com/olzhasar/pytest-watcher ) | `0.4.3`
| `0.6.3` |
| [pytest-codspeed](https://github.com/CodSpeedHQ/pytest-codspeed ) |
`4.2.0` | `4.3.0` |
Bumps the langchain-deps group with 31 updates in the /libs/langchain
directory:
| Package | From | To |
| --- | --- | --- |
| [langsmith](https://github.com/langchain-ai/langsmith-sdk ) | `0.4.31`
| `0.7.1` |
| [packaging](https://github.com/pypa/packaging ) | `25.0` | `26.0` |
| [pydantic](https://github.com/pydantic/pydantic ) | `2.12.1` | `2.12.5`
|
| [ruff](https://github.com/astral-sh/ruff ) | `0.14.11` | `0.15.0` |
| [types-requests](https://github.com/typeshed-internal/stub_uploader ) |
`2.31.0.6` | `2.32.4.20260107` |
| [setuptools](https://github.com/pypa/setuptools ) | `80.9.0` | `82.0.0`
|
| [pytest](https://github.com/pytest-dev/pytest ) | `8.4.2` | `9.0.2` |
| [pytest-watcher](https://github.com/olzhasar/pytest-watcher ) | `0.4.3`
| `0.6.3` |
| [numpy](https://github.com/numpy/numpy ) | `1.26.4` | `2.2.6` |
| [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy ) | `2.0.43` |
`2.0.46` |
| [langchain-anthropic](https://github.com/langchain-ai/langchain ) |
`0.0.1.post1` | `1.3.2` |
|
[langchain-google-vertexai](https://github.com/langchain-ai/langchain-google )
| `2.1.2` | `3.2.2` |
|
[langchain-google-genai](https://github.com/langchain-ai/langchain-google )
| `2.1.12` | `4.2.0` |
| [langchain-fireworks](https://github.com/langchain-ai/langchain ) |
`1.0.0a1` | `1.1.0` |
| [langchain-ollama](https://github.com/langchain-ai/langchain ) |
`1.0.0a1` | `1.0.1` |
| [langchain-mistralai](https://github.com/langchain-ai/langchain ) |
`0.2.12` | `1.1.1` |
| [langchain-huggingface](https://github.com/langchain-ai/langchain ) |
`1.0.0` | `1.2.0` |
| [langchain-groq](https://github.com/langchain-ai/langchain ) |
`1.0.0a1` | `1.1.2` |
| [langchain-aws](https://github.com/langchain-ai/langchain-aws ) |
`1.0.0a1` | `1.2.3` |
| [langchain-deepseek](https://github.com/langchain-ai/langchain ) |
`1.0.0a1` | `1.0.1` |
| [langchain-xai](https://github.com/langchain-ai/langchain ) | `1.0.0a1`
| `1.2.2` |
| [langchain-perplexity](https://github.com/langchain-ai/langchain ) |
`1.0.0a1` | `1.1.0` |
| [pytest-cov](https://github.com/pytest-dev/pytest-cov ) | `4.1.0` |
`7.0.0` |
| [lark](https://github.com/lark-parser/lark ) | `1.3.0` | `1.3.1` |
| [wrapt](https://github.com/GrahamDumpleton/wrapt ) | `1.17.3` | `2.1.1`
|
| [python-dotenv](https://github.com/theskumar/python-dotenv ) | `1.1.1`
| `1.2.1` |
| langchainhub | `0.1.18` | `0.1.21` |
| [mypy-protobuf](https://github.com/nipunn1313/mypy-protobuf ) | `3.6.0`
| `5.0.0` |
| [types-pytz](https://github.com/typeshed-internal/stub_uploader ) |
`2023.4.0.20240130` | `2025.2.0.20251108` |
| [fastapi](https://github.com/fastapi/fastapi ) | `0.128.0` | `0.128.6`
|
| [playwright](https://github.com/microsoft/playwright-python ) |
`1.55.0` | `1.58.0` |
Bumps the langchain-deps group with 17 updates in the /libs/langchain_v1
directory:
| Package | From | To |
| --- | --- | --- |
| [pydantic](https://github.com/pydantic/pydantic ) | `2.12.4` | `2.12.5`
|
| [ruff](https://github.com/astral-sh/ruff ) | `0.14.11` | `0.15.0` |
| [pytest](https://github.com/pytest-dev/pytest ) | `8.4.2` | `9.0.2` |
| [pytest-watcher](https://github.com/olzhasar/pytest-watcher ) | `0.4.3`
| `0.6.3` |
|
[langchain-google-vertexai](https://github.com/langchain-ai/langchain-google )
| `3.0.3` | `3.2.2` |
|
[langchain-google-genai](https://github.com/langchain-ai/langchain-google )
| `3.0.3` | `4.2.0` |
| [langchain-fireworks](https://github.com/langchain-ai/langchain ) |
`1.0.0` | `1.1.0` |
| [langchain-ollama](https://github.com/langchain-ai/langchain ) |
`1.0.0` | `1.0.1` |
| [langchain-mistralai](https://github.com/langchain-ai/langchain ) |
`1.0.1` | `1.1.1` |
| [langchain-huggingface](https://github.com/langchain-ai/langchain ) |
`1.0.1` | `1.2.0` |
| [langchain-groq](https://github.com/langchain-ai/langchain ) | `1.0.1`
| `1.1.2` |
| [langchain-aws](https://github.com/langchain-ai/langchain-aws ) |
`1.0.0` | `1.2.3` |
| [langchain-xai](https://github.com/langchain-ai/langchain ) | `1.0.0` |
`1.2.2` |
| [langchain-perplexity](https://github.com/langchain-ai/langchain ) |
`1.0.0` | `1.1.0` |
| [wrapt](https://github.com/GrahamDumpleton/wrapt ) | `1.17.3` | `2.1.1`
|
| [langgraph](https://github.com/langchain-ai/langgraph ) | `1.0.7` |
`1.0.8` |
| [langchain-azure-ai](https://github.com/langchain-ai/langchain-azure )
| `1.0.3` | `1.0.4` |
Updates `langsmith` from 0.6.0 to 0.7.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/langchain-ai/langsmith-sdk/releases ">langsmith's
releases</a>.</em></p>
<blockquote>
<h2>v0.7.1</h2>
<h2>What's Changed</h2>
<ul>
<li>release(js): 0.5.0 by <a
href="https://github.com/jacoblee93 "><code>@jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2381 ">langchain-ai/langsmith-sdk#2381</a></li>
<li>fix(ci): Convert JS release workflow to use OIDC by <a
href="https://github.com/jacoblee93 "><code>@jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2383 ">langchain-ai/langsmith-sdk#2383</a></li>
<li>feat(js): run evaluations as examples complete by <a
href="https://github.com/bees "><code>@bees</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2349 ">langchain-ai/langsmith-sdk#2349</a></li>
<li>fix(js): Restore default concurrency behavior for JS eval runner by
<a href="https://github.com/jacoblee93 "><code>@jacoblee93</code></a> in
<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2385 ">langchain-ai/langsmith-sdk#2385</a></li>
<li>fix(js,py): Adds backcompat for old prompt cache API by <a
href="https://github.com/jacoblee93 "><code>@jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2386 ">langchain-ai/langsmith-sdk#2386</a></li>
<li>fix(js): Add system message visibility to Anthropic wrapper traces
by <a href="https://github.com/veeceey "><code>@veeceey</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2375 ">langchain-ai/langsmith-sdk#2375</a></li>
<li>release(py): 0.7.1 by <a
href="https://github.com/jacoblee93 "><code>@jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2388 ">langchain-ai/langsmith-sdk#2388</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/veeceey "><code>@veeceey</code></a> made
their first contribution in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2375 ">langchain-ai/langsmith-sdk#2375</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/langchain-ai/langsmith-sdk/compare/v0.7.0...v0.7.1 ">https://github.com/langchain-ai/langsmith-sdk/compare/v0.7.0...v0.7.1 </a></p>
<h2>v0.7.0</h2>
<h2>What's Changed</h2>
<ul>
<li>chore(deps): bump form-data from 4.0.3 to 4.0.5 in /js by <a
href="https://github.com/dependabot "><code>@dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2282 ">langchain-ai/langsmith-sdk#2282</a></li>
<li>chore(deps-dev): bump langchain from 0.3.29 to 0.3.37 in /js by <a
href="https://github.com/dependabot "><code>@dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2283 ">langchain-ai/langsmith-sdk#2283</a></li>
<li>chore(deps): bump vite from 6.3.5 to 6.4.1 in /js by <a
href="https://github.com/dependabot "><code>@dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2284 ">langchain-ai/langsmith-sdk#2284</a></li>
<li>chore:deps by <a
href="https://github.com/jkennedyvz "><code>@jkennedyvz</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2356 ">langchain-ai/langsmith-sdk#2356</a></li>
<li>chore(deps): bump python-multipart from 0.0.21 to 0.0.22 in /python
by <a
href="https://github.com/dependabot "><code>@dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2351 ">langchain-ai/langsmith-sdk#2351</a></li>
<li>chore(deps): bump protobuf from 6.33.2 to 6.33.5 in /python by <a
href="https://github.com/dependabot "><code>@dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2352 ">langchain-ai/langsmith-sdk#2352</a></li>
<li>chore(deps): bump pyasn1 from 0.6.1 to 0.6.2 in /python by <a
href="https://github.com/dependabot "><code>@dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2353 ">langchain-ai/langsmith-sdk#2353</a></li>
<li>chore(deps-dev): bump esbuild from 0.20.2 to 0.25.0 in
/js/internal/environment_tests/test-exports-esbuild in the npm_and_yarn
group across 1 directory by <a
href="https://github.com/dependabot "><code>@dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2354 ">langchain-ai/langsmith-sdk#2354</a></li>
<li>chore(deps): bump jws from 4.0.0 to 4.0.1 in /js by <a
href="https://github.com/dependabot "><code>@dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2355 ">langchain-ai/langsmith-sdk#2355</a></li>
<li>chore(deps): bump actions/setup-node from 3 to 6 by <a
href="https://github.com/dependabot "><code>@dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2357 ">langchain-ai/langsmith-sdk#2357</a></li>
<li>chore(deps): bump actions/github-script from 6 to 8 by <a
href="https://github.com/dependabot "><code>@dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2358 ">langchain-ai/langsmith-sdk#2358</a></li>
<li>chore(deps): bump actions/checkout from 2 to 6 by <a
href="https://github.com/dependabot "><code>@dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2359 ">langchain-ai/langsmith-sdk#2359</a></li>
<li>chore(deps): bump astral-sh/setup-uv from 6 to 7 by <a
href="https://github.com/dependabot "><code>@dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2360 ">langchain-ai/langsmith-sdk#2360</a></li>
<li>chore(deps): bump actions/cache from 4 to 5 by <a
href="https://github.com/dependabot "><code>@dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2361 ">langchain-ai/langsmith-sdk#2361</a></li>
<li>chore(deps-dev): bump ty from 0.0.10 to 0.0.15 in /python in the
py-minor-and-patch group by <a
href="https://github.com/dependabot "><code>@dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2362 ">langchain-ai/langsmith-sdk#2362</a></li>
<li>chore(deps): update httpx requirement from <0.28.0,>=0.23.0 to
>=0.23.0,<0.29.0 in /python by <a
href="https://github.com/dependabot "><code>@dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2363 ">langchain-ai/langsmith-sdk#2363</a></li>
<li>chore(deps-dev): bump eslint-plugin-prettier from 4.2.1 to 4.2.5 in
/js by <a
href="https://github.com/dependabot "><code>@dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2366 ">langchain-ai/langsmith-sdk#2366</a></li>
<li>chore(deps-dev): bump babel-jest from 29.7.0 to 30.2.0 in /js by <a
href="https://github.com/dependabot "><code>@dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2365 ">langchain-ai/langsmith-sdk#2365</a></li>
<li>chore: adding workflow perms by <a
href="https://github.com/jkennedyvz "><code>@jkennedyvz</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2367 ">langchain-ai/langsmith-sdk#2367</a></li>
<li>fix: esbuild CVE dependabot 78 by <a
href="https://github.com/jkennedyvz "><code>@jkennedyvz</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2369 ">langchain-ai/langsmith-sdk#2369</a></li>
<li>fix(deps): resolve glob CLI command injection (CVE-2025-64756) by <a
href="https://github.com/jkennedyvz "><code>@jkennedyvz</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2368 ">langchain-ai/langsmith-sdk#2368</a></li>
<li>fix(deps): resolve js-yaml prototype pollution vulnerability by <a
href="https://github.com/jkennedyvz "><code>@jkennedyvz</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2370 ">langchain-ai/langsmith-sdk#2370</a></li>
<li>chore(deps): bump the js-minor-and-patch group in /js with 20
updates by <a
href="https://github.com/dependabot "><code>@dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2364 ">langchain-ai/langsmith-sdk#2364</a></li>
<li>chore: rm unused fn by <a
href="https://github.com/hinthornw "><code>@hinthornw</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2346 ">langchain-ai/langsmith-sdk#2346</a></li>
<li>feat(py,js): Use global singleton for prompt cache, enable by
default by <a
href="https://github.com/jacoblee93 "><code>@jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2371 ">langchain-ai/langsmith-sdk#2371</a></li>
<li>chore: Support jwt auth in replicas by <a
href="https://github.com/hinthornw "><code>@hinthornw</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2293 ">langchain-ai/langsmith-sdk#2293</a></li>
<li>release(py): 0.7.0 by <a
href="https://github.com/jacoblee93 "><code>@jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2382 ">langchain-ai/langsmith-sdk#2382</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/jkennedyvz "><code>@jkennedyvz</code></a> made
their first contribution in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2356 ">langchain-ai/langsmith-sdk#2356</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/langchain-ai/langsmith-sdk/compare/v0.6.9...v0.7.0 ">https://github.com/langchain-ai/langsmith-sdk/compare/v0.6.9...v0.7.0 </a></p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ff55b58836 "><code>ff55b58</code></a>
release(py): 0.7.1 (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2388 ">#2388</a>)</li>
<li><a
href="c41e3fbc85 "><code>c41e3fb</code></a>
fix(js): Add system message visibility to Anthropic wrapper traces (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2375 ">#2375</a>)</li>
<li><a
href="ffc3769a46 "><code>ffc3769</code></a>
fix(js,py): Adds backcompat for old prompt cache API (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2386 ">#2386</a>)</li>
<li><a
href="de02f1deab "><code>de02f1d</code></a>
fix(js): Restore default concurrency behavior for JS eval runner (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2385 ">#2385</a>)</li>
<li><a
href="2083f3b149 "><code>2083f3b</code></a>
feat(js): run evaluations as examples complete (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2349 ">#2349</a>)</li>
<li><a
href="c231c07b34 "><code>c231c07</code></a>
fix(ci): Convert JS release workflow to use OIDC (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2383 ">#2383</a>)</li>
<li><a
href="9587a467a3 "><code>9587a46</code></a>
release(js): 0.5.0 (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2381 ">#2381</a>)</li>
<li><a
href="c9f9c9b49d "><code>c9f9c9b</code></a>
release(py): 0.7.0 (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2382 ">#2382</a>)</li>
<li><a
href="0fbbc113bc "><code>0fbbc11</code></a>
chore: Support jwt auth in replicas (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2293 ">#2293</a>)</li>
<li><a
href="024cd6cbed "><code>024cd6c</code></a>
feat(py,js): Use global singleton for prompt cache, enable by default
(<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2371 ">#2371</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/langchain-ai/langsmith-sdk/compare/v0.6.0...v0.7.1 ">compare
view</a></li>
</ul>
</details>
<br />
Updates `tenacity` from 9.1.2 to 9.1.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/jd/tenacity/releases ">tenacity's
releases</a>.</em></p>
<blockquote>
<h2>9.1.4</h2>
<h2>What's Changed</h2>
<ul>
<li>Fix <code>retry()</code> annotations with async <code>sleep=</code>
function by <a
href="https://github.com/Zac-HD "><code>@Zac-HD</code></a> in <a
href="https://redirect.github.com/jd/tenacity/pull/555 ">jd/tenacity#555</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/jd/tenacity/compare/9.1.3...9.1.4 ">https://github.com/jd/tenacity/compare/9.1.3...9.1.4 </a></p>
<h2>9.1.3</h2>
<h2>What's Changed</h2>
<ul>
<li>Apply formatting to num seconds in before_sleep_log by <a
href="https://github.com/aguinane "><code>@aguinane</code></a> in <a
href="https://redirect.github.com/jd/tenacity/pull/489 ">jd/tenacity#489</a></li>
<li>Support Python 3.14 by <a
href="https://github.com/sandrobonazzola "><code>@sandrobonazzola</code></a>
in <a
href="https://redirect.github.com/jd/tenacity/pull/528 ">jd/tenacity#528</a></li>
<li>Typing: Accept non-standard logger in helpers logging something by
<a href="https://github.com/k4nar "><code>@k4nar</code></a> in <a
href="https://redirect.github.com/jd/tenacity/pull/540 ">jd/tenacity#540</a></li>
<li>feat(wait): add <code>wait_exception</code> strategy by <a
href="https://github.com/capitan-davide "><code>@capitan-davide</code></a>
in <a
href="https://redirect.github.com/jd/tenacity/pull/541 ">jd/tenacity#541</a></li>
<li>docs: fix syntax error in wait_chain docstring example by <a
href="https://github.com/VedantMadane "><code>@VedantMadane</code></a>
in <a
href="https://redirect.github.com/jd/tenacity/pull/548 ">jd/tenacity#548</a></li>
<li>chore: drop Python 3.9 support (EOL) by <a
href="https://github.com/Zac-HD "><code>@Zac-HD</code></a> in <a
href="https://redirect.github.com/jd/tenacity/pull/552 ">jd/tenacity#552</a></li>
<li>Support async sleep for sync fn-to-retry by <a
href="https://github.com/Zac-HD "><code>@Zac-HD</code></a> in <a
href="https://redirect.github.com/jd/tenacity/pull/551 ">jd/tenacity#551</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/aguinane "><code>@aguinane</code></a>
made their first contribution in <a
href="https://redirect.github.com/jd/tenacity/pull/489 ">jd/tenacity#489</a></li>
<li><a
href="https://github.com/sandrobonazzola "><code>@sandrobonazzola</code></a>
made their first contribution in <a
href="https://redirect.github.com/jd/tenacity/pull/528 ">jd/tenacity#528</a></li>
<li><a href="https://github.com/k4nar "><code>@k4nar</code></a> made
their first contribution in <a
href="https://redirect.github.com/jd/tenacity/pull/540 ">jd/tenacity#540</a></li>
<li><a
href="https://github.com/capitan-davide "><code>@capitan-davide</code></a>
made their first contribution in <a
href="https://redirect.github.com/jd/tenacity/pull/541 ">jd/tenacity#541</a></li>
<li><a
href="https://github.com/VedantMadane "><code>@VedantMadane</code></a>
made their first contribution in <a
href="https://redirect.github.com/jd/tenacity/pull/548 ">jd/tenacity#548</a></li>
<li><a href="https://github.com/Zac-HD "><code>@Zac-HD</code></a> made
their first contribution in <a
href="https://redirect.github.com/jd/tenacity/pull/552 ">jd/tenacity#552</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/jd/tenacity/compare/9.1.2...9.1.3 ">https://github.com/jd/tenacity/compare/9.1.2...9.1.3 </a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="d4e868d6b8 "><code>d4e868d</code></a>
Fix <code>retry()</code> annotations with async <code>sleep=</code>
function (<a
href="https://redirect.github.com/jd/tenacity/issues/555 ">#555</a>)</li>
<li><a
href="24415ebbca "><code>24415eb</code></a>
support async sleep for sync fn (<a
href="https://redirect.github.com/jd/tenacity/issues/551 ">#551</a>)</li>
<li><a
href="3bf33b4409 "><code>3bf33b4</code></a>
chore: drop Python 3.9 support (EOL) (<a
href="https://redirect.github.com/jd/tenacity/issues/552 ">#552</a>)</li>
<li><a
href="7027da31d2 "><code>7027da3</code></a>
chore(deps): bump the github-actions group with 2 updates (<a
href="https://redirect.github.com/jd/tenacity/issues/550 ">#550</a>)</li>
<li><a
href="21ae7d0cc2 "><code>21ae7d0</code></a>
docs: fix syntax error in wait_chain docstring example (<a
href="https://redirect.github.com/jd/tenacity/issues/548 ">#548</a>)</li>
<li><a
href="ef12c9ed1d "><code>ef12c9e</code></a>
chore(deps): bump actions/checkout in the github-actions group (<a
href="https://redirect.github.com/jd/tenacity/issues/547 ">#547</a>)</li>
<li><a
href="c35a4b341e "><code>c35a4b3</code></a>
chore(deps): bump the github-actions group with 2 updates (<a
href="https://redirect.github.com/jd/tenacity/issues/545 ">#545</a>)</li>
<li><a
href="e792bbaf0c "><code>e792bba</code></a>
ci: fix mypy (<a
href="https://redirect.github.com/jd/tenacity/issues/546 ">#546</a>)</li>
<li><a
href="0f55245b8d "><code>0f55245</code></a>
ci: remove reno requirements (<a
href="https://redirect.github.com/jd/tenacity/issues/542 ">#542</a>)</li>
<li><a
href="815c34fec2 "><code>815c34f</code></a>
feat(wait): add <code>wait_exception</code> strategy (<a
href="https://redirect.github.com/jd/tenacity/issues/541 ">#541</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/jd/tenacity/compare/9.1.2...9.1.4 ">compare
view</a></li>
</ul>
</details>
<br />
Updates `packaging` from 25.0 to 26.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pypa/packaging/releases ">packaging's
releases</a>.</em></p>
<blockquote>
<h2>26.0</h2>
<p>Read about the performance improvements here: <a
href="https://iscinumpy.dev/post/packaging-faster ">https://iscinumpy.dev/post/packaging-faster </a>.</p>
<h2>What's Changed</h2>
<p>Features:</p>
<ul>
<li>PEP 751: support pylock by <a
href="https://github.com/sbidoul "><code>@sbidoul</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/900 ">pypa/packaging#900</a></li>
<li>PEP 794: import name metadata by <a
href="https://github.com/brettcannon "><code>@brettcannon</code></a> in
<a
href="https://redirect.github.com/pypa/packaging/pull/948 ">pypa/packaging#948</a></li>
<li>Support writing metadata by <a
href="https://github.com/henryiii "><code>@henryiii</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/846 ">pypa/packaging#846</a></li>
<li>Support <code>__replace__</code> for <code>Version</code> by <a
href="https://github.com/henryiii "><code>@henryiii</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/1003 ">pypa/packaging#1003</a></li>
<li>Support positional pattern matching for <code>Version</code> and
<code>Specifier</code> by <a
href="https://github.com/henryiii "><code>@henryiii</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/1004 ">pypa/packaging#1004</a></li>
</ul>
<p>Behavior adaptations:</p>
<ul>
<li>PEP 440 handling of prereleases for <code>Specifier.contains</code>,
<code>SpecifierSet.contains</code>, and <code>SpecifierSet.filter</code>
by <a
href="https://github.com/notatallshaw "><code>@notatallshaw</code></a>
in <a
href="https://redirect.github.com/pypa/packaging/pull/897 ">pypa/packaging#897</a></li>
<li>Handle PEP 440 edge case in <code>SpecifierSet.filter</code> by <a
href="https://github.com/notatallshaw "><code>@notatallshaw</code></a>
in <a
href="https://redirect.github.com/pypa/packaging/pull/942 ">pypa/packaging#942</a></li>
<li>Adjust arbitrary equality intersection preservation in
<code>SpecifierSet</code> by <a
href="https://github.com/notatallshaw "><code>@notatallshaw</code></a>
in <a
href="https://redirect.github.com/pypa/packaging/pull/951 ">pypa/packaging#951</a></li>
<li>Return <code>False</code> instead of raising for
<code>.contains</code> with invalid version by <a
href="https://github.com/Liam-DeVoe "><code>@Liam-DeVoe</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/932 ">pypa/packaging#932</a></li>
<li>Support arbitrary equality on arbitrary strings for
<code>Specifier</code> and <code>SpecifierSet</code>'s
<code>filter</code> and <code>contains</code> method. by <a
href="https://github.com/notatallshaw "><code>@notatallshaw</code></a>
in <a
href="https://redirect.github.com/pypa/packaging/pull/954 ">pypa/packaging#954</a></li>
<li>Only try to parse as <code>Version</code> on certain marker keys,
return <code>False</code> on unequal ordered comparsions by <a
href="https://github.com/JP-Ellis "><code>@JP-Ellis</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/939 ">pypa/packaging#939</a></li>
</ul>
<p>Fixes:</p>
<ul>
<li>Update <code>_hash</code> when unpickling <code>Tag()</code> by <a
href="https://github.com/dholth "><code>@dholth</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/860 ">pypa/packaging#860</a></li>
<li>Correct comment and simplify implicit prerelease handling in
<code>Specifier.prereleases</code> by <a
href="https://github.com/notatallshaw "><code>@notatallshaw</code></a>
in <a
href="https://redirect.github.com/pypa/packaging/pull/896 ">pypa/packaging#896</a></li>
<li>Use explicit <code>_GLibCVersion</code> <code>NamedTuple</code> in
<code>_manylinux</code> by <a
href="https://github.com/cthoyt "><code>@cthoyt</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/868 ">pypa/packaging#868</a></li>
<li>Detect invalid license expressions containing <code>()</code> by <a
href="https://github.com/bwoodsend "><code>@bwoodsend</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/879 ">pypa/packaging#879</a></li>
<li>Correct regex for metadata <code>'name'</code> format by <a
href="https://github.com/di "><code>@di</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/925 ">pypa/packaging#925</a></li>
<li>Improve the message around expecting a semicolon by <a
href="https://github.com/pradyunsg "><code>@pradyunsg</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/833 ">pypa/packaging#833</a></li>
<li>Support nested parens in license expressions by <a
href="https://github.com/Liam-DeVoe "><code>@Liam-DeVoe</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/931 ">pypa/packaging#931</a></li>
<li>Add space before at symbol in <code>Requirements</code> string by <a
href="https://github.com/henryiii "><code>@henryiii</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/953 ">pypa/packaging#953</a></li>
<li>A root logger use found by ruff LOG, use <code>packaging</code>
logger instead by <a
href="https://github.com/henryiii "><code>@henryiii</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/965 ">pypa/packaging#965</a></li>
<li>Better support for subclassing <code>Marker</code> and
<code>Requirement</code> by <a
href="https://github.com/henryiii "><code>@henryiii</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/1022 ">pypa/packaging#1022</a></li>
<li>Normalize all extras, not just if it comes first by <a
href="https://github.com/henryiii "><code>@henryiii</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/1024 ">pypa/packaging#1024</a></li>
<li>Don't produce a broken repr if <code>Marker</code> fails to
construct by <a
href="https://github.com/henryiii "><code>@henryiii</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/1033 ">pypa/packaging#1033</a></li>
</ul>
<p>Performance:</p>
<ul>
<li>Avoid recompiling regexes in the tokenizer for a 3x speedup by <a
href="https://github.com/hauntsaninja "><code>@hauntsaninja</code></a>
in <a
href="https://redirect.github.com/pypa/packaging/pull/1019 ">pypa/packaging#1019</a></li>
<li>Improve performance in <code>_manylinux.py</code> by <a
href="https://github.com/cthoyt "><code>@cthoyt</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/869 ">pypa/packaging#869</a></li>
<li>Minor cleanups to <code>Version</code> by <a
href="https://github.com/bearomorphism "><code>@bearomorphism</code></a>
in <a
href="https://redirect.github.com/pypa/packaging/pull/913 ">pypa/packaging#913</a></li>
<li>Skip redundant creation of <code>Version</code>s in specifier
comparison by <a
href="https://github.com/notatallshaw "><code>@notatallshaw</code></a>
in <a
href="https://redirect.github.com/pypa/packaging/pull/986 ">pypa/packaging#986</a></li>
<li>Cache <code>Specifier</code>'s Version by <a
href="https://github.com/notatallshaw "><code>@notatallshaw</code></a>
in <a
href="https://redirect.github.com/pypa/packaging/pull/985 ">pypa/packaging#985</a></li>
<li>Make <code>Version</code> a little faster by <a
href="https://github.com/henryiii "><code>@henryiii</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/987 ">pypa/packaging#987</a></li>
<li>Minor <code>Version</code> regex cleanup by <a
href="https://github.com/henryiii "><code>@henryiii</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/990 ">pypa/packaging#990</a></li>
<li>Faster regex on Python 3.11.5+ by <a
href="https://github.com/henryiii "><code>@henryiii</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/988 ">pypa/packaging#988</a>
and <a
href="https://redirect.github.com/pypa/packaging/pull/1055 ">pypa/packaging#1055</a></li>
<li>Lazily calculate <code>_key</code> in <code>Version</code> by <a
href="https://github.com/notatallshaw "><code>@notatallshaw</code></a>
in <a
href="https://redirect.github.com/pypa/packaging/pull/989 ">pypa/packaging#989</a>
and regression for <code>packaging_legacy</code> fixed by <a
href="https://github.com/henryiii "><code>@henryiii</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/1048 ">pypa/packaging#1048</a></li>
<li>Faster <code>canonicalize_version</code> by <a
href="https://github.com/henryiii "><code>@henryiii</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/993 ">pypa/packaging#993</a></li>
<li>Use <code>fullmatch</code> in a couple more places by <a
href="https://github.com/henryiii "><code>@henryiii</code></a> in <a
href="https://redirect.github.com/pypa/packaging/pull/992 ">pypa/packaging#992</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pypa/packaging/blob/main/CHANGELOG.rst ">packaging's
changelog</a>.</em></p>
<blockquote>
<p>26.0 - 2026-01-20</p>
<pre><code>
Features:
<ul>
<li>PEP 751: support pylock (:pull:<code>900</code>)</li>
<li>PEP 794: import name metadata (:pull:<code>948</code>)</li>
<li>Support for writing metadata to a file (:pull:<code>846</code>)</li>
<li>Support <code>__replace__</code> on Version
(:pull:<code>1003</code>)</li>
<li>Support positional pattern matching for <code>Version</code> and
<code>SpecifierSet</code> (:pull:<code>1004</code>)</li>
</ul>
<p>Behavior adaptations:</p>
<ul>
<li>PEP 440 handling of prereleases for <code>Specifier.contains</code>,
<code>SpecifierSet.contains</code>, and <code>SpecifierSet.filter</code>
(:pull:<code>897</code>)</li>
<li>Handle PEP 440 edge case in <code>SpecifierSet.filter</code>
(:pull:<code>942</code>)</li>
<li>Adjust arbitrary equality intersection preservation in
<code>SpecifierSet</code> (:pull:<code>951</code>)</li>
<li>Return <code>False</code> instead of raising for
<code>.contains</code> with invalid version
(:pull:<code>932</code>)</li>
<li>Support arbitrary equality on arbitrary strings for
<code>Specifier</code> and <code>SpecifierSet</code>'s
<code>filter</code> and <code>contains</code> method.
(:pull:<code>954</code>)</li>
<li>Only try to parse as <code>Version</code> on certain marker keys,
return <code>False</code> on unequal ordered comparisons
(:pull:<code>939</code>)</li>
</ul>
<p>Fixes:</p>
<ul>
<li>Update <code>_hash</code> when unpickling <code>Tag()</code>
(:pull:<code>860</code>)</li>
<li>Correct comment and simplify implicit prerelease handling in
<code>Specifier.prereleases</code> (:pull:<code>896</code>)</li>
<li>Use explicit <code>_GLibCVersion</code> <code>NamedTuple</code> in
<code>_manylinux</code> (:pull:<code>868</code>)</li>
<li>Detect invalid license expressions containing <code>()</code>
(:pull:<code>879</code>)</li>
<li>Correct regex for metadata <code>'name'</code> format
(:pull:<code>925</code>)</li>
<li>Improve the message around expecting a semicolon
(:pull:<code>833</code>)</li>
<li>Support nested parens in license expressions
(:pull:<code>931</code>)</li>
<li>Add space before at symbol in <code>Requirements</code> string
(:pull:<code>953</code>)</li>
<li>A root logger use found, use a <code>packaging</code> logger instead
(:pull:<code>965</code>)</li>
<li>Better support for subclassing <code>Marker</code> and
<code>Requirement</code> (:pull:<code>1022</code>)</li>
<li>Normalize all extras, not just if it comes first
(:pull:<code>1024</code>)</li>
<li>Don't produce a broken repr if <code>Marker</code> fails to
construct (:pull:<code>1033</code>)</li>
</ul>
<p>Performance:</p>
<ul>
<li>Avoid recompiling regexes in the tokenizer for a 3x speedup
(:pull:<code>1019</code>)</li>
<li>Improve performance in <code>_manylinux.py</code>
(:pull:<code>869</code>)</li>
<li>Minor cleanups to <code>Version</code> (:pull:<code>913</code>)</li>
<li>Skip redundant creation of <code>Version</code>'s in specifier
comparison (:pull:<code>986</code>)</li>
<li>Cache the <code>Specifier</code>'s <code>Version</code>
(:pull:<code>985</code>)</li>
<li>Make <code>Version</code> a little faster
(:pull:<code>987</code>)</li>
<li>Minor <code>Version</code> regex cleanup
(:pull:<code>990</code>)</li>
<li>Faster regex on Python 3.11.5+ for <code>Version</code>
(:pull:<code>988</code>, :pull:<code>1055</code>)</li>
<li>Lazily calculate <code>_key</code> in <code>Version</code>
(:pull:<code>989</code>, :pull:<code>1048</code>)</li>
<li>Faster <code>canonicalize_version</code>
(:pull:<code>993</code>)</li>
<li>Use <code>re.fullmatch</code> in a couple more places
(:pull:<code>992</code>, :pull:<code>1029</code>)</li>
<li>Use <code>map</code> instead of generator
(:pull:<code>996</code>)</li>
<li>Deprecate <code>._version</code> (<code>_Version</code>, a
<code>NamedTuple</code>) (:pull:<code>995</code>,
:pull:<code>1062</code>)<br />
</tr></table><br />
</code></pre></li>
</ul>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="3b77a26f5a "><code>3b77a26</code></a>
Bump for release</li>
<li><a
href="31371cce59 "><code>31371cc</code></a>
docs: prepare for 26.0 final (<a
href="https://redirect.github.com/pypa/packaging/issues/1063 ">#1063</a>)</li>
<li><a
href="9627a8821f "><code>9627a88</code></a>
perf: dual replace (<a
href="https://redirect.github.com/pypa/packaging/issues/1064 ">#1064</a>)</li>
<li><a
href="d5398b8bc1 "><code>d5398b8</code></a>
fix: restore ._version as a compat shim (<a
href="https://redirect.github.com/pypa/packaging/issues/1062 ">#1062</a>)</li>
<li><a
href="3a7b600a12 "><code>3a7b600</code></a>
Bump for development</li>
<li><a
href="d4eefdccf9 "><code>d4eefdc</code></a>
Bump for release</li>
<li><a
href="46189124fb "><code>4618912</code></a>
docs: prepare for 26.0rc3 (<a
href="https://redirect.github.com/pypa/packaging/issues/1060 ">#1060</a>)</li>
<li><a
href="0cf1b41b4b "><code>0cf1b41</code></a>
ci: test on first public release of CPythons (<a
href="https://redirect.github.com/pypa/packaging/issues/1056 ">#1056</a>)</li>
<li><a
href="716beb1c0a "><code>716beb1</code></a>
perf: 10% faster stripping zeros (<a
href="https://redirect.github.com/pypa/packaging/issues/1058 ">#1058</a>)</li>
<li><a
href="350a230670 "><code>350a230</code></a>
fix: support CPython 3.11.0-3.11.4 and older PyPy3.11 (<a
href="https://redirect.github.com/pypa/packaging/issues/1055 ">#1055</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/pypa/packaging/compare/25.0...26.0 ">compare
view</a></li>
</ul>
</details>
<br />
Updates `uuid-utils` from 0.12.0 to 0.14.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/aminalaee/uuid-utils/releases ">uuid-utils's
releases</a>.</em></p>
<blockquote>
<h2>0.14.0</h2>
<h3>Added</h3>
<ul>
<li>Call reseed RNG in fork process in <a
href="https://redirect.github.com/aminalaee/uuid-utils/pull/108 ">aminalaee/uuid-utils#108</a></li>
<li>Change <code>getnode</code> to be compatible with stdlib <a
href="https://redirect.github.com/aminalaee/uuid-utils/pull/113 ">aminalaee/uuid-utils#113</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/aminalaee/uuid-utils/compare/0.13.0...0.14.0 ">https://github.com/aminalaee/uuid-utils/compare/0.13.0...0.14.0 </a></p>
<h2>0.13.0</h2>
<h3>Added</h3>
<ul>
<li>add <code>NIL</code> and <code>MAX</code> UUID by <a
href="https://github.com/aminalaee "><code>@aminalaee</code></a> in <a
href="https://redirect.github.com/aminalaee/uuid-utils/pull/107 ">aminalaee/uuid-utils#107</a></li>
</ul>
<h3>Fixed</h3>
<ul>
<li>remove duplicate pyo3 features by <a
href="https://github.com/chirizxc "><code>@chirizxc</code></a> in <a
href="https://redirect.github.com/aminalaee/uuid-utils/pull/96 ">aminalaee/uuid-utils#96</a></li>
<li>bump <code>uuid</code> by <a
href="https://github.com/chirizxc "><code>@chirizxc</code></a> in <a
href="https://redirect.github.com/aminalaee/uuid-utils/pull/98 ">aminalaee/uuid-utils#98</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/aminalaee/uuid-utils/compare/0.12.0...0.13.0 ">https://github.com/aminalaee/uuid-utils/compare/0.12.0...0.13.0 </a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c555f9887c "><code>c555f98</code></a>
Version 0.14.0 (<a
href="https://redirect.github.com/aminalaee/uuid-utils/issues/114 ">#114</a>)</li>
<li><a
href="842cc6140e "><code>842cc61</code></a>
Change <code>getnode</code> to be compatible with python (<a
href="https://redirect.github.com/aminalaee/uuid-utils/issues/113 ">#113</a>)</li>
<li><a
href="1294ee9691 "><code>1294ee9</code></a>
Use PyPI trusted publisher with uv (<a
href="https://redirect.github.com/aminalaee/uuid-utils/issues/112 ">#112</a>)</li>
<li><a
href="5fd983919b "><code>5fd9839</code></a>
Call reseed in fork process (<a
href="https://redirect.github.com/aminalaee/uuid-utils/issues/108 ">#108</a>)</li>
<li><a
href="51ed31d6b4 "><code>51ed31d</code></a>
chore: cleanup (<a
href="https://redirect.github.com/aminalaee/uuid-utils/issues/111 ">#111</a>)</li>
<li><a
href="3072e53b6f "><code>3072e53</code></a>
chore: docs and benchmarks</li>
<li><a
href="152f8c617b "><code>152f8c6</code></a>
add third-party tests github action (<a
href="https://redirect.github.com/aminalaee/uuid-utils/issues/110 ">#110</a>)</li>
<li><a
href="10def287dd "><code>10def28</code></a>
Version 0.13.0 (<a
href="https://redirect.github.com/aminalaee/uuid-utils/issues/109 ">#109</a>)</li>
<li><a
href="ed464fabe4 "><code>ed464fa</code></a>
update typehints</li>
<li><a
href="4467139f3b "><code>4467139</code></a>
update docs and classifiers</li>
<li>Additional commits viewable in <a
href="https://github.com/aminalaee/uuid-utils/compare/0.12.0...0.14.0 ">compare
view</a></li>
</ul>
</details>
<br />
Updates `ruff` from 0.14.11 to 0.15.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/ruff/releases ">ruff's
releases</a>.</em></p>
<blockquote>
<h2>0.15.0</h2>
<h2>Release Notes</h2>
<p>Released on 2026-02-03.</p>
<p>Check out the <a href="https://astral.sh/blog/ruff-v0.15.0 ">blog
post</a> for a migration guide and overview of the changes!</p>
<h3>Breaking changes</h3>
<ul>
<li>
<p>Ruff now formats your code according to the 2026 style guide. See the
formatter section below or in the blog post for a detailed list of
changes.</p>
</li>
<li>
<p>The linter now supports block suppression comments. For example, to
suppress <code>N803</code> for all parameters in this function:</p>
<pre lang="python"><code># ruff: disable[N803]
def foo(
legacyArg1,
legacyArg2,
legacyArg3,
legacyArg4,
): ...
# ruff: enable[N803]
</code></pre>
<p>See the <a
href="https://docs.astral.sh/ruff/linter/#block-level ">documentation</a>
for more details.</p>
</li>
<li>
<p>The <code>ruff:alpine</code> Docker image is now based on Alpine 3.23
(up from 3.21).</p>
</li>
<li>
<p>The <code>ruff:debian</code> and <code>ruff:debian-slim</code> Docker
images are now based on Debian 13 "Trixie" instead of Debian
12 "Bookworm."</p>
</li>
<li>
<p>Binaries for the <code>ppc64</code> (64-bit big-endian PowerPC)
architecture are no longer included in our releases. It should still be
possible to build Ruff manually for this platform, if needed.</p>
</li>
<li>
<p>Ruff now resolves all <code>extend</code>ed configuration files
before falling back on a default Python version.</p>
</li>
</ul>
<h3>Stabilization</h3>
<p>The following rules have been stabilized and are no longer in
preview:</p>
<ul>
<li><a
href="https://docs.astral.sh/ruff/rules/blocking-http-call-httpx-in-async-function "><code>blocking-http-call-httpx-in-async-function</code></a>
(<code>ASYNC212</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/blocking-path-method-in-async-function "><code>blocking-path-method-in-async-function</code></a>
(<code>ASYNC240</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/blocking-input-in-async-function "><code>blocking-input-in-async-function</code></a>
(<code>ASYNC250</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/map-without-explicit-strict "><code>map-without-explicit-strict</code></a>
(<code>B912</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/if-exp-instead-of-or-operator "><code>if-exp-instead-of-or-operator</code></a>
(<code>FURB110</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/single-item-membership-test "><code>single-item-membership-test</code></a>
(<code>FURB171</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/missing-maxsplit-arg "><code>missing-maxsplit-arg</code></a>
(<code>PLC0207</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/unnecessary-lambda "><code>unnecessary-lambda</code></a>
(<code>PLW0108</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/unnecessary-empty-iterable-within-deque-call "><code>unnecessary-empty-iterable-within-deque-call</code></a>
(<code>RUF037</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/in-empty-collection "><code>in-empty-collection</code></a>
(<code>RUF060</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/legacy-form-pytest-raises "><code>legacy-form-pytest-raises</code></a>
(<code>RUF061</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/non-octal-permissions "><code>non-octal-permissions</code></a>
(<code>RUF064</code>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md ">ruff's
changelog</a>.</em></p>
<blockquote>
<h2>0.15.0</h2>
<p>Released on 2026-02-03.</p>
<p>Check out the <a href="https://astral.sh/blog/ruff-v0.15.0 ">blog
post</a> for a migration
guide and overview of the changes!</p>
<h3>Breaking changes</h3>
<ul>
<li>
<p>Ruff now formats your code according to the 2026 style guide. See the
formatter section below or in the blog post for a detailed list of
changes.</p>
</li>
<li>
<p>The linter now supports block suppression comments. For example, to
suppress <code>N803</code> for all parameters in this function:</p>
<pre lang="python"><code># ruff: disable[N803]
def foo(
legacyArg1,
legacyArg2,
legacyArg3,
legacyArg4,
): ...
# ruff: enable[N803]
</code></pre>
<p>See the <a
href="https://docs.astral.sh/ruff/linter/#block-level ">documentation</a>
for more details.</p>
</li>
<li>
<p>The <code>ruff:alpine</code> Docker image is now based on Alpine 3.23
(up from 3.21).</p>
</li>
<li>
<p>The <code>ruff:debian</code> and <code>ruff:debian-slim</code> Docker
images are now based on Debian 13 "Trixie" instead of Debian
12 "Bookworm."</p>
</li>
<li>
<p>Binaries for the <code>ppc64</code> (64-bit big-endian PowerPC)
architecture are no longer included in our releases. It should still be
possible to build Ruff manually for this platform, if needed.</p>
</li>
<li>
<p>Ruff now resolves all <code>extend</code>ed configuration files
before falling back on a default Python version.</p>
</li>
</ul>
<h3>Stabilization</h3>
<p>The following rules have been stabilized and are no longer in
preview:</p>
<ul>
<li><a
href="https://docs.astral.sh/ruff/rules/blocking-http-call-httpx-in-async-function "><code>blocking-http-call-httpx-in-async-function</code></a>
(<code>ASYNC212</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/blocking-path-method-in-async-function "><code>blocking-path-method-in-async-function</code></a>
(<code>ASYNC240</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/blocking-input-in-async-function "><code>blocking-input-in-async-function</code></a>
(<code>ASYNC250</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/map-without-explicit-strict "><code>map-without-explicit-strict</code></a>
(<code>B912</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/if-exp-instead-of-or-operator "><code>if-exp-instead-of-or-operator</code></a>
(<code>FURB110</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/single-item-membership-test "><code>single-item-membership-test</code></a>
(<code>FURB171</code>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ce5f7b6127 "><code>ce5f7b6</code></a>
Bump 0.15.0 (<a
href="https://redirect.github.com/astral-sh/ruff/issues/23055 ">#23055</a>)</li>
<li><a
href="b4e40f539c "><code>b4e40f5</code></a>
[ty] Fix <code>__contains__</code> to respect descriptors (<a
href="https://redirect.github.com/astral-sh/ruff/issues/23056 ">#23056</a>)</li>
<li><a
href="848cb72dc1 "><code>848cb72</code></a>
[ty] Fix narrowing of nonlocal variables with conditional assignments
(<a
href="https://redirect.github.com/astral-sh/ruff/issues/22966 ">#22966</a>)</li>
<li><a
href="da7f33af22 "><code>da7f33a</code></a>
[ty] Add a diagnostic for <code>Final</code> without assignment (<a
href="https://redirect.github.com/astral-sh/ruff/issues/23001 ">#23001</a>)</li>
<li><a
href="e65f9a6b03 "><code>e65f9a6</code></a>
Document markdown formatting feature (<a
href="https://redirect.github.com/astral-sh/ruff/issues/22990 ">#22990</a>)</li>
<li><a
href="c0c1b985c9 "><code>c0c1b98</code></a>
Format markdown code blocks with line-by-line regex parse (<a
href="https://redirect.github.com/astral-sh/ruff/issues/22996 ">#22996</a>)</li>
<li><a
href="9f8f3e196b "><code>9f8f3e1</code></a>
Allow positional-only params with defaults in method overrides (<a
href="https://redirect.github.com/astral-sh/ruff/issues/23037 ">#23037</a>)</li>
<li><a
href="ef83810e11 "><code>ef83810</code></a>
[ty] ecosystem-analyzer: Support bare git repositories (<a
href="https://redirect.github.com/astral-sh/ruff/issues/23054 ">#23054</a>)</li>
<li><a
href="54dfee4cb8 "><code>54dfee4</code></a>
Customize where the <code>fix_title</code> sub-diagnostic appears (<a
href="https://redirect.github.com/astral-sh/ruff/issues/23044 ">#23044</a>)</li>
<li><a
href="b53460799b "><code>b534607</code></a>
2026 Ruff Formatter Style (<a
href="https://redirect.github.com/astral-sh/ruff/issues/22735 ">#22735</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/astral-sh/ruff/compare/0.14.11...0.15.0 ">compare
view</a></li>
</ul>
</details>
<br />
Updates `types-requests` from 2.31.0.6 to 2.32.4.20260107
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/typeshed-internal/stub_uploader/commits ">compare
view</a></li>
</ul>
</details>
<br />
Updates `setuptools` from 78.1.1 to 82.0.0
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pypa/setuptools/blob/main/NEWS.rst ">setuptools's
changelog</a>.</em></p>
<blockquote>
<h1>v82.0.0</h1>
<h2>Deprecations and Removals</h2>
<ul>
<li><code>pkg_resources</code> has been removed from Setuptools. Most
common uses of <code>pkg_resources</code> have been superseded by the
<code>importlib.resources
<https://docs.python.org/3/library/importlib.resources.html> ;</code>_
and <code>importlib.metadata
<https://docs.python.org/3/library/importlib.metadata.html> ;</code>_
projects. Projects and environments relying on
<code>pkg_resources</code> for namespace packages or other behavior
should depend on older versions of <code>setuptools</code>. (<a
href="https://redirect.github.com/pypa/setuptools/issues/3085 ">#3085</a>)</li>
</ul>
<h1>v81.0.0</h1>
<h2>Deprecations and Removals</h2>
<ul>
<li>Removed support for the --dry-run parameter to setup.py. This one
feature by its nature threads through lots of core and ancillary
functionality, adding complexity and friction. Removal of this parameter
will help decouple the compiler functionality from distutils and thus
the eventual full integration of distutils. These changes do affect some
class and function signatures, so any derivative functionality may
require some compatibility shims to support their expected interface.
Please report any issues to the Setuptools project for investigation.
(<a
href="https://redirect.github.com/pypa/setuptools/issues/4872 ">#4872</a>)</li>
</ul>
<h1>v80.10.2</h1>
<h2>Bugfixes</h2>
<ul>
<li>Update vendored dependencies. (<a
href="https://redirect.github.com/pypa/setuptools/issues/5159 ">#5159</a>)</li>
</ul>
<h2>Misc</h2>
<ul>
<li><a
href="https://redirect.github.com/pypa/setuptools/issues/5115 ">#5115</a>,
<a
href="https://redirect.github.com/pypa/setuptools/issues/5128 ">#5128</a></li>
</ul>
<h1>v80.10.1</h1>
<h2>Misc</h2>
<ul>
<li><a
href="https://redirect.github.com/pypa/setuptools/issues/5152 ">#5152</a></li>
</ul>
<h1>v80.10.0</h1>
<h2>Features</h2>
<ul>
<li>Remove post-release tags on setuptools' own build. (<a
href="https://redirect.github.com/pypa/setuptools/issues/4530 ">#4530</a>)</li>
<li>Refreshed vendored dependencies. (<a
href="https://redirect.github.com/pypa/setuptools/issues/5139 ">#5139</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="03f3615362 "><code>03f3615</code></a>
Bump version: 81.0.0 → 82.0.0</li>
<li><a
href="530d11498a "><code>530d114</code></a>
Merge pull request <a
href="https://redirect.github.com/pypa/setuptools/issues/5007 ">#5007</a>
from pypa/feature/remove-more-pkg_resources</li>
<li><a
href="11efe9f552 "><code>11efe9f</code></a>
Merge branch 'maint/75.3'</li>
<li><a
href="118f129dd0 "><code>118f129</code></a>
Bump version: 75.3.3 → 75.3.4</li>
<li><a
href="90561ffde1 "><code>90561ff</code></a>
Merge pull request <a
href="https://redirect.github.com/pypa/setuptools/issues/5150 ">#5150</a>
from UladzimirTrehubenka/backport_cve_47273</li>
<li><a
href="4595034db8 "><code>4595034</code></a>
Add news fragment.</li>
<li><a
href="fc008006fc "><code>fc00800</code></a>
Merge pull request <a
href="https://redirect.github.com/pypa/setuptools/issues/5171 ">#5171</a>
from cclauss/ruff-v0.15.0</li>
<li><a
href="127e561362 "><code>127e561</code></a>
Remove tests reliant on pkg_resources, rather than xfailing them.</li>
<li><a
href="64bc21e10b "><code>64bc21e</code></a>
Reference the superseding libraries.</li>
<li><a
href="cf1ff459ea "><code>cf1ff45</code></a>
Merge branch 'main' into debt/pbr-without-pkg_resources</li>
<li>Additional commits viewable in <a
href="https://github.com/pypa/setuptools/compare/v78.1.1...v82.0.0 ">compare
view</a></li>
</ul>
</details>
<br />
Updates `pytest` from 8.4.2 to 9.0.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pytest-dev/pytest/releases ">pytest's
releases</a>.</em></p>
<blockquote>
<h2>9.0.2</h2>
<h1>pytest 9.0.2 (2025-12-06)</h1>
<h2>Bug fixes</h2>
<ul>
<li>
<p><a
href="https://redirect.github.com/pytest-dev/pytest/issues/13896 ">#13896</a>:
The terminal progress feature added in pytest 9.0.0 has been disabled by
default, except on Windows, due to compatibility issues with some
terminal emulators.</p>
<p>You may enable it again by passing <code>-p terminalprogress</code>.
We may enable it by default again once compatibility improves in the
future.</p>
<p>Additionally, when the environment variable <code>TERM</code> is
<code>dumb</code>, the escape codes are no longer emitted, even if the
plugin is enabled.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/pytest-dev/pytest/issues/13904 ">#13904</a>:
Fixed the TOML type of the <code>tmp_path_retention_count</code>
settings in the API reference from number to string.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/pytest-dev/pytest/issues/13946 ">#13946</a>:
The private <code>config.inicfg</code> attribute was changed in a
breaking manner in pytest 9.0.0.
Due to its usage in the ecosystem, it is now restored to working order
using a compatibility shim.
It will be deprecated in pytest 9.1 and removed in pytest 10.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/pytest-dev/pytest/issues/13965 ">#13965</a>:
Fixed quadratic-time behavior when handling <code>unittest</code>
subtests in Python 3.10.</p>
</li>
</ul>
<h2>Improved documentation</h2>
<ul>
<li><a
href="https://redirect.github.com/pytest-dev/pytest/issues/4492 ">#4492</a>:
The API Reference now contains cross-reference-able documentation of
<code>pytest's command-line flags
<command-line-flags></code>.</li>
</ul>
<h2>9.0.1</h2>
<h1>pytest 9.0.1 (2025-11-12)</h1>
<h2>Bug fixes</h2>
<ul>
<li><a
href="https://redirect.github.com/pytest-dev/pytest/issues/13895 ">#13895</a>:
Restore support for skipping tests via <code>raise
unittest.SkipTest</code>.</li>
<li><a
href="https://redirect.github.com/pytest-dev/pytest/issues/13896 ">#13896</a>:
The terminal progress plugin added in pytest 9.0 is now automatically
disabled when iTerm2 is detected, it generated desktop notifications
instead of the desired functionality.</li>
<li><a
href="https://redirect.github.com/pytest-dev/pytest/issues/13904 ">#13904</a>:
Fixed the TOML type of the verbosity settings in the API reference from
number to string.</li>
<li><a
href="https://redirect.github.com/pytest-dev/pytest/issues/13910 ">#13910</a>:
Fixed <!-- raw HTML omitted -->UserWarning: Do not expect
file_or_dir<!-- raw HTML omitted --> on some earlier Python 3.12 and
3.13 point versions.</li>
</ul>
<h2>Packaging updates and notes for downstreams</h2>
<ul>
<li><a
href="https://redirect.github.com/pytest-dev/pytest/issues/13933 ">#13933</a>:
The tox configuration has been adjusted to make sure the desired
version string can be passed into its <code>package_env</code> through
the <code>SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST</code> environment
variable as a part of the release process -- by
<code>webknjaz</code>.</li>
</ul>
<h2>Contributor-facing changes</h2>
<ul>
<li><a
href="https://redirect.github.com/pytest-dev/pytest/issues/13891 ">#13891</a>,
<a
href="https://redirect.github.com/pytest-dev/pytest/issues/13942 ">#13942</a>:
The CI/CD part of the release automation is now capable of
creating GitHub Releases without having a Git checkout on
disk -- by <code>bluetech</code> and <code>webknjaz</code>.</li>
<li><a
href="https://redirect.github.com/pytest-dev/pytest/issues/13933 ">#13933</a>:
The tox configuration has been adjusted to make sure the desired
version string can be passed into its <code>package_env</code> through
the <code>SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST</code> environment
variable as a part of the release process -- by
<code>webknjaz</code>.</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="3d10b5148e "><code>3d10b51</code></a>
Prepare release version 9.0.2</li>
<li><a
href="188750b725 "><code>188750b</code></a>
Merge pull request <a
href="https://redirect.github.com/pytest-dev/pytest/issues/14030 ">#14030</a>
from pytest-dev/patchback/backports/9.0.x/1e4b01d1f...</li>
<li><a
href="b7d7bef90c "><code>b7d7bef</code></a>
Merge pull request <a
href="https://redirect.github.com/pytest-dev/pytest/issues/14014 ">#14014</a>
from bluetech/compat-note</li>
<li><a
href="bd08e85ac7 "><code>bd08e85</code></a>
Merge pull request <a
href="https://redirect.github.com/pytest-dev/pytest/issues/14013 ">#14013</a>
from pytest-dev/patchback/backports/9.0.x/922b60377...</li>
<li><a
href="bc78386299 "><code>bc78386</code></a>
Add CLI options reference documentation (<a
href="https://redirect.github.com/pytest-dev/pytest/issues/13930 ">#13930</a>)</li>
<li><a
href="5a4e398ce8 "><code>5a4e398</code></a>
Fix docs typo (<a
href="https://redirect.github.com/pytest-dev/pytest/issues/14005 ">#14005</a>)
(<a
href="https://redirect.github.com/pytest-dev/pytest/issues/14008 ">#14008</a>)</li>
<li><a
href="d7ae6df394 "><code>d7ae6df</code></a>
Merge pull request <a
href="https://redirect.github.com/pytest-dev/pytest/issues/14006 ">#14006</a>
from pytest-dev/maintenance/update-plugin-list-tmpl...</li>
<li><a
href="556f6a22e1 "><code>556f6a2</code></a>
pre-commit: fix rst-lint after new release (<a
href="https://redirect.github.com/pytest-dev/pytest/issues/13999 ">#13999</a>)
(<a
href="https://redirect.github.com/pytest-dev/pytest/issues/14001 ">#14001</a>)</li>
<li><a
href="c60fbe63a2 "><code>c60fbe6</code></a>
Fix quadratic-time behavior when handling <code>unittest</code> subtests
in Python 3.10 ...</li>
<li><a
href="73d9b01118 "><code>73d9b01</code></a>
Merge pull request <a
href="https://redirect.github.com/pytest-dev/pytest/issues/13995 ">#13995</a>
from nicoddemus/patchback/backports/9.0.x/1b5200c0f...</li>
<li>Additional commits viewable in <a
href="https://github.com/pytest-dev/pytest/compare/8.4.2...9.0.2 ">compare
view</a></li>
</ul>
</details>
<br />
Updates `syrupy` from 4.9.1 to 5.1.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/syrupy-project/syrupy/releases ">syrupy's
releases</a>.</em></p>
<blockquote>
<h2>v5.1.0</h2>
<h1><a
href="https://github.com/syrupy-project/syrupy/compare/v5.0.0...v5.1.0 ">5.1.0</a>
(2026-01-25)</h1>
<h3>Features</h3>
<ul>
<li>add serializer plugin system; plugins for data models (<a
href="https://redirect.github.com/syrupy-project/syrupy/issues/1062 ">#1062</a>)
(<a
href="df9bc8f6b3 ">df9bc8f</a>)</li>
</ul>
<h2>v5.0.0</h2>
<h2>Syrupy 5.0.0</h2>
<p><em>(2025-09-28)</em></p>
<p>This release introduces new features, bug fixes, and a major license
change. It also includes several <strong>breaking changes</strong>, so
please review those carefully before upgrading.</p>
<hr />
<h3>New Features ✨ </h3>
<ul>
<li><strong>Add <code>--snapshot-dirname</code> option:</strong> A new
option, <code>--snapshot-dirname</code>, is now available to change the
default directory snapshots are stored in. ([<a
href="https://redirect.github.com/syrupy-project/syrupy/issues/810 ">#81...
_Description has been truncated_
---------
Signed-off-by: dependabot[bot] <support@github.com >
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: John Kennedy <65985482+jkennedyvz@users.noreply.github.com >
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-09 23:49:11 -08:00
ccurme
0040e1a8aa
fix(langchain): fix token counting on partial message sequences ( #35101 )
2026-02-09 15:27:17 -05:00
Mason Daugherty
ce5f73e07c
refactor(langchain): rename _SUPPORTED_PROVIDERS -> _BUILTIN_PROVIDERS ( #35100 )
2026-02-09 15:26:01 -05:00
Sydney Runkle
8767a462ca
feat: support state updates from wrap_model_call with command(s) ( #35033 )
...
Alternative to https://github.com/langchain-ai/langchain/pull/35024 .
Paving the way for summarization in `wrap_model_call` (which requires
state updates).
---
Add `ExtendedModelResponse` dataclass that allows `wrap_model_call`
middleware to return a `Command` alongside the model response for
additional state updates.
```py
@dataclass
class ExtendedModelResponse(Generic[ResponseT]):
model_response: ModelResponse[ResponseT]
command: Command
```
## Motivation
Previously, `wrap_model_call` middleware could only return a
`ModelResponse` or `AIMessage` — there was no way to inject additional
state updates (e.g. custom state fields) from the model call middleware
layer. `ExtendedModelResponse` fills this gap by accepting an optional
`Command`.
This feature is needed by the summarization middleware, which needs to
track summarization trigger points calculated during `wrap_model_call`.
## Why `Command` instead of a plain `state_update` dict?
We chose `Command` rather than the raw `state_update: dict` approach
from the earlier iteration because `Command` is the established
LangGraph primitive for state updates from nodes. Using `Command` means:
- State updates flow through the graph's reducers (e.g. `add_messages`)
rather than being merged as raw dicts. This makes messages updates
additive alongside the model response instead of replacing them.
- Consistency with `wrap_tool_call`, which already returns `Command`.
- Future-proof: as `Command` gains new capabilities (e.g. `goto`,
`send`), middleware can leverage them without API changes.
## Why keep `model_response` separate instead of using `Command`
directly?
The model node needs to distinguish the model's actual response
(messages + structured output) from supplementary middleware state
updates. If middleware returned only a `Command`, there would be no
clean way to extract the `ModelResponse` for structured output handling,
response validation, and the core model-to-tools routing logic. Keeping
`model_response` explicit preserves a clear boundary between "what the
model said" and "what middleware wants to update."
Also, in order to avoid breaking, the `handler` passed to
`wrap_tool_call` needs to always return a `ModelResponse`. There's no
easy way to preserve this if we pump it into a `Command`.
One nice thing about having this `ExtendedModelResponse` structure is
that it's extensible if we want to add more metadata in the future.
## Composition
When multiple middleware layers return `ExtendedModelResponse`, their
commands compose naturally:
- **Inner commands propagate outward:** At composition boundaries,
`ExtendedModelResponse` is unwrapped to its underlying `ModelResponse`
so outer middleware always sees a plain `ModelResponse` from
`handler()`. The inner command is captured and accumulated.
- **Commands are applied through reducers:** Each `Command` becomes a
separate state update applied through the graph's reducers. For
messages, this means they're additive (via `add_messages`), not
replacing.
- **Outer wins on conflicts:** For non-reducer state fields, commands
are applied inner-first then outer, so the outermost middleware's value
takes precedence on conflicting keys.
- **Retry-safe:** When outer middleware retries by calling `handler()`
again, accumulated inner commands are cleared and re-collected from the
fresh call.
```python
class Outer(AgentMiddleware):
def wrap_model_call(self, request, handler):
response = handler(request) # sees ModelResponse, not ExtendedModelResponse
return ExtendedModelResponse(
model_response=response,
command=Command(update={"outer_key": "val"}),
)
class Inner(AgentMiddleware):
def wrap_model_call(self, request, handler):
response = handler(request)
return ExtendedModelResponse(
model_response=response,
command=Command(update={"inner_key": "val"}),
)
# Final state merges both commands: {"inner_key": "val", "outer_key": "val"}
```
## Backwards compatibility
Fully backwards compatible. The `ModelCallResult` type alias is widened
from `ModelResponse | AIMessage` to `ModelResponse | AIMessage |
ExtendedModelResponse`, but existing middleware returning
`ModelResponse` or `AIMessage` continues to work identically.
## Internals
- `model_node` / `amodel_node` now return `list[Command]` instead of
`dict[str, Any]`
- `_build_commands` converts the model response + accumulated middleware
commands into a list of `Command` objects for LangGraph
- `_ComposedExtendedModelResponse` is the internal type that accumulates
commands across layers during composition
2026-02-06 07:28:04 -05:00
Christophe Bornet
d181a59ebe
test(langchain): types in test_tool_call_limit and test_model_retry ( #34629 )
...
Co-authored-by: Mason Daugherty <github@mdrxy.com >
Co-authored-by: Mason Daugherty <mason@langchain.dev >
2026-02-05 15:50:02 -05:00
Sydney Runkle
dde2012b83
feat: threading context through create_agent flows + middleware ( #34978 )
...
Closes https://github.com/langchain-ai/langchain/issues/33956
* Making `ModelRequest` generic on `ContextT` and `ResponseT` so that we
can thread type information through to `wrap_model_call`
* Making builtin middlewares generic on `ContextT` and `ResponseT` so
their context and response types can be inferred from the `create_agent`
signature
See new tests that verify backwards compatibility (for cases where folks
use custom middleware that wasn't parametrized).
This fixes:
1. Lack of access to context and response types in `wrap_model_call`
2. Lack of cohesion between middleware context + response types with
those specified in `create_agent`
See examples below:
### Type-safe context and response access
```python
class MyMiddleware(AgentMiddleware[AgentState[AnalysisResult], UserContext, AnalysisResult]):
def wrap_model_call(
self,
request: ModelRequest[UserContext],
handler: Callable[[ModelRequest[UserContext]], ModelResponse[AnalysisResult]],
) -> ModelResponse[AnalysisResult]:
# ✅ Now type-safe: IDE knows user_id exists and is str
user_id: str = request.runtime.context["user_id"]
# ❌ mypy error: "session_id" doesn't exist on UserContext
request.runtime.context["session_id"]
response = handler(request)
if response.structured_response is not None:
# ✅ Now type-safe: IDE knows sentiment exists and is str
sentiment: str = response.structured_response.sentiment
# ❌ mypy error: "summary" doesn't exist on AnalysisResult
response.structured_response.summary
return response
```
### Mismatched middleware/schema caught at `create_agent`
```python
class SessionMiddleware(AgentMiddleware[AgentState[Any], SessionContext, Any]):
...
# ❌ mypy error: SessionMiddleware expects SessionContext, not UserContext
create_agent(
model=model,
middleware=[SessionMiddleware()],
context_schema=UserContext, # mismatch!
)
class AnalysisMiddleware(AgentMiddleware[AgentState[AnalysisResult], ContextT, AnalysisResult]):
...
# ❌ mypy error: AnalysisMiddleware expects AnalysisResult, not SummaryResult
create_agent(
model=model,
middleware=[AnalysisMiddleware()],
response_format=SummaryResult, # mismatch!
)
```
2026-02-05 07:41:27 -05:00
Saakshi Gupta
91bb474dbc
fix(langchain): avoid UnboundLocalError when no AIMessage exists ( #34816 )
2026-02-02 20:56:30 -05:00
Shivangi Sharma
d189663b47
fix: reuse ToolStrategy in agent factory to prevent name mismatch ( #34871 )
2026-01-31 22:10:25 -05:00
Mason Daugherty
72333ad644
fix(langchain): blocking unit test ( #34866 )
...
=
2026-01-23 22:58:03 -05:00
Christophe Bornet
ca9d2c0bdd
test(langchain): use blockbuster to detect blocking calls in the async event loop ( #34777 )
2026-01-23 14:52:56 -05:00
Sydney Runkle
bc8620189c
feat: dynamic tool registration via middleware ( #34842 )
...
dependent upon https://github.com/langchain-ai/langgraph/pull/6711
1. relax constraint in `factory.py` to allow for tools not
pre-registered in the `ModelRequest.tools` list
2. always add tool node if `wrap_tool_call` or `awrap_tool_call` is
implemented
3. add tests confirming you can register new tools at runtime in
`wrap_model_call` and execute them via `wrap_tool_call`
allows for the following pattern
```py
from langchain_core.messages import HumanMessage, ToolMessage
from langchain_core.tools import tool
from libs.langchain_v1.langchain.agents.factory import create_agent
from libs.langchain_v1.langchain.agents.middleware.types import (
AgentMiddleware,
ModelRequest,
ToolCallRequest,
)
@tool
def get_weather(location: str) -> str:
"""Get the current weather for a location."""
return f"The weather in {location} is sunny and 72°F."
@tool
def calculate_tip(bill_amount: float, tip_percentage: float = 20.0) -> str:
"""Calculate the tip amount for a bill."""
tip = bill_amount * (tip_percentage / 100)
return f"Tip: ${tip:.2f}, Total: ${bill_amount + tip:.2f}"
class DynamicToolMiddleware(AgentMiddleware):
"""Middleware that adds and handles a dynamic tool."""
def wrap_model_call(self, request: ModelRequest, handler):
updated = request.override(tools=[*request.tools, calculate_tip])
return handler(updated)
def wrap_tool_call(self, request: ToolCallRequest, handler):
if request.tool_call["name"] == "calculate_tip":
return handler(request.override(tool=calculate_tip))
return handler(request)
agent = create_agent(model="openai:gpt-4o-mini", tools=[get_weather], middleware=[DynamicToolMiddleware()])
result = agent.invoke({
"messages": [HumanMessage("What's the weather in NYC? Also calculate a 20% tip on a $85 bill")]
})
for msg in result["messages"]:
msg.pretty_print()
```
2026-01-23 10:12:48 -05:00
Mason Daugherty
09c3c52fd0
fix(langchain): add metadata configuration to summarization model invocation ( #34763 )
...
We need to set `{"metadata": {"lc_source": "summarization"}}` on the
invocation so that consumers (e.g. `deepagents-cli`) can see that a
summarization LLM call is being made, and therefore take any necessary
actions (such as updating the status line to say `'Currently
summarizing...'`
See https://github.com/langchain-ai/deepagents/pull/742 for more
Related to #34693 (but for outbound)
2026-01-15 15:39:12 -05:00
Sydney Runkle
73ebaddcf0
chore: add tests for agent name metadata when streaming ( #34764 )
2026-01-15 15:38:15 +00:00
Sydney Runkle
ee6fce5586
Revert "metadata"
...
This reverts commit 13301a779e .
2026-01-15 10:13:35 -05:00
Sydney Runkle
13301a779e
metadata
2026-01-15 10:12:28 -05:00
Sydney Runkle
5799aa1045
chore: add tests for private state attr use (really, lack thereof) ( #34725 )
...
If a user injects a private state value, it should be ignored (and is)!
2026-01-12 20:47:44 +00:00
ccurme
725d204b95
fix(langchain): tag messages generated from summarization ( #34693 )
2026-01-12 09:26:09 -05:00
Christophe Bornet
a7b943bbe3
fix(langchain): activate test_return_direct_spec tests, fix types ( #34565 )
...
Co-authored-by: Mason Daugherty <mason@langchain.dev >
Co-authored-by: Mason Daugherty <github@mdrxy.com >
2026-01-09 22:52:12 -05:00
Christophe Bornet
5fbf270c9d
chore(langchain): fix types in test_todo, test_tool_retry ( #34503 )
...
Co-authored-by: Mason Daugherty <mason@langchain.dev >
2026-01-09 22:50:20 -05:00
Christophe Bornet
e73b027686
chore(langchain): fix types in test_shell_tool ( #34502 )
...
Co-authored-by: Mason Daugherty <mason@langchain.dev >
2026-01-09 22:46:56 -05:00
Christophe Bornet
ecd19ff71f
chore(langchain): activate mypy warn_return_any rule ( #34549 )
...
Co-authored-by: Mason Daugherty <github@mdrxy.com >
Co-authored-by: Mason Daugherty <mason@langchain.dev >
2026-01-09 22:46:25 -05:00
Christophe Bornet
cb0d227d8a
chore(langchain): fix types in test_tool_selection and test_tool_emulator ( #34499 )
...
Co-authored-by: Mason Daugherty <mason@langchain.dev >
2026-01-09 22:37:54 -05:00
Christophe Bornet
b688e36e38
chore(langchain): fix types in test_shell_execution_policies ( #34498 )
...
Co-authored-by: Mason Daugherty <mason@langchain.dev >
2026-01-09 22:31:53 -05:00
Christophe Bornet
36e590ca5f
test(langchain): complete and activate test_responses tests ( #34560 )
...
Co-authored-by: Mason Daugherty <github@mdrxy.com >
Co-authored-by: Mason Daugherty <mason@langchain.dev >
2026-01-09 22:17:03 -05:00
Christophe Bornet
fc417aaf17
fix(langchain): activate mypy warn-unreachable ( #34553 )
...
Co-authored-by: Mason Daugherty <mason@langchain.dev >
2026-01-09 22:11:16 -05:00
Christophe Bornet
5dc8ba3c99
chore(langchain): fix types in test_injected_runtime_create_agent, test_create_agent_tool_validation ( #34568 )
2026-01-09 21:50:18 -05:00
Christophe Bornet
f1ab8c5c80
chore(langchain): fix types in test_response_format and test_state_schema ( #34571 )
2026-01-09 21:49:16 -05:00
Christophe Bornet
bfe0a26547
chore(langchain): remove generic from FakeToolCallingModel ( #34572 )
...
* Making `FakeToolCallingModel` generic on its `structured_response`
doesn't help anywhere in typing.
* There are more than 120 references of `FakeToolCallingModel` in the
code where you get ` error: Need type annotation for "model"
[var-annotated]` because mypy can't resolve the generic type (we don't
see them atm because they are in files temporarily excluded from mypy
checking). We would need to explicitly type them to
`FakeToolCallingModel[Any]`
Co-authored-by: Mason Daugherty <mason@langchain.dev >
2026-01-09 21:48:33 -05:00
Christophe Bornet
bb5bd1181f
chore(langchain): fix types in test_context_editing, test_agent_name, test_response_format_integration ( #34574 )
...
Co-authored-by: Mason Daugherty <mason@langchain.dev >
2026-01-09 21:47:46 -05:00
Christophe Bornet
5e9765d811
chore(langchain): fix types in test_overrides ( #34635 )
...
Co-authored-by: Mason Daugherty <github@mdrxy.com >
Co-authored-by: Mason Daugherty <mason@langchain.dev >
2026-01-09 18:31:13 -05:00
Christophe Bornet
61fd703e5f
chore(langchain): fix types in test_tools ( #34592 )
...
Co-authored-by: Mason Daugherty <mason@langchain.dev >
Co-authored-by: Mason Daugherty <github@mdrxy.com >
2026-01-09 18:05:28 -05:00
Christophe Bornet
4e40c2766a
chore(langchain): fix types in test_summarization ( #34656 )
...
Co-authored-by: Mason Daugherty <mason@langchain.dev >
Co-authored-by: Mason Daugherty <github@mdrxy.com >
2026-01-09 17:54:42 -05:00
Christophe Bornet
9ce73a73f8
test(langchain): activate test_responses_spec tests ( #34564 )
...
description by @mdrxy
- Enable `test_responses_spec.py` integration tests that were previously
skipped at module level
- Widen `ToolStrategy.schema` type annotation from `type[SchemaT]` to
`type[SchemaT] | dict[str, Any]` to match actual supported usage (JSON
schema dicts were already handled at runtime)
- Fix type annotations and linting issues in test file (modernize to
`dict`/`list`, add return types, prefix unused `_request` param)
- Improve generic typing in `load_spec` utility with bounded `TypeVar`
Co-authored-by: Mason Daugherty <mason@langchain.dev >
2026-01-09 17:44:33 -05:00
Christophe Bornet
b4cd67ac15
style(langchain): fix some ruff preview rules ( #34663 )
...
Co-authored-by: Mason Daugherty <github@mdrxy.com >
Co-authored-by: Mason Daugherty <mason@langchain.dev >
2026-01-09 17:41:05 -05:00
Christophe Bornet
e6dde3267a
chore(langchain): fix types in test_framework ( #34567 )
...
Co-authored-by: Mason Daugherty <mason@langchain.dev >
Co-authored-by: Mason Daugherty <github@mdrxy.com >
2026-01-09 17:24:38 -05:00
Christophe Bornet
23c4c506d3
chore(langchain): fix types in memory_assert, conftest, conftest_checkpointer and conftest_store ( #34636 )
...
Co-authored-by: Mason Daugherty <mason@langchain.dev >
Co-authored-by: Mason Daugherty <github@mdrxy.com >
2026-01-09 17:18:05 -05:00
Christophe Bornet
d1404e63bb
chore(langchain): fix types in test_system_message ( #34634 )
...
Co-authored-by: Mason Daugherty <github@mdrxy.com >
Co-authored-by: Mason Daugherty <mason@langchain.dev >
2026-01-09 17:17:57 -05:00
Sydney Runkle
fbe9babb34
fix: remove relative imports ( #34680 )
...
standardizing on absolute imports rather than relative across the
codebase
2026-01-09 13:00:51 -05:00
Guofang.Tang
384158daec
fix(langchain): infer provider from mixed-case prefixes ( #34672 )
...
Fix provider inference for mixed-case model prefixes and add matching
unit coverage.
2026-01-09 11:07:14 -05:00
Sydney Runkle
323c76504a
fix: add test confirming we don't inject args based on args_schema alone ( #34677 )
...
pending exclusion from function signature
2026-01-09 11:00:13 -05:00
ccurme
d383f00489
refactor(langchain): engage summarization based on reported usage_metadata ( #34632 )
2026-01-08 11:12:00 -05:00
Mason Daugherty
2b6911d9af
fix(langchain): keep tool call / AIMessage pairings when summarizing ( #34609 )
...
Fixes #34282
**Before:** When using agents with tools (like file reading, web search,
etc.), the conversation looks like this:
```
[User] "Read these 10 files and summarize them"
[AI] "I'll read all 10 files" + [tool_call: read_file x 10]
[Tool] "Contents of file1.txt..."
[Tool] "Contents of file2.txt..."
[Tool] "Contents of file3.txt..."
... (7 more tool responses)
```
When the conversation gets too long, `SummarizationMiddleware` kicks in
to compress older messages. The problem was:
If you asked to keep the last 6 messages, you'd get:
```
[Summary] "Here's what happened before..."
[Tool] "Contents of file5.txt..."
[Tool] "Contents of file6.txt..."
[Tool] "Contents of file7.txt..."
[Tool] "Contents of file8.txt..."
[Tool] "Contents of file9.txt..."
[Tool] "Contents of file10.txt..."
```
The AI's original request to read the files (`[AI]` message with
`tool_calls`) was summarized away, but the tool responses remained. This
caused the error:
```
Error code: 400 - "No tool call found for function call output with call_id..."
```
Many APIs require that every tool response has a matching tool request.
Without the AI message, the tool responses are "orphaned."
## The fix
Now when the cutoff lands on tool messages, we **move backward** to
include the AI message that requested those tools:
Same scenario, keeping last 6 messages:
```
[Summary] "Here's what happened before..."
[AI] "I'll read all 10 files" + [tool_call: read_file x 10]
[Tool] "Contents of file1.txt..."
[Tool] "Contents of file2.txt..."
... (all 10 tool responses)
```
The AI message is preserved along with its tool responses, keeping them
paired together.
## Practical examples
### Example 1: Parallel tool calls
**Scenario:** Agent reads 10 files in parallel, summarization triggers
(see above)
### Example 2: Mixed conversation
**Scenario:** User asks question, AI uses tools, user says thanks
```
[User] "What's the weather?"
[AI] "Let me check" + [tool_call: get_weather]
[Tool] "72F and sunny"
[AI] "It's 72F and sunny!"
[User] "Thanks!"
```
Keeping last 2 messages:
| Before (Bug) | After (Fix) |
|--------------|-------------|
| Only `[User] "Thanks!"` kept | `[AI] + [Tool] + [AI] + [User]` all
kept |
| Lost the weather info | Tool pair preserved with response |
### Example 3: Multiple tool sequences
```
[User] "Search for X"
[AI] [tool_call: search]
[Tool] "Results for X"
[User] "Now search for Y"
[AI] [tool_call: search]
[Tool] "Results for Y"
[User] "Great!"
```
**Keeping last 3 messages:** If cutoff lands on `[Tool] "Results for
Y"`, we now include `[AI] [tool_call: search]` to keep the pair
together.
2026-01-08 10:07:56 -05:00
Guofang.Tang
f805ea9601
test(langchain): cover chat model provider inference ( #34657 )
...
Add unit coverage for chat model provider inference across common model
name prefixes. This improves regression protection without touching
runtime
---------
Co-authored-by: Mason Daugherty <github@mdrxy.com >
2026-01-08 09:59:12 -05:00
Eugene Yurtsev
ceca38d3fe
fix(langchain): add test to verify version ( #34644 )
...
verify version in langchain to avoid accidental drift
2026-01-07 22:36:10 +00:00
Harrison Chase
bda22aa1d9
fix(langchain): handle parallel usage of the todo tool in planning middleware ( #34637 )
...
The agent should only make a single call to update the todo list at a
time. A parallel call doesn't make sense, but also cannot work as
there's no obvious reducer to use.
On parallel calls of the todo tool, we return ToolMessage containing to
guide the LLM to not call the tool in parallel.
---------
Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com >
2026-01-07 17:23:56 -05:00
Christophe Bornet
f10225184d
chore(langchain): fix types in test_wrap_model_call ( #34573 )
2026-01-07 11:49:46 -05:00
Mason Daugherty
8aeff95341
fix(core,langchain): use get_buffer_string for message summarization ( #34607 )
...
Fixes #34517
Supersedes #34557 , #34570
Fixes token inflation in `SummarizationMiddleware` that caused context
window overflow during summarization.
**Root cause:** When formatting messages for the summary prompt,
`str(messages)` was implicitly called, which includes all Pydantic
metadata fields (`usage_metadata`, `response_metadata`,
`additional_kwargs`, etc.). This caused the stringified representation
to use ~2.5x more tokens than `count_tokens_approximately` estimates.
**Problem:**
- Summarization triggers at 85% of context window based on
`count_tokens_approximately`
- But `str(messages)` in the prompt uses 2.5x more tokens
- Results in `ContextLengthExceeded`
**Fix:** Use `get_buffer_string()` to format messages, which produces
compact output:
```
Human: What's the weather?
AI: Let me check...[tool_calls]
Tool: 72°F and sunny
```
Instead of verbose Pydantic repr:
```python
[HumanMessage(content='What's the weather?', additional_kwargs={}, response_metadata={}), ...]
```
2026-01-06 19:05:03 -05:00