Compare commits

...
Author SHA1 Message Date
Sydney RunkleandGitHub 4705248c5b release: prebuilt 1.0.9 and langgraph 1.1.5 (#7401) 2026-04-03 14:01:24 +00:00
Sydney RunkleandGitHub 39288e6111 feat: enhance runtime w/ more execution information (#7363)
## Summary

Enhances `ExecutionInfo` and `Runtime` to surface richer execution
context and introduces `ServerInfo` for LangGraph Server metadata.

### `ExecutionInfo` expansion

Converted from `NamedTuple` to a frozen `dataclass`. Added identity
fields populated during task preparation in `_algo.py`:

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `checkpoint_id` | `str` | required | Checkpoint ID for the current
execution |
| `checkpoint_ns` | `str` | required | Checkpoint namespace for the
current execution |
| `task_id` | `str` | required | Task ID for the current execution |
| `thread_id` | `str \| None` | `None` | Thread ID (None without a
checkpointer) |
| `run_id` | `str \| None` | `None` | Run ID (None when not provided in
config) |
| `node_attempt` | `int` | `1` | Current node execution attempt number
(1-indexed) |
| `node_first_attempt_time` | `float \| None` | `None` | Unix timestamp
for when the first attempt started |

`checkpoint_id`, `checkpoint_ns`, and `task_id` are required (no
defaults) — they are always populated during task preparation in
`_algo.py`. `Runtime.execution_info` is `None` until that point.

### New `ServerInfo` type

Frozen dataclass with `assistant_id: str`, `graph_id: str`, and optional
`user: BaseUser | None`. Populated from config metadata (`assistant_id`,
`graph_id`) and `configurable["langgraph_auth_user"]` via
`_build_server_info()` in `pregel/main.py`.

User detection uses `isinstance(BaseUser)` with a `hasattr("identity")`
fallback — needed because the server's `ProxyUser` provides
`permissions` via `__getattr__`, which Python's `runtime_checkable`
Protocol check doesn't see.

### `Runtime` changes

- `execution_info` is now `ExecutionInfo | None` (default `None`), set
during task prep
- Added `server_info: ServerInfo | None` field, wired through `merge()`
and `override()`

### `ToolNode` / `ToolRuntime` forwarding

`execution_info` and `server_info` are forwarded from `Runtime` to
`ToolRuntime` so tools can access execution and server context.

### New public API surface

```python
from langgraph.runtime import BaseUser, ExecutionInfo, Runtime, ServerInfo, get_runtime
```

## Test plan

- [x] `ExecutionInfo` defaults, patch, and frozen behavior
- [x] Integration tests verifying identity fields are populated in sync
and async execution
- [x] Retry tests confirming identity fields persist and `node_attempt`
increments
- [x] `ServerInfo` construction, frozen behavior, and `Runtime.merge`
precedence
- [x] `server_info` populated from config metadata and
`langgraph_auth_user` (including starlette-style proxy user)
- [x] `server_info` is `None` when no server metadata present
- [x] `ToolRuntime` forwarding of `execution_info` and `server_info`

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-02 19:38:03 +00:00
William FHandGitHub 9f5f3fb35e Revert "chore: update configurable metadata" (#7393)
Reverts langchain-ai/langgraph#7367
2026-04-02 11:05:17 -07:00
Asamu DavidandGitHub b3eeb4fa1d feat(cli): add remote build support for langgraph deploy (#7234)
**Description:** 

 - extend host_backend client with remote build support
- refactored `cli.py` for better clarity
- update tests
2026-04-02 16:39:30 +01:00
Sydney RunkleandGitHub 57b314c5d7 fix: tool node injection bug (#7391)
ensuring that injected args can only be injected by LC code, not LLMs :)

this does not appear to be an actual security concern because it falls
outside of documented usage, the tool node doesn't inject arbitrary args
2026-04-02 11:19:24 -04:00
Christian BromannandGitHub ee0566d31d chore: fix URL (#7385)
Minor adjustment
2026-04-01 13:27:15 -04:00
Christian BromannandGitHub 6c5a18791b fix(langgraph): update readme (#7384)
Replace outdated image on LangGraph readme.
2026-04-01 13:14:42 -04:00
William FHandGitHub a12e558020 chore: update configurable metadata (#7367) 2026-03-31 13:59:22 -07:00
Mason DaughertyandGitHub c965a483e8 ci: minimize stale enforcement comments on pr reopen (#7365)
When the `require_issue_link` workflow closes a PR and posts an
enforcement comment, that comment was never cleaned up after the
situation resolved — leaving a stale "automatically closed" message
visible on reopened PRs. Now all three resolution paths (maintainer
bypass, author fixing the issue link, and contributor assignment)
minimize the enforcement comment as outdated via GraphQL. The cleanup is
best-effort: failures log a warning but never block the primary workflow
logic (label removal, bypass, reopen).
2026-03-31 15:39:29 -04:00
Eugene YurtsevandGitHub 5c9c1d598d release(langgraph): 1.1.4 (#7356)
1.1.4
2026-03-31 08:48:44 -04:00
13528ef3ae fix: moving threat model to .github/ (#7360)
Moves threat model to .github/ if we want to

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-31 08:48:12 -04:00
1fd51e8f2a docs: add threat model for LangGraph monorepo (#7026)
## Summary

- Adds `THREAT_MODEL.md` mapping trust boundaries, data flows, and
threats across all 7 Python libraries in the monorepo
- Documents 14 components, 4 trust boundaries, 11 data flows, 8 threats,
and 8 out-of-scope patterns
- Integrates context from 4 published security advisories
(GHSA-mhr3-j7m5-c7c9, GHSA-9rwj-6rc7-p77c, GHSA-wwqv-p2pp-99h5,
GHSA-7p73-8jqx-23r8)
- Covers checkpoint deserialization risks (T1-T3), RemoteGraph inbound
validation (T4), CLI Dockerfile injection (T5), and encrypted serializer
concerns (T7-T8)
- Documents open-source responsibility model with detailed out-of-scope
threat rationale

## Test plan

- [x] Verify trust boundary descriptions match current code behavior
- [ ] Confirm out-of-scope patterns align with project's security
responsibility model

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 20:38:48 -07:00
Mason DaughertyandGitHub d344a22dfb ci: auto-reopen PRs on issue assignment (#7358)
`require_issue_link.yml` auto-closes external PRs when the author isn't
assigned to the linked issue, but there was no trigger to reopen them
when a maintainer later grants the assignment. Contributors had to
manually edit their PR description to trigger re-evaluation — poor UX
that generated repeat questions. This adds a companion workflow that
listens for issue assignment events and reopens matching PRs
automatically.
2026-03-30 20:54:02 -04:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
13fa88279b chore(deps): bump pygments from 2.19.2 to 2.20.0 in /libs/checkpoint-postgres (#7349)
Bumps [pygments](https://github.com/pygments/pygments) from 2.19.2 to
2.20.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pygments/pygments/releases">pygments's
releases</a>.</em></p>
<blockquote>
<h2>2.20.0</h2>
<ul>
<li>
<p>New lexers:</p>
<ul>
<li>Rell (<a
href="https://redirect.github.com/pygments/pygments/issues/2914">#2914</a>)</li>
</ul>
</li>
<li>
<p>Updated lexers:</p>
<ul>
<li>archetype: Fix catastrophic backtracking in GUID and ID patterns (<a
href="https://redirect.github.com/pygments/pygments/issues/3064">#3064</a>)</li>
<li>ASN.1: Recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3014">#3014</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li>C++: Add C++26 keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>),
add integer literal suffixes (<a
href="https://redirect.github.com/pygments/pygments/issues/2966">#2966</a>)</li>
<li>ComponentPascal: Fix <code>analyse_text</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/3028">#3028</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3032">#3032</a>)</li>
<li>Coq renamed to Rocq (<a
href="https://redirect.github.com/pygments/pygments/issues/2883">#2883</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2908">#2908</a>)</li>
<li>Cython: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2932">#2932</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2933">#2933</a>)</li>
<li>Debian control: Improve architecture parsing (<a
href="https://redirect.github.com/pygments/pygments/issues/3052">#3052</a>)</li>
<li>Devicetree: Add support for overlay/fragments (<a
href="https://redirect.github.com/pygments/pygments/issues/3021">#3021</a>),
add bytestring support (<a
href="https://redirect.github.com/pygments/pygments/issues/3022">#3022</a>),
fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3057">#3057</a>)</li>
<li>Fennel: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2911">#2911</a>)</li>
<li>Haskell: Handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/1795">#1795</a>)</li>
<li>Java: Add module keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>)</li>
<li>Lean4: Add operators <code>]'</code>, <code>]?</code>,
<code>]!</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2946">#2946</a>)</li>
<li>LESS: Support single-line comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3005">#3005</a>)</li>
<li>LilyPond: Update to 2.25.29 (<a
href="https://redirect.github.com/pygments/pygments/issues/2974">#2974</a>)</li>
<li>LLVM: Support C-style comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3023">#3023</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2978">#2978</a>)</li>
<li>Lua(u): Fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3047">#3047</a>)</li>
<li>Macaulay2: Update to 1.25.05 (<a
href="https://redirect.github.com/pygments/pygments/issues/2893">#2893</a>),
1.25.11 (<a
href="https://redirect.github.com/pygments/pygments/issues/2988">#2988</a>)</li>
<li>Mathematica: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2957">#2957</a>)</li>
<li>meson: Add additional operators (<a
href="https://redirect.github.com/pygments/pygments/issues/2919">#2919</a>)</li>
<li>MySQL: Update keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2970">#2970</a>)</li>
<li>org-Mode: Support both schedule and deadline (<a
href="https://redirect.github.com/pygments/pygments/issues/2899">#2899</a>)</li>
<li>PHP: Add <code>__PROPERTY__</code> magic constant (<a
href="https://redirect.github.com/pygments/pygments/issues/2924">#2924</a>),
add reserved keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/3002">#3002</a>)</li>
<li>PostgreSQL: Add more keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2985">#2985</a>)</li>
<li>protobuf: Fix namespace tokenization (<a
href="https://redirect.github.com/pygments/pygments/issues/2929">#2929</a>)</li>
<li>Python: Add <code>t</code>-string support (<a
href="https://redirect.github.com/pygments/pygments/issues/2973">#2973</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3009">#3009</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3010">#3010</a>)</li>
<li>Tablegen: Fix infinite loop (<a
href="https://redirect.github.com/pygments/pygments/issues/2972">#2972</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2940">#2940</a>)</li>
<li>Tera Term macro: Add commands introduced in v5.3 through v5.6 (<a
href="https://redirect.github.com/pygments/pygments/issues/2951">#2951</a>)</li>
<li>TOML: Support TOML 1.1.0 (<a
href="https://redirect.github.com/pygments/pygments/issues/3026">#3026</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3027">#3027</a>)</li>
<li>Turtle: Allow empty comment lines (<a
href="https://redirect.github.com/pygments/pygments/issues/2980">#2980</a>)</li>
<li>XML: Added <code>.xbrl</code> as file ending (<a
href="https://redirect.github.com/pygments/pygments/issues/2890">#2890</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2891">#2891</a>)</li>
</ul>
</li>
<li>
<p>Drop Python 3.8, and add Python 3.14 as a supported version (<a
href="https://redirect.github.com/pygments/pygments/issues/2987">#2987</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3012">#3012</a>)</p>
</li>
<li>
<p>Various improvements to <code>autopygmentize</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2894">#2894</a>)</p>
</li>
<li>
<p>Update <code>onedark</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2977">#2977</a>)</p>
</li>
<li>
<p>Update <code>rtt</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2895">#2895</a>)</p>
</li>
<li>
<p>Cache entry points to improve performance (<a
href="https://redirect.github.com/pygments/pygments/issues/2979">#2979</a>)</p>
</li>
<li>
<p>Fix <code>xterm-256</code> color table (<a
href="https://redirect.github.com/pygments/pygments/issues/3043">#3043</a>)</p>
</li>
<li>
<p>Fix <code>kwargs</code> dictionary getting mutated on each call (<a
href="https://redirect.github.com/pygments/pygments/issues/3044">#3044</a>)</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pygments/pygments/blob/master/CHANGES">pygments's
changelog</a>.</em></p>
<blockquote>
<h2>Version 2.20.0</h2>
<p>(released March 29th, 2026)</p>
<ul>
<li>
<p>New lexers:</p>
<ul>
<li>Rell (<a
href="https://redirect.github.com/pygments/pygments/issues/2914">#2914</a>)</li>
</ul>
</li>
<li>
<p>Updated lexers:</p>
<ul>
<li>archetype: Fix catastrophic backtracking in GUID and ID patterns (<a
href="https://redirect.github.com/pygments/pygments/issues/3064">#3064</a>)</li>
<li>ASN.1: Recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3014">#3014</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li>C++: Add C++26 keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>),
add integer literal suffixes (<a
href="https://redirect.github.com/pygments/pygments/issues/2966">#2966</a>)</li>
<li>ComponentPascal: Fix <code>analyse_text</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/3028">#3028</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3032">#3032</a>)</li>
<li>Coq renamed to Rocq (<a
href="https://redirect.github.com/pygments/pygments/issues/2883">#2883</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2908">#2908</a>)</li>
<li>Cython: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2932">#2932</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2933">#2933</a>)</li>
<li>Debian control: Improve architecture parsing (<a
href="https://redirect.github.com/pygments/pygments/issues/3052">#3052</a>)</li>
<li>Devicetree: Add support for overlay/fragments (<a
href="https://redirect.github.com/pygments/pygments/issues/3021">#3021</a>),
add bytestring support (<a
href="https://redirect.github.com/pygments/pygments/issues/3022">#3022</a>),
fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3057">#3057</a>)</li>
<li>Fennel: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2911">#2911</a>)</li>
<li>Haskell: Handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/1795">#1795</a>)</li>
<li>Java: Add module keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>)</li>
<li>Lean4: Add operators <code>]'</code>, <code>]?</code>,
<code>]!</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2946">#2946</a>)</li>
<li>LESS: Support single-line comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3005">#3005</a>)</li>
<li>LilyPond: Update to 2.25.29 (<a
href="https://redirect.github.com/pygments/pygments/issues/2974">#2974</a>)</li>
<li>LLVM: Support C-style comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3023">#3023</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2978">#2978</a>)</li>
<li>Lua(u): Fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3047">#3047</a>)</li>
<li>Macaulay2: Update to 1.25.05 (<a
href="https://redirect.github.com/pygments/pygments/issues/2893">#2893</a>),
1.25.11 (<a
href="https://redirect.github.com/pygments/pygments/issues/2988">#2988</a>)</li>
<li>Mathematica: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2957">#2957</a>)</li>
<li>meson: Add additional operators (<a
href="https://redirect.github.com/pygments/pygments/issues/2919">#2919</a>)</li>
<li>MySQL: Update keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2970">#2970</a>)</li>
<li>org-Mode: Support both schedule and deadline (<a
href="https://redirect.github.com/pygments/pygments/issues/2899">#2899</a>)</li>
<li>PHP: Add <code>__PROPERTY__</code> magic constant (<a
href="https://redirect.github.com/pygments/pygments/issues/2924">#2924</a>),
add reserved keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/3002">#3002</a>)</li>
<li>PostgreSQL: Add more keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2985">#2985</a>)</li>
<li>protobuf: Fix namespace tokenization (<a
href="https://redirect.github.com/pygments/pygments/issues/2929">#2929</a>)</li>
<li>Python: Add <code>t</code>-string support (<a
href="https://redirect.github.com/pygments/pygments/issues/2973">#2973</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3009">#3009</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3010">#3010</a>)</li>
<li>Tablegen: Fix infinite loop (<a
href="https://redirect.github.com/pygments/pygments/issues/2972">#2972</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2940">#2940</a>)</li>
<li>Tera Term macro: Add commands introduced in v5.3 through v5.6 (<a
href="https://redirect.github.com/pygments/pygments/issues/2951">#2951</a>)</li>
<li>TOML: Support TOML 1.1.0 (<a
href="https://redirect.github.com/pygments/pygments/issues/3026">#3026</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3027">#3027</a>)</li>
<li>Turtle: Allow empty comment lines (<a
href="https://redirect.github.com/pygments/pygments/issues/2980">#2980</a>)</li>
<li>XML: Added <code>.xbrl</code> as file ending (<a
href="https://redirect.github.com/pygments/pygments/issues/2890">#2890</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2891">#2891</a>)</li>
</ul>
</li>
<li>
<p>Drop Python 3.8, and add Python 3.14 as a supported version (<a
href="https://redirect.github.com/pygments/pygments/issues/2987">#2987</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3012">#3012</a>)</p>
</li>
<li>
<p>Various improvements to <code>autopygmentize</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2894">#2894</a>)</p>
</li>
<li>
<p>Update <code>onedark</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2977">#2977</a>)</p>
</li>
<li>
<p>Update <code>rtt</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2895">#2895</a>)</p>
</li>
<li>
<p>Cache entry points to improve performance (<a
href="https://redirect.github.com/pygments/pygments/issues/2979">#2979</a>)</p>
</li>
<li>
<p>Fix <code>xterm-256</code> color table (<a
href="https://redirect.github.com/pygments/pygments/issues/3043">#3043</a>)</p>
</li>
<li>
<p>Fix <code>kwargs</code> dictionary getting mutated on each call (<a
href="https://redirect.github.com/pygments/pygments/issues/3044">#3044</a>)</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/pygments/pygments/commit/708197d82827ba2d5ca78bcbb653c7102ce86dcd"><code>708197d</code></a>
Fix underline length.</li>
<li><a
href="https://github.com/pygments/pygments/commit/1d4538ae8621d766ecc91ff59caf76ab75983abc"><code>1d4538a</code></a>
Prepare 2.20 release.</li>
<li><a
href="https://github.com/pygments/pygments/commit/2ceaee4e634eebae2d10a47fd05406871f6bac8f"><code>2ceaee4</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/e3a3c54b58c7f80bc4db887e471d4f91c77844ed"><code>e3a3c54</code></a>
Fix Haskell lexer: handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>)</li>
<li><a
href="https://github.com/pygments/pygments/commit/d7c3453e342dac319f58e4091f4ef183cc49d802"><code>d7c3453</code></a>
Merge pull request <a
href="https://redirect.github.com/pygments/pygments/issues/3071">#3071</a>
from pygments/harden-html-formatter</li>
<li><a
href="https://github.com/pygments/pygments/commit/0f97e7c37d44abfa4ddfddf44a3290fdad586034"><code>0f97e7c</code></a>
Harden the HTML formatter against CSS.</li>
<li><a
href="https://github.com/pygments/pygments/commit/9f981b2ba42b88ca5bdcebf12cd01efd7cd80aec"><code>9f981b2</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/1d889151024e9a53f3702a60558b29b070306e9e"><code>1d88915</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/c3d93adb9827fc054c3c12b47bde31c781a36a93"><code>c3d93ad</code></a>
Fix ASN.1 lexer: recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li><a
href="https://github.com/pygments/pygments/commit/4f06bcf8a5ba3f2b5bda24a26ccf041a1a65d91e"><code>4f06bcf</code></a>
fix bad behaving backtracking regex in CommonLispLexer</li>
<li>Additional commits viewable in <a
href="https://github.com/pygments/pygments/compare/2.19.2...2.20.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pygments&package-manager=uv&previous-version=2.19.2&new-version=2.20.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-30 18:20:39 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
6204281b1c chore(deps): bump pygments from 2.19.2 to 2.20.0 in /libs/sdk-py (#7351)
Bumps [pygments](https://github.com/pygments/pygments) from 2.19.2 to
2.20.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pygments/pygments/releases">pygments's
releases</a>.</em></p>
<blockquote>
<h2>2.20.0</h2>
<ul>
<li>
<p>New lexers:</p>
<ul>
<li>Rell (<a
href="https://redirect.github.com/pygments/pygments/issues/2914">#2914</a>)</li>
</ul>
</li>
<li>
<p>Updated lexers:</p>
<ul>
<li>archetype: Fix catastrophic backtracking in GUID and ID patterns (<a
href="https://redirect.github.com/pygments/pygments/issues/3064">#3064</a>)</li>
<li>ASN.1: Recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3014">#3014</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li>C++: Add C++26 keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>),
add integer literal suffixes (<a
href="https://redirect.github.com/pygments/pygments/issues/2966">#2966</a>)</li>
<li>ComponentPascal: Fix <code>analyse_text</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/3028">#3028</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3032">#3032</a>)</li>
<li>Coq renamed to Rocq (<a
href="https://redirect.github.com/pygments/pygments/issues/2883">#2883</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2908">#2908</a>)</li>
<li>Cython: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2932">#2932</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2933">#2933</a>)</li>
<li>Debian control: Improve architecture parsing (<a
href="https://redirect.github.com/pygments/pygments/issues/3052">#3052</a>)</li>
<li>Devicetree: Add support for overlay/fragments (<a
href="https://redirect.github.com/pygments/pygments/issues/3021">#3021</a>),
add bytestring support (<a
href="https://redirect.github.com/pygments/pygments/issues/3022">#3022</a>),
fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3057">#3057</a>)</li>
<li>Fennel: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2911">#2911</a>)</li>
<li>Haskell: Handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/1795">#1795</a>)</li>
<li>Java: Add module keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>)</li>
<li>Lean4: Add operators <code>]'</code>, <code>]?</code>,
<code>]!</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2946">#2946</a>)</li>
<li>LESS: Support single-line comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3005">#3005</a>)</li>
<li>LilyPond: Update to 2.25.29 (<a
href="https://redirect.github.com/pygments/pygments/issues/2974">#2974</a>)</li>
<li>LLVM: Support C-style comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3023">#3023</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2978">#2978</a>)</li>
<li>Lua(u): Fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3047">#3047</a>)</li>
<li>Macaulay2: Update to 1.25.05 (<a
href="https://redirect.github.com/pygments/pygments/issues/2893">#2893</a>),
1.25.11 (<a
href="https://redirect.github.com/pygments/pygments/issues/2988">#2988</a>)</li>
<li>Mathematica: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2957">#2957</a>)</li>
<li>meson: Add additional operators (<a
href="https://redirect.github.com/pygments/pygments/issues/2919">#2919</a>)</li>
<li>MySQL: Update keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2970">#2970</a>)</li>
<li>org-Mode: Support both schedule and deadline (<a
href="https://redirect.github.com/pygments/pygments/issues/2899">#2899</a>)</li>
<li>PHP: Add <code>__PROPERTY__</code> magic constant (<a
href="https://redirect.github.com/pygments/pygments/issues/2924">#2924</a>),
add reserved keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/3002">#3002</a>)</li>
<li>PostgreSQL: Add more keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2985">#2985</a>)</li>
<li>protobuf: Fix namespace tokenization (<a
href="https://redirect.github.com/pygments/pygments/issues/2929">#2929</a>)</li>
<li>Python: Add <code>t</code>-string support (<a
href="https://redirect.github.com/pygments/pygments/issues/2973">#2973</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3009">#3009</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3010">#3010</a>)</li>
<li>Tablegen: Fix infinite loop (<a
href="https://redirect.github.com/pygments/pygments/issues/2972">#2972</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2940">#2940</a>)</li>
<li>Tera Term macro: Add commands introduced in v5.3 through v5.6 (<a
href="https://redirect.github.com/pygments/pygments/issues/2951">#2951</a>)</li>
<li>TOML: Support TOML 1.1.0 (<a
href="https://redirect.github.com/pygments/pygments/issues/3026">#3026</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3027">#3027</a>)</li>
<li>Turtle: Allow empty comment lines (<a
href="https://redirect.github.com/pygments/pygments/issues/2980">#2980</a>)</li>
<li>XML: Added <code>.xbrl</code> as file ending (<a
href="https://redirect.github.com/pygments/pygments/issues/2890">#2890</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2891">#2891</a>)</li>
</ul>
</li>
<li>
<p>Drop Python 3.8, and add Python 3.14 as a supported version (<a
href="https://redirect.github.com/pygments/pygments/issues/2987">#2987</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3012">#3012</a>)</p>
</li>
<li>
<p>Various improvements to <code>autopygmentize</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2894">#2894</a>)</p>
</li>
<li>
<p>Update <code>onedark</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2977">#2977</a>)</p>
</li>
<li>
<p>Update <code>rtt</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2895">#2895</a>)</p>
</li>
<li>
<p>Cache entry points to improve performance (<a
href="https://redirect.github.com/pygments/pygments/issues/2979">#2979</a>)</p>
</li>
<li>
<p>Fix <code>xterm-256</code> color table (<a
href="https://redirect.github.com/pygments/pygments/issues/3043">#3043</a>)</p>
</li>
<li>
<p>Fix <code>kwargs</code> dictionary getting mutated on each call (<a
href="https://redirect.github.com/pygments/pygments/issues/3044">#3044</a>)</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pygments/pygments/blob/master/CHANGES">pygments's
changelog</a>.</em></p>
<blockquote>
<h2>Version 2.20.0</h2>
<p>(released March 29th, 2026)</p>
<ul>
<li>
<p>New lexers:</p>
<ul>
<li>Rell (<a
href="https://redirect.github.com/pygments/pygments/issues/2914">#2914</a>)</li>
</ul>
</li>
<li>
<p>Updated lexers:</p>
<ul>
<li>archetype: Fix catastrophic backtracking in GUID and ID patterns (<a
href="https://redirect.github.com/pygments/pygments/issues/3064">#3064</a>)</li>
<li>ASN.1: Recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3014">#3014</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li>C++: Add C++26 keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>),
add integer literal suffixes (<a
href="https://redirect.github.com/pygments/pygments/issues/2966">#2966</a>)</li>
<li>ComponentPascal: Fix <code>analyse_text</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/3028">#3028</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3032">#3032</a>)</li>
<li>Coq renamed to Rocq (<a
href="https://redirect.github.com/pygments/pygments/issues/2883">#2883</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2908">#2908</a>)</li>
<li>Cython: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2932">#2932</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2933">#2933</a>)</li>
<li>Debian control: Improve architecture parsing (<a
href="https://redirect.github.com/pygments/pygments/issues/3052">#3052</a>)</li>
<li>Devicetree: Add support for overlay/fragments (<a
href="https://redirect.github.com/pygments/pygments/issues/3021">#3021</a>),
add bytestring support (<a
href="https://redirect.github.com/pygments/pygments/issues/3022">#3022</a>),
fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3057">#3057</a>)</li>
<li>Fennel: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2911">#2911</a>)</li>
<li>Haskell: Handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/1795">#1795</a>)</li>
<li>Java: Add module keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>)</li>
<li>Lean4: Add operators <code>]'</code>, <code>]?</code>,
<code>]!</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2946">#2946</a>)</li>
<li>LESS: Support single-line comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3005">#3005</a>)</li>
<li>LilyPond: Update to 2.25.29 (<a
href="https://redirect.github.com/pygments/pygments/issues/2974">#2974</a>)</li>
<li>LLVM: Support C-style comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3023">#3023</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2978">#2978</a>)</li>
<li>Lua(u): Fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3047">#3047</a>)</li>
<li>Macaulay2: Update to 1.25.05 (<a
href="https://redirect.github.com/pygments/pygments/issues/2893">#2893</a>),
1.25.11 (<a
href="https://redirect.github.com/pygments/pygments/issues/2988">#2988</a>)</li>
<li>Mathematica: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2957">#2957</a>)</li>
<li>meson: Add additional operators (<a
href="https://redirect.github.com/pygments/pygments/issues/2919">#2919</a>)</li>
<li>MySQL: Update keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2970">#2970</a>)</li>
<li>org-Mode: Support both schedule and deadline (<a
href="https://redirect.github.com/pygments/pygments/issues/2899">#2899</a>)</li>
<li>PHP: Add <code>__PROPERTY__</code> magic constant (<a
href="https://redirect.github.com/pygments/pygments/issues/2924">#2924</a>),
add reserved keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/3002">#3002</a>)</li>
<li>PostgreSQL: Add more keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2985">#2985</a>)</li>
<li>protobuf: Fix namespace tokenization (<a
href="https://redirect.github.com/pygments/pygments/issues/2929">#2929</a>)</li>
<li>Python: Add <code>t</code>-string support (<a
href="https://redirect.github.com/pygments/pygments/issues/2973">#2973</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3009">#3009</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3010">#3010</a>)</li>
<li>Tablegen: Fix infinite loop (<a
href="https://redirect.github.com/pygments/pygments/issues/2972">#2972</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2940">#2940</a>)</li>
<li>Tera Term macro: Add commands introduced in v5.3 through v5.6 (<a
href="https://redirect.github.com/pygments/pygments/issues/2951">#2951</a>)</li>
<li>TOML: Support TOML 1.1.0 (<a
href="https://redirect.github.com/pygments/pygments/issues/3026">#3026</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3027">#3027</a>)</li>
<li>Turtle: Allow empty comment lines (<a
href="https://redirect.github.com/pygments/pygments/issues/2980">#2980</a>)</li>
<li>XML: Added <code>.xbrl</code> as file ending (<a
href="https://redirect.github.com/pygments/pygments/issues/2890">#2890</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2891">#2891</a>)</li>
</ul>
</li>
<li>
<p>Drop Python 3.8, and add Python 3.14 as a supported version (<a
href="https://redirect.github.com/pygments/pygments/issues/2987">#2987</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3012">#3012</a>)</p>
</li>
<li>
<p>Various improvements to <code>autopygmentize</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2894">#2894</a>)</p>
</li>
<li>
<p>Update <code>onedark</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2977">#2977</a>)</p>
</li>
<li>
<p>Update <code>rtt</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2895">#2895</a>)</p>
</li>
<li>
<p>Cache entry points to improve performance (<a
href="https://redirect.github.com/pygments/pygments/issues/2979">#2979</a>)</p>
</li>
<li>
<p>Fix <code>xterm-256</code> color table (<a
href="https://redirect.github.com/pygments/pygments/issues/3043">#3043</a>)</p>
</li>
<li>
<p>Fix <code>kwargs</code> dictionary getting mutated on each call (<a
href="https://redirect.github.com/pygments/pygments/issues/3044">#3044</a>)</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/pygments/pygments/commit/708197d82827ba2d5ca78bcbb653c7102ce86dcd"><code>708197d</code></a>
Fix underline length.</li>
<li><a
href="https://github.com/pygments/pygments/commit/1d4538ae8621d766ecc91ff59caf76ab75983abc"><code>1d4538a</code></a>
Prepare 2.20 release.</li>
<li><a
href="https://github.com/pygments/pygments/commit/2ceaee4e634eebae2d10a47fd05406871f6bac8f"><code>2ceaee4</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/e3a3c54b58c7f80bc4db887e471d4f91c77844ed"><code>e3a3c54</code></a>
Fix Haskell lexer: handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>)</li>
<li><a
href="https://github.com/pygments/pygments/commit/d7c3453e342dac319f58e4091f4ef183cc49d802"><code>d7c3453</code></a>
Merge pull request <a
href="https://redirect.github.com/pygments/pygments/issues/3071">#3071</a>
from pygments/harden-html-formatter</li>
<li><a
href="https://github.com/pygments/pygments/commit/0f97e7c37d44abfa4ddfddf44a3290fdad586034"><code>0f97e7c</code></a>
Harden the HTML formatter against CSS.</li>
<li><a
href="https://github.com/pygments/pygments/commit/9f981b2ba42b88ca5bdcebf12cd01efd7cd80aec"><code>9f981b2</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/1d889151024e9a53f3702a60558b29b070306e9e"><code>1d88915</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/c3d93adb9827fc054c3c12b47bde31c781a36a93"><code>c3d93ad</code></a>
Fix ASN.1 lexer: recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li><a
href="https://github.com/pygments/pygments/commit/4f06bcf8a5ba3f2b5bda24a26ccf041a1a65d91e"><code>4f06bcf</code></a>
fix bad behaving backtracking regex in CommonLispLexer</li>
<li>Additional commits viewable in <a
href="https://github.com/pygments/pygments/compare/2.19.2...2.20.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pygments&package-manager=uv&previous-version=2.19.2&new-version=2.20.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-30 11:14:00 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
a05e521f94 chore(deps): bump pygments from 2.19.2 to 2.20.0 in /libs/checkpoint-sqlite (#7350)
Bumps [pygments](https://github.com/pygments/pygments) from 2.19.2 to
2.20.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pygments/pygments/releases">pygments's
releases</a>.</em></p>
<blockquote>
<h2>2.20.0</h2>
<ul>
<li>
<p>New lexers:</p>
<ul>
<li>Rell (<a
href="https://redirect.github.com/pygments/pygments/issues/2914">#2914</a>)</li>
</ul>
</li>
<li>
<p>Updated lexers:</p>
<ul>
<li>archetype: Fix catastrophic backtracking in GUID and ID patterns (<a
href="https://redirect.github.com/pygments/pygments/issues/3064">#3064</a>)</li>
<li>ASN.1: Recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3014">#3014</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li>C++: Add C++26 keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>),
add integer literal suffixes (<a
href="https://redirect.github.com/pygments/pygments/issues/2966">#2966</a>)</li>
<li>ComponentPascal: Fix <code>analyse_text</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/3028">#3028</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3032">#3032</a>)</li>
<li>Coq renamed to Rocq (<a
href="https://redirect.github.com/pygments/pygments/issues/2883">#2883</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2908">#2908</a>)</li>
<li>Cython: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2932">#2932</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2933">#2933</a>)</li>
<li>Debian control: Improve architecture parsing (<a
href="https://redirect.github.com/pygments/pygments/issues/3052">#3052</a>)</li>
<li>Devicetree: Add support for overlay/fragments (<a
href="https://redirect.github.com/pygments/pygments/issues/3021">#3021</a>),
add bytestring support (<a
href="https://redirect.github.com/pygments/pygments/issues/3022">#3022</a>),
fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3057">#3057</a>)</li>
<li>Fennel: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2911">#2911</a>)</li>
<li>Haskell: Handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/1795">#1795</a>)</li>
<li>Java: Add module keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>)</li>
<li>Lean4: Add operators <code>]'</code>, <code>]?</code>,
<code>]!</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2946">#2946</a>)</li>
<li>LESS: Support single-line comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3005">#3005</a>)</li>
<li>LilyPond: Update to 2.25.29 (<a
href="https://redirect.github.com/pygments/pygments/issues/2974">#2974</a>)</li>
<li>LLVM: Support C-style comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3023">#3023</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2978">#2978</a>)</li>
<li>Lua(u): Fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3047">#3047</a>)</li>
<li>Macaulay2: Update to 1.25.05 (<a
href="https://redirect.github.com/pygments/pygments/issues/2893">#2893</a>),
1.25.11 (<a
href="https://redirect.github.com/pygments/pygments/issues/2988">#2988</a>)</li>
<li>Mathematica: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2957">#2957</a>)</li>
<li>meson: Add additional operators (<a
href="https://redirect.github.com/pygments/pygments/issues/2919">#2919</a>)</li>
<li>MySQL: Update keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2970">#2970</a>)</li>
<li>org-Mode: Support both schedule and deadline (<a
href="https://redirect.github.com/pygments/pygments/issues/2899">#2899</a>)</li>
<li>PHP: Add <code>__PROPERTY__</code> magic constant (<a
href="https://redirect.github.com/pygments/pygments/issues/2924">#2924</a>),
add reserved keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/3002">#3002</a>)</li>
<li>PostgreSQL: Add more keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2985">#2985</a>)</li>
<li>protobuf: Fix namespace tokenization (<a
href="https://redirect.github.com/pygments/pygments/issues/2929">#2929</a>)</li>
<li>Python: Add <code>t</code>-string support (<a
href="https://redirect.github.com/pygments/pygments/issues/2973">#2973</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3009">#3009</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3010">#3010</a>)</li>
<li>Tablegen: Fix infinite loop (<a
href="https://redirect.github.com/pygments/pygments/issues/2972">#2972</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2940">#2940</a>)</li>
<li>Tera Term macro: Add commands introduced in v5.3 through v5.6 (<a
href="https://redirect.github.com/pygments/pygments/issues/2951">#2951</a>)</li>
<li>TOML: Support TOML 1.1.0 (<a
href="https://redirect.github.com/pygments/pygments/issues/3026">#3026</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3027">#3027</a>)</li>
<li>Turtle: Allow empty comment lines (<a
href="https://redirect.github.com/pygments/pygments/issues/2980">#2980</a>)</li>
<li>XML: Added <code>.xbrl</code> as file ending (<a
href="https://redirect.github.com/pygments/pygments/issues/2890">#2890</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2891">#2891</a>)</li>
</ul>
</li>
<li>
<p>Drop Python 3.8, and add Python 3.14 as a supported version (<a
href="https://redirect.github.com/pygments/pygments/issues/2987">#2987</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3012">#3012</a>)</p>
</li>
<li>
<p>Various improvements to <code>autopygmentize</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2894">#2894</a>)</p>
</li>
<li>
<p>Update <code>onedark</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2977">#2977</a>)</p>
</li>
<li>
<p>Update <code>rtt</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2895">#2895</a>)</p>
</li>
<li>
<p>Cache entry points to improve performance (<a
href="https://redirect.github.com/pygments/pygments/issues/2979">#2979</a>)</p>
</li>
<li>
<p>Fix <code>xterm-256</code> color table (<a
href="https://redirect.github.com/pygments/pygments/issues/3043">#3043</a>)</p>
</li>
<li>
<p>Fix <code>kwargs</code> dictionary getting mutated on each call (<a
href="https://redirect.github.com/pygments/pygments/issues/3044">#3044</a>)</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pygments/pygments/blob/master/CHANGES">pygments's
changelog</a>.</em></p>
<blockquote>
<h2>Version 2.20.0</h2>
<p>(released March 29th, 2026)</p>
<ul>
<li>
<p>New lexers:</p>
<ul>
<li>Rell (<a
href="https://redirect.github.com/pygments/pygments/issues/2914">#2914</a>)</li>
</ul>
</li>
<li>
<p>Updated lexers:</p>
<ul>
<li>archetype: Fix catastrophic backtracking in GUID and ID patterns (<a
href="https://redirect.github.com/pygments/pygments/issues/3064">#3064</a>)</li>
<li>ASN.1: Recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3014">#3014</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li>C++: Add C++26 keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>),
add integer literal suffixes (<a
href="https://redirect.github.com/pygments/pygments/issues/2966">#2966</a>)</li>
<li>ComponentPascal: Fix <code>analyse_text</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/3028">#3028</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3032">#3032</a>)</li>
<li>Coq renamed to Rocq (<a
href="https://redirect.github.com/pygments/pygments/issues/2883">#2883</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2908">#2908</a>)</li>
<li>Cython: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2932">#2932</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2933">#2933</a>)</li>
<li>Debian control: Improve architecture parsing (<a
href="https://redirect.github.com/pygments/pygments/issues/3052">#3052</a>)</li>
<li>Devicetree: Add support for overlay/fragments (<a
href="https://redirect.github.com/pygments/pygments/issues/3021">#3021</a>),
add bytestring support (<a
href="https://redirect.github.com/pygments/pygments/issues/3022">#3022</a>),
fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3057">#3057</a>)</li>
<li>Fennel: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2911">#2911</a>)</li>
<li>Haskell: Handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/1795">#1795</a>)</li>
<li>Java: Add module keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>)</li>
<li>Lean4: Add operators <code>]'</code>, <code>]?</code>,
<code>]!</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2946">#2946</a>)</li>
<li>LESS: Support single-line comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3005">#3005</a>)</li>
<li>LilyPond: Update to 2.25.29 (<a
href="https://redirect.github.com/pygments/pygments/issues/2974">#2974</a>)</li>
<li>LLVM: Support C-style comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3023">#3023</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2978">#2978</a>)</li>
<li>Lua(u): Fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3047">#3047</a>)</li>
<li>Macaulay2: Update to 1.25.05 (<a
href="https://redirect.github.com/pygments/pygments/issues/2893">#2893</a>),
1.25.11 (<a
href="https://redirect.github.com/pygments/pygments/issues/2988">#2988</a>)</li>
<li>Mathematica: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2957">#2957</a>)</li>
<li>meson: Add additional operators (<a
href="https://redirect.github.com/pygments/pygments/issues/2919">#2919</a>)</li>
<li>MySQL: Update keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2970">#2970</a>)</li>
<li>org-Mode: Support both schedule and deadline (<a
href="https://redirect.github.com/pygments/pygments/issues/2899">#2899</a>)</li>
<li>PHP: Add <code>__PROPERTY__</code> magic constant (<a
href="https://redirect.github.com/pygments/pygments/issues/2924">#2924</a>),
add reserved keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/3002">#3002</a>)</li>
<li>PostgreSQL: Add more keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2985">#2985</a>)</li>
<li>protobuf: Fix namespace tokenization (<a
href="https://redirect.github.com/pygments/pygments/issues/2929">#2929</a>)</li>
<li>Python: Add <code>t</code>-string support (<a
href="https://redirect.github.com/pygments/pygments/issues/2973">#2973</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3009">#3009</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3010">#3010</a>)</li>
<li>Tablegen: Fix infinite loop (<a
href="https://redirect.github.com/pygments/pygments/issues/2972">#2972</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2940">#2940</a>)</li>
<li>Tera Term macro: Add commands introduced in v5.3 through v5.6 (<a
href="https://redirect.github.com/pygments/pygments/issues/2951">#2951</a>)</li>
<li>TOML: Support TOML 1.1.0 (<a
href="https://redirect.github.com/pygments/pygments/issues/3026">#3026</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3027">#3027</a>)</li>
<li>Turtle: Allow empty comment lines (<a
href="https://redirect.github.com/pygments/pygments/issues/2980">#2980</a>)</li>
<li>XML: Added <code>.xbrl</code> as file ending (<a
href="https://redirect.github.com/pygments/pygments/issues/2890">#2890</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2891">#2891</a>)</li>
</ul>
</li>
<li>
<p>Drop Python 3.8, and add Python 3.14 as a supported version (<a
href="https://redirect.github.com/pygments/pygments/issues/2987">#2987</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3012">#3012</a>)</p>
</li>
<li>
<p>Various improvements to <code>autopygmentize</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2894">#2894</a>)</p>
</li>
<li>
<p>Update <code>onedark</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2977">#2977</a>)</p>
</li>
<li>
<p>Update <code>rtt</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2895">#2895</a>)</p>
</li>
<li>
<p>Cache entry points to improve performance (<a
href="https://redirect.github.com/pygments/pygments/issues/2979">#2979</a>)</p>
</li>
<li>
<p>Fix <code>xterm-256</code> color table (<a
href="https://redirect.github.com/pygments/pygments/issues/3043">#3043</a>)</p>
</li>
<li>
<p>Fix <code>kwargs</code> dictionary getting mutated on each call (<a
href="https://redirect.github.com/pygments/pygments/issues/3044">#3044</a>)</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/pygments/pygments/commit/708197d82827ba2d5ca78bcbb653c7102ce86dcd"><code>708197d</code></a>
Fix underline length.</li>
<li><a
href="https://github.com/pygments/pygments/commit/1d4538ae8621d766ecc91ff59caf76ab75983abc"><code>1d4538a</code></a>
Prepare 2.20 release.</li>
<li><a
href="https://github.com/pygments/pygments/commit/2ceaee4e634eebae2d10a47fd05406871f6bac8f"><code>2ceaee4</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/e3a3c54b58c7f80bc4db887e471d4f91c77844ed"><code>e3a3c54</code></a>
Fix Haskell lexer: handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>)</li>
<li><a
href="https://github.com/pygments/pygments/commit/d7c3453e342dac319f58e4091f4ef183cc49d802"><code>d7c3453</code></a>
Merge pull request <a
href="https://redirect.github.com/pygments/pygments/issues/3071">#3071</a>
from pygments/harden-html-formatter</li>
<li><a
href="https://github.com/pygments/pygments/commit/0f97e7c37d44abfa4ddfddf44a3290fdad586034"><code>0f97e7c</code></a>
Harden the HTML formatter against CSS.</li>
<li><a
href="https://github.com/pygments/pygments/commit/9f981b2ba42b88ca5bdcebf12cd01efd7cd80aec"><code>9f981b2</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/1d889151024e9a53f3702a60558b29b070306e9e"><code>1d88915</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/c3d93adb9827fc054c3c12b47bde31c781a36a93"><code>c3d93ad</code></a>
Fix ASN.1 lexer: recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li><a
href="https://github.com/pygments/pygments/commit/4f06bcf8a5ba3f2b5bda24a26ccf041a1a65d91e"><code>4f06bcf</code></a>
fix bad behaving backtracking regex in CommonLispLexer</li>
<li>Additional commits viewable in <a
href="https://github.com/pygments/pygments/compare/2.19.2...2.20.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pygments&package-manager=uv&previous-version=2.19.2&new-version=2.20.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-30 11:13:48 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
ec045477f8 chore(deps): bump pygments from 2.19.2 to 2.20.0 in /libs/checkpoint (#7348)
Bumps [pygments](https://github.com/pygments/pygments) from 2.19.2 to
2.20.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pygments/pygments/releases">pygments's
releases</a>.</em></p>
<blockquote>
<h2>2.20.0</h2>
<ul>
<li>
<p>New lexers:</p>
<ul>
<li>Rell (<a
href="https://redirect.github.com/pygments/pygments/issues/2914">#2914</a>)</li>
</ul>
</li>
<li>
<p>Updated lexers:</p>
<ul>
<li>archetype: Fix catastrophic backtracking in GUID and ID patterns (<a
href="https://redirect.github.com/pygments/pygments/issues/3064">#3064</a>)</li>
<li>ASN.1: Recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3014">#3014</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li>C++: Add C++26 keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>),
add integer literal suffixes (<a
href="https://redirect.github.com/pygments/pygments/issues/2966">#2966</a>)</li>
<li>ComponentPascal: Fix <code>analyse_text</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/3028">#3028</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3032">#3032</a>)</li>
<li>Coq renamed to Rocq (<a
href="https://redirect.github.com/pygments/pygments/issues/2883">#2883</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2908">#2908</a>)</li>
<li>Cython: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2932">#2932</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2933">#2933</a>)</li>
<li>Debian control: Improve architecture parsing (<a
href="https://redirect.github.com/pygments/pygments/issues/3052">#3052</a>)</li>
<li>Devicetree: Add support for overlay/fragments (<a
href="https://redirect.github.com/pygments/pygments/issues/3021">#3021</a>),
add bytestring support (<a
href="https://redirect.github.com/pygments/pygments/issues/3022">#3022</a>),
fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3057">#3057</a>)</li>
<li>Fennel: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2911">#2911</a>)</li>
<li>Haskell: Handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/1795">#1795</a>)</li>
<li>Java: Add module keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>)</li>
<li>Lean4: Add operators <code>]'</code>, <code>]?</code>,
<code>]!</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2946">#2946</a>)</li>
<li>LESS: Support single-line comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3005">#3005</a>)</li>
<li>LilyPond: Update to 2.25.29 (<a
href="https://redirect.github.com/pygments/pygments/issues/2974">#2974</a>)</li>
<li>LLVM: Support C-style comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3023">#3023</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2978">#2978</a>)</li>
<li>Lua(u): Fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3047">#3047</a>)</li>
<li>Macaulay2: Update to 1.25.05 (<a
href="https://redirect.github.com/pygments/pygments/issues/2893">#2893</a>),
1.25.11 (<a
href="https://redirect.github.com/pygments/pygments/issues/2988">#2988</a>)</li>
<li>Mathematica: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2957">#2957</a>)</li>
<li>meson: Add additional operators (<a
href="https://redirect.github.com/pygments/pygments/issues/2919">#2919</a>)</li>
<li>MySQL: Update keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2970">#2970</a>)</li>
<li>org-Mode: Support both schedule and deadline (<a
href="https://redirect.github.com/pygments/pygments/issues/2899">#2899</a>)</li>
<li>PHP: Add <code>__PROPERTY__</code> magic constant (<a
href="https://redirect.github.com/pygments/pygments/issues/2924">#2924</a>),
add reserved keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/3002">#3002</a>)</li>
<li>PostgreSQL: Add more keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2985">#2985</a>)</li>
<li>protobuf: Fix namespace tokenization (<a
href="https://redirect.github.com/pygments/pygments/issues/2929">#2929</a>)</li>
<li>Python: Add <code>t</code>-string support (<a
href="https://redirect.github.com/pygments/pygments/issues/2973">#2973</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3009">#3009</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3010">#3010</a>)</li>
<li>Tablegen: Fix infinite loop (<a
href="https://redirect.github.com/pygments/pygments/issues/2972">#2972</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2940">#2940</a>)</li>
<li>Tera Term macro: Add commands introduced in v5.3 through v5.6 (<a
href="https://redirect.github.com/pygments/pygments/issues/2951">#2951</a>)</li>
<li>TOML: Support TOML 1.1.0 (<a
href="https://redirect.github.com/pygments/pygments/issues/3026">#3026</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3027">#3027</a>)</li>
<li>Turtle: Allow empty comment lines (<a
href="https://redirect.github.com/pygments/pygments/issues/2980">#2980</a>)</li>
<li>XML: Added <code>.xbrl</code> as file ending (<a
href="https://redirect.github.com/pygments/pygments/issues/2890">#2890</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2891">#2891</a>)</li>
</ul>
</li>
<li>
<p>Drop Python 3.8, and add Python 3.14 as a supported version (<a
href="https://redirect.github.com/pygments/pygments/issues/2987">#2987</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3012">#3012</a>)</p>
</li>
<li>
<p>Various improvements to <code>autopygmentize</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2894">#2894</a>)</p>
</li>
<li>
<p>Update <code>onedark</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2977">#2977</a>)</p>
</li>
<li>
<p>Update <code>rtt</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2895">#2895</a>)</p>
</li>
<li>
<p>Cache entry points to improve performance (<a
href="https://redirect.github.com/pygments/pygments/issues/2979">#2979</a>)</p>
</li>
<li>
<p>Fix <code>xterm-256</code> color table (<a
href="https://redirect.github.com/pygments/pygments/issues/3043">#3043</a>)</p>
</li>
<li>
<p>Fix <code>kwargs</code> dictionary getting mutated on each call (<a
href="https://redirect.github.com/pygments/pygments/issues/3044">#3044</a>)</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pygments/pygments/blob/master/CHANGES">pygments's
changelog</a>.</em></p>
<blockquote>
<h2>Version 2.20.0</h2>
<p>(released March 29th, 2026)</p>
<ul>
<li>
<p>New lexers:</p>
<ul>
<li>Rell (<a
href="https://redirect.github.com/pygments/pygments/issues/2914">#2914</a>)</li>
</ul>
</li>
<li>
<p>Updated lexers:</p>
<ul>
<li>archetype: Fix catastrophic backtracking in GUID and ID patterns (<a
href="https://redirect.github.com/pygments/pygments/issues/3064">#3064</a>)</li>
<li>ASN.1: Recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3014">#3014</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li>C++: Add C++26 keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>),
add integer literal suffixes (<a
href="https://redirect.github.com/pygments/pygments/issues/2966">#2966</a>)</li>
<li>ComponentPascal: Fix <code>analyse_text</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/3028">#3028</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3032">#3032</a>)</li>
<li>Coq renamed to Rocq (<a
href="https://redirect.github.com/pygments/pygments/issues/2883">#2883</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2908">#2908</a>)</li>
<li>Cython: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2932">#2932</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2933">#2933</a>)</li>
<li>Debian control: Improve architecture parsing (<a
href="https://redirect.github.com/pygments/pygments/issues/3052">#3052</a>)</li>
<li>Devicetree: Add support for overlay/fragments (<a
href="https://redirect.github.com/pygments/pygments/issues/3021">#3021</a>),
add bytestring support (<a
href="https://redirect.github.com/pygments/pygments/issues/3022">#3022</a>),
fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3057">#3057</a>)</li>
<li>Fennel: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2911">#2911</a>)</li>
<li>Haskell: Handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/1795">#1795</a>)</li>
<li>Java: Add module keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>)</li>
<li>Lean4: Add operators <code>]'</code>, <code>]?</code>,
<code>]!</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2946">#2946</a>)</li>
<li>LESS: Support single-line comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3005">#3005</a>)</li>
<li>LilyPond: Update to 2.25.29 (<a
href="https://redirect.github.com/pygments/pygments/issues/2974">#2974</a>)</li>
<li>LLVM: Support C-style comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3023">#3023</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2978">#2978</a>)</li>
<li>Lua(u): Fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3047">#3047</a>)</li>
<li>Macaulay2: Update to 1.25.05 (<a
href="https://redirect.github.com/pygments/pygments/issues/2893">#2893</a>),
1.25.11 (<a
href="https://redirect.github.com/pygments/pygments/issues/2988">#2988</a>)</li>
<li>Mathematica: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2957">#2957</a>)</li>
<li>meson: Add additional operators (<a
href="https://redirect.github.com/pygments/pygments/issues/2919">#2919</a>)</li>
<li>MySQL: Update keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2970">#2970</a>)</li>
<li>org-Mode: Support both schedule and deadline (<a
href="https://redirect.github.com/pygments/pygments/issues/2899">#2899</a>)</li>
<li>PHP: Add <code>__PROPERTY__</code> magic constant (<a
href="https://redirect.github.com/pygments/pygments/issues/2924">#2924</a>),
add reserved keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/3002">#3002</a>)</li>
<li>PostgreSQL: Add more keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2985">#2985</a>)</li>
<li>protobuf: Fix namespace tokenization (<a
href="https://redirect.github.com/pygments/pygments/issues/2929">#2929</a>)</li>
<li>Python: Add <code>t</code>-string support (<a
href="https://redirect.github.com/pygments/pygments/issues/2973">#2973</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3009">#3009</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3010">#3010</a>)</li>
<li>Tablegen: Fix infinite loop (<a
href="https://redirect.github.com/pygments/pygments/issues/2972">#2972</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2940">#2940</a>)</li>
<li>Tera Term macro: Add commands introduced in v5.3 through v5.6 (<a
href="https://redirect.github.com/pygments/pygments/issues/2951">#2951</a>)</li>
<li>TOML: Support TOML 1.1.0 (<a
href="https://redirect.github.com/pygments/pygments/issues/3026">#3026</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3027">#3027</a>)</li>
<li>Turtle: Allow empty comment lines (<a
href="https://redirect.github.com/pygments/pygments/issues/2980">#2980</a>)</li>
<li>XML: Added <code>.xbrl</code> as file ending (<a
href="https://redirect.github.com/pygments/pygments/issues/2890">#2890</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2891">#2891</a>)</li>
</ul>
</li>
<li>
<p>Drop Python 3.8, and add Python 3.14 as a supported version (<a
href="https://redirect.github.com/pygments/pygments/issues/2987">#2987</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3012">#3012</a>)</p>
</li>
<li>
<p>Various improvements to <code>autopygmentize</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2894">#2894</a>)</p>
</li>
<li>
<p>Update <code>onedark</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2977">#2977</a>)</p>
</li>
<li>
<p>Update <code>rtt</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2895">#2895</a>)</p>
</li>
<li>
<p>Cache entry points to improve performance (<a
href="https://redirect.github.com/pygments/pygments/issues/2979">#2979</a>)</p>
</li>
<li>
<p>Fix <code>xterm-256</code> color table (<a
href="https://redirect.github.com/pygments/pygments/issues/3043">#3043</a>)</p>
</li>
<li>
<p>Fix <code>kwargs</code> dictionary getting mutated on each call (<a
href="https://redirect.github.com/pygments/pygments/issues/3044">#3044</a>)</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/pygments/pygments/commit/708197d82827ba2d5ca78bcbb653c7102ce86dcd"><code>708197d</code></a>
Fix underline length.</li>
<li><a
href="https://github.com/pygments/pygments/commit/1d4538ae8621d766ecc91ff59caf76ab75983abc"><code>1d4538a</code></a>
Prepare 2.20 release.</li>
<li><a
href="https://github.com/pygments/pygments/commit/2ceaee4e634eebae2d10a47fd05406871f6bac8f"><code>2ceaee4</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/e3a3c54b58c7f80bc4db887e471d4f91c77844ed"><code>e3a3c54</code></a>
Fix Haskell lexer: handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>)</li>
<li><a
href="https://github.com/pygments/pygments/commit/d7c3453e342dac319f58e4091f4ef183cc49d802"><code>d7c3453</code></a>
Merge pull request <a
href="https://redirect.github.com/pygments/pygments/issues/3071">#3071</a>
from pygments/harden-html-formatter</li>
<li><a
href="https://github.com/pygments/pygments/commit/0f97e7c37d44abfa4ddfddf44a3290fdad586034"><code>0f97e7c</code></a>
Harden the HTML formatter against CSS.</li>
<li><a
href="https://github.com/pygments/pygments/commit/9f981b2ba42b88ca5bdcebf12cd01efd7cd80aec"><code>9f981b2</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/1d889151024e9a53f3702a60558b29b070306e9e"><code>1d88915</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/c3d93adb9827fc054c3c12b47bde31c781a36a93"><code>c3d93ad</code></a>
Fix ASN.1 lexer: recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li><a
href="https://github.com/pygments/pygments/commit/4f06bcf8a5ba3f2b5bda24a26ccf041a1a65d91e"><code>4f06bcf</code></a>
fix bad behaving backtracking regex in CommonLispLexer</li>
<li>Additional commits viewable in <a
href="https://github.com/pygments/pygments/compare/2.19.2...2.20.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pygments&package-manager=uv&previous-version=2.19.2&new-version=2.20.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-30 11:13:40 -07:00
Eugene YurtsevandGitHub 2fb367e90c fix(langgraph): avoid recursion limit default sentinel collision (#7355)
This changes the fallback `DEFAULT_RECURSION_LIMIT` from `10000` to
`10007`. Today `merge_configs()` treats the default recursion limit as a
proxy for "not explicitly set", so using a round number like `10000`
creates possible collision risk with user-supplied values. Moving the
fallback to `10007` slightly reduces the chance that an explicitly
chosen recursion limit is mistaken for the implicit default while we
keep the current merge semantics.

Created with [Deep Agents
CLI](https://docs.langchain.com/oss/python/deepagents/cli/overview)
using gpt-5.4 (provider: openai).
2026-03-30 13:53:59 -04:00
TanushreeandGitHub 0475497127 feat: Add LangSmith integration metadata to langgraph (#7203)
Adds ls_integration metadata to agents created via langgraph:
`ls_integration:langgraph`

Only sets the value if the key doesn't already exist so that we don't
override the `ls_integration` field set in
[deepagents](https://github.com/langchain-ai/deepagents/pull/1837),
[langchain](https://github.com/langchain-ai/langchain/pull/35810).

LangGraph trace
<img width="1321" height="1017" alt="image"
src="https://github.com/user-attachments/assets/134fad3a-034d-4d90-8fba-318dd7658e3c"
/>

Deepagents trace (value is correctly not set to langgraph in this case)
<img width="1317" height="882" alt="image"
src="https://github.com/user-attachments/assets/d9b09346-5827-4267-95c1-f3f77d0c76f3"
/>
2026-03-30 13:15:53 -04:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
d7343b94c0 chore(deps): bump pygments from 2.19.2 to 2.20.0 in /libs/checkpoint-conformance (#7352)
Bumps [pygments](https://github.com/pygments/pygments) from 2.19.2 to
2.20.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pygments/pygments/releases">pygments's
releases</a>.</em></p>
<blockquote>
<h2>2.20.0</h2>
<ul>
<li>
<p>New lexers:</p>
<ul>
<li>Rell (<a
href="https://redirect.github.com/pygments/pygments/issues/2914">#2914</a>)</li>
</ul>
</li>
<li>
<p>Updated lexers:</p>
<ul>
<li>archetype: Fix catastrophic backtracking in GUID and ID patterns (<a
href="https://redirect.github.com/pygments/pygments/issues/3064">#3064</a>)</li>
<li>ASN.1: Recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3014">#3014</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li>C++: Add C++26 keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>),
add integer literal suffixes (<a
href="https://redirect.github.com/pygments/pygments/issues/2966">#2966</a>)</li>
<li>ComponentPascal: Fix <code>analyse_text</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/3028">#3028</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3032">#3032</a>)</li>
<li>Coq renamed to Rocq (<a
href="https://redirect.github.com/pygments/pygments/issues/2883">#2883</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2908">#2908</a>)</li>
<li>Cython: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2932">#2932</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2933">#2933</a>)</li>
<li>Debian control: Improve architecture parsing (<a
href="https://redirect.github.com/pygments/pygments/issues/3052">#3052</a>)</li>
<li>Devicetree: Add support for overlay/fragments (<a
href="https://redirect.github.com/pygments/pygments/issues/3021">#3021</a>),
add bytestring support (<a
href="https://redirect.github.com/pygments/pygments/issues/3022">#3022</a>),
fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3057">#3057</a>)</li>
<li>Fennel: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2911">#2911</a>)</li>
<li>Haskell: Handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/1795">#1795</a>)</li>
<li>Java: Add module keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>)</li>
<li>Lean4: Add operators <code>]'</code>, <code>]?</code>,
<code>]!</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2946">#2946</a>)</li>
<li>LESS: Support single-line comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3005">#3005</a>)</li>
<li>LilyPond: Update to 2.25.29 (<a
href="https://redirect.github.com/pygments/pygments/issues/2974">#2974</a>)</li>
<li>LLVM: Support C-style comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3023">#3023</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2978">#2978</a>)</li>
<li>Lua(u): Fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3047">#3047</a>)</li>
<li>Macaulay2: Update to 1.25.05 (<a
href="https://redirect.github.com/pygments/pygments/issues/2893">#2893</a>),
1.25.11 (<a
href="https://redirect.github.com/pygments/pygments/issues/2988">#2988</a>)</li>
<li>Mathematica: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2957">#2957</a>)</li>
<li>meson: Add additional operators (<a
href="https://redirect.github.com/pygments/pygments/issues/2919">#2919</a>)</li>
<li>MySQL: Update keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2970">#2970</a>)</li>
<li>org-Mode: Support both schedule and deadline (<a
href="https://redirect.github.com/pygments/pygments/issues/2899">#2899</a>)</li>
<li>PHP: Add <code>__PROPERTY__</code> magic constant (<a
href="https://redirect.github.com/pygments/pygments/issues/2924">#2924</a>),
add reserved keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/3002">#3002</a>)</li>
<li>PostgreSQL: Add more keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2985">#2985</a>)</li>
<li>protobuf: Fix namespace tokenization (<a
href="https://redirect.github.com/pygments/pygments/issues/2929">#2929</a>)</li>
<li>Python: Add <code>t</code>-string support (<a
href="https://redirect.github.com/pygments/pygments/issues/2973">#2973</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3009">#3009</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3010">#3010</a>)</li>
<li>Tablegen: Fix infinite loop (<a
href="https://redirect.github.com/pygments/pygments/issues/2972">#2972</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2940">#2940</a>)</li>
<li>Tera Term macro: Add commands introduced in v5.3 through v5.6 (<a
href="https://redirect.github.com/pygments/pygments/issues/2951">#2951</a>)</li>
<li>TOML: Support TOML 1.1.0 (<a
href="https://redirect.github.com/pygments/pygments/issues/3026">#3026</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3027">#3027</a>)</li>
<li>Turtle: Allow empty comment lines (<a
href="https://redirect.github.com/pygments/pygments/issues/2980">#2980</a>)</li>
<li>XML: Added <code>.xbrl</code> as file ending (<a
href="https://redirect.github.com/pygments/pygments/issues/2890">#2890</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2891">#2891</a>)</li>
</ul>
</li>
<li>
<p>Drop Python 3.8, and add Python 3.14 as a supported version (<a
href="https://redirect.github.com/pygments/pygments/issues/2987">#2987</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3012">#3012</a>)</p>
</li>
<li>
<p>Various improvements to <code>autopygmentize</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2894">#2894</a>)</p>
</li>
<li>
<p>Update <code>onedark</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2977">#2977</a>)</p>
</li>
<li>
<p>Update <code>rtt</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2895">#2895</a>)</p>
</li>
<li>
<p>Cache entry points to improve performance (<a
href="https://redirect.github.com/pygments/pygments/issues/2979">#2979</a>)</p>
</li>
<li>
<p>Fix <code>xterm-256</code> color table (<a
href="https://redirect.github.com/pygments/pygments/issues/3043">#3043</a>)</p>
</li>
<li>
<p>Fix <code>kwargs</code> dictionary getting mutated on each call (<a
href="https://redirect.github.com/pygments/pygments/issues/3044">#3044</a>)</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pygments/pygments/blob/master/CHANGES">pygments's
changelog</a>.</em></p>
<blockquote>
<h2>Version 2.20.0</h2>
<p>(released March 29th, 2026)</p>
<ul>
<li>
<p>New lexers:</p>
<ul>
<li>Rell (<a
href="https://redirect.github.com/pygments/pygments/issues/2914">#2914</a>)</li>
</ul>
</li>
<li>
<p>Updated lexers:</p>
<ul>
<li>archetype: Fix catastrophic backtracking in GUID and ID patterns (<a
href="https://redirect.github.com/pygments/pygments/issues/3064">#3064</a>)</li>
<li>ASN.1: Recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3014">#3014</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li>C++: Add C++26 keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>),
add integer literal suffixes (<a
href="https://redirect.github.com/pygments/pygments/issues/2966">#2966</a>)</li>
<li>ComponentPascal: Fix <code>analyse_text</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/3028">#3028</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3032">#3032</a>)</li>
<li>Coq renamed to Rocq (<a
href="https://redirect.github.com/pygments/pygments/issues/2883">#2883</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2908">#2908</a>)</li>
<li>Cython: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2932">#2932</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2933">#2933</a>)</li>
<li>Debian control: Improve architecture parsing (<a
href="https://redirect.github.com/pygments/pygments/issues/3052">#3052</a>)</li>
<li>Devicetree: Add support for overlay/fragments (<a
href="https://redirect.github.com/pygments/pygments/issues/3021">#3021</a>),
add bytestring support (<a
href="https://redirect.github.com/pygments/pygments/issues/3022">#3022</a>),
fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3057">#3057</a>)</li>
<li>Fennel: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2911">#2911</a>)</li>
<li>Haskell: Handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/1795">#1795</a>)</li>
<li>Java: Add module keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>)</li>
<li>Lean4: Add operators <code>]'</code>, <code>]?</code>,
<code>]!</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2946">#2946</a>)</li>
<li>LESS: Support single-line comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3005">#3005</a>)</li>
<li>LilyPond: Update to 2.25.29 (<a
href="https://redirect.github.com/pygments/pygments/issues/2974">#2974</a>)</li>
<li>LLVM: Support C-style comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3023">#3023</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2978">#2978</a>)</li>
<li>Lua(u): Fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3047">#3047</a>)</li>
<li>Macaulay2: Update to 1.25.05 (<a
href="https://redirect.github.com/pygments/pygments/issues/2893">#2893</a>),
1.25.11 (<a
href="https://redirect.github.com/pygments/pygments/issues/2988">#2988</a>)</li>
<li>Mathematica: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2957">#2957</a>)</li>
<li>meson: Add additional operators (<a
href="https://redirect.github.com/pygments/pygments/issues/2919">#2919</a>)</li>
<li>MySQL: Update keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2970">#2970</a>)</li>
<li>org-Mode: Support both schedule and deadline (<a
href="https://redirect.github.com/pygments/pygments/issues/2899">#2899</a>)</li>
<li>PHP: Add <code>__PROPERTY__</code> magic constant (<a
href="https://redirect.github.com/pygments/pygments/issues/2924">#2924</a>),
add reserved keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/3002">#3002</a>)</li>
<li>PostgreSQL: Add more keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2985">#2985</a>)</li>
<li>protobuf: Fix namespace tokenization (<a
href="https://redirect.github.com/pygments/pygments/issues/2929">#2929</a>)</li>
<li>Python: Add <code>t</code>-string support (<a
href="https://redirect.github.com/pygments/pygments/issues/2973">#2973</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3009">#3009</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3010">#3010</a>)</li>
<li>Tablegen: Fix infinite loop (<a
href="https://redirect.github.com/pygments/pygments/issues/2972">#2972</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2940">#2940</a>)</li>
<li>Tera Term macro: Add commands introduced in v5.3 through v5.6 (<a
href="https://redirect.github.com/pygments/pygments/issues/2951">#2951</a>)</li>
<li>TOML: Support TOML 1.1.0 (<a
href="https://redirect.github.com/pygments/pygments/issues/3026">#3026</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3027">#3027</a>)</li>
<li>Turtle: Allow empty comment lines (<a
href="https://redirect.github.com/pygments/pygments/issues/2980">#2980</a>)</li>
<li>XML: Added <code>.xbrl</code> as file ending (<a
href="https://redirect.github.com/pygments/pygments/issues/2890">#2890</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2891">#2891</a>)</li>
</ul>
</li>
<li>
<p>Drop Python 3.8, and add Python 3.14 as a supported version (<a
href="https://redirect.github.com/pygments/pygments/issues/2987">#2987</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3012">#3012</a>)</p>
</li>
<li>
<p>Various improvements to <code>autopygmentize</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2894">#2894</a>)</p>
</li>
<li>
<p>Update <code>onedark</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2977">#2977</a>)</p>
</li>
<li>
<p>Update <code>rtt</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2895">#2895</a>)</p>
</li>
<li>
<p>Cache entry points to improve performance (<a
href="https://redirect.github.com/pygments/pygments/issues/2979">#2979</a>)</p>
</li>
<li>
<p>Fix <code>xterm-256</code> color table (<a
href="https://redirect.github.com/pygments/pygments/issues/3043">#3043</a>)</p>
</li>
<li>
<p>Fix <code>kwargs</code> dictionary getting mutated on each call (<a
href="https://redirect.github.com/pygments/pygments/issues/3044">#3044</a>)</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/pygments/pygments/commit/708197d82827ba2d5ca78bcbb653c7102ce86dcd"><code>708197d</code></a>
Fix underline length.</li>
<li><a
href="https://github.com/pygments/pygments/commit/1d4538ae8621d766ecc91ff59caf76ab75983abc"><code>1d4538a</code></a>
Prepare 2.20 release.</li>
<li><a
href="https://github.com/pygments/pygments/commit/2ceaee4e634eebae2d10a47fd05406871f6bac8f"><code>2ceaee4</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/e3a3c54b58c7f80bc4db887e471d4f91c77844ed"><code>e3a3c54</code></a>
Fix Haskell lexer: handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>)</li>
<li><a
href="https://github.com/pygments/pygments/commit/d7c3453e342dac319f58e4091f4ef183cc49d802"><code>d7c3453</code></a>
Merge pull request <a
href="https://redirect.github.com/pygments/pygments/issues/3071">#3071</a>
from pygments/harden-html-formatter</li>
<li><a
href="https://github.com/pygments/pygments/commit/0f97e7c37d44abfa4ddfddf44a3290fdad586034"><code>0f97e7c</code></a>
Harden the HTML formatter against CSS.</li>
<li><a
href="https://github.com/pygments/pygments/commit/9f981b2ba42b88ca5bdcebf12cd01efd7cd80aec"><code>9f981b2</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/1d889151024e9a53f3702a60558b29b070306e9e"><code>1d88915</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/c3d93adb9827fc054c3c12b47bde31c781a36a93"><code>c3d93ad</code></a>
Fix ASN.1 lexer: recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li><a
href="https://github.com/pygments/pygments/commit/4f06bcf8a5ba3f2b5bda24a26ccf041a1a65d91e"><code>4f06bcf</code></a>
fix bad behaving backtracking regex in CommonLispLexer</li>
<li>Additional commits viewable in <a
href="https://github.com/pygments/pygments/compare/2.19.2...2.20.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pygments&package-manager=uv&previous-version=2.19.2&new-version=2.20.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-30 16:52:47 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
b38226f4db chore(deps): bump pygments from 2.19.2 to 2.20.0 in /libs/langgraph (#7353)
Bumps [pygments](https://github.com/pygments/pygments) from 2.19.2 to
2.20.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pygments/pygments/releases">pygments's
releases</a>.</em></p>
<blockquote>
<h2>2.20.0</h2>
<ul>
<li>
<p>New lexers:</p>
<ul>
<li>Rell (<a
href="https://redirect.github.com/pygments/pygments/issues/2914">#2914</a>)</li>
</ul>
</li>
<li>
<p>Updated lexers:</p>
<ul>
<li>archetype: Fix catastrophic backtracking in GUID and ID patterns (<a
href="https://redirect.github.com/pygments/pygments/issues/3064">#3064</a>)</li>
<li>ASN.1: Recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3014">#3014</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li>C++: Add C++26 keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>),
add integer literal suffixes (<a
href="https://redirect.github.com/pygments/pygments/issues/2966">#2966</a>)</li>
<li>ComponentPascal: Fix <code>analyse_text</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/3028">#3028</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3032">#3032</a>)</li>
<li>Coq renamed to Rocq (<a
href="https://redirect.github.com/pygments/pygments/issues/2883">#2883</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2908">#2908</a>)</li>
<li>Cython: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2932">#2932</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2933">#2933</a>)</li>
<li>Debian control: Improve architecture parsing (<a
href="https://redirect.github.com/pygments/pygments/issues/3052">#3052</a>)</li>
<li>Devicetree: Add support for overlay/fragments (<a
href="https://redirect.github.com/pygments/pygments/issues/3021">#3021</a>),
add bytestring support (<a
href="https://redirect.github.com/pygments/pygments/issues/3022">#3022</a>),
fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3057">#3057</a>)</li>
<li>Fennel: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2911">#2911</a>)</li>
<li>Haskell: Handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/1795">#1795</a>)</li>
<li>Java: Add module keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>)</li>
<li>Lean4: Add operators <code>]'</code>, <code>]?</code>,
<code>]!</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2946">#2946</a>)</li>
<li>LESS: Support single-line comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3005">#3005</a>)</li>
<li>LilyPond: Update to 2.25.29 (<a
href="https://redirect.github.com/pygments/pygments/issues/2974">#2974</a>)</li>
<li>LLVM: Support C-style comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3023">#3023</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2978">#2978</a>)</li>
<li>Lua(u): Fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3047">#3047</a>)</li>
<li>Macaulay2: Update to 1.25.05 (<a
href="https://redirect.github.com/pygments/pygments/issues/2893">#2893</a>),
1.25.11 (<a
href="https://redirect.github.com/pygments/pygments/issues/2988">#2988</a>)</li>
<li>Mathematica: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2957">#2957</a>)</li>
<li>meson: Add additional operators (<a
href="https://redirect.github.com/pygments/pygments/issues/2919">#2919</a>)</li>
<li>MySQL: Update keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2970">#2970</a>)</li>
<li>org-Mode: Support both schedule and deadline (<a
href="https://redirect.github.com/pygments/pygments/issues/2899">#2899</a>)</li>
<li>PHP: Add <code>__PROPERTY__</code> magic constant (<a
href="https://redirect.github.com/pygments/pygments/issues/2924">#2924</a>),
add reserved keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/3002">#3002</a>)</li>
<li>PostgreSQL: Add more keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2985">#2985</a>)</li>
<li>protobuf: Fix namespace tokenization (<a
href="https://redirect.github.com/pygments/pygments/issues/2929">#2929</a>)</li>
<li>Python: Add <code>t</code>-string support (<a
href="https://redirect.github.com/pygments/pygments/issues/2973">#2973</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3009">#3009</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3010">#3010</a>)</li>
<li>Tablegen: Fix infinite loop (<a
href="https://redirect.github.com/pygments/pygments/issues/2972">#2972</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2940">#2940</a>)</li>
<li>Tera Term macro: Add commands introduced in v5.3 through v5.6 (<a
href="https://redirect.github.com/pygments/pygments/issues/2951">#2951</a>)</li>
<li>TOML: Support TOML 1.1.0 (<a
href="https://redirect.github.com/pygments/pygments/issues/3026">#3026</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3027">#3027</a>)</li>
<li>Turtle: Allow empty comment lines (<a
href="https://redirect.github.com/pygments/pygments/issues/2980">#2980</a>)</li>
<li>XML: Added <code>.xbrl</code> as file ending (<a
href="https://redirect.github.com/pygments/pygments/issues/2890">#2890</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2891">#2891</a>)</li>
</ul>
</li>
<li>
<p>Drop Python 3.8, and add Python 3.14 as a supported version (<a
href="https://redirect.github.com/pygments/pygments/issues/2987">#2987</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3012">#3012</a>)</p>
</li>
<li>
<p>Various improvements to <code>autopygmentize</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2894">#2894</a>)</p>
</li>
<li>
<p>Update <code>onedark</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2977">#2977</a>)</p>
</li>
<li>
<p>Update <code>rtt</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2895">#2895</a>)</p>
</li>
<li>
<p>Cache entry points to improve performance (<a
href="https://redirect.github.com/pygments/pygments/issues/2979">#2979</a>)</p>
</li>
<li>
<p>Fix <code>xterm-256</code> color table (<a
href="https://redirect.github.com/pygments/pygments/issues/3043">#3043</a>)</p>
</li>
<li>
<p>Fix <code>kwargs</code> dictionary getting mutated on each call (<a
href="https://redirect.github.com/pygments/pygments/issues/3044">#3044</a>)</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pygments/pygments/blob/master/CHANGES">pygments's
changelog</a>.</em></p>
<blockquote>
<h2>Version 2.20.0</h2>
<p>(released March 29th, 2026)</p>
<ul>
<li>
<p>New lexers:</p>
<ul>
<li>Rell (<a
href="https://redirect.github.com/pygments/pygments/issues/2914">#2914</a>)</li>
</ul>
</li>
<li>
<p>Updated lexers:</p>
<ul>
<li>archetype: Fix catastrophic backtracking in GUID and ID patterns (<a
href="https://redirect.github.com/pygments/pygments/issues/3064">#3064</a>)</li>
<li>ASN.1: Recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3014">#3014</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li>C++: Add C++26 keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>),
add integer literal suffixes (<a
href="https://redirect.github.com/pygments/pygments/issues/2966">#2966</a>)</li>
<li>ComponentPascal: Fix <code>analyse_text</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/3028">#3028</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3032">#3032</a>)</li>
<li>Coq renamed to Rocq (<a
href="https://redirect.github.com/pygments/pygments/issues/2883">#2883</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2908">#2908</a>)</li>
<li>Cython: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2932">#2932</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2933">#2933</a>)</li>
<li>Debian control: Improve architecture parsing (<a
href="https://redirect.github.com/pygments/pygments/issues/3052">#3052</a>)</li>
<li>Devicetree: Add support for overlay/fragments (<a
href="https://redirect.github.com/pygments/pygments/issues/3021">#3021</a>),
add bytestring support (<a
href="https://redirect.github.com/pygments/pygments/issues/3022">#3022</a>),
fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3057">#3057</a>)</li>
<li>Fennel: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2911">#2911</a>)</li>
<li>Haskell: Handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/1795">#1795</a>)</li>
<li>Java: Add module keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>)</li>
<li>Lean4: Add operators <code>]'</code>, <code>]?</code>,
<code>]!</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2946">#2946</a>)</li>
<li>LESS: Support single-line comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3005">#3005</a>)</li>
<li>LilyPond: Update to 2.25.29 (<a
href="https://redirect.github.com/pygments/pygments/issues/2974">#2974</a>)</li>
<li>LLVM: Support C-style comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3023">#3023</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2978">#2978</a>)</li>
<li>Lua(u): Fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3047">#3047</a>)</li>
<li>Macaulay2: Update to 1.25.05 (<a
href="https://redirect.github.com/pygments/pygments/issues/2893">#2893</a>),
1.25.11 (<a
href="https://redirect.github.com/pygments/pygments/issues/2988">#2988</a>)</li>
<li>Mathematica: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2957">#2957</a>)</li>
<li>meson: Add additional operators (<a
href="https://redirect.github.com/pygments/pygments/issues/2919">#2919</a>)</li>
<li>MySQL: Update keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2970">#2970</a>)</li>
<li>org-Mode: Support both schedule and deadline (<a
href="https://redirect.github.com/pygments/pygments/issues/2899">#2899</a>)</li>
<li>PHP: Add <code>__PROPERTY__</code> magic constant (<a
href="https://redirect.github.com/pygments/pygments/issues/2924">#2924</a>),
add reserved keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/3002">#3002</a>)</li>
<li>PostgreSQL: Add more keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2985">#2985</a>)</li>
<li>protobuf: Fix namespace tokenization (<a
href="https://redirect.github.com/pygments/pygments/issues/2929">#2929</a>)</li>
<li>Python: Add <code>t</code>-string support (<a
href="https://redirect.github.com/pygments/pygments/issues/2973">#2973</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3009">#3009</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3010">#3010</a>)</li>
<li>Tablegen: Fix infinite loop (<a
href="https://redirect.github.com/pygments/pygments/issues/2972">#2972</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2940">#2940</a>)</li>
<li>Tera Term macro: Add commands introduced in v5.3 through v5.6 (<a
href="https://redirect.github.com/pygments/pygments/issues/2951">#2951</a>)</li>
<li>TOML: Support TOML 1.1.0 (<a
href="https://redirect.github.com/pygments/pygments/issues/3026">#3026</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3027">#3027</a>)</li>
<li>Turtle: Allow empty comment lines (<a
href="https://redirect.github.com/pygments/pygments/issues/2980">#2980</a>)</li>
<li>XML: Added <code>.xbrl</code> as file ending (<a
href="https://redirect.github.com/pygments/pygments/issues/2890">#2890</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2891">#2891</a>)</li>
</ul>
</li>
<li>
<p>Drop Python 3.8, and add Python 3.14 as a supported version (<a
href="https://redirect.github.com/pygments/pygments/issues/2987">#2987</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3012">#3012</a>)</p>
</li>
<li>
<p>Various improvements to <code>autopygmentize</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2894">#2894</a>)</p>
</li>
<li>
<p>Update <code>onedark</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2977">#2977</a>)</p>
</li>
<li>
<p>Update <code>rtt</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2895">#2895</a>)</p>
</li>
<li>
<p>Cache entry points to improve performance (<a
href="https://redirect.github.com/pygments/pygments/issues/2979">#2979</a>)</p>
</li>
<li>
<p>Fix <code>xterm-256</code> color table (<a
href="https://redirect.github.com/pygments/pygments/issues/3043">#3043</a>)</p>
</li>
<li>
<p>Fix <code>kwargs</code> dictionary getting mutated on each call (<a
href="https://redirect.github.com/pygments/pygments/issues/3044">#3044</a>)</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/pygments/pygments/commit/708197d82827ba2d5ca78bcbb653c7102ce86dcd"><code>708197d</code></a>
Fix underline length.</li>
<li><a
href="https://github.com/pygments/pygments/commit/1d4538ae8621d766ecc91ff59caf76ab75983abc"><code>1d4538a</code></a>
Prepare 2.20 release.</li>
<li><a
href="https://github.com/pygments/pygments/commit/2ceaee4e634eebae2d10a47fd05406871f6bac8f"><code>2ceaee4</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/e3a3c54b58c7f80bc4db887e471d4f91c77844ed"><code>e3a3c54</code></a>
Fix Haskell lexer: handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>)</li>
<li><a
href="https://github.com/pygments/pygments/commit/d7c3453e342dac319f58e4091f4ef183cc49d802"><code>d7c3453</code></a>
Merge pull request <a
href="https://redirect.github.com/pygments/pygments/issues/3071">#3071</a>
from pygments/harden-html-formatter</li>
<li><a
href="https://github.com/pygments/pygments/commit/0f97e7c37d44abfa4ddfddf44a3290fdad586034"><code>0f97e7c</code></a>
Harden the HTML formatter against CSS.</li>
<li><a
href="https://github.com/pygments/pygments/commit/9f981b2ba42b88ca5bdcebf12cd01efd7cd80aec"><code>9f981b2</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/1d889151024e9a53f3702a60558b29b070306e9e"><code>1d88915</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/c3d93adb9827fc054c3c12b47bde31c781a36a93"><code>c3d93ad</code></a>
Fix ASN.1 lexer: recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li><a
href="https://github.com/pygments/pygments/commit/4f06bcf8a5ba3f2b5bda24a26ccf041a1a65d91e"><code>4f06bcf</code></a>
fix bad behaving backtracking regex in CommonLispLexer</li>
<li>Additional commits viewable in <a
href="https://github.com/pygments/pygments/compare/2.19.2...2.20.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pygments&package-manager=uv&previous-version=2.19.2&new-version=2.20.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-30 16:52:29 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
cf95f29318 chore(deps): bump pygments from 2.19.2 to 2.20.0 in /libs/prebuilt (#7354)
Bumps [pygments](https://github.com/pygments/pygments) from 2.19.2 to
2.20.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pygments/pygments/releases">pygments's
releases</a>.</em></p>
<blockquote>
<h2>2.20.0</h2>
<ul>
<li>
<p>New lexers:</p>
<ul>
<li>Rell (<a
href="https://redirect.github.com/pygments/pygments/issues/2914">#2914</a>)</li>
</ul>
</li>
<li>
<p>Updated lexers:</p>
<ul>
<li>archetype: Fix catastrophic backtracking in GUID and ID patterns (<a
href="https://redirect.github.com/pygments/pygments/issues/3064">#3064</a>)</li>
<li>ASN.1: Recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3014">#3014</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li>C++: Add C++26 keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>),
add integer literal suffixes (<a
href="https://redirect.github.com/pygments/pygments/issues/2966">#2966</a>)</li>
<li>ComponentPascal: Fix <code>analyse_text</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/3028">#3028</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3032">#3032</a>)</li>
<li>Coq renamed to Rocq (<a
href="https://redirect.github.com/pygments/pygments/issues/2883">#2883</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2908">#2908</a>)</li>
<li>Cython: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2932">#2932</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2933">#2933</a>)</li>
<li>Debian control: Improve architecture parsing (<a
href="https://redirect.github.com/pygments/pygments/issues/3052">#3052</a>)</li>
<li>Devicetree: Add support for overlay/fragments (<a
href="https://redirect.github.com/pygments/pygments/issues/3021">#3021</a>),
add bytestring support (<a
href="https://redirect.github.com/pygments/pygments/issues/3022">#3022</a>),
fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3057">#3057</a>)</li>
<li>Fennel: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2911">#2911</a>)</li>
<li>Haskell: Handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/1795">#1795</a>)</li>
<li>Java: Add module keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>)</li>
<li>Lean4: Add operators <code>]'</code>, <code>]?</code>,
<code>]!</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2946">#2946</a>)</li>
<li>LESS: Support single-line comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3005">#3005</a>)</li>
<li>LilyPond: Update to 2.25.29 (<a
href="https://redirect.github.com/pygments/pygments/issues/2974">#2974</a>)</li>
<li>LLVM: Support C-style comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3023">#3023</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2978">#2978</a>)</li>
<li>Lua(u): Fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3047">#3047</a>)</li>
<li>Macaulay2: Update to 1.25.05 (<a
href="https://redirect.github.com/pygments/pygments/issues/2893">#2893</a>),
1.25.11 (<a
href="https://redirect.github.com/pygments/pygments/issues/2988">#2988</a>)</li>
<li>Mathematica: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2957">#2957</a>)</li>
<li>meson: Add additional operators (<a
href="https://redirect.github.com/pygments/pygments/issues/2919">#2919</a>)</li>
<li>MySQL: Update keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2970">#2970</a>)</li>
<li>org-Mode: Support both schedule and deadline (<a
href="https://redirect.github.com/pygments/pygments/issues/2899">#2899</a>)</li>
<li>PHP: Add <code>__PROPERTY__</code> magic constant (<a
href="https://redirect.github.com/pygments/pygments/issues/2924">#2924</a>),
add reserved keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/3002">#3002</a>)</li>
<li>PostgreSQL: Add more keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2985">#2985</a>)</li>
<li>protobuf: Fix namespace tokenization (<a
href="https://redirect.github.com/pygments/pygments/issues/2929">#2929</a>)</li>
<li>Python: Add <code>t</code>-string support (<a
href="https://redirect.github.com/pygments/pygments/issues/2973">#2973</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3009">#3009</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3010">#3010</a>)</li>
<li>Tablegen: Fix infinite loop (<a
href="https://redirect.github.com/pygments/pygments/issues/2972">#2972</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2940">#2940</a>)</li>
<li>Tera Term macro: Add commands introduced in v5.3 through v5.6 (<a
href="https://redirect.github.com/pygments/pygments/issues/2951">#2951</a>)</li>
<li>TOML: Support TOML 1.1.0 (<a
href="https://redirect.github.com/pygments/pygments/issues/3026">#3026</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3027">#3027</a>)</li>
<li>Turtle: Allow empty comment lines (<a
href="https://redirect.github.com/pygments/pygments/issues/2980">#2980</a>)</li>
<li>XML: Added <code>.xbrl</code> as file ending (<a
href="https://redirect.github.com/pygments/pygments/issues/2890">#2890</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2891">#2891</a>)</li>
</ul>
</li>
<li>
<p>Drop Python 3.8, and add Python 3.14 as a supported version (<a
href="https://redirect.github.com/pygments/pygments/issues/2987">#2987</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3012">#3012</a>)</p>
</li>
<li>
<p>Various improvements to <code>autopygmentize</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2894">#2894</a>)</p>
</li>
<li>
<p>Update <code>onedark</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2977">#2977</a>)</p>
</li>
<li>
<p>Update <code>rtt</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2895">#2895</a>)</p>
</li>
<li>
<p>Cache entry points to improve performance (<a
href="https://redirect.github.com/pygments/pygments/issues/2979">#2979</a>)</p>
</li>
<li>
<p>Fix <code>xterm-256</code> color table (<a
href="https://redirect.github.com/pygments/pygments/issues/3043">#3043</a>)</p>
</li>
<li>
<p>Fix <code>kwargs</code> dictionary getting mutated on each call (<a
href="https://redirect.github.com/pygments/pygments/issues/3044">#3044</a>)</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pygments/pygments/blob/master/CHANGES">pygments's
changelog</a>.</em></p>
<blockquote>
<h2>Version 2.20.0</h2>
<p>(released March 29th, 2026)</p>
<ul>
<li>
<p>New lexers:</p>
<ul>
<li>Rell (<a
href="https://redirect.github.com/pygments/pygments/issues/2914">#2914</a>)</li>
</ul>
</li>
<li>
<p>Updated lexers:</p>
<ul>
<li>archetype: Fix catastrophic backtracking in GUID and ID patterns (<a
href="https://redirect.github.com/pygments/pygments/issues/3064">#3064</a>)</li>
<li>ASN.1: Recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3014">#3014</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li>C++: Add C++26 keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>),
add integer literal suffixes (<a
href="https://redirect.github.com/pygments/pygments/issues/2966">#2966</a>)</li>
<li>ComponentPascal: Fix <code>analyse_text</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/3028">#3028</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3032">#3032</a>)</li>
<li>Coq renamed to Rocq (<a
href="https://redirect.github.com/pygments/pygments/issues/2883">#2883</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2908">#2908</a>)</li>
<li>Cython: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2932">#2932</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2933">#2933</a>)</li>
<li>Debian control: Improve architecture parsing (<a
href="https://redirect.github.com/pygments/pygments/issues/3052">#3052</a>)</li>
<li>Devicetree: Add support for overlay/fragments (<a
href="https://redirect.github.com/pygments/pygments/issues/3021">#3021</a>),
add bytestring support (<a
href="https://redirect.github.com/pygments/pygments/issues/3022">#3022</a>),
fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3057">#3057</a>)</li>
<li>Fennel: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2911">#2911</a>)</li>
<li>Haskell: Handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/1795">#1795</a>)</li>
<li>Java: Add module keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2955">#2955</a>)</li>
<li>Lean4: Add operators <code>]'</code>, <code>]?</code>,
<code>]!</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2946">#2946</a>)</li>
<li>LESS: Support single-line comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3005">#3005</a>)</li>
<li>LilyPond: Update to 2.25.29 (<a
href="https://redirect.github.com/pygments/pygments/issues/2974">#2974</a>)</li>
<li>LLVM: Support C-style comments (<a
href="https://redirect.github.com/pygments/pygments/issues/3023">#3023</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2978">#2978</a>)</li>
<li>Lua(u): Fix catastrophic backtracking (<a
href="https://redirect.github.com/pygments/pygments/issues/3047">#3047</a>)</li>
<li>Macaulay2: Update to 1.25.05 (<a
href="https://redirect.github.com/pygments/pygments/issues/2893">#2893</a>),
1.25.11 (<a
href="https://redirect.github.com/pygments/pygments/issues/2988">#2988</a>)</li>
<li>Mathematica: Various improvements (<a
href="https://redirect.github.com/pygments/pygments/issues/2957">#2957</a>)</li>
<li>meson: Add additional operators (<a
href="https://redirect.github.com/pygments/pygments/issues/2919">#2919</a>)</li>
<li>MySQL: Update keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2970">#2970</a>)</li>
<li>org-Mode: Support both schedule and deadline (<a
href="https://redirect.github.com/pygments/pygments/issues/2899">#2899</a>)</li>
<li>PHP: Add <code>__PROPERTY__</code> magic constant (<a
href="https://redirect.github.com/pygments/pygments/issues/2924">#2924</a>),
add reserved keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/3002">#3002</a>)</li>
<li>PostgreSQL: Add more keywords (<a
href="https://redirect.github.com/pygments/pygments/issues/2985">#2985</a>)</li>
<li>protobuf: Fix namespace tokenization (<a
href="https://redirect.github.com/pygments/pygments/issues/2929">#2929</a>)</li>
<li>Python: Add <code>t</code>-string support (<a
href="https://redirect.github.com/pygments/pygments/issues/2973">#2973</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3009">#3009</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3010">#3010</a>)</li>
<li>Tablegen: Fix infinite loop (<a
href="https://redirect.github.com/pygments/pygments/issues/2972">#2972</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2940">#2940</a>)</li>
<li>Tera Term macro: Add commands introduced in v5.3 through v5.6 (<a
href="https://redirect.github.com/pygments/pygments/issues/2951">#2951</a>)</li>
<li>TOML: Support TOML 1.1.0 (<a
href="https://redirect.github.com/pygments/pygments/issues/3026">#3026</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3027">#3027</a>)</li>
<li>Turtle: Allow empty comment lines (<a
href="https://redirect.github.com/pygments/pygments/issues/2980">#2980</a>)</li>
<li>XML: Added <code>.xbrl</code> as file ending (<a
href="https://redirect.github.com/pygments/pygments/issues/2890">#2890</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/2891">#2891</a>)</li>
</ul>
</li>
<li>
<p>Drop Python 3.8, and add Python 3.14 as a supported version (<a
href="https://redirect.github.com/pygments/pygments/issues/2987">#2987</a>,
<a
href="https://redirect.github.com/pygments/pygments/issues/3012">#3012</a>)</p>
</li>
<li>
<p>Various improvements to <code>autopygmentize</code> (<a
href="https://redirect.github.com/pygments/pygments/issues/2894">#2894</a>)</p>
</li>
<li>
<p>Update <code>onedark</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2977">#2977</a>)</p>
</li>
<li>
<p>Update <code>rtt</code> style to support more token types (<a
href="https://redirect.github.com/pygments/pygments/issues/2895">#2895</a>)</p>
</li>
<li>
<p>Cache entry points to improve performance (<a
href="https://redirect.github.com/pygments/pygments/issues/2979">#2979</a>)</p>
</li>
<li>
<p>Fix <code>xterm-256</code> color table (<a
href="https://redirect.github.com/pygments/pygments/issues/3043">#3043</a>)</p>
</li>
<li>
<p>Fix <code>kwargs</code> dictionary getting mutated on each call (<a
href="https://redirect.github.com/pygments/pygments/issues/3044">#3044</a>)</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/pygments/pygments/commit/708197d82827ba2d5ca78bcbb653c7102ce86dcd"><code>708197d</code></a>
Fix underline length.</li>
<li><a
href="https://github.com/pygments/pygments/commit/1d4538ae8621d766ecc91ff59caf76ab75983abc"><code>1d4538a</code></a>
Prepare 2.20 release.</li>
<li><a
href="https://github.com/pygments/pygments/commit/2ceaee4e634eebae2d10a47fd05406871f6bac8f"><code>2ceaee4</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/e3a3c54b58c7f80bc4db887e471d4f91c77844ed"><code>e3a3c54</code></a>
Fix Haskell lexer: handle escape sequences in character literals (<a
href="https://redirect.github.com/pygments/pygments/issues/3069">#3069</a>)</li>
<li><a
href="https://github.com/pygments/pygments/commit/d7c3453e342dac319f58e4091f4ef183cc49d802"><code>d7c3453</code></a>
Merge pull request <a
href="https://redirect.github.com/pygments/pygments/issues/3071">#3071</a>
from pygments/harden-html-formatter</li>
<li><a
href="https://github.com/pygments/pygments/commit/0f97e7c37d44abfa4ddfddf44a3290fdad586034"><code>0f97e7c</code></a>
Harden the HTML formatter against CSS.</li>
<li><a
href="https://github.com/pygments/pygments/commit/9f981b2ba42b88ca5bdcebf12cd01efd7cd80aec"><code>9f981b2</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/1d889151024e9a53f3702a60558b29b070306e9e"><code>1d88915</code></a>
Update CHANGES.</li>
<li><a
href="https://github.com/pygments/pygments/commit/c3d93adb9827fc054c3c12b47bde31c781a36a93"><code>c3d93ad</code></a>
Fix ASN.1 lexer: recognize minus sign and fix range operator (<a
href="https://redirect.github.com/pygments/pygments/issues/3060">#3060</a>)</li>
<li><a
href="https://github.com/pygments/pygments/commit/4f06bcf8a5ba3f2b5bda24a26ccf041a1a65d91e"><code>4f06bcf</code></a>
fix bad behaving backtracking regex in CommonLispLexer</li>
<li>Additional commits viewable in <a
href="https://github.com/pygments/pygments/compare/2.19.2...2.20.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pygments&package-manager=uv&previous-version=2.19.2&new-version=2.20.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-30 16:52:28 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
6e81c6c12c chore(deps): bump cryptography from 46.0.5 to 46.0.6 in /libs/cli (#7325)
Bumps [cryptography](https://github.com/pyca/cryptography) from 46.0.5
to 46.0.6.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst">cryptography's
changelog</a>.</em></p>
<blockquote>
<p>46.0.6 - 2026-03-25</p>
<pre><code>
* **SECURITY ISSUE**: Fixed a bug where name constraints were not
applied
  to peer names during verification when the leaf certificate contains a
wildcard DNS SAN. Ordinary X.509 topologies are not affected by this
bug,
including those used by the Web PKI. Credit to **Oleh Konko (1seal)**
for
  reporting the issue. **CVE-2026-34073**
<p>.. _v46-0-5:<br />
</code></pre></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/pyca/cryptography/commit/91d728897bdad30cd5c79a2b23e207f1f050d587"><code>91d7288</code></a>
Cherry-pick <a
href="https://redirect.github.com/pyca/cryptography/issues/14542">#14542</a>
(<a
href="https://redirect.github.com/pyca/cryptography/issues/14543">#14543</a>)</li>
<li>See full diff in <a
href="https://github.com/pyca/cryptography/compare/46.0.5...46.0.6">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=cryptography&package-manager=uv&previous-version=46.0.5&new-version=46.0.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-30 16:52:04 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>John Kennedy
d2f8610b1f chore(deps): bump requests from 2.32.5 to 2.33.0 in /libs/cli (#7286)
Bumps [requests](https://github.com/psf/requests) from 2.32.5 to 2.33.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/psf/requests/releases">requests's
releases</a>.</em></p>
<blockquote>
<h2>v2.33.0</h2>
<h2>2.33.0 (2026-03-25)</h2>
<p><strong>Announcements</strong></p>
<ul>
<li>📣 Requests is adding inline types. If you have a typed code base
that uses Requests, please take a look at <a
href="https://redirect.github.com/psf/requests/issues/7271">#7271</a>.
Give it a try, and report any gaps or feedback you may have in the
issue. 📣</li>
</ul>
<p><strong>Security</strong></p>
<ul>
<li>CVE-2026-25645 <code>requests.utils.extract_zipped_paths</code> now
extracts contents to a non-deterministic location to prevent malicious
file replacement. This does not affect default usage of Requests, only
applications calling the utility function directly.</li>
</ul>
<p><strong>Improvements</strong></p>
<ul>
<li>Migrated to a PEP 517 build system using setuptools. (<a
href="https://redirect.github.com/psf/requests/issues/7012">#7012</a>)</li>
</ul>
<p><strong>Bugfixes</strong></p>
<ul>
<li>Fixed an issue where an empty netrc entry could cause malformed
authentication to be applied to Requests on Python 3.11+. (<a
href="https://redirect.github.com/psf/requests/issues/7205">#7205</a>)</li>
</ul>
<p><strong>Deprecations</strong></p>
<ul>
<li>Dropped support for Python 3.9 following its end of support. (<a
href="https://redirect.github.com/psf/requests/issues/7196">#7196</a>)</li>
</ul>
<p><strong>Documentation</strong></p>
<ul>
<li>Various typo fixes and doc improvements.</li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/M0d3v1"><code>@​M0d3v1</code></a> made
their first contribution in <a
href="https://redirect.github.com/psf/requests/pull/6865">psf/requests#6865</a></li>
<li><a href="https://github.com/aminvakil"><code>@​aminvakil</code></a>
made their first contribution in <a
href="https://redirect.github.com/psf/requests/pull/7220">psf/requests#7220</a></li>
<li><a href="https://github.com/E8Price"><code>@​E8Price</code></a> made
their first contribution in <a
href="https://redirect.github.com/psf/requests/pull/6960">psf/requests#6960</a></li>
<li><a href="https://github.com/mitre88"><code>@​mitre88</code></a> made
their first contribution in <a
href="https://redirect.github.com/psf/requests/pull/7244">psf/requests#7244</a></li>
<li><a href="https://github.com/magsen"><code>@​magsen</code></a> made
their first contribution in <a
href="https://redirect.github.com/psf/requests/pull/6553">psf/requests#6553</a></li>
<li><a
href="https://github.com/Rohan5commit"><code>@​Rohan5commit</code></a>
made their first contribution in <a
href="https://redirect.github.com/psf/requests/pull/7227">psf/requests#7227</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/psf/requests/blob/main/HISTORY.md#2330-2026-03-25">https://github.com/psf/requests/blob/main/HISTORY.md#2330-2026-03-25</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/psf/requests/blob/main/HISTORY.md">requests's
changelog</a>.</em></p>
<blockquote>
<h2>2.33.0 (2026-03-25)</h2>
<p><strong>Announcements</strong></p>
<ul>
<li>📣 Requests is adding inline types. If you have a typed code base
that
uses Requests, please take a look at <a
href="https://redirect.github.com/psf/requests/issues/7271">#7271</a>.
Give it a try, and report
any gaps or feedback you may have in the issue. 📣</li>
</ul>
<p><strong>Security</strong></p>
<ul>
<li>CVE-2026-25645 <code>requests.utils.extract_zipped_paths</code> now
extracts
contents to a non-deterministic location to prevent malicious file
replacement. This does not affect default usage of Requests, only
applications calling the utility function directly.</li>
</ul>
<p><strong>Improvements</strong></p>
<ul>
<li>Migrated to a PEP 517 build system using setuptools. (<a
href="https://redirect.github.com/psf/requests/issues/7012">#7012</a>)</li>
</ul>
<p><strong>Bugfixes</strong></p>
<ul>
<li>Fixed an issue where an empty netrc entry could cause
malformed authentication to be applied to Requests on
Python 3.11+. (<a
href="https://redirect.github.com/psf/requests/issues/7205">#7205</a>)</li>
</ul>
<p><strong>Deprecations</strong></p>
<ul>
<li>Dropped support for Python 3.9 following its end of support. (<a
href="https://redirect.github.com/psf/requests/issues/7196">#7196</a>)</li>
</ul>
<p><strong>Documentation</strong></p>
<ul>
<li>Various typo fixes and doc improvements.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/psf/requests/commit/bc04dfd6dad4cb02cd92f5daa81eb562d280a761"><code>bc04dfd</code></a>
v2.33.0</li>
<li><a
href="https://github.com/psf/requests/commit/66d21cb07bd6255b1280291c4fafb71803cdb3b7"><code>66d21cb</code></a>
Merge commit from fork</li>
<li><a
href="https://github.com/psf/requests/commit/8b9bc8fc0f63be84602387913c4b689f19efd028"><code>8b9bc8f</code></a>
Move badges to top of README (<a
href="https://redirect.github.com/psf/requests/issues/7293">#7293</a>)</li>
<li><a
href="https://github.com/psf/requests/commit/e331a288f369973f5de0ec8901c94cae4fa87286"><code>e331a28</code></a>
Remove unused extraction call (<a
href="https://redirect.github.com/psf/requests/issues/7292">#7292</a>)</li>
<li><a
href="https://github.com/psf/requests/commit/753fd08c5eacce0aa0df73fe47e49525c67e0a29"><code>753fd08</code></a>
docs: fix FAQ grammar in httplib2 example</li>
<li><a
href="https://github.com/psf/requests/commit/774a0b837a194ee885d4fdd9ca947900cc3daf71"><code>774a0b8</code></a>
docs(socks): same block as other sections</li>
<li><a
href="https://github.com/psf/requests/commit/9c72a41bec8597f948c9d8caa5dc3f12273b3303"><code>9c72a41</code></a>
Bump github/codeql-action from 4.33.0 to 4.34.1</li>
<li><a
href="https://github.com/psf/requests/commit/ebf71906798ec82f34e07d3168f8b8aecaf8a3be"><code>ebf7190</code></a>
Bump github/codeql-action from 4.32.0 to 4.33.0</li>
<li><a
href="https://github.com/psf/requests/commit/0e4ae38f0c93d4f92a96c774bd52c069d12a4798"><code>0e4ae38</code></a>
docs: exclude Response.is_permanent_redirect from API docs (<a
href="https://redirect.github.com/psf/requests/issues/7244">#7244</a>)</li>
<li><a
href="https://github.com/psf/requests/commit/d568f47278492e630cc990a259047c67991d007a"><code>d568f47</code></a>
docs: clarify Quickstart POST example (<a
href="https://redirect.github.com/psf/requests/issues/6960">#6960</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/psf/requests/compare/v2.32.5...v2.33.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=requests&package-manager=uv&previous-version=2.32.5&new-version=2.33.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

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>
2026-03-30 09:45:07 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>John Kennedy
d8b742a4b3 chore(deps): bump the minor-and-patch group in /libs/cli/js-examples with 3 updates (#7295)
Bumps the minor-and-patch group in /libs/cli/js-examples with 3 updates:
[@langchain/core](https://github.com/langchain-ai/langchainjs),
[@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin)
and
[@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser).

Updates `@langchain/core` from 1.1.35 to 1.1.36
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/langchain-ai/langchainjs/releases"><code>@​langchain/core</code>'s
releases</a>.</em></p>
<blockquote>
<h2><code>@​langchain/core</code><a
href="https://github.com/1"><code>@​1</code></a>.1.36</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/langchain-ai/langchainjs/pull/10512">#10512</a>
<a
href="https://github.com/langchain-ai/langchainjs/commit/bbbfea185c0777ae06df2b24a1a84f941d499c2a"><code>bbbfea1</code></a>
Thanks <a href="https://github.com/hntrl"><code>@​hntrl</code></a>! -
fix(core): fix streaming chunk merge for providers without
<code>index</code> on tool call deltas</p>
<p><code>_mergeLists</code> now falls back to <code>id</code>-based
matching when items don't have an <code>index</code> field. Previously,
providers routing through the OpenAI-compatible API without
<code>index</code> on streaming tool call deltas (e.g. Anthropic models
via <code>ChatOpenAI</code>) would accumulate hundreds of individual raw
deltas in <code>tool_call_chunks</code> and
<code>additional_kwargs.tool_calls</code> instead of merging them into a
single entry per tool call. In a real trace with 3 concurrent subagents,
this caused a single AI message to balloon from ~4KB to 146KB -- with
826 uncollapsed streaming fragments carrying a few bytes each.</p>
<p>Also fixes <code>SystemMessage.concat()</code> which used
<code>...this</code> to spread all instance properties (including
<code>lc_kwargs</code>) into the new constructor, causing each chained
<code>concat()</code> call to nest one level deeper. After 7 middleware
<code>concat()</code> calls (typical in deepagents), a 7KB system prompt
would serialize to 81KB due to content being duplicated at every nesting
level.</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/langchain-ai/langchainjs/commit/d2a0c2d5b5a23a60791d01c98874c53f555ed5d8"><code>d2a0c2d</code></a>
chore: version packages (<a
href="https://redirect.github.com/langchain-ai/langchainjs/issues/10508">#10508</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchainjs/commit/bbbfea185c0777ae06df2b24a1a84f941d499c2a"><code>bbbfea1</code></a>
fix(core): fix _mergeLists id-only fallback and SystemMessage.concat
lc_kwarg...</li>
<li><a
href="https://github.com/langchain-ai/langchainjs/commit/478652c01cdae0703415febd250b6c2656b36410"><code>478652c</code></a>
fix(openai): detect DeepSeek context overflow errors as ContextOverfl…
(<a
href="https://redirect.github.com/langchain-ai/langchainjs/issues/10481">#10481</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchainjs/commit/3d35eb112b46b36aea80cebe0147e315d03a1d8e"><code>3d35eb1</code></a>
fix(langchain): add &quot;aws&quot; alias to MODEL_PROVIDER_CONFIG for
Bedrock hub prom...</li>
<li><a
href="https://github.com/langchain-ai/langchainjs/commit/52e501b44ee54ace1889ec9149a3617c4409db51"><code>52e501b</code></a>
fix(openai): guard JSON.parse in streaming json_schema when text is
empty (<a
href="https://redirect.github.com/langchain-ai/langchainjs/issues/1">#1</a>...</li>
<li><a
href="https://github.com/langchain-ai/langchainjs/commit/ae4122f9523904423504e5a92c134c625977261d"><code>ae4122f</code></a>
Align Zod Importation For 'libs/langchain/src/agents/nodes/utils.ts' (<a
href="https://redirect.github.com/langchain-ai/langchainjs/issues/10258">#10258</a>)</li>
<li>See full diff in <a
href="https://github.com/langchain-ai/langchainjs/compare/@langchain/core@1.1.35...@langchain/core@1.1.36">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/eslint-plugin` from 8.57.1 to 8.57.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases"><code>@​typescript-eslint/eslint-plugin</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v8.57.2</h2>
<h2>8.57.2 (2026-03-23)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [prefer-optional-chain] remove
dangling closing parenthesis (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11865">#11865</a>)</li>
<li><strong>eslint-plugin:</strong> [array-type] ignore Array and
ReadonlyArray without type arguments (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11971">#11971</a>)</li>
<li><strong>eslint-plugin:</strong> [no-restricted-types] flag banned
generics in extends or implements (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12120">#12120</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unsafe-return] false positive on
unwrapping generic (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12125">#12125</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unsafe-return] false positive on
unwrapping generic (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12125">#12125</a>)</li>
<li><strong>eslint-plugin:</strong> [no-useless-default-assignment] skip
reporting false positives for unresolved type parameters (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12127">#12127</a>)</li>
<li><strong>eslint-plugin:</strong> [prefer-readonly-parameter-types]
preserve type alias infomation (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11954">#11954</a>)</li>
<li><strong>typescript-estree:</strong> skip createIsolatedProgram
fallback for projectService (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12066">#12066</a>,
<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/issues/12065">#12065</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
<li>Konv Suu</li>
<li>mdm317</li>
<li>Newton Yuan <a
href="https://github.com/NewtonYuan"><code>@​NewtonYuan</code></a></li>
<li>RyoheiYamamoto</li>
<li>SungHyun627 <a
href="https://github.com/SungHyun627"><code>@​SungHyun627</code></a></li>
<li>Tamashoo <a
href="https://github.com/Tamashoo"><code>@​Tamashoo</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.57.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md"><code>@​typescript-eslint/eslint-plugin</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>8.57.2 (2026-03-23)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [prefer-readonly-parameter-types]
preserve type alias infomation (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11954">#11954</a>)</li>
<li><strong>eslint-plugin:</strong> [no-useless-default-assignment] skip
reporting false positives for unresolved type parameters (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12127">#12127</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unsafe-return] false positive on
unwrapping generic (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12125">#12125</a>)</li>
<li><strong>eslint-plugin:</strong> [no-restricted-types] flag banned
generics in extends or implements (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12120">#12120</a>)</li>
<li><strong>eslint-plugin:</strong> [array-type] ignore Array and
ReadonlyArray without type arguments (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11971">#11971</a>)</li>
<li><strong>eslint-plugin:</strong> [prefer-optional-chain] remove
dangling closing parenthesis (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11865">#11865</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
<li>Konv Suu</li>
<li>mdm317</li>
<li>Newton Yuan <a
href="https://github.com/NewtonYuan"><code>@​NewtonYuan</code></a></li>
<li>SungHyun627 <a
href="https://github.com/SungHyun627"><code>@​SungHyun627</code></a></li>
<li>Tamashoo <a
href="https://github.com/Tamashoo"><code>@​Tamashoo</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.57.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/typescript-eslint/typescript-eslint/commit/be4d54d26e695cc93605ffcca67dd75848e95c6f"><code>be4d54d</code></a>
chore(release): publish 8.57.2</li>
<li><a
href="https://github.com/typescript-eslint/typescript-eslint/commit/f68c8e4baca096281b458ccb6ff16ca6c5a1d199"><code>f68c8e4</code></a>
fix(eslint-plugin): [prefer-readonly-parameter-types] preserve type
alias inf...</li>
<li><a
href="https://github.com/typescript-eslint/typescript-eslint/commit/73acd2e6833c4757d2743a8dbb979154d31a1e98"><code>73acd2e</code></a>
fix(eslint-plugin): [no-useless-default-assignment] skip reporting false
posi...</li>
<li><a
href="https://github.com/typescript-eslint/typescript-eslint/commit/3d21482030e4fd220f466cea7036e07695277364"><code>3d21482</code></a>
fix(eslint-plugin): [no-unsafe-return] false positive on unwrapping
generic (...</li>
<li><a
href="https://github.com/typescript-eslint/typescript-eslint/commit/e128548b50573ebe3904662222e05be63970fc32"><code>e128548</code></a>
fix(eslint-plugin): [no-restricted-types] flag banned generics in
extends or ...</li>
<li><a
href="https://github.com/typescript-eslint/typescript-eslint/commit/2b7f63f9cdf91dc216678f9a0d1ffe1aaf2ff0af"><code>2b7f63f</code></a>
chore(eslint-plugin): correct tsutils.isTypeFlag usage post-merge</li>
<li><a
href="https://github.com/typescript-eslint/typescript-eslint/commit/65175cdfb564218a785e0b63056eee3b113d287f"><code>65175cd</code></a>
fix(eslint-plugin): [array-type] ignore Array and ReadonlyArray without
type ...</li>
<li><a
href="https://github.com/typescript-eslint/typescript-eslint/commit/9c9ab5e8a37a2db49bde7255337f64d1140ee640"><code>9c9ab5e</code></a>
feat(eslint-plugin): [no-unnecessary-type-arguments] report inferred
required...</li>
<li><a
href="https://github.com/typescript-eslint/typescript-eslint/commit/42a1c89c89e7fe1c13962b2e41cb78611ad16d41"><code>42a1c89</code></a>
fix(eslint-plugin): [prefer-optional-chain] remove dangling closing
parenthes...</li>
<li><a
href="https://github.com/typescript-eslint/typescript-eslint/commit/71855ff116a074e1ee5e2d804cf5cf493ee49e98"><code>71855ff</code></a>
docs(eslint-plugin): [no-unnecessary-condition] add link to TS handbook
(<a
href="https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin/issues/12131">#12131</a>)</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.57.2/packages/eslint-plugin">compare
view</a></li>
</ul>
</details>
<br />

Updates `@typescript-eslint/parser` from 8.57.1 to 8.57.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases"><code>@​typescript-eslint/parser</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v8.57.2</h2>
<h2>8.57.2 (2026-03-23)</h2>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [prefer-optional-chain] remove
dangling closing parenthesis (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11865">#11865</a>)</li>
<li><strong>eslint-plugin:</strong> [array-type] ignore Array and
ReadonlyArray without type arguments (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11971">#11971</a>)</li>
<li><strong>eslint-plugin:</strong> [no-restricted-types] flag banned
generics in extends or implements (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12120">#12120</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unsafe-return] false positive on
unwrapping generic (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12125">#12125</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unsafe-return] false positive on
unwrapping generic (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12125">#12125</a>)</li>
<li><strong>eslint-plugin:</strong> [no-useless-default-assignment] skip
reporting false positives for unresolved type parameters (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12127">#12127</a>)</li>
<li><strong>eslint-plugin:</strong> [prefer-readonly-parameter-types]
preserve type alias infomation (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/11954">#11954</a>)</li>
<li><strong>typescript-estree:</strong> skip createIsolatedProgram
fallback for projectService (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12066">#12066</a>,
<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/issues/12065">#12065</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Kirk Waiblinger <a
href="https://github.com/kirkwaiblinger"><code>@​kirkwaiblinger</code></a></li>
<li>Konv Suu</li>
<li>mdm317</li>
<li>Newton Yuan <a
href="https://github.com/NewtonYuan"><code>@​NewtonYuan</code></a></li>
<li>RyoheiYamamoto</li>
<li>SungHyun627 <a
href="https://github.com/SungHyun627"><code>@​SungHyun627</code></a></li>
<li>Tamashoo <a
href="https://github.com/Tamashoo"><code>@​Tamashoo</code></a></li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.57.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md"><code>@​typescript-eslint/parser</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>8.57.2 (2026-03-23)</h2>
<p>This was a version bump only for parser to align it with other
projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.57.2">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/typescript-eslint/typescript-eslint/commit/be4d54d26e695cc93605ffcca67dd75848e95c6f"><code>be4d54d</code></a>
chore(release): publish 8.57.2</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.57.2/packages/parser">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

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>
2026-03-29 23:30:30 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2510e450f9 chore(deps): bump handlebars from 4.7.8 to 4.7.9 in /libs/cli/js-examples (#7309)
Bumps [handlebars](https://github.com/handlebars-lang/handlebars.js)
from 4.7.8 to 4.7.9.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/handlebars-lang/handlebars.js/releases">handlebars's
releases</a>.</em></p>
<blockquote>
<h2>v4.7.9</h2>
<ul>
<li>fix: enable shell mode for spawn to resolve Windows EINVAL issue -
e0137c2</li>
<li>fix type &quot;RuntimeOptions&quot; also accepting string partials -
eab1d14</li>
<li>feat(types): set <code>hash</code> to be a <code>Record&lt;string,
any&gt;</code> - de4414d</li>
<li>fix non-contiguous program indices - 4512766</li>
<li>refactor: rename i to startPartIndex - e497a35</li>
<li>security: fix security issues - 68d8df5
<ul>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-2w6w-674q-4c4q">https://github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-2w6w-674q-4c4q</a></li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-3mfm-83xf-c92r">https://github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-3mfm-83xf-c92r</a></li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-xhpv-hc6g-r9c6">https://github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-xhpv-hc6g-r9c6</a></li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-xjpj-3mr7-gcpf">https://github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-xjpj-3mr7-gcpf</a></li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-9cx6-37pm-9jff">https://github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-9cx6-37pm-9jff</a></li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-2qvq-rjwj-gvw9">https://github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-2qvq-rjwj-gvw9</a></li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-7rx3-28cr-v5wh">https://github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-7rx3-28cr-v5wh</a></li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-442j-39wm-28r2">https://github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-442j-39wm-28r2</a></li>
</ul>
</li>
</ul>
<p><a
href="https://github.com/handlebars-lang/handlebars.js/compare/v4.7.8...v4.7.9">Commits</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/handlebars-lang/handlebars.js/blob/v4.7.9/release-notes.md">handlebars's
changelog</a>.</em></p>
<blockquote>
<h2>v4.7.9 - March 26th, 2026</h2>
<ul>
<li>fix: enable shell mode for spawn to resolve Windows EINVAL issue -
e0137c2</li>
<li>fix type &quot;RuntimeOptions&quot; also accepting string partials -
eab1d14</li>
<li>feat(types): set <code>hash</code> to be a <code>Record&lt;string,
any&gt;</code> - de4414d</li>
<li>fix non-contiguous program indices - 4512766</li>
<li>refactor: rename i to startPartIndex - e497a35</li>
<li>security: fix security issues - 68d8df5</li>
</ul>
<p><a
href="https://github.com/handlebars-lang/handlebars.js/compare/v4.7.8...v4.7.9">Commits</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/dce542c9a660048d31f0981ac8a45c08b919bddb"><code>dce542c</code></a>
v4.7.9</li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/8a41389ba5b2624b6f43a5463d8e2533b843a562"><code>8a41389</code></a>
Update release notes</li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/68d8df5a88e0a26fe9e6084c5c6aaebe67b07da2"><code>68d8df5</code></a>
Fix security issues</li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/b2a083136b11e1da9f0f47a11f749a9830a49328"><code>b2a0831</code></a>
Fix browser tests</li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/9f98c1629834abf8de5a127caff8a2eab03d2c12"><code>9f98c16</code></a>
Fix release script</li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/45443b4290475dfb7cec32a85d344f12ab345eb9"><code>45443b4</code></a>
Revert &quot;Improve partial indenting performance&quot;</li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/8841a5f6d35096aee95d68e1e49636a4cb5c661e"><code>8841a5f</code></a>
Fix CI errors with linting</li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/e0137c26f2202593bca7cc25184e733e87d54709"><code>e0137c2</code></a>
fix: enable shell mode for spawn to resolve Windows EINVAL issue</li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/e914d6037ffb0dd371f7e4823cdb019732ae66d7"><code>e914d60</code></a>
Improve rendering performance</li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/7de4b41c344a5d702edca93d1841b59642fa32bd"><code>7de4b41</code></a>
Upgrade GitHub Actions checkout and setup-node on 4.x branch</li>
<li>Additional commits viewable in <a
href="https://github.com/handlebars-lang/handlebars.js/compare/v4.7.8...v4.7.9">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=handlebars&package-manager=npm_and_yarn&previous-version=4.7.8&new-version=4.7.9)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-29 23:30:08 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
280ccbec04 chore(deps): bump langchain-core from 1.2.16 to 1.2.22 in /libs/cli (#7320)
Bumps [langchain-core](https://github.com/langchain-ai/langchain) from
1.2.16 to 1.2.22.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/langchain-ai/langchain/releases">langchain-core's
releases</a>.</em></p>
<blockquote>
<h2>langchain-core==1.2.22</h2>
<p>Changes since langchain-core==1.2.21</p>
<p>release(core): 1.2.22 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36201">#36201</a>)
fix(core): validate paths in <code>prompt.save</code> and
<code>load_prompt</code>, deprecate methods (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36200">#36200</a>)</p>
<h2>langchain-core==1.2.21</h2>
<p>Changes since langchain-core==1.2.20</p>
<p>release(core): 1.2.21 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36179">#36179</a>)
fix(core,model-profiles): add missing <code>ModelProfile</code> fields,
warn on schema drift (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36129">#36129</a>)
chore(core): remove stale blockbuster allowlist for deleted context
module (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36168">#36168</a>)
ci: suppress pytest streaming output in CI (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36092">#36092</a>)</p>
<h2>langchain-core==1.2.20</h2>
<p>Changes since langchain-core==1.2.19</p>
<p>release(core): 1.2.20 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36085">#36085</a>)
fix(core): trace invocation params in metadata (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36080">#36080</a>)
feat: Add LangSmith integration metadata to create_agent and
init_chat_model (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35810">#35810</a>)
feat(core): harden anti-ssrf (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35960">#35960</a>)
ci: avoid unnecessary dep installs in lint targets (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36046">#36046</a>)
docs(core): document <code>base_url</code> in mermaid api (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35961">#35961</a>)
chore: bump orjson from 3.11.5 to 3.11.6 in /libs/core (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35805">#35805</a>)
chore: housekeeping (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35850">#35850</a>)</p>
<h2>langchain-core==1.2.19</h2>
<p>Changes since langchain-core==1.2.18</p>
<p>release(core): 1.2.19 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35832">#35832</a>)
chore(core): move BaseCrossEncoder to langchain-core (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35809">#35809</a>)
chore: bump tornado from 6.5.2 to 6.5.5 in /libs/core (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35775">#35775</a>)</p>
<h2>langchain-core==1.2.18</h2>
<p>Changes since langchain-core==1.2.17</p>
<p>release(core): 1.2.18 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35704">#35704</a>)
fix(core): fix double backticks in deprecation docstring for
alternative_import (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35658">#35658</a>)
fix(core): preserve default_factory when generating tool call schema (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35550">#35550</a>)
feat(openai): support tool search (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35582">#35582</a>)
chore: bump the minor-and-patch group across 3 directories with 7
updates (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35605">#35605</a>)</p>
<h2>langchain-core==1.2.17</h2>
<p>Changes since langchain-core==1.2.16</p>
<p>release(core): 1.2.17 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35527">#35527</a>)
fix(core): extract usage metadata from serialized tracer message outputs
(<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35526">#35526</a>)
chore: bump the langchain-deps group across 3 directories with 7 updates
(<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35513">#35513</a>)
chore: bump the langchain-deps group across 3 directories with 14
updates (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35441">#35441</a>)</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/langchain-ai/langchain/commit/d22df94537e4267f72dc1bbfc8e3849baf20d9f7"><code>d22df94</code></a>
release(core): 1.2.22 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36201">#36201</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/27add913474e01e33bededf4096151130ba0d47c"><code>27add91</code></a>
fix(core): validate paths in <code>prompt.save</code> and
<code>load_prompt</code>, deprecate metho...</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/7563fceb40ce31165524f3f57ec65e487c02b1a7"><code>7563fce</code></a>
chore(model-profiles): refresh model profile data (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36195">#36195</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/3e64c255b84b283b3a65216b19b9838734258c96"><code>3e64c25</code></a>
chore: use repo permissions instead of org membership for maintainer
override...</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/1778b082ecd64a9dedd48674d874ca1bfcbe4c7d"><code>1778b08</code></a>
chore(partners): bump <code>langchain-core</code> min to
<code>1.2.21</code> (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36183">#36183</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/ad574fce0d52740c249b0db7bde871d779ffb93d"><code>ad574fc</code></a>
fix(openai): bump min core version (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36180">#36180</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/19f81cf6f1d73f7adf156491ba0617497a526b8c"><code>19f81cf</code></a>
release(core): 1.2.21 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36179">#36179</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/6d07ef28a7023dc7b832fe52862f7a6fc0a187f3"><code>6d07ef2</code></a>
release(openai): 1.1.12 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36178">#36178</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/2f64d80cc65091985873c339ca76a59af7baf739"><code>2f64d80</code></a>
fix(core,model-profiles): add missing <code>ModelProfile</code> fields,
warn on schema d...</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/5ffece5c033365baf4a3df52ffed5c6bfbed27ee"><code>5ffece5</code></a>
chore(core): remove stale blockbuster allowlist for deleted context
module (#...</li>
<li>Additional commits viewable in <a
href="https://github.com/langchain-ai/langchain/compare/langchain-core==1.2.16...langchain-core==1.2.22">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=langchain-core&package-manager=uv&previous-version=1.2.16&new-version=1.2.22)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-29 23:29:53 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>John Kennedy
dffb0adb7d chore(deps): bump picomatch from 4.0.3 to 4.0.4 in /libs/cli/js-monorepo-example (#7305)
Bumps [picomatch](https://github.com/micromatch/picomatch) from 4.0.3 to
4.0.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/micromatch/picomatch/releases">picomatch's
releases</a>.</em></p>
<blockquote>
<h2>4.0.4</h2>
<p>This is a security release fixing several security relevant
issues.</p>
<h2>What's Changed</h2>
<ul>
<li>Fix for <a
href="https://github.com/micromatch/picomatch/security/advisories/GHSA-c2c7-rcm5-vvqj">CVE-2026-33671</a></li>
<li>Fix for <a
href="https://github.com/micromatch/picomatch/security/advisories/GHSA-3v7f-55p6-f55p">CVE-2026-33672</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/micromatch/picomatch/compare/4.0.3...4.0.4">https://github.com/micromatch/picomatch/compare/4.0.3...4.0.4</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/micromatch/picomatch/commit/e5474fc1a4d7991870058170407dda8a42be5334"><code>e5474fc</code></a>
Publish 4.0.4</li>
<li><a
href="https://github.com/micromatch/picomatch/commit/4516eb521f13a46b2fe1a1d2c9ef6b20ddc0e903"><code>4516eb5</code></a>
Merge commit from fork</li>
<li><a
href="https://github.com/micromatch/picomatch/commit/5eceecd27543b8e056b9307d69e105ea03618a7d"><code>5eceecd</code></a>
Merge commit from fork</li>
<li><a
href="https://github.com/micromatch/picomatch/commit/0db7dd70651ca7c8265601c0442a996ed32e3238"><code>0db7dd7</code></a>
Run benchmark again against latest minimatch version (<a
href="https://redirect.github.com/micromatch/picomatch/issues/161">#161</a>)</li>
<li><a
href="https://github.com/micromatch/picomatch/commit/95003777eb1c60dec09495a8231fa2ba4054d76a"><code>9500377</code></a>
docs: clarify what brace expansion syntax is and isn't supported (<a
href="https://redirect.github.com/micromatch/picomatch/issues/134">#134</a>)</li>
<li><a
href="https://github.com/micromatch/picomatch/commit/2661f23eca86c8b4a2b14815b9b2b3b74bd5a171"><code>2661f23</code></a>
fix typo in globstars.js test name (<a
href="https://redirect.github.com/micromatch/picomatch/issues/138">#138</a>)</li>
<li><a
href="https://github.com/micromatch/picomatch/commit/1798b07e9df59500b9cf567294d44d559032f4c7"><code>1798b07</code></a>
docs: fix <code>makeRe</code> example (<a
href="https://redirect.github.com/micromatch/picomatch/issues/143">#143</a>)</li>
<li><a
href="https://github.com/micromatch/picomatch/commit/9d76bc57a03b7f57cc4ca516c8071daf632bafd8"><code>9d76bc5</code></a>
chore: undocument removed options (<a
href="https://redirect.github.com/micromatch/picomatch/issues/146">#146</a>)</li>
<li><a
href="https://github.com/micromatch/picomatch/commit/e4d718bbfb47e4f030ab2612b5b04a9297fe272d"><code>e4d718b</code></a>
Remove unused time-require (<a
href="https://redirect.github.com/micromatch/picomatch/issues/160">#160</a>)</li>
<li><a
href="https://github.com/micromatch/picomatch/commit/38dffeb16221cc8eb8981524fb6895dd2aaaba76"><code>38dffeb</code></a>
chore(deps): pin dependencies (<a
href="https://redirect.github.com/micromatch/picomatch/issues/158">#158</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/micromatch/picomatch/compare/4.0.3...4.0.4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=picomatch&package-manager=npm_and_yarn&previous-version=4.0.3&new-version=4.0.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

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>
2026-03-29 23:29:19 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
3a1a70da1a chore(deps): bump cryptography from 46.0.5 to 46.0.6 in /libs/langgraph (#7324)
Bumps [cryptography](https://github.com/pyca/cryptography) from 46.0.5
to 46.0.6.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst">cryptography's
changelog</a>.</em></p>
<blockquote>
<p>46.0.6 - 2026-03-25</p>
<pre><code>
* **SECURITY ISSUE**: Fixed a bug where name constraints were not
applied
  to peer names during verification when the leaf certificate contains a
wildcard DNS SAN. Ordinary X.509 topologies are not affected by this
bug,
including those used by the Web PKI. Credit to **Oleh Konko (1seal)**
for
  reporting the issue. **CVE-2026-34073**
<p>.. _v46-0-5:<br />
</code></pre></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/pyca/cryptography/commit/91d728897bdad30cd5c79a2b23e207f1f050d587"><code>91d7288</code></a>
Cherry-pick <a
href="https://redirect.github.com/pyca/cryptography/issues/14542">#14542</a>
(<a
href="https://redirect.github.com/pyca/cryptography/issues/14543">#14543</a>)</li>
<li>See full diff in <a
href="https://github.com/pyca/cryptography/compare/46.0.5...46.0.6">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=cryptography&package-manager=uv&previous-version=46.0.5&new-version=46.0.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-29 16:22:56 -07:00
William FHandGitHub 0f20c3fe04 fix(cli): persist deployment name to .env after prompt (#7323)
## Summary
- When `langgraph deploy` prompts for the deployment name interactively,
persist it as `LANGSMITH_DEPLOYMENT_NAME` in the `.env` file so
subsequent deploys pick it up automatically
- Extracted `_resolve_env_path()` helper from `_parse_env_from_config()`
to share env file path resolution logic
- Skips writing when env vars are configured as an inline dict in
`langgraph.json` (no file to write to)
- **CI fix**: CLI integration tests were using `pip install` but
`setup-uv` with caching enabled, so the post-step cache save failed on a
non-existent directory — switched to `uv pip install`

## Test plan
- [x] All 207 existing unit tests pass
- [ ] Manual: run `langgraph deploy` without `--name`, enter a name at
prompt, verify `.env` now contains `LANGSMITH_DEPLOYMENT_NAME=<name>`
- [ ] Manual: run `langgraph deploy` again, verify the name is picked up
from `.env` without re-prompting
- [x] CI integration test cache fix (broken on main since Feb 2026)
2026-03-29 07:50:57 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
ad17e8b002 chore(deps): bump langchain-core from 1.2.20 to 1.2.22 in /libs/sdk-py (#7321)
Bumps [langchain-core](https://github.com/langchain-ai/langchain) from
1.2.20 to 1.2.22.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/langchain-ai/langchain/releases">langchain-core's
releases</a>.</em></p>
<blockquote>
<h2>langchain-core==1.2.22</h2>
<p>Changes since langchain-core==1.2.21</p>
<p>release(core): 1.2.22 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36201">#36201</a>)
fix(core): validate paths in <code>prompt.save</code> and
<code>load_prompt</code>, deprecate methods (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36200">#36200</a>)</p>
<h2>langchain-core==1.2.21</h2>
<p>Changes since langchain-core==1.2.20</p>
<p>release(core): 1.2.21 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36179">#36179</a>)
fix(core,model-profiles): add missing <code>ModelProfile</code> fields,
warn on schema drift (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36129">#36129</a>)
chore(core): remove stale blockbuster allowlist for deleted context
module (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36168">#36168</a>)
ci: suppress pytest streaming output in CI (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36092">#36092</a>)</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/langchain-ai/langchain/commit/d22df94537e4267f72dc1bbfc8e3849baf20d9f7"><code>d22df94</code></a>
release(core): 1.2.22 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36201">#36201</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/27add913474e01e33bededf4096151130ba0d47c"><code>27add91</code></a>
fix(core): validate paths in <code>prompt.save</code> and
<code>load_prompt</code>, deprecate metho...</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/7563fceb40ce31165524f3f57ec65e487c02b1a7"><code>7563fce</code></a>
chore(model-profiles): refresh model profile data (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36195">#36195</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/3e64c255b84b283b3a65216b19b9838734258c96"><code>3e64c25</code></a>
chore: use repo permissions instead of org membership for maintainer
override...</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/1778b082ecd64a9dedd48674d874ca1bfcbe4c7d"><code>1778b08</code></a>
chore(partners): bump <code>langchain-core</code> min to
<code>1.2.21</code> (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36183">#36183</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/ad574fce0d52740c249b0db7bde871d779ffb93d"><code>ad574fc</code></a>
fix(openai): bump min core version (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36180">#36180</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/19f81cf6f1d73f7adf156491ba0617497a526b8c"><code>19f81cf</code></a>
release(core): 1.2.21 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36179">#36179</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/6d07ef28a7023dc7b832fe52862f7a6fc0a187f3"><code>6d07ef2</code></a>
release(openai): 1.1.12 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36178">#36178</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/2f64d80cc65091985873c339ca76a59af7baf739"><code>2f64d80</code></a>
fix(core,model-profiles): add missing <code>ModelProfile</code> fields,
warn on schema d...</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/5ffece5c033365baf4a3df52ffed5c6bfbed27ee"><code>5ffece5</code></a>
chore(core): remove stale blockbuster allowlist for deleted context
module (#...</li>
<li>Additional commits viewable in <a
href="https://github.com/langchain-ai/langchain/compare/langchain-core==1.2.20...langchain-core==1.2.22">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=langchain-core&package-manager=uv&previous-version=1.2.20&new-version=1.2.22)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-27 21:28:25 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
aa950ea8c5 chore(deps): bump langchain-core from 1.2.13 to 1.2.22 in /libs/checkpoint-conformance (#7319)
Bumps [langchain-core](https://github.com/langchain-ai/langchain) from
1.2.13 to 1.2.22.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/langchain-ai/langchain/releases">langchain-core's
releases</a>.</em></p>
<blockquote>
<h2>langchain-core==1.2.22</h2>
<p>Changes since langchain-core==1.2.21</p>
<p>release(core): 1.2.22 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36201">#36201</a>)
fix(core): validate paths in <code>prompt.save</code> and
<code>load_prompt</code>, deprecate methods (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36200">#36200</a>)</p>
<h2>langchain-core==1.2.21</h2>
<p>Changes since langchain-core==1.2.20</p>
<p>release(core): 1.2.21 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36179">#36179</a>)
fix(core,model-profiles): add missing <code>ModelProfile</code> fields,
warn on schema drift (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36129">#36129</a>)
chore(core): remove stale blockbuster allowlist for deleted context
module (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36168">#36168</a>)
ci: suppress pytest streaming output in CI (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36092">#36092</a>)</p>
<h2>langchain-core==1.2.20</h2>
<p>Changes since langchain-core==1.2.19</p>
<p>release(core): 1.2.20 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36085">#36085</a>)
fix(core): trace invocation params in metadata (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36080">#36080</a>)
feat: Add LangSmith integration metadata to create_agent and
init_chat_model (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35810">#35810</a>)
feat(core): harden anti-ssrf (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35960">#35960</a>)
ci: avoid unnecessary dep installs in lint targets (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36046">#36046</a>)
docs(core): document <code>base_url</code> in mermaid api (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35961">#35961</a>)
chore: bump orjson from 3.11.5 to 3.11.6 in /libs/core (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35805">#35805</a>)
chore: housekeeping (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35850">#35850</a>)</p>
<h2>langchain-core==1.2.19</h2>
<p>Changes since langchain-core==1.2.18</p>
<p>release(core): 1.2.19 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35832">#35832</a>)
chore(core): move BaseCrossEncoder to langchain-core (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35809">#35809</a>)
chore: bump tornado from 6.5.2 to 6.5.5 in /libs/core (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35775">#35775</a>)</p>
<h2>langchain-core==1.2.18</h2>
<p>Changes since langchain-core==1.2.17</p>
<p>release(core): 1.2.18 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35704">#35704</a>)
fix(core): fix double backticks in deprecation docstring for
alternative_import (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35658">#35658</a>)
fix(core): preserve default_factory when generating tool call schema (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35550">#35550</a>)
feat(openai): support tool search (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35582">#35582</a>)
chore: bump the minor-and-patch group across 3 directories with 7
updates (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35605">#35605</a>)</p>
<h2>langchain-core==1.2.17</h2>
<p>Changes since langchain-core==1.2.16</p>
<p>release(core): 1.2.17 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35527">#35527</a>)
fix(core): extract usage metadata from serialized tracer message outputs
(<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35526">#35526</a>)
chore: bump the langchain-deps group across 3 directories with 7 updates
(<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35513">#35513</a>)
chore: bump the langchain-deps group across 3 directories with 14
updates (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35441">#35441</a>)</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/langchain-ai/langchain/commit/d22df94537e4267f72dc1bbfc8e3849baf20d9f7"><code>d22df94</code></a>
release(core): 1.2.22 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36201">#36201</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/27add913474e01e33bededf4096151130ba0d47c"><code>27add91</code></a>
fix(core): validate paths in <code>prompt.save</code> and
<code>load_prompt</code>, deprecate metho...</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/7563fceb40ce31165524f3f57ec65e487c02b1a7"><code>7563fce</code></a>
chore(model-profiles): refresh model profile data (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36195">#36195</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/3e64c255b84b283b3a65216b19b9838734258c96"><code>3e64c25</code></a>
chore: use repo permissions instead of org membership for maintainer
override...</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/1778b082ecd64a9dedd48674d874ca1bfcbe4c7d"><code>1778b08</code></a>
chore(partners): bump <code>langchain-core</code> min to
<code>1.2.21</code> (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36183">#36183</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/ad574fce0d52740c249b0db7bde871d779ffb93d"><code>ad574fc</code></a>
fix(openai): bump min core version (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36180">#36180</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/19f81cf6f1d73f7adf156491ba0617497a526b8c"><code>19f81cf</code></a>
release(core): 1.2.21 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36179">#36179</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/6d07ef28a7023dc7b832fe52862f7a6fc0a187f3"><code>6d07ef2</code></a>
release(openai): 1.1.12 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36178">#36178</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/2f64d80cc65091985873c339ca76a59af7baf739"><code>2f64d80</code></a>
fix(core,model-profiles): add missing <code>ModelProfile</code> fields,
warn on schema d...</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/5ffece5c033365baf4a3df52ffed5c6bfbed27ee"><code>5ffece5</code></a>
chore(core): remove stale blockbuster allowlist for deleted context
module (#...</li>
<li>Additional commits viewable in <a
href="https://github.com/langchain-ai/langchain/compare/langchain-core==1.2.13...langchain-core==1.2.22">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=langchain-core&package-manager=uv&previous-version=1.2.13&new-version=1.2.22)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-27 21:28:14 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
0f2ad78fc1 chore(deps): bump langchain-core from 1.2.11 to 1.2.22 in /libs/checkpoint-sqlite (#7318)
Bumps [langchain-core](https://github.com/langchain-ai/langchain) from
1.2.11 to 1.2.22.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/langchain-ai/langchain/releases">langchain-core's
releases</a>.</em></p>
<blockquote>
<h2>langchain-core==1.2.22</h2>
<p>Changes since langchain-core==1.2.21</p>
<p>release(core): 1.2.22 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36201">#36201</a>)
fix(core): validate paths in <code>prompt.save</code> and
<code>load_prompt</code>, deprecate methods (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36200">#36200</a>)</p>
<h2>langchain-core==1.2.21</h2>
<p>Changes since langchain-core==1.2.20</p>
<p>release(core): 1.2.21 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36179">#36179</a>)
fix(core,model-profiles): add missing <code>ModelProfile</code> fields,
warn on schema drift (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36129">#36129</a>)
chore(core): remove stale blockbuster allowlist for deleted context
module (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36168">#36168</a>)
ci: suppress pytest streaming output in CI (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36092">#36092</a>)</p>
<h2>langchain-core==1.2.20</h2>
<p>Changes since langchain-core==1.2.19</p>
<p>release(core): 1.2.20 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36085">#36085</a>)
fix(core): trace invocation params in metadata (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36080">#36080</a>)
feat: Add LangSmith integration metadata to create_agent and
init_chat_model (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35810">#35810</a>)
feat(core): harden anti-ssrf (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35960">#35960</a>)
ci: avoid unnecessary dep installs in lint targets (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36046">#36046</a>)
docs(core): document <code>base_url</code> in mermaid api (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35961">#35961</a>)
chore: bump orjson from 3.11.5 to 3.11.6 in /libs/core (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35805">#35805</a>)
chore: housekeeping (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35850">#35850</a>)</p>
<h2>langchain-core==1.2.19</h2>
<p>Changes since langchain-core==1.2.18</p>
<p>release(core): 1.2.19 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35832">#35832</a>)
chore(core): move BaseCrossEncoder to langchain-core (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35809">#35809</a>)
chore: bump tornado from 6.5.2 to 6.5.5 in /libs/core (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35775">#35775</a>)</p>
<h2>langchain-core==1.2.18</h2>
<p>Changes since langchain-core==1.2.17</p>
<p>release(core): 1.2.18 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35704">#35704</a>)
fix(core): fix double backticks in deprecation docstring for
alternative_import (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35658">#35658</a>)
fix(core): preserve default_factory when generating tool call schema (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35550">#35550</a>)
feat(openai): support tool search (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35582">#35582</a>)
chore: bump the minor-and-patch group across 3 directories with 7
updates (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35605">#35605</a>)</p>
<h2>langchain-core==1.2.17</h2>
<p>Changes since langchain-core==1.2.16</p>
<p>release(core): 1.2.17 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35527">#35527</a>)
fix(core): extract usage metadata from serialized tracer message outputs
(<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35526">#35526</a>)
chore: bump the langchain-deps group across 3 directories with 7 updates
(<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35513">#35513</a>)
chore: bump the langchain-deps group across 3 directories with 14
updates (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35441">#35441</a>)</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/langchain-ai/langchain/commit/d22df94537e4267f72dc1bbfc8e3849baf20d9f7"><code>d22df94</code></a>
release(core): 1.2.22 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36201">#36201</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/27add913474e01e33bededf4096151130ba0d47c"><code>27add91</code></a>
fix(core): validate paths in <code>prompt.save</code> and
<code>load_prompt</code>, deprecate metho...</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/7563fceb40ce31165524f3f57ec65e487c02b1a7"><code>7563fce</code></a>
chore(model-profiles): refresh model profile data (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36195">#36195</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/3e64c255b84b283b3a65216b19b9838734258c96"><code>3e64c25</code></a>
chore: use repo permissions instead of org membership for maintainer
override...</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/1778b082ecd64a9dedd48674d874ca1bfcbe4c7d"><code>1778b08</code></a>
chore(partners): bump <code>langchain-core</code> min to
<code>1.2.21</code> (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36183">#36183</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/ad574fce0d52740c249b0db7bde871d779ffb93d"><code>ad574fc</code></a>
fix(openai): bump min core version (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36180">#36180</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/19f81cf6f1d73f7adf156491ba0617497a526b8c"><code>19f81cf</code></a>
release(core): 1.2.21 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36179">#36179</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/6d07ef28a7023dc7b832fe52862f7a6fc0a187f3"><code>6d07ef2</code></a>
release(openai): 1.1.12 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36178">#36178</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/2f64d80cc65091985873c339ca76a59af7baf739"><code>2f64d80</code></a>
fix(core,model-profiles): add missing <code>ModelProfile</code> fields,
warn on schema d...</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/5ffece5c033365baf4a3df52ffed5c6bfbed27ee"><code>5ffece5</code></a>
chore(core): remove stale blockbuster allowlist for deleted context
module (#...</li>
<li>Additional commits viewable in <a
href="https://github.com/langchain-ai/langchain/compare/langchain-core==1.2.11...langchain-core==1.2.22">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=langchain-core&package-manager=uv&previous-version=1.2.11&new-version=1.2.22)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-27 21:28:04 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
436043392d chore(deps): bump langchain-core from 1.2.11 to 1.2.22 in /libs/checkpoint-postgres (#7317)
Bumps [langchain-core](https://github.com/langchain-ai/langchain) from
1.2.11 to 1.2.22.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/langchain-ai/langchain/releases">langchain-core's
releases</a>.</em></p>
<blockquote>
<h2>langchain-core==1.2.22</h2>
<p>Changes since langchain-core==1.2.21</p>
<p>release(core): 1.2.22 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36201">#36201</a>)
fix(core): validate paths in <code>prompt.save</code> and
<code>load_prompt</code>, deprecate methods (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36200">#36200</a>)</p>
<h2>langchain-core==1.2.21</h2>
<p>Changes since langchain-core==1.2.20</p>
<p>release(core): 1.2.21 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36179">#36179</a>)
fix(core,model-profiles): add missing <code>ModelProfile</code> fields,
warn on schema drift (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36129">#36129</a>)
chore(core): remove stale blockbuster allowlist for deleted context
module (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36168">#36168</a>)
ci: suppress pytest streaming output in CI (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36092">#36092</a>)</p>
<h2>langchain-core==1.2.20</h2>
<p>Changes since langchain-core==1.2.19</p>
<p>release(core): 1.2.20 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36085">#36085</a>)
fix(core): trace invocation params in metadata (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36080">#36080</a>)
feat: Add LangSmith integration metadata to create_agent and
init_chat_model (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35810">#35810</a>)
feat(core): harden anti-ssrf (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35960">#35960</a>)
ci: avoid unnecessary dep installs in lint targets (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36046">#36046</a>)
docs(core): document <code>base_url</code> in mermaid api (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35961">#35961</a>)
chore: bump orjson from 3.11.5 to 3.11.6 in /libs/core (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35805">#35805</a>)
chore: housekeeping (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35850">#35850</a>)</p>
<h2>langchain-core==1.2.19</h2>
<p>Changes since langchain-core==1.2.18</p>
<p>release(core): 1.2.19 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35832">#35832</a>)
chore(core): move BaseCrossEncoder to langchain-core (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35809">#35809</a>)
chore: bump tornado from 6.5.2 to 6.5.5 in /libs/core (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35775">#35775</a>)</p>
<h2>langchain-core==1.2.18</h2>
<p>Changes since langchain-core==1.2.17</p>
<p>release(core): 1.2.18 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35704">#35704</a>)
fix(core): fix double backticks in deprecation docstring for
alternative_import (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35658">#35658</a>)
fix(core): preserve default_factory when generating tool call schema (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35550">#35550</a>)
feat(openai): support tool search (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35582">#35582</a>)
chore: bump the minor-and-patch group across 3 directories with 7
updates (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35605">#35605</a>)</p>
<h2>langchain-core==1.2.17</h2>
<p>Changes since langchain-core==1.2.16</p>
<p>release(core): 1.2.17 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35527">#35527</a>)
fix(core): extract usage metadata from serialized tracer message outputs
(<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35526">#35526</a>)
chore: bump the langchain-deps group across 3 directories with 7 updates
(<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35513">#35513</a>)
chore: bump the langchain-deps group across 3 directories with 14
updates (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/35441">#35441</a>)</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/langchain-ai/langchain/commit/d22df94537e4267f72dc1bbfc8e3849baf20d9f7"><code>d22df94</code></a>
release(core): 1.2.22 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36201">#36201</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/27add913474e01e33bededf4096151130ba0d47c"><code>27add91</code></a>
fix(core): validate paths in <code>prompt.save</code> and
<code>load_prompt</code>, deprecate metho...</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/7563fceb40ce31165524f3f57ec65e487c02b1a7"><code>7563fce</code></a>
chore(model-profiles): refresh model profile data (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36195">#36195</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/3e64c255b84b283b3a65216b19b9838734258c96"><code>3e64c25</code></a>
chore: use repo permissions instead of org membership for maintainer
override...</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/1778b082ecd64a9dedd48674d874ca1bfcbe4c7d"><code>1778b08</code></a>
chore(partners): bump <code>langchain-core</code> min to
<code>1.2.21</code> (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36183">#36183</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/ad574fce0d52740c249b0db7bde871d779ffb93d"><code>ad574fc</code></a>
fix(openai): bump min core version (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36180">#36180</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/19f81cf6f1d73f7adf156491ba0617497a526b8c"><code>19f81cf</code></a>
release(core): 1.2.21 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36179">#36179</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/6d07ef28a7023dc7b832fe52862f7a6fc0a187f3"><code>6d07ef2</code></a>
release(openai): 1.1.12 (<a
href="https://redirect.github.com/langchain-ai/langchain/issues/36178">#36178</a>)</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/2f64d80cc65091985873c339ca76a59af7baf739"><code>2f64d80</code></a>
fix(core,model-profiles): add missing <code>ModelProfile</code> fields,
warn on schema d...</li>
<li><a
href="https://github.com/langchain-ai/langchain/commit/5ffece5c033365baf4a3df52ffed5c6bfbed27ee"><code>5ffece5</code></a>
chore(core): remove stale blockbuster allowlist for deleted context
module (#...</li>
<li>Additional commits viewable in <a
href="https://github.com/langchain-ai/langchain/compare/langchain-core==1.2.11...langchain-core==1.2.22">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=langchain-core&package-manager=uv&previous-version=1.2.11&new-version=1.2.22)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-27 21:27:52 -07:00
45 changed files with 4142 additions and 1515 deletions
+479
View File
@@ -0,0 +1,479 @@
# Threat Model: LangGraph
> Generated: 2026-03-28 | Commit: 0ba22143 | Scope: Full monorepo (all libs/)
> **Disclaimer:** This threat model is automatically generated to help developers and security researchers understand where trust is placed in this system and where boundaries exist. It is experimental, subject to change, and not an authoritative security reference — findings should be validated before acting on them. The analysis may be incomplete or contain inaccuracies. We welcome suggestions and corrections to improve this document.
For vulnerability reporting, see the [GitHub Security Advisories](https://github.com/langchain-ai/langgraph/security/advisories) page.
## Scope
### In Scope
- `libs/langgraph` — Core graph execution engine (Pregel, StateGraph, channels, functional API with `@entrypoint`/`@task`)
- `libs/prebuilt` — High-level agent APIs (ToolNode, create_react_agent, ValidationNode, InjectedState/InjectedStore/ToolRuntime injection)
- `libs/checkpoint` — Checkpoint serialization/deserialization (JsonPlusSerializer, EncryptedSerializer, BaseCache, stores, serde event hooks, SAFE_MSGPACK_TYPES allowlist)
- `libs/checkpoint-postgres` — PostgreSQL checkpoint saver, key-value store, and vector search
- `libs/checkpoint-sqlite` — SQLite checkpoint saver, key-value store, and vector search
- `libs/cli` — CLI for Docker-based deployment (`langgraph up/build/dev/new`), WebhookUrlPolicy
- `libs/sdk-py` — Python SDK client for LangGraph Server API (HttpClient, Auth system, Encryption handlers)
### Out of Scope
- `libs/sdk-js` — Moved to external `langchain-ai/langgraphjs` repository; no source in this repo
- `libs/checkpoint-conformance` — Conformance test suite only; not shipped code
- LangGraph Server / `langgraph-api` — Closed-source server runtime; not in this repo
- LangChain Core (`langchain-core`) — Upstream dependency; separate threat model
- User application code — Tools, prompts, model selection, deployment infrastructure
- LLM provider behavior — Model output content and safety
- LangSmith platform — Observability/tracing backend
- Tests, benchmarks, documentation — Not shipped code
### Assumptions
1. The project is used as a library/framework — users control their own application code, model selection, and deployment.
2. Checkpoint storage backends (databases) are deployed with proper access controls by the user.
3. LLM providers return well-formed responses per their documented API contracts.
4. The `langgraph.json` configuration file is developer-controlled and not user-supplied at runtime.
5. The CLI runs in a developer environment with Docker access.
6. The SDK connects to trusted LangGraph Server endpoints chosen by the user.
7. SDK Encryption handlers are developer-authored server-side code with application-level trust.
---
## System Overview
LangGraph is an open-source Python framework for building stateful, multi-actor AI agent applications. It provides a graph-based execution model (Bulk Synchronous Parallel via the Pregel engine) where user-defined nodes process shared state through typed channels. The framework supports two authoring APIs: the declarative StateGraph API and the functional API (`@entrypoint`/`@task` decorators). It includes checkpointing (persistence of graph state to databases), tool execution (dispatching LLM-generated tool calls with runtime injection of state/store/context), remote graph composition (calling LangGraph Server APIs), Docker-based deployment via a CLI, and a beta SDK encryption framework for custom at-rest encryption handlers.
### Architecture Diagram
```
+---------------------------------------------------------------------------+
| User Application |
| |
| +-----------------------------------------------+ |
| | User Application Code | |
| | (graph nodes, tools; StateGraph builder API | |
| | and functional API @entrypoint/@task both | |
| | compile to the same Pregel execution engine) | |
| +------------------------+----------------------+ |
| | |
| +------------v-----------+ |
| | StateGraph / Pregel | |
| | (core execution engine)| |
| +------+----------+------+ |
| | | |
| InjectedState +--v---------+ |
| InjectedStore | ToolNode | |
| ToolRuntime | (opt-in) | |
| +------------+ |
| | |
| - - - - - - - - - - - | - - - - TB1: User/Framework API - - - - - - - - |
| | |
| +-----v------+ +--------------+ |
| | Checkpoint | | RemoteGraph | |
| | Serializer | | (SDK client) | |
| |(jsonplus) | +------+--------+ |
| +-----+------+ | |
| | | |
| - - - - - - - - - - - | - - - - - - - -|- - TB2: Storage/Network - - - - |
| v v |
| +--------------+ +--------------+ |
| | PostgreSQL | | LangGraph | |
| | / SQLite | | Server API | |
| +--------------+ +--------------+ |
| |
| +----------+ +--------------+ |
| | CLI |------------------>| Docker | |
| |(langgraph| TB4: Config | Engine | |
| | up/build)| +--------------+ |
| +----------+ |
| |
| +--------------------+ |
| | SDK Encryption | TB5: Developer-authored handlers |
| | Handlers (beta) | (server-side execution in langgraph-api) |
| +--------------------+ |
+---------------------------------------------------------------------------+
```
---
## Components
| ID | Component | Description | Trust Level | Default? | Entry Points |
|----|-----------|-------------|-------------|----------|--------------|
| C1 | StateGraph / Pregel | Core graph builder and execution engine with v1/v2 output, durability modes (sync/async/exit), interrupt_before/interrupt_after | framework-controlled | Yes | `StateGraph.add_node()`, `StateGraph.compile()`, `Pregel.invoke()`, `Pregel.stream()` |
| C2 | JsonPlusSerializer | Checkpoint serialization/deserialization with msgpack, JSON, and pickle codecs; 47-entry SAFE_MSGPACK_TYPES allowlist | framework-controlled | Yes | `loads_typed()`, `dumps_typed()`, `_create_msgpack_ext_hook()`, `_reviver()` |
| C3 | ToolNode | Dispatches LLM-generated tool calls to registered BaseTool instances; supports InjectedState/InjectedStore/ToolRuntime injection into tools | framework-controlled | No (explicit opt-in required) | `ToolNode._func()`, `_run_one()`, `_execute_tool_sync()`, `_validate_tool_call()`, `_inject_tool_args()` |
| C4 | RemoteGraph | Client for remote LangGraph Server API; implements PregelProtocol | framework-controlled | No (opt-in) | `RemoteGraph.stream()`, `RemoteGraph.invoke()`, `RemoteGraph.get_state()` |
| C5 | PostgresSaver / PostgresStore | PostgreSQL checkpoint saver, key-value store, and vector search | framework-controlled | No (opt-in) | `from_conn_string()`, `put()`, `get_tuple()`, `search()` |
| C6 | SqliteSaver / SqliteStore | SQLite checkpoint saver, key-value store with JSON path filtering | framework-controlled | No (opt-in) | `from_conn_string()`, `put()`, `get_tuple()`, `search()` |
| C7 | EncryptedSerializer | AES-EAX authenticated encryption wrapper for checkpoint data | framework-controlled | No (opt-in) | `from_pycryptodome_aes()`, `loads_typed()`, `dumps_typed()` |
| C8 | CLI (langgraph_cli) | Docker-based build and deployment tooling; config schema includes WebhookUrlPolicy for SSRF protection | framework-controlled | No (separate install) | `langgraph up`, `langgraph build`, `langgraph dev`, `langgraph new` |
| C9 | SDK Client (langgraph_sdk) | HTTP client for LangGraph Server API with SSE streaming and reconnection | framework-controlled | Yes | `get_client()`, `get_sync_client()`, `HttpClient.request_reconnect()`, `HttpClient.stream()` |
| C10 | User-Registered Tools | BaseTool instances provided by users; may use InjectedState/InjectedStore/ToolRuntime annotations | user-controlled | N/A | Tool `invoke()` / `ainvoke()` methods |
| C11 | User-Registered Nodes | Arbitrary callables added via `add_node()` or `@task`/`@entrypoint` | user-controlled | N/A | Node function signatures |
| C12 | Checkpoint Storage | PostgreSQL or SQLite databases storing serialized graph state | external | N/A | Database connection interface |
| C13 | Functional API | `@entrypoint`/`@task` decorators for function-based workflow authoring with retry/cache policies | framework-controlled | Yes | `entrypoint.__call__()`, `task()`, `_TaskFunction.__call__()` (`libs/langgraph/langgraph/func/__init__.py`) |
| C14 | BaseCache | Cache layer for task results with JsonPlusSerializer (pickle_fallback=False) | framework-controlled | No (opt-in, requires checkpointer) | `get()`, `set()`, `clear()` (`libs/checkpoint/langgraph/cache/base/__init__.py`) |
| C15 | Serde Event Hooks | Monitoring system for serialization/deserialization events (msgpack_blocked, msgpack_unregistered_allowed, msgpack_method_blocked) | framework-controlled | Yes | `register_serde_event_listener()`, `emit_serde_event()` (`libs/checkpoint/langgraph/checkpoint/serde/event_hooks.py`) |
| C16 | Auth System (SDK) | Custom authentication/authorization handler framework | framework-controlled | No (opt-in) | `Auth.authenticate()`, `Auth.on()` handler registration (`libs/sdk-py/langgraph_sdk/auth/__init__.py`) |
| C17 | SDK Encryption Handlers (beta) | Custom at-rest encryption/decryption framework; supports blob and JSON handlers with per-model/field context; server-side execution | framework-controlled | No (opt-in, beta) | `Encryption.encrypt.blob()`, `Encryption.encrypt.json()`, `Encryption.decrypt.blob()`, `Encryption.decrypt.json()`, `Encryption.context()` (`libs/sdk-py/langgraph_sdk/encryption/__init__.py`) |
---
## Data Classification
| ID | PII Category | Specific Fields | Sensitivity | Storage Location(s) | Encrypted at Rest | Retention | Regulatory |
|----|-------------|----------------|-------------|---------------------|-------------------|-----------|------------|
| DC1 | API credentials | `x-api-key` header, `LANGGRAPH_API_KEY`, `LANGSMITH_API_KEY`, `LANGCHAIN_API_KEY` env vars | Critical | Environment variables, HTTP headers in transit | N/A (in-memory) | Session lifetime | All — breach trigger |
| DC2 | Encryption keys | `LANGGRAPH_AES_KEY` env var, `key` parameter to `from_pycryptodome_aes()` | Critical | Environment variable, in-memory | N/A | Application lifetime | All — breach trigger |
| DC3 | Serialized graph state | Checkpoint data in `checkpoints` and `writes` tables (msgpack/JSON/pickle bytes) | High | PostgreSQL (BYTEA), SQLite (BLOB) | Optional via EncryptedSerializer or SDK Encryption Handlers | Unbounded (no default TTL) | GDPR if state contains PII |
| DC4 | Store key-value data | User-stored items in `store` tables via BaseStore | High | PostgreSQL, SQLite | No (plaintext JSON); optional via SDK Encryption Handlers | Configurable TTL, default unbounded | GDPR if contains PII |
| DC5 | Checkpoint metadata | `thread_id`, `checkpoint_ns`, `run_id`, `step`, `source` | Medium | PostgreSQL, SQLite (metadata JSONB/JSON column) | No | Same as DC3 | Minimal |
| DC6 | Agent conversation history | LangChain messages (HumanMessage, AIMessage, ToolMessage) serialized in checkpoint state | High | PostgreSQL, SQLite (within DC3 checkpoint bytes) | Only if DC3 encrypted | Unbounded | GDPR, CCPA if contains user PII |
| DC7 | Connection strings | PostgreSQL URIs, SQLite file paths passed to `from_conn_string()` | Critical | Application code, environment variables | N/A (in-memory) | Application lifetime | All — may contain credentials |
| DC8 | Vector embeddings | Document embeddings in `store_vectors` table | Low | PostgreSQL (pgvector), SQLite (vec extension) | No | Same as DC4 | Minimal |
| DC9 | SDK Encryption context metadata | `EncryptionContext.metadata` dict passed to encryption handlers | Medium | In-memory per request; persisted with encrypted data | N/A (context, not payload) | Request lifetime + persistence alongside encrypted data | Depends on content |
### Data Classification Details
#### DC1: API Credentials
- **Fields**: `x-api-key` HTTP header, `LANGGRAPH_API_KEY`/`LANGSMITH_API_KEY`/`LANGCHAIN_API_KEY` environment variables
- **Storage**: Environment variables (loaded at runtime), HTTP request headers (in transit)
- **Access**: SDK client code (`libs/sdk-py/langgraph_sdk/_shared/utilities.py:_get_api_key`), any process with env var access
- **Encryption**: TLS in transit (if HTTPS); no at-rest encryption for env vars
- **Retention**: Session/process lifetime
- **Logging exposure**: API key stripped of quotes but could appear in debug logs if HTTP headers are logged. `RESERVED_HEADERS` prevents user override of `x-api-key` but doesn't prevent logging.
- **Cross-border**: Travels with every HTTP request to the LangGraph Server
- **Gaps**: SDK `request_reconnect()` and `stream()` forward `x-api-key` header to server-controlled `Location` redirect URLs without URL validation (see T9)
#### DC2: Encryption Keys
- **Fields**: `LANGGRAPH_AES_KEY` environment variable, `key` bytes parameter
- **Storage**: Environment variable or direct bytes in application code
- **Access**: `libs/checkpoint/langgraph/checkpoint/serde/encrypted.py:from_pycryptodome_aes`
- **Encryption**: N/A — this IS the encryption key
- **Retention**: Application lifetime
- **Logging exposure**: Not logged by framework code
- **Gaps**: Key loaded from env var as UTF-8 string limits entropy to ~6.57 bits/byte (see T7). Cipher name validated with `assert` which is stripped by `python -O` (see T8).
#### DC3: Serialized Graph State
- **Fields**: All channel values serialized via `JsonPlusSerializer.dumps_typed()` — includes complete agent state, conversation history, tool call results, and any user-defined state
- **Storage**: PostgreSQL `checkpoints.checkpoint` (BYTEA), `writes.blob` (BYTEA); SQLite `checkpoints.checkpoint` (BLOB), `writes.blob` (BLOB)
- **Access**: Any code with database credentials; `BaseCheckpointSaver.get_tuple()` / `put()`
- **Encryption**: Optional via `EncryptedSerializer` wrapping (AES-EAX) or SDK Encryption Handlers (beta, server-side). Not encrypted by default.
- **Retention**: Unbounded by default. Optional TTL via `CheckpointerConfig.ttl` (server-side config)
- **Logging exposure**: Serde event hooks emit module/class names of deserialized types but not the data itself
- **Gaps**: Default unbounded retention of potentially PII-containing state. Unencrypted by default. EncryptedSerializer has fallback that accepts unencrypted data (see T10).
#### DC6: Agent Conversation History
- **Fields**: `HumanMessage.content`, `AIMessage.content`, `ToolMessage.content`, `AIMessage.tool_calls` — embedded within DC3 checkpoint bytes
- **Storage**: Same as DC3 (within serialized checkpoint data)
- **Access**: Same as DC3
- **Encryption**: Only if DC3 is encrypted via EncryptedSerializer or SDK Encryption Handlers
- **Retention**: Same as DC3 (unbounded default)
- **Gaps**: Conversation content may include user PII, PHI, or sensitive business data. No field-level encryption or redaction. Retention inherits from DC3 with no conversation-specific policy.
#### DC9: SDK Encryption Context Metadata
- **Fields**: `EncryptionContext.model` (str), `EncryptionContext.field` (str), `EncryptionContext.metadata` (dict)
- **Storage**: In-memory during request processing; persisted alongside encrypted data for later decryption
- **Access**: Encryption/decryption handlers (developer-authored), ContextHandler (receives authenticated BaseUser)
- **Encryption**: N/A — this is context for encryption, not encrypted data itself
- **Retention**: Persisted with encrypted data indefinitely
- **Logging exposure**: Not logged by SDK code
- **Gaps**: `metadata` is a mutable dict — whether cross-request isolation is enforced depends on server-side implementation (langgraph-api, out of scope). ContextHandler registration at `libs/sdk-py/langgraph_sdk/encryption/__init__.py:Encryption.context` does not call `_validate_handler` (missing async/param-count validation, unlike all other handler types).
---
## Trust Boundaries
| ID | Boundary | Description | Controls (Inside) | Does NOT Control (Outside) |
|----|----------|-------------|-------------------|---------------------------|
| TB1 | User/Framework API | Where user-provided code and configuration enters the framework | Graph execution logic, channel semantics, default configs, validation of graph structure, tool injection merge order (system values overwrite LLM values) | User node implementations, tool behavior, model selection, prompt construction, state schema design |
| TB2 | Checkpoint Storage | Where serialized data enters/leaves the persistence layer | Serialization format, allowlists for deserialization (47 safe types, 1 safe method), encryption (if configured), serde event hooks | Database access controls, who can write to the checkpoint tables, storage infrastructure security |
| TB3 | Remote API | Where data crosses the network to/from LangGraph Server | Outbound config sanitization (`_sanitize_config`), SDK HTTP transport, API key handling, `RESERVED_HEADERS` | Remote server behavior, response content integrity, network security (TLS), server-provided Location redirect targets |
| TB4 | CLI Config/Docker | Where developer config drives container image generation | Dockerfile template structure, config schema validation (including WebhookUrlPolicy), list-based subprocess args, build command content validation | `langgraph.json` file content, Docker daemon security, host filesystem |
| TB5 | SDK Encryption Handlers | Where developer-authored encryption handlers process sensitive data | Handler signature validation (async, 2-param for encrypt/decrypt), duplicate registration prevention, EncryptionContext construction | Handler implementation correctness, key management, actual encrypt/decrypt behavior, server-side execution environment |
### Boundary Details
#### TB1: User/Framework API
- **Inside**: Graph compilation validates structure (`libs/langgraph/langgraph/pregel/_validate.py:validate_graph`). Channel types enforce update semantics (`libs/langgraph/langgraph/channels/base.py:BaseChannel.update`). Functional API validates entrypoint has at least one parameter (`libs/langgraph/langgraph/func/__init__.py:entrypoint`). Sensitive config keys filtered from metadata propagation — keys containing "key", "token", "secret", "password", "auth" are excluded (`libs/langgraph/langgraph/_internal/_config.py:_exclude_as_metadata`). Tool injection merge order ensures system-injected values (InjectedState/InjectedStore/ToolRuntime) overwrite any LLM-supplied collisions (`libs/prebuilt/langgraph/prebuilt/tool_node.py:ToolNode._inject_tool_args` line 1380). Injected parameter names hidden from LLM tool schema via `tool_call_schema` filtering.
- **Outside**: What user nodes do, what tools return, what LLMs generate, how users handle output.
- **Crossing mechanism**: Python function calls — `add_node(callable)`, `add_edge()`, `compile(checkpointer=...)`, `@entrypoint`, `@task`.
#### TB2: Checkpoint Storage
- **Inside**: `JsonPlusSerializer` controls serialization format (`libs/checkpoint/langgraph/checkpoint/serde/jsonplus.py:JsonPlusSerializer`). Msgpack type allowlist (`libs/checkpoint/langgraph/checkpoint/serde/_msgpack.py:SAFE_MSGPACK_TYPES` — 47 safe types including stdlib, langchain_core messages, and langgraph types). Msgpack method allowlist (`libs/checkpoint/langgraph/checkpoint/serde/_msgpack.py:SAFE_MSGPACK_METHODS` — 1 safe method: `datetime.datetime.fromisoformat`). JSON module allowlist (`libs/checkpoint/langgraph/checkpoint/serde/jsonplus.py:_check_allowed_json_modules`). Serde event hooks for monitoring (`libs/checkpoint/langgraph/checkpoint/serde/event_hooks.py:emit_serde_event`). Optional `EncryptedSerializer` wrapping (`libs/checkpoint/langgraph/checkpoint/serde/encrypted.py:EncryptedSerializer`). SQLite filter key regex validation (`libs/checkpoint-sqlite/langgraph/checkpoint/sqlite/utils.py:_validate_filter_key`). Parameterized SQL queries in both Postgres and SQLite backends.
- **Outside**: Database access controls, who can read/write checkpoint tables, storage backend integrity.
- **Crossing mechanism**: Database read/write operations — serialized bytes stored as BYTEA (Postgres) or BLOB (SQLite).
#### TB3: Remote API
- **Inside**: `_sanitize_config()` strips non-primitive values and drops checkpoint-internal keys from outbound config (`libs/langgraph/langgraph/pregel/remote.py:_sanitize_config`). SDK handles API key from env vars (`libs/sdk-py/langgraph_sdk/_shared/utilities.py:_get_api_key`). `RESERVED_HEADERS` prevents user override of `x-api-key` (`libs/sdk-py/langgraph_sdk/_shared/utilities.py:RESERVED_HEADERS`).
- **Outside**: Remote server response content, network integrity, whether the server is legitimate, server-provided Location redirect targets.
- **Crossing mechanism**: HTTPS requests via `httpx` through `langgraph_sdk`.
#### TB4: CLI Config/Docker
- **Inside**: Config file parsed as JSON (`libs/cli/langgraph_cli/config.py:validate_config_file`). Docker subprocess invoked with list-based args via `asyncio.create_subprocess_exec`, not `shell=True` (`libs/cli/langgraph_cli/exec.py:subp_exec`). Template downloads from hardcoded GitHub URLs (`libs/cli/langgraph_cli/templates.py`). Config schema validation covers store, auth, encryption, http, webhooks, checkpointer, and ui sections (`libs/cli/langgraph_cli/schemas.py`). Build command content validation blocks shell metacharacters (`libs/cli/langgraph_cli/config.py:has_disallowed_build_command_content`). WebhookUrlPolicy (`libs/cli/langgraph_cli/schemas.py:WebhookUrlPolicy`) supports `require_https`, `allowed_domains`, `allowed_ports`, `max_url_length`, `disable_loopback` for SSRF protection.
- **Outside**: Content of `langgraph.json`, Docker daemon behavior, filesystem permissions.
- **Crossing mechanism**: JSON file read, subprocess execution, ZIP download/extraction.
#### TB5: SDK Encryption Handlers
- **Inside**: Handler signature validation — must be async, must accept exactly 2 positional params (`libs/sdk-py/langgraph_sdk/encryption/__init__.py:_validate_handler`). Duplicate handler registration prevention (`DuplicateHandlerError`). `EncryptionContext` construction with model/field/metadata (`libs/sdk-py/langgraph_sdk/encryption/types.py:EncryptionContext`). JSON key preservation constraint documented (enforced server-side).
- **Outside**: Handler implementation correctness, key management strategy, actual encryption/decryption logic, server-side execution in langgraph-api.
- **Crossing mechanism**: Python decorator registration at import time; server-side invocation at runtime.
---
## Data Flows
| ID | Source | Destination | Data Type | Classification | Crosses Boundary | Protocol |
|----|--------|-------------|-----------|----------------|------------------|----------|
| DF1 | C12 (Checkpoint Storage) | C2 (JsonPlusSerializer) | Serialized checkpoint bytes (msgpack/JSON/pickle) | DC3 | TB2 | Database read |
| DF2 | C2 (JsonPlusSerializer) | C1 (Pregel) | Deserialized Python objects (channel state) | DC3, DC6 | TB2 | Function call |
| DF3 | LLM (external) | C3 (ToolNode) | Tool call arguments (JSON strings in AIMessage) | — | TB1 | Function call (via langchain-core) |
| DF4 | C3 (ToolNode) | C10 (User Tools) | Parsed argument dicts merged with injected state/store/runtime | — | TB1 | `tool.invoke(call_args)` |
| DF5 | C4 (RemoteGraph) | C1 (Pregel) | Stream chunks (JSON-deserialized dicts) | — | TB3 | HTTPS / SSE |
| DF6 | `langgraph.json` | C8 (CLI) | Config dict (graphs, env, store, auth, encryption, http, webhooks, checkpointer, ui) | — | TB4 | `json.load()` |
| DF7 | C8 (CLI) | Docker | Dockerfile content with embedded ENV values | — | TB4 | `asyncio.create_subprocess_exec` |
| DF8 | C11 (User Nodes) | C1 (Pregel) | State updates (arbitrary Python objects) | — | TB1 | Channel write |
| DF9 | C9 (SDK Client) | C4 (RemoteGraph) | API responses (JSON) | — | TB3 | HTTPS |
| DF10 | User config | C7 (EncryptedSerializer) | AES key from LANGGRAPH_AES_KEY env var | DC2 | TB2 | `os.getenv()` |
| DF11 | C12 (Checkpoint Storage) | C14 (BaseCache) | Cached task results via JsonPlusSerializer | DC3 | TB2 | Database read |
| DF12 | LangGraph Server | C9 (SDK Client) | HTTP responses with Location header | DC1 | TB3 | HTTP redirect |
| DF13 | C9 (SDK Client) | Redirect target | Request headers including x-api-key | DC1 | TB3 | HTTPS |
| DF14 | C1 (Pregel state) | C3 (ToolNode) | InjectedState/InjectedStore/ToolRuntime values for tool injection | DC3, DC4 | TB1 | Function call (dict merge) |
| DF15 | Developer code | C17 (SDK Encryption Handlers) | Encryption/decryption handler functions and context handler | — | TB5 | Python decorator registration |
### Flow Details
#### DF1: Checkpoint Storage -> JsonPlusSerializer
- **Data**: Serialized graph state as `(type_tag, bytes)` tuples. Type tags include `"msgpack"`, `"json"`, `"pickle"`, `"bytes"`, `"null"`. When encrypted: `"msgpack+aes"`, `"json+aes"`.
- **Validation**: Type tag dispatches to codec. Msgpack: `_create_msgpack_ext_hook` with allowlist check — `SAFE_MSGPACK_TYPES` (47 entries) always checked first, then `allowed_modules` determines behavior for unregistered types (`libs/checkpoint/langgraph/checkpoint/serde/jsonplus.py:_create_msgpack_ext_hook`). JSON: `_reviver` with `lc:2` module allowlist. Pickle: **no restrictions** (`pickle.loads(data_)` if `pickle_fallback=True`, `libs/checkpoint/langgraph/checkpoint/serde/jsonplus.py:JsonPlusSerializer.loads_typed`). The proposed `secure_pickle.py` with `RestrictedUnpickler` was documented in `SECURITY_FIX_SUMMARY.md` but never merged.
- **Trust assumption**: Checkpoint storage is access-controlled. An attacker with write access to the database can craft malicious checkpoint data.
#### DF3: LLM -> ToolNode
- **Data**: Tool call name and arguments from LLM-generated `AIMessage.tool_calls`.
- **Validation**: Tool name checked against registered `tools_by_name` dict — unknown names return error `ToolMessage` (`libs/prebuilt/langgraph/prebuilt/tool_node.py:ToolNode._validate_tool_call`). Argument values validated only by the target tool's Pydantic schema.
- **Trust assumption**: LLM output is treated as untrusted for tool name routing but argument values pass through to tools without ToolNode-level sanitization.
#### DF4: ToolNode -> User Tools (with Injection)
- **Data**: Parsed argument dicts from LLM, merged with system-injected InjectedState/InjectedStore/ToolRuntime values.
- **Validation**: Four-layer defense: (1) Injected parameter names hidden from LLM via `tool_call_schema` filtering. (2) Dict merge `{**llm_args, **injected_args}` places system values last — system always wins on collision (`libs/prebuilt/langgraph/prebuilt/tool_node.py:ToolNode._inject_tool_args` line 1380). (3) Pydantic `model_validate` with default `extra="ignore"` drops unknown keys. (4) Output construction only includes declared model fields.
- **Trust assumption**: LLM-provided arguments cannot override system-injected values due to merge order.
#### DF5: RemoteGraph -> Pregel
- **Data**: Stream event chunks containing dicts for `Interrupt`, `Command`, state snapshots.
- **Validation**: **None** on inbound data. `Interrupt(**i)` uses dict-splatting with no schema check (`libs/langgraph/langgraph/pregel/remote.py:RemoteGraph.stream`). `Command(**chunk.data)` uses dict-splatting for parent commands.
- **Trust assumption**: Remote server is trusted. A compromised or malicious server can inject arbitrary field values.
#### DF6: langgraph.json -> CLI
- **Data**: JSON config including `graphs`, `env`, `store`, `auth`, `encryption`, `http`, `webhooks`, `checkpointer`, `ui`, `ui_config` sections.
- **Validation**: Schema validation in `validate_config_file()` (`libs/cli/langgraph_cli/config.py:validate_config_file`). Config values embedded in Dockerfile via `json.dumps()` in single-quoted `ENV` lines (`libs/cli/langgraph_cli/config.py:python_config_to_docker`). Build command content validation (`libs/cli/langgraph_cli/config.py:has_disallowed_build_command_content`) blocks shell metacharacters.
- **Trust assumption**: `langgraph.json` is developer-authored. Single quotes in config values could break Dockerfile `ENV` syntax.
#### DF11: Checkpoint Storage -> BaseCache
- **Data**: Cached task results stored via `BaseCache.set()` and retrieved via `BaseCache.get()`.
- **Validation**: Uses `JsonPlusSerializer(pickle_fallback=False)` by default (`libs/checkpoint/langgraph/cache/base/__init__.py:BaseCache`). Subject to same msgpack deserialization behavior as DF1 (allowed_modules defaults based on `LANGGRAPH_STRICT_MSGPACK`).
- **Trust assumption**: Cache storage has same access controls as checkpoint storage.
#### DF12-13: Server -> SDK -> Redirect Target (API Key Leak)
- **Data**: Server provides `Location` header in HTTP response. SDK follows the redirect and sends all original request headers (including `x-api-key`) to the target URL.
- **Validation**: **None** on Location URL. No allowlist, no same-origin check, no header stripping on cross-origin redirect.
- **Trust assumption**: The LangGraph Server is trusted to not redirect to malicious URLs. Violated if server is compromised.
#### DF14: Pregel State -> ToolNode (Runtime Injection)
- **Data**: Graph state dict (InjectedState), BaseStore instance (InjectedStore), ToolRuntime object (containing state, config, store, context, stream_writer, tool_call_id).
- **Validation**: Injection targets determined by tool type annotations at compile time. Injected values overwrite any LLM-provided values with matching keys (safe merge order). Pydantic validation on tool input drops extra keys not in the tool's declared schema.
- **Trust assumption**: System-injected values are trusted; LLM-provided values cannot interfere due to merge order guarantees.
#### DF15: Developer Code -> SDK Encryption Handlers
- **Data**: Async Python callables registered via decorators for blob/JSON encryption/decryption and context derivation.
- **Validation**: `_validate_handler` checks async-ness and 2-param signature for encrypt/decrypt handlers. `DuplicateHandlerError` prevents double registration. **Gap**: `Encryption.context()` method does NOT call `_validate_handler` — a sync function or wrong param count passes registration and fails only at server-side invocation (`libs/sdk-py/langgraph_sdk/encryption/__init__.py:Encryption.context`).
- **Trust assumption**: Handler authors are application developers with server-level trust.
---
## Threats
| ID | Data Flow | Classification | Threat | Boundary | Severity | Validation | Code Reference |
|----|-----------|----------------|--------|----------|----------|------------|----------------|
| T1 | DF1, DF11 | DC3 | Arbitrary code execution via msgpack deserialization when strict mode is OFF (default) | TB2 | High | Verified | `libs/checkpoint/langgraph/checkpoint/serde/jsonplus.py:_create_msgpack_ext_hook` |
| T2 | DF1 | DC3 | Arbitrary code execution via `pickle.loads` when `pickle_fallback=True` | TB2 | High | Verified | `libs/checkpoint/langgraph/checkpoint/serde/jsonplus.py:JsonPlusSerializer.loads_typed` |
| T3 | DF1 | DC3 | Arbitrary module import/execution via JSON `lc:2` constructor when `allowed_json_modules=True` | TB2 | High | Verified | `libs/checkpoint/langgraph/checkpoint/serde/jsonplus.py:JsonPlusSerializer._revive_lc2` |
| T4 | DF5 | — | Unvalidated dict-splatting from remote API into `Interrupt`/`Command` objects | TB3 | Medium | Likely | `libs/langgraph/langgraph/pregel/remote.py:RemoteGraph.stream` |
| T5 | DF6, DF7 | — | Dockerfile ENV injection via single-quote in `langgraph.json` config values | TB4 | Low | Likely | `libs/cli/langgraph_cli/config.py:python_config_to_docker` |
| T6 | DF7 | — | ZIP slip in `langgraph new` template extraction | TB4 | Low | Unverified | `libs/cli/langgraph_cli/templates.py:_download_repo_with_requests` |
| T7 | DF10 | DC2 | AES key entropy limited to printable characters via env var string encoding | TB2 | Info | — | `libs/checkpoint/langgraph/checkpoint/serde/encrypted.py:EncryptedSerializer.from_pycryptodome_aes` |
| T8 | DF10 | DC2 | EncryptedSerializer cipher name check uses `assert` (stripped with `python -O`) | TB2 | Low | Verified | `libs/checkpoint/langgraph/checkpoint/serde/encrypted.py:PycryptodomeAesCipher.decrypt` |
| T9 | DF12, DF13 | DC1 | SDK API key leak via server-controlled Location redirect to attacker-controlled URL | TB3 | Medium | Verified | `libs/sdk-py/langgraph_sdk/_async/http.py:HttpClient.request_reconnect`, `libs/sdk-py/langgraph_sdk/_async/http.py:HttpClient.stream` |
| T10 | DF1 | DC3 | EncryptedSerializer silently accepts unencrypted data — attacker bypasses encryption by writing plain type tags | TB2 | Medium | Verified | `libs/checkpoint/langgraph/checkpoint/serde/encrypted.py:EncryptedSerializer.loads_typed` |
| T11 | DF1, DF11 | DC3, DC6 | Unbounded retention of checkpoint data containing PII/conversation history | TB2 | Medium | — | `libs/checkpoint/langgraph/checkpoint/base/__init__.py:BaseCheckpointSaver` |
### Threat Details
#### T1: Msgpack Deserialization RCE (Default Config)
- **Flow**: DF1 (Checkpoint Storage -> JsonPlusSerializer), DF11 (Checkpoint Storage -> BaseCache)
- **Description**: When `LANGGRAPH_STRICT_MSGPACK` is not set (the default), the msgpack `_create_msgpack_ext_hook` allows **any** `(module, class)` pair stored in checkpoint data to be imported via `importlib.import_module` and instantiated with attacker-controlled arguments. The `SAFE_MSGPACK_TYPES` allowlist (47 entries) is checked first, but unregistered types are logged as warnings and allowed through when `allowed_modules=True` (the default when strict mode is off). Seven EXT codes are processed: `EXT_CONSTRUCTOR_SINGLE_ARG` (0), `EXT_CONSTRUCTOR_POS_ARGS` (1), `EXT_CONSTRUCTOR_KW_ARGS` (2), `EXT_METHOD_SINGLE_ARG` (3), `EXT_PYDANTIC_V1` (4), `EXT_PYDANTIC_V2` (5), `EXT_NUMPY_ARRAY` (6). The `BaseCache` component uses `JsonPlusSerializer(pickle_fallback=False)` but inherits the same msgpack `allowed_modules` default behavior. The proposed `RestrictedUnpickler` (`secure_pickle.py`) documented in `SECURITY_FIX_SUMMARY.md` was never merged — pickle remains unrestricted when enabled.
- **Preconditions**: Attacker must have write access to the checkpoint database (PostgreSQL or SQLite). This requires compromised database credentials or a co-located attacker.
#### T2: Pickle Deserialization RCE
- **Flow**: DF1 (Checkpoint Storage -> JsonPlusSerializer)
- **Description**: When `pickle_fallback=True` is explicitly passed to `JsonPlusSerializer`, checkpoint data with type tag `"pickle"` is deserialized via `pickle.loads()` with zero restrictions (`libs/checkpoint/langgraph/checkpoint/serde/jsonplus.py:JsonPlusSerializer.loads_typed`).
- **Preconditions**: (1) Application or checkpointer explicitly enables `pickle_fallback=True`. (2) Attacker writes `("pickle", <payload>)` to checkpoint storage.
#### T3: JSON lc:2 Constructor RCE
- **Flow**: DF1 (Checkpoint Storage -> JsonPlusSerializer)
- **Description**: The JSON `_reviver` handles `lc:2` type constructors by importing the module path from checkpoint JSON data via `importlib.import_module` (`libs/checkpoint/langgraph/checkpoint/serde/jsonplus.py:JsonPlusSerializer._revive_lc2`). If `allowed_json_modules=True` (explicit opt-in), any module reachable in the Python environment can be imported and instantiated. The method also supports method chaining — a `method` key in the JSON can call arbitrary methods on the imported class.
- **Preconditions**: (1) `allowed_json_modules` set to `True` (not the default). (2) Attacker writes crafted JSON to checkpoint storage.
#### T4: RemoteGraph Unvalidated Inbound Data
- **Flow**: DF5 (RemoteGraph -> Pregel)
- **Description**: Stream events from the remote LangGraph Server are deserialized from JSON and dict-splatted into `Interrupt(**i)` and `Command(**chunk.data)` without schema validation (`libs/langgraph/langgraph/pregel/remote.py:RemoteGraph.stream`). A compromised or malicious remote server can inject unexpected fields. `Command.update` can carry arbitrary state modifications; `Command.goto` can alter graph execution flow. `Interrupt` accepts `**deprecated_kwargs` which includes a `ns` parameter that can override interrupt ID generation via `xxh3_128_hexdigest`.
- **Preconditions**: User connects `RemoteGraph` to a compromised or attacker-controlled server URL.
#### T5: Dockerfile ENV Single-Quote Injection
- **Flow**: DF6, DF7 (langgraph.json -> CLI -> Dockerfile)
- **Description**: Config values from `langgraph.json` are serialized via `json.dumps()` and embedded in single-quoted `ENV` directives across multiple config sections (store, auth, encryption, http, webhooks, checkpointer, ui, ui_config, graphs). JSON does not escape single quotes, so a config value containing `'` could break the Dockerfile syntax or inject additional Dockerfile instructions. The pattern is duplicated in two Dockerfile generation functions (`libs/cli/langgraph_cli/config.py:python_config_to_docker` and `libs/cli/langgraph_cli/config.py:node_config_to_docker`).
- **Preconditions**: A `langgraph.json` config value contains a single quote character.
#### T6: ZIP Slip in Template Extraction
- **Flow**: DF7 (CLI template download)
- **Description**: `langgraph new` downloads a ZIP from GitHub and uses `zip_file.extractall(path)`. If the archive contains path-traversal entries (e.g., `../../etc/cron.d/exploit`), files could be written outside the target directory.
- **Preconditions**: The GitHub-hosted template archive must contain malicious path entries. This requires compromise of the upstream template repo.
#### T7: AES Key Entropy via Environment Variable
- **Flow**: DF10 (User config -> EncryptedSerializer)
- **Description**: The AES key is loaded from `LANGGRAPH_AES_KEY` as a UTF-8 string and `.encode()`d to bytes (`libs/checkpoint/langgraph/checkpoint/serde/encrypted.py:EncryptedSerializer.from_pycryptodome_aes`). This limits key entropy to printable characters (~6.57 bits/byte vs. 8 bits/byte for random bytes), reducing effective key strength for AES-128 from 128 bits to ~105 bits.
- **Preconditions**: User relies on environment variable path for key loading (vs. passing raw bytes directly via `key=` parameter).
#### T8: EncryptedSerializer Assert Bypass
- **Flow**: DF10 (Encrypted checkpoint data)
- **Description**: The cipher name check in `decrypt()` uses `assert ciphername == "aes"` (`libs/checkpoint/langgraph/checkpoint/serde/encrypted.py:PycryptodomeAesCipher.decrypt`), which is stripped when Python runs with `-O` (optimize) flag. The `ciphername` value comes from the type tag in checkpoint storage (split from the `type+cipher` format).
- **Preconditions**: Python running with `-O` flag AND attacker can write to checkpoint storage.
#### T9: SDK API Key Leak via Server-Controlled Location Redirect
- **Flow**: DF12 (Server -> SDK), DF13 (SDK -> Redirect target)
- **Description**: The SDK's `HttpClient.request_reconnect()` (`libs/sdk-py/langgraph_sdk/_async/http.py:HttpClient.request_reconnect`) follows server-provided `Location` headers and forwards the full `request_headers` dict (including the `x-api-key` authentication header) to the redirected URL. The `HttpClient.stream()` method (`libs/sdk-py/langgraph_sdk/_async/http.py:HttpClient.stream`) also follows `Location` headers for SSE reconnection and forwards `reconnect_headers` (which include `x-api-key`) to the server-controlled URL. No URL validation, same-origin check, or sensitive header stripping is performed before following the redirect. The same pattern exists in the sync client (`libs/sdk-py/langgraph_sdk/_sync/http.py`).
- **Preconditions**: (1) User connects SDK to a LangGraph Server that is compromised or attacker-controlled. (2) The server returns a response with a `Location` header pointing to an attacker-controlled URL.
#### T10: EncryptedSerializer Encryption Bypass via Unencrypted Data Injection
- **Flow**: DF1 (Checkpoint Storage -> EncryptedSerializer)
- **Description**: `EncryptedSerializer.loads_typed()` (`libs/checkpoint/langgraph/checkpoint/serde/encrypted.py:EncryptedSerializer.loads_typed`) checks if the type tag contains a `+` delimiter. If it does not (e.g., type tag is `"msgpack"` instead of `"msgpack+aes"`), the data is passed directly to the inner serde's `loads_typed()` **without any decryption or MAC verification**. An attacker with write access to checkpoint storage can bypass the encryption layer entirely by writing data with a plain type tag.
- **Preconditions**: (1) Application uses `EncryptedSerializer` for checkpoint protection. (2) Attacker has write access to checkpoint storage.
#### T11: Unbounded Checkpoint Data Retention
- **Flow**: DF1, DF11 (Checkpoint Storage lifecycle)
- **Description**: Checkpoint data (DC3, DC6) is retained indefinitely by default. No built-in TTL, pruning, or data lifecycle management in the library-level checkpoint savers. Conversation history containing user PII may accumulate without bounds.
- **Preconditions**: Application uses checkpointing (the primary use case). No explicit cleanup configured.
---
## Input Source Coverage
| Input Source | Data Flows | Threats | Validation Points | Responsibility | Gaps |
|-------------|-----------|---------|-------------------|----------------|------|
| User direct input (graph state, config) | DF8 | — | Graph structure validation (`libs/langgraph/langgraph/pregel/_validate.py:validate_graph`), channel type enforcement (`libs/langgraph/langgraph/channels/base.py:BaseChannel`), sensitive key filtering (`libs/langgraph/langgraph/_internal/_config.py:_exclude_as_metadata`) | User | Node implementation safety is user's responsibility |
| LLM output (tool calls) | DF3, DF4, DF14 | — | Tool name allowlist (`libs/prebuilt/langgraph/prebuilt/tool_node.py:ToolNode._validate_tool_call`), tool Pydantic schemas, injection merge order (`libs/prebuilt/langgraph/prebuilt/tool_node.py:ToolNode._inject_tool_args`), `tool_call_schema` filtering of injected params | Shared (project validates name and injection safety; user validates args via tool schema) | No ToolNode-level argument sanitization beyond injection overwrite |
| Checkpoint storage data | DF1, DF2, DF11 | T1, T2, T3, T10 | Msgpack allowlist (`libs/checkpoint/langgraph/checkpoint/serde/_msgpack.py:SAFE_MSGPACK_TYPES` — 47 entries), msgpack method allowlist (`libs/checkpoint/langgraph/checkpoint/serde/_msgpack.py:SAFE_MSGPACK_METHODS`), JSON allowlist (`libs/checkpoint/langgraph/checkpoint/serde/jsonplus.py:_check_allowed_json_modules`), pickle gating, serde event hooks, optional encryption | Shared (project owns serializer defaults; user owns DB access controls) | Default msgpack mode allows unregistered types; EncryptedSerializer accepts unencrypted data; proposed secure_pickle.py never merged |
| Remote API responses | DF5, DF9, DF12, DF13 | T4, T9 | Outbound config sanitization (`libs/langgraph/langgraph/pregel/remote.py:_sanitize_config`); no inbound validation; no redirect URL validation | User (user chooses which server to trust) | No inbound schema validation; API key forwarded on redirects |
| Configuration (langgraph.json) | DF6, DF7 | T5 | JSON schema validation (`libs/cli/langgraph_cli/config.py:validate_config_file`), build command content validation (`libs/cli/langgraph_cli/config.py:has_disallowed_build_command_content`), list-based subprocess args, WebhookUrlPolicy (`libs/cli/langgraph_cli/schemas.py:WebhookUrlPolicy`) | User (developer-controlled file) | Single-quote not escaped in ENV embedding |
| Configuration (env vars) | DF10 | T7, T8 | AES key length validation, EAX MAC verification | User (deployer controls env) | Key entropy, assert-based check |
| Developer encryption handlers | DF15 | — | Handler signature validation (`libs/sdk-py/langgraph_sdk/encryption/__init__.py:_validate_handler`), duplicate prevention | User (developer-authored code) | `context()` handler missing `_validate_handler` call |
---
## Out-of-Scope Threats
Threats that appear valid in isolation but fall outside project responsibility because they depend on conditions the project does not control.
| Pattern | Why Out of Scope | Project Responsibility Ends At |
|---------|-----------------|-------------------------------|
| Prompt injection leading to arbitrary tool execution | Project does not control LLM model behavior, user prompt construction, or which tools are registered. ToolNode routes by name only to user-registered tools. | Providing tool name allowlist routing (`libs/prebuilt/langgraph/prebuilt/tool_node.py:ToolNode._validate_tool_call`); user owns tool registration and argument handling |
| State poisoning via malicious node output | User-registered nodes (including `@task`-decorated functions) can write arbitrary values to channels. The framework executes nodes as provided. | Enforcing channel type contracts (`libs/langgraph/langgraph/channels/base.py:BaseChannel.update`); user owns node implementation correctness |
| Cross-session state access via thread_id guessing | Checkpoint savers index by `thread_id`. Without application-level auth, any caller with a valid thread_id can access that thread's state. | Providing the `Auth` handler system for access control (`libs/sdk-py/langgraph_sdk/auth/__init__.py:Auth`); user must implement auth handlers |
| Tool shadowing via duplicate registration | If a user registers two tools with the same name, ToolNode uses the last one. This is user misconfiguration. | Documenting tool registration semantics |
| Indirect prompt injection via tool output | LLM reads tool output and may follow injected instructions. This is a fundamental LLM limitation, not a framework vulnerability. | Not including tool output in system prompts; user owns output handling |
| Model selecting dangerous tool arguments | An LLM may generate SQL injection, path traversal, or command injection payloads as tool arguments. The risk depends entirely on what the user's tools do with those arguments. | Routing tool calls to registered tools only; user owns tool input validation |
| RCE via user-provided node code | `add_node()` and `@entrypoint`/`@task` accept arbitrary callables. A malicious node can do anything. This is by design — the user controls their own code. | Executing nodes within the graph runtime; user owns node code safety |
| SSRF via RemoteGraph URL | User provides the `url` parameter to `RemoteGraph`. Pointing it at an internal service is the user's decision. | Documenting that `url` should be a trusted endpoint; user owns URL selection |
| Malicious SDK Encryption handler | Encryption handlers are developer-authored server-side code. A malicious handler has full process access, equivalent to any application code. | Validating handler signature (async, param count); handler behavior is the developer's responsibility |
### Rationale
**Prompt injection and tool execution**: LangGraph's `ToolNode` validates tool names against the registered set but does not inspect or sanitize argument values. This is the correct boundary — the framework cannot know what constitutes a "safe" argument for an arbitrary user-defined tool. The tool's own Pydantic schema and implementation must validate inputs. The framework's responsibility is to not execute unregistered tools and to correctly route registered ones. The injection system (InjectedState/InjectedStore/ToolRuntime) is safe because system-injected values always overwrite LLM-supplied collisions via dict merge order, and injected parameter names are hidden from the LLM's tool schema.
**State integrity**: LangGraph channels enforce type contracts (e.g., `LastValue` accepts one value per step, `BinaryOperatorAggregate` applies a reducer). The framework validates graph structure at compile time (`libs/langgraph/langgraph/pregel/_validate.py:validate_graph`). However, the semantic correctness of state updates is the user's responsibility — the framework cannot know what values are "valid" for a user-defined state schema.
**Checkpoint access control**: The framework provides `BaseCheckpointSaver` as an abstract interface and the `Auth` handler system for authorization (`libs/sdk-py/langgraph_sdk/auth/__init__.py:Auth`). It does not enforce authentication by default because it operates as a library, not a server. The `langgraph-api` server layer (out of scope) is responsible for enforcing auth on API endpoints. Users embedding LangGraph directly must implement their own access controls.
**Encryption handler safety**: The SDK Encryption module (`libs/sdk-py/langgraph_sdk/encryption/`) provides a registration framework for developer-authored encryption handlers. These handlers run server-side with full process access, identical to any application code. A buggy or malicious handler could return crafted data, but this is the same trust model as any developer-written code. The SDK validates handler shape (async, 2-param) but not handler behavior — this is the correct boundary for developer-trust-level code.
---
## Investigated and Dismissed
| ID | Original Threat | Investigation | Evidence | Conclusion |
|----|----------------|---------------|----------|------------|
| D1 | SQL injection via filter keys in PostgreSQL store | Traced filter key handling through `libs/checkpoint-postgres/langgraph/store/postgres/base.py:_get_filter_condition`. All filter operations use parameterized queries with `%s` placeholders. Keys map to `json_extract` path operators with type-safe wrappers. | `libs/checkpoint-postgres/langgraph/store/postgres/base.py:_get_filter_condition` — parameterized `%s` for all value bindings; key names used in `value->%s` path expressions are also parameterized | Disproven: All SQL operations in PostgreSQL store are fully parameterized. No injection vector. |
| D2 | SQL injection via filter keys in SQLite store (post-fix) | Traced current filter handling through `libs/checkpoint-sqlite/langgraph/store/sqlite/base.py` and `libs/checkpoint-sqlite/langgraph/checkpoint/sqlite/utils.py:_validate_filter_key`. Regex `^[a-zA-Z0-9_.-]+$` applied to all filter keys before use in `json_extract()` expressions. | `libs/checkpoint-sqlite/langgraph/checkpoint/sqlite/utils.py:_validate_filter_key` — regex validation blocks injection characters. Published advisories GHSA-9rwj-6rc7-p77c and GHSA-7p73-8jqx-23r8 confirmed fixed. | Disproven: SQL injection in SQLite store filter keys is remediated by regex validation. |
| D3 | Command injection via CLI subprocess execution | Traced CLI subprocess invocation path. `libs/cli/langgraph_cli/exec.py:subp_exec` uses `asyncio.create_subprocess_exec` with list-based arguments (not `shell=True`). `has_disallowed_build_command_content` blocks shell metacharacters in user-provided Dockerfile lines. | `libs/cli/langgraph_cli/exec.py:subp_exec` — explicit exec-style invocation; `libs/cli/langgraph_cli/config.py:has_disallowed_build_command_content` — regex blocks `\|`, `;`, `$`, `>`, `<`, backtick, `\`, single `&` | Disproven: CLI uses exec-style subprocess and validates build command content. No shell injection vector. |
| D4 | Tool argument injection via InjectedState/InjectedStore dict-splatting | Investigated whether LLM-generated tool call arguments could override system-injected values (InjectedState, InjectedStore, ToolRuntime) via key collision in the dict merge at `libs/prebuilt/langgraph/prebuilt/tool_node.py:ToolNode._inject_tool_args` line 1380. Traced four independent defense layers. | (1) `tool_call_schema` at langchain-core `base.py` filters injected params from LLM schema. (2) `{**llm_args, **injected_args}` merge puts system values last — system wins on collision. (3) Pydantic `model_validate` with `extra="ignore"` drops unknown keys. (4) Output construction at `base.py` only includes declared model fields. | Disproven: Four-layer defense prevents LLM arguments from overriding system-injected values. Merge order guarantees system values win. No adversarial collision path exists. |
---
## External Context
### Published Security Advisories
| GHSA ID | Severity | Summary | CWEs | Relevance |
|---------|----------|---------|------|-----------|
| GHSA-g48c-2wqr-h844 | Medium | Unsafe msgpack deserialization in LangGraph checkpoint loading | — | Directly relates to T1 — patched in 1.0.10, confirms attack path via crafted msgpack payloads |
| GHSA-mhr3-j7m5-c7c9 | Medium | BaseCache Deserialization RCE | CWE-502 | Directly relates to T1 — msgpack deserialization in cache layer |
| GHSA-9rwj-6rc7-p77c | High | SQL injection via metadata filter key in SQLite checkpointer | CWE-89 | Fixed via `_validate_filter_key()` regex — see D2 |
| GHSA-wwqv-p2pp-99h5 | High | RCE in JSON mode of JsonPlusSerializer | CWE-502 | Directly relates to T3 — `lc:2` constructor import |
| GHSA-7p73-8jqx-23r8 | High | SQLite Filter Key SQL Injection in SqliteStore | CWE-89 | Fixed via `_validate_filter_key()` regex — see D2 |
**Pattern**: 3 of 5 published advisories involve CWE-502 (insecure deserialization) in the checkpoint serialization layer. This confirms the checkpoint storage boundary (TB2) as the highest-risk area. The extensive closed advisory history (~15 deserialization bypass attempts) further validates this assessment. No new published advisories since the prior assessment (2026-03-27).
---
## Revision History
| Date | Author | Changes |
|------|--------|---------|
| 2026-03-04 | Generated | Initial threat model |
| 2026-03-04 | Updated | Added C13 (Functional API), C14 (BaseCache), DF11. Updated T1 for BaseCache/serde event hooks. Added GHSA-mhr3-j7m5-c7c9 and GHSA-9rwj-6rc7-p77c. Updated CLI config scope. Added External Context section. |
| 2026-03-27 | Deep refinement | **Mode upgraded to Deep.** Added: Data Classification section (DC1-DC8 with detailed analysis for Critical/High entries). Added: C15 (Serde Event Hooks), C16 (Auth System). Added: Default? column to Components. Added: Classification column to Data Flows. Added: DF12-DF13 (SDK redirect flows). Added: T9 (SDK API key leak via Location redirect), T10 (EncryptedSerializer encryption bypass), T11 (unbounded checkpoint retention). Added: Validation column to Threats with flaw validation for High/Critical. Added: Investigated and Dismissed section (D1-D3: SQL injection and CLI command injection disproven). Added: Input Source Coverage section. Updated external context with GHSA-g48c-2wqr-h844 (new published advisory). Updated all code references to file:SymbolName notation. Expanded trust boundary details. |
| 2026-03-30 | Diagram and Default? corrections | Fixed architecture diagram: merged "User Code" and "User-Registered Tools" into single "User Application Code" boundary; removed @entrypoint/@task as separate diagram elements (both compile to Pregel — authoring style, not separate component). Fixed Default? column: C3 ToolNode → No (explicit opt-in required); C8 CLI → No (separate install). |
| 2026-03-28 | Deep update | **Added:** C17 (SDK Encryption Handlers — beta at-rest encryption framework). DC9 (SDK Encryption context metadata). TB5 (SDK Encryption Handler boundary). DF14 (ToolRuntime injection flow), DF15 (Encryption handler registration flow). D4 (Tool argument injection via InjectedState dict-splatting — disproven with 4-layer defense evidence). **Updated:** C1 description (v1/v2 output, durability modes, interrupt_before/after). C2 description (SAFE_MSGPACK_TYPES now 47 entries including langchain_core messages, Document, GetOp). C3 description (InjectedState/InjectedStore/ToolRuntime injection support, _inject_tool_args entry point). C8 description (WebhookUrlPolicy for SSRF protection). TB1 details (tool injection merge order guarantees). TB2 details (47 safe types, updated allowlist composition). TB4 details (WebhookUrlPolicy). DF4 description (injection merge semantics). T1 details (noted secure_pickle.py proposed but never merged). T4 details (Interrupt deprecated_kwargs ns parameter). Input Source Coverage (LLM output row updated with injection validation points, encryption handler row added). Out-of-Scope Threats (malicious encryption handler pattern added). Commit updated to 0ba22143. External context confirmed no new published advisories. |
+1 -1
View File
@@ -49,7 +49,7 @@ jobs:
uses: ./.github/actions/uv_setup
with:
python-version: ${{ matrix.python-version }}
cache-suffix: "cli-integration-test"
enable-cache: "false"
working-directory: libs/cli
- name: Install cli globally
if: (steps.changed-files.outputs.all || github.event_name == 'workflow_dispatch')
+161
View File
@@ -0,0 +1,161 @@
# Reopen PRs that were auto-closed by require_issue_link.yml when the
# contributor was not assigned to the linked issue. When a maintainer
# assigns the contributor to the issue, this workflow finds matching
# closed PRs, verifies the issue link, and reopens them.
#
# Uses the default GITHUB_TOKEN (not a PAT or app token) so that the
# reopen and label-removal events do NOT re-trigger other workflows.
# GitHub suppresses events created by the default GITHUB_TOKEN within
# workflow runs to prevent infinite loops.
name: Reopen PR on Issue Assignment
on:
issues:
types: [assigned]
permissions:
contents: read
jobs:
reopen-linked-prs:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Find and reopen matching PRs
uses: actions/github-script@v8
with:
script: |
const { owner, repo } = context.repo;
const issueNumber = context.payload.issue.number;
const assignee = context.payload.assignee.login;
console.log(
`Issue #${issueNumber} assigned to ${assignee} — searching for closed PRs to reopen`,
);
const q = [
`is:pr`,
`is:closed`,
`author:${assignee}`,
`label:missing-issue-link`,
`repo:${owner}/${repo}`,
].join(' ');
let data;
try {
({ data } = await github.rest.search.issuesAndPullRequests({
q,
per_page: 30,
}));
} catch (e) {
throw new Error(
`Failed to search for closed PRs to reopen after assigning ${assignee} ` +
`to #${issueNumber} (HTTP ${e.status ?? 'unknown'}): ${e.message}`,
);
}
if (data.total_count === 0) {
console.log('No matching closed PRs found');
return;
}
console.log(`Found ${data.total_count} candidate PR(s)`);
// Must stay in sync with the identical pattern in require_issue_link.yml
const pattern = /(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s*#(\d+)/gi;
for (const item of data.items) {
const prNumber = item.number;
const body = item.body || '';
const matches = [...body.matchAll(pattern)];
const referencedIssues = matches.map(m => parseInt(m[1], 10));
if (!referencedIssues.includes(issueNumber)) {
console.log(`PR #${prNumber} does not reference #${issueNumber} — skipping`);
continue;
}
// Skip if already bypassed
const labels = item.labels.map(l => l.name);
if (labels.includes('bypass-issue-check')) {
console.log(`PR #${prNumber} already has bypass-issue-check — skipping`);
continue;
}
// Reopen first, remove label second — a closed PR that still has
// missing-issue-link is recoverable; a closed PR with the label
// stripped is invisible to both workflows.
try {
await github.rest.pulls.update({
owner,
repo,
pull_number: prNumber,
state: 'open',
});
console.log(`Reopened PR #${prNumber}`);
} catch (e) {
if (e.status === 422) {
// Head branch deleted — PR is unrecoverable. Notify the
// contributor so they know to open a new PR.
core.warning(`Cannot reopen PR #${prNumber}: head branch was likely deleted`);
try {
await github.rest.issues.createComment({
owner,
repo,
issue_number: prNumber,
body:
`You have been assigned to #${issueNumber}, but this PR could not be ` +
`reopened because the head branch has been deleted. Please open a new ` +
`PR referencing the issue.`,
});
} catch (commentErr) {
core.warning(
`Also failed to post comment on PR #${prNumber}: ${commentErr.message}`,
);
}
continue;
}
// Transient errors (rate limit, 5xx) should fail the job so
// the label is NOT removed and the run can be retried.
throw e;
}
// Remove missing-issue-link label only after successful reopen
try {
await github.rest.issues.removeLabel({
owner,
repo,
issue_number: prNumber,
name: 'missing-issue-link',
});
console.log(`Removed missing-issue-link from PR #${prNumber}`);
} catch (e) {
if (e.status !== 404) throw e;
}
// Minimize stale enforcement comment (best-effort;
// sync w/ require_issue_link.yml minimize blocks)
try {
const marker = '<!-- require-issue-link -->';
const comments = await github.paginate(
github.rest.issues.listComments,
{ owner, repo, issue_number: prNumber, per_page: 100 },
);
const stale = comments.find(c => c.body && c.body.includes(marker));
if (stale) {
await github.graphql(`
mutation($id: ID!) {
minimizeComment(input: {subjectId: $id, classifier: OUTDATED}) {
minimizedComment { isMinimized }
}
}
`, { id: stale.node_id });
console.log(`Minimized stale enforcement comment ${stale.id} as outdated`);
}
} catch (e) {
core.warning(`Could not minimize stale comment on PR #${prNumber}: ${e.message}`);
}
}
+49 -1
View File
@@ -13,6 +13,8 @@ name: Require Issue Link
on:
pull_request_target:
# NEVER CHECK OUT UNTRUSTED CODE FROM A PR's HEAD IN A pull_request_target JOB.
# Doing so would allow attackers to execute arbitrary code in the context of your repository.
types: [edited, reopened, labeled, unlabeled]
# ──────────────────────────────────────────────────────────────────────────────
@@ -142,6 +144,29 @@ jobs:
// Add bypass-issue-check so future triggers skip enforcement
await ensureAndAddLabel('bypass-issue-check', '0e8a16');
// Minimize stale enforcement comment (best-effort; must not
// abort bypass — sync w/ reopen_on_assignment.yml & step below)
try {
const marker = '<!-- require-issue-link -->';
const comments = await github.paginate(
github.rest.issues.listComments,
{ owner, repo, issue_number: prNumber, per_page: 100 },
);
const stale = comments.find(c => c.body && c.body.includes(marker));
if (stale) {
await github.graphql(`
mutation($id: ID!) {
minimizeComment(input: {subjectId: $id, classifier: OUTDATED}) {
minimizedComment { isMinimized }
}
}
`, { id: stale.node_id });
console.log(`Minimized stale enforcement comment ${stale.id} as outdated`);
}
} catch (e) {
core.warning(`Could not minimize stale comment on PR #${prNumber}: ${e.message}`);
}
core.setOutput('has-link', 'true');
core.setOutput('is-assigned', 'true');
}
@@ -314,6 +339,29 @@ jobs:
console.log(`Reopened PR #${prNumber}`);
}
// Minimize stale enforcement comment (best-effort;
// sync w/ applyMaintainerBypass above & reopen_on_assignment.yml)
try {
const marker = '<!-- require-issue-link -->';
const comments = await github.paginate(
github.rest.issues.listComments,
{ owner, repo, issue_number: prNumber, per_page: 100 },
);
const stale = comments.find(c => c.body && c.body.includes(marker));
if (stale) {
await github.graphql(`
mutation($id: ID!) {
minimizeComment(input: {subjectId: $id, classifier: OUTDATED}) {
minimizedComment { isMinimized }
}
}
`, { id: stale.node_id });
console.log(`Minimized stale enforcement comment ${stale.id} as outdated`);
}
} catch (e) {
core.warning(`Could not minimize stale comment on PR #${prNumber}: ${e.message}`);
}
- name: Post comment, close PR, and fail
if: >-
env.ENFORCE_ISSUE_LINK == 'true' &&
@@ -347,7 +395,7 @@ jobs:
'',
'External contributors must be assigned to an issue before opening a PR for it. Please:',
'1. Comment on the linked issue to request assignment from a maintainer',
'2. Once assigned, edit your PR description and the PR will be reopened automatically',
'2. Once assigned, your PR will be reopened automatically',
'',
'*Maintainers: reopen this PR or remove the `missing-issue-link` label to bypass this check.*',
];
+6 -6
View File
@@ -231,7 +231,7 @@ wheels = [
[[package]]
name = "langchain-core"
version = "1.2.13"
version = "1.2.22"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "jsonpatch" },
@@ -243,9 +243,9 @@ dependencies = [
{ name = "typing-extensions" },
{ name = "uuid-utils" },
]
sdist = { url = "https://files.pythonhosted.org/packages/fb/bb/c501ca60556c11ac80d1454bdcac63cb33583ce4e64fc4535ad5a7d5c6ba/langchain_core-1.2.13.tar.gz", hash = "sha256:d2773d0d0130a356378db9a858cfeef64c3d64bc03722f1d4d6c40eb46fdf01b", size = 831612, upload-time = "2026-02-15T07:45:57.014Z" }
sdist = { url = "https://files.pythonhosted.org/packages/b1/a3/c4cd6827a1df46c821e7214b7f7b7a28b189e6c9b84ef15c6d629c5e3179/langchain_core-1.2.22.tar.gz", hash = "sha256:8d8f726d03d3652d403da915126626bb6250747e8ba406537d849e68b9f5d058", size = 842487, upload-time = "2026-03-24T18:48:44.9Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/12/ab/60fd69e5d55f67d422baefddaaca523c42cd7510ab6aeb17db6ae57fb107/langchain_core-1.2.13-py3-none-any.whl", hash = "sha256:b31823e28d3eff1e237096d0bd3bf80c6f9624eb471a9496dbfbd427779f8d82", size = 500485, upload-time = "2026-02-15T07:45:55.422Z" },
{ url = "https://files.pythonhosted.org/packages/c7/a6/2ffacf0f1a3788f250e75d0b52a24896c413be11be3a6d42bcdf46fbea48/langchain_core-1.2.22-py3-none-any.whl", hash = "sha256:7e30d586b75918e828833b9ec1efc25465723566845dd652c277baf751e9c04b", size = 506829, upload-time = "2026-03-24T18:48:43.286Z" },
]
[[package]]
@@ -614,11 +614,11 @@ wheels = [
[[package]]
name = "pygments"
version = "2.19.2"
version = "2.20.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" }
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" },
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
]
[[package]]
+6 -6
View File
@@ -240,7 +240,7 @@ wheels = [
[[package]]
name = "langchain-core"
version = "1.2.11"
version = "1.2.22"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "jsonpatch" },
@@ -252,9 +252,9 @@ dependencies = [
{ name = "typing-extensions" },
{ name = "uuid-utils" },
]
sdist = { url = "https://files.pythonhosted.org/packages/12/17/1943cedfc118e04b8128e4c3e1dbf0fa0ea58eefddbb6198cfd699d19f01/langchain_core-1.2.11.tar.gz", hash = "sha256:f164bb36602dd74a3a50c1334fca75309ad5ed95767acdfdbb9fa95ce28a1e01", size = 831211, upload-time = "2026-02-10T20:35:28.35Z" }
sdist = { url = "https://files.pythonhosted.org/packages/b1/a3/c4cd6827a1df46c821e7214b7f7b7a28b189e6c9b84ef15c6d629c5e3179/langchain_core-1.2.22.tar.gz", hash = "sha256:8d8f726d03d3652d403da915126626bb6250747e8ba406537d849e68b9f5d058", size = 842487, upload-time = "2026-03-24T18:48:44.9Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/10/30/1f80e3fc674353cad975ed5294353d42512535d2094ef032c06454c2c873/langchain_core-1.2.11-py3-none-any.whl", hash = "sha256:ae11ceb8dda60d0b9d09e763116e592f1683327c17be5b715f350fd29aee65d3", size = 500062, upload-time = "2026-02-10T20:35:26.698Z" },
{ url = "https://files.pythonhosted.org/packages/c7/a6/2ffacf0f1a3788f250e75d0b52a24896c413be11be3a6d42bcdf46fbea48/langchain_core-1.2.22-py3-none-any.whl", hash = "sha256:7e30d586b75918e828833b9ec1efc25465723566845dd652c277baf751e9c04b", size = 506829, upload-time = "2026-03-24T18:48:43.286Z" },
]
[[package]]
@@ -917,11 +917,11 @@ wheels = [
[[package]]
name = "pygments"
version = "2.19.2"
version = "2.20.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" }
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" },
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
]
[[package]]
+6 -6
View File
@@ -249,7 +249,7 @@ wheels = [
[[package]]
name = "langchain-core"
version = "1.2.11"
version = "1.2.22"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "jsonpatch" },
@@ -261,9 +261,9 @@ dependencies = [
{ name = "typing-extensions" },
{ name = "uuid-utils" },
]
sdist = { url = "https://files.pythonhosted.org/packages/12/17/1943cedfc118e04b8128e4c3e1dbf0fa0ea58eefddbb6198cfd699d19f01/langchain_core-1.2.11.tar.gz", hash = "sha256:f164bb36602dd74a3a50c1334fca75309ad5ed95767acdfdbb9fa95ce28a1e01", size = 831211, upload-time = "2026-02-10T20:35:28.35Z" }
sdist = { url = "https://files.pythonhosted.org/packages/b1/a3/c4cd6827a1df46c821e7214b7f7b7a28b189e6c9b84ef15c6d629c5e3179/langchain_core-1.2.22.tar.gz", hash = "sha256:8d8f726d03d3652d403da915126626bb6250747e8ba406537d849e68b9f5d058", size = 842487, upload-time = "2026-03-24T18:48:44.9Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/10/30/1f80e3fc674353cad975ed5294353d42512535d2094ef032c06454c2c873/langchain_core-1.2.11-py3-none-any.whl", hash = "sha256:ae11ceb8dda60d0b9d09e763116e592f1683327c17be5b715f350fd29aee65d3", size = 500062, upload-time = "2026-02-10T20:35:26.698Z" },
{ url = "https://files.pythonhosted.org/packages/c7/a6/2ffacf0f1a3788f250e75d0b52a24896c413be11be3a6d42bcdf46fbea48/langchain_core-1.2.22-py3-none-any.whl", hash = "sha256:7e30d586b75918e828833b9ec1efc25465723566845dd652c277baf751e9c04b", size = 506829, upload-time = "2026-03-24T18:48:43.286Z" },
]
[[package]]
@@ -829,11 +829,11 @@ wheels = [
[[package]]
name = "pygments"
version = "2.19.2"
version = "2.20.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" }
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" },
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
]
[[package]]
+3 -3
View File
@@ -1084,11 +1084,11 @@ wheels = [
[[package]]
name = "pygments"
version = "2.19.2"
version = "2.20.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" }
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" },
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
]
[[package]]
+3 -3
View File
@@ -21,7 +21,7 @@
"test:all": "yarn test && yarn test:int && yarn lint:langgraph"
},
"dependencies": {
"@langchain/core": "^1.1.35",
"@langchain/core": "^1.1.36",
"@langchain/langgraph": "^1.2.5"
},
"devDependencies": {
@@ -29,8 +29,8 @@
"@eslint/js": "^10.0.1",
"@tsconfig/recommended": "^1.0.13",
"@types/jest": "^30.0.0",
"@typescript-eslint/eslint-plugin": "^8.57.1",
"@typescript-eslint/parser": "^8.57.1",
"@typescript-eslint/eslint-plugin": "^8.57.2",
"@typescript-eslint/parser": "^8.57.2",
"dotenv": "^17.3.1",
"eslint": "^10.1.0",
"eslint-config-prettier": "^10.1.8",
+70 -70
View File
@@ -890,10 +890,10 @@
"@jridgewell/resolve-uri" "^3.1.0"
"@jridgewell/sourcemap-codec" "^1.4.14"
"@langchain/core@^1.1.35":
version "1.1.35"
resolved "https://registry.yarnpkg.com/@langchain/core/-/core-1.1.35.tgz#4c681cc9af3d59d139f6272768dd30361dccd518"
integrity sha512-TM0idLSAx17IEMqEIN7F8MDdXpN53p4A4vhhjZxf7LedwShB/8Zx1F5D5Nq1Bbn0zh9QDzSHpWyfCrTtggKf7g==
"@langchain/core@^1.1.36":
version "1.1.36"
resolved "https://registry.yarnpkg.com/@langchain/core/-/core-1.1.36.tgz#672d758e50e09fe402db2919ceb98b82cbca901b"
integrity sha512-9NWsdzU3uZD13lJwunXK0t6SIwew+UwcbHggW5yUdaiMmzKeNkDpp1lRD6p49N8+D0Vv4qmQBEKB4Ukh2jfnvw==
dependencies:
"@cfworker/json-schema" "^4.0.2"
"@standard-schema/spec" "^1.1.0"
@@ -1103,100 +1103,100 @@
dependencies:
"@types/yargs-parser" "*"
"@typescript-eslint/eslint-plugin@^8.57.1":
version "8.57.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.1.tgz#ddfdfb30f8b5ccee7f3c21798b377c51370edd55"
integrity sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==
"@typescript-eslint/eslint-plugin@^8.57.2":
version "8.57.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.2.tgz#ad0dcefeca9c2ecbe09f730d478063666aee010b"
integrity sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w==
dependencies:
"@eslint-community/regexpp" "^4.12.2"
"@typescript-eslint/scope-manager" "8.57.1"
"@typescript-eslint/type-utils" "8.57.1"
"@typescript-eslint/utils" "8.57.1"
"@typescript-eslint/visitor-keys" "8.57.1"
"@typescript-eslint/scope-manager" "8.57.2"
"@typescript-eslint/type-utils" "8.57.2"
"@typescript-eslint/utils" "8.57.2"
"@typescript-eslint/visitor-keys" "8.57.2"
ignore "^7.0.5"
natural-compare "^1.4.0"
ts-api-utils "^2.4.0"
"@typescript-eslint/parser@^8.57.1":
version "8.57.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.57.1.tgz#d523e559b148264055c0a49a29d5f50c7de659c2"
integrity sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==
"@typescript-eslint/parser@^8.57.2":
version "8.57.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.57.2.tgz#b819955e39f976c0d4f95b5ed67fe22f85cd6898"
integrity sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==
dependencies:
"@typescript-eslint/scope-manager" "8.57.1"
"@typescript-eslint/types" "8.57.1"
"@typescript-eslint/typescript-estree" "8.57.1"
"@typescript-eslint/visitor-keys" "8.57.1"
"@typescript-eslint/scope-manager" "8.57.2"
"@typescript-eslint/types" "8.57.2"
"@typescript-eslint/typescript-estree" "8.57.2"
"@typescript-eslint/visitor-keys" "8.57.2"
debug "^4.4.3"
"@typescript-eslint/project-service@8.57.1":
version "8.57.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.57.1.tgz#16af9fe16eedbd7085e4fdc29baa73715c0c55c5"
integrity sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==
"@typescript-eslint/project-service@8.57.2":
version "8.57.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.57.2.tgz#dfbc7777f9f633f2b06b558cda3836e76f856e3c"
integrity sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw==
dependencies:
"@typescript-eslint/tsconfig-utils" "^8.57.1"
"@typescript-eslint/types" "^8.57.1"
"@typescript-eslint/tsconfig-utils" "^8.57.2"
"@typescript-eslint/types" "^8.57.2"
debug "^4.4.3"
"@typescript-eslint/scope-manager@8.57.1":
version "8.57.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.57.1.tgz#4524d7e7b420cb501807499684d435ae129aaf35"
integrity sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==
"@typescript-eslint/scope-manager@8.57.2":
version "8.57.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.57.2.tgz#734dcde40677f430b5d963108337295bdbc09dae"
integrity sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw==
dependencies:
"@typescript-eslint/types" "8.57.1"
"@typescript-eslint/visitor-keys" "8.57.1"
"@typescript-eslint/types" "8.57.2"
"@typescript-eslint/visitor-keys" "8.57.2"
"@typescript-eslint/tsconfig-utils@8.57.1", "@typescript-eslint/tsconfig-utils@^8.57.1":
version "8.57.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.1.tgz#9233443ec716882a6f9e240fd900a73f0235f3d7"
integrity sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==
"@typescript-eslint/tsconfig-utils@8.57.2", "@typescript-eslint/tsconfig-utils@^8.57.2":
version "8.57.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.2.tgz#cf82dc11e884103ec13188a7352591efaa1a887e"
integrity sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw==
"@typescript-eslint/type-utils@8.57.1":
version "8.57.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.57.1.tgz#c49af1347b5869ca85155547a8f34f84ab386fd9"
integrity sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==
"@typescript-eslint/type-utils@8.57.2":
version "8.57.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.57.2.tgz#3ec65a94e73776252991a3cf0a15d220734c28f5"
integrity sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg==
dependencies:
"@typescript-eslint/types" "8.57.1"
"@typescript-eslint/typescript-estree" "8.57.1"
"@typescript-eslint/utils" "8.57.1"
"@typescript-eslint/types" "8.57.2"
"@typescript-eslint/typescript-estree" "8.57.2"
"@typescript-eslint/utils" "8.57.2"
debug "^4.4.3"
ts-api-utils "^2.4.0"
"@typescript-eslint/types@8.57.1", "@typescript-eslint/types@^8.57.1":
version "8.57.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.57.1.tgz#54b27a8a25a7b45b4f978c3f8e00c4c78f11142c"
integrity sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==
"@typescript-eslint/types@8.57.2", "@typescript-eslint/types@^8.57.2":
version "8.57.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.57.2.tgz#efe0da4c28b505ed458f113aa960dce2c5c671f4"
integrity sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==
"@typescript-eslint/typescript-estree@8.57.1":
version "8.57.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.1.tgz#a9fd28d4a0ec896aa9a9a7e0cead62ea24f99e76"
integrity sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==
"@typescript-eslint/typescript-estree@8.57.2":
version "8.57.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.2.tgz#432e61a6cf2ab565837da387e5262c159672abea"
integrity sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA==
dependencies:
"@typescript-eslint/project-service" "8.57.1"
"@typescript-eslint/tsconfig-utils" "8.57.1"
"@typescript-eslint/types" "8.57.1"
"@typescript-eslint/visitor-keys" "8.57.1"
"@typescript-eslint/project-service" "8.57.2"
"@typescript-eslint/tsconfig-utils" "8.57.2"
"@typescript-eslint/types" "8.57.2"
"@typescript-eslint/visitor-keys" "8.57.2"
debug "^4.4.3"
minimatch "^10.2.2"
semver "^7.7.3"
tinyglobby "^0.2.15"
ts-api-utils "^2.4.0"
"@typescript-eslint/utils@8.57.1":
version "8.57.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.57.1.tgz#e40f5a7fcff02fd24092a7b52bd6ec029fb50465"
integrity sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==
"@typescript-eslint/utils@8.57.2":
version "8.57.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.57.2.tgz#46a8974c24326fb8899486728428a0f1a3115014"
integrity sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg==
dependencies:
"@eslint-community/eslint-utils" "^4.9.1"
"@typescript-eslint/scope-manager" "8.57.1"
"@typescript-eslint/types" "8.57.1"
"@typescript-eslint/typescript-estree" "8.57.1"
"@typescript-eslint/scope-manager" "8.57.2"
"@typescript-eslint/types" "8.57.2"
"@typescript-eslint/typescript-estree" "8.57.2"
"@typescript-eslint/visitor-keys@8.57.1":
version "8.57.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.1.tgz#3af4f88118924d3be983d4b8ae84803f11fe4563"
integrity sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==
"@typescript-eslint/visitor-keys@8.57.2":
version "8.57.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.2.tgz#a5c9605774247336c0412beb7dc288ab2a07c11e"
integrity sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw==
dependencies:
"@typescript-eslint/types" "8.57.1"
"@typescript-eslint/types" "8.57.2"
eslint-visitor-keys "^5.0.0"
"@ungap/structured-clone@^1.3.0":
@@ -2696,9 +2696,9 @@ graceful-fs@^4.2.11:
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
handlebars@^4.7.8:
version "4.7.8"
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9"
integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==
version "4.7.9"
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.9.tgz#6f139082ab58dc4e5a0e51efe7db5ae890d56a0f"
integrity sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==
dependencies:
minimist "^1.2.5"
neo-async "^2.6.2"
+3 -3
View File
@@ -1586,9 +1586,9 @@ path-parse@^1.0.7:
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
picomatch@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.3.tgz#796c76136d1eead715db1e7bad785dedd695a042"
integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==
version "4.0.4"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.4.tgz#fd6f5e00a143086e074dffe4c924b8fb293b0589"
integrity sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==
possible-typed-array-names@^1.0.0:
version "1.1.0"
+161
View File
@@ -0,0 +1,161 @@
"""Create a tarball of project source for remote builds."""
import os
import pathlib
import tarfile
import tempfile
from contextlib import contextmanager
import click
import pathspec
from langgraph_cli.config import Config, _assemble_local_deps
_WARN_SIZE = 50 * 1024 * 1024 # 50 MB
_MAX_SIZE = 200 * 1024 * 1024 # 200 MB
_ALWAYS_EXCLUDE = [
"__pycache__/",
".git/",
".venv/",
"venv/",
"node_modules/",
".tox/",
".mypy_cache/",
]
def _build_ignore_spec(directory: pathlib.Path) -> pathspec.PathSpec:
"""Build a PathSpec combining built-in exclusions with .dockerignore and .gitignore.
Always excludes common non-source directories (_ALWAYS_EXCLUDE). On top of
that, patterns from .dockerignore and .gitignore (if present) are merged in.
"""
lines: list[str] = list(_ALWAYS_EXCLUDE)
for name in (".dockerignore", ".gitignore"):
ignore_file = directory / name
if ignore_file.is_file():
lines.extend(ignore_file.read_text(encoding="utf-8").splitlines())
return pathspec.PathSpec.from_lines("gitwildmatch", lines)
def _tar_filter(tarinfo: tarfile.TarInfo) -> tarfile.TarInfo | None:
"""Strip symlinks, hardlinks, and traversal paths from archive."""
if tarinfo.issym() or tarinfo.islnk():
return None
if ".." in tarinfo.name.split("/"):
return None
return tarinfo
def _add_directory(
tar: tarfile.TarFile,
source_dir: pathlib.Path,
arcname_prefix: str | None,
ignore_spec: pathspec.PathSpec,
) -> None:
"""Recursively add a directory to the tarball under the given prefix.
If arcname_prefix is None, files are added at the archive root.
Paths matching ignore_spec are excluded.
"""
for root, dirs, files in os.walk(source_dir):
rel_root = os.path.relpath(root, source_dir).replace(os.sep, "/")
dirs[:] = [
d
for d in dirs
if not ignore_spec.match_file(
f"{rel_root}/{d}/" if rel_root != "." else f"{d}/"
)
]
for f in files:
full_path = os.path.join(root, f)
rel = os.path.relpath(full_path, source_dir).replace(os.sep, "/")
if ignore_spec.match_file(rel):
continue
arcname = f"{arcname_prefix}/{rel}" if arcname_prefix else rel
info = tar.gettarinfo(full_path, arcname=arcname)
filtered = _tar_filter(info)
if filtered is None:
continue
with open(full_path, "rb") as fobj:
tar.addfile(filtered, fobj)
@contextmanager
def create_archive(
config_path: pathlib.Path,
config: Config,
):
"""Context manager that creates a .tar.gz archive of the project source.
Uses _assemble_local_deps to discover local dependencies referenced in
langgraph.json, including those outside config.parent (monorepo case).
The archive preserves the real filesystem layout relative to the common
ancestor of config.parent and all external dependency directories, so that
relative references (e.g. `../shared-lib`) resolve correctly after
extraction.
Yields (archive_path, file_size, config_relative_path). The temporary
directory holding the archive is cleaned up automatically on exit.
"""
config_path = config_path.resolve()
context_dir = config_path.parent
local_deps = _assemble_local_deps(config_path, config)
extra_contexts = local_deps.additional_contexts or []
dirs_to_include = [context_dir] + list(extra_contexts)
common = context_dir
for d in extra_contexts:
common = pathlib.Path(os.path.commonpath([common, d]))
tmp_dir = tempfile.mkdtemp(prefix="langgraph-deploy-")
try:
archive_path = os.path.join(tmp_dir, "source.tar.gz")
added_dirs: set[str] = set()
with tarfile.open(archive_path, "w:gz") as tar:
for dir_path in dirs_to_include:
rel = dir_path.relative_to(common)
prefix = str(rel).replace(os.sep, "/") if str(rel) != "." else None
key = prefix or ""
if key in added_dirs:
continue
added_dirs.add(key)
ignore_spec = _build_ignore_spec(dir_path)
_add_directory(
tar, dir_path, arcname_prefix=prefix, ignore_spec=ignore_spec
)
file_size = os.path.getsize(archive_path)
config_rel = str(config_path.relative_to(common)).replace(os.sep, "/")
with tarfile.open(archive_path, "r:gz") as tar:
names = tar.getnames()
if config_rel not in names:
raise click.ClickException(
f"Archive validation failed: {config_rel} not found in archive"
)
if file_size > _MAX_SIZE:
raise click.ClickException(
f"Source archive is {file_size / 1_048_576:.1f} MB, which exceeds the 200 MB limit. "
"Add large files to .dockerignore or .gitignore (model weights, data sets, etc.)."
)
if file_size > _WARN_SIZE:
click.secho(
f" Warning: source archive is {file_size / 1_048_576:.1f} MB. "
"Consider adding large files to .dockerignore or .gitignore.",
fg="yellow",
)
yield archive_path, file_size, config_rel
finally:
import shutil
shutil.rmtree(tmp_dir, ignore_errors=True)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+128
View File
@@ -1,10 +1,14 @@
import copy
import json
import pathlib
import platform
import shutil
from collections.abc import Callable, Sequence
from typing import Literal, NamedTuple
import click.exceptions
import langgraph_cli.config
from langgraph_cli.exec import subp_exec
ROOT = pathlib.Path(__file__).parent.resolve()
@@ -45,6 +49,54 @@ def _parse_version(version: str) -> Version:
)
def can_build_locally() -> tuple[bool, str | None]:
"""Return whether local deployment builds can run on this machine.
Checks:
- Docker binary is installed
- Docker daemon is running
- Buildx is available when cross-compilation is required (non-x86_64)
"""
if shutil.which("docker") is None:
return (
False,
"Docker is required but not installed.\n"
"Install Docker Desktop: https://docs.docker.com/get-docker/",
)
try:
import subprocess
docker_info = subprocess.run(
["docker", "info"],
capture_output=True,
timeout=10,
)
if docker_info.returncode != 0:
return (
False,
"Docker is installed but not running.\nStart Docker and try again.",
)
if platform.machine() != "x86_64":
buildx = subprocess.run(
["docker", "buildx", "version"],
capture_output=True,
timeout=10,
)
if buildx.returncode != 0:
return (
False,
"Docker Buildx is required but not installed.\n"
"Your machine architecture ("
+ platform.machine()
+ ") requires Buildx to cross-compile images for linux/amd64.\n"
"Install Buildx: https://docs.docker.com/build/install-buildx/",
)
return True, None
except Exception:
return False, "Unable to verify local Docker build support."
def check_capabilities(runner) -> DockerCapabilities:
# check docker available
if shutil.which("docker") is None:
@@ -276,3 +328,79 @@ def compose(
)
compose_str = dict_to_yaml(compose_content)
return compose_str
def build_docker_image(
runner,
set: Callable[[str], None],
config: pathlib.Path,
config_json: dict,
base_image: str | None,
api_version: str | None,
pull: bool,
tag: str,
passthrough: Sequence[str] = (),
install_command: str | None = None,
build_command: str | None = None,
docker_command: Sequence[str] | None = None,
extra_flags: Sequence[str] = (),
verbose: bool = True,
):
"""Build a Docker image from a LangGraph config."""
# pull latest images
if pull:
runner.run(
subp_exec(
"docker",
"pull",
langgraph_cli.config.docker_tag(config_json, base_image, api_version),
verbose=verbose,
)
)
set("Building...")
# apply options
args = [
"-f",
"-", # stdin
"-t",
tag,
]
# determine build context: use current directory for JS projects, config parent for Python
is_js_project = config_json.get("node_version") and not config_json.get(
"python_version"
)
# build/install commands only apply to JS projects for now
# without install/build command, JS projects will follow the old behavior
if is_js_project and (build_command or install_command):
build_context = str(pathlib.Path.cwd())
else:
build_context = str(config.parent)
# Deep copy to avoid mutating the caller's config (config_to_docker
# rewrites graph paths to container-internal paths in place).
config_json = copy.deepcopy(config_json)
stdin, additional_contexts = langgraph_cli.config.config_to_docker(
config_path=config,
config=config_json,
base_image=base_image,
api_version=api_version,
install_command=install_command,
build_command=build_command,
build_context=build_context,
)
# add additional_contexts
if additional_contexts:
for k, v in additional_contexts.items():
args.extend(["--build-context", f"{k}={v}"])
cmd = tuple(docker_command) if docker_command else ("docker", "build")
runner.run(
subp_exec(
*cmd,
*args,
*extra_flags,
*passthrough,
build_context,
input=stdin,
verbose=verbose,
)
)
-59
View File
@@ -1,59 +0,0 @@
"""Helpers for the ``langgraph logs`` CLI command."""
from __future__ import annotations
from datetime import datetime, timezone
import click
from langgraph_cli.host_backend import HostBackendClient
def resolve_deployment_id(
client: HostBackendClient,
deployment_id: str | None,
name: str | None,
) -> str:
"""Resolve a deployment ID from --deployment-id or --name."""
if deployment_id:
return deployment_id
if not name:
raise click.UsageError("Either --deployment-id or --name is required.")
existing = client.list_deployments(name_contains=name)
if isinstance(existing, dict):
for dep in existing.get("resources", []):
if isinstance(dep, dict) and dep.get("name") == name:
found_id = dep.get("id")
if found_id:
return str(found_id)
raise click.ClickException(f"Deployment '{name}' not found.")
def format_timestamp(ts) -> str:
"""Convert a timestamp (epoch ms or string) to a readable string."""
if isinstance(ts, (int, float)):
dt = datetime.fromtimestamp(ts / 1000, tz=timezone.utc)
return dt.strftime("%Y-%m-%d %H:%M:%S")
return str(ts) if ts else ""
def format_log_entry(entry: dict) -> str:
"""Format a single log entry for display."""
ts = format_timestamp(entry.get("timestamp", ""))
level = entry.get("level", "")
message = entry.get("message", "")
if ts and level:
return f"[{ts}] [{level}] {message}"
elif ts:
return f"[{ts}] {message}"
return message
def level_fg(level: str) -> str | None:
"""Return click color for a log level."""
level_upper = level.upper() if level else ""
if level_upper in {"ERROR", "CRITICAL"}:
return "red"
if level_upper == "WARNING":
return "yellow"
return None
+57 -1
View File
@@ -70,7 +70,25 @@ class HostBackendClient:
f"Failed to decode response from {path}: {err}"
) from None
def create_deployment(self, payload: dict[str, Any]) -> dict[str, Any]:
def create_deployment(
self,
name: str,
deployment_type: str,
source: str,
config_path: str | None = None,
secrets: list[dict[str, str]] | None = None,
) -> dict[str, Any]:
"""Create a deployment."""
payload: dict[str, Any] = {
"name": name,
"source": source,
"source_config": {"deployment_type": deployment_type},
"source_revision_config": {},
}
if source == "internal_source" and config_path:
payload["source_revision_config"]["langgraph_config_path"] = config_path
if secrets is not None:
payload["secrets"] = secrets
return self._request("POST", "/v2/deployments", payload)
def list_deployments(self, name_contains: str = "") -> dict[str, Any]:
@@ -92,6 +110,13 @@ class HostBackendClient:
f"/v2/deployments/{deployment_id}/push-token",
)
def request_upload_url(self, deployment_id: str) -> dict[str, Any]:
"""Get a signed GCS URL for uploading the source tarball."""
return self._request(
"POST",
f"/v2/deployments/{deployment_id}/upload-url",
)
def update_deployment(
self,
deployment_id: str,
@@ -99,6 +124,7 @@ class HostBackendClient:
secrets: list[dict[str, str]] | None = None,
) -> dict[str, Any]:
payload: dict[str, Any] = {
"revision_source": "internal_docker",
"source_revision_config": {"image_uri": image_uri},
}
if secrets is not None:
@@ -109,6 +135,36 @@ class HostBackendClient:
payload,
)
def update_deployment_internal_source(
self,
deployment_id: str,
source_tarball_path: str,
config_path: str,
secrets: list[dict[str, str]] | None = None,
install_command: str | None = None,
build_command: str | None = None,
) -> dict[str, Any]:
"""Trigger a remote build revision with the uploaded tarball."""
payload: dict[str, Any] = {
"revision_source": "internal_source",
"source_revision_config": {
"source_tarball_path": source_tarball_path,
"langgraph_config_path": config_path,
},
}
source_config: dict[str, Any] = {}
if install_command is not None:
source_config["install_command"] = install_command
if build_command is not None:
source_config["build_command"] = build_command
if source_config:
payload["source_config"] = source_config
if secrets is not None:
payload["secrets"] = secrets
return self._request("PATCH", f"/v2/deployments/{deployment_id}", payload)
def list_revisions(self, deployment_id: str, limit: int = 1) -> dict[str, Any]:
return self._request(
"GET",
+9
View File
@@ -18,6 +18,9 @@ class Progress:
self._show_elapsed = elapsed
# use this to make sure we don't kill thread when we set msg to ""
self._stop = threading.Event()
# signalled when the spinner has no text on screen
self._line_clear = threading.Event()
self._line_clear.set()
self.spinner_generator = self.spinning_cursor()
def spinner_iteration(self):
@@ -43,13 +46,16 @@ class Progress:
start = time.monotonic()
while not self._stop.is_set():
if not self.message:
self._line_clear.set()
time.sleep(self.delay)
continue
if self._show_elapsed:
self.message = self._format_elapsed(time.monotonic() - start)
message = self.message
if not message:
self._line_clear.set()
continue
self._line_clear.clear()
sys.stdout.write(next(self.spinner_generator) + " " + message)
sys.stdout.flush()
time.sleep(self.delay)
@@ -60,6 +66,7 @@ class Progress:
+ "\b" * (len(message) + 2)
)
sys.stdout.flush()
self._line_clear.set()
def __enter__(self) -> Callable[[str], None]:
if sys.stdout.isatty():
@@ -69,6 +76,8 @@ class Progress:
def set_message(message):
self.message = message
self._base_message = message or self._base_message
if not message:
self._line_clear.wait(timeout=0.5)
return set_message
else:
+1 -65
View File
@@ -1,4 +1,4 @@
from collections.abc import Sequence
"""General-purpose utilities shared across the LangGraph CLI."""
import click
@@ -25,67 +25,3 @@ def warn_non_wolfi_distro(config_json: dict) -> None:
fg="yellow",
)
click.secho("") # Empty line for better readability
def _extract_deployment_url(deployment: dict[str, object]) -> str:
source_config = deployment.get("source_config")
if isinstance(source_config, dict):
custom_url = source_config.get("custom_url")
if isinstance(custom_url, str) and custom_url:
return custom_url
return "-"
def format_deployments_table(deployments: Sequence[dict[str, object]]) -> str:
headers = ("Deployment ID", "Deployment Name", "Deployment URL")
rows = [
(
str(deployment.get("id", "-") or "-"),
str(deployment.get("name", "-") or "-"),
_extract_deployment_url(deployment),
)
for deployment in deployments
]
widths = [
max(len(headers[index]), *(len(row[index]) for row in rows))
for index in range(len(headers))
]
def format_row(row: Sequence[str]) -> str:
return " ".join(value.ljust(widths[index]) for index, value in enumerate(row))
lines = [format_row(headers), format_row(tuple("-" * width for width in widths))]
lines.extend(format_row(row) for row in rows)
return "\n".join(lines)
def format_revisions_table(revisions: Sequence[dict[str, object]]) -> str:
headers = ("Revision ID", "Status", "Created At")
latest_deployed_seen = False
rows = []
for revision in revisions:
status = str(revision.get("status", "-") or "-")
if status == "DEPLOYED":
if latest_deployed_seen:
status = "REPLACED"
else:
latest_deployed_seen = True
rows.append(
(
str(revision.get("id", "-") or "-"),
status,
str(revision.get("created_at", "-") or "-"),
)
)
widths = [
max(len(headers[index]), *(len(row[index]) for row in rows))
for index in range(len(headers))
]
def format_row(row: Sequence[str]) -> str:
return " ".join(value.ljust(widths[index]) for index, value in enumerate(row))
lines = [format_row(headers), format_row(tuple("-" * width for width in widths))]
lines.extend(format_row(row) for row in rows)
return "\n".join(lines)
+1
View File
@@ -15,6 +15,7 @@ dependencies = [
"click>=8.1.7",
"httpx>=0.24.0",
"langgraph-sdk>=0.1.0 ; python_version >= '3.11'",
"pathspec>=0.11.0",
"python-dotenv>=0.8.0",
]
[tool.hatch.version]
+9 -9
View File
@@ -9,7 +9,7 @@ from pathlib import Path
from click.testing import CliRunner
import langgraph_cli.cli as cli_module
import langgraph_cli.deploy as deploy_module
from langgraph_cli.cli import cli, prepare_args_and_stdin
from langgraph_cli.config import Config, _get_pip_cleanup_lines, validate_config
from langgraph_cli.docker import DEFAULT_POSTGRES_URI, DockerCapabilities, Version
@@ -346,7 +346,7 @@ def test_deploy_list_command(monkeypatch) -> None:
]
}
monkeypatch.setattr(cli_module, "HostBackendClient", FakeClient)
monkeypatch.setattr(deploy_module, "HostBackendClient", FakeClient)
result = runner.invoke(
cli,
@@ -386,7 +386,7 @@ def test_deploy_list_command_no_results(monkeypatch) -> None:
def list_deployments(self, name_contains: str = ""):
return {"resources": []}
monkeypatch.setattr(cli_module, "HostBackendClient", FakeClient)
monkeypatch.setattr(deploy_module, "HostBackendClient", FakeClient)
result = runner.invoke(
cli,
@@ -432,7 +432,7 @@ def test_deploy_revisions_list_command(monkeypatch) -> None:
]
}
monkeypatch.setattr(cli_module, "HostBackendClient", FakeClient)
monkeypatch.setattr(deploy_module, "HostBackendClient", FakeClient)
result = runner.invoke(
cli,
@@ -473,7 +473,7 @@ def test_deploy_revisions_list_command_no_results(monkeypatch) -> None:
def list_revisions(self, deployment_id: str, limit: int = 1):
return {"resources": []}
monkeypatch.setattr(cli_module, "HostBackendClient", FakeClient)
monkeypatch.setattr(deploy_module, "HostBackendClient", FakeClient)
result = runner.invoke(
cli,
@@ -506,7 +506,7 @@ def test_deploy_revisions_list_command_with_explicit_limit(monkeypatch) -> None:
captured["limit"] = str(limit)
return {"resources": []}
monkeypatch.setattr(cli_module, "HostBackendClient", FakeClient)
monkeypatch.setattr(deploy_module, "HostBackendClient", FakeClient)
result = runner.invoke(
cli,
@@ -552,7 +552,7 @@ def test_deploy_delete_command(monkeypatch) -> None:
captured["deployment_id"] = deployment_id
return None
monkeypatch.setattr(cli_module, "HostBackendClient", FakeClient)
monkeypatch.setattr(deploy_module, "HostBackendClient", FakeClient)
result = runner.invoke(
cli,
@@ -594,7 +594,7 @@ def test_deploy_delete_command_cancelled(monkeypatch) -> None:
deleted = True
return None
monkeypatch.setattr(cli_module, "HostBackendClient", FakeClient)
monkeypatch.setattr(deploy_module, "HostBackendClient", FakeClient)
result = runner.invoke(
cli,
@@ -629,7 +629,7 @@ def test_deploy_delete_command_force(monkeypatch) -> None:
captured["deployment_id"] = deployment_id
return None
monkeypatch.setattr(cli_module, "HostBackendClient", FakeClient)
monkeypatch.setattr(deploy_module, "HostBackendClient", FakeClient)
result = runner.invoke(
cli,
+299
View File
@@ -0,0 +1,299 @@
import os
import tarfile
from unittest.mock import patch
import click
import pytest
from langgraph_cli.archive import (
_add_directory,
_build_ignore_spec,
_tar_filter,
create_archive,
)
# ---------------------------------------------------------------------------
# _tar_filter
# ---------------------------------------------------------------------------
class TestTarFilter:
def _make_info(self, name: str, *, type_: int = tarfile.REGTYPE) -> tarfile.TarInfo:
info = tarfile.TarInfo(name=name)
info.type = type_
return info
def test_regular_file_passes(self):
info = self._make_info("src/main.py")
assert _tar_filter(info) is info
def test_symlink_rejected(self):
info = self._make_info("link", type_=tarfile.SYMTYPE)
assert _tar_filter(info) is None
def test_hardlink_rejected(self):
info = self._make_info("link", type_=tarfile.LNKTYPE)
assert _tar_filter(info) is None
def test_path_traversal_rejected(self):
info = self._make_info("../../etc/passwd")
assert _tar_filter(info) is None
def test_path_traversal_in_middle_rejected(self):
info = self._make_info("src/../../../etc/passwd")
assert _tar_filter(info) is None
def test_dotdot_as_name_component_rejected(self):
info = self._make_info("foo/../bar")
assert _tar_filter(info) is None
def test_dotdot_in_filename_allowed(self):
"""A file literally named 'foo..bar' is not traversal."""
info = self._make_info("foo..bar")
assert _tar_filter(info) is info
def test_directory_passes(self):
info = self._make_info("src/", type_=tarfile.DIRTYPE)
assert _tar_filter(info) is info
# ---------------------------------------------------------------------------
# _build_ignore_spec
# ---------------------------------------------------------------------------
class TestBuildIgnoreSpec:
def test_always_excludes_builtins(self, tmp_path):
spec = _build_ignore_spec(tmp_path)
assert spec.match_file("__pycache__/")
assert spec.match_file(".git/")
assert spec.match_file(".venv/")
assert spec.match_file("venv/")
assert spec.match_file("node_modules/")
assert spec.match_file(".tox/")
assert spec.match_file(".mypy_cache/")
def test_regular_file_not_excluded(self, tmp_path):
spec = _build_ignore_spec(tmp_path)
assert not spec.match_file("main.py")
assert not spec.match_file("src/app.py")
def test_merges_dockerignore(self, tmp_path):
(tmp_path / ".dockerignore").write_text("*.log\nbuild/\n")
spec = _build_ignore_spec(tmp_path)
assert spec.match_file("server.log")
assert spec.match_file("build/")
# builtins still present
assert spec.match_file("__pycache__/")
def test_merges_gitignore(self, tmp_path):
(tmp_path / ".gitignore").write_text("*.pyc\ndist/\n")
spec = _build_ignore_spec(tmp_path)
assert spec.match_file("module.pyc")
assert spec.match_file("dist/")
def test_merges_both_ignore_files(self, tmp_path):
(tmp_path / ".dockerignore").write_text("*.log\n")
(tmp_path / ".gitignore").write_text("*.pyc\n")
spec = _build_ignore_spec(tmp_path)
assert spec.match_file("app.log")
assert spec.match_file("mod.pyc")
def test_no_ignore_files_only_builtins(self, tmp_path):
spec = _build_ignore_spec(tmp_path)
assert spec.match_file("__pycache__/")
assert not spec.match_file("README.md")
# ---------------------------------------------------------------------------
# _add_directory
# ---------------------------------------------------------------------------
class TestAddDirectory:
def _create_project(self, tmp_path):
"""Create a small project structure for testing."""
(tmp_path / "main.py").write_text("print('hello')")
(tmp_path / "lib").mkdir()
(tmp_path / "lib" / "util.py").write_text("x = 1")
(tmp_path / "__pycache__").mkdir()
(tmp_path / "__pycache__" / "main.cpython-311.pyc").write_bytes(b"\x00")
return tmp_path
def test_adds_files_without_prefix(self, tmp_path):
project = self._create_project(tmp_path)
spec = _build_ignore_spec(project)
archive_path = tmp_path / "out.tar"
with tarfile.open(archive_path, "w") as tar:
_add_directory(tar, project, arcname_prefix=None, ignore_spec=spec)
with tarfile.open(archive_path, "r") as tar:
names = tar.getnames()
assert "main.py" in names
assert "lib/util.py" in names
def test_excludes_pycache(self, tmp_path):
project = self._create_project(tmp_path)
spec = _build_ignore_spec(project)
archive_path = tmp_path / "out.tar"
with tarfile.open(archive_path, "w") as tar:
_add_directory(tar, project, arcname_prefix=None, ignore_spec=spec)
with tarfile.open(archive_path, "r") as tar:
names = tar.getnames()
assert not any("__pycache__" in n for n in names)
def test_adds_files_with_prefix(self, tmp_path):
project = self._create_project(tmp_path)
spec = _build_ignore_spec(project)
archive_path = tmp_path / "out.tar"
with tarfile.open(archive_path, "w") as tar:
_add_directory(tar, project, arcname_prefix="myapp", ignore_spec=spec)
with tarfile.open(archive_path, "r") as tar:
names = tar.getnames()
assert "myapp/main.py" in names
assert "myapp/lib/util.py" in names
def test_respects_custom_ignore_patterns(self, tmp_path):
project = self._create_project(tmp_path)
(project / ".gitignore").write_text("lib/\n")
spec = _build_ignore_spec(project)
archive_path = tmp_path / "out.tar"
with tarfile.open(archive_path, "w") as tar:
_add_directory(tar, project, arcname_prefix=None, ignore_spec=spec)
with tarfile.open(archive_path, "r") as tar:
names = tar.getnames()
assert "main.py" in names
assert "lib/util.py" not in names
# ---------------------------------------------------------------------------
# create_archive (integration)
# ---------------------------------------------------------------------------
class TestCreateArchive:
def _make_project(self, tmp_path):
"""Set up a minimal project directory with a config file."""
project = tmp_path / "myproject"
project.mkdir()
config_file = project / "langgraph.json"
config_file.write_text('{"dependencies": ["."]}')
(project / "app.py").write_text("print('hello')")
(project / "__pycache__").mkdir()
(project / "__pycache__" / "app.cpython-311.pyc").write_bytes(b"\x00")
return config_file
@patch("langgraph_cli.archive._assemble_local_deps")
def test_yields_archive_with_config(self, mock_deps, tmp_path):
from langgraph_cli.config import LocalDeps
config_file = self._make_project(tmp_path)
mock_deps.return_value = LocalDeps(
pip_reqs=[], real_pkgs={}, faux_pkgs={}, additional_contexts=None
)
with create_archive(config_file, {}) as (archive_path, file_size, config_rel):
assert os.path.isfile(archive_path)
assert archive_path.endswith(".tar.gz")
assert file_size > 0
assert config_rel == "langgraph.json"
with tarfile.open(archive_path, "r:gz") as tar:
names = tar.getnames()
assert "langgraph.json" in names
assert "app.py" in names
@patch("langgraph_cli.archive._assemble_local_deps")
def test_excludes_pycache(self, mock_deps, tmp_path):
from langgraph_cli.config import LocalDeps
config_file = self._make_project(tmp_path)
mock_deps.return_value = LocalDeps(
pip_reqs=[], real_pkgs={}, faux_pkgs={}, additional_contexts=None
)
with create_archive(config_file, {}) as (archive_path, _size, _rel):
with tarfile.open(archive_path, "r:gz") as tar:
names = tar.getnames()
assert not any("__pycache__" in n for n in names)
@patch("langgraph_cli.archive._assemble_local_deps")
def test_cleans_up_tmp_dir_on_normal_exit(self, mock_deps, tmp_path):
from langgraph_cli.config import LocalDeps
config_file = self._make_project(tmp_path)
mock_deps.return_value = LocalDeps(
pip_reqs=[], real_pkgs={}, faux_pkgs={}, additional_contexts=None
)
with create_archive(config_file, {}) as (archive_path, _size, _rel):
tmp_dir = os.path.dirname(archive_path)
assert os.path.isdir(tmp_dir)
assert not os.path.exists(tmp_dir)
@patch("langgraph_cli.archive._assemble_local_deps")
def test_cleans_up_tmp_dir_on_exception(self, mock_deps, tmp_path):
from langgraph_cli.config import LocalDeps
config_file = self._make_project(tmp_path)
mock_deps.return_value = LocalDeps(
pip_reqs=[], real_pkgs={}, faux_pkgs={}, additional_contexts=None
)
with pytest.raises(RuntimeError, match="boom"):
with create_archive(config_file, {}) as (archive_path, _size, _rel):
tmp_dir = os.path.dirname(archive_path)
raise RuntimeError("boom")
assert not os.path.exists(tmp_dir)
@patch("langgraph_cli.archive._assemble_local_deps")
@patch("langgraph_cli.archive._MAX_SIZE", 10)
def test_raises_on_oversized_archive(self, mock_deps, tmp_path):
from langgraph_cli.config import LocalDeps
config_file = self._make_project(tmp_path)
mock_deps.return_value = LocalDeps(
pip_reqs=[], real_pkgs={}, faux_pkgs={}, additional_contexts=None
)
with pytest.raises(click.ClickException, match="exceeds the 200 MB limit"):
with create_archive(config_file, {}):
pass
@patch("langgraph_cli.archive._assemble_local_deps")
def test_handles_extra_contexts(self, mock_deps, tmp_path):
"""Monorepo case: project + sibling dependency directory."""
from langgraph_cli.config import LocalDeps
project = tmp_path / "myproject"
project.mkdir()
config_file = project / "langgraph.json"
config_file.write_text('{"dependencies": [".", "../shared"]}')
(project / "app.py").write_text("print('hello')")
shared = tmp_path / "shared"
shared.mkdir()
(shared / "lib.py").write_text("y = 2")
mock_deps.return_value = LocalDeps(
pip_reqs=[],
real_pkgs={},
faux_pkgs={},
additional_contexts=[shared],
)
with create_archive(config_file, {}) as (archive_path, _size, config_rel):
with tarfile.open(archive_path, "r:gz") as tar:
names = tar.getnames()
assert "myproject/app.py" in names
assert "shared/lib.py" in names
assert config_rel == "myproject/langgraph.json"
@@ -6,12 +6,14 @@ import click
import httpx
import pytest
from langgraph_cli.cli import (
from langgraph_cli.deploy import (
_call_host_backend_with_optional_tenant,
_docker_config_for_token,
_normalize_image_name,
_normalize_image_tag,
_env_without_deployment_name,
_parse_env_from_config,
_resolve_env_path,
normalize_image_name,
normalize_image_tag,
)
from langgraph_cli.host_backend import HostBackendClient, HostBackendError
@@ -40,47 +42,47 @@ class TestDockerConfigForToken:
class TestNormalizeImageName:
def test_simple_name(self):
assert _normalize_image_name("myapp") == "myapp"
assert normalize_image_name("myapp") == "myapp"
def test_uppercase_lowered(self):
assert _normalize_image_name("MyApp") == "myapp"
assert normalize_image_name("MyApp") == "myapp"
def test_special_chars_replaced(self):
assert _normalize_image_name("my app!@#v2") == "my-app-v2"
assert normalize_image_name("my app!@#v2") == "my-app-v2"
def test_dots_and_hyphens_kept(self):
assert _normalize_image_name("my-app.v2") == "my-app.v2"
assert normalize_image_name("my-app.v2") == "my-app.v2"
def test_leading_trailing_stripped(self):
assert _normalize_image_name("--my-app..") == "my-app"
assert normalize_image_name("--my-app..") == "my-app"
def test_empty_string_returns_app(self):
assert _normalize_image_name("") == "app"
assert normalize_image_name("") == "app"
def test_none_returns_app(self):
assert _normalize_image_name(None) == "app"
assert normalize_image_name(None) == "app"
def test_all_invalid_chars_returns_app(self):
assert _normalize_image_name("!!!") == "app"
assert normalize_image_name("!!!") == "app"
class TestNormalizeImageTag:
def test_valid_tag(self):
assert _normalize_image_tag("v1.2.3") == "v1.2.3"
assert normalize_image_tag("v1.2.3") == "v1.2.3"
def test_empty_defaults_to_latest(self):
assert _normalize_image_tag("") == "latest"
assert normalize_image_tag("") == "latest"
def test_alphanumeric_and_special(self):
assert _normalize_image_tag("my_tag-1.0") == "my_tag-1.0"
assert normalize_image_tag("my_tag-1.0") == "my_tag-1.0"
def test_invalid_chars_raises(self):
with pytest.raises(click.UsageError, match="Image tag may only contain"):
_normalize_image_tag("v1.0:bad")
normalize_image_tag("v1.0:bad")
def test_spaces_raises(self):
with pytest.raises(click.UsageError, match="Image tag may only contain"):
_normalize_image_tag("has space")
normalize_image_tag("has space")
class TestParseEnvFromConfig:
@@ -137,6 +139,51 @@ class TestParseEnvFromConfig:
assert result["EMPTY"] == ""
class TestResolveEnvPath:
def test_inline_env_dict_returns_none(self, tmp_path):
config_path = tmp_path / "langgraph.json"
config_path.touch()
assert _resolve_env_path({"env": {"FOO": "bar"}}, config_path) is None
def test_relative_env_path_resolves(self, tmp_path):
env_file = tmp_path / "custom.env"
env_file.write_text("FOO=bar\n")
config_path = tmp_path / "langgraph.json"
config_path.touch()
resolved = _resolve_env_path({"env": "custom.env"}, config_path)
assert resolved == env_file.resolve()
def test_missing_env_file_returns_none(self, tmp_path):
config_path = tmp_path / "langgraph.json"
config_path.touch()
assert _resolve_env_path({"env": "missing.env"}, config_path) is None
def test_default_env_is_cwd_dotenv(self, tmp_path, monkeypatch):
monkeypatch.chdir(tmp_path)
config_path = tmp_path / "langgraph.json"
config_path.touch()
assert _resolve_env_path({}, config_path) == tmp_path / ".env"
class TestEnvWithoutDeploymentName:
def test_removes_deployment_name_only(self):
env = {
"LANGSMITH_DEPLOYMENT_NAME": "my-deploy",
"KEEP_ME": "value",
}
cleaned = _env_without_deployment_name(env)
assert "LANGSMITH_DEPLOYMENT_NAME" not in cleaned
assert cleaned["KEEP_ME"] == "value"
# Original dict should be unchanged.
assert env["LANGSMITH_DEPLOYMENT_NAME"] == "my-deploy"
def test_noop_when_deployment_name_absent(self):
env = {"FOO": "bar"}
assert _env_without_deployment_name(env) == {"FOO": "bar"}
class TestCallHostBackendWithOptionalTenant:
def _make_client(self, handler):
c = HostBackendClient("https://api.example.com", "test-key")
@@ -121,7 +121,9 @@ def test_request_transport_error_raises():
def test_create_deployment(client):
result = client.create_deployment({"name": "my-deploy"})
result = client.create_deployment(
name="my-deploy", deployment_type="dev", source="internal_docker"
)
assert result == {"ok": True}
@@ -1,4 +1,4 @@
from langgraph_cli.helpers import format_log_entry, format_timestamp, level_fg
from langgraph_cli.deploy import format_log_entry, format_timestamp, level_fg
class TestFormatTimestamp:
+2 -3
View File
@@ -1,12 +1,11 @@
from unittest.mock import patch
from langgraph_cli.util import (
from langgraph_cli.deploy import (
_extract_deployment_url,
clean_empty_lines,
format_deployments_table,
format_revisions_table,
warn_non_wolfi_distro,
)
from langgraph_cli.util import clean_empty_lines, warn_non_wolfi_distro
def test_clean_empty_lines():
+59 -57
View File
@@ -1,5 +1,5 @@
version = 1
revision = 3
revision = 4
requires-python = ">=3.10"
resolution-markers = [
"python_full_version >= '3.11'",
@@ -398,62 +398,62 @@ wheels = [
[[package]]
name = "cryptography"
version = "46.0.5"
version = "46.0.6"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/60/04/ee2a9e8542e4fa2773b81771ff8349ff19cdd56b7258a0cc442639052edb/cryptography-46.0.5.tar.gz", hash = "sha256:abace499247268e3757271b2f1e244b36b06f8515cf27c4d49468fc9eb16e93d", size = 750064, upload-time = "2026-02-10T19:18:38.255Z" }
sdist = { url = "https://files.pythonhosted.org/packages/a4/ba/04b1bd4218cbc58dc90ce967106d51582371b898690f3ae0402876cc4f34/cryptography-46.0.6.tar.gz", hash = "sha256:27550628a518c5c6c903d84f637fbecf287f6cb9ced3804838a1295dc1fd0759", size = 750542, upload-time = "2026-03-25T23:34:53.396Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f7/81/b0bb27f2ba931a65409c6b8a8b358a7f03c0e46eceacddff55f7c84b1f3b/cryptography-46.0.5-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:351695ada9ea9618b3500b490ad54c739860883df6c1f555e088eaf25b1bbaad", size = 7176289, upload-time = "2026-02-10T19:17:08.274Z" },
{ url = "https://files.pythonhosted.org/packages/ff/9e/6b4397a3e3d15123de3b1806ef342522393d50736c13b20ec4c9ea6693a6/cryptography-46.0.5-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c18ff11e86df2e28854939acde2d003f7984f721eba450b56a200ad90eeb0e6b", size = 4275637, upload-time = "2026-02-10T19:17:10.53Z" },
{ url = "https://files.pythonhosted.org/packages/63/e7/471ab61099a3920b0c77852ea3f0ea611c9702f651600397ac567848b897/cryptography-46.0.5-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d7e3d356b8cd4ea5aff04f129d5f66ebdc7b6f8eae802b93739ed520c47c79b", size = 4424742, upload-time = "2026-02-10T19:17:12.388Z" },
{ url = "https://files.pythonhosted.org/packages/37/53/a18500f270342d66bf7e4d9f091114e31e5ee9e7375a5aba2e85a91e0044/cryptography-46.0.5-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:50bfb6925eff619c9c023b967d5b77a54e04256c4281b0e21336a130cd7fc263", size = 4277528, upload-time = "2026-02-10T19:17:13.853Z" },
{ url = "https://files.pythonhosted.org/packages/22/29/c2e812ebc38c57b40e7c583895e73c8c5adb4d1e4a0cc4c5a4fdab2b1acc/cryptography-46.0.5-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:803812e111e75d1aa73690d2facc295eaefd4439be1023fefc4995eaea2af90d", size = 4947993, upload-time = "2026-02-10T19:17:15.618Z" },
{ url = "https://files.pythonhosted.org/packages/6b/e7/237155ae19a9023de7e30ec64e5d99a9431a567407ac21170a046d22a5a3/cryptography-46.0.5-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3ee190460e2fbe447175cda91b88b84ae8322a104fc27766ad09428754a618ed", size = 4456855, upload-time = "2026-02-10T19:17:17.221Z" },
{ url = "https://files.pythonhosted.org/packages/2d/87/fc628a7ad85b81206738abbd213b07702bcbdada1dd43f72236ef3cffbb5/cryptography-46.0.5-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:f145bba11b878005c496e93e257c1e88f154d278d2638e6450d17e0f31e558d2", size = 3984635, upload-time = "2026-02-10T19:17:18.792Z" },
{ url = "https://files.pythonhosted.org/packages/84/29/65b55622bde135aedf4565dc509d99b560ee4095e56989e815f8fd2aa910/cryptography-46.0.5-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:e9251e3be159d1020c4030bd2e5f84d6a43fe54b6c19c12f51cde9542a2817b2", size = 4277038, upload-time = "2026-02-10T19:17:20.256Z" },
{ url = "https://files.pythonhosted.org/packages/bc/36/45e76c68d7311432741faf1fbf7fac8a196a0a735ca21f504c75d37e2558/cryptography-46.0.5-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:47fb8a66058b80e509c47118ef8a75d14c455e81ac369050f20ba0d23e77fee0", size = 4912181, upload-time = "2026-02-10T19:17:21.825Z" },
{ url = "https://files.pythonhosted.org/packages/6d/1a/c1ba8fead184d6e3d5afcf03d569acac5ad063f3ac9fb7258af158f7e378/cryptography-46.0.5-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:4c3341037c136030cb46e4b1e17b7418ea4cbd9dd207e4a6f3b2b24e0d4ac731", size = 4456482, upload-time = "2026-02-10T19:17:25.133Z" },
{ url = "https://files.pythonhosted.org/packages/f9/e5/3fb22e37f66827ced3b902cf895e6a6bc1d095b5b26be26bd13c441fdf19/cryptography-46.0.5-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:890bcb4abd5a2d3f852196437129eb3667d62630333aacc13dfd470fad3aaa82", size = 4405497, upload-time = "2026-02-10T19:17:26.66Z" },
{ url = "https://files.pythonhosted.org/packages/1a/df/9d58bb32b1121a8a2f27383fabae4d63080c7ca60b9b5c88be742be04ee7/cryptography-46.0.5-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:80a8d7bfdf38f87ca30a5391c0c9ce4ed2926918e017c29ddf643d0ed2778ea1", size = 4667819, upload-time = "2026-02-10T19:17:28.569Z" },
{ url = "https://files.pythonhosted.org/packages/ea/ed/325d2a490c5e94038cdb0117da9397ece1f11201f425c4e9c57fe5b9f08b/cryptography-46.0.5-cp311-abi3-win32.whl", hash = "sha256:60ee7e19e95104d4c03871d7d7dfb3d22ef8a9b9c6778c94e1c8fcc8365afd48", size = 3028230, upload-time = "2026-02-10T19:17:30.518Z" },
{ url = "https://files.pythonhosted.org/packages/e9/5a/ac0f49e48063ab4255d9e3b79f5def51697fce1a95ea1370f03dc9db76f6/cryptography-46.0.5-cp311-abi3-win_amd64.whl", hash = "sha256:38946c54b16c885c72c4f59846be9743d699eee2b69b6988e0a00a01f46a61a4", size = 3480909, upload-time = "2026-02-10T19:17:32.083Z" },
{ url = "https://files.pythonhosted.org/packages/00/13/3d278bfa7a15a96b9dc22db5a12ad1e48a9eb3d40e1827ef66a5df75d0d0/cryptography-46.0.5-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:94a76daa32eb78d61339aff7952ea819b1734b46f73646a07decb40e5b3448e2", size = 7119287, upload-time = "2026-02-10T19:17:33.801Z" },
{ url = "https://files.pythonhosted.org/packages/67/c8/581a6702e14f0898a0848105cbefd20c058099e2c2d22ef4e476dfec75d7/cryptography-46.0.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5be7bf2fb40769e05739dd0046e7b26f9d4670badc7b032d6ce4db64dddc0678", size = 4265728, upload-time = "2026-02-10T19:17:35.569Z" },
{ url = "https://files.pythonhosted.org/packages/dd/4a/ba1a65ce8fc65435e5a849558379896c957870dd64fecea97b1ad5f46a37/cryptography-46.0.5-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fe346b143ff9685e40192a4960938545c699054ba11d4f9029f94751e3f71d87", size = 4408287, upload-time = "2026-02-10T19:17:36.938Z" },
{ url = "https://files.pythonhosted.org/packages/f8/67/8ffdbf7b65ed1ac224d1c2df3943553766914a8ca718747ee3871da6107e/cryptography-46.0.5-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:c69fd885df7d089548a42d5ec05be26050ebcd2283d89b3d30676eb32ff87dee", size = 4270291, upload-time = "2026-02-10T19:17:38.748Z" },
{ url = "https://files.pythonhosted.org/packages/f8/e5/f52377ee93bc2f2bba55a41a886fd208c15276ffbd2569f2ddc89d50e2c5/cryptography-46.0.5-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:8293f3dea7fc929ef7240796ba231413afa7b68ce38fd21da2995549f5961981", size = 4927539, upload-time = "2026-02-10T19:17:40.241Z" },
{ url = "https://files.pythonhosted.org/packages/3b/02/cfe39181b02419bbbbcf3abdd16c1c5c8541f03ca8bda240debc467d5a12/cryptography-46.0.5-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:1abfdb89b41c3be0365328a410baa9df3ff8a9110fb75e7b52e66803ddabc9a9", size = 4442199, upload-time = "2026-02-10T19:17:41.789Z" },
{ url = "https://files.pythonhosted.org/packages/c0/96/2fcaeb4873e536cf71421a388a6c11b5bc846e986b2b069c79363dc1648e/cryptography-46.0.5-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:d66e421495fdb797610a08f43b05269e0a5ea7f5e652a89bfd5a7d3c1dee3648", size = 3960131, upload-time = "2026-02-10T19:17:43.379Z" },
{ url = "https://files.pythonhosted.org/packages/d8/d2/b27631f401ddd644e94c5cf33c9a4069f72011821cf3dc7309546b0642a0/cryptography-46.0.5-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:4e817a8920bfbcff8940ecfd60f23d01836408242b30f1a708d93198393a80b4", size = 4270072, upload-time = "2026-02-10T19:17:45.481Z" },
{ url = "https://files.pythonhosted.org/packages/f4/a7/60d32b0370dae0b4ebe55ffa10e8599a2a59935b5ece1b9f06edb73abdeb/cryptography-46.0.5-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:68f68d13f2e1cb95163fa3b4db4bf9a159a418f5f6e7242564fc75fcae667fd0", size = 4892170, upload-time = "2026-02-10T19:17:46.997Z" },
{ url = "https://files.pythonhosted.org/packages/d2/b9/cf73ddf8ef1164330eb0b199a589103c363afa0cf794218c24d524a58eab/cryptography-46.0.5-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:a3d1fae9863299076f05cb8a778c467578262fae09f9dc0ee9b12eb4268ce663", size = 4441741, upload-time = "2026-02-10T19:17:48.661Z" },
{ url = "https://files.pythonhosted.org/packages/5f/eb/eee00b28c84c726fe8fa0158c65afe312d9c3b78d9d01daf700f1f6e37ff/cryptography-46.0.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c4143987a42a2397f2fc3b4d7e3a7d313fbe684f67ff443999e803dd75a76826", size = 4396728, upload-time = "2026-02-10T19:17:50.058Z" },
{ url = "https://files.pythonhosted.org/packages/65/f4/6bc1a9ed5aef7145045114b75b77c2a8261b4d38717bd8dea111a63c3442/cryptography-46.0.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:7d731d4b107030987fd61a7f8ab512b25b53cef8f233a97379ede116f30eb67d", size = 4652001, upload-time = "2026-02-10T19:17:51.54Z" },
{ url = "https://files.pythonhosted.org/packages/86/ef/5d00ef966ddd71ac2e6951d278884a84a40ffbd88948ef0e294b214ae9e4/cryptography-46.0.5-cp314-cp314t-win32.whl", hash = "sha256:c3bcce8521d785d510b2aad26ae2c966092b7daa8f45dd8f44734a104dc0bc1a", size = 3003637, upload-time = "2026-02-10T19:17:52.997Z" },
{ url = "https://files.pythonhosted.org/packages/b7/57/f3f4160123da6d098db78350fdfd9705057aad21de7388eacb2401dceab9/cryptography-46.0.5-cp314-cp314t-win_amd64.whl", hash = "sha256:4d8ae8659ab18c65ced284993c2265910f6c9e650189d4e3f68445ef82a810e4", size = 3469487, upload-time = "2026-02-10T19:17:54.549Z" },
{ url = "https://files.pythonhosted.org/packages/e2/fa/a66aa722105ad6a458bebd64086ca2b72cdd361fed31763d20390f6f1389/cryptography-46.0.5-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:4108d4c09fbbf2789d0c926eb4152ae1760d5a2d97612b92d508d96c861e4d31", size = 7170514, upload-time = "2026-02-10T19:17:56.267Z" },
{ url = "https://files.pythonhosted.org/packages/0f/04/c85bdeab78c8bc77b701bf0d9bdcf514c044e18a46dcff330df5448631b0/cryptography-46.0.5-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1f30a86d2757199cb2d56e48cce14deddf1f9c95f1ef1b64ee91ea43fe2e18", size = 4275349, upload-time = "2026-02-10T19:17:58.419Z" },
{ url = "https://files.pythonhosted.org/packages/5c/32/9b87132a2f91ee7f5223b091dc963055503e9b442c98fc0b8a5ca765fab0/cryptography-46.0.5-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:039917b0dc418bb9f6edce8a906572d69e74bd330b0b3fea4f79dab7f8ddd235", size = 4420667, upload-time = "2026-02-10T19:18:00.619Z" },
{ url = "https://files.pythonhosted.org/packages/a1/a6/a7cb7010bec4b7c5692ca6f024150371b295ee1c108bdc1c400e4c44562b/cryptography-46.0.5-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ba2a27ff02f48193fc4daeadf8ad2590516fa3d0adeeb34336b96f7fa64c1e3a", size = 4276980, upload-time = "2026-02-10T19:18:02.379Z" },
{ url = "https://files.pythonhosted.org/packages/8e/7c/c4f45e0eeff9b91e3f12dbd0e165fcf2a38847288fcfd889deea99fb7b6d/cryptography-46.0.5-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:61aa400dce22cb001a98014f647dc21cda08f7915ceb95df0c9eaf84b4b6af76", size = 4939143, upload-time = "2026-02-10T19:18:03.964Z" },
{ url = "https://files.pythonhosted.org/packages/37/19/e1b8f964a834eddb44fa1b9a9976f4e414cbb7aa62809b6760c8803d22d1/cryptography-46.0.5-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3ce58ba46e1bc2aac4f7d9290223cead56743fa6ab94a5d53292ffaac6a91614", size = 4453674, upload-time = "2026-02-10T19:18:05.588Z" },
{ url = "https://files.pythonhosted.org/packages/db/ed/db15d3956f65264ca204625597c410d420e26530c4e2943e05a0d2f24d51/cryptography-46.0.5-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:420d0e909050490d04359e7fdb5ed7e667ca5c3c402b809ae2563d7e66a92229", size = 3978801, upload-time = "2026-02-10T19:18:07.167Z" },
{ url = "https://files.pythonhosted.org/packages/41/e2/df40a31d82df0a70a0daf69791f91dbb70e47644c58581d654879b382d11/cryptography-46.0.5-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:582f5fcd2afa31622f317f80426a027f30dc792e9c80ffee87b993200ea115f1", size = 4276755, upload-time = "2026-02-10T19:18:09.813Z" },
{ url = "https://files.pythonhosted.org/packages/33/45/726809d1176959f4a896b86907b98ff4391a8aa29c0aaaf9450a8a10630e/cryptography-46.0.5-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:bfd56bb4b37ed4f330b82402f6f435845a5f5648edf1ad497da51a8452d5d62d", size = 4901539, upload-time = "2026-02-10T19:18:11.263Z" },
{ url = "https://files.pythonhosted.org/packages/99/0f/a3076874e9c88ecb2ecc31382f6e7c21b428ede6f55aafa1aa272613e3cd/cryptography-46.0.5-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:a3d507bb6a513ca96ba84443226af944b0f7f47dcc9a399d110cd6146481d24c", size = 4452794, upload-time = "2026-02-10T19:18:12.914Z" },
{ url = "https://files.pythonhosted.org/packages/02/ef/ffeb542d3683d24194a38f66ca17c0a4b8bf10631feef44a7ef64e631b1a/cryptography-46.0.5-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9f16fbdf4da055efb21c22d81b89f155f02ba420558db21288b3d0035bafd5f4", size = 4404160, upload-time = "2026-02-10T19:18:14.375Z" },
{ url = "https://files.pythonhosted.org/packages/96/93/682d2b43c1d5f1406ed048f377c0fc9fc8f7b0447a478d5c65ab3d3a66eb/cryptography-46.0.5-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:ced80795227d70549a411a4ab66e8ce307899fad2220ce5ab2f296e687eacde9", size = 4667123, upload-time = "2026-02-10T19:18:15.886Z" },
{ url = "https://files.pythonhosted.org/packages/45/2d/9c5f2926cb5300a8eefc3f4f0b3f3df39db7f7ce40c8365444c49363cbda/cryptography-46.0.5-cp38-abi3-win32.whl", hash = "sha256:02f547fce831f5096c9a567fd41bc12ca8f11df260959ecc7c3202555cc47a72", size = 3010220, upload-time = "2026-02-10T19:18:17.361Z" },
{ url = "https://files.pythonhosted.org/packages/48/ef/0c2f4a8e31018a986949d34a01115dd057bf536905dca38897bacd21fac3/cryptography-46.0.5-cp38-abi3-win_amd64.whl", hash = "sha256:556e106ee01aa13484ce9b0239bca667be5004efb0aabbed28d353df86445595", size = 3467050, upload-time = "2026-02-10T19:18:18.899Z" },
{ url = "https://files.pythonhosted.org/packages/eb/dd/2d9fdb07cebdf3d51179730afb7d5e576153c6744c3ff8fded23030c204e/cryptography-46.0.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:3b4995dc971c9fb83c25aa44cf45f02ba86f71ee600d81091c2f0cbae116b06c", size = 3476964, upload-time = "2026-02-10T19:18:20.687Z" },
{ url = "https://files.pythonhosted.org/packages/e9/6f/6cc6cc9955caa6eaf83660b0da2b077c7fe8ff9950a3c5e45d605038d439/cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:bc84e875994c3b445871ea7181d424588171efec3e185dced958dad9e001950a", size = 4218321, upload-time = "2026-02-10T19:18:22.349Z" },
{ url = "https://files.pythonhosted.org/packages/3e/5d/c4da701939eeee699566a6c1367427ab91a8b7088cc2328c09dbee940415/cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:2ae6971afd6246710480e3f15824ed3029a60fc16991db250034efd0b9fb4356", size = 4381786, upload-time = "2026-02-10T19:18:24.529Z" },
{ url = "https://files.pythonhosted.org/packages/ac/97/a538654732974a94ff96c1db621fa464f455c02d4bb7d2652f4edc21d600/cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:d861ee9e76ace6cf36a6a89b959ec08e7bc2493ee39d07ffe5acb23ef46d27da", size = 4217990, upload-time = "2026-02-10T19:18:25.957Z" },
{ url = "https://files.pythonhosted.org/packages/ae/11/7e500d2dd3ba891197b9efd2da5454b74336d64a7cc419aa7327ab74e5f6/cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:2b7a67c9cd56372f3249b39699f2ad479f6991e62ea15800973b956f4b73e257", size = 4381252, upload-time = "2026-02-10T19:18:27.496Z" },
{ url = "https://files.pythonhosted.org/packages/bc/58/6b3d24e6b9bc474a2dcdee65dfd1f008867015408a271562e4b690561a4d/cryptography-46.0.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:8456928655f856c6e1533ff59d5be76578a7157224dbd9ce6872f25055ab9ab7", size = 3407605, upload-time = "2026-02-10T19:18:29.233Z" },
{ url = "https://files.pythonhosted.org/packages/47/23/9285e15e3bc57325b0a72e592921983a701efc1ee8f91c06c5f0235d86d9/cryptography-46.0.6-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:64235194bad039a10bb6d2d930ab3323baaec67e2ce36215fd0952fad0930ca8", size = 7176401, upload-time = "2026-03-25T23:33:22.096Z" },
{ url = "https://files.pythonhosted.org/packages/60/f8/e61f8f13950ab6195b31913b42d39f0f9afc7d93f76710f299b5ec286ae6/cryptography-46.0.6-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:26031f1e5ca62fcb9d1fcb34b2b60b390d1aacaa15dc8b895a9ed00968b97b30", size = 4275275, upload-time = "2026-03-25T23:33:23.844Z" },
{ url = "https://files.pythonhosted.org/packages/19/69/732a736d12c2631e140be2348b4ad3d226302df63ef64d30dfdb8db7ad1c/cryptography-46.0.6-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9a693028b9cbe51b5a1136232ee8f2bc242e4e19d456ded3fa7c86e43c713b4a", size = 4425320, upload-time = "2026-03-25T23:33:25.703Z" },
{ url = "https://files.pythonhosted.org/packages/d4/12/123be7292674abf76b21ac1fc0e1af50661f0e5b8f0ec8285faac18eb99e/cryptography-46.0.6-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:67177e8a9f421aa2d3a170c3e56eca4e0128883cf52a071a7cbf53297f18b175", size = 4278082, upload-time = "2026-03-25T23:33:27.423Z" },
{ url = "https://files.pythonhosted.org/packages/5b/ba/d5e27f8d68c24951b0a484924a84c7cdaed7502bac9f18601cd357f8b1d2/cryptography-46.0.6-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:d9528b535a6c4f8ff37847144b8986a9a143585f0540fbcb1a98115b543aa463", size = 4926514, upload-time = "2026-03-25T23:33:29.206Z" },
{ url = "https://files.pythonhosted.org/packages/34/71/1ea5a7352ae516d5512d17babe7e1b87d9db5150b21f794b1377eac1edc0/cryptography-46.0.6-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:22259338084d6ae497a19bae5d4c66b7ca1387d3264d1c2c0e72d9e9b6a77b97", size = 4457766, upload-time = "2026-03-25T23:33:30.834Z" },
{ url = "https://files.pythonhosted.org/packages/01/59/562be1e653accee4fdad92c7a2e88fced26b3fdfce144047519bbebc299e/cryptography-46.0.6-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:760997a4b950ff00d418398ad73fbc91aa2894b5c1db7ccb45b4f68b42a63b3c", size = 3986535, upload-time = "2026-03-25T23:33:33.02Z" },
{ url = "https://files.pythonhosted.org/packages/d6/8b/b1ebfeb788bf4624d36e45ed2662b8bd43a05ff62157093c1539c1288a18/cryptography-46.0.6-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:3dfa6567f2e9e4c5dceb8ccb5a708158a2a871052fa75c8b78cb0977063f1507", size = 4277618, upload-time = "2026-03-25T23:33:34.567Z" },
{ url = "https://files.pythonhosted.org/packages/dd/52/a005f8eabdb28df57c20f84c44d397a755782d6ff6d455f05baa2785bd91/cryptography-46.0.6-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:cdcd3edcbc5d55757e5f5f3d330dd00007ae463a7e7aa5bf132d1f22a4b62b19", size = 4890802, upload-time = "2026-03-25T23:33:37.034Z" },
{ url = "https://files.pythonhosted.org/packages/ec/4d/8e7d7245c79c617d08724e2efa397737715ca0ec830ecb3c91e547302555/cryptography-46.0.6-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:d4e4aadb7fc1f88687f47ca20bb7227981b03afaae69287029da08096853b738", size = 4457425, upload-time = "2026-03-25T23:33:38.904Z" },
{ url = "https://files.pythonhosted.org/packages/1d/5c/f6c3596a1430cec6f949085f0e1a970638d76f81c3ea56d93d564d04c340/cryptography-46.0.6-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2b417edbe8877cda9022dde3a008e2deb50be9c407eef034aeeb3a8b11d9db3c", size = 4405530, upload-time = "2026-03-25T23:33:40.842Z" },
{ url = "https://files.pythonhosted.org/packages/7e/c9/9f9cea13ee2dbde070424e0c4f621c091a91ffcc504ffea5e74f0e1daeff/cryptography-46.0.6-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:380343e0653b1c9d7e1f55b52aaa2dbb2fdf2730088d48c43ca1c7c0abb7cc2f", size = 4667896, upload-time = "2026-03-25T23:33:42.781Z" },
{ url = "https://files.pythonhosted.org/packages/ad/b5/1895bc0821226f129bc74d00eccfc6a5969e2028f8617c09790bf89c185e/cryptography-46.0.6-cp311-abi3-win32.whl", hash = "sha256:bcb87663e1f7b075e48c3be3ecb5f0b46c8fc50b50a97cf264e7f60242dca3f2", size = 3026348, upload-time = "2026-03-25T23:33:45.021Z" },
{ url = "https://files.pythonhosted.org/packages/c3/f8/c9bcbf0d3e6ad288b9d9aa0b1dee04b063d19e8c4f871855a03ab3a297ab/cryptography-46.0.6-cp311-abi3-win_amd64.whl", hash = "sha256:6739d56300662c468fddb0e5e291f9b4d084bead381667b9e654c7dd81705124", size = 3483896, upload-time = "2026-03-25T23:33:46.649Z" },
{ url = "https://files.pythonhosted.org/packages/01/41/3a578f7fd5c70611c0aacba52cd13cb364a5dee895a5c1d467208a9380b0/cryptography-46.0.6-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:2ef9e69886cbb137c2aef9772c2e7138dc581fad4fcbcf13cc181eb5a3ab6275", size = 7117147, upload-time = "2026-03-25T23:33:48.249Z" },
{ url = "https://files.pythonhosted.org/packages/fa/87/887f35a6fca9dde90cad08e0de0c89263a8e59b2d2ff904fd9fcd8025b6f/cryptography-46.0.6-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7f417f034f91dcec1cb6c5c35b07cdbb2ef262557f701b4ecd803ee8cefed4f4", size = 4266221, upload-time = "2026-03-25T23:33:49.874Z" },
{ url = "https://files.pythonhosted.org/packages/aa/a8/0a90c4f0b0871e0e3d1ed126aed101328a8a57fd9fd17f00fb67e82a51ca/cryptography-46.0.6-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d24c13369e856b94892a89ddf70b332e0b70ad4a5c43cf3e9cb71d6d7ffa1f7b", size = 4408952, upload-time = "2026-03-25T23:33:52.128Z" },
{ url = "https://files.pythonhosted.org/packages/16/0b/b239701eb946523e4e9f329336e4ff32b1247e109cbab32d1a7b61da8ed7/cryptography-46.0.6-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:aad75154a7ac9039936d50cf431719a2f8d4ed3d3c277ac03f3339ded1a5e707", size = 4270141, upload-time = "2026-03-25T23:33:54.11Z" },
{ url = "https://files.pythonhosted.org/packages/0f/a8/976acdd4f0f30df7b25605f4b9d3d89295351665c2091d18224f7ad5cdbf/cryptography-46.0.6-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:3c21d92ed15e9cfc6eb64c1f5a0326db22ca9c2566ca46d845119b45b4400361", size = 4904178, upload-time = "2026-03-25T23:33:55.725Z" },
{ url = "https://files.pythonhosted.org/packages/b1/1b/bf0e01a88efd0e59679b69f42d4afd5bced8700bb5e80617b2d63a3741af/cryptography-46.0.6-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:4668298aef7cddeaf5c6ecc244c2302a2b8e40f384255505c22875eebb47888b", size = 4441812, upload-time = "2026-03-25T23:33:57.364Z" },
{ url = "https://files.pythonhosted.org/packages/bb/8b/11df86de2ea389c65aa1806f331cae145f2ed18011f30234cc10ca253de8/cryptography-46.0.6-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:8ce35b77aaf02f3b59c90b2c8a05c73bac12cea5b4e8f3fbece1f5fddea5f0ca", size = 3963923, upload-time = "2026-03-25T23:33:59.361Z" },
{ url = "https://files.pythonhosted.org/packages/91/e0/207fb177c3a9ef6a8108f234208c3e9e76a6aa8cf20d51932916bd43bda0/cryptography-46.0.6-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:c89eb37fae9216985d8734c1afd172ba4927f5a05cfd9bf0e4863c6d5465b013", size = 4269695, upload-time = "2026-03-25T23:34:00.909Z" },
{ url = "https://files.pythonhosted.org/packages/21/5e/19f3260ed1e95bced52ace7501fabcd266df67077eeb382b79c81729d2d3/cryptography-46.0.6-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:ed418c37d095aeddf5336898a132fba01091f0ac5844e3e8018506f014b6d2c4", size = 4869785, upload-time = "2026-03-25T23:34:02.796Z" },
{ url = "https://files.pythonhosted.org/packages/10/38/cd7864d79aa1d92ef6f1a584281433419b955ad5a5ba8d1eb6c872165bcb/cryptography-46.0.6-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:69cf0056d6947edc6e6760e5f17afe4bea06b56a9ac8a06de9d2bd6b532d4f3a", size = 4441404, upload-time = "2026-03-25T23:34:04.35Z" },
{ url = "https://files.pythonhosted.org/packages/09/0a/4fe7a8d25fed74419f91835cf5829ade6408fd1963c9eae9c4bce390ecbb/cryptography-46.0.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e7304c4f4e9490e11efe56af6713983460ee0780f16c63f219984dab3af9d2d", size = 4397549, upload-time = "2026-03-25T23:34:06.342Z" },
{ url = "https://files.pythonhosted.org/packages/5f/a0/7d738944eac6513cd60a8da98b65951f4a3b279b93479a7e8926d9cd730b/cryptography-46.0.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b928a3ca837c77a10e81a814a693f2295200adb3352395fad024559b7be7a736", size = 4651874, upload-time = "2026-03-25T23:34:07.916Z" },
{ url = "https://files.pythonhosted.org/packages/cb/f1/c2326781ca05208845efca38bf714f76939ae446cd492d7613808badedf1/cryptography-46.0.6-cp314-cp314t-win32.whl", hash = "sha256:97c8115b27e19e592a05c45d0dd89c57f81f841cc9880e353e0d3bf25b2139ed", size = 3001511, upload-time = "2026-03-25T23:34:09.892Z" },
{ url = "https://files.pythonhosted.org/packages/c9/57/fe4a23eb549ac9d903bd4698ffda13383808ef0876cc912bcb2838799ece/cryptography-46.0.6-cp314-cp314t-win_amd64.whl", hash = "sha256:c797e2517cb7880f8297e2c0f43bb910e91381339336f75d2c1c2cbf811b70b4", size = 3471692, upload-time = "2026-03-25T23:34:11.613Z" },
{ url = "https://files.pythonhosted.org/packages/c4/cc/f330e982852403da79008552de9906804568ae9230da8432f7496ce02b71/cryptography-46.0.6-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:12cae594e9473bca1a7aceb90536060643128bb274fcea0fc459ab90f7d1ae7a", size = 7162776, upload-time = "2026-03-25T23:34:13.308Z" },
{ url = "https://files.pythonhosted.org/packages/49/b3/dc27efd8dcc4bff583b3f01d4a3943cd8b5821777a58b3a6a5f054d61b79/cryptography-46.0.6-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:639301950939d844a9e1c4464d7e07f902fe9a7f6b215bb0d4f28584729935d8", size = 4270529, upload-time = "2026-03-25T23:34:15.019Z" },
{ url = "https://files.pythonhosted.org/packages/e6/05/e8d0e6eb4f0d83365b3cb0e00eb3c484f7348db0266652ccd84632a3d58d/cryptography-46.0.6-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ed3775295fb91f70b4027aeba878d79b3e55c0b3e97eaa4de71f8f23a9f2eb77", size = 4414827, upload-time = "2026-03-25T23:34:16.604Z" },
{ url = "https://files.pythonhosted.org/packages/2f/97/daba0f5d2dc6d855e2dcb70733c812558a7977a55dd4a6722756628c44d1/cryptography-46.0.6-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:8927ccfbe967c7df312ade694f987e7e9e22b2425976ddbf28271d7e58845290", size = 4271265, upload-time = "2026-03-25T23:34:18.586Z" },
{ url = "https://files.pythonhosted.org/packages/89/06/fe1fce39a37ac452e58d04b43b0855261dac320a2ebf8f5260dd55b201a9/cryptography-46.0.6-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:b12c6b1e1651e42ab5de8b1e00dc3b6354fdfd778e7fa60541ddacc27cd21410", size = 4916800, upload-time = "2026-03-25T23:34:20.561Z" },
{ url = "https://files.pythonhosted.org/packages/ff/8a/b14f3101fe9c3592603339eb5d94046c3ce5f7fc76d6512a2d40efd9724e/cryptography-46.0.6-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:063b67749f338ca9c5a0b7fe438a52c25f9526b851e24e6c9310e7195aad3b4d", size = 4448771, upload-time = "2026-03-25T23:34:22.406Z" },
{ url = "https://files.pythonhosted.org/packages/01/b3/0796998056a66d1973fd52ee89dc1bb3b6581960a91ad4ac705f182d398f/cryptography-46.0.6-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:02fad249cb0e090b574e30b276a3da6a149e04ee2f049725b1f69e7b8351ec70", size = 3978333, upload-time = "2026-03-25T23:34:24.281Z" },
{ url = "https://files.pythonhosted.org/packages/c5/3d/db200af5a4ffd08918cd55c08399dc6c9c50b0bc72c00a3246e099d3a849/cryptography-46.0.6-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:7e6142674f2a9291463e5e150090b95a8519b2fb6e6aaec8917dd8d094ce750d", size = 4271069, upload-time = "2026-03-25T23:34:25.895Z" },
{ url = "https://files.pythonhosted.org/packages/d7/18/61acfd5b414309d74ee838be321c636fe71815436f53c9f0334bf19064fa/cryptography-46.0.6-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:456b3215172aeefb9284550b162801d62f5f264a081049a3e94307fe20792cfa", size = 4878358, upload-time = "2026-03-25T23:34:27.67Z" },
{ url = "https://files.pythonhosted.org/packages/8b/65/5bf43286d566f8171917cae23ac6add941654ccf085d739195a4eacf1674/cryptography-46.0.6-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:341359d6c9e68834e204ceaf25936dffeafea3829ab80e9503860dcc4f4dac58", size = 4448061, upload-time = "2026-03-25T23:34:29.375Z" },
{ url = "https://files.pythonhosted.org/packages/e0/25/7e49c0fa7205cf3597e525d156a6bce5b5c9de1fd7e8cb01120e459f205a/cryptography-46.0.6-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9a9c42a2723999a710445bc0d974e345c32adfd8d2fac6d8a251fa829ad31cfb", size = 4399103, upload-time = "2026-03-25T23:34:32.036Z" },
{ url = "https://files.pythonhosted.org/packages/44/46/466269e833f1c4718d6cd496ffe20c56c9c8d013486ff66b4f69c302a68d/cryptography-46.0.6-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6617f67b1606dfd9fe4dbfa354a9508d4a6d37afe30306fe6c101b7ce3274b72", size = 4659255, upload-time = "2026-03-25T23:34:33.679Z" },
{ url = "https://files.pythonhosted.org/packages/0a/09/ddc5f630cc32287d2c953fc5d32705e63ec73e37308e5120955316f53827/cryptography-46.0.6-cp38-abi3-win32.whl", hash = "sha256:7f6690b6c55e9c5332c0b59b9c8a3fb232ebf059094c17f9019a51e9827df91c", size = 3010660, upload-time = "2026-03-25T23:34:35.418Z" },
{ url = "https://files.pythonhosted.org/packages/1b/82/ca4893968aeb2709aacfb57a30dec6fa2ab25b10fa9f064b8882ce33f599/cryptography-46.0.6-cp38-abi3-win_amd64.whl", hash = "sha256:79e865c642cfc5c0b3eb12af83c35c5aeff4fa5c672dc28c43721c2c9fdd2f0f", size = 3471160, upload-time = "2026-03-25T23:34:37.191Z" },
{ url = "https://files.pythonhosted.org/packages/2e/84/7ccff00ced5bac74b775ce0beb7d1be4e8637536b522b5df9b73ada42da2/cryptography-46.0.6-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:2ea0f37e9a9cf0df2952893ad145fd9627d326a59daec9b0802480fa3bcd2ead", size = 3475444, upload-time = "2026-03-25T23:34:38.944Z" },
{ url = "https://files.pythonhosted.org/packages/bc/1f/4c926f50df7749f000f20eede0c896769509895e2648db5da0ed55db711d/cryptography-46.0.6-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a3e84d5ec9ba01f8fd03802b2147ba77f0c8f2617b2aff254cedd551844209c8", size = 4218227, upload-time = "2026-03-25T23:34:40.871Z" },
{ url = "https://files.pythonhosted.org/packages/c6/65/707be3ffbd5f786028665c3223e86e11c4cda86023adbc56bd72b1b6bab5/cryptography-46.0.6-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:12f0fa16cc247b13c43d56d7b35287ff1569b5b1f4c5e87e92cc4fcc00cd10c0", size = 4381399, upload-time = "2026-03-25T23:34:42.609Z" },
{ url = "https://files.pythonhosted.org/packages/f3/6d/73557ed0ef7d73d04d9aba745d2c8e95218213687ee5e76b7d236a5030fc/cryptography-46.0.6-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:50575a76e2951fe7dbd1f56d181f8c5ceeeb075e9ff88e7ad997d2f42af06e7b", size = 4217595, upload-time = "2026-03-25T23:34:44.205Z" },
{ url = "https://files.pythonhosted.org/packages/9e/c5/e1594c4eec66a567c3ac4400008108a415808be2ce13dcb9a9045c92f1a0/cryptography-46.0.6-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:90e5f0a7b3be5f40c3a0a0eafb32c681d8d2c181fc2a1bdabe9b3f611d9f6b1a", size = 4380912, upload-time = "2026-03-25T23:34:46.328Z" },
{ url = "https://files.pythonhosted.org/packages/1a/89/843b53614b47f97fe1abc13f9a86efa5ec9e275292c457af1d4a60dc80e0/cryptography-46.0.6-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6728c49e3b2c180ef26f8e9f0a883a2c585638db64cf265b49c9ba10652d430e", size = 3409955, upload-time = "2026-03-25T23:34:48.465Z" },
]
[[package]]
@@ -893,7 +893,7 @@ wheels = [
[[package]]
name = "langchain-core"
version = "1.2.16"
version = "1.2.22"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "jsonpatch", marker = "python_full_version >= '3.11'" },
@@ -905,9 +905,9 @@ dependencies = [
{ name = "typing-extensions", marker = "python_full_version >= '3.11'" },
{ name = "uuid-utils", marker = "python_full_version >= '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/2e/a7/4c992456dae89a8704afec03e3c2a0149ccc5f29c1cbdd5f4aa77628e921/langchain_core-1.2.16.tar.gz", hash = "sha256:055a4bfe7d62f4ac45ed49fd759ee2e6bdd15abf998fbeea695fda5da2de6413", size = 835286, upload-time = "2026-02-25T16:27:30.551Z" }
sdist = { url = "https://files.pythonhosted.org/packages/b1/a3/c4cd6827a1df46c821e7214b7f7b7a28b189e6c9b84ef15c6d629c5e3179/langchain_core-1.2.22.tar.gz", hash = "sha256:8d8f726d03d3652d403da915126626bb6250747e8ba406537d849e68b9f5d058", size = 842487, upload-time = "2026-03-24T18:48:44.9Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2d/a1/57d5feaa11dc2ebb40f3bc3d7bf4294b6703e152e56edea9d4c622475a6a/langchain_core-1.2.16-py3-none-any.whl", hash = "sha256:2768add9aa97232a7712580f678e0ba045ee1036c71fe471355be0434fcb6e30", size = 502219, upload-time = "2026-02-25T16:27:29.379Z" },
{ url = "https://files.pythonhosted.org/packages/c7/a6/2ffacf0f1a3788f250e75d0b52a24896c413be11be3a6d42bcdf46fbea48/langchain_core-1.2.22-py3-none-any.whl", hash = "sha256:7e30d586b75918e828833b9ec1efc25465723566845dd652c277baf751e9c04b", size = 506829, upload-time = "2026-03-24T18:48:43.286Z" },
]
[[package]]
@@ -985,6 +985,7 @@ dependencies = [
{ name = "click" },
{ name = "httpx" },
{ name = "langgraph-sdk", marker = "python_full_version >= '3.11'" },
{ name = "pathspec" },
{ name = "python-dotenv" },
]
@@ -1026,6 +1027,7 @@ requires-dist = [
{ name = "langgraph-api", marker = "python_full_version >= '3.11' and extra == 'inmem'", specifier = ">=0.5.35,<0.8.0" },
{ name = "langgraph-runtime-inmem", marker = "python_full_version >= '3.11' and extra == 'inmem'", specifier = ">=0.7" },
{ name = "langgraph-sdk", marker = "python_full_version >= '3.11'", specifier = ">=0.1.0" },
{ name = "pathspec", specifier = ">=0.11.0" },
{ name = "python-dotenv", specifier = ">=0.8.0" },
]
provides-extras = ["inmem"]
@@ -1986,7 +1988,7 @@ wheels = [
[[package]]
name = "requests"
version = "2.32.5"
version = "2.33.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "certifi", marker = "python_full_version >= '3.11'" },
@@ -1994,9 +1996,9 @@ dependencies = [
{ name = "idna", marker = "python_full_version >= '3.11'" },
{ name = "urllib3", marker = "python_full_version >= '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" }
sdist = { url = "https://files.pythonhosted.org/packages/34/64/8860370b167a9721e8956ae116825caff829224fbca0ca6e7bf8ddef8430/requests-2.33.0.tar.gz", hash = "sha256:c7ebc5e8b0f21837386ad0e1c8fe8b829fa5f544d8df3b2253bff14ef29d7652", size = 134232, upload-time = "2026-03-25T15:10:41.586Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" },
{ url = "https://files.pythonhosted.org/packages/56/5d/c814546c2333ceea4ba42262d8c4d55763003e767fa169adc693bd524478/requests-2.33.0-py3-none-any.whl", hash = "sha256:3324635456fa185245e24865e810cecec7b4caf933d7eb133dcde67d48cee69b", size = 65017, upload-time = "2026-03-25T15:10:40.382Z" },
]
[[package]]
+22 -12
View File
@@ -1,17 +1,27 @@
<picture class="github-only">
<source media="(prefers-color-scheme: light)" srcset="https://langchain-ai.github.io/langgraph/static/wordmark_dark.svg">
<source media="(prefers-color-scheme: dark)" srcset="https://langchain-ai.github.io/langgraph/static/wordmark_light.svg">
<img alt="LangGraph Logo" src="https://langchain-ai.github.io/langgraph/static/wordmark_dark.svg" width="80%">
</picture>
<div>
<br>
<div align="center">
<a href="https://www.langchain.com/langgraph">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="../../.github/images/logo-dark.svg">
<source media="(prefers-color-scheme: light)" srcset="../../.github/images/logo-light.svg">
<img alt="LangGraph Logo" src=".github/images/logo-dark.svg" width="50%">
</picture>
</a>
</div>
[![Version](https://img.shields.io/pypi/v/langgraph.svg)](https://pypi.org/project/langgraph/)
[![Downloads](https://static.pepy.tech/badge/langgraph/month)](https://pepy.tech/project/langgraph)
[![Open Issues](https://img.shields.io/github/issues-raw/langchain-ai/langgraph)](https://github.com/langchain-ai/langgraph/issues)
[![Docs](https://img.shields.io/badge/docs-latest-blue)](https://docs.langchain.com/oss/python/langgraph/overview)
<div align="center">
<h3>Low-level orchestration framework for building stateful agents.</h3>
</div>
<div align="center">
<a href="https://opensource.org/licenses/MIT" target="_blank"><img src="https://img.shields.io/pypi/l/langgraph" alt="PyPI - License"></a>
<a href="https://pypistats.org/packages/langgraph" target="_blank"><img src="https://img.shields.io/pepy/dt/langgraph" alt="PyPI - Downloads"></a>
<a href="https://pypi.org/project/langgraph/" target="_blank"><img src="https://img.shields.io/pypi/v/langgraph.svg?label=%20" alt="Version"></a>
<a href="https://github.com/langchain-ai/langgraph/issues" target="_blank"><img src="https://img.shields.io/github/issues-raw/langchain-ai/langgraph" alt="Open Issues"></a>
<a href="https://docs.langchain.com/oss/python/langgraph/overview" target="_blank"><img src="https://img.shields.io/badge/docs-latest-blue" alt="Docs"></a>
<a href="https://x.com/langchain" target="_blank"><img src="https://img.shields.io/twitter/url/https/twitter.com/langchain.svg?style=social&label=Follow%20%40LangChain" alt="Twitter / X"></a>
</div>
<br>
Trusted by companies shaping the future of agents including Klarna, Replit, Elastic, and more LangGraph is a low-level orchestration framework for building, managing, and deploying long-running, stateful agents.
@@ -28,7 +28,7 @@ from langgraph._internal._constants import (
NS_SEP,
)
DEFAULT_RECURSION_LIMIT = int(getenv("LANGGRAPH_DEFAULT_RECURSION_LIMIT", "10000"))
DEFAULT_RECURSION_LIMIT = int(getenv("LANGGRAPH_DEFAULT_RECURSION_LIMIT", "10007"))
def recast_checkpoint_ns(ns: str) -> str:
+28 -3
View File
@@ -45,6 +45,7 @@ from langgraph._internal._constants import (
CONFIG_KEY_SCRATCHPAD,
CONFIG_KEY_SEND,
CONFIG_KEY_TASK_ID,
CONFIG_KEY_THREAD_ID,
ERROR,
INTERRUPT,
NO_WRITES,
@@ -70,7 +71,7 @@ from langgraph.pregel._call import get_runnable_for_task, identifier
from langgraph.pregel._io import read_channels
from langgraph.pregel._log import logger
from langgraph.pregel._read import INPUT_CACHE_KEY_TYPE, PregelNode
from langgraph.runtime import DEFAULT_RUNTIME, Runtime
from langgraph.runtime import DEFAULT_RUNTIME, ExecutionInfo, Runtime
from langgraph.types import (
All,
CacheKey,
@@ -668,6 +669,13 @@ def prepare_single_task(
runtime = runtime.override(
previous=checkpoint["channel_values"].get(PREVIOUS, None),
store=store,
execution_info=ExecutionInfo(
checkpoint_id=checkpoint["id"],
checkpoint_ns=task_checkpoint_ns,
task_id=task_id,
thread_id=configurable.get(CONFIG_KEY_THREAD_ID),
run_id=str(rid) if (rid := config.get("run_id")) else None,
),
)
additional_config = {
"metadata": metadata,
@@ -813,7 +821,16 @@ def prepare_push_task_functional(
stop,
)
runtime = cast(Runtime, configurable.get(CONFIG_KEY_RUNTIME, DEFAULT_RUNTIME))
runtime = runtime.override(store=store)
runtime = runtime.override(
store=store,
execution_info=ExecutionInfo(
checkpoint_id=checkpoint["id"],
checkpoint_ns=task_checkpoint_ns,
task_id=task_id,
thread_id=configurable.get(CONFIG_KEY_THREAD_ID),
run_id=str(rid) if (rid := config.get("run_id")) else None,
),
)
return PregelExecutableTask(
name,
call.input,
@@ -966,7 +983,15 @@ def prepare_push_task_send(
)
runtime = cast(Runtime, configurable.get(CONFIG_KEY_RUNTIME, DEFAULT_RUNTIME))
runtime = runtime.override(
store=store, previous=checkpoint["channel_values"].get(PREVIOUS, None)
store=store,
previous=checkpoint["channel_values"].get(PREVIOUS, None),
execution_info=ExecutionInfo(
checkpoint_id=checkpoint["id"],
checkpoint_ns=task_checkpoint_ns,
task_id=task_id,
thread_id=configurable.get(CONFIG_KEY_THREAD_ID),
run_id=str(rid) if (rid := config.get("run_id")) else None,
),
)
additional_config: RunnableConfig = {
"metadata": metadata,
+54 -5
View File
@@ -136,7 +136,12 @@ from langgraph.pregel._validate import validate_graph, validate_keys
from langgraph.pregel._write import ChannelWrite, ChannelWriteEntry
from langgraph.pregel.debug import get_bolded_text, get_colored_text, tasks_w_writes
from langgraph.pregel.protocol import PregelProtocol, StreamChunk, StreamProtocol
from langgraph.runtime import DEFAULT_RUNTIME, ExecutionInfo, Runtime
from langgraph.runtime import (
DEFAULT_RUNTIME,
BaseUser,
Runtime,
ServerInfo,
)
from langgraph.types import (
All,
CachePolicy,
@@ -2572,6 +2577,8 @@ class Pregel(
config = ensure_config(self.config, config)
callback_manager = get_callback_manager_for_config(config)
if "ls_integration" not in callback_manager.metadata:
callback_manager.add_metadata({"ls_integration": "langgraph"})
run_manager = callback_manager.on_chain_start(
None,
input,
@@ -2643,14 +2650,18 @@ class Pregel(
if durability is not None:
config[CONF][CONFIG_KEY_DURABILITY] = durability_
# build server_info from metadata + parent runtime
parent_runtime = config[CONF].get(CONFIG_KEY_RUNTIME, DEFAULT_RUNTIME)
server_info = _build_server_info(config, parent_runtime)
runtime = Runtime(
context=_coerce_context(self.context_schema, context),
store=store,
stream_writer=stream_writer,
previous=None,
execution_info=ExecutionInfo(),
execution_info=None,
server_info=server_info,
)
parent_runtime = config[CONF].get(CONFIG_KEY_RUNTIME, DEFAULT_RUNTIME)
runtime = parent_runtime.merge(runtime)
config[CONF][CONFIG_KEY_RUNTIME] = runtime
@@ -2909,6 +2920,8 @@ class Pregel(
config = ensure_config(self.config, config)
callback_manager = get_async_callback_manager_for_config(config)
if "ls_integration" not in callback_manager.metadata:
callback_manager.add_metadata({"ls_integration": "langgraph"})
run_manager = await callback_manager.on_chain_start(
None,
input,
@@ -3010,14 +3023,18 @@ class Pregel(
if durability is not None:
config[CONF][CONFIG_KEY_DURABILITY] = durability_
# build server_info from metadata + parent runtime
parent_runtime = config[CONF].get(CONFIG_KEY_RUNTIME, DEFAULT_RUNTIME)
server_info = _build_server_info(config, parent_runtime)
runtime = Runtime(
context=_coerce_context(self.context_schema, context),
store=store,
stream_writer=stream_writer,
previous=None,
execution_info=ExecutionInfo(),
execution_info=None,
server_info=server_info,
)
parent_runtime = config[CONF].get(CONFIG_KEY_RUNTIME, DEFAULT_RUNTIME)
runtime = parent_runtime.merge(runtime)
config[CONF][CONFIG_KEY_RUNTIME] = runtime
@@ -3639,6 +3656,38 @@ def _coerce_checkpoint_values(payload: Any, mapper: Callable[[Any], Any]) -> Non
payload["values"] = mapper(payload["values"])
def _build_server_info(
config: RunnableConfig, parent_runtime: Runtime[Any]
) -> ServerInfo | None:
"""Build ServerInfo from config metadata and configurable.
The server puts assistant_id/graph_id in config metadata and the
authenticated user dict in configurable["langgraph_auth_user"].
"""
metadata = config.get("metadata") or {}
configurable = config.get(CONF) or {}
assistant_id = metadata.get("assistant_id")
graph_id = metadata.get("graph_id")
# Read authenticated user from configurable (set by LangGraph Server).
# We prefer isinstance(BaseUser) but fall back to hasattr("identity")
# because the server's ProxyUser provides `permissions` via __getattr__,
# which Python's runtime_checkable Protocol check doesn't see.
auth_user_data = configurable.get("langgraph_auth_user")
user: BaseUser | None = None
if auth_user_data is not None:
if isinstance(auth_user_data, BaseUser) or hasattr(auth_user_data, "identity"):
user = cast(BaseUser, auth_user_data)
if assistant_id is not None or graph_id is not None or user is not None:
return ServerInfo(
assistant_id=str(assistant_id) if assistant_id else "",
graph_id=str(graph_id) if graph_id else "",
user=user,
)
return None
def _coerce_context(
context_schema: type[ContextT] | None, context: Any
) -> ContextT | None:
+64 -8
View File
@@ -1,9 +1,10 @@
from __future__ import annotations
from dataclasses import dataclass, field, replace
from typing import Any, Generic, NamedTuple, cast
from typing import Any, Generic, cast
from langgraph.store.base import BaseStore
from langgraph_sdk.auth.types import BaseUser
from typing_extensions import TypedDict, Unpack
from langgraph._internal._constants import CONF, CONFIG_KEY_RUNTIME
@@ -11,12 +12,38 @@ from langgraph.config import get_config
from langgraph.types import _DC_KWARGS, StreamWriter
from langgraph.typing import ContextT
__all__ = ("ExecutionInfo", "Runtime", "get_runtime")
__all__ = (
"BaseUser",
"ExecutionInfo",
"Runtime",
"ServerInfo",
"get_runtime",
)
class ExecutionInfo(NamedTuple):
@dataclass(frozen=True, slots=True)
class ExecutionInfo:
"""Read-only execution info/metadata for the execution of current thread/run/node."""
checkpoint_id: str
"""The checkpoint ID for the current execution."""
checkpoint_ns: str
"""The checkpoint namespace for the current execution."""
task_id: str
"""The task ID for the current execution."""
thread_id: str | None = None
"""The thread ID for the current execution.
None when running without a checkpointer (i.e., no persistence)."""
run_id: str | None = None
"""The run ID for the current execution.
None when `run_id` is not provided in the RunnableConfig."""
node_attempt: int = 1
"""Current node execution attempt number (1-indexed)."""
@@ -25,7 +52,26 @@ class ExecutionInfo(NamedTuple):
def patch(self, **overrides: Any) -> ExecutionInfo:
"""Return a new execution info object with selected fields replaced."""
return self._replace(**overrides)
return replace(self, **overrides)
@dataclass(frozen=True, slots=True)
class ServerInfo:
"""Metadata injected by LangGraph Server. None when running open-source LangGraph without LangSmith deployments."""
assistant_id: str
"""The assistant ID for the current execution."""
graph_id: str
"""The graph ID for the current execution."""
user: BaseUser | None = None
"""The authenticated user, if any.
This implements the `BaseUser` protocol from `langgraph_sdk.auth.types`,
which supports both attribute access (e.g. `user.identity`) and dict-like
access (e.g. `user["identity"]`).
"""
def _no_op_stream_writer(_: Any) -> None: ...
@@ -37,6 +83,7 @@ class _RuntimeOverrides(TypedDict, Generic[ContextT], total=False):
stream_writer: StreamWriter
previous: Any
execution_info: ExecutionInfo
server_info: ServerInfo | None
@dataclass(**_DC_KWARGS)
@@ -130,8 +177,13 @@ class Runtime(Generic[ContextT]):
Only available with the functional API when a checkpointer is provided.
"""
execution_info: ExecutionInfo = field(default_factory=ExecutionInfo)
"""Read-only execution information/metadata for the current node run."""
execution_info: ExecutionInfo | None = field(default=None)
"""Read-only execution information/metadata for the current node run.
None before task preparation populates it."""
server_info: ServerInfo | None = field(default=None)
"""Metadata injected by LangGraph Server. None when running open-source LangGraph without LangSmith deployments."""
def merge(self, other: Runtime[ContextT]) -> Runtime[ContextT]:
"""Merge two runtimes together.
@@ -145,7 +197,8 @@ class Runtime(Generic[ContextT]):
if other.stream_writer is not _no_op_stream_writer
else self.stream_writer,
previous=self.previous if other.previous is None else other.previous,
execution_info=other.execution_info,
execution_info=other.execution_info or self.execution_info,
server_info=other.server_info or self.server_info,
)
def override(
@@ -156,6 +209,9 @@ class Runtime(Generic[ContextT]):
def patch_execution_info(self, **overrides: Any) -> Runtime[ContextT]:
"""Return a new runtime with selected execution_info fields replaced."""
if self.execution_info is None:
msg = "Cannot patch execution_info before it has been set"
raise RuntimeError(msg)
return replace(
self,
execution_info=self.execution_info.patch(**overrides),
@@ -167,7 +223,7 @@ DEFAULT_RUNTIME = Runtime(
store=None,
stream_writer=_no_op_stream_writer,
previous=None,
execution_info=ExecutionInfo(),
execution_info=None,
)
+2 -2
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "langgraph"
version = "1.1.3"
version = "1.1.5"
description = "Building stateful, multi-actor applications with LLMs"
authors = []
requires-python = ">=3.10"
@@ -27,7 +27,7 @@ dependencies = [
"langchain-core>=0.1",
"langgraph-checkpoint>=2.1.0,<5.0.0",
"langgraph-sdk>=0.3.0,<0.4.0",
"langgraph-prebuilt>=1.0.8,<1.1.0",
"langgraph-prebuilt>=1.0.9,<1.1.0",
"xxhash>=3.5.0",
"pydantic>=2.7.4",
]
+3
View File
@@ -1409,6 +1409,7 @@ def test_prebuilt_tool_chat(snapshot: SnapshotAssertion) -> None:
tool_call_id="tool_call123",
),
{
"ls_integration": "langgraph",
"langgraph_step": 2,
"langgraph_node": "tools",
"langgraph_triggers": (PUSH,),
@@ -1474,6 +1475,7 @@ def test_prebuilt_tool_chat(snapshot: SnapshotAssertion) -> None:
tool_call_id="tool_call234",
),
{
"ls_integration": "langgraph",
"langgraph_step": 4,
"langgraph_node": "tools",
"langgraph_triggers": (PUSH,),
@@ -1488,6 +1490,7 @@ def test_prebuilt_tool_chat(snapshot: SnapshotAssertion) -> None:
tool_call_id="tool_call567",
),
{
"ls_integration": "langgraph",
"langgraph_step": 4,
"langgraph_node": "tools",
"langgraph_triggers": (PUSH,),
@@ -1160,6 +1160,7 @@ async def test_prebuilt_tool_chat() -> None:
tool_call_id="tool_call123",
),
{
"ls_integration": "langgraph",
"langgraph_step": 2,
"langgraph_node": "tools",
"langgraph_triggers": (PUSH,),
@@ -1225,6 +1226,7 @@ async def test_prebuilt_tool_chat() -> None:
tool_call_id="tool_call234",
),
{
"ls_integration": "langgraph",
"langgraph_step": 4,
"langgraph_node": "tools",
"langgraph_triggers": (PUSH,),
@@ -1239,6 +1241,7 @@ async def test_prebuilt_tool_chat() -> None:
tool_call_id="tool_call567",
),
{
"ls_integration": "langgraph",
"langgraph_step": 4,
"langgraph_node": "tools",
"langgraph_triggers": (PUSH,),
+3
View File
@@ -6930,6 +6930,7 @@ def test_stream_mode_messages_command() -> None:
(
_AnyIdHumanMessage(content="foo"),
{
"ls_integration": "langgraph",
"langgraph_step": 1,
"langgraph_node": "my_node",
"langgraph_triggers": ("branch:to:my_node",),
@@ -6940,6 +6941,7 @@ def test_stream_mode_messages_command() -> None:
(
_AnyIdHumanMessage(content="bar"),
{
"ls_integration": "langgraph",
"langgraph_step": 2,
"langgraph_node": "my_other_node",
"langgraph_triggers": ("branch:to:my_other_node",),
@@ -6950,6 +6952,7 @@ def test_stream_mode_messages_command() -> None:
(
_AnyIdHumanMessage(content="baz"),
{
"ls_integration": "langgraph",
"langgraph_step": 3,
"langgraph_node": "my_last_node",
"langgraph_triggers": ("branch:to:my_last_node",),
+17 -5
View File
@@ -7578,6 +7578,7 @@ async def test_stream_mode_messages_command() -> None:
(
_AnyIdHumanMessage(content="foo"),
{
"ls_integration": "langgraph",
"langgraph_step": 1,
"langgraph_node": "my_node",
"langgraph_triggers": ("branch:to:my_node",),
@@ -7588,6 +7589,7 @@ async def test_stream_mode_messages_command() -> None:
(
_AnyIdHumanMessage(content="bar"),
{
"ls_integration": "langgraph",
"langgraph_step": 2,
"langgraph_node": "my_other_node",
"langgraph_triggers": ("branch:to:my_other_node",),
@@ -8646,7 +8648,7 @@ async def test_imp_exception(
"name": "LangGraph",
"tags": [],
"run_id": AnyStr(),
"metadata": {"thread_id": "1"},
"metadata": {"thread_id": "1", "ls_integration": "langgraph"},
"parent_ids": [],
},
{
@@ -8657,6 +8659,7 @@ async def test_imp_exception(
"run_id": AnyStr(),
"metadata": {
"thread_id": "1",
"ls_integration": "langgraph",
"langgraph_step": 4,
"langgraph_node": "my_workflow",
"langgraph_triggers": ("__start__",),
@@ -8673,6 +8676,7 @@ async def test_imp_exception(
"run_id": AnyStr(),
"metadata": {
"thread_id": "1",
"ls_integration": "langgraph",
"langgraph_step": 4,
"langgraph_node": "my_task",
"langgraph_triggers": ("__pregel_push",),
@@ -8696,6 +8700,7 @@ async def test_imp_exception(
"tags": ["seq:step:1"],
"metadata": {
"thread_id": "1",
"ls_integration": "langgraph",
"langgraph_step": 4,
"langgraph_node": "my_task",
"langgraph_triggers": ("__pregel_push",),
@@ -8721,6 +8726,7 @@ async def test_imp_exception(
"tags": ["seq:step:1"],
"metadata": {
"thread_id": "1",
"ls_integration": "langgraph",
"langgraph_step": 4,
"langgraph_node": "my_task",
"langgraph_triggers": ("__pregel_push",),
@@ -8742,7 +8748,7 @@ async def test_imp_exception(
"run_id": AnyStr(),
"name": "LangGraph",
"tags": [],
"metadata": {"thread_id": "1"},
"metadata": {"thread_id": "1", "ls_integration": "langgraph"},
"data": {"chunk": {"my_task": 2}},
"parent_ids": [],
},
@@ -8754,6 +8760,7 @@ async def test_imp_exception(
"run_id": AnyStr(),
"metadata": {
"thread_id": "1",
"ls_integration": "langgraph",
"langgraph_step": 4,
"langgraph_node": "my_task",
"langgraph_triggers": ("__pregel_push",),
@@ -8778,6 +8785,7 @@ async def test_imp_exception(
"run_id": AnyStr(),
"metadata": {
"thread_id": "1",
"ls_integration": "langgraph",
"langgraph_step": 4,
"langgraph_node": "my_task",
"langgraph_triggers": ("__pregel_push",),
@@ -8801,6 +8809,7 @@ async def test_imp_exception(
"tags": ["seq:step:1"],
"metadata": {
"thread_id": "1",
"ls_integration": "langgraph",
"langgraph_step": 4,
"langgraph_node": "my_task",
"langgraph_triggers": ("__pregel_push",),
@@ -8826,6 +8835,7 @@ async def test_imp_exception(
"tags": ["seq:step:1"],
"metadata": {
"thread_id": "1",
"ls_integration": "langgraph",
"langgraph_step": 4,
"langgraph_node": "my_task",
"langgraph_triggers": ("__pregel_push",),
@@ -8849,6 +8859,7 @@ async def test_imp_exception(
"tags": ["graph:step:4"],
"metadata": {
"thread_id": "1",
"ls_integration": "langgraph",
"langgraph_step": 4,
"langgraph_node": "my_workflow",
"langgraph_triggers": ("__start__",),
@@ -8863,7 +8874,7 @@ async def test_imp_exception(
"run_id": AnyStr(),
"name": "LangGraph",
"tags": [],
"metadata": {"thread_id": "1"},
"metadata": {"thread_id": "1", "ls_integration": "langgraph"},
"data": {"chunk": {"my_task": 2}},
"parent_ids": [],
},
@@ -8875,6 +8886,7 @@ async def test_imp_exception(
"tags": ["graph:step:4"],
"metadata": {
"thread_id": "1",
"ls_integration": "langgraph",
"langgraph_step": 4,
"langgraph_node": "my_workflow",
"langgraph_triggers": ("__start__",),
@@ -8888,7 +8900,7 @@ async def test_imp_exception(
"run_id": AnyStr(),
"name": "LangGraph",
"tags": [],
"metadata": {"thread_id": "1"},
"metadata": {"thread_id": "1", "ls_integration": "langgraph"},
"data": {"chunk": {"my_workflow": "done"}},
"parent_ids": [],
},
@@ -8898,7 +8910,7 @@ async def test_imp_exception(
"run_id": AnyStr(),
"name": "LangGraph",
"tags": [],
"metadata": {"thread_id": "1"},
"metadata": {"thread_id": "1", "ls_integration": "langgraph"},
"parent_ids": [],
},
]
+63
View File
@@ -1,6 +1,7 @@
from unittest.mock import Mock, patch
import pytest
from langgraph.checkpoint.memory import MemorySaver
from typing_extensions import TypedDict
from langgraph.graph import START, StateGraph
@@ -393,3 +394,65 @@ def test_graph_with_max_attempts_exceeded():
graph.invoke({"foo": ""})
mock_sleep.assert_called_with(0.01)
def test_execution_info_identity_fields_populated_on_retry():
"""Test that thread_id, task_id, run_id, etc. are populated in execution_info during retries."""
class State(TypedDict):
foo: str
attempt_count = 0
captured_infos: list[dict] = []
def failing_node(state: State, runtime: Runtime):
nonlocal attempt_count
attempt_count += 1
info = runtime.execution_info
captured_infos.append(
{
"thread_id": info.thread_id,
"run_id": info.run_id,
"node_attempt": info.node_attempt,
"node_first_attempt_time": info.node_first_attempt_time,
"checkpoint_ns": info.checkpoint_ns,
}
)
if attempt_count < 2:
raise ValueError("Intentional failure")
return {"foo": "success"}
retry_policy = RetryPolicy(
max_attempts=3,
initial_interval=0.01,
jitter=False,
retry_on=ValueError,
)
graph = (
StateGraph(State)
.add_node("failing_node", failing_node, retry_policy=retry_policy)
.add_edge(START, "failing_node")
.compile(checkpointer=MemorySaver())
)
with patch("time.sleep"):
result = graph.invoke(
{"foo": ""},
config={"configurable": {"thread_id": "retry-thread"}},
)
assert result["foo"] == "success"
assert len(captured_infos) == 2
# Both attempts should have the same thread_id and first_attempt_time
assert captured_infos[0]["thread_id"] == "retry-thread"
assert captured_infos[1]["thread_id"] == "retry-thread"
assert (
captured_infos[0]["node_first_attempt_time"]
== captured_infos[1]["node_first_attempt_time"]
)
# node_attempt should increment
assert captured_infos[0]["node_attempt"] == 1
assert captured_infos[1]["node_attempt"] == 2
+258 -1
View File
@@ -2,11 +2,12 @@ from dataclasses import dataclass
from typing import Any
import pytest
from langgraph.checkpoint.memory import MemorySaver
from pydantic import BaseModel, ValidationError
from typing_extensions import TypedDict
from langgraph.graph import END, START, StateGraph
from langgraph.runtime import Runtime, get_runtime
from langgraph.runtime import ExecutionInfo, Runtime, ServerInfo, get_runtime
def test_injected_runtime() -> None:
@@ -389,3 +390,259 @@ def test_context_coercion_pydantic_validation_errors() -> None:
compiled.invoke(
{"message": "test"}, context={"api_key": "sk_test", "timeout": "not_an_int"}
)
# --- ExecutionInfo unit tests ---
def test_execution_info_defaults_and_patch() -> None:
info = ExecutionInfo(checkpoint_id="c1", checkpoint_ns="ns1", task_id="t1")
assert info.checkpoint_id == "c1"
assert info.checkpoint_ns == "ns1"
assert info.task_id == "t1"
assert info.thread_id is None
assert info.run_id is None
assert info.node_attempt == 1
assert info.node_first_attempt_time is None
# patch returns new instance, original unchanged
patched = info.patch(thread_id="th1", node_attempt=3, task_id="tk1")
assert patched.thread_id == "th1"
assert patched.node_attempt == 3
assert patched.task_id == "tk1"
assert info.node_attempt == 1
assert info.task_id == "t1"
# frozen
with pytest.raises(AttributeError):
info.thread_id = "t2" # type: ignore[misc]
# --- ServerInfo / Runtime unit tests ---
def test_server_info_and_runtime_merge() -> None:
si = ServerInfo(assistant_id="asst-1", graph_id="graph-1")
assert si.assistant_id == "asst-1"
assert si.user is None
# frozen
with pytest.raises(AttributeError):
si.assistant_id = "asst-2" # type: ignore[misc]
# runtime default is None
assert Runtime().server_info is None
# merge preserves server_info from self when other has None
r1 = Runtime(server_info=si)
merged = r1.merge(Runtime())
assert merged.server_info is si
# merge takes server_info from other when present
si2 = ServerInfo(assistant_id="asst-2", graph_id="graph-2")
merged2 = r1.merge(Runtime(server_info=si2))
assert merged2.server_info is si2
# --- Integration tests ---
def _make_capture_graph(
capture: dict[str, Any],
*,
checkpointer: Any = None,
) -> Any:
"""Helper: build a simple graph that captures runtime info."""
class State(TypedDict):
message: str
def capture_node(state: State, runtime: Runtime) -> dict[str, Any]:
capture["execution_info"] = runtime.execution_info
capture["server_info"] = runtime.server_info
return {"message": "done"}
graph = StateGraph(state_schema=State)
graph.add_node("capture", capture_node)
graph.add_edge(START, "capture")
graph.add_edge("capture", END)
return graph.compile(checkpointer=checkpointer)
def test_execution_info_populated_in_graph() -> None:
"""execution_info fields are populated when running with a checkpointer."""
captured: dict[str, Any] = {}
compiled = _make_capture_graph(captured, checkpointer=MemorySaver())
compiled.invoke(
{"message": "hi"},
config={"configurable": {"thread_id": "t-123"}},
)
info = captured["execution_info"]
assert info.thread_id == "t-123"
assert info.task_id is not None
assert info.checkpoint_id is not None
assert info.checkpoint_ns is not None
assert info.node_attempt == 1
assert isinstance(info.node_first_attempt_time, float)
@pytest.mark.anyio
async def test_execution_info_populated_in_graph_async() -> None:
"""execution_info fields are populated in async execution."""
captured: dict[str, Any] = {}
compiled = _make_capture_graph(captured, checkpointer=MemorySaver())
await compiled.ainvoke(
{"message": "hi"},
config={"configurable": {"thread_id": "t-xyz"}},
)
info = captured["execution_info"]
assert info.thread_id == "t-xyz"
assert info.node_attempt == 1
assert isinstance(info.node_first_attempt_time, float)
def test_server_info_from_metadata() -> None:
"""server_info is built from assistant_id/graph_id in config metadata."""
captured: dict[str, Any] = {}
compiled = _make_capture_graph(captured)
compiled.invoke(
{"message": "hi"},
config={"metadata": {"assistant_id": "asst-abc", "graph_id": "my-graph"}},
)
si = captured["server_info"]
assert si is not None
assert si.assistant_id == "asst-abc"
assert si.graph_id == "my-graph"
assert si.user is None
def test_server_info_none_without_metadata() -> None:
"""server_info is None when no assistant_id/graph_id in metadata."""
captured: dict[str, Any] = {}
compiled = _make_capture_graph(captured)
compiled.invoke({"message": "hi"})
assert captured["server_info"] is None
def test_server_info_user_from_auth_user() -> None:
"""server_info.user is populated from configurable['langgraph_auth_user'].
Tests both a proper BaseUser protocol object and a starlette-style proxy
that provides `permissions` via __getattr__ (which the Protocol isinstance
check may not see).
"""
class _ProxyUser:
"""Mimics langgraph_api's ProxyUser: identity/display_name as properties,
permissions via __getattr__."""
def __init__(self, data: dict[str, Any]) -> None:
self._data = data
@property
def identity(self) -> str:
return self._data["identity"]
@property
def display_name(self) -> str:
return self._data.get("display_name", self.identity)
@property
def is_authenticated(self) -> bool:
return True
def __getattr__(self, name: str) -> Any:
return self._data[name]
def __getitem__(self, key: str) -> Any:
return self._data[key]
def __contains__(self, key: str) -> bool:
return key in self._data
def __iter__(self) -> Any:
return iter(self._data)
proxy = _ProxyUser(
{
"identity": "proxy-user",
"display_name": "Proxy User",
"is_authenticated": True,
"permissions": ["read"],
}
)
assert not isinstance(proxy, dict)
assert hasattr(proxy, "identity")
captured: dict[str, Any] = {}
compiled = _make_capture_graph(captured)
compiled.invoke(
{"message": "hi"},
config={
"configurable": {"langgraph_auth_user": proxy},
"metadata": {"assistant_id": "asst-proxy", "graph_id": "graph-proxy"},
},
)
si = captured["server_info"]
assert si is not None
assert si.assistant_id == "asst-proxy"
assert si.user is not None
assert si.user.identity == "proxy-user"
assert si.user["display_name"] == "Proxy User"
def test_execution_info_inherited_by_subgraph() -> None:
"""execution_info is correctly populated for subgraph nodes, including namespace."""
captured_main: dict[str, Any] = {}
captured_sub: dict[str, Any] = {}
class State(TypedDict, total=False):
message: str
def subgraph_node(state: State, runtime: Runtime) -> dict[str, str]:
captured_sub["execution_info"] = runtime.execution_info
return {"message": "from_sub"}
subgraph_builder = StateGraph(State)
subgraph_builder.add_node("sub_node", subgraph_node)
subgraph_builder.add_edge(START, "sub_node")
subgraph = subgraph_builder.compile()
def main_node(state: State, runtime: Runtime) -> dict[str, str]:
captured_main["execution_info"] = runtime.execution_info
return {"message": "from_main"}
builder = StateGraph(State)
builder.add_node("main_node", main_node)
builder.add_node("subgraph", subgraph)
builder.add_edge(START, "main_node")
builder.add_edge("main_node", "subgraph")
graph = builder.compile(checkpointer=MemorySaver())
graph.invoke(
{"message": "hi"},
config={"configurable": {"thread_id": "sub-thread"}},
)
main_info = captured_main["execution_info"]
sub_info = captured_sub["execution_info"]
# Both share the same thread_id
assert main_info.thread_id == "sub-thread"
assert sub_info.thread_id == "sub-thread"
# Both have node_attempt = 1
assert main_info.node_attempt == 1
assert sub_info.node_attempt == 1
# Main namespace is "main_node:<task_id>" (top-level, no separator)
assert main_info.checkpoint_ns.startswith("main_node:")
assert "|" not in main_info.checkpoint_ns
# Subgraph namespace is "subgraph:<task_id>|sub_node:<task_id>" (nested)
assert sub_info.checkpoint_ns.startswith("subgraph:")
assert "|sub_node:" in sub_info.checkpoint_ns
# task_id appears in its own namespace segment
assert main_info.task_id in main_info.checkpoint_ns
assert sub_info.task_id in sub_info.checkpoint_ns
+60 -58
View File
@@ -524,61 +524,61 @@ toml = [
[[package]]
name = "cryptography"
version = "46.0.5"
version = "46.0.6"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cffi", marker = "python_full_version >= '3.11' and python_full_version < '3.14' and platform_python_implementation != 'PyPy'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/60/04/ee2a9e8542e4fa2773b81771ff8349ff19cdd56b7258a0cc442639052edb/cryptography-46.0.5.tar.gz", hash = "sha256:abace499247268e3757271b2f1e244b36b06f8515cf27c4d49468fc9eb16e93d", size = 750064, upload-time = "2026-02-10T19:18:38.255Z" }
sdist = { url = "https://files.pythonhosted.org/packages/a4/ba/04b1bd4218cbc58dc90ce967106d51582371b898690f3ae0402876cc4f34/cryptography-46.0.6.tar.gz", hash = "sha256:27550628a518c5c6c903d84f637fbecf287f6cb9ced3804838a1295dc1fd0759", size = 750542, upload-time = "2026-03-25T23:34:53.396Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f7/81/b0bb27f2ba931a65409c6b8a8b358a7f03c0e46eceacddff55f7c84b1f3b/cryptography-46.0.5-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:351695ada9ea9618b3500b490ad54c739860883df6c1f555e088eaf25b1bbaad", size = 7176289, upload-time = "2026-02-10T19:17:08.274Z" },
{ url = "https://files.pythonhosted.org/packages/ff/9e/6b4397a3e3d15123de3b1806ef342522393d50736c13b20ec4c9ea6693a6/cryptography-46.0.5-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c18ff11e86df2e28854939acde2d003f7984f721eba450b56a200ad90eeb0e6b", size = 4275637, upload-time = "2026-02-10T19:17:10.53Z" },
{ url = "https://files.pythonhosted.org/packages/63/e7/471ab61099a3920b0c77852ea3f0ea611c9702f651600397ac567848b897/cryptography-46.0.5-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d7e3d356b8cd4ea5aff04f129d5f66ebdc7b6f8eae802b93739ed520c47c79b", size = 4424742, upload-time = "2026-02-10T19:17:12.388Z" },
{ url = "https://files.pythonhosted.org/packages/37/53/a18500f270342d66bf7e4d9f091114e31e5ee9e7375a5aba2e85a91e0044/cryptography-46.0.5-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:50bfb6925eff619c9c023b967d5b77a54e04256c4281b0e21336a130cd7fc263", size = 4277528, upload-time = "2026-02-10T19:17:13.853Z" },
{ url = "https://files.pythonhosted.org/packages/22/29/c2e812ebc38c57b40e7c583895e73c8c5adb4d1e4a0cc4c5a4fdab2b1acc/cryptography-46.0.5-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:803812e111e75d1aa73690d2facc295eaefd4439be1023fefc4995eaea2af90d", size = 4947993, upload-time = "2026-02-10T19:17:15.618Z" },
{ url = "https://files.pythonhosted.org/packages/6b/e7/237155ae19a9023de7e30ec64e5d99a9431a567407ac21170a046d22a5a3/cryptography-46.0.5-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3ee190460e2fbe447175cda91b88b84ae8322a104fc27766ad09428754a618ed", size = 4456855, upload-time = "2026-02-10T19:17:17.221Z" },
{ url = "https://files.pythonhosted.org/packages/2d/87/fc628a7ad85b81206738abbd213b07702bcbdada1dd43f72236ef3cffbb5/cryptography-46.0.5-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:f145bba11b878005c496e93e257c1e88f154d278d2638e6450d17e0f31e558d2", size = 3984635, upload-time = "2026-02-10T19:17:18.792Z" },
{ url = "https://files.pythonhosted.org/packages/84/29/65b55622bde135aedf4565dc509d99b560ee4095e56989e815f8fd2aa910/cryptography-46.0.5-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:e9251e3be159d1020c4030bd2e5f84d6a43fe54b6c19c12f51cde9542a2817b2", size = 4277038, upload-time = "2026-02-10T19:17:20.256Z" },
{ url = "https://files.pythonhosted.org/packages/bc/36/45e76c68d7311432741faf1fbf7fac8a196a0a735ca21f504c75d37e2558/cryptography-46.0.5-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:47fb8a66058b80e509c47118ef8a75d14c455e81ac369050f20ba0d23e77fee0", size = 4912181, upload-time = "2026-02-10T19:17:21.825Z" },
{ url = "https://files.pythonhosted.org/packages/6d/1a/c1ba8fead184d6e3d5afcf03d569acac5ad063f3ac9fb7258af158f7e378/cryptography-46.0.5-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:4c3341037c136030cb46e4b1e17b7418ea4cbd9dd207e4a6f3b2b24e0d4ac731", size = 4456482, upload-time = "2026-02-10T19:17:25.133Z" },
{ url = "https://files.pythonhosted.org/packages/f9/e5/3fb22e37f66827ced3b902cf895e6a6bc1d095b5b26be26bd13c441fdf19/cryptography-46.0.5-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:890bcb4abd5a2d3f852196437129eb3667d62630333aacc13dfd470fad3aaa82", size = 4405497, upload-time = "2026-02-10T19:17:26.66Z" },
{ url = "https://files.pythonhosted.org/packages/1a/df/9d58bb32b1121a8a2f27383fabae4d63080c7ca60b9b5c88be742be04ee7/cryptography-46.0.5-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:80a8d7bfdf38f87ca30a5391c0c9ce4ed2926918e017c29ddf643d0ed2778ea1", size = 4667819, upload-time = "2026-02-10T19:17:28.569Z" },
{ url = "https://files.pythonhosted.org/packages/ea/ed/325d2a490c5e94038cdb0117da9397ece1f11201f425c4e9c57fe5b9f08b/cryptography-46.0.5-cp311-abi3-win32.whl", hash = "sha256:60ee7e19e95104d4c03871d7d7dfb3d22ef8a9b9c6778c94e1c8fcc8365afd48", size = 3028230, upload-time = "2026-02-10T19:17:30.518Z" },
{ url = "https://files.pythonhosted.org/packages/e9/5a/ac0f49e48063ab4255d9e3b79f5def51697fce1a95ea1370f03dc9db76f6/cryptography-46.0.5-cp311-abi3-win_amd64.whl", hash = "sha256:38946c54b16c885c72c4f59846be9743d699eee2b69b6988e0a00a01f46a61a4", size = 3480909, upload-time = "2026-02-10T19:17:32.083Z" },
{ url = "https://files.pythonhosted.org/packages/00/13/3d278bfa7a15a96b9dc22db5a12ad1e48a9eb3d40e1827ef66a5df75d0d0/cryptography-46.0.5-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:94a76daa32eb78d61339aff7952ea819b1734b46f73646a07decb40e5b3448e2", size = 7119287, upload-time = "2026-02-10T19:17:33.801Z" },
{ url = "https://files.pythonhosted.org/packages/67/c8/581a6702e14f0898a0848105cbefd20c058099e2c2d22ef4e476dfec75d7/cryptography-46.0.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5be7bf2fb40769e05739dd0046e7b26f9d4670badc7b032d6ce4db64dddc0678", size = 4265728, upload-time = "2026-02-10T19:17:35.569Z" },
{ url = "https://files.pythonhosted.org/packages/dd/4a/ba1a65ce8fc65435e5a849558379896c957870dd64fecea97b1ad5f46a37/cryptography-46.0.5-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fe346b143ff9685e40192a4960938545c699054ba11d4f9029f94751e3f71d87", size = 4408287, upload-time = "2026-02-10T19:17:36.938Z" },
{ url = "https://files.pythonhosted.org/packages/f8/67/8ffdbf7b65ed1ac224d1c2df3943553766914a8ca718747ee3871da6107e/cryptography-46.0.5-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:c69fd885df7d089548a42d5ec05be26050ebcd2283d89b3d30676eb32ff87dee", size = 4270291, upload-time = "2026-02-10T19:17:38.748Z" },
{ url = "https://files.pythonhosted.org/packages/f8/e5/f52377ee93bc2f2bba55a41a886fd208c15276ffbd2569f2ddc89d50e2c5/cryptography-46.0.5-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:8293f3dea7fc929ef7240796ba231413afa7b68ce38fd21da2995549f5961981", size = 4927539, upload-time = "2026-02-10T19:17:40.241Z" },
{ url = "https://files.pythonhosted.org/packages/3b/02/cfe39181b02419bbbbcf3abdd16c1c5c8541f03ca8bda240debc467d5a12/cryptography-46.0.5-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:1abfdb89b41c3be0365328a410baa9df3ff8a9110fb75e7b52e66803ddabc9a9", size = 4442199, upload-time = "2026-02-10T19:17:41.789Z" },
{ url = "https://files.pythonhosted.org/packages/c0/96/2fcaeb4873e536cf71421a388a6c11b5bc846e986b2b069c79363dc1648e/cryptography-46.0.5-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:d66e421495fdb797610a08f43b05269e0a5ea7f5e652a89bfd5a7d3c1dee3648", size = 3960131, upload-time = "2026-02-10T19:17:43.379Z" },
{ url = "https://files.pythonhosted.org/packages/d8/d2/b27631f401ddd644e94c5cf33c9a4069f72011821cf3dc7309546b0642a0/cryptography-46.0.5-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:4e817a8920bfbcff8940ecfd60f23d01836408242b30f1a708d93198393a80b4", size = 4270072, upload-time = "2026-02-10T19:17:45.481Z" },
{ url = "https://files.pythonhosted.org/packages/f4/a7/60d32b0370dae0b4ebe55ffa10e8599a2a59935b5ece1b9f06edb73abdeb/cryptography-46.0.5-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:68f68d13f2e1cb95163fa3b4db4bf9a159a418f5f6e7242564fc75fcae667fd0", size = 4892170, upload-time = "2026-02-10T19:17:46.997Z" },
{ url = "https://files.pythonhosted.org/packages/d2/b9/cf73ddf8ef1164330eb0b199a589103c363afa0cf794218c24d524a58eab/cryptography-46.0.5-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:a3d1fae9863299076f05cb8a778c467578262fae09f9dc0ee9b12eb4268ce663", size = 4441741, upload-time = "2026-02-10T19:17:48.661Z" },
{ url = "https://files.pythonhosted.org/packages/5f/eb/eee00b28c84c726fe8fa0158c65afe312d9c3b78d9d01daf700f1f6e37ff/cryptography-46.0.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c4143987a42a2397f2fc3b4d7e3a7d313fbe684f67ff443999e803dd75a76826", size = 4396728, upload-time = "2026-02-10T19:17:50.058Z" },
{ url = "https://files.pythonhosted.org/packages/65/f4/6bc1a9ed5aef7145045114b75b77c2a8261b4d38717bd8dea111a63c3442/cryptography-46.0.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:7d731d4b107030987fd61a7f8ab512b25b53cef8f233a97379ede116f30eb67d", size = 4652001, upload-time = "2026-02-10T19:17:51.54Z" },
{ url = "https://files.pythonhosted.org/packages/86/ef/5d00ef966ddd71ac2e6951d278884a84a40ffbd88948ef0e294b214ae9e4/cryptography-46.0.5-cp314-cp314t-win32.whl", hash = "sha256:c3bcce8521d785d510b2aad26ae2c966092b7daa8f45dd8f44734a104dc0bc1a", size = 3003637, upload-time = "2026-02-10T19:17:52.997Z" },
{ url = "https://files.pythonhosted.org/packages/b7/57/f3f4160123da6d098db78350fdfd9705057aad21de7388eacb2401dceab9/cryptography-46.0.5-cp314-cp314t-win_amd64.whl", hash = "sha256:4d8ae8659ab18c65ced284993c2265910f6c9e650189d4e3f68445ef82a810e4", size = 3469487, upload-time = "2026-02-10T19:17:54.549Z" },
{ url = "https://files.pythonhosted.org/packages/e2/fa/a66aa722105ad6a458bebd64086ca2b72cdd361fed31763d20390f6f1389/cryptography-46.0.5-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:4108d4c09fbbf2789d0c926eb4152ae1760d5a2d97612b92d508d96c861e4d31", size = 7170514, upload-time = "2026-02-10T19:17:56.267Z" },
{ url = "https://files.pythonhosted.org/packages/0f/04/c85bdeab78c8bc77b701bf0d9bdcf514c044e18a46dcff330df5448631b0/cryptography-46.0.5-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1f30a86d2757199cb2d56e48cce14deddf1f9c95f1ef1b64ee91ea43fe2e18", size = 4275349, upload-time = "2026-02-10T19:17:58.419Z" },
{ url = "https://files.pythonhosted.org/packages/5c/32/9b87132a2f91ee7f5223b091dc963055503e9b442c98fc0b8a5ca765fab0/cryptography-46.0.5-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:039917b0dc418bb9f6edce8a906572d69e74bd330b0b3fea4f79dab7f8ddd235", size = 4420667, upload-time = "2026-02-10T19:18:00.619Z" },
{ url = "https://files.pythonhosted.org/packages/a1/a6/a7cb7010bec4b7c5692ca6f024150371b295ee1c108bdc1c400e4c44562b/cryptography-46.0.5-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ba2a27ff02f48193fc4daeadf8ad2590516fa3d0adeeb34336b96f7fa64c1e3a", size = 4276980, upload-time = "2026-02-10T19:18:02.379Z" },
{ url = "https://files.pythonhosted.org/packages/8e/7c/c4f45e0eeff9b91e3f12dbd0e165fcf2a38847288fcfd889deea99fb7b6d/cryptography-46.0.5-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:61aa400dce22cb001a98014f647dc21cda08f7915ceb95df0c9eaf84b4b6af76", size = 4939143, upload-time = "2026-02-10T19:18:03.964Z" },
{ url = "https://files.pythonhosted.org/packages/37/19/e1b8f964a834eddb44fa1b9a9976f4e414cbb7aa62809b6760c8803d22d1/cryptography-46.0.5-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3ce58ba46e1bc2aac4f7d9290223cead56743fa6ab94a5d53292ffaac6a91614", size = 4453674, upload-time = "2026-02-10T19:18:05.588Z" },
{ url = "https://files.pythonhosted.org/packages/db/ed/db15d3956f65264ca204625597c410d420e26530c4e2943e05a0d2f24d51/cryptography-46.0.5-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:420d0e909050490d04359e7fdb5ed7e667ca5c3c402b809ae2563d7e66a92229", size = 3978801, upload-time = "2026-02-10T19:18:07.167Z" },
{ url = "https://files.pythonhosted.org/packages/41/e2/df40a31d82df0a70a0daf69791f91dbb70e47644c58581d654879b382d11/cryptography-46.0.5-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:582f5fcd2afa31622f317f80426a027f30dc792e9c80ffee87b993200ea115f1", size = 4276755, upload-time = "2026-02-10T19:18:09.813Z" },
{ url = "https://files.pythonhosted.org/packages/33/45/726809d1176959f4a896b86907b98ff4391a8aa29c0aaaf9450a8a10630e/cryptography-46.0.5-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:bfd56bb4b37ed4f330b82402f6f435845a5f5648edf1ad497da51a8452d5d62d", size = 4901539, upload-time = "2026-02-10T19:18:11.263Z" },
{ url = "https://files.pythonhosted.org/packages/99/0f/a3076874e9c88ecb2ecc31382f6e7c21b428ede6f55aafa1aa272613e3cd/cryptography-46.0.5-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:a3d507bb6a513ca96ba84443226af944b0f7f47dcc9a399d110cd6146481d24c", size = 4452794, upload-time = "2026-02-10T19:18:12.914Z" },
{ url = "https://files.pythonhosted.org/packages/02/ef/ffeb542d3683d24194a38f66ca17c0a4b8bf10631feef44a7ef64e631b1a/cryptography-46.0.5-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9f16fbdf4da055efb21c22d81b89f155f02ba420558db21288b3d0035bafd5f4", size = 4404160, upload-time = "2026-02-10T19:18:14.375Z" },
{ url = "https://files.pythonhosted.org/packages/96/93/682d2b43c1d5f1406ed048f377c0fc9fc8f7b0447a478d5c65ab3d3a66eb/cryptography-46.0.5-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:ced80795227d70549a411a4ab66e8ce307899fad2220ce5ab2f296e687eacde9", size = 4667123, upload-time = "2026-02-10T19:18:15.886Z" },
{ url = "https://files.pythonhosted.org/packages/45/2d/9c5f2926cb5300a8eefc3f4f0b3f3df39db7f7ce40c8365444c49363cbda/cryptography-46.0.5-cp38-abi3-win32.whl", hash = "sha256:02f547fce831f5096c9a567fd41bc12ca8f11df260959ecc7c3202555cc47a72", size = 3010220, upload-time = "2026-02-10T19:18:17.361Z" },
{ url = "https://files.pythonhosted.org/packages/48/ef/0c2f4a8e31018a986949d34a01115dd057bf536905dca38897bacd21fac3/cryptography-46.0.5-cp38-abi3-win_amd64.whl", hash = "sha256:556e106ee01aa13484ce9b0239bca667be5004efb0aabbed28d353df86445595", size = 3467050, upload-time = "2026-02-10T19:18:18.899Z" },
{ url = "https://files.pythonhosted.org/packages/eb/dd/2d9fdb07cebdf3d51179730afb7d5e576153c6744c3ff8fded23030c204e/cryptography-46.0.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:3b4995dc971c9fb83c25aa44cf45f02ba86f71ee600d81091c2f0cbae116b06c", size = 3476964, upload-time = "2026-02-10T19:18:20.687Z" },
{ url = "https://files.pythonhosted.org/packages/e9/6f/6cc6cc9955caa6eaf83660b0da2b077c7fe8ff9950a3c5e45d605038d439/cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:bc84e875994c3b445871ea7181d424588171efec3e185dced958dad9e001950a", size = 4218321, upload-time = "2026-02-10T19:18:22.349Z" },
{ url = "https://files.pythonhosted.org/packages/3e/5d/c4da701939eeee699566a6c1367427ab91a8b7088cc2328c09dbee940415/cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:2ae6971afd6246710480e3f15824ed3029a60fc16991db250034efd0b9fb4356", size = 4381786, upload-time = "2026-02-10T19:18:24.529Z" },
{ url = "https://files.pythonhosted.org/packages/ac/97/a538654732974a94ff96c1db621fa464f455c02d4bb7d2652f4edc21d600/cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:d861ee9e76ace6cf36a6a89b959ec08e7bc2493ee39d07ffe5acb23ef46d27da", size = 4217990, upload-time = "2026-02-10T19:18:25.957Z" },
{ url = "https://files.pythonhosted.org/packages/ae/11/7e500d2dd3ba891197b9efd2da5454b74336d64a7cc419aa7327ab74e5f6/cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:2b7a67c9cd56372f3249b39699f2ad479f6991e62ea15800973b956f4b73e257", size = 4381252, upload-time = "2026-02-10T19:18:27.496Z" },
{ url = "https://files.pythonhosted.org/packages/bc/58/6b3d24e6b9bc474a2dcdee65dfd1f008867015408a271562e4b690561a4d/cryptography-46.0.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:8456928655f856c6e1533ff59d5be76578a7157224dbd9ce6872f25055ab9ab7", size = 3407605, upload-time = "2026-02-10T19:18:29.233Z" },
{ url = "https://files.pythonhosted.org/packages/47/23/9285e15e3bc57325b0a72e592921983a701efc1ee8f91c06c5f0235d86d9/cryptography-46.0.6-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:64235194bad039a10bb6d2d930ab3323baaec67e2ce36215fd0952fad0930ca8", size = 7176401, upload-time = "2026-03-25T23:33:22.096Z" },
{ url = "https://files.pythonhosted.org/packages/60/f8/e61f8f13950ab6195b31913b42d39f0f9afc7d93f76710f299b5ec286ae6/cryptography-46.0.6-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:26031f1e5ca62fcb9d1fcb34b2b60b390d1aacaa15dc8b895a9ed00968b97b30", size = 4275275, upload-time = "2026-03-25T23:33:23.844Z" },
{ url = "https://files.pythonhosted.org/packages/19/69/732a736d12c2631e140be2348b4ad3d226302df63ef64d30dfdb8db7ad1c/cryptography-46.0.6-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9a693028b9cbe51b5a1136232ee8f2bc242e4e19d456ded3fa7c86e43c713b4a", size = 4425320, upload-time = "2026-03-25T23:33:25.703Z" },
{ url = "https://files.pythonhosted.org/packages/d4/12/123be7292674abf76b21ac1fc0e1af50661f0e5b8f0ec8285faac18eb99e/cryptography-46.0.6-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:67177e8a9f421aa2d3a170c3e56eca4e0128883cf52a071a7cbf53297f18b175", size = 4278082, upload-time = "2026-03-25T23:33:27.423Z" },
{ url = "https://files.pythonhosted.org/packages/5b/ba/d5e27f8d68c24951b0a484924a84c7cdaed7502bac9f18601cd357f8b1d2/cryptography-46.0.6-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:d9528b535a6c4f8ff37847144b8986a9a143585f0540fbcb1a98115b543aa463", size = 4926514, upload-time = "2026-03-25T23:33:29.206Z" },
{ url = "https://files.pythonhosted.org/packages/34/71/1ea5a7352ae516d5512d17babe7e1b87d9db5150b21f794b1377eac1edc0/cryptography-46.0.6-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:22259338084d6ae497a19bae5d4c66b7ca1387d3264d1c2c0e72d9e9b6a77b97", size = 4457766, upload-time = "2026-03-25T23:33:30.834Z" },
{ url = "https://files.pythonhosted.org/packages/01/59/562be1e653accee4fdad92c7a2e88fced26b3fdfce144047519bbebc299e/cryptography-46.0.6-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:760997a4b950ff00d418398ad73fbc91aa2894b5c1db7ccb45b4f68b42a63b3c", size = 3986535, upload-time = "2026-03-25T23:33:33.02Z" },
{ url = "https://files.pythonhosted.org/packages/d6/8b/b1ebfeb788bf4624d36e45ed2662b8bd43a05ff62157093c1539c1288a18/cryptography-46.0.6-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:3dfa6567f2e9e4c5dceb8ccb5a708158a2a871052fa75c8b78cb0977063f1507", size = 4277618, upload-time = "2026-03-25T23:33:34.567Z" },
{ url = "https://files.pythonhosted.org/packages/dd/52/a005f8eabdb28df57c20f84c44d397a755782d6ff6d455f05baa2785bd91/cryptography-46.0.6-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:cdcd3edcbc5d55757e5f5f3d330dd00007ae463a7e7aa5bf132d1f22a4b62b19", size = 4890802, upload-time = "2026-03-25T23:33:37.034Z" },
{ url = "https://files.pythonhosted.org/packages/ec/4d/8e7d7245c79c617d08724e2efa397737715ca0ec830ecb3c91e547302555/cryptography-46.0.6-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:d4e4aadb7fc1f88687f47ca20bb7227981b03afaae69287029da08096853b738", size = 4457425, upload-time = "2026-03-25T23:33:38.904Z" },
{ url = "https://files.pythonhosted.org/packages/1d/5c/f6c3596a1430cec6f949085f0e1a970638d76f81c3ea56d93d564d04c340/cryptography-46.0.6-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2b417edbe8877cda9022dde3a008e2deb50be9c407eef034aeeb3a8b11d9db3c", size = 4405530, upload-time = "2026-03-25T23:33:40.842Z" },
{ url = "https://files.pythonhosted.org/packages/7e/c9/9f9cea13ee2dbde070424e0c4f621c091a91ffcc504ffea5e74f0e1daeff/cryptography-46.0.6-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:380343e0653b1c9d7e1f55b52aaa2dbb2fdf2730088d48c43ca1c7c0abb7cc2f", size = 4667896, upload-time = "2026-03-25T23:33:42.781Z" },
{ url = "https://files.pythonhosted.org/packages/ad/b5/1895bc0821226f129bc74d00eccfc6a5969e2028f8617c09790bf89c185e/cryptography-46.0.6-cp311-abi3-win32.whl", hash = "sha256:bcb87663e1f7b075e48c3be3ecb5f0b46c8fc50b50a97cf264e7f60242dca3f2", size = 3026348, upload-time = "2026-03-25T23:33:45.021Z" },
{ url = "https://files.pythonhosted.org/packages/c3/f8/c9bcbf0d3e6ad288b9d9aa0b1dee04b063d19e8c4f871855a03ab3a297ab/cryptography-46.0.6-cp311-abi3-win_amd64.whl", hash = "sha256:6739d56300662c468fddb0e5e291f9b4d084bead381667b9e654c7dd81705124", size = 3483896, upload-time = "2026-03-25T23:33:46.649Z" },
{ url = "https://files.pythonhosted.org/packages/01/41/3a578f7fd5c70611c0aacba52cd13cb364a5dee895a5c1d467208a9380b0/cryptography-46.0.6-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:2ef9e69886cbb137c2aef9772c2e7138dc581fad4fcbcf13cc181eb5a3ab6275", size = 7117147, upload-time = "2026-03-25T23:33:48.249Z" },
{ url = "https://files.pythonhosted.org/packages/fa/87/887f35a6fca9dde90cad08e0de0c89263a8e59b2d2ff904fd9fcd8025b6f/cryptography-46.0.6-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7f417f034f91dcec1cb6c5c35b07cdbb2ef262557f701b4ecd803ee8cefed4f4", size = 4266221, upload-time = "2026-03-25T23:33:49.874Z" },
{ url = "https://files.pythonhosted.org/packages/aa/a8/0a90c4f0b0871e0e3d1ed126aed101328a8a57fd9fd17f00fb67e82a51ca/cryptography-46.0.6-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d24c13369e856b94892a89ddf70b332e0b70ad4a5c43cf3e9cb71d6d7ffa1f7b", size = 4408952, upload-time = "2026-03-25T23:33:52.128Z" },
{ url = "https://files.pythonhosted.org/packages/16/0b/b239701eb946523e4e9f329336e4ff32b1247e109cbab32d1a7b61da8ed7/cryptography-46.0.6-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:aad75154a7ac9039936d50cf431719a2f8d4ed3d3c277ac03f3339ded1a5e707", size = 4270141, upload-time = "2026-03-25T23:33:54.11Z" },
{ url = "https://files.pythonhosted.org/packages/0f/a8/976acdd4f0f30df7b25605f4b9d3d89295351665c2091d18224f7ad5cdbf/cryptography-46.0.6-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:3c21d92ed15e9cfc6eb64c1f5a0326db22ca9c2566ca46d845119b45b4400361", size = 4904178, upload-time = "2026-03-25T23:33:55.725Z" },
{ url = "https://files.pythonhosted.org/packages/b1/1b/bf0e01a88efd0e59679b69f42d4afd5bced8700bb5e80617b2d63a3741af/cryptography-46.0.6-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:4668298aef7cddeaf5c6ecc244c2302a2b8e40f384255505c22875eebb47888b", size = 4441812, upload-time = "2026-03-25T23:33:57.364Z" },
{ url = "https://files.pythonhosted.org/packages/bb/8b/11df86de2ea389c65aa1806f331cae145f2ed18011f30234cc10ca253de8/cryptography-46.0.6-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:8ce35b77aaf02f3b59c90b2c8a05c73bac12cea5b4e8f3fbece1f5fddea5f0ca", size = 3963923, upload-time = "2026-03-25T23:33:59.361Z" },
{ url = "https://files.pythonhosted.org/packages/91/e0/207fb177c3a9ef6a8108f234208c3e9e76a6aa8cf20d51932916bd43bda0/cryptography-46.0.6-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:c89eb37fae9216985d8734c1afd172ba4927f5a05cfd9bf0e4863c6d5465b013", size = 4269695, upload-time = "2026-03-25T23:34:00.909Z" },
{ url = "https://files.pythonhosted.org/packages/21/5e/19f3260ed1e95bced52ace7501fabcd266df67077eeb382b79c81729d2d3/cryptography-46.0.6-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:ed418c37d095aeddf5336898a132fba01091f0ac5844e3e8018506f014b6d2c4", size = 4869785, upload-time = "2026-03-25T23:34:02.796Z" },
{ url = "https://files.pythonhosted.org/packages/10/38/cd7864d79aa1d92ef6f1a584281433419b955ad5a5ba8d1eb6c872165bcb/cryptography-46.0.6-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:69cf0056d6947edc6e6760e5f17afe4bea06b56a9ac8a06de9d2bd6b532d4f3a", size = 4441404, upload-time = "2026-03-25T23:34:04.35Z" },
{ url = "https://files.pythonhosted.org/packages/09/0a/4fe7a8d25fed74419f91835cf5829ade6408fd1963c9eae9c4bce390ecbb/cryptography-46.0.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e7304c4f4e9490e11efe56af6713983460ee0780f16c63f219984dab3af9d2d", size = 4397549, upload-time = "2026-03-25T23:34:06.342Z" },
{ url = "https://files.pythonhosted.org/packages/5f/a0/7d738944eac6513cd60a8da98b65951f4a3b279b93479a7e8926d9cd730b/cryptography-46.0.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b928a3ca837c77a10e81a814a693f2295200adb3352395fad024559b7be7a736", size = 4651874, upload-time = "2026-03-25T23:34:07.916Z" },
{ url = "https://files.pythonhosted.org/packages/cb/f1/c2326781ca05208845efca38bf714f76939ae446cd492d7613808badedf1/cryptography-46.0.6-cp314-cp314t-win32.whl", hash = "sha256:97c8115b27e19e592a05c45d0dd89c57f81f841cc9880e353e0d3bf25b2139ed", size = 3001511, upload-time = "2026-03-25T23:34:09.892Z" },
{ url = "https://files.pythonhosted.org/packages/c9/57/fe4a23eb549ac9d903bd4698ffda13383808ef0876cc912bcb2838799ece/cryptography-46.0.6-cp314-cp314t-win_amd64.whl", hash = "sha256:c797e2517cb7880f8297e2c0f43bb910e91381339336f75d2c1c2cbf811b70b4", size = 3471692, upload-time = "2026-03-25T23:34:11.613Z" },
{ url = "https://files.pythonhosted.org/packages/c4/cc/f330e982852403da79008552de9906804568ae9230da8432f7496ce02b71/cryptography-46.0.6-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:12cae594e9473bca1a7aceb90536060643128bb274fcea0fc459ab90f7d1ae7a", size = 7162776, upload-time = "2026-03-25T23:34:13.308Z" },
{ url = "https://files.pythonhosted.org/packages/49/b3/dc27efd8dcc4bff583b3f01d4a3943cd8b5821777a58b3a6a5f054d61b79/cryptography-46.0.6-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:639301950939d844a9e1c4464d7e07f902fe9a7f6b215bb0d4f28584729935d8", size = 4270529, upload-time = "2026-03-25T23:34:15.019Z" },
{ url = "https://files.pythonhosted.org/packages/e6/05/e8d0e6eb4f0d83365b3cb0e00eb3c484f7348db0266652ccd84632a3d58d/cryptography-46.0.6-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ed3775295fb91f70b4027aeba878d79b3e55c0b3e97eaa4de71f8f23a9f2eb77", size = 4414827, upload-time = "2026-03-25T23:34:16.604Z" },
{ url = "https://files.pythonhosted.org/packages/2f/97/daba0f5d2dc6d855e2dcb70733c812558a7977a55dd4a6722756628c44d1/cryptography-46.0.6-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:8927ccfbe967c7df312ade694f987e7e9e22b2425976ddbf28271d7e58845290", size = 4271265, upload-time = "2026-03-25T23:34:18.586Z" },
{ url = "https://files.pythonhosted.org/packages/89/06/fe1fce39a37ac452e58d04b43b0855261dac320a2ebf8f5260dd55b201a9/cryptography-46.0.6-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:b12c6b1e1651e42ab5de8b1e00dc3b6354fdfd778e7fa60541ddacc27cd21410", size = 4916800, upload-time = "2026-03-25T23:34:20.561Z" },
{ url = "https://files.pythonhosted.org/packages/ff/8a/b14f3101fe9c3592603339eb5d94046c3ce5f7fc76d6512a2d40efd9724e/cryptography-46.0.6-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:063b67749f338ca9c5a0b7fe438a52c25f9526b851e24e6c9310e7195aad3b4d", size = 4448771, upload-time = "2026-03-25T23:34:22.406Z" },
{ url = "https://files.pythonhosted.org/packages/01/b3/0796998056a66d1973fd52ee89dc1bb3b6581960a91ad4ac705f182d398f/cryptography-46.0.6-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:02fad249cb0e090b574e30b276a3da6a149e04ee2f049725b1f69e7b8351ec70", size = 3978333, upload-time = "2026-03-25T23:34:24.281Z" },
{ url = "https://files.pythonhosted.org/packages/c5/3d/db200af5a4ffd08918cd55c08399dc6c9c50b0bc72c00a3246e099d3a849/cryptography-46.0.6-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:7e6142674f2a9291463e5e150090b95a8519b2fb6e6aaec8917dd8d094ce750d", size = 4271069, upload-time = "2026-03-25T23:34:25.895Z" },
{ url = "https://files.pythonhosted.org/packages/d7/18/61acfd5b414309d74ee838be321c636fe71815436f53c9f0334bf19064fa/cryptography-46.0.6-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:456b3215172aeefb9284550b162801d62f5f264a081049a3e94307fe20792cfa", size = 4878358, upload-time = "2026-03-25T23:34:27.67Z" },
{ url = "https://files.pythonhosted.org/packages/8b/65/5bf43286d566f8171917cae23ac6add941654ccf085d739195a4eacf1674/cryptography-46.0.6-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:341359d6c9e68834e204ceaf25936dffeafea3829ab80e9503860dcc4f4dac58", size = 4448061, upload-time = "2026-03-25T23:34:29.375Z" },
{ url = "https://files.pythonhosted.org/packages/e0/25/7e49c0fa7205cf3597e525d156a6bce5b5c9de1fd7e8cb01120e459f205a/cryptography-46.0.6-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9a9c42a2723999a710445bc0d974e345c32adfd8d2fac6d8a251fa829ad31cfb", size = 4399103, upload-time = "2026-03-25T23:34:32.036Z" },
{ url = "https://files.pythonhosted.org/packages/44/46/466269e833f1c4718d6cd496ffe20c56c9c8d013486ff66b4f69c302a68d/cryptography-46.0.6-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6617f67b1606dfd9fe4dbfa354a9508d4a6d37afe30306fe6c101b7ce3274b72", size = 4659255, upload-time = "2026-03-25T23:34:33.679Z" },
{ url = "https://files.pythonhosted.org/packages/0a/09/ddc5f630cc32287d2c953fc5d32705e63ec73e37308e5120955316f53827/cryptography-46.0.6-cp38-abi3-win32.whl", hash = "sha256:7f6690b6c55e9c5332c0b59b9c8a3fb232ebf059094c17f9019a51e9827df91c", size = 3010660, upload-time = "2026-03-25T23:34:35.418Z" },
{ url = "https://files.pythonhosted.org/packages/1b/82/ca4893968aeb2709aacfb57a30dec6fa2ab25b10fa9f064b8882ce33f599/cryptography-46.0.6-cp38-abi3-win_amd64.whl", hash = "sha256:79e865c642cfc5c0b3eb12af83c35c5aeff4fa5c672dc28c43721c2c9fdd2f0f", size = 3471160, upload-time = "2026-03-25T23:34:37.191Z" },
{ url = "https://files.pythonhosted.org/packages/2e/84/7ccff00ced5bac74b775ce0beb7d1be4e8637536b522b5df9b73ada42da2/cryptography-46.0.6-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:2ea0f37e9a9cf0df2952893ad145fd9627d326a59daec9b0802480fa3bcd2ead", size = 3475444, upload-time = "2026-03-25T23:34:38.944Z" },
{ url = "https://files.pythonhosted.org/packages/bc/1f/4c926f50df7749f000f20eede0c896769509895e2648db5da0ed55db711d/cryptography-46.0.6-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a3e84d5ec9ba01f8fd03802b2147ba77f0c8f2617b2aff254cedd551844209c8", size = 4218227, upload-time = "2026-03-25T23:34:40.871Z" },
{ url = "https://files.pythonhosted.org/packages/c6/65/707be3ffbd5f786028665c3223e86e11c4cda86023adbc56bd72b1b6bab5/cryptography-46.0.6-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:12f0fa16cc247b13c43d56d7b35287ff1569b5b1f4c5e87e92cc4fcc00cd10c0", size = 4381399, upload-time = "2026-03-25T23:34:42.609Z" },
{ url = "https://files.pythonhosted.org/packages/f3/6d/73557ed0ef7d73d04d9aba745d2c8e95218213687ee5e76b7d236a5030fc/cryptography-46.0.6-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:50575a76e2951fe7dbd1f56d181f8c5ceeeb075e9ff88e7ad997d2f42af06e7b", size = 4217595, upload-time = "2026-03-25T23:34:44.205Z" },
{ url = "https://files.pythonhosted.org/packages/9e/c5/e1594c4eec66a567c3ac4400008108a415808be2ce13dcb9a9045c92f1a0/cryptography-46.0.6-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:90e5f0a7b3be5f40c3a0a0eafb32c681d8d2c181fc2a1bdabe9b3f611d9f6b1a", size = 4380912, upload-time = "2026-03-25T23:34:46.328Z" },
{ url = "https://files.pythonhosted.org/packages/1a/89/843b53614b47f97fe1abc13f9a86efa5ec9e275292c457af1d4a60dc80e0/cryptography-46.0.6-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6728c49e3b2c180ef26f8e9f0a883a2c585638db64cf265b49c9ba10652d430e", size = 3409955, upload-time = "2026-03-25T23:34:48.465Z" },
]
[[package]]
@@ -1367,7 +1367,7 @@ wheels = [
[[package]]
name = "langgraph"
version = "1.1.3"
version = "1.1.5"
source = { editable = "." }
dependencies = [
{ name = "langchain-core" },
@@ -1691,6 +1691,7 @@ dependencies = [
{ name = "click", marker = "python_full_version < '3.14'" },
{ name = "httpx", marker = "python_full_version < '3.14'" },
{ name = "langgraph-sdk", marker = "python_full_version >= '3.11' and python_full_version < '3.14'" },
{ name = "pathspec", marker = "python_full_version < '3.14'" },
{ name = "python-dotenv", marker = "python_full_version < '3.14'" },
]
@@ -1707,6 +1708,7 @@ requires-dist = [
{ name = "langgraph-api", marker = "python_full_version >= '3.11' and extra == 'inmem'", specifier = ">=0.5.35,<0.8.0" },
{ name = "langgraph-runtime-inmem", marker = "python_full_version >= '3.11' and extra == 'inmem'", specifier = ">=0.7" },
{ name = "langgraph-sdk", marker = "python_full_version >= '3.11'", specifier = ">=0.1.0" },
{ name = "pathspec", specifier = ">=0.11.0" },
{ name = "python-dotenv", specifier = ">=0.8.0" },
]
provides-extras = ["inmem"]
@@ -1738,7 +1740,7 @@ test = [
[[package]]
name = "langgraph-prebuilt"
version = "1.0.8"
version = "1.0.9"
source = { editable = "../prebuilt" }
dependencies = [
{ name = "langchain-core" },
@@ -2871,11 +2873,11 @@ wheels = [
[[package]]
name = "pygments"
version = "2.19.2"
version = "2.20.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" }
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" },
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
]
[[package]]
@@ -3209,7 +3211,7 @@ wheels = [
[[package]]
name = "requests"
version = "2.33.0"
version = "2.33.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "certifi" },
@@ -3217,9 +3219,9 @@ dependencies = [
{ name = "idna" },
{ name = "urllib3" },
]
sdist = { url = "https://files.pythonhosted.org/packages/34/64/8860370b167a9721e8956ae116825caff829224fbca0ca6e7bf8ddef8430/requests-2.33.0.tar.gz", hash = "sha256:c7ebc5e8b0f21837386ad0e1c8fe8b829fa5f544d8df3b2253bff14ef29d7652", size = 134232, upload-time = "2026-03-25T15:10:41.586Z" }
sdist = { url = "https://files.pythonhosted.org/packages/5f/a4/98b9c7c6428a668bf7e42ebb7c79d576a1c3c1e3ae2d47e674b468388871/requests-2.33.1.tar.gz", hash = "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517", size = 134120, upload-time = "2026-03-30T16:09:15.531Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/56/5d/c814546c2333ceea4ba42262d8c4d55763003e767fa169adc693bd524478/requests-2.33.0-py3-none-any.whl", hash = "sha256:3324635456fa185245e24865e810cecec7b4caf933d7eb133dcde67d48cee69b", size = 65017, upload-time = "2026-03-25T15:10:40.382Z" },
{ url = "https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl", hash = "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a", size = 64947, upload-time = "2026-03-30T16:09:13.83Z" },
]
[[package]]
+24 -1
View File
@@ -79,11 +79,13 @@ from langchain_core.tools.base import (
TOOL_MESSAGE_BLOCK_TYPES,
ToolException,
_DirectlyInjectedToolArg,
_is_injected_arg_type,
get_all_basemodel_annotations,
)
from langgraph._internal._runnable import RunnableCallable
from langgraph.errors import GraphBubbleUp
from langgraph.graph.message import REMOVE_ALL_MESSAGES
from langgraph.runtime import ExecutionInfo, ServerInfo # noqa: TC002
from langgraph.store.base import BaseStore # noqa: TC002
from langgraph.types import Command, Send, StreamWriter
from pydantic import BaseModel, ValidationError
@@ -611,6 +613,7 @@ class _InjectedArgs:
state: dict[str, str | None]
store: str | None
runtime: str | None
all_injected_keys: set[str]
class ToolNode(RunnableCallable):
@@ -804,6 +807,8 @@ class ToolNode(RunnableCallable):
context=runtime.context,
store=runtime.store,
stream_writer=runtime.stream_writer,
execution_info=runtime.execution_info,
server_info=runtime.server_info,
)
tool_runtimes.append(tool_runtime)
@@ -836,6 +841,8 @@ class ToolNode(RunnableCallable):
context=runtime.context,
store=runtime.store,
stream_writer=runtime.stream_writer,
execution_info=runtime.execution_info,
server_info=runtime.server_info,
)
tool_runtimes.append(tool_runtime)
@@ -1377,7 +1384,15 @@ class ToolNode(RunnableCallable):
if injected.runtime:
injected_args[injected.runtime] = tool_runtime
tool_call_copy["args"] = {**tool_call_copy["args"], **injected_args}
# Strip any caller-supplied values for injected args, then add
# back only trusted values. This prevents an LLM from forging
# hidden InjectedToolArg fields via ToolCall.args.
stripped_args = {
k: v
for k, v in tool_call_copy["args"].items()
if k not in injected.all_injected_keys
}
tool_call_copy["args"] = {**stripped_args, **injected_args}
return tool_call_copy
def _validate_tool_command(
@@ -1598,6 +1613,8 @@ class ToolRuntime(_DirectlyInjectedToolArg, Generic[ContextT, StateT]):
stream_writer: StreamWriter
tool_call_id: str | None
store: BaseStore | None
execution_info: ExecutionInfo | None = None
server_info: ServerInfo | None = None
class InjectedState(InjectedToolArg):
@@ -1841,8 +1858,13 @@ def _get_all_injected_args(tool: BaseTool) -> _InjectedArgs:
state_args: dict[str, str | None] = {}
store_arg: str | None = None
runtime_arg: str | None = None
all_injected_keys: set[str] = set()
for name, type_ in all_annotations.items():
# Track all InjectedToolArg-annotated params (including custom subclasses)
if _is_injected_arg_type(type_):
all_injected_keys.add(name)
# Check for runtime (special case: parameter named "runtime")
if name == "runtime":
runtime_arg = name
@@ -1866,4 +1888,5 @@ def _get_all_injected_args(tool: BaseTool) -> _InjectedArgs:
state=state_args,
store=store_arg,
runtime=runtime_arg,
all_injected_keys=all_injected_keys,
)
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "langgraph-prebuilt"
version = "1.0.8"
version = "1.0.9"
description = "Library with high-level APIs for creating and executing LangGraph agents and tools."
authors = []
requires-python = ">=3.10"
+195 -1
View File
@@ -21,7 +21,7 @@ from langchain_core.messages import (
ToolMessage,
)
from langchain_core.runnables.config import RunnableConfig
from langchain_core.tools import BaseTool, ToolException
from langchain_core.tools import BaseTool, InjectedToolArg, ToolException
from langchain_core.tools import tool as dec_tool
from langgraph.config import get_stream_writer
from langgraph.errors import GraphBubbleUp, GraphInterrupt
@@ -59,10 +59,16 @@ def _create_mock_runtime(store: BaseStore | None = None) -> Mock:
which is injected by RunnableCallable from config["configurable"]["__pregel_runtime"].
When testing ToolNode directly (outside a graph), we need to provide this manually.
"""
from langgraph.runtime import ExecutionInfo
mock_runtime = Mock()
mock_runtime.store = store
mock_runtime.context = None
mock_runtime.stream_writer = lambda *args, **kwargs: None
mock_runtime.execution_info = ExecutionInfo(
checkpoint_id="test-cp", checkpoint_ns="", task_id="test-task"
)
mock_runtime.server_info = None
return mock_runtime
@@ -2008,3 +2014,191 @@ async def test_tool_node_inject_runtime_dynamic_tool_via_wrap_tool_call_async()
tool_message = result["messages"][-1]
assert tool_message.content == "dynamic: x=42, tool_call_id=call_dynamic_2"
assert tool_message.tool_call_id == "call_dynamic_2"
def test_tool_runtime_forwards_execution_info_and_server_info() -> None:
"""Test that execution_info and server_info are forwarded from Runtime to ToolRuntime."""
from langgraph.runtime import ExecutionInfo, ServerInfo
exec_info = ExecutionInfo(
thread_id="t-1",
checkpoint_id="cp-1",
checkpoint_ns="",
task_id="tk-1",
run_id="r-1",
)
server_info = ServerInfo(assistant_id="asst-1", graph_id="graph-1")
mock_runtime = Mock()
mock_runtime.store = None
mock_runtime.context = None
mock_runtime.stream_writer = lambda *args, **kwargs: None
mock_runtime.execution_info = exec_info
mock_runtime.server_info = server_info
captured: dict = {}
@dec_tool
def info_tool(x: int, runtime: ToolRuntime) -> str:
"""Tool that captures runtime info."""
captured["execution_info"] = runtime.execution_info
captured["server_info"] = runtime.server_info
return "ok"
node = ToolNode([info_tool])
tool_call = {
"name": "info_tool",
"args": {"x": 1},
"id": "call-1",
"type": "tool_call",
}
msg = AIMessage("", tool_calls=[tool_call])
config: RunnableConfig = {"configurable": {"__pregel_runtime": mock_runtime}}
node.invoke({"messages": [msg]}, config=config)
assert captured["execution_info"] is exec_info
assert captured["execution_info"].thread_id == "t-1"
assert captured["execution_info"].task_id == "tk-1"
assert captured["server_info"] is server_info
assert captured["server_info"].assistant_id == "asst-1"
async def test_tool_runtime_forwards_execution_info_and_server_info_async() -> None:
"""Test that execution_info and server_info are forwarded in async path."""
from langgraph.runtime import ExecutionInfo, ServerInfo
exec_info = ExecutionInfo(
thread_id="t-2",
checkpoint_id="cp-2",
checkpoint_ns="",
task_id="tk-2",
run_id="r-2",
)
server_info = ServerInfo(assistant_id="asst-2", graph_id="graph-2")
mock_runtime = Mock()
mock_runtime.store = None
mock_runtime.context = None
mock_runtime.stream_writer = lambda *args, **kwargs: None
mock_runtime.execution_info = exec_info
mock_runtime.server_info = server_info
captured: dict = {}
@dec_tool
async def info_tool_async(x: int, runtime: ToolRuntime) -> str:
"""Async tool that captures runtime info."""
captured["execution_info"] = runtime.execution_info
captured["server_info"] = runtime.server_info
return "ok"
node = ToolNode([info_tool_async])
tool_call = {
"name": "info_tool_async",
"args": {"x": 1},
"id": "call-2",
"type": "tool_call",
}
msg = AIMessage("", tool_calls=[tool_call])
config: RunnableConfig = {"configurable": {"__pregel_runtime": mock_runtime}}
await node.ainvoke({"messages": [msg]}, config=config)
assert captured["execution_info"] is exec_info
assert captured["execution_info"].thread_id == "t-2"
assert captured["server_info"] is server_info
assert captured["server_info"].graph_id == "graph-2"
# --- InjectedToolArg security tests ---
def test_tool_node_strips_plain_injected_tool_arg() -> None:
"""Plain InjectedToolArg values supplied by the LLM should be stripped."""
@dec_tool
def read_secret(
query: str,
auth: Annotated[dict, InjectedToolArg()],
) -> str:
"""Return secret data based on auth role."""
if auth.get("role") == "admin":
return "ADMIN_SECRET"
return "PUBLIC_DATA"
node = ToolNode([read_secret], handle_tool_errors=True)
# LLM tries to supply the hidden 'auth' field
tool_call = {
"name": "read_secret",
"args": {"query": "hello", "auth": {"role": "admin"}},
"id": "call-1",
"type": "tool_call",
}
msg = AIMessage("", tool_calls=[tool_call])
result = node.invoke({"messages": [msg]}, config=_create_config_with_runtime())
tool_message = result["messages"][-1]
# auth should have been stripped, so tool should fail (missing required arg)
assert "ADMIN_SECRET" not in tool_message.content
def test_tool_node_strips_custom_injected_tool_arg_subclass() -> None:
"""Custom InjectedToolArg subclasses should also be stripped."""
class InjectedAuth(InjectedToolArg):
pass
@dec_tool
def read_secret(
query: str,
auth: Annotated[dict, InjectedAuth()],
) -> str:
"""Return secret data based on auth role."""
if auth.get("role") == "admin":
return "ADMIN_SECRET"
return "PUBLIC_DATA"
node = ToolNode([read_secret], handle_tool_errors=True)
tool_call = {
"name": "read_secret",
"args": {"query": "hello", "auth": {"role": "admin"}},
"id": "call-1",
"type": "tool_call",
}
msg = AIMessage("", tool_calls=[tool_call])
result = node.invoke({"messages": [msg]}, config=_create_config_with_runtime())
tool_message = result["messages"][-1]
assert "ADMIN_SECRET" not in tool_message.content
def test_tool_node_injected_state_overwrites_llm_value() -> None:
"""InjectedState should use graph state, not LLM-supplied values."""
@dec_tool
def read_secret(
query: str,
auth: Annotated[dict, InjectedState("auth")],
) -> str:
"""Return secret data based on auth from graph state."""
if auth.get("role") == "admin":
return "ADMIN_SECRET"
return "PUBLIC_DATA"
node = ToolNode([read_secret])
# LLM tries to supply auth as admin
tool_call = {
"name": "read_secret",
"args": {"query": "hello", "auth": {"role": "admin"}},
"id": "call-1",
"type": "tool_call",
}
msg = AIMessage("", tool_calls=[tool_call])
# Graph state has auth as viewer
result = node.invoke(
{"messages": [msg], "auth": {"role": "viewer"}},
config=_create_config_with_runtime(),
)
tool_message = result["messages"][-1]
assert tool_message.content == "PUBLIC_DATA"
+5 -5
View File
@@ -268,7 +268,7 @@ wheels = [
[[package]]
name = "langgraph"
version = "1.1.3"
version = "1.1.5"
source = { editable = "../langgraph" }
dependencies = [
{ name = "langchain-core" },
@@ -490,7 +490,7 @@ test = [
[[package]]
name = "langgraph-prebuilt"
version = "1.0.8"
version = "1.0.9"
source = { editable = "." }
dependencies = [
{ name = "langchain-core" },
@@ -1149,11 +1149,11 @@ wheels = [
[[package]]
name = "pygments"
version = "2.19.2"
version = "2.20.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" }
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" },
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
]
[[package]]
+8 -8
View File
@@ -262,7 +262,7 @@ wheels = [
[[package]]
name = "langchain-core"
version = "1.2.20"
version = "1.2.22"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "jsonpatch" },
@@ -274,14 +274,14 @@ dependencies = [
{ name = "typing-extensions" },
{ name = "uuid-utils" },
]
sdist = { url = "https://files.pythonhosted.org/packages/db/41/6552a419fe549a79601e5a698d1d5ee2ca7fe93bb87fd624a16a8c1bdee3/langchain_core-1.2.20.tar.gz", hash = "sha256:c7ac8b976039b5832abb989fef058b88c270594ba331efc79e835df046e7dc44", size = 838330, upload-time = "2026-03-18T17:34:45.522Z" }
sdist = { url = "https://files.pythonhosted.org/packages/b1/a3/c4cd6827a1df46c821e7214b7f7b7a28b189e6c9b84ef15c6d629c5e3179/langchain_core-1.2.22.tar.gz", hash = "sha256:8d8f726d03d3652d403da915126626bb6250747e8ba406537d849e68b9f5d058", size = 842487, upload-time = "2026-03-24T18:48:44.9Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d9/06/08c88ddd4d6766de4e6c43111ae8f3025df383d2a4379cb938fc571b49d4/langchain_core-1.2.20-py3-none-any.whl", hash = "sha256:b65ff678f3c3dc1f1b4d03a3af5ee3b8d51f9be5181d74eb53c6c11cd9dd5e68", size = 504215, upload-time = "2026-03-18T17:34:44.087Z" },
{ url = "https://files.pythonhosted.org/packages/c7/a6/2ffacf0f1a3788f250e75d0b52a24896c413be11be3a6d42bcdf46fbea48/langchain_core-1.2.22-py3-none-any.whl", hash = "sha256:7e30d586b75918e828833b9ec1efc25465723566845dd652c277baf751e9c04b", size = 506829, upload-time = "2026-03-24T18:48:43.286Z" },
]
[[package]]
name = "langgraph"
version = "1.1.3"
version = "1.1.5"
source = { editable = "../langgraph" }
dependencies = [
{ name = "langchain-core" },
@@ -413,7 +413,7 @@ test = [
[[package]]
name = "langgraph-prebuilt"
version = "1.0.8"
version = "1.0.9"
source = { editable = "../prebuilt" }
dependencies = [
{ name = "langchain-core" },
@@ -991,11 +991,11 @@ wheels = [
[[package]]
name = "pygments"
version = "2.19.2"
version = "2.20.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" }
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" },
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
]
[[package]]