langgraph-api 0.5.4__py3-none-any.whl → 0.7.3__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 +1 -1
- langgraph_api/api/__init__.py +93 -27
- langgraph_api/api/a2a.py +36 -32
- langgraph_api/api/assistants.py +114 -26
- langgraph_api/api/mcp.py +3 -3
- langgraph_api/api/meta.py +15 -2
- langgraph_api/api/openapi.py +27 -17
- langgraph_api/api/profile.py +108 -0
- langgraph_api/api/runs.py +114 -57
- langgraph_api/api/store.py +19 -2
- langgraph_api/api/threads.py +133 -10
- langgraph_api/asgi_transport.py +14 -9
- langgraph_api/auth/custom.py +23 -13
- langgraph_api/cli.py +86 -41
- langgraph_api/command.py +2 -2
- langgraph_api/config/__init__.py +532 -0
- langgraph_api/config/_parse.py +58 -0
- langgraph_api/config/schemas.py +431 -0
- langgraph_api/cron_scheduler.py +17 -1
- langgraph_api/encryption/__init__.py +15 -0
- langgraph_api/encryption/aes_json.py +158 -0
- langgraph_api/encryption/context.py +35 -0
- langgraph_api/encryption/custom.py +280 -0
- langgraph_api/encryption/middleware.py +632 -0
- langgraph_api/encryption/shared.py +63 -0
- langgraph_api/errors.py +12 -1
- langgraph_api/executor_entrypoint.py +11 -6
- langgraph_api/feature_flags.py +19 -0
- langgraph_api/graph.py +163 -64
- langgraph_api/{grpc_ops → grpc}/client.py +142 -12
- langgraph_api/{grpc_ops → grpc}/config_conversion.py +16 -10
- langgraph_api/grpc/generated/__init__.py +29 -0
- langgraph_api/grpc/generated/checkpointer_pb2.py +63 -0
- langgraph_api/grpc/generated/checkpointer_pb2.pyi +99 -0
- langgraph_api/grpc/generated/checkpointer_pb2_grpc.py +329 -0
- langgraph_api/grpc/generated/core_api_pb2.py +216 -0
- langgraph_api/{grpc_ops → grpc}/generated/core_api_pb2.pyi +292 -372
- langgraph_api/{grpc_ops → grpc}/generated/core_api_pb2_grpc.py +252 -31
- langgraph_api/grpc/generated/engine_common_pb2.py +219 -0
- langgraph_api/{grpc_ops → grpc}/generated/engine_common_pb2.pyi +178 -104
- langgraph_api/grpc/generated/enum_cancel_run_action_pb2.py +37 -0
- langgraph_api/grpc/generated/enum_cancel_run_action_pb2.pyi +12 -0
- langgraph_api/grpc/generated/enum_cancel_run_action_pb2_grpc.py +24 -0
- langgraph_api/grpc/generated/enum_control_signal_pb2.py +37 -0
- langgraph_api/grpc/generated/enum_control_signal_pb2.pyi +16 -0
- langgraph_api/grpc/generated/enum_control_signal_pb2_grpc.py +24 -0
- langgraph_api/grpc/generated/enum_durability_pb2.py +37 -0
- langgraph_api/grpc/generated/enum_durability_pb2.pyi +16 -0
- langgraph_api/grpc/generated/enum_durability_pb2_grpc.py +24 -0
- langgraph_api/grpc/generated/enum_multitask_strategy_pb2.py +37 -0
- langgraph_api/grpc/generated/enum_multitask_strategy_pb2.pyi +16 -0
- langgraph_api/grpc/generated/enum_multitask_strategy_pb2_grpc.py +24 -0
- langgraph_api/grpc/generated/enum_run_status_pb2.py +37 -0
- langgraph_api/grpc/generated/enum_run_status_pb2.pyi +22 -0
- langgraph_api/grpc/generated/enum_run_status_pb2_grpc.py +24 -0
- langgraph_api/grpc/generated/enum_stream_mode_pb2.py +37 -0
- langgraph_api/grpc/generated/enum_stream_mode_pb2.pyi +28 -0
- langgraph_api/grpc/generated/enum_stream_mode_pb2_grpc.py +24 -0
- langgraph_api/grpc/generated/enum_thread_status_pb2.py +37 -0
- langgraph_api/grpc/generated/enum_thread_status_pb2.pyi +16 -0
- langgraph_api/grpc/generated/enum_thread_status_pb2_grpc.py +24 -0
- langgraph_api/grpc/generated/enum_thread_stream_mode_pb2.py +37 -0
- langgraph_api/grpc/generated/enum_thread_stream_mode_pb2.pyi +16 -0
- langgraph_api/grpc/generated/enum_thread_stream_mode_pb2_grpc.py +24 -0
- langgraph_api/grpc/generated/errors_pb2.py +39 -0
- langgraph_api/grpc/generated/errors_pb2.pyi +21 -0
- langgraph_api/grpc/generated/errors_pb2_grpc.py +24 -0
- langgraph_api/grpc/ops/__init__.py +370 -0
- langgraph_api/grpc/ops/assistants.py +424 -0
- langgraph_api/grpc/ops/runs.py +792 -0
- langgraph_api/grpc/ops/threads.py +1013 -0
- langgraph_api/http.py +16 -5
- langgraph_api/js/client.mts +1 -4
- langgraph_api/js/package.json +28 -27
- langgraph_api/js/remote.py +39 -17
- langgraph_api/js/sse.py +2 -2
- langgraph_api/js/ui.py +1 -1
- langgraph_api/js/yarn.lock +1139 -869
- langgraph_api/metadata.py +29 -3
- langgraph_api/middleware/http_logger.py +1 -1
- langgraph_api/middleware/private_network.py +7 -7
- langgraph_api/models/run.py +44 -26
- langgraph_api/otel_context.py +205 -0
- langgraph_api/patch.py +2 -2
- langgraph_api/queue_entrypoint.py +34 -35
- langgraph_api/route.py +33 -1
- langgraph_api/schema.py +84 -9
- langgraph_api/self_hosted_logs.py +2 -2
- langgraph_api/self_hosted_metrics.py +73 -3
- langgraph_api/serde.py +16 -4
- langgraph_api/server.py +33 -31
- langgraph_api/state.py +3 -2
- langgraph_api/store.py +25 -16
- langgraph_api/stream.py +20 -16
- langgraph_api/thread_ttl.py +28 -13
- langgraph_api/timing/__init__.py +25 -0
- langgraph_api/timing/profiler.py +200 -0
- langgraph_api/timing/timer.py +318 -0
- langgraph_api/utils/__init__.py +53 -8
- langgraph_api/utils/config.py +2 -1
- langgraph_api/utils/future.py +10 -6
- langgraph_api/utils/uuids.py +29 -62
- langgraph_api/validation.py +6 -0
- langgraph_api/webhook.py +120 -6
- langgraph_api/worker.py +54 -24
- {langgraph_api-0.5.4.dist-info → langgraph_api-0.7.3.dist-info}/METADATA +8 -6
- langgraph_api-0.7.3.dist-info/RECORD +168 -0
- {langgraph_api-0.5.4.dist-info → langgraph_api-0.7.3.dist-info}/WHEEL +1 -1
- langgraph_runtime/__init__.py +1 -0
- langgraph_runtime/routes.py +11 -0
- logging.json +1 -3
- openapi.json +635 -537
- langgraph_api/config.py +0 -523
- langgraph_api/grpc_ops/generated/__init__.py +0 -5
- langgraph_api/grpc_ops/generated/core_api_pb2.py +0 -275
- langgraph_api/grpc_ops/generated/engine_common_pb2.py +0 -194
- langgraph_api/grpc_ops/ops.py +0 -1045
- langgraph_api-0.5.4.dist-info/RECORD +0 -121
- /langgraph_api/{grpc_ops → grpc}/__init__.py +0 -0
- /langgraph_api/{grpc_ops → grpc}/generated/engine_common_pb2_grpc.py +0 -0
- {langgraph_api-0.5.4.dist-info → langgraph_api-0.7.3.dist-info}/entry_points.txt +0 -0
- {langgraph_api-0.5.4.dist-info → langgraph_api-0.7.3.dist-info}/licenses/LICENSE +0 -0
langgraph_api/http.py
CHANGED
|
@@ -70,11 +70,11 @@ class JsonHttpClient:
|
|
|
70
70
|
await res.aclose()
|
|
71
71
|
|
|
72
72
|
|
|
73
|
-
_http_client: JsonHttpClient
|
|
73
|
+
_http_client: JsonHttpClient | None = None
|
|
74
74
|
_loopback_client: JsonHttpClient | None = None
|
|
75
75
|
|
|
76
76
|
|
|
77
|
-
async def start_http_client() ->
|
|
77
|
+
async def start_http_client() -> JsonHttpClient:
|
|
78
78
|
global _http_client
|
|
79
79
|
_http_client = JsonHttpClient(
|
|
80
80
|
client=httpx.AsyncClient(
|
|
@@ -86,15 +86,26 @@ async def start_http_client() -> None:
|
|
|
86
86
|
),
|
|
87
87
|
),
|
|
88
88
|
)
|
|
89
|
+
return _http_client
|
|
89
90
|
|
|
90
91
|
|
|
91
92
|
async def stop_http_client() -> None:
|
|
92
93
|
global _http_client
|
|
94
|
+
if _http_client is None:
|
|
95
|
+
return
|
|
93
96
|
await _http_client.client.aclose()
|
|
94
|
-
|
|
97
|
+
_http_client = None
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def get_http_client() -> JsonHttpClient | None:
|
|
101
|
+
global _http_client
|
|
102
|
+
return _http_client
|
|
95
103
|
|
|
96
104
|
|
|
97
|
-
def
|
|
105
|
+
async def ensure_http_client() -> JsonHttpClient:
|
|
106
|
+
global _http_client
|
|
107
|
+
if _http_client is None:
|
|
108
|
+
return await start_http_client()
|
|
98
109
|
return _http_client
|
|
99
110
|
|
|
100
111
|
|
|
@@ -168,7 +179,7 @@ async def http_request(
|
|
|
168
179
|
if not path.startswith(("http://", "https://", "/")):
|
|
169
180
|
raise ValueError("path must start with / or http")
|
|
170
181
|
|
|
171
|
-
client = client or
|
|
182
|
+
client = client or (await ensure_http_client())
|
|
172
183
|
|
|
173
184
|
content = None
|
|
174
185
|
if body is not None:
|
langgraph_api/js/client.mts
CHANGED
|
@@ -527,10 +527,7 @@ export class RemoteStore extends BaseStore {
|
|
|
527
527
|
}
|
|
528
528
|
|
|
529
529
|
async get(namespace: string[], key: string): Promise<Item | null> {
|
|
530
|
-
return await sendRecv<Item | null>("store_get", {
|
|
531
|
-
namespace: namespace.join("."),
|
|
532
|
-
key,
|
|
533
|
-
});
|
|
530
|
+
return await sendRecv<Item | null>("store_get", { namespace, key });
|
|
534
531
|
}
|
|
535
532
|
|
|
536
533
|
async search(
|
langgraph_api/js/package.json
CHANGED
|
@@ -7,41 +7,42 @@
|
|
|
7
7
|
"format": "prettier --write ."
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@hono/node-server": "^1.
|
|
11
|
-
"@hono/zod-validator": "^0.
|
|
12
|
-
"@langchain/core": "^1.
|
|
13
|
-
"@langchain/langgraph": "^1.
|
|
10
|
+
"@hono/node-server": "^1.19.8",
|
|
11
|
+
"@hono/zod-validator": "^0.7.6",
|
|
12
|
+
"@langchain/core": "^1.1.8",
|
|
13
|
+
"@langchain/langgraph": "^1.1.0",
|
|
14
14
|
"@langchain/langgraph-api": "^1.0.3",
|
|
15
|
-
"@langchain/langgraph-ui": "^1.0.3",
|
|
16
15
|
"@langchain/langgraph-checkpoint": "^1.0.0",
|
|
16
|
+
"@langchain/langgraph-ui": "^1.1.11",
|
|
17
17
|
"@types/json-schema": "^7.0.15",
|
|
18
|
-
"@typescript/vfs": "^1.6.
|
|
19
|
-
"dedent": "^1.7.
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"p-
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
18
|
+
"@typescript/vfs": "^1.6.2",
|
|
19
|
+
"dedent": "^1.7.1",
|
|
20
|
+
"esbuild": "^0.27.2",
|
|
21
|
+
"exit-hook": "^5.0.1",
|
|
22
|
+
"hono": "^4.11.4",
|
|
23
|
+
"p-queue": "^9.0.1",
|
|
24
|
+
"p-retry": "^7.1.1",
|
|
25
|
+
"tsx": "^4.21.0",
|
|
26
|
+
"typescript": "^5.9.3",
|
|
27
|
+
"undici": "^7.18.2",
|
|
28
|
+
"uuid": "^13.0.0",
|
|
29
|
+
"vite": "^7.3.0",
|
|
30
|
+
"winston": "^3.19.0",
|
|
31
|
+
"zod": "^4.2.1"
|
|
31
32
|
},
|
|
32
33
|
"resolutions": {
|
|
33
34
|
"esbuild": "^0.25.0",
|
|
34
35
|
"vite": "^6.1.6"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
|
-
"@langchain/langgraph-sdk": "^
|
|
38
|
-
"@types/node": "^
|
|
39
|
-
"@types/react": "^19.
|
|
40
|
-
"@types/react-dom": "^19.
|
|
41
|
-
"jose": "^6.
|
|
42
|
-
"postgres": "^3.4.
|
|
43
|
-
"prettier": "^3.
|
|
44
|
-
"vitest": "^4.0.
|
|
38
|
+
"@langchain/langgraph-sdk": "^1.5.4",
|
|
39
|
+
"@types/node": "^25.0.9",
|
|
40
|
+
"@types/react": "^19.2.7",
|
|
41
|
+
"@types/react-dom": "^19.2.3",
|
|
42
|
+
"jose": "^6.1.3",
|
|
43
|
+
"postgres": "^3.4.7",
|
|
44
|
+
"prettier": "^3.7.4",
|
|
45
|
+
"vitest": "^4.0.16"
|
|
45
46
|
},
|
|
46
47
|
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
|
47
|
-
}
|
|
48
|
+
}
|
langgraph_api/js/remote.py
CHANGED
|
@@ -15,7 +15,7 @@ import httpx
|
|
|
15
15
|
import orjson
|
|
16
16
|
import structlog
|
|
17
17
|
import uvicorn
|
|
18
|
-
from langchain_core.runnables.config import RunnableConfig
|
|
18
|
+
from langchain_core.runnables.config import RunnableConfig, merge_configs
|
|
19
19
|
from langchain_core.runnables.graph import Edge, Node
|
|
20
20
|
from langchain_core.runnables.graph import Graph as DrawableGraph
|
|
21
21
|
from langchain_core.runnables.schema import (
|
|
@@ -49,6 +49,7 @@ from langgraph_api.js.sse import SSEDecoder, aiter_lines_raw
|
|
|
49
49
|
from langgraph_api.route import ApiResponse
|
|
50
50
|
from langgraph_api.schema import Config
|
|
51
51
|
from langgraph_api.serde import json_dumpb
|
|
52
|
+
from langgraph_api.utils import get_auth_ctx, get_user_id
|
|
52
53
|
|
|
53
54
|
logger = structlog.stdlib.get_logger(__name__)
|
|
54
55
|
|
|
@@ -170,9 +171,9 @@ class RemotePregel(BaseRemotePregel):
|
|
|
170
171
|
"getGraph",
|
|
171
172
|
{
|
|
172
173
|
"graph_id": self.graph_id,
|
|
173
|
-
"graph_config": self.config,
|
|
174
|
+
"graph_config": self._inject_auth_to_config(self.config),
|
|
174
175
|
"graph_name": self.name,
|
|
175
|
-
"config": config,
|
|
176
|
+
"config": self._inject_auth_to_config(config),
|
|
176
177
|
"xray": xray,
|
|
177
178
|
},
|
|
178
179
|
)
|
|
@@ -211,11 +212,11 @@ class RemotePregel(BaseRemotePregel):
|
|
|
211
212
|
"getSubgraphs",
|
|
212
213
|
{
|
|
213
214
|
"graph_id": self.graph_id,
|
|
214
|
-
"graph_config": self.config,
|
|
215
|
+
"graph_config": self._inject_auth_to_config(self.config),
|
|
215
216
|
"graph_name": self.name,
|
|
216
217
|
"namespace": namespace,
|
|
217
218
|
"recurse": recurse,
|
|
218
|
-
"config": config,
|
|
219
|
+
"config": self._inject_auth_to_config(config),
|
|
219
220
|
},
|
|
220
221
|
)
|
|
221
222
|
|
|
@@ -248,7 +249,7 @@ class RemotePregel(BaseRemotePregel):
|
|
|
248
249
|
|
|
249
250
|
return StateSnapshot( # type: ignore[missing-argument]
|
|
250
251
|
item.get("values"),
|
|
251
|
-
cast(tuple, item.get("next", ())),
|
|
252
|
+
cast("tuple", item.get("next", ())),
|
|
252
253
|
item.get("config"),
|
|
253
254
|
item.get("metadata"),
|
|
254
255
|
item.get("createdAt"),
|
|
@@ -266,9 +267,9 @@ class RemotePregel(BaseRemotePregel):
|
|
|
266
267
|
"getState",
|
|
267
268
|
{
|
|
268
269
|
"graph_id": self.graph_id,
|
|
269
|
-
"graph_config": self.config,
|
|
270
|
+
"graph_config": self._inject_auth_to_config(self.config),
|
|
270
271
|
"graph_name": self.name,
|
|
271
|
-
"config": config,
|
|
272
|
+
"config": self._inject_auth_to_config(config),
|
|
272
273
|
"subgraphs": subgraphs,
|
|
273
274
|
},
|
|
274
275
|
)
|
|
@@ -284,9 +285,9 @@ class RemotePregel(BaseRemotePregel):
|
|
|
284
285
|
"updateState",
|
|
285
286
|
{
|
|
286
287
|
"graph_id": self.graph_id,
|
|
287
|
-
"graph_config": self.config,
|
|
288
|
+
"graph_config": self._inject_auth_to_config(self.config),
|
|
288
289
|
"graph_name": self.name,
|
|
289
|
-
"config": config,
|
|
290
|
+
"config": self._inject_auth_to_config(config),
|
|
290
291
|
"values": values,
|
|
291
292
|
"as_node": as_node,
|
|
292
293
|
},
|
|
@@ -305,9 +306,9 @@ class RemotePregel(BaseRemotePregel):
|
|
|
305
306
|
"getStateHistory",
|
|
306
307
|
{
|
|
307
308
|
"graph_id": self.graph_id,
|
|
308
|
-
"graph_config": self.config,
|
|
309
|
+
"graph_config": self._inject_auth_to_config(self.config),
|
|
309
310
|
"graph_name": self.name,
|
|
310
|
-
"config": config,
|
|
311
|
+
"config": self._inject_auth_to_config(config),
|
|
311
312
|
"limit": limit,
|
|
312
313
|
"filter": filter,
|
|
313
314
|
"before": before,
|
|
@@ -353,6 +354,27 @@ class RemotePregel(BaseRemotePregel):
|
|
|
353
354
|
)
|
|
354
355
|
return result["nodesExecuted"]
|
|
355
356
|
|
|
357
|
+
def _inject_auth_to_config(self, config: RunnableConfig | Config):
|
|
358
|
+
if ctx := get_auth_ctx():
|
|
359
|
+
user_id = get_user_id(cast("BaseUser | None", ctx.user))
|
|
360
|
+
|
|
361
|
+
# Skip if cannot serialize the user to JSON
|
|
362
|
+
if not hasattr(ctx.user, "model_dump"):
|
|
363
|
+
return config
|
|
364
|
+
|
|
365
|
+
return merge_configs(
|
|
366
|
+
config,
|
|
367
|
+
{
|
|
368
|
+
"configurable": {
|
|
369
|
+
"langgraph_auth_user": ctx.user,
|
|
370
|
+
"langgraph_auth_user_id": user_id,
|
|
371
|
+
"langgraph_auth_permissions": list(ctx.permissions),
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
)
|
|
375
|
+
|
|
376
|
+
return config
|
|
377
|
+
|
|
356
378
|
|
|
357
379
|
async def run_js_process(paths_str: str | None, watch: bool = False):
|
|
358
380
|
# check if tsx is available
|
|
@@ -632,13 +654,13 @@ async def run_remote_checkpointer():
|
|
|
632
654
|
|
|
633
655
|
async def store_get(payload: dict):
|
|
634
656
|
"""Get store data"""
|
|
635
|
-
|
|
657
|
+
namespaces = payload.get("namespace")
|
|
636
658
|
key = payload.get("key")
|
|
637
659
|
|
|
638
|
-
if not
|
|
660
|
+
if not namespaces or not key:
|
|
639
661
|
raise ValueError("Both namespaces and key are required")
|
|
640
662
|
|
|
641
|
-
namespaces =
|
|
663
|
+
namespaces = tuple(namespaces)
|
|
642
664
|
|
|
643
665
|
store = await _get_passthrough_store()
|
|
644
666
|
result = await store.aget(namespaces, key)
|
|
@@ -648,7 +670,7 @@ async def run_remote_checkpointer():
|
|
|
648
670
|
async def store_put(payload: dict):
|
|
649
671
|
"""Put the new store data"""
|
|
650
672
|
|
|
651
|
-
namespace = tuple(payload["namespace"]
|
|
673
|
+
namespace = tuple(payload["namespace"])
|
|
652
674
|
key = payload["key"]
|
|
653
675
|
value = payload["value"]
|
|
654
676
|
index = payload.get("index")
|
|
@@ -958,7 +980,7 @@ async def handle_js_auth_event(
|
|
|
958
980
|
|
|
959
981
|
raise HTTPException(status_code=status, detail=message, headers=headers)
|
|
960
982
|
|
|
961
|
-
filters = cast(Auth.types.FilterType | None, response.get("filters"))
|
|
983
|
+
filters = cast("Auth.types.FilterType | None", response.get("filters"))
|
|
962
984
|
|
|
963
985
|
# mutate metadata in value if applicable
|
|
964
986
|
# we need to preserve the identity of the object, so cannot create a new
|
langgraph_api/js/sse.py
CHANGED
|
@@ -51,7 +51,7 @@ class BytesLineDecoder:
|
|
|
51
51
|
# Include any existing buffer in the first portion of the
|
|
52
52
|
# splitlines result.
|
|
53
53
|
self.buffer.extend(lines[0])
|
|
54
|
-
lines = [self.buffer
|
|
54
|
+
lines = [self.buffer, *lines[1:]]
|
|
55
55
|
self.buffer = bytearray()
|
|
56
56
|
|
|
57
57
|
if not trailing_newline:
|
|
@@ -79,7 +79,7 @@ class SSEDecoder:
|
|
|
79
79
|
self._retry: int | None = None
|
|
80
80
|
|
|
81
81
|
def decode(self, line: bytes) -> StreamPart | None:
|
|
82
|
-
# See: https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation
|
|
82
|
+
# See: https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation
|
|
83
83
|
|
|
84
84
|
if not line:
|
|
85
85
|
if (
|