langgraph-api 0.0.14__tar.gz → 0.0.16__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.

Potentially problematic release.


This version of langgraph-api might be problematic. Click here for more details.

Files changed (94) hide show
  1. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/PKG-INFO +3 -3
  2. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/api/__init__.py +2 -1
  3. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/api/assistants.py +4 -4
  4. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/api/store.py +67 -15
  5. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/asyncio.py +5 -0
  6. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/auth/custom.py +20 -5
  7. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/config.py +1 -0
  8. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/graph.py +6 -13
  9. langgraph_api-0.0.16/langgraph_api/js/base.py +9 -0
  10. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/build.mts +2 -0
  11. langgraph_api-0.0.16/langgraph_api/js/client.mts +830 -0
  12. langgraph_api-0.0.16/langgraph_api/js/client.new.mts +856 -0
  13. langgraph_api-0.0.16/langgraph_api/js/errors.py +11 -0
  14. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/package.json +3 -1
  15. langgraph_api-0.0.16/langgraph_api/js/remote.py +18 -0
  16. langgraph_api-0.0.16/langgraph_api/js/remote_new.py +693 -0
  17. langgraph_api-0.0.14/langgraph_api/js/remote.py → langgraph_api-0.0.16/langgraph_api/js/remote_old.py +188 -198
  18. langgraph_api-0.0.16/langgraph_api/js/schema.py +29 -0
  19. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/src/utils/serde.mts +7 -0
  20. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/tests/api.test.mts +125 -8
  21. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/tests/compose-postgres.yml +2 -1
  22. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/tests/graphs/agent.mts +2 -0
  23. langgraph_api-0.0.16/langgraph_api/js/tests/graphs/delay.mts +30 -0
  24. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/tests/graphs/langgraph.json +2 -1
  25. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/yarn.lock +870 -18
  26. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/models/run.py +1 -0
  27. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/queue.py +129 -31
  28. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/route.py +8 -3
  29. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/schema.py +1 -1
  30. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/stream.py +12 -5
  31. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/utils.py +11 -5
  32. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_storage/ops.py +9 -2
  33. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/openapi.json +5 -5
  34. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/pyproject.toml +4 -3
  35. langgraph_api-0.0.14/langgraph_api/js/client.mts +0 -856
  36. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/LICENSE +0 -0
  37. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/README.md +0 -0
  38. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/__init__.py +0 -0
  39. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/api/meta.py +0 -0
  40. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/api/openapi.py +0 -0
  41. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/api/runs.py +0 -0
  42. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/api/threads.py +0 -0
  43. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/auth/__init__.py +0 -0
  44. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/auth/langsmith/__init__.py +0 -0
  45. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/auth/langsmith/backend.py +0 -0
  46. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/auth/langsmith/client.py +0 -0
  47. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/auth/middleware.py +0 -0
  48. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/auth/noop.py +0 -0
  49. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/auth/studio_user.py +0 -0
  50. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/cli.py +0 -0
  51. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/cron_scheduler.py +0 -0
  52. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/errors.py +0 -0
  53. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/http.py +0 -0
  54. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/http_logger.py +0 -0
  55. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/.gitignore +0 -0
  56. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/global.d.ts +0 -0
  57. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/server_sent_events.py +0 -0
  58. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/src/graph.mts +0 -0
  59. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/src/hooks.mjs +0 -0
  60. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/src/parser/parser.mts +0 -0
  61. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/src/parser/parser.worker.mjs +0 -0
  62. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/src/schema/types.mts +0 -0
  63. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/src/schema/types.template.mts +0 -0
  64. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/src/utils/importMap.mts +0 -0
  65. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
  66. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/tests/graphs/.gitignore +0 -0
  67. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/tests/graphs/error.mts +0 -0
  68. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/tests/graphs/nested.mts +0 -0
  69. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/tests/graphs/package.json +0 -0
  70. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/tests/graphs/weather.mts +0 -0
  71. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/tests/graphs/yarn.lock +0 -0
  72. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/tests/parser.test.mts +0 -0
  73. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/js/tests/utils.mts +0 -0
  74. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/lifespan.py +0 -0
  75. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/logging.py +0 -0
  76. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/metadata.py +0 -0
  77. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/models/__init__.py +0 -0
  78. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/patch.py +0 -0
  79. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/serde.py +0 -0
  80. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/server.py +0 -0
  81. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/sse.py +0 -0
  82. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/state.py +0 -0
  83. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_api/validation.py +0 -0
  84. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_license/__init__.py +0 -0
  85. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_license/middleware.py +0 -0
  86. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_license/validation.py +0 -0
  87. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_storage/__init__.py +0 -0
  88. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_storage/checkpoint.py +0 -0
  89. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_storage/database.py +0 -0
  90. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_storage/queue.py +0 -0
  91. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_storage/retry.py +0 -0
  92. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_storage/store.py +0 -0
  93. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/langgraph_storage/ttl_dict.py +0 -0
  94. {langgraph_api-0.0.14 → langgraph_api-0.0.16}/logging.json +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langgraph-api
3
- Version: 0.0.14
3
+ Version: 0.0.16
4
4
  Summary:
5
5
  License: Elastic-2.0
6
6
  Author: Nuno Campos
@@ -16,11 +16,11 @@ Requires-Dist: jsonschema-rs (>=0.25.0,<0.26.0)
16
16
  Requires-Dist: langchain-core (>=0.2.38,<0.4.0)
17
17
  Requires-Dist: langgraph (>=0.2.56,<0.3.0)
18
18
  Requires-Dist: langgraph-checkpoint (>=2.0.7,<3.0)
19
- Requires-Dist: langgraph-sdk (>=0.1.48,<0.2.0)
19
+ Requires-Dist: langgraph-sdk (>=0.1.51,<0.2.0)
20
20
  Requires-Dist: langsmith (>=0.1.63,<0.3.0)
21
21
  Requires-Dist: orjson (>=3.10.1)
22
22
  Requires-Dist: pyjwt (>=2.9.0,<3.0.0)
23
- Requires-Dist: sse-starlette (>=2.1.0,<3.0.0)
23
+ Requires-Dist: sse-starlette (>=2.1.0,<2.2.0)
24
24
  Requires-Dist: starlette (>=0.38.6)
25
25
  Requires-Dist: structlog (>=24.4.0,<25.0.0)
26
26
  Requires-Dist: tenacity (>=8.3.0,<9.0.0)
@@ -13,7 +13,6 @@ from langgraph_api.api.threads import threads_routes
13
13
  from langgraph_api.auth.middleware import auth_middleware
14
14
  from langgraph_api.config import MIGRATIONS_PATH
15
15
  from langgraph_api.graph import js_bg_tasks
16
- from langgraph_api.js.remote import js_healthcheck
17
16
  from langgraph_api.validation import DOCS_HTML
18
17
  from langgraph_storage.database import connect, healthcheck
19
18
 
@@ -23,6 +22,8 @@ async def ok(request: Request):
23
22
  if check_db:
24
23
  await healthcheck()
25
24
  if js_bg_tasks:
25
+ from langgraph_api.js.remote import js_healthcheck
26
+
26
27
  await js_healthcheck()
27
28
  return JSONResponse({"ok": True})
28
29
 
@@ -8,7 +8,7 @@ from starlette.responses import Response
8
8
  from starlette.routing import BaseRoute
9
9
 
10
10
  from langgraph_api.graph import get_assistant_id, get_graph
11
- from langgraph_api.js.remote import RemotePregel
11
+ from langgraph_api.js.base import BaseRemotePregel
12
12
  from langgraph_api.route import ApiRequest, ApiResponse, ApiRoute
13
13
  from langgraph_api.serde import ajson_loads
14
14
  from langgraph_api.utils import fetchone, validate_uuid
@@ -138,7 +138,7 @@ async def get_assistant_graph(
138
138
  if xray <= 0:
139
139
  raise HTTPException(422, detail="Invalid xray value") from None
140
140
 
141
- if isinstance(graph, RemotePregel):
141
+ if isinstance(graph, BaseRemotePregel):
142
142
  drawable_graph = await graph.fetch_graph(xray=xray)
143
143
  return ApiResponse(drawable_graph.to_json())
144
144
  return ApiResponse(graph.get_graph(xray=xray).to_json())
@@ -158,7 +158,7 @@ async def get_assistant_subgraphs(
158
158
  async with get_graph(assistant["graph_id"], config) as graph:
159
159
  namespace = request.path_params.get("namespace")
160
160
 
161
- if isinstance(graph, RemotePregel):
161
+ if isinstance(graph, BaseRemotePregel):
162
162
  return ApiResponse(
163
163
  await graph.fetch_subgraphs(
164
164
  namespace=namespace,
@@ -191,7 +191,7 @@ async def get_assistant_schemas(
191
191
  assistant = await fetchone(assistant_)
192
192
  config = await ajson_loads(assistant["config"])
193
193
  async with get_graph(assistant["graph_id"], config) as graph:
194
- if isinstance(graph, RemotePregel):
194
+ if isinstance(graph, BaseRemotePregel):
195
195
  schemas = await graph.fetch_state_schema()
196
196
  return ApiResponse(
197
197
  {
@@ -1,7 +1,12 @@
1
+ from typing import Any
2
+
3
+ from langgraph_sdk.auth import Auth
1
4
  from starlette.responses import Response
2
5
  from starlette.routing import BaseRoute
3
6
 
7
+ from langgraph_api.auth.custom import handle_event as _handle_event
4
8
  from langgraph_api.route import ApiRequest, ApiResponse, ApiRoute
9
+ from langgraph_api.utils import get_auth_ctx
5
10
  from langgraph_api.validation import (
6
11
  StoreDeleteRequest,
7
12
  StoreListNamespacesRequest,
@@ -21,6 +26,24 @@ def _validate_namespace(namespace: tuple[str, ...]) -> Response | None:
21
26
  )
22
27
 
23
28
 
29
+ async def handle_event(
30
+ action: str,
31
+ value: Any,
32
+ ) -> None:
33
+ ctx = get_auth_ctx()
34
+ if not ctx:
35
+ return
36
+ await _handle_event(
37
+ Auth.types.AuthContext(
38
+ user=ctx.user,
39
+ permissions=ctx.permissions,
40
+ resource="store",
41
+ action=action,
42
+ ),
43
+ value,
44
+ )
45
+
46
+
24
47
  @retry_db
25
48
  async def put_item(request: ApiRequest):
26
49
  """Store or update an item."""
@@ -28,9 +51,13 @@ async def put_item(request: ApiRequest):
28
51
  namespace = tuple(payload["namespace"]) if payload.get("namespace") else ()
29
52
  if err := _validate_namespace(namespace):
30
53
  return err
31
- key = payload["key"]
32
- value = payload["value"]
33
- await Store().aput(namespace, key, value)
54
+ handler_payload = {
55
+ "namespace": namespace,
56
+ "key": payload["key"],
57
+ "value": payload["value"],
58
+ }
59
+ await handle_event("put", handler_payload)
60
+ await Store().aput(namespace, handler_payload["key"], handler_payload["value"])
34
61
  return Response(status_code=204)
35
62
 
36
63
 
@@ -43,6 +70,11 @@ async def get_item(request: ApiRequest):
43
70
  key = request.query_params.get("key")
44
71
  if not key:
45
72
  return ApiResponse({"error": "Key is required"}, status_code=400)
73
+ handler_payload = {
74
+ "namespace": namespace,
75
+ "key": key,
76
+ }
77
+ await handle_event("get", handler_payload)
46
78
  result = await Store().aget(namespace, key)
47
79
  return ApiResponse(result.dict() if result is not None else None)
48
80
 
@@ -54,8 +86,12 @@ async def delete_item(request: ApiRequest):
54
86
  namespace = tuple(payload["namespace"]) if payload.get("namespace") else ()
55
87
  if err := _validate_namespace(namespace):
56
88
  return err
57
- key = payload["key"]
58
- await Store().adelete(namespace, key)
89
+ handler_payload = {
90
+ "namespace": namespace,
91
+ "key": payload["key"],
92
+ }
93
+ await handle_event("delete", handler_payload)
94
+ await Store().adelete(handler_payload["namespace"], handler_payload["key"])
59
95
  return Response(status_code=204)
60
96
 
61
97
 
@@ -70,12 +106,20 @@ async def search_items(request: ApiRequest):
70
106
  limit = payload.get("limit") or 10
71
107
  offset = payload.get("offset") or 0
72
108
  query = payload.get("query")
109
+ handler_payload = {
110
+ "namespace": namespace_prefix,
111
+ "filter": filter,
112
+ "limit": limit,
113
+ "offset": offset,
114
+ "query": query,
115
+ }
116
+ await handle_event("search", handler_payload)
73
117
  items = await Store().asearch(
74
- namespace_prefix,
75
- filter=filter,
76
- limit=limit,
77
- offset=offset,
78
- query=query,
118
+ handler_payload["namespace"],
119
+ filter=handler_payload["filter"],
120
+ limit=handler_payload["limit"],
121
+ offset=handler_payload["offset"],
122
+ query=handler_payload["query"],
79
123
  )
80
124
  return ApiResponse({"items": [item.dict() for item in items]})
81
125
 
@@ -93,12 +137,20 @@ async def list_namespaces(request: ApiRequest):
93
137
  max_depth = payload.get("max_depth")
94
138
  limit = payload.get("limit", 100)
95
139
  offset = payload.get("offset", 0)
140
+ handler_payload = {
141
+ "namespace": prefix,
142
+ "suffix": suffix,
143
+ "max_depth": max_depth,
144
+ "limit": limit,
145
+ "offset": offset,
146
+ }
147
+ await handle_event("list_namespaces", handler_payload)
96
148
  result = await Store().alist_namespaces(
97
- prefix=prefix,
98
- suffix=suffix,
99
- max_depth=max_depth,
100
- limit=limit,
101
- offset=offset,
149
+ prefix=handler_payload["namespace"],
150
+ suffix=handler_payload["suffix"],
151
+ max_depth=handler_payload["max_depth"],
152
+ limit=handler_payload["limit"],
153
+ offset=handler_payload["offset"],
102
154
  )
103
155
  return ApiResponse({"namespaces": result})
104
156
 
@@ -60,6 +60,11 @@ async def wait_if_not_done(coro: Coroutine[Any, Any, T], done: ValueEvent) -> T:
60
60
  try:
61
61
  return await coro_task
62
62
  except asyncio.CancelledError as e:
63
+ if e.args and asyncio.isfuture(e.args[-1]):
64
+ await logger.ainfo(
65
+ "Awaiting future upon cancellation", task=str(e.args[-1])
66
+ )
67
+ await e.args[-1]
63
68
  if e.args and isinstance(e.args[0], Exception):
64
69
  raise e.args[0] from None
65
70
  raise
@@ -398,6 +398,16 @@ class DotDict:
398
398
  raise AttributeError(f"'DotDict' object has no attribute '{name}'")
399
399
  return self._dict[name]
400
400
 
401
+ def __getitem__(self, key):
402
+ return self._dict[key]
403
+
404
+ def __setitem__(self, key, value):
405
+ self._dict[key] = value
406
+ if isinstance(value, dict):
407
+ setattr(self, key, DotDict(value))
408
+ else:
409
+ setattr(self, key, value)
410
+
401
411
  def __deepcopy__(self, memo):
402
412
  return DotDict(copy.deepcopy(self._dict))
403
413
 
@@ -457,6 +467,12 @@ class ProxyUser(BaseUser):
457
467
  **d,
458
468
  }
459
469
 
470
+ def __getitem__(self, key):
471
+ return self._user[key]
472
+
473
+ def __setitem__(self, key, value):
474
+ self._user[key] = value
475
+
460
476
  def __getattr__(self, name: str) -> Any:
461
477
  """Proxy any other attributes to the underlying user object."""
462
478
  return getattr(self._user, name)
@@ -481,10 +497,10 @@ def _normalize_auth_response(
481
497
  user = response
482
498
  permissions = []
483
499
 
484
- return AuthCredentials(permissions), _normalize_user(user)
500
+ return AuthCredentials(permissions), normalize_user(user)
485
501
 
486
502
 
487
- def _normalize_user(user: Any) -> BaseUser:
503
+ def normalize_user(user: Any) -> BaseUser:
488
504
  """Normalize user into a BaseUser instance."""
489
505
  if isinstance(user, BaseUser):
490
506
  return user
@@ -571,9 +587,8 @@ def _get_handler(auth: Auth, ctx: Auth.types.AuthContext) -> Auth.types.Handler
571
587
  ]
572
588
  for key in keys:
573
589
  if key in auth._handlers:
574
- result = auth._handlers[key][
575
- -1
576
- ] # Get the last defined, most specific handler
590
+ # Get the last defined, most specific handler
591
+ result = auth._handlers[key][-1]
577
592
  auth._handler_cache[key] = result
578
593
  return result
579
594
  if auth._global_handlers:
@@ -28,6 +28,7 @@ BG_JOB_NO_DELAY = env("BG_JOB_NO_DELAY", cast=bool, default=False)
28
28
  N_JOBS_PER_WORKER = env("N_JOBS_PER_WORKER", cast=int, default=10)
29
29
  BG_JOB_TIMEOUT_SECS = env("BG_JOB_TIMEOUT_SECS", cast=float, default=3600)
30
30
  FF_CRONS_ENABLED = env("FF_CRONS_ENABLED", cast=bool, default=True)
31
+ FF_JS_ZEROMQ_ENABLED = env("FF_JS_ZEROMQ_ENABLED", cast=bool, default=False)
31
32
 
32
33
  # auth
33
34
 
@@ -21,7 +21,7 @@ from langgraph.pregel import Pregel
21
21
  from langgraph.store.base import BaseStore
22
22
  from starlette.exceptions import HTTPException
23
23
 
24
- from langgraph_api.js.remote import RemotePregel
24
+ from langgraph_api.js.base import BaseRemotePregel
25
25
  from langgraph_api.schema import Config
26
26
 
27
27
  if TYPE_CHECKING:
@@ -63,7 +63,7 @@ async def register_graph(graph_id: str, graph: GraphValue, config: dict | None)
63
63
  @asynccontextmanager
64
64
  async def _generate_graph(value: Any) -> AsyncIterator[Any]:
65
65
  """Yield a graph object regardless of its type."""
66
- if isinstance(value, Pregel | RemotePregel):
66
+ if isinstance(value, Pregel | BaseRemotePregel):
67
67
  yield value
68
68
  elif hasattr(value, "__aenter__") and hasattr(value, "__aexit__"):
69
69
  async with value as ctx_value:
@@ -94,12 +94,12 @@ async def get_graph(
94
94
  async with _generate_graph(value) as graph_obj:
95
95
  if isinstance(graph_obj, Graph):
96
96
  graph_obj = graph_obj.compile()
97
- if not isinstance(graph_obj, Pregel | RemotePregel):
97
+ if not isinstance(graph_obj, Pregel | BaseRemotePregel):
98
98
  raise HTTPException(
99
99
  status_code=424,
100
100
  detail=f"Graph '{graph_id}' is not valid. Review graph registration.",
101
101
  )
102
- if isinstance(graph_obj, RemotePregel):
102
+ if isinstance(graph_obj, BaseRemotePregel):
103
103
  graph_obj.checkpointer = checkpointer
104
104
  graph_obj.name = graph_id
105
105
  yield graph_obj
@@ -228,20 +228,13 @@ async def collect_graphs_from_env(register: bool = False) -> None:
228
228
  RemotePregel,
229
229
  run_js_process,
230
230
  run_remote_checkpointer,
231
- run_remote_store,
232
231
  wait_until_js_ready,
233
232
  )
234
233
 
235
234
  js_bg_tasks.add(
236
235
  asyncio.create_task(
237
236
  run_remote_checkpointer(),
238
- name="remote-checkpointer",
239
- )
240
- )
241
- js_bg_tasks.add(
242
- asyncio.create_task(
243
- run_remote_store(),
244
- name="remote-store",
237
+ name="remote-socket-poller",
245
238
  )
246
239
  )
247
240
  js_bg_tasks.add(
@@ -256,7 +249,7 @@ async def collect_graphs_from_env(register: bool = False) -> None:
256
249
  await wait_until_js_ready()
257
250
 
258
251
  for spec in js_specs:
259
- graph = await RemotePregel.load(graph_id=spec.id)
252
+ graph = RemotePregel.load(graph_id=spec.id)
260
253
  if register:
261
254
  await register_graph(spec.id, graph, spec.config)
262
255
 
@@ -0,0 +1,9 @@
1
+ from langchain_core.runnables import Runnable
2
+
3
+
4
+ class BaseRemotePregel(Runnable):
5
+ # TODO: implement name overriding
6
+ name: str = "LangGraph"
7
+
8
+ # TODO: implement graph_id overriding
9
+ graph_id: str
@@ -1,3 +1,5 @@
1
+ /// <reference types="./global.d.ts" />
2
+
1
3
  import { z } from "zod";
2
4
  import * as fs from "node:fs/promises";
3
5
  import * as path from "node:path";