langgraph-api 0.2.20__tar.gz → 0.2.21__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.
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/PKG-INFO +1 -1
- langgraph_api-0.2.21/langgraph_api/__init__.py +1 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/api/assistants.py +134 -97
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/graph.py +33 -19
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/stream.py +1 -1
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/pyproject.toml +1 -1
- langgraph_api-0.2.20/langgraph_api/__init__.py +0 -1
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/LICENSE +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/README.md +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/api/__init__.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/api/mcp.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/api/meta.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/api/openapi.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/api/runs.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/api/store.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/api/threads.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/api/ui.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/asyncio.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/auth/__init__.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/auth/custom.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/auth/langsmith/__init__.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/auth/langsmith/backend.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/auth/langsmith/client.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/auth/middleware.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/auth/noop.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/auth/studio_user.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/cli.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/command.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/config.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/cron_scheduler.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/errors.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/http.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/.gitignore +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/.prettierrc +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/__init__.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/base.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/build.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/client.http.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/client.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/errors.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/global.d.ts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/package.json +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/remote.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/schema.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/src/graph.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/src/load.hooks.mjs +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/src/preload.mjs +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/src/utils/files.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/src/utils/importMap.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/src/utils/serde.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/sse.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/api.test.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/auth.test.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/compose-postgres.auth.yml +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/compose-postgres.yml +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/graphs/.gitignore +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/graphs/agent.css +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/graphs/agent.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/graphs/agent.ui.tsx +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/graphs/agent_simple.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/graphs/auth.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/graphs/command.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/graphs/delay.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/graphs/dynamic.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/graphs/error.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/graphs/http.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/graphs/langgraph.json +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/graphs/nested.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/graphs/package.json +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/graphs/weather.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/graphs/yarn.lock +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/utils.mts +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tsconfig.json +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/ui.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/yarn.lock +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/logging.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/metadata.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/middleware/__init__.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/middleware/http_logger.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/middleware/private_network.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/middleware/request_id.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/models/__init__.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/models/run.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/patch.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/queue_entrypoint.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/route.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/schema.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/serde.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/server.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/sse.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/state.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/thread_ttl.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/tunneling/cloudflare.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/utils.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/validation.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/webhook.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/worker.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_license/__init__.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_license/validation.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_runtime/__init__.py +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/logging.json +0 -0
- {langgraph_api-0.2.20 → langgraph_api-0.2.21}/openapi.json +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.21"
|
|
@@ -3,6 +3,13 @@ from uuid import uuid4
|
|
|
3
3
|
|
|
4
4
|
import structlog
|
|
5
5
|
from langchain_core.runnables.utils import create_model
|
|
6
|
+
from langgraph.constants import (
|
|
7
|
+
CONFIG_KEY_CHECKPOINT_ID,
|
|
8
|
+
CONFIG_KEY_CHECKPOINT_NS,
|
|
9
|
+
CONFIG_KEY_CHECKPOINTER,
|
|
10
|
+
CONFIG_KEY_STORE,
|
|
11
|
+
CONFIG_KEY_THREAD_ID,
|
|
12
|
+
)
|
|
6
13
|
from langgraph.pregel import Pregel
|
|
7
14
|
from pydantic import TypeAdapter
|
|
8
15
|
from starlette.exceptions import HTTPException
|
|
@@ -21,13 +28,24 @@ from langgraph_api.validation import (
|
|
|
21
28
|
AssistantVersionChange,
|
|
22
29
|
AssistantVersionsSearchRequest,
|
|
23
30
|
)
|
|
31
|
+
from langgraph_runtime.checkpoint import Checkpointer
|
|
24
32
|
from langgraph_runtime.database import connect
|
|
25
33
|
from langgraph_runtime.ops import Assistants
|
|
26
34
|
from langgraph_runtime.retry import retry_db
|
|
35
|
+
from langgraph_runtime.store import Store
|
|
27
36
|
|
|
28
37
|
logger = structlog.stdlib.get_logger(__name__)
|
|
29
38
|
|
|
30
39
|
|
|
40
|
+
EXCLUDED_CONFIG_SCHEMA = (
|
|
41
|
+
CONFIG_KEY_CHECKPOINTER,
|
|
42
|
+
CONFIG_KEY_STORE,
|
|
43
|
+
CONFIG_KEY_CHECKPOINT_ID,
|
|
44
|
+
CONFIG_KEY_CHECKPOINT_NS,
|
|
45
|
+
CONFIG_KEY_THREAD_ID,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
31
49
|
def _get_configurable_jsonschema(graph: Pregel) -> dict:
|
|
32
50
|
"""Get the JSON schema for the configurable part of the graph.
|
|
33
51
|
|
|
@@ -52,6 +70,9 @@ def _get_configurable_jsonschema(graph: Pregel) -> dict:
|
|
|
52
70
|
if model_fields is not None and "configurable" in model_fields:
|
|
53
71
|
configurable = TypeAdapter(model_fields["configurable"].annotation)
|
|
54
72
|
json_schema = configurable.json_schema()
|
|
73
|
+
if json_schema:
|
|
74
|
+
for key in EXCLUDED_CONFIG_SCHEMA:
|
|
75
|
+
json_schema["properties"].pop(key, None)
|
|
55
76
|
# The type name of the configurable type is not preserved.
|
|
56
77
|
# We'll add it back to the schema if we can.
|
|
57
78
|
if hasattr(graph, "config_type") and graph.config_type is not None:
|
|
@@ -174,36 +195,41 @@ async def get_assistant_graph(
|
|
|
174
195
|
validate_uuid(assistant_id, "Invalid assistant ID: must be a UUID")
|
|
175
196
|
async with connect() as conn:
|
|
176
197
|
assistant_ = await Assistants.get(conn, assistant_id)
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
xray =
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
198
|
+
assistant = await fetchone(assistant_)
|
|
199
|
+
config = await ajson_loads(assistant["config"])
|
|
200
|
+
async with get_graph(
|
|
201
|
+
assistant["graph_id"],
|
|
202
|
+
config,
|
|
203
|
+
checkpointer=Checkpointer(conn),
|
|
204
|
+
store=Store(),
|
|
205
|
+
) as graph:
|
|
206
|
+
xray: bool | int = False
|
|
207
|
+
xray_query = request.query_params.get("xray")
|
|
208
|
+
if xray_query:
|
|
209
|
+
if xray_query in ("true", "True"):
|
|
210
|
+
xray = True
|
|
211
|
+
elif xray_query in ("false", "False"):
|
|
212
|
+
xray = False
|
|
213
|
+
else:
|
|
214
|
+
try:
|
|
215
|
+
xray = int(xray_query)
|
|
216
|
+
except ValueError:
|
|
217
|
+
raise HTTPException(422, detail="Invalid xray value") from None
|
|
218
|
+
|
|
219
|
+
if xray <= 0:
|
|
220
|
+
raise HTTPException(422, detail="Invalid xray value") from None
|
|
221
|
+
|
|
222
|
+
if isinstance(graph, BaseRemotePregel):
|
|
223
|
+
drawable_graph = await graph.fetch_graph(xray=xray)
|
|
224
|
+
return ApiResponse(drawable_graph.to_json())
|
|
225
|
+
|
|
226
|
+
try:
|
|
227
|
+
drawable_graph = await graph.aget_graph(xray=xray)
|
|
228
|
+
return ApiResponse(drawable_graph.to_json())
|
|
229
|
+
except NotImplementedError:
|
|
230
|
+
raise HTTPException(
|
|
231
|
+
422, detail="The graph does not support visualization"
|
|
232
|
+
) from None
|
|
207
233
|
|
|
208
234
|
|
|
209
235
|
@retry_db
|
|
@@ -215,35 +241,40 @@ async def get_assistant_subgraphs(
|
|
|
215
241
|
validate_uuid(assistant_id, "Invalid assistant ID: must be a UUID")
|
|
216
242
|
async with connect() as conn:
|
|
217
243
|
assistant_ = await Assistants.get(conn, assistant_id)
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
try:
|
|
233
|
-
return ApiResponse(
|
|
234
|
-
{
|
|
235
|
-
ns: _graph_schemas(subgraph)
|
|
236
|
-
async for ns, subgraph in graph.aget_subgraphs(
|
|
244
|
+
assistant = await fetchone(assistant_)
|
|
245
|
+
config = await ajson_loads(assistant["config"])
|
|
246
|
+
async with get_graph(
|
|
247
|
+
assistant["graph_id"],
|
|
248
|
+
config,
|
|
249
|
+
checkpointer=Checkpointer(conn),
|
|
250
|
+
store=Store(),
|
|
251
|
+
) as graph:
|
|
252
|
+
namespace = request.path_params.get("namespace")
|
|
253
|
+
|
|
254
|
+
if isinstance(graph, BaseRemotePregel):
|
|
255
|
+
return ApiResponse(
|
|
256
|
+
await graph.fetch_subgraphs(
|
|
237
257
|
namespace=namespace,
|
|
238
258
|
recurse=request.query_params.get("recurse", "False")
|
|
239
259
|
in ("true", "True"),
|
|
240
260
|
)
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
try:
|
|
264
|
+
return ApiResponse(
|
|
265
|
+
{
|
|
266
|
+
ns: _graph_schemas(subgraph)
|
|
267
|
+
async for ns, subgraph in graph.aget_subgraphs(
|
|
268
|
+
namespace=namespace,
|
|
269
|
+
recurse=request.query_params.get("recurse", "False")
|
|
270
|
+
in ("true", "True"),
|
|
271
|
+
)
|
|
272
|
+
}
|
|
273
|
+
)
|
|
274
|
+
except NotImplementedError:
|
|
275
|
+
raise HTTPException(
|
|
276
|
+
422, detail="The graph does not support visualization"
|
|
277
|
+
) from None
|
|
247
278
|
|
|
248
279
|
|
|
249
280
|
@retry_db
|
|
@@ -255,54 +286,60 @@ async def get_assistant_schemas(
|
|
|
255
286
|
validate_uuid(assistant_id, "Invalid assistant ID: must be a UUID")
|
|
256
287
|
async with connect() as conn:
|
|
257
288
|
assistant_ = await Assistants.get(conn, assistant_id)
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
289
|
+
# TODO Implementa cache so we can de-dent and release this connection.
|
|
290
|
+
assistant = await fetchone(assistant_)
|
|
291
|
+
config = await ajson_loads(assistant["config"])
|
|
292
|
+
async with get_graph(
|
|
293
|
+
assistant["graph_id"],
|
|
294
|
+
config,
|
|
295
|
+
checkpointer=Checkpointer(conn),
|
|
296
|
+
store=Store(),
|
|
297
|
+
) as graph:
|
|
298
|
+
if isinstance(graph, BaseRemotePregel):
|
|
299
|
+
schemas = await graph.fetch_state_schema()
|
|
300
|
+
return ApiResponse(
|
|
301
|
+
{
|
|
302
|
+
"graph_id": assistant["graph_id"],
|
|
303
|
+
"input_schema": schemas.get("input"),
|
|
304
|
+
"output_schema": schemas.get("output"),
|
|
305
|
+
"state_schema": schemas.get("state"),
|
|
306
|
+
"config_schema": schemas.get("config"),
|
|
307
|
+
}
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
try:
|
|
311
|
+
input_schema = graph.get_input_jsonschema()
|
|
312
|
+
except Exception as e:
|
|
313
|
+
logger.warning(
|
|
314
|
+
f"Failed to get input schema for graph {graph.name} with error: `{str(e)}`"
|
|
315
|
+
)
|
|
316
|
+
input_schema = None
|
|
317
|
+
try:
|
|
318
|
+
output_schema = graph.get_output_jsonschema()
|
|
319
|
+
except Exception as e:
|
|
320
|
+
logger.warning(
|
|
321
|
+
f"Failed to get output schema for graph {graph.name} with error: `{str(e)}`"
|
|
322
|
+
)
|
|
323
|
+
output_schema = None
|
|
324
|
+
|
|
325
|
+
state_schema = _state_jsonschema(graph)
|
|
326
|
+
try:
|
|
327
|
+
config_schema = _get_configurable_jsonschema(graph)
|
|
328
|
+
except Exception as e:
|
|
329
|
+
config_schema = None
|
|
330
|
+
logger.warning(
|
|
331
|
+
f"Failed to get config schema for graph {graph.name} with error: `{str(e)}`"
|
|
332
|
+
)
|
|
263
333
|
return ApiResponse(
|
|
264
334
|
{
|
|
265
335
|
"graph_id": assistant["graph_id"],
|
|
266
|
-
"input_schema":
|
|
267
|
-
"output_schema":
|
|
268
|
-
"state_schema":
|
|
269
|
-
"config_schema":
|
|
336
|
+
"input_schema": input_schema,
|
|
337
|
+
"output_schema": output_schema,
|
|
338
|
+
"state_schema": state_schema,
|
|
339
|
+
"config_schema": config_schema,
|
|
270
340
|
}
|
|
271
341
|
)
|
|
272
342
|
|
|
273
|
-
try:
|
|
274
|
-
input_schema = graph.get_input_jsonschema()
|
|
275
|
-
except Exception as e:
|
|
276
|
-
logger.warning(
|
|
277
|
-
f"Failed to get input schema for graph {graph.name} with error: `{str(e)}`"
|
|
278
|
-
)
|
|
279
|
-
input_schema = None
|
|
280
|
-
try:
|
|
281
|
-
output_schema = graph.get_output_jsonschema()
|
|
282
|
-
except Exception as e:
|
|
283
|
-
logger.warning(
|
|
284
|
-
f"Failed to get output schema for graph {graph.name} with error: `{str(e)}`"
|
|
285
|
-
)
|
|
286
|
-
output_schema = None
|
|
287
|
-
|
|
288
|
-
state_schema = _state_jsonschema(graph)
|
|
289
|
-
try:
|
|
290
|
-
config_schema = _get_configurable_jsonschema(graph)
|
|
291
|
-
except Exception as e:
|
|
292
|
-
config_schema = None
|
|
293
|
-
logger.warning(
|
|
294
|
-
f"Failed to get config schema for graph {graph.name} with error: `{str(e)}`"
|
|
295
|
-
)
|
|
296
|
-
return ApiResponse(
|
|
297
|
-
{
|
|
298
|
-
"graph_id": assistant["graph_id"],
|
|
299
|
-
"input_schema": input_schema,
|
|
300
|
-
"output_schema": output_schema,
|
|
301
|
-
"state_schema": state_schema,
|
|
302
|
-
"config_schema": config_schema,
|
|
303
|
-
}
|
|
304
|
-
)
|
|
305
|
-
|
|
306
343
|
|
|
307
344
|
@retry_db
|
|
308
345
|
async def patch_assistant(
|
|
@@ -15,11 +15,13 @@ from typing import TYPE_CHECKING, Any, NamedTuple
|
|
|
15
15
|
from uuid import UUID, uuid5
|
|
16
16
|
|
|
17
17
|
import structlog
|
|
18
|
-
from langchain_core.runnables.config import run_in_executor
|
|
18
|
+
from langchain_core.runnables.config import run_in_executor, var_child_runnable_config
|
|
19
19
|
from langgraph.checkpoint.base import BaseCheckpointSaver
|
|
20
|
+
from langgraph.constants import CONFIG_KEY_CHECKPOINTER, CONFIG_KEY_STORE
|
|
20
21
|
from langgraph.graph import Graph
|
|
21
22
|
from langgraph.pregel import Pregel
|
|
22
23
|
from langgraph.store.base import BaseStore
|
|
24
|
+
from langgraph.utils.config import ensure_config
|
|
23
25
|
from starlette.exceptions import HTTPException
|
|
24
26
|
|
|
25
27
|
from langgraph_api import asyncio as lg_asyncio
|
|
@@ -109,26 +111,38 @@ async def get_graph(
|
|
|
109
111
|
"""Return the runnable."""
|
|
110
112
|
assert_graph_exists(graph_id)
|
|
111
113
|
value = GRAPHS[graph_id]
|
|
114
|
+
token = None
|
|
112
115
|
if graph_id in FACTORY_ACCEPTS_CONFIG:
|
|
116
|
+
config = ensure_config(config)
|
|
117
|
+
if store is not None and not config["configurable"].get(CONFIG_KEY_STORE):
|
|
118
|
+
config["configurable"][CONFIG_KEY_STORE] = store
|
|
119
|
+
if checkpointer is not None and not config["configurable"].get(
|
|
120
|
+
CONFIG_KEY_CHECKPOINTER
|
|
121
|
+
):
|
|
122
|
+
config["configurable"][CONFIG_KEY_CHECKPOINTER] = checkpointer
|
|
123
|
+
token = var_child_runnable_config.set(config)
|
|
113
124
|
value = value(config) if FACTORY_ACCEPTS_CONFIG[graph_id] else value()
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
125
|
+
try:
|
|
126
|
+
async with _generate_graph(value) as graph_obj:
|
|
127
|
+
if isinstance(graph_obj, Graph):
|
|
128
|
+
graph_obj = graph_obj.compile()
|
|
129
|
+
if not isinstance(graph_obj, Pregel | BaseRemotePregel):
|
|
130
|
+
raise HTTPException(
|
|
131
|
+
status_code=424,
|
|
132
|
+
detail=f"Graph '{graph_id}' is not valid. Review graph registration.",
|
|
133
|
+
)
|
|
134
|
+
update = {
|
|
135
|
+
"checkpointer": checkpointer,
|
|
136
|
+
"store": store,
|
|
137
|
+
}
|
|
138
|
+
if graph_obj.name == "LangGraph":
|
|
139
|
+
update["name"] = graph_id
|
|
140
|
+
if isinstance(graph_obj, BaseRemotePregel):
|
|
141
|
+
update["config"] = config
|
|
142
|
+
yield graph_obj.copy(update=update)
|
|
143
|
+
finally:
|
|
144
|
+
if token is not None:
|
|
145
|
+
var_child_runnable_config.reset(token)
|
|
132
146
|
|
|
133
147
|
|
|
134
148
|
def graph_exists(graph_id: str) -> bool:
|
|
@@ -119,7 +119,7 @@ async def astream_state(
|
|
|
119
119
|
is_remote_pregel = isinstance(graph, BaseRemotePregel)
|
|
120
120
|
if not is_remote_pregel:
|
|
121
121
|
config["configurable"]["__pregel_node_finished"] = incr_nodes
|
|
122
|
-
|
|
122
|
+
|
|
123
123
|
# attach run_id to config
|
|
124
124
|
# for attempts beyond the first, use a fresh, unique run_id
|
|
125
125
|
config = {**config, "run_id": run["run_id"]} if attempt == 1 else config
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.2.20"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/compose-postgres.auth.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langgraph_api-0.2.20 → langgraph_api-0.2.21}/langgraph_api/js/tests/graphs/agent_simple.mts
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|