Bump langgraph-checkpoint from 3.0.1 to 4.1.1 in /libs/langmem-cloudflare-vectorize - #59
Conversation
* add AI Search notebook * bump idna, langsmith, langgraph-sdk, urllib3 Applies the safe subset of the Dependabot PRs opened after uv.lock became tracked: - idna 3.11 -> 3.18 (#54) - langsmith 0.5.0 -> 0.11.0 (#57) - langgraph-sdk 0.3.1 -> 0.3.15 (#58) - urllib3 2.6.2 -> 2.7.0 (#55, root dev-tooling lock) Locked with per-package --upgrade-package so no unrelated resolution drift rides along. Two open Dependabot PRs are deliberately not included: - langgraph-checkpoint 4.1.1 (#59) forces langgraph 1.2.11, which forces langchain-core >= 1.5.6. langchain-core >= 1.2.11 requires uuid-utils >= 0.12.0, a compiled Rust dependency with no Pyodide/WASM wheels, so it breaks `pywrangler sync` for the Worker examples. - vcrpy 8.2.1 (#56) forces langchain-tests back from 1.1.1 to 0.3.21 on CPython, downgrading the conformance suite to satisfy a test-only recording library. Verified against langmem-cloudflare-vectorize on Python 3.10 and 3.12 in clean venvs matching CI's sync targets: lint, 14 unit tests, 8 live REST integration tests, and 11 live Worker binding tests all pass. * add Browser Run integration (Loader + Tool) with Worker binding support Adds CloudflareBrowserRunLoader (a BaseLoader) and CloudflareBrowserRunTool (a BaseTool) for Cloudflare Browser Run, covering both the REST Quick Actions API and the browser Worker binding. Loader modes: markdown, content, scrape, and crawl (REST-only -- crawl is an async job with polling and has no quickAction() equivalent). Tool modes: markdown, json, links, screenshot, pdf, snapshot, and accessibility_tree. Tool name is set per mode so agents can disambiguate. Both classes accept binding=env.BROWSER to call quickAction() from inside a Python Worker instead of the REST API. The binding path is async-only, matching the convention used by CloudflareAISearchRetriever. Also adds browser="kitesurf" to opt into the stateless agent-optimized browser runtime. It is REST-only: sent through quickAction() it is rejected as an unrecognized body key, so combining it with binding= raises ValueError. Three bugs worth calling out, all found by running against the live API rather than reasoning about it: - The nested response_format key for mode="json" is json_schema, not schema. The latter returns a 400. - quickAction() resolves to workers._workers.Response, the Python-native runtime wrapper, not a raw JS Response. It has no .arrayBuffer(); binary Quick Actions read via .bytes(), which already returns Python bytes. - The kitesurf query parameter had to be kept off the base crawl URL, since the crawl job-status poll reuses it to build the results URL. Verified: 234 unit tests; 21 live REST integration tests covering every loader and tool mode plus kitesurf; and all 10 binding-supported modes driven live through a running Python Worker via quickAction() (both Loader and Tool paths). Originally proposed as a REST-only integration in #41 by Vamshi Mugala (@vamshi694). Worker binding support did not exist when that PR was opened; this adds it, along with the snapshot and accessibility_tree modes and the expanded crawl options the API has gained since. Co-authored-by: Vamshi Mugala <vamshi@cloudflare.com> * fix Worker example startup when langsmith requires uuid_utils setup_pyodide_deps.sh removes uuid_utils from python_modules because it is a compiled Rust extension with no Pyodide/WebAssembly wheel. That was safe while the resolved langsmith did not import it. langsmith >= 0.10 added _internal/_uuid.py, which does an unconditional `from uuid_utils.compat import uuid7` at import time. langchain-core imports langsmith, so once a fresh dependency resolution picks up a newer langsmith the Worker now dies during startup, before any handler runs: ImportError: module 'langchain_core.runnables'.'base' not found (No module named 'uuid_utils') Adds a pure Python uuid_utils stub alongside the existing xxhash and ormsgpack stubs and installs it in the same step, instead of leaving a hole where the removed package used to be. The stub implements the RFC 9562 UUIDv7 layout directly and returns stdlib uuid.UUID objects, which is what uuid_utils.compat does natively. Unlike the real package it uses random rather than monotonically-counted bits, so UUIDs minted within the same millisecond are not ordered against each other; ordering across milliseconds, which is what the timestamp prefix provides, is unaffected. Verified: stub output is version 7 with the RFC 4122 variant, encodes both the implicit and explicit timestamp/nanos forms correctly, is time-ordered across milliseconds, and is collision-free over 5000 draws. The Worker binding test suite passes against a live dev server with the stub in place. * accept reasoning-only responses in the Worker reasoning test test_reasoning_content_returned asserted a non-empty content string, but some reasoning models return the whole answer inside reasoning_content and leave content empty. gpt-oss-20b does this on roughly 2 of 5 calls to /reasoning: HTTP 200, reasoning_content populated, content == "". Measured by hitting the endpoint directly outside pytest, with gpt-oss-120b as a control returning non-empty content on 5 of 5. That is a complete answer carried in the other field, not a failure, and the test is named for reasoning_content -- which was always returned correctly. Requires one of the two fields instead of content alone. Retries were not the right tool here: the model produced empty content on all three attempts of a rerun-marked run, and every other gpt-oss-20b test in the suite passes, so there was no basis for marking the model broadly flaky. Full Worker suite before: 186 passed, 1 failed. After: this class passes 20/20 with no reruns. * mark gpt-oss-20b as flaky gpt-oss-20b intermittently returns an empty content string, measured at roughly 2 of 5 calls to /reasoning outside pytest (HTTP 200, reasoning_content populated, content == "") with gpt-oss-120b as a control at 0 of 5. The reasoning test itself already accepts a reasoning-only response, so this covers the remaining surface: the model appears in MODELS and REASONING_MODELS across both the Worker and REST suites, where the same instability can surface as an empty response on any request type. * track the Worker Pyodide lockfile and pin pywrangler Three fixes for the dependency drift that broke Worker startup: pylock.toml -- the Pyodide lockfile pywrangler vendors into python_modules -- was ignored by a rule added in e35d4a7 (AI Search, #46). That was a deliberate choice, not stale boilerplate, though landing it directly under the "# Poetry" heading made it read as such. Reversing it on evidence: untracked, the file let transitive deps move on any fresh sync, which is how langsmith reached a version importing uuid_utils -- a compiled Rust package with no Pyodide wheel -- and killed Worker startup with no source change to blame. A lockfile that is not committed is not pinning anything. Only one pylock.toml exists in the repo, so the rule only ever covered this one. workers-py was unconstrained in the dev group. pywrangler enforces a minimum uv version at runtime -- 1.16.x requires uv >= 0.12.3 and hard-fails sync below it -- so an unpinned resolve can raise the floor of a developer's toolchain silently. Pinned to >=1.16.4,<2. The README listed uv as a prerequisite without a version, so that failure read as a broken checkout rather than an expected upgrade prompt. Documents the floor and the fix. uv.lock there stays ignored: it resolves the local dev venv, not what ships to the Worker. Also drops the Poetry section. Unlike pylock.toml that one is genuine boilerplate, added in 5361f93 ("Standardize gitignore") from a stock template. The repo has no poetry.lock anywhere and every package builds with hatchling, so it never guarded anything -- it just supplied the misleading heading. Verified: pywrangler sync --force succeeds with the pin, and the Worker binding tests pass against a live dev server afterwards. Applied to all three Worker examples, not just langchain-cloudflare: langmem and the D1 checkpointer had the same unpinned workers-py and the same untracked pylock.toml, so the same silent drift could land on either. * reuse the shared Pyodide stubs in the langchain-cloudflare Worker example The langmem and D1 checkpointer Worker examples already carried uuid_utils and websockets stubs, byte-identical to each other. langchain-cloudflare was the only one missing them, which is why its Worker died on the langsmith bump while langmem's Worker tests kept passing. Replaces the uuid_utils stub written for the previous commit with those examples' existing implementation so all three are identical, and adds the websockets stub, which was likewise being deleted from python_modules with nothing put back in its place. Verified: Worker binding tests pass against a live dev server afterwards. Note: the ormsgpack stub still differs between examples -- langmem and D1 use the real ormsgpack 1.12.x OPT_* values while this one uses invented ones. Harmless today because every stub ignores those flags, so left alone rather than folded into an unrelated change. * refresh langmem's lockfile for the langchain-cloudflare 0.3.8 bump langmem depends on langchain-cloudflare as a local editable path, so its lockfile still pinned 0.3.7 after the Browser Run change bumped that package to 0.3.8. The remaining diff is uv normalizing redundant environment markers (dropping `platform_python_implementation` qualifiers it no longer needs to spell out). That is a formatting change from resolving under a newer uv, not a dependency change -- no package versions move. CI installs uv with version "latest", so this brings the committed lockfile closer to what CI resolves rather than further from it. * standardize the ormsgpack stub across the Worker examples The previous commit left this one divergent. langchain-cloudflare's copy declared its own OPT_* values (OPT_SERIALIZE_NUMPY = 1, OPT_UTC_Z = 8, ...) while langmem and the D1 checkpointer use the values from real ormsgpack 1.12.x, and it was missing OPT_PASSTHROUGH_TUPLE, OPT_SERIALIZE_PYDANTIC, OPT_SORT_KEYS, OPT_DATETIME_AS_TIMESTAMP_EXT and OPT_REPLACE_SURROGATES entirely while declaring two names the real package does not export. Nothing depended on the wrong values -- every stub ignores these flags when packing -- but a caller OR-ing two options together got a combination that would not have matched the real package, and any missing name would have been an AttributeError rather than a no-op. Adopts the langmem/D1 copy verbatim. All four Pyodide stubs (ormsgpack, uuid_utils, websockets, xxhash) are now byte-identical across the three Worker examples. Verified: Worker binding and agent-tool tests, which exercise the langgraph-checkpoint serialization path, pass against a live dev server. * add Qwen 3.8 27B (closes #60) Adds @cf/qwen/qwen3.8-27b to the REST and Worker model matrices, the reasoning and vision lists, and the Worker example's supported models. 262,144-token context, reasoning, function calling and image input. No MODEL_BEHAVIORS entry is needed: get_model_behavior() matches on substring and the existing "qwen" key already maps to _REASONING_BEHAVIOR. Confirmed against the live API rather than the model card: this model returns its chain of thought in `reasoning`, not `reasoning_content` -- the same shape Nemotron uses. The extraction path already falls back to that field, so reasoning is captured without a code change. It also answers in OpenAI `choices[]` form rather than a top-level `response`. Verified: 234 unit tests, and the full REST suite at 152 passed / 74 skipped with every qwen3.8-27b case green, including vision and reasoning-with-tool-calls. * test: xfail unsupported legacy Llama behavior * docs: add locked notebook development workflow --------- Co-authored-by: Collier King <collier@example.com> Co-authored-by: Vamshi Mugala <vamshi@cloudflare.com>
Bumps [langgraph-checkpoint](https://github.com/langchain-ai/langgraph) from 3.0.1 to 4.1.1. - [Release notes](https://github.com/langchain-ai/langgraph/releases) - [Commits](langchain-ai/langgraph@checkpoint==3.0.1...checkpoint==4.1.1) --- updated-dependencies: - dependency-name: langgraph-checkpoint dependency-version: 4.1.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>
4d0f253 to
7c3a3bd
Compare
|
Closing intentionally rather than leaving a known Worker-risk update open. This lockfile bump also pulls langgraph 1.2.11 and langchain-core 1.5.6, materially expanding the change beyond langgraph-checkpoint 4.1.1. That dependency path introduces compiled uuid_utils requirements into the Pyodide/Worker environment; the normal PR CI does not run the live Worker integration suite. Revisit as a dedicated compatibility update with pywrangler sync plus the real Worker tests, rather than merging this automated lockfile-only PR. |
|
OK, I won't notify you again about this release, but will get in touch when a new version is available. If you'd rather skip all updates until the next major or minor version, let me know by commenting If you change your mind, just re-open this PR and I'll resolve any conflicts on it. |
Bumps langgraph-checkpoint from 3.0.1 to 4.1.1.
Release notes
Sourced from langgraph-checkpoint's releases.
... (truncated)
Commits
d1e2ff0release(checkpoint): 4.1.1 (#7890)e787af2release(sdk-py): 0.3.15 (#7891)604534efix(sdk-py): percent-encode caller-supplied identifiers in URL paths (#7893)346aa97fix(checkpoint): restrict lc:2 envelope revival to default constructor (#7892)82b3872chore(deps): bump the uv group across 2 directories with 1 update (#7853)fcc4ab8chore(deps): bump idna from 3.11 to 3.15 in /libs/checkpoint (#7860)701d344chore(deps): bump idna from 3.11 to 3.15 in /libs/checkpoint-postgres (#7861)2c7967cchore(deps): bump idna from 3.11 to 3.15 in /libs/cli (#7865)bf7fec0release(langgraph): 1.2.1 (#7883)8215a9dfeat(langgraph): addbefore_builtinsopt-in for stream transformers (#7882)