langgraph-api 0.16.0.dev6__py3-none-any.whl → 0.16.0.dev7__py3-none-any.whl

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_api/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.16.0.dev6"
1
+ __version__ = "0.16.0.dev7"
@@ -4,6 +4,7 @@ from starlette.exceptions import HTTPException
4
4
  from starlette.responses import Response
5
5
  from starlette.routing import BaseRoute
6
6
 
7
+ from langgraph_api.config import USE_CUSTOM_CHECKPOINTER
7
8
  from langgraph_api.encryption.middleware import (
8
9
  decrypt_response,
9
10
  decrypt_responses,
@@ -45,6 +46,7 @@ from langgraph_api.validation import (
45
46
  ThreadStateSearch,
46
47
  ThreadStateUpdate,
47
48
  )
49
+ from langgraph_runtime import checkpoint as runtime_checkpoint
48
50
  from langgraph_runtime.database import connect
49
51
  from langgraph_runtime.retry import retry_db
50
52
 
@@ -376,6 +378,25 @@ async def get_thread_history_post(
376
378
  return ApiResponse(states)
377
379
 
378
380
 
381
+ @retry_db
382
+ async def get_thread_storage(request: ApiRequest):
383
+ """Bytes a thread's checkpoints occupy, per table and per channel."""
384
+ thread_id = request.path_params["thread_id"]
385
+ validate_uuid(thread_id, "Invalid thread ID: must be a UUID")
386
+ thread_storage = getattr(runtime_checkpoint, "thread_storage", None)
387
+ if USE_CUSTOM_CHECKPOINTER or thread_storage is None:
388
+ raise HTTPException(
389
+ status_code=501,
390
+ detail="Checkpoint storage is only reported for the built-in checkpointer.",
391
+ )
392
+ async with connect() as conn:
393
+ await fetchone(await Threads.get(conn, thread_id))
394
+ # The built-in tables are read directly; the core-api stand-in cannot run SQL.
395
+ async with connect(supports_core_api=False) as conn:
396
+ storage = await thread_storage(conn, thread_id)
397
+ return ApiResponse({"thread_id": thread_id, **storage})
398
+
399
+
379
400
  @retry_db
380
401
  async def get_thread(
381
402
  request: ApiRequest,
@@ -547,6 +568,9 @@ threads_routes: list[BaseRoute] = [
547
568
  ApiRoute("/threads/{thread_id}", endpoint=patch_thread, methods=["PATCH"]),
548
569
  ApiRoute("/threads/{thread_id}", endpoint=delete_thread, methods=["DELETE"]),
549
570
  ApiRoute("/threads/{thread_id}/state", endpoint=get_thread_state, methods=["GET"]),
571
+ ApiRoute(
572
+ "/threads/{thread_id}/storage", endpoint=get_thread_storage, methods=["GET"]
573
+ ),
550
574
  ApiRoute(
551
575
  "/threads/{thread_id}/state", endpoint=update_thread_state, methods=["POST"]
552
576
  ),
@@ -13,6 +13,7 @@ import orjson
13
13
  import structlog
14
14
  from google.protobuf.empty_pb2 import Empty # ty: ignore[unresolved-import]
15
15
  from langgraph_grpc_common.conversion.checkpoint import (
16
+ checkpoint_config_to_proto,
16
17
  checkpoint_from_proto,
17
18
  checkpoint_metadata_from_proto,
18
19
  checkpoint_tuple_to_proto,
@@ -22,7 +23,6 @@ from langgraph_grpc_common.conversion.checkpoint import (
22
23
  from langgraph_grpc_common.conversion.config import (
23
24
  config_from_proto,
24
25
  config_from_proto_optional,
25
- config_to_proto,
26
26
  )
27
27
  from langgraph_grpc_common.proto import checkpointer_pb2
28
28
  from langgraph_grpc_common.proto.checkpointer_pb2_grpc import CheckpointerServicer
@@ -64,7 +64,7 @@ class CheckpointerServicerImpl(CheckpointerServicer):
64
64
  next_config = await checkpointer.aput(
65
65
  config, checkpoint, metadata, new_versions
66
66
  )
67
- next_config_pb = config_to_proto(next_config)
67
+ next_config_pb = checkpoint_config_to_proto(next_config)
68
68
  if next_config_pb is None:
69
69
  return checkpointer_pb2.PutResponse()
70
70
  return checkpointer_pb2.PutResponse(next_config=next_config_pb)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langgraph-api
3
- Version: 0.16.0.dev6
3
+ Version: 0.16.0.dev7
4
4
  Author-email: Will Fu-Hinthorn <will@langchain.dev>, Josh Rogers <josh@langchain.dev>, Parker Rule <parker@langchain.dev>
5
5
  License: Elastic-2.0
6
6
  License-File: LICENSE
@@ -1,4 +1,4 @@
1
- langgraph_api/__init__.py,sha256=Tea7ymkB4nX_zD1WSeuGpkEk3r2zpOb-cvWZRXmsogA,28
1
+ langgraph_api/__init__.py,sha256=aBRzlOKsAMKJlCRnhr4-7ukE_yGNccJoqTq2ODz7v1k,28
2
2
  langgraph_api/_factory_utils.py,sha256=_FqW0olMu2PGLsnRq0ylt3a4jDCe12YIFHExMXI6Nyo,5976
3
3
  langgraph_api/asgi_transport.py,sha256=XApY3lIWBZTMbbsl8dDJzl0cLGirmAGE0SifqZUnXvs,11896
4
4
  langgraph_api/asyncio.py,sha256=smqyAoO9nIyPPQRw1IVSCh85fwoZP4PEo-5dDhxGruc,10676
@@ -51,7 +51,7 @@ langgraph_api/api/openapi.py,sha256=Zkdlb9mjrQyHro1TtrDIWVuaBDovxx-uGWJ1fZMOg54,
51
51
  langgraph_api/api/profile.py,sha256=CA1ZkHALOuP8orYTICnEhcG_JnnA2wnyjbWyeb117jA,3455
52
52
  langgraph_api/api/runs.py,sha256=Po9sBkjTImo1lnKKfgFmYJRtXIGk0Mriqm5_9YC77Kw,36068
53
53
  langgraph_api/api/store.py,sha256=mvFEGlrTN77bxH3rLqreRJ1iWvG0r6iv88nQTAkpuAQ,7244
54
- langgraph_api/api/threads.py,sha256=n2cn0FZr_b1jKq7McX6HHuYn80Z0x89wNH4zLs5Co6Y,19649
54
+ langgraph_api/api/threads.py,sha256=1VaWwUJvCIiCkjHHsaS6l1R-ErlBs3Y-Jzyy954e-WM,20764
55
55
  langgraph_api/api/ui.py,sha256=A1cRxaMK_4pb192mrZ_LMxLSFb8NriYwwvjeDdNDD7k,2803
56
56
  langgraph_api/api/a2ui_schemas/README.md,sha256=fZCc9rSK-qeUHsbJ17EYxMZjS3yUrYQdoQLX7ltgP8M,298
57
57
  langgraph_api/api/a2ui_schemas/client_capabilities.json,sha256=3YAHlRfeOn9dUH6uAek1loCL4caeSUuQzhrtWKWW9nU,1906
@@ -102,7 +102,7 @@ langgraph_api/grpc/ops/crons.py,sha256=BzFTBo0C45oTLzFqxVsR15Fy1RvCoGGEL9rYiI6Za
102
102
  langgraph_api/grpc/ops/runs.py,sha256=oOSxzgubnPvRRoRb1OKMDzdcmXve4V6Zh5AWS4sc4Rs,42401
103
103
  langgraph_api/grpc/ops/threads.py,sha256=SJraV838nZ0m6wRrCia7sLYh8KK1WfY7x5xmcspZLek,48140
104
104
  langgraph_api/grpc/servicers/__init__.py,sha256=l8yqTA_gMbIj0xHw5-RZYo0JbjL-EpFD8RxPMgW_-bA,422
105
- langgraph_api/grpc/servicers/checkpointer.py,sha256=aeB2hzsDxbb9i-ildx-kylpDxaYtpAUSG6rphOzbDOs,10482
105
+ langgraph_api/grpc/servicers/checkpointer.py,sha256=0NeBZDrRiMTpUElu0ss60FTZ8LDjgnSVRdzwWVnUYF4,10504
106
106
  langgraph_api/grpc/servicers/encryption.py,sha256=qmov9a4gBJqdUNZkFASf6BLKOWce0Juwd_650G-DyPs,16924
107
107
  langgraph_api/js/.gitignore,sha256=l5yI6G_V6F1600I1IjiUKn87f4uYIrBAYU1MOyBBhg4,59
108
108
  langgraph_api/js/.prettierrc,sha256=0es3ovvyNIqIw81rPQsdt1zCQcOdBqyR_DMbFE4Ifms,19
@@ -173,15 +173,15 @@ langgraph_runtime/store.py,sha256=7mowndlsIroGHv3NpTSOZDJR0lCuaYMBoTnTrewjslw,11
173
173
  LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
174
174
  hatch_build.py,sha256=Nn9N-EFfVqmH5q3iCUrhqX6zc7qT1jLI3gWSBN2xgYQ,1738
175
175
  logging.json,sha256=sBy8HDDPuucpLbLUD6e8t5fsiQjJoklZsbVHi2qQ7aQ,367
176
- openapi.json,sha256=C009Hi2gZaUKU4OOf2P12Qdjodx1mxZd16RAm1lZiIw,219991
176
+ openapi.json,sha256=ZrgPaq1MMyscZiLqi3F09rWPUN67YRoT-5GHPcdN3HU,224041
177
177
  langgraph_grpc_common/__init__.py,sha256=sO7jFHekQxt6zZPhTPZAWLYLB_S8w7-VuJ7NyWFlFNo,97
178
- langgraph_grpc_common/checkpointer.py,sha256=-F51xCHjP3A2gWfwVTTm7x7w9YsH78qJnZ57zTYAwdI,15344
178
+ langgraph_grpc_common/checkpointer.py,sha256=GoSI_wFBRxI-ltJKARI84qPOYT_qH__d0fsMwM8E6BE,15394
179
179
  langgraph_grpc_common/serde.py,sha256=8q290nZ6TdxbEhCTzwEs44XGi2b-3pfrUeMYY5WGlTY,6179
180
180
  langgraph_grpc_common/store.py,sha256=ae34gPQS260oBh2hcNLzI7-c1xKMs6FVvsJExqFRbhk,4743
181
181
  langgraph_grpc_common/conversion/__init__.py,sha256=pLsOrRtmF9YkgmCPhcfym6lYOB7PCJTRItyo1YK_AT8,208
182
182
  langgraph_grpc_common/conversion/_compat.py,sha256=MIEo69I7tfaPskunPGwBCKheksLwxpw-z-4O3hvO9og,4010
183
- langgraph_grpc_common/conversion/checkpoint.py,sha256=0Wyjyt4jL7BrwjbxWXnrEH869KhQJ0IOKI26NfJsv9g,13185
184
- langgraph_grpc_common/conversion/config.py,sha256=4QESPHOoYBmCg46ZbK4ulFAq1WBlha3fabLeXI7PBcU,13094
183
+ langgraph_grpc_common/conversion/checkpoint.py,sha256=BENL92Wn67Puedf6hWmb6eT_wtuurqd6l0KvICMM5x8,13490
184
+ langgraph_grpc_common/conversion/config.py,sha256=LmPNpMiJ5JFTAHI_Z9A_zjbxPru5gCbIa-wgs2L9HSk,13458
185
185
  langgraph_grpc_common/conversion/durability.py,sha256=FWhqjzVN4JrrsAL9AwsJkvIorQGNRl14w97Va-WZRk0,991
186
186
  langgraph_grpc_common/conversion/store.py,sha256=eQQ7YHrMYRsd1jN9LbqvCxGQGErySV_07n3meADiYIE,15237
187
187
  langgraph_grpc_common/conversion/struct.py,sha256=yk4jpPdywzn8UosAohun21lU5D_IIglOY9rkBhiG-gA,2072
@@ -251,8 +251,8 @@ langgraph_grpc_common/proto/store_pb2.py,sha256=JKcuJK0YUC1BSwLUZJWHCQ7AWkzVS9Kf
251
251
  langgraph_grpc_common/proto/store_pb2.pyi,sha256=ItSuXbA2X9bQlHtuEjDGi0fT_gJj2b0sr7XuQkybe3s,28983
252
252
  langgraph_grpc_common/proto/store_pb2_grpc.py,sha256=Kyt8eV2NXkjh3be_BYytGdD19kNf74961cruonMvCrw,3300
253
253
  langgraph_grpc_common/proto/store_pb2_grpc.pyi,sha256=oS1h2cDoq2OjyM8xazcmc8LwRDC5oCAD0zto2QUmPQw,2027
254
- langgraph_api-0.16.0.dev6.dist-info/METADATA,sha256=mV3FLySPe4k0GO_pVdWvPeIcLNEhmvKFcoTCqNktyR8,5850
255
- langgraph_api-0.16.0.dev6.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
256
- langgraph_api-0.16.0.dev6.dist-info/entry_points.txt,sha256=hGedv8n7cgi41PypMfinwS_HfCwA7xJIfS0jAp8htV8,78
257
- langgraph_api-0.16.0.dev6.dist-info/licenses/LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
258
- langgraph_api-0.16.0.dev6.dist-info/RECORD,,
254
+ langgraph_api-0.16.0.dev7.dist-info/METADATA,sha256=O4v84kkO5EJfHWbc_4YRpJP86LiHIG14qlxnrJGZ9Vw,5850
255
+ langgraph_api-0.16.0.dev7.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
256
+ langgraph_api-0.16.0.dev7.dist-info/entry_points.txt,sha256=hGedv8n7cgi41PypMfinwS_HfCwA7xJIfS0jAp8htV8,78
257
+ langgraph_api-0.16.0.dev7.dist-info/licenses/LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
258
+ langgraph_api-0.16.0.dev7.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.32.0
2
+ Generator: hatchling 1.32.4
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -29,7 +29,6 @@ from langgraph_grpc_common import serde as _grpc_serde
29
29
  from langgraph_grpc_common.conversion import checkpoint as ckpt_conv
30
30
  from langgraph_grpc_common.conversion.config import (
31
31
  config_from_proto,
32
- config_to_proto,
33
32
  convert_dict_to_json_bytes,
34
33
  )
35
34
  from langgraph_grpc_common.proto import checkpointer_pb2
@@ -146,7 +145,9 @@ class GrpcCheckpointer(BaseCheckpointSaver):
146
145
 
147
146
  async def aget_tuple(self, config: RunnableConfig) -> CheckpointTuple | None:
148
147
  with self._scoped():
149
- request = checkpointer_pb2.GetTupleRequest(config=config_to_proto(config))
148
+ request = checkpointer_pb2.GetTupleRequest(
149
+ config=ckpt_conv.checkpoint_config_to_proto(config)
150
+ )
150
151
 
151
152
  async def _request() -> CheckpointTuple | None:
152
153
  response = await (await self._stub()).GetTuple(request)
@@ -183,7 +184,7 @@ class GrpcCheckpointer(BaseCheckpointSaver):
183
184
  ) -> RunnableConfig:
184
185
  with self._scoped():
185
186
  request = checkpointer_pb2.PutRequest(
186
- config=config_to_proto(config),
187
+ config=ckpt_conv.checkpoint_config_to_proto(config),
187
188
  checkpoint=ckpt_conv.checkpoint_to_proto(checkpoint),
188
189
  metadata=ckpt_conv.checkpoint_metadata_to_proto(metadata),
189
190
  new_versions={k: str(v) for k, v in new_versions.items()},
@@ -218,7 +219,7 @@ class GrpcCheckpointer(BaseCheckpointSaver):
218
219
  ) -> None:
219
220
  with self._scoped():
220
221
  request = checkpointer_pb2.PutWritesRequest(
221
- config=config_to_proto(config),
222
+ config=ckpt_conv.checkpoint_config_to_proto(config),
222
223
  writes=ckpt_conv.writes_to_proto(writes),
223
224
  task_id=task_id,
224
225
  task_path=task_path,
@@ -272,9 +273,9 @@ class GrpcCheckpointer(BaseCheckpointSaver):
272
273
  ) -> AsyncIterator[CheckpointTuple]:
273
274
  with self._scoped():
274
275
  request = checkpointer_pb2.ListRequest(
275
- config=config_to_proto(config) if config is not None else None,
276
+ config=ckpt_conv.checkpoint_config_to_proto(config),
276
277
  filter_json=convert_dict_to_json_bytes(filter) or b"",
277
- before=config_to_proto(before) if before is not None else None,
278
+ before=ckpt_conv.checkpoint_config_to_proto(before),
278
279
  )
279
280
  if limit is not None:
280
281
  request.limit = limit
@@ -2,6 +2,7 @@ from collections.abc import Mapping
2
2
  from collections.abc import Sequence as SequenceType
3
3
  from typing import Any, Literal, cast
4
4
 
5
+ from langchain_core.runnables import RunnableConfig
5
6
  from langgraph.checkpoint.base import (
6
7
  Checkpoint,
7
8
  CheckpointMetadata,
@@ -35,6 +36,14 @@ SOURCE_MAP = {
35
36
  }
36
37
 
37
38
 
39
+ def checkpoint_config_to_proto(
40
+ config: RunnableConfig | None,
41
+ ) -> engine_common_pb2.EngineRunnableConfig | None:
42
+ if config is None:
43
+ return None
44
+ return config_to_proto(config, skip_private_configurable=True)
45
+
46
+
38
47
  def checkpoint_from_proto(
39
48
  request_checkpoint: engine_common_pb2.Checkpoint,
40
49
  ) -> Checkpoint:
@@ -135,13 +144,13 @@ def checkpoint_tuple_to_proto(
135
144
  checkpoint_tuple: CheckpointTuple,
136
145
  ) -> engine_common_pb2.CheckpointTuple:
137
146
  proto = engine_common_pb2.CheckpointTuple()
138
- if config_pb := config_to_proto(checkpoint_tuple.config):
147
+ if config_pb := checkpoint_config_to_proto(checkpoint_tuple.config):
139
148
  proto.config.CopyFrom(config_pb)
140
149
  proto.checkpoint.CopyFrom(checkpoint_to_proto(checkpoint_tuple.checkpoint))
141
150
  if checkpoint_tuple.metadata:
142
151
  proto.metadata.CopyFrom(checkpoint_metadata_to_proto(checkpoint_tuple.metadata))
143
152
  if checkpoint_tuple.parent_config:
144
- if parent_pb := config_to_proto(checkpoint_tuple.parent_config):
153
+ if parent_pb := checkpoint_config_to_proto(checkpoint_tuple.parent_config):
145
154
  proto.parent_config.CopyFrom(parent_pb)
146
155
  if checkpoint_tuple.pending_writes:
147
156
  for task_id, channel, value in checkpoint_tuple.pending_writes:
@@ -30,6 +30,7 @@ from langgraph_grpc_common.conversion.struct import _default_serializer
30
30
  from langgraph_grpc_common.proto import engine_common_pb2, enum_stream_mode_pb2
31
31
 
32
32
  CONFIG_KEY_GRAPH_ID = "graph_id"
33
+ CONFIG_KEY_NODE_FINISHED = "__pregel_node_finished"
33
34
  # DR-specific key for storing root graph stream modes, required for patched subgraph streaming.
34
35
  CONFIG_KEY_ROOT_STREAM_MODES = "__pregel_root_stream_modes"
35
36
  CONFIG_KEY_REPLAY_STATE = "__pregel_replay_state"
@@ -185,6 +186,8 @@ KNOWN_CONFIG_KEYS = {
185
186
 
186
187
  def config_to_proto(
187
188
  config: RunnableConfig,
189
+ *,
190
+ skip_private_configurable: bool = False,
188
191
  ) -> engine_common_pb2.EngineRunnableConfig | None:
189
192
  # Prepare kwargs for construction
190
193
  if not config:
@@ -228,7 +231,11 @@ def config_to_proto(
228
231
  pb_config.tags.extend(tags)
229
232
 
230
233
  if configurable := config.get("configurable"):
231
- _inject_configurable_into_proto(configurable, pb_config)
234
+ _inject_configurable_into_proto(
235
+ configurable,
236
+ pb_config,
237
+ skip_private_configurable=skip_private_configurable,
238
+ )
232
239
 
233
240
  # Preserve extra top-level keys (not in KNOWN_CONFIG_KEYS)
234
241
  extra = {k: v for k, v in config.items() if k not in KNOWN_CONFIG_KEYS}
@@ -252,6 +259,8 @@ def config_to_proto(
252
259
  return pb_config
253
260
 
254
261
 
262
+ # Known process-local framework values excluded from every proto conversion.
263
+ # Checkpoint conversion also skips arbitrary private keys to match Python savers.
255
264
  RESTRICTED_RESERVED_CONFIGURABLE_KEYS = {
256
265
  CONFIG_KEY_SEND,
257
266
  CONFIG_KEY_READ,
@@ -261,13 +270,17 @@ RESTRICTED_RESERVED_CONFIGURABLE_KEYS = {
261
270
  CONFIG_KEY_STREAM,
262
271
  CONFIG_KEY_CACHE,
263
272
  CONFIG_KEY_RUNNER_SUBMIT,
273
+ CONFIG_KEY_NODE_FINISHED,
264
274
  CONFIG_KEY_ROOT_STREAM_MODES,
265
275
  CONFIG_KEY_REPLAY_STATE,
266
276
  }
267
277
 
268
278
 
269
279
  def _inject_configurable_into_proto(
270
- configurable: dict[str, Any], proto: engine_common_pb2.EngineRunnableConfig
280
+ configurable: dict[str, Any],
281
+ proto: engine_common_pb2.EngineRunnableConfig,
282
+ *,
283
+ skip_private_configurable: bool = False,
271
284
  ) -> None:
272
285
  extra = {}
273
286
  for key, value in configurable.items():
@@ -313,26 +326,24 @@ def _inject_configurable_into_proto(
313
326
  elif key == CONFIG_KEY_TRACING_EXAMPLE_ID:
314
327
  if value is not None:
315
328
  proto.tracing_example_id = str(value)
329
+ elif skip_private_configurable and key.startswith("__"):
330
+ continue
316
331
  elif key not in RESTRICTED_RESERVED_CONFIGURABLE_KEYS:
317
332
  extra[key] = value
318
- if extra:
319
- extra_configurable_json = {}
320
- for k, v in extra.items():
321
- try:
322
- extra_configurable_json[k] = orjson.dumps(
323
- v, default=_default_serializer
324
- )
325
- except Exception:
326
- logger.warning(
327
- "Failed to serialize extra configurable value",
328
- extra={
329
- "configurable_key": str(k),
330
- "configurable_value_type": str(type(v)),
331
- },
332
- )
333
- raise
334
-
335
- proto.extra_configurable_json.update(extra_configurable_json)
333
+ for k, v in extra.items():
334
+ try:
335
+ proto.extra_configurable_json[k] = orjson.dumps(
336
+ v, default=_default_serializer
337
+ )
338
+ except Exception:
339
+ logger.warning(
340
+ "Failed to serialize extra configurable value",
341
+ extra={
342
+ "configurable_key": str(k),
343
+ "configurable_value_type": str(type(v)),
344
+ },
345
+ )
346
+ raise
336
347
 
337
348
 
338
349
  def runtime_to_proto(runtime: Runtime) -> engine_common_pb2.Runtime:
openapi.json CHANGED
@@ -948,6 +948,60 @@
948
948
  }
949
949
  }
950
950
  },
951
+ "/threads/{thread_id}/storage": {
952
+ "get": {
953
+ "tags": ["Threads"],
954
+ "summary": "Get Thread Storage",
955
+ "description": "Bytes the thread's checkpoints occupy in the built-in checkpointer, as stored: checkpoints, channel values (per channel) and pending writes. Returns 501 when a custom checkpointer is configured.",
956
+ "operationId": "get_thread_storage_threads__thread_id__storage_get",
957
+ "parameters": [
958
+ {
959
+ "description": "The ID of the thread.",
960
+ "required": true,
961
+ "schema": {
962
+ "type": "string",
963
+ "format": "uuid",
964
+ "title": "Thread Id",
965
+ "description": "The ID of the thread."
966
+ },
967
+ "name": "thread_id",
968
+ "in": "path"
969
+ }
970
+ ],
971
+ "responses": {
972
+ "200": {
973
+ "description": "Success",
974
+ "content": {
975
+ "application/json": {
976
+ "schema": {
977
+ "$ref": "#/components/schemas/ThreadStorage"
978
+ }
979
+ }
980
+ }
981
+ },
982
+ "404": {
983
+ "description": "Thread not found",
984
+ "content": {
985
+ "application/json": {
986
+ "schema": {
987
+ "$ref": "#/components/schemas/ErrorResponse"
988
+ }
989
+ }
990
+ }
991
+ },
992
+ "422": {
993
+ "description": "Validation Error",
994
+ "content": {
995
+ "application/json": {
996
+ "schema": {
997
+ "$ref": "#/components/schemas/ErrorResponse"
998
+ }
999
+ }
1000
+ }
1001
+ }
1002
+ }
1003
+ }
1004
+ },
951
1005
  "/threads/{thread_id}/state": {
952
1006
  "get": {
953
1007
  "tags": ["Threads"],
@@ -5940,6 +5994,72 @@
5940
5994
  "title": "ThreadStateCheckpointRequest",
5941
5995
  "description": "Payload for getting the state of a thread at a checkpoint."
5942
5996
  },
5997
+ "ThreadStorage": {
5998
+ "properties": {
5999
+ "thread_id": {
6000
+ "type": "string",
6001
+ "format": "uuid",
6002
+ "title": "Thread Id"
6003
+ },
6004
+ "total_bytes": {
6005
+ "type": "integer",
6006
+ "title": "Total Bytes",
6007
+ "description": "Sum of the three sections below."
6008
+ },
6009
+ "checkpoints": {
6010
+ "type": "object",
6011
+ "title": "Checkpoints",
6012
+ "description": "Checkpoint rows: serialized checkpoint plus metadata.",
6013
+ "properties": {
6014
+ "count": { "type": "integer", "title": "Count" },
6015
+ "bytes": { "type": "integer", "title": "Bytes" }
6016
+ },
6017
+ "required": ["count", "bytes"]
6018
+ },
6019
+ "channel_values": {
6020
+ "type": "object",
6021
+ "title": "Channel Values",
6022
+ "description": "Stored channel values, one row per channel version.",
6023
+ "properties": {
6024
+ "count": { "type": "integer", "title": "Count" },
6025
+ "bytes": { "type": "integer", "title": "Bytes" },
6026
+ "by_channel": {
6027
+ "type": "object",
6028
+ "title": "By Channel",
6029
+ "additionalProperties": {
6030
+ "type": "object",
6031
+ "properties": {
6032
+ "versions": { "type": "integer", "title": "Versions" },
6033
+ "bytes": { "type": "integer", "title": "Bytes" }
6034
+ },
6035
+ "required": ["versions", "bytes"]
6036
+ }
6037
+ }
6038
+ },
6039
+ "required": ["count", "bytes", "by_channel"]
6040
+ },
6041
+ "pending_writes": {
6042
+ "type": "object",
6043
+ "title": "Pending Writes",
6044
+ "description": "Task writes not yet folded into a checkpoint.",
6045
+ "properties": {
6046
+ "count": { "type": "integer", "title": "Count" },
6047
+ "bytes": { "type": "integer", "title": "Bytes" }
6048
+ },
6049
+ "required": ["count", "bytes"]
6050
+ }
6051
+ },
6052
+ "type": "object",
6053
+ "required": [
6054
+ "thread_id",
6055
+ "total_bytes",
6056
+ "checkpoints",
6057
+ "channel_values",
6058
+ "pending_writes"
6059
+ ],
6060
+ "title": "ThreadStorage",
6061
+ "description": "Bytes a thread occupies in the checkpointer, as stored."
6062
+ },
5943
6063
  "ThreadState": {
5944
6064
  "properties": {
5945
6065
  "values": {