langgraph-checkpoint-tigris 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,27 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+ build/
7
+ dist/
8
+ *.egg
9
+
10
+ # Virtual environments
11
+ .venv/
12
+ venv/
13
+ env/
14
+
15
+ # Tooling caches
16
+ .pytest_cache/
17
+ .ruff_cache/
18
+ .mypy_cache/
19
+ .ty_cache/
20
+ .coverage
21
+ htmlcov/
22
+
23
+ # Editor / OS
24
+ .idea/
25
+ .vscode/
26
+ .DS_Store
27
+ </content>
@@ -0,0 +1,58 @@
1
+ # AGENTS Instructions — checkpoint-tigris
2
+
3
+ `langgraph-checkpoint-tigris`: a `BaseCheckpointSaver` backed by Tigris object
4
+ storage (S3 API), with a zero-copy bucket-fork helper for instant branching.
5
+
6
+ ## What this package is
7
+
8
+ - A standalone checkpointer backend, parallel to `checkpoint-postgres` and
9
+ `checkpoint-sqlite`. It depends only on `langgraph-checkpoint` (the base
10
+ interface). Core `langgraph` is not modified.
11
+ - Sync saver: `langgraph.checkpoint.tigris.TigrisSaver`.
12
+ - Async saver: `langgraph.checkpoint.tigris.aio.AsyncTigrisSaver`.
13
+ - Fork helper: `TigrisSaver.fork(target_bucket)` →
14
+ `langgraph/checkpoint/tigris/_fork.py`.
15
+
16
+ ## Layout
17
+
18
+ ```
19
+ langgraph/checkpoint/tigris/
20
+ __init__.py # TigrisSaver (sync) + fork()
21
+ aio.py # AsyncTigrisSaver (aioboto3)
22
+ _keys.py # pure object-key layout helpers (unit-tested, no network)
23
+ _client.py # boto3 / aioboto3 client construction (endpoint: t3.storage.dev)
24
+ _fork.py # X-Tigris-Fork-Source-Bucket fork helper
25
+ utils.py # manifest (de)serialization + filter matching
26
+ tests/ # test_keys (offline) + conformance/integration/fork (live)
27
+ ```
28
+
29
+ ## Design invariants (don't break these)
30
+
31
+ - Checkpoints are immutable and uniquely keyed by
32
+ `(thread_id, checkpoint_ns, checkpoint_id)`; `checkpoint_id` is time-sortable
33
+ so "latest" = `max()` over a prefix listing (no mutable HEAD pointer).
34
+ - Requires a **Single-region or Multi-region** bucket for strong consistency.
35
+ - Conditional writes (`If-Match` / `If-None-Match`) are for idempotency/CAS only.
36
+
37
+ ## Workflow (run inside this dir)
38
+
39
+ ```bash
40
+ uv sync
41
+ make format
42
+ make lint # ruff + ty
43
+ make test # offline unit tests; live tests auto-skip without creds
44
+ ```
45
+
46
+ Live conformance/integration/fork tests need `TIGRIS_TEST_BUCKET`,
47
+ `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` (optional `TIGRIS_ENDPOINT_URL`).
48
+
49
+ ## Source of truth
50
+
51
+ The LangGraph checkpointer conformance suite (`langgraph-checkpoint-conformance`,
52
+ installed from PyPI) is the primary correctness gate: `report.passed_all_base()`
53
+ must be True, and the `copy_thread` capability must be detected and pass. The
54
+ live conformance/integration/fork tests live in `tests/` and run only when
55
+ Tigris credentials are present in the environment.
56
+
57
+ Formatting: use single backticks for inline code in docstrings/comments (no
58
+ Sphinx-style double backticks).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Tigris Data, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,37 @@
1
+ .PHONY: test test_watch lint type format
2
+
3
+ ######################
4
+ # TESTING AND COVERAGE
5
+ ######################
6
+
7
+ TEST ?= .
8
+
9
+ test:
10
+ uv run pytest $(TEST)
11
+
12
+ test_watch:
13
+ uv run ptw $(TEST)
14
+
15
+ ######################
16
+ # LINTING AND FORMATTING
17
+ ######################
18
+
19
+ # Define a variable for Python and notebook files.
20
+ PYTHON_FILES=.
21
+ lint format: PYTHON_FILES=.
22
+ lint_diff format_diff: PYTHON_FILES=$(shell git diff --name-only --relative --diff-filter=d main . | grep -E '\.py$$|\.ipynb$$')
23
+ lint_package: PYTHON_FILES=langgraph
24
+ lint_tests: PYTHON_FILES=tests
25
+
26
+ lint lint_diff lint_package lint_tests:
27
+ uv run ruff check .
28
+ [ "$(PYTHON_FILES)" = "" ] || uv run ruff format $(PYTHON_FILES) --diff
29
+ [ "$(PYTHON_FILES)" = "" ] || uv run ruff check --select I $(PYTHON_FILES)
30
+ [ "$(PYTHON_FILES)" = "" ] || uv run ty check $(PYTHON_FILES)
31
+
32
+ type:
33
+ uv run ty check $(PYTHON_FILES)
34
+
35
+ format format_diff:
36
+ uv run ruff format $(PYTHON_FILES)
37
+ uv run ruff check --select I --fix $(PYTHON_FILES)
@@ -0,0 +1,124 @@
1
+ Metadata-Version: 2.4
2
+ Name: langgraph-checkpoint-tigris
3
+ Version: 0.1.0
4
+ Summary: Library with a Tigris object-storage implementation of LangGraph checkpoint saver, with zero-copy bucket-fork branching.
5
+ Project-URL: Homepage, https://www.tigrisdata.com/
6
+ Project-URL: Source, https://github.com/tigrisdata/tigris-langgraph/tree/main/libs/checkpoint-tigris
7
+ Project-URL: Documentation, https://www.tigrisdata.com/docs/
8
+ Author: Tigris Data, Inc.
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: agent,checkpoint,langchain,langgraph,s3,tigris
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Requires-Python: >=3.10
20
+ Requires-Dist: aioboto3>=12.3
21
+ Requires-Dist: boto3>=1.34
22
+ Requires-Dist: langgraph-checkpoint<5.0.0,>=4.1.0
23
+ Description-Content-Type: text/markdown
24
+
25
+ # LangGraph Tigris Checkpoint
26
+
27
+ Implementation of a LangGraph `BaseCheckpointSaver` that persists agent state in
28
+ [Tigris](https://www.tigrisdata.com/) globally-distributed object storage over
29
+ the S3 API (sync and async), plus a **zero-copy bucket-fork** helper for instant
30
+ branching of an entire thread's checkpoint lineage.
31
+
32
+ ## Why Tigris
33
+
34
+ - **Durable, global, cheap state** — checkpoints live in globally-replicated
35
+ object storage with no egress fees.
36
+ - **Instant branching** — `fork()` creates a zero-copy fork of the bucket, so an
37
+ agent's entire checkpoint history can be branched in O(1) for parallel
38
+ experiments, evals, or what-if exploration. Writes to the fork are isolated
39
+ from the source.
40
+ - **Pure object store** — no separate database to operate. "Latest checkpoint"
41
+ is found via a sorted list under strong consistency; conditional writes are
42
+ available for idempotency/CAS.
43
+
44
+ ## Bucket requirement
45
+
46
+ > Use a **Single-region** or **Multi-region** Tigris bucket. These provide
47
+ > strong, globally consistent reads, lists, and conditional operations, which
48
+ > this saver relies on. **Global** and **Dual-region** buckets give only
49
+ > eventual cross-region consistency and can return stale "latest" results.
50
+
51
+ ## Install
52
+
53
+ ```bash
54
+ pip install langgraph-checkpoint-tigris
55
+ ```
56
+
57
+ ## Usage
58
+
59
+ ```python
60
+ from langgraph.checkpoint.tigris import TigrisSaver
61
+
62
+ # Credentials from the standard AWS env chain
63
+ # (AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY), endpoint defaults to Tigris.
64
+ with TigrisSaver.from_conn_string("my-bucket") as checkpointer:
65
+ checkpointer.setup()
66
+ graph = builder.compile(checkpointer=checkpointer)
67
+ graph.invoke({"messages": [...]}, {"configurable": {"thread_id": "1"}})
68
+ ```
69
+
70
+ Async:
71
+
72
+ ```python
73
+ from langgraph.checkpoint.tigris.aio import AsyncTigrisSaver
74
+
75
+ async with AsyncTigrisSaver.from_conn_string("my-bucket") as checkpointer:
76
+ await checkpointer.setup()
77
+ graph = builder.compile(checkpointer=checkpointer)
78
+ await graph.ainvoke({"messages": [...]}, {"configurable": {"thread_id": "1"}})
79
+ ```
80
+
81
+ ## Instant branching with forks
82
+
83
+ ```python
84
+ with TigrisSaver.from_conn_string("prod-agent-state") as checkpointer:
85
+ # Branch the ENTIRE bucket (all threads/checkpoints) instantly.
86
+ experiment = checkpointer.fork("experiment-run-42")
87
+ # `experiment` is an isolated TigrisSaver; writes here never touch prod.
88
+ ```
89
+
90
+ ## Object layout
91
+
92
+ ```
93
+ {prefix}checkpoints/{thread}/{ns}/{checkpoint_id}/manifest.json
94
+ {prefix}checkpoints/{thread}/{ns}/{checkpoint_id}/checkpoint.bin
95
+ {prefix}checkpoints/{thread}/{ns}/{checkpoint_id}/writes/{task_id}/{idx}.bin
96
+ ```
97
+
98
+ Checkpoints are immutable and uniquely keyed; `checkpoint_id`s are time-sortable
99
+ so the latest is `max(...)` of a prefix listing — no mutable HEAD pointer.
100
+
101
+ ## Development
102
+
103
+ ```bash
104
+ cd libs/checkpoint-tigris
105
+ uv sync
106
+ make format && make lint && make test # unit tests run without creds
107
+
108
+ # Full suite (conformance + integration + fork) needs a live Tigris bucket:
109
+ TIGRIS_TEST_BUCKET=my-bucket \
110
+ AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... \
111
+ make test
112
+ ```
113
+
114
+ Integration, conformance, and fork tests are skipped automatically when those
115
+ environment variables are absent. The pure key-layout unit tests
116
+ (`tests/test_keys.py`) always run.
117
+
118
+ ## Status
119
+
120
+ The synchronous and asynchronous savers, the `copy_thread`/`acopy_thread`
121
+ branching capability, and the zero-copy `fork()` helper are implemented and
122
+ pass the LangGraph checkpointer conformance suite
123
+ (`langgraph-checkpoint-conformance`) against a live Tigris bucket. The pure
124
+ key-layout and manifest logic are additionally unit-tested offline.
@@ -0,0 +1,100 @@
1
+ # LangGraph Tigris Checkpoint
2
+
3
+ Implementation of a LangGraph `BaseCheckpointSaver` that persists agent state in
4
+ [Tigris](https://www.tigrisdata.com/) globally-distributed object storage over
5
+ the S3 API (sync and async), plus a **zero-copy bucket-fork** helper for instant
6
+ branching of an entire thread's checkpoint lineage.
7
+
8
+ ## Why Tigris
9
+
10
+ - **Durable, global, cheap state** — checkpoints live in globally-replicated
11
+ object storage with no egress fees.
12
+ - **Instant branching** — `fork()` creates a zero-copy fork of the bucket, so an
13
+ agent's entire checkpoint history can be branched in O(1) for parallel
14
+ experiments, evals, or what-if exploration. Writes to the fork are isolated
15
+ from the source.
16
+ - **Pure object store** — no separate database to operate. "Latest checkpoint"
17
+ is found via a sorted list under strong consistency; conditional writes are
18
+ available for idempotency/CAS.
19
+
20
+ ## Bucket requirement
21
+
22
+ > Use a **Single-region** or **Multi-region** Tigris bucket. These provide
23
+ > strong, globally consistent reads, lists, and conditional operations, which
24
+ > this saver relies on. **Global** and **Dual-region** buckets give only
25
+ > eventual cross-region consistency and can return stale "latest" results.
26
+
27
+ ## Install
28
+
29
+ ```bash
30
+ pip install langgraph-checkpoint-tigris
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ ```python
36
+ from langgraph.checkpoint.tigris import TigrisSaver
37
+
38
+ # Credentials from the standard AWS env chain
39
+ # (AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY), endpoint defaults to Tigris.
40
+ with TigrisSaver.from_conn_string("my-bucket") as checkpointer:
41
+ checkpointer.setup()
42
+ graph = builder.compile(checkpointer=checkpointer)
43
+ graph.invoke({"messages": [...]}, {"configurable": {"thread_id": "1"}})
44
+ ```
45
+
46
+ Async:
47
+
48
+ ```python
49
+ from langgraph.checkpoint.tigris.aio import AsyncTigrisSaver
50
+
51
+ async with AsyncTigrisSaver.from_conn_string("my-bucket") as checkpointer:
52
+ await checkpointer.setup()
53
+ graph = builder.compile(checkpointer=checkpointer)
54
+ await graph.ainvoke({"messages": [...]}, {"configurable": {"thread_id": "1"}})
55
+ ```
56
+
57
+ ## Instant branching with forks
58
+
59
+ ```python
60
+ with TigrisSaver.from_conn_string("prod-agent-state") as checkpointer:
61
+ # Branch the ENTIRE bucket (all threads/checkpoints) instantly.
62
+ experiment = checkpointer.fork("experiment-run-42")
63
+ # `experiment` is an isolated TigrisSaver; writes here never touch prod.
64
+ ```
65
+
66
+ ## Object layout
67
+
68
+ ```
69
+ {prefix}checkpoints/{thread}/{ns}/{checkpoint_id}/manifest.json
70
+ {prefix}checkpoints/{thread}/{ns}/{checkpoint_id}/checkpoint.bin
71
+ {prefix}checkpoints/{thread}/{ns}/{checkpoint_id}/writes/{task_id}/{idx}.bin
72
+ ```
73
+
74
+ Checkpoints are immutable and uniquely keyed; `checkpoint_id`s are time-sortable
75
+ so the latest is `max(...)` of a prefix listing — no mutable HEAD pointer.
76
+
77
+ ## Development
78
+
79
+ ```bash
80
+ cd libs/checkpoint-tigris
81
+ uv sync
82
+ make format && make lint && make test # unit tests run without creds
83
+
84
+ # Full suite (conformance + integration + fork) needs a live Tigris bucket:
85
+ TIGRIS_TEST_BUCKET=my-bucket \
86
+ AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... \
87
+ make test
88
+ ```
89
+
90
+ Integration, conformance, and fork tests are skipped automatically when those
91
+ environment variables are absent. The pure key-layout unit tests
92
+ (`tests/test_keys.py`) always run.
93
+
94
+ ## Status
95
+
96
+ The synchronous and asynchronous savers, the `copy_thread`/`acopy_thread`
97
+ branching capability, and the zero-copy `fork()` helper are implemented and
98
+ pass the LangGraph checkpointer conformance suite
99
+ (`langgraph-checkpoint-conformance`) against a live Tigris bucket. The pure
100
+ key-layout and manifest logic are additionally unit-tested offline.