langgraph-checkpoint-sqlite 2.0.10__tar.gz → 3.0.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.
- {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/.gitignore +1 -0
- {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/PKG-INFO +5 -7
- {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/README.md +2 -4
- {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/langgraph/checkpoint/sqlite/__init__.py +30 -33
- {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/langgraph/checkpoint/sqlite/aio.py +33 -36
- {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/langgraph/checkpoint/sqlite/utils.py +6 -5
- {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/langgraph/store/sqlite/aio.py +80 -39
- {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/langgraph/store/sqlite/base.py +112 -69
- {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/pyproject.toml +16 -8
- {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/tests/test_aiosqlite.py +4 -13
- {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/tests/test_async_store.py +6 -6
- {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/tests/test_sqlite.py +15 -13
- {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/tests/test_store.py +56 -8
- {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/tests/test_ttl.py +76 -2
- langgraph_checkpoint_sqlite-3.0.0/uv.lock +1137 -0
- langgraph_checkpoint_sqlite-2.0.10/uv.lock +0 -1136
- {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/Makefile +0 -0
- {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/langgraph/cache/sqlite/__init__.py +0 -0
- {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/langgraph/checkpoint/sqlite/py.typed +0 -0
- {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/langgraph/store/sqlite/__init__.py +0 -0
- {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/tests/__init__.py +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: langgraph-checkpoint-sqlite
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0.0
|
|
4
4
|
Summary: Library with a SQLite implementation of LangGraph checkpoint saver.
|
|
5
5
|
Project-URL: Repository, https://www.github.com/langchain-ai/langgraph
|
|
6
6
|
License-Expression: MIT
|
|
7
|
-
Requires-Python: >=3.
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
8
|
Requires-Dist: aiosqlite>=0.20
|
|
9
|
-
Requires-Dist: langgraph-checkpoint
|
|
9
|
+
Requires-Dist: langgraph-checkpoint<4.0.0,>=3
|
|
10
10
|
Requires-Dist: sqlite-vec>=0.1.6
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
|
|
@@ -24,7 +24,7 @@ read_config = {"configurable": {"thread_id": "1"}}
|
|
|
24
24
|
|
|
25
25
|
with SqliteSaver.from_conn_string(":memory:") as checkpointer:
|
|
26
26
|
checkpoint = {
|
|
27
|
-
"v":
|
|
27
|
+
"v": 4,
|
|
28
28
|
"ts": "2024-07-31T20:14:19.804150+00:00",
|
|
29
29
|
"id": "1ef4f797-8335-6428-8001-8a1503f9b875",
|
|
30
30
|
"channel_values": {
|
|
@@ -46,7 +46,6 @@ with SqliteSaver.from_conn_string(":memory:") as checkpointer:
|
|
|
46
46
|
"start:node": 2
|
|
47
47
|
}
|
|
48
48
|
},
|
|
49
|
-
"pending_sends": [],
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
# store checkpoint
|
|
@@ -66,7 +65,7 @@ from langgraph.checkpoint.sqlite.aio import AsyncSqliteSaver
|
|
|
66
65
|
|
|
67
66
|
async with AsyncSqliteSaver.from_conn_string(":memory:") as checkpointer:
|
|
68
67
|
checkpoint = {
|
|
69
|
-
"v":
|
|
68
|
+
"v": 4,
|
|
70
69
|
"ts": "2024-07-31T20:14:19.804150+00:00",
|
|
71
70
|
"id": "1ef4f797-8335-6428-8001-8a1503f9b875",
|
|
72
71
|
"channel_values": {
|
|
@@ -88,7 +87,6 @@ async with AsyncSqliteSaver.from_conn_string(":memory:") as checkpointer:
|
|
|
88
87
|
"start:node": 2
|
|
89
88
|
}
|
|
90
89
|
},
|
|
91
|
-
"pending_sends": [],
|
|
92
90
|
}
|
|
93
91
|
|
|
94
92
|
# store checkpoint
|
|
@@ -12,7 +12,7 @@ read_config = {"configurable": {"thread_id": "1"}}
|
|
|
12
12
|
|
|
13
13
|
with SqliteSaver.from_conn_string(":memory:") as checkpointer:
|
|
14
14
|
checkpoint = {
|
|
15
|
-
"v":
|
|
15
|
+
"v": 4,
|
|
16
16
|
"ts": "2024-07-31T20:14:19.804150+00:00",
|
|
17
17
|
"id": "1ef4f797-8335-6428-8001-8a1503f9b875",
|
|
18
18
|
"channel_values": {
|
|
@@ -34,7 +34,6 @@ with SqliteSaver.from_conn_string(":memory:") as checkpointer:
|
|
|
34
34
|
"start:node": 2
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
|
-
"pending_sends": [],
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
# store checkpoint
|
|
@@ -54,7 +53,7 @@ from langgraph.checkpoint.sqlite.aio import AsyncSqliteSaver
|
|
|
54
53
|
|
|
55
54
|
async with AsyncSqliteSaver.from_conn_string(":memory:") as checkpointer:
|
|
56
55
|
checkpoint = {
|
|
57
|
-
"v":
|
|
56
|
+
"v": 4,
|
|
58
57
|
"ts": "2024-07-31T20:14:19.804150+00:00",
|
|
59
58
|
"id": "1ef4f797-8335-6428-8001-8a1503f9b875",
|
|
60
59
|
"channel_values": {
|
|
@@ -76,7 +75,6 @@ async with AsyncSqliteSaver.from_conn_string(":memory:") as checkpointer:
|
|
|
76
75
|
"start:node": 2
|
|
77
76
|
}
|
|
78
77
|
},
|
|
79
|
-
"pending_sends": [],
|
|
80
78
|
}
|
|
81
79
|
|
|
82
80
|
# store checkpoint
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
1
4
|
import random
|
|
2
5
|
import sqlite3
|
|
3
6
|
import threading
|
|
4
7
|
from collections.abc import AsyncIterator, Iterator, Sequence
|
|
5
8
|
from contextlib import closing, contextmanager
|
|
6
|
-
from typing import Any,
|
|
9
|
+
from typing import Any, cast
|
|
7
10
|
|
|
8
11
|
from langchain_core.runnables import RunnableConfig
|
|
9
|
-
|
|
10
12
|
from langgraph.checkpoint.base import (
|
|
11
13
|
WRITES_IDX_MAP,
|
|
12
14
|
BaseCheckpointSaver,
|
|
@@ -19,7 +21,7 @@ from langgraph.checkpoint.base import (
|
|
|
19
21
|
get_checkpoint_metadata,
|
|
20
22
|
)
|
|
21
23
|
from langgraph.checkpoint.serde.jsonplus import JsonPlusSerializer
|
|
22
|
-
|
|
24
|
+
|
|
23
25
|
from langgraph.checkpoint.sqlite.utils import search_where
|
|
24
26
|
|
|
25
27
|
_AIO_ERROR_MSG = (
|
|
@@ -28,7 +30,7 @@ _AIO_ERROR_MSG = (
|
|
|
28
30
|
"from langgraph.checkpoint.sqlite.aio import AsyncSqliteSaver\n"
|
|
29
31
|
"Note: AsyncSqliteSaver requires the aiosqlite package to use.\n"
|
|
30
32
|
"Install with:\n`pip install aiosqlite`\n"
|
|
31
|
-
"See https://langchain-ai.github.io/langgraph/reference/checkpoints
|
|
33
|
+
"See https://langchain-ai.github.io/langgraph/reference/checkpoints/#langgraph.checkpoint.sqlite.aio.AsyncSqliteSaver"
|
|
32
34
|
"for more information."
|
|
33
35
|
)
|
|
34
36
|
|
|
@@ -77,7 +79,7 @@ class SqliteSaver(BaseCheckpointSaver[str]):
|
|
|
77
79
|
self,
|
|
78
80
|
conn: sqlite3.Connection,
|
|
79
81
|
*,
|
|
80
|
-
serde:
|
|
82
|
+
serde: SerializerProtocol | None = None,
|
|
81
83
|
) -> None:
|
|
82
84
|
super().__init__(serde=serde)
|
|
83
85
|
self.jsonplus_serde = JsonPlusSerializer()
|
|
@@ -87,7 +89,7 @@ class SqliteSaver(BaseCheckpointSaver[str]):
|
|
|
87
89
|
|
|
88
90
|
@classmethod
|
|
89
91
|
@contextmanager
|
|
90
|
-
def from_conn_string(cls, conn_string: str) -> Iterator[
|
|
92
|
+
def from_conn_string(cls, conn_string: str) -> Iterator[SqliteSaver]:
|
|
91
93
|
"""Create a new SqliteSaver instance from a connection string.
|
|
92
94
|
|
|
93
95
|
Args:
|
|
@@ -179,11 +181,11 @@ class SqliteSaver(BaseCheckpointSaver[str]):
|
|
|
179
181
|
self.conn.commit()
|
|
180
182
|
cur.close()
|
|
181
183
|
|
|
182
|
-
def get_tuple(self, config: RunnableConfig) ->
|
|
184
|
+
def get_tuple(self, config: RunnableConfig) -> CheckpointTuple | None:
|
|
183
185
|
"""Get a checkpoint tuple from the database.
|
|
184
186
|
|
|
185
187
|
This method retrieves a checkpoint tuple from the SQLite database based on the
|
|
186
|
-
provided config. If the config contains a
|
|
188
|
+
provided config. If the config contains a `checkpoint_id` key, the checkpoint with
|
|
187
189
|
the matching thread ID and checkpoint ID is retrieved. Otherwise, the latest checkpoint
|
|
188
190
|
for the given thread ID is retrieved.
|
|
189
191
|
|
|
@@ -191,7 +193,7 @@ class SqliteSaver(BaseCheckpointSaver[str]):
|
|
|
191
193
|
config: The config to use for retrieving the checkpoint.
|
|
192
194
|
|
|
193
195
|
Returns:
|
|
194
|
-
|
|
196
|
+
The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
|
195
197
|
|
|
196
198
|
Examples:
|
|
197
199
|
|
|
@@ -264,9 +266,7 @@ class SqliteSaver(BaseCheckpointSaver[str]):
|
|
|
264
266
|
self.serde.loads_typed((type, checkpoint)),
|
|
265
267
|
cast(
|
|
266
268
|
CheckpointMetadata,
|
|
267
|
-
|
|
268
|
-
if metadata is not None
|
|
269
|
-
else {},
|
|
269
|
+
json.loads(metadata) if metadata is not None else {},
|
|
270
270
|
),
|
|
271
271
|
(
|
|
272
272
|
{
|
|
@@ -287,11 +287,11 @@ class SqliteSaver(BaseCheckpointSaver[str]):
|
|
|
287
287
|
|
|
288
288
|
def list(
|
|
289
289
|
self,
|
|
290
|
-
config:
|
|
290
|
+
config: RunnableConfig | None,
|
|
291
291
|
*,
|
|
292
|
-
filter:
|
|
293
|
-
before:
|
|
294
|
-
limit:
|
|
292
|
+
filter: dict[str, Any] | None = None,
|
|
293
|
+
before: RunnableConfig | None = None,
|
|
294
|
+
limit: int | None = None,
|
|
295
295
|
) -> Iterator[CheckpointTuple]:
|
|
296
296
|
"""List checkpoints from the database.
|
|
297
297
|
|
|
@@ -300,12 +300,12 @@ class SqliteSaver(BaseCheckpointSaver[str]):
|
|
|
300
300
|
|
|
301
301
|
Args:
|
|
302
302
|
config: The config to use for listing the checkpoints.
|
|
303
|
-
filter: Additional filtering criteria for metadata.
|
|
304
|
-
before: If provided, only checkpoints before the specified checkpoint ID are returned.
|
|
305
|
-
limit: The maximum number of checkpoints to return.
|
|
303
|
+
filter: Additional filtering criteria for metadata.
|
|
304
|
+
before: If provided, only checkpoints before the specified checkpoint ID are returned.
|
|
305
|
+
limit: The maximum number of checkpoints to return.
|
|
306
306
|
|
|
307
307
|
Yields:
|
|
308
|
-
|
|
308
|
+
An iterator of checkpoint tuples.
|
|
309
309
|
|
|
310
310
|
Examples:
|
|
311
311
|
>>> from langgraph.checkpoint.sqlite import SqliteSaver
|
|
@@ -357,9 +357,7 @@ class SqliteSaver(BaseCheckpointSaver[str]):
|
|
|
357
357
|
self.serde.loads_typed((type, checkpoint)),
|
|
358
358
|
cast(
|
|
359
359
|
CheckpointMetadata,
|
|
360
|
-
|
|
361
|
-
if metadata is not None
|
|
362
|
-
else {},
|
|
360
|
+
json.loads(metadata) if metadata is not None else {},
|
|
363
361
|
),
|
|
364
362
|
(
|
|
365
363
|
{
|
|
@@ -412,9 +410,9 @@ class SqliteSaver(BaseCheckpointSaver[str]):
|
|
|
412
410
|
thread_id = config["configurable"]["thread_id"]
|
|
413
411
|
checkpoint_ns = config["configurable"]["checkpoint_ns"]
|
|
414
412
|
type_, serialized_checkpoint = self.serde.dumps_typed(checkpoint)
|
|
415
|
-
serialized_metadata =
|
|
416
|
-
get_checkpoint_metadata(config, metadata)
|
|
417
|
-
)
|
|
413
|
+
serialized_metadata = json.dumps(
|
|
414
|
+
get_checkpoint_metadata(config, metadata), ensure_ascii=False
|
|
415
|
+
).encode("utf-8", "ignore")
|
|
418
416
|
with self.cursor() as cur:
|
|
419
417
|
cur.execute(
|
|
420
418
|
"INSERT OR REPLACE INTO checkpoints (thread_id, checkpoint_ns, checkpoint_id, parent_checkpoint_id, type, checkpoint, metadata) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
|
@@ -494,7 +492,7 @@ class SqliteSaver(BaseCheckpointSaver[str]):
|
|
|
494
492
|
(str(thread_id),),
|
|
495
493
|
)
|
|
496
494
|
|
|
497
|
-
async def aget_tuple(self, config: RunnableConfig) ->
|
|
495
|
+
async def aget_tuple(self, config: RunnableConfig) -> CheckpointTuple | None:
|
|
498
496
|
"""Get a checkpoint tuple from the database asynchronously.
|
|
499
497
|
|
|
500
498
|
Note:
|
|
@@ -505,11 +503,11 @@ class SqliteSaver(BaseCheckpointSaver[str]):
|
|
|
505
503
|
|
|
506
504
|
async def alist(
|
|
507
505
|
self,
|
|
508
|
-
config:
|
|
506
|
+
config: RunnableConfig | None,
|
|
509
507
|
*,
|
|
510
|
-
filter:
|
|
511
|
-
before:
|
|
512
|
-
limit:
|
|
508
|
+
filter: dict[str, Any] | None = None,
|
|
509
|
+
before: RunnableConfig | None = None,
|
|
510
|
+
limit: int | None = None,
|
|
513
511
|
) -> AsyncIterator[CheckpointTuple]:
|
|
514
512
|
"""List checkpoints from the database asynchronously.
|
|
515
513
|
|
|
@@ -535,14 +533,13 @@ class SqliteSaver(BaseCheckpointSaver[str]):
|
|
|
535
533
|
"""
|
|
536
534
|
raise NotImplementedError(_AIO_ERROR_MSG)
|
|
537
535
|
|
|
538
|
-
def get_next_version(self, current:
|
|
536
|
+
def get_next_version(self, current: str | None, channel: None) -> str:
|
|
539
537
|
"""Generate the next version ID for a channel.
|
|
540
538
|
|
|
541
539
|
This method creates a new version identifier for a channel based on its current version.
|
|
542
540
|
|
|
543
541
|
Args:
|
|
544
542
|
current (Optional[str]): The current version identifier of the channel.
|
|
545
|
-
channel (BaseChannel): The channel being versioned.
|
|
546
543
|
|
|
547
544
|
Returns:
|
|
548
545
|
str: The next version identifier, which is guaranteed to be monotonically increasing.
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import asyncio
|
|
4
|
+
import json
|
|
2
5
|
import random
|
|
3
|
-
from collections.abc import AsyncIterator, Iterator, Sequence
|
|
6
|
+
from collections.abc import AsyncIterator, Callable, Iterator, Sequence
|
|
4
7
|
from contextlib import asynccontextmanager
|
|
5
|
-
from typing import Any,
|
|
8
|
+
from typing import Any, TypeVar, cast
|
|
6
9
|
|
|
7
10
|
import aiosqlite
|
|
8
11
|
from langchain_core.runnables import RunnableConfig
|
|
9
|
-
|
|
10
12
|
from langgraph.checkpoint.base import (
|
|
11
13
|
WRITES_IDX_MAP,
|
|
12
14
|
BaseCheckpointSaver,
|
|
@@ -19,7 +21,7 @@ from langgraph.checkpoint.base import (
|
|
|
19
21
|
get_checkpoint_metadata,
|
|
20
22
|
)
|
|
21
23
|
from langgraph.checkpoint.serde.jsonplus import JsonPlusSerializer
|
|
22
|
-
|
|
24
|
+
|
|
23
25
|
from langgraph.checkpoint.sqlite.utils import search_where
|
|
24
26
|
|
|
25
27
|
T = TypeVar("T", bound=Callable)
|
|
@@ -109,7 +111,7 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|
|
109
111
|
self,
|
|
110
112
|
conn: aiosqlite.Connection,
|
|
111
113
|
*,
|
|
112
|
-
serde:
|
|
114
|
+
serde: SerializerProtocol | None = None,
|
|
113
115
|
):
|
|
114
116
|
super().__init__(serde=serde)
|
|
115
117
|
self.jsonplus_serde = JsonPlusSerializer()
|
|
@@ -122,7 +124,7 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|
|
122
124
|
@asynccontextmanager
|
|
123
125
|
async def from_conn_string(
|
|
124
126
|
cls, conn_string: str
|
|
125
|
-
) -> AsyncIterator[
|
|
127
|
+
) -> AsyncIterator[AsyncSqliteSaver]:
|
|
126
128
|
"""Create a new AsyncSqliteSaver instance from a connection string.
|
|
127
129
|
|
|
128
130
|
Args:
|
|
@@ -134,11 +136,11 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|
|
134
136
|
async with aiosqlite.connect(conn_string) as conn:
|
|
135
137
|
yield cls(conn)
|
|
136
138
|
|
|
137
|
-
def get_tuple(self, config: RunnableConfig) ->
|
|
139
|
+
def get_tuple(self, config: RunnableConfig) -> CheckpointTuple | None:
|
|
138
140
|
"""Get a checkpoint tuple from the database.
|
|
139
141
|
|
|
140
142
|
This method retrieves a checkpoint tuple from the SQLite database based on the
|
|
141
|
-
provided config. If the config contains a
|
|
143
|
+
provided config. If the config contains a `checkpoint_id` key, the checkpoint with
|
|
142
144
|
the matching thread ID and checkpoint ID is retrieved. Otherwise, the latest checkpoint
|
|
143
145
|
for the given thread ID is retrieved.
|
|
144
146
|
|
|
@@ -146,7 +148,7 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|
|
146
148
|
config: The config to use for retrieving the checkpoint.
|
|
147
149
|
|
|
148
150
|
Returns:
|
|
149
|
-
|
|
151
|
+
The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
|
150
152
|
"""
|
|
151
153
|
try:
|
|
152
154
|
# check if we are in the main thread, only bg threads can block
|
|
@@ -166,11 +168,11 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|
|
166
168
|
|
|
167
169
|
def list(
|
|
168
170
|
self,
|
|
169
|
-
config:
|
|
171
|
+
config: RunnableConfig | None,
|
|
170
172
|
*,
|
|
171
|
-
filter:
|
|
172
|
-
before:
|
|
173
|
-
limit:
|
|
173
|
+
filter: dict[str, Any] | None = None,
|
|
174
|
+
before: RunnableConfig | None = None,
|
|
175
|
+
limit: int | None = None,
|
|
174
176
|
) -> Iterator[CheckpointTuple]:
|
|
175
177
|
"""List checkpoints from the database asynchronously.
|
|
176
178
|
|
|
@@ -180,11 +182,11 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|
|
180
182
|
Args:
|
|
181
183
|
config: Base configuration for filtering checkpoints.
|
|
182
184
|
filter: Additional filtering criteria for metadata.
|
|
183
|
-
before: If provided, only checkpoints before the specified checkpoint ID are returned.
|
|
185
|
+
before: If provided, only checkpoints before the specified checkpoint ID are returned.
|
|
184
186
|
limit: Maximum number of checkpoints to return.
|
|
185
187
|
|
|
186
188
|
Yields:
|
|
187
|
-
|
|
189
|
+
An iterator of matching checkpoint tuples.
|
|
188
190
|
"""
|
|
189
191
|
try:
|
|
190
192
|
# check if we are in the main thread, only bg threads can block
|
|
@@ -202,7 +204,7 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|
|
202
204
|
while True:
|
|
203
205
|
try:
|
|
204
206
|
yield asyncio.run_coroutine_threadsafe(
|
|
205
|
-
anext(aiter_), # noqa: F821
|
|
207
|
+
anext(aiter_), # type: ignore[arg-type] # noqa: F821
|
|
206
208
|
self.loop,
|
|
207
209
|
).result()
|
|
208
210
|
except StopAsyncIteration:
|
|
@@ -311,11 +313,11 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|
|
311
313
|
|
|
312
314
|
self.is_setup = True
|
|
313
315
|
|
|
314
|
-
async def aget_tuple(self, config: RunnableConfig) ->
|
|
316
|
+
async def aget_tuple(self, config: RunnableConfig) -> CheckpointTuple | None:
|
|
315
317
|
"""Get a checkpoint tuple from the database asynchronously.
|
|
316
318
|
|
|
317
319
|
This method retrieves a checkpoint tuple from the SQLite database based on the
|
|
318
|
-
provided config. If the config contains a
|
|
320
|
+
provided config. If the config contains a `checkpoint_id` key, the checkpoint with
|
|
319
321
|
the matching thread ID and checkpoint ID is retrieved. Otherwise, the latest checkpoint
|
|
320
322
|
for the given thread ID is retrieved.
|
|
321
323
|
|
|
@@ -323,7 +325,7 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|
|
323
325
|
config: The config to use for retrieving the checkpoint.
|
|
324
326
|
|
|
325
327
|
Returns:
|
|
326
|
-
|
|
328
|
+
The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
|
327
329
|
"""
|
|
328
330
|
await self.setup()
|
|
329
331
|
checkpoint_ns = config["configurable"].get("checkpoint_ns", "")
|
|
@@ -376,9 +378,7 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|
|
376
378
|
self.serde.loads_typed((type, checkpoint)),
|
|
377
379
|
cast(
|
|
378
380
|
CheckpointMetadata,
|
|
379
|
-
|
|
380
|
-
if metadata is not None
|
|
381
|
-
else {},
|
|
381
|
+
(json.loads(metadata) if metadata is not None else {}),
|
|
382
382
|
),
|
|
383
383
|
(
|
|
384
384
|
{
|
|
@@ -399,11 +399,11 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|
|
399
399
|
|
|
400
400
|
async def alist(
|
|
401
401
|
self,
|
|
402
|
-
config:
|
|
402
|
+
config: RunnableConfig | None,
|
|
403
403
|
*,
|
|
404
|
-
filter:
|
|
405
|
-
before:
|
|
406
|
-
limit:
|
|
404
|
+
filter: dict[str, Any] | None = None,
|
|
405
|
+
before: RunnableConfig | None = None,
|
|
406
|
+
limit: int | None = None,
|
|
407
407
|
) -> AsyncIterator[CheckpointTuple]:
|
|
408
408
|
"""List checkpoints from the database asynchronously.
|
|
409
409
|
|
|
@@ -413,11 +413,11 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|
|
413
413
|
Args:
|
|
414
414
|
config: Base configuration for filtering checkpoints.
|
|
415
415
|
filter: Additional filtering criteria for metadata.
|
|
416
|
-
before: If provided, only checkpoints before the specified checkpoint ID are returned.
|
|
416
|
+
before: If provided, only checkpoints before the specified checkpoint ID are returned.
|
|
417
417
|
limit: Maximum number of checkpoints to return.
|
|
418
418
|
|
|
419
419
|
Yields:
|
|
420
|
-
|
|
420
|
+
An asynchronous iterator of matching checkpoint tuples.
|
|
421
421
|
"""
|
|
422
422
|
await self.setup()
|
|
423
423
|
where, params = search_where(config, filter, before)
|
|
@@ -456,9 +456,7 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|
|
456
456
|
self.serde.loads_typed((type, checkpoint)),
|
|
457
457
|
cast(
|
|
458
458
|
CheckpointMetadata,
|
|
459
|
-
|
|
460
|
-
if metadata is not None
|
|
461
|
-
else {},
|
|
459
|
+
(json.loads(metadata) if metadata is not None else {}),
|
|
462
460
|
),
|
|
463
461
|
(
|
|
464
462
|
{
|
|
@@ -502,9 +500,9 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|
|
502
500
|
thread_id = config["configurable"]["thread_id"]
|
|
503
501
|
checkpoint_ns = config["configurable"]["checkpoint_ns"]
|
|
504
502
|
type_, serialized_checkpoint = self.serde.dumps_typed(checkpoint)
|
|
505
|
-
serialized_metadata =
|
|
506
|
-
get_checkpoint_metadata(config, metadata)
|
|
507
|
-
)
|
|
503
|
+
serialized_metadata = json.dumps(
|
|
504
|
+
get_checkpoint_metadata(config, metadata), ensure_ascii=False
|
|
505
|
+
).encode("utf-8", "ignore")
|
|
508
506
|
async with (
|
|
509
507
|
self.lock,
|
|
510
508
|
self.conn.execute(
|
|
@@ -590,14 +588,13 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|
|
590
588
|
)
|
|
591
589
|
await self.conn.commit()
|
|
592
590
|
|
|
593
|
-
def get_next_version(self, current:
|
|
591
|
+
def get_next_version(self, current: str | None, channel: None) -> str:
|
|
594
592
|
"""Generate the next version ID for a channel.
|
|
595
593
|
|
|
596
594
|
This method creates a new version identifier for a channel based on its current version.
|
|
597
595
|
|
|
598
596
|
Args:
|
|
599
597
|
current (Optional[str]): The current version identifier of the channel.
|
|
600
|
-
channel (BaseChannel): The channel being versioned.
|
|
601
598
|
|
|
602
599
|
Returns:
|
|
603
600
|
str: The next version identifier, which is guaranteed to be monotonically increasing.
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import json
|
|
2
4
|
from collections.abc import Sequence
|
|
3
|
-
from typing import Any
|
|
5
|
+
from typing import Any
|
|
4
6
|
|
|
5
7
|
from langchain_core.runnables import RunnableConfig
|
|
6
|
-
|
|
7
8
|
from langgraph.checkpoint.base import get_checkpoint_id
|
|
8
9
|
|
|
9
10
|
|
|
@@ -52,9 +53,9 @@ def _metadata_predicate(
|
|
|
52
53
|
|
|
53
54
|
|
|
54
55
|
def search_where(
|
|
55
|
-
config:
|
|
56
|
-
filter:
|
|
57
|
-
before:
|
|
56
|
+
config: RunnableConfig | None,
|
|
57
|
+
filter: dict[str, Any] | None,
|
|
58
|
+
before: RunnableConfig | None = None,
|
|
58
59
|
) -> tuple[str, Sequence[Any]]:
|
|
59
60
|
"""Return WHERE clause predicates for (a)search() given metadata filter
|
|
60
61
|
and `before` config.
|