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.
Files changed (21) hide show
  1. {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/.gitignore +1 -0
  2. {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/PKG-INFO +5 -7
  3. {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/README.md +2 -4
  4. {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/langgraph/checkpoint/sqlite/__init__.py +30 -33
  5. {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/langgraph/checkpoint/sqlite/aio.py +33 -36
  6. {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/langgraph/checkpoint/sqlite/utils.py +6 -5
  7. {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/langgraph/store/sqlite/aio.py +80 -39
  8. {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/langgraph/store/sqlite/base.py +112 -69
  9. {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/pyproject.toml +16 -8
  10. {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/tests/test_aiosqlite.py +4 -13
  11. {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/tests/test_async_store.py +6 -6
  12. {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/tests/test_sqlite.py +15 -13
  13. {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/tests/test_store.py +56 -8
  14. {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/tests/test_ttl.py +76 -2
  15. langgraph_checkpoint_sqlite-3.0.0/uv.lock +1137 -0
  16. langgraph_checkpoint_sqlite-2.0.10/uv.lock +0 -1136
  17. {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/Makefile +0 -0
  18. {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/langgraph/cache/sqlite/__init__.py +0 -0
  19. {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/langgraph/checkpoint/sqlite/py.typed +0 -0
  20. {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/langgraph/store/sqlite/__init__.py +0 -0
  21. {langgraph_checkpoint_sqlite-2.0.10 → langgraph_checkpoint_sqlite-3.0.0}/tests/__init__.py +0 -0
@@ -181,3 +181,4 @@ Chinook.db
181
181
  .vercel
182
182
  .turbo
183
183
  .editorconfig
184
+ .scratch
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langgraph-checkpoint-sqlite
3
- Version: 2.0.10
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.9
7
+ Requires-Python: >=3.10
8
8
  Requires-Dist: aiosqlite>=0.20
9
- Requires-Dist: langgraph-checkpoint>=2.0.21
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": 2,
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": 2,
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": 2,
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": 2,
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, Optional, cast
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
- from langgraph.checkpoint.serde.types import ChannelProtocol
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/asyncsqlitesaver"
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: Optional[SerializerProtocol] = None,
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["SqliteSaver"]:
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) -> Optional[CheckpointTuple]:
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 "checkpoint_id" key, the checkpoint with
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
- Optional[CheckpointTuple]: The retrieved checkpoint tuple, or None if no matching checkpoint was found.
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
- self.jsonplus_serde.loads(metadata)
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: Optional[RunnableConfig],
290
+ config: RunnableConfig | None,
291
291
  *,
292
- filter: Optional[dict[str, Any]] = None,
293
- before: Optional[RunnableConfig] = None,
294
- limit: Optional[int] = None,
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. Defaults to None.
304
- before: If provided, only checkpoints before the specified checkpoint ID are returned. Defaults to None.
305
- limit: The maximum number of checkpoints to return. Defaults to None.
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
- Iterator[CheckpointTuple]: An iterator of checkpoint tuples.
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
- self.jsonplus_serde.loads(metadata)
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 = self.jsonplus_serde.dumps(
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) -> Optional[CheckpointTuple]:
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: Optional[RunnableConfig],
506
+ config: RunnableConfig | None,
509
507
  *,
510
- filter: Optional[dict[str, Any]] = None,
511
- before: Optional[RunnableConfig] = None,
512
- limit: Optional[int] = None,
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: Optional[str], channel: ChannelProtocol) -> str:
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, Callable, Optional, TypeVar, cast
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
- from langgraph.checkpoint.serde.types import ChannelProtocol
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: Optional[SerializerProtocol] = None,
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["AsyncSqliteSaver"]:
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) -> Optional[CheckpointTuple]:
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 "checkpoint_id" key, the checkpoint with
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
- Optional[CheckpointTuple]: The retrieved checkpoint tuple, or None if no matching checkpoint was found.
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: Optional[RunnableConfig],
171
+ config: RunnableConfig | None,
170
172
  *,
171
- filter: Optional[dict[str, Any]] = None,
172
- before: Optional[RunnableConfig] = None,
173
- limit: Optional[int] = None,
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. Defaults to None.
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
- Iterator[CheckpointTuple]: An iterator of matching checkpoint tuples.
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) -> Optional[CheckpointTuple]:
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 "checkpoint_id" key, the checkpoint with
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
- Optional[CheckpointTuple]: The retrieved checkpoint tuple, or None if no matching checkpoint was found.
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
- self.jsonplus_serde.loads(metadata)
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: Optional[RunnableConfig],
402
+ config: RunnableConfig | None,
403
403
  *,
404
- filter: Optional[dict[str, Any]] = None,
405
- before: Optional[RunnableConfig] = None,
406
- limit: Optional[int] = None,
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. Defaults to None.
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
- AsyncIterator[CheckpointTuple]: An asynchronous iterator of matching checkpoint tuples.
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
- self.jsonplus_serde.loads(metadata)
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 = self.jsonplus_serde.dumps(
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: Optional[str], channel: ChannelProtocol) -> str:
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, Optional
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: Optional[RunnableConfig],
56
- filter: Optional[dict[str, Any]],
57
- before: Optional[RunnableConfig] = None,
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.