langgraph-api 0.0.26__tar.gz → 0.0.27__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.0.26 → langgraph_api-0.0.27}/PKG-INFO +8 -8
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/README.md +1 -1
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/api/meta.py +1 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/cli.py +72 -57
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/config.py +9 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/build.mts +5 -2
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/client.mts +17 -9
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/client.new.mts +18 -4
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/package.json +4 -2
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/remote_old.py +9 -6
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/src/graph.mts +5 -4
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/yarn.lock +5 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/pyproject.toml +7 -7
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/LICENSE +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/__init__.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/api/__init__.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/api/assistants.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/api/openapi.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/api/runs.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/api/store.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/api/threads.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/asyncio.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/auth/__init__.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/auth/custom.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/auth/langsmith/__init__.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/auth/langsmith/backend.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/auth/langsmith/client.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/auth/middleware.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/auth/noop.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/auth/studio_user.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/cron_scheduler.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/errors.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/graph.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/http.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/.gitignore +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/base.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/errors.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/global.d.ts +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/remote.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/remote_new.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/schema.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/server_sent_events.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/src/hooks.mjs +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/src/parser/parser.mts +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/src/parser/parser.worker.mjs +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/src/schema/types.mts +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/src/schema/types.template.mts +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/src/utils/importMap.mts +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/src/utils/serde.mts +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/tests/api.test.mts +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/tests/compose-postgres.yml +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/tests/graphs/.gitignore +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/tests/graphs/agent.mts +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/tests/graphs/delay.mts +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/tests/graphs/error.mts +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/tests/graphs/langgraph.json +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/tests/graphs/nested.mts +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/tests/graphs/package.json +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/tests/graphs/weather.mts +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/tests/graphs/yarn.lock +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/tests/parser.test.mts +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/js/tests/utils.mts +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/lifespan.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/logging.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/metadata.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/middleware/__init__.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/middleware/http_logger.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/middleware/private_network.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/models/__init__.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/models/run.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/patch.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/queue.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/route.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/schema.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/serde.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/server.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/sse.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/state.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/stream.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/utils.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_api/validation.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_license/__init__.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_license/middleware.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_license/validation.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_storage/__init__.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_storage/checkpoint.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_storage/database.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_storage/ops.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_storage/queue.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_storage/retry.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_storage/store.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/langgraph_storage/ttl_dict.py +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/logging.json +0 -0
- {langgraph_api-0.0.26 → langgraph_api-0.0.27}/openapi.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: langgraph-api
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.27
|
|
4
4
|
Summary:
|
|
5
5
|
License: Elastic-2.0
|
|
6
6
|
Author: Nuno Campos
|
|
@@ -11,26 +11,26 @@ Classifier: Programming Language :: Python :: 3
|
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.12
|
|
13
13
|
Requires-Dist: cryptography (>=43.0.3,<44.0.0)
|
|
14
|
-
Requires-Dist: httpx (>=0.
|
|
15
|
-
Requires-Dist: jsonschema-rs (>=0.
|
|
14
|
+
Requires-Dist: httpx (>=0.25.0)
|
|
15
|
+
Requires-Dist: jsonschema-rs (>=0.20.0,<0.21.0)
|
|
16
16
|
Requires-Dist: langchain-core (>=0.2.38,<0.4.0)
|
|
17
|
-
Requires-Dist: langgraph (>=0.2.56,<0.
|
|
17
|
+
Requires-Dist: langgraph (>=0.2.56,<0.4.0)
|
|
18
18
|
Requires-Dist: langgraph-checkpoint (>=2.0.15,<3.0)
|
|
19
19
|
Requires-Dist: langgraph-sdk (>=0.1.53,<0.2.0)
|
|
20
20
|
Requires-Dist: langsmith (>=0.1.63,<0.4.0)
|
|
21
|
-
Requires-Dist: orjson (>=3.
|
|
21
|
+
Requires-Dist: orjson (>=3.9.7)
|
|
22
22
|
Requires-Dist: pyjwt (>=2.9.0,<3.0.0)
|
|
23
23
|
Requires-Dist: sse-starlette (>=2.1.0,<2.2.0)
|
|
24
24
|
Requires-Dist: starlette (>=0.38.6)
|
|
25
|
-
Requires-Dist: structlog (>=
|
|
26
|
-
Requires-Dist: tenacity (>=8.
|
|
25
|
+
Requires-Dist: structlog (>=23.1.0,<24.0.0)
|
|
26
|
+
Requires-Dist: tenacity (>=8.0.0)
|
|
27
27
|
Requires-Dist: uvicorn (>=0.26.0)
|
|
28
28
|
Requires-Dist: watchfiles (>=0.13)
|
|
29
29
|
Description-Content-Type: text/markdown
|
|
30
30
|
|
|
31
31
|
# LangGraph API
|
|
32
32
|
|
|
33
|
-
This package implements the LangGraph API for rapid development and testing. Build and iterate on LangGraph agents with a tight feedback loop. The
|
|
33
|
+
This package implements the LangGraph API for rapid development and testing. Build and iterate on LangGraph agents with a tight feedback loop. The server is backed by a predominently in-memory data store that is persisted to local disk when the server is restarted.
|
|
34
34
|
|
|
35
35
|
For production use, see the various [deployment options](https://langchain-ai.github.io/langgraph/concepts/deployment_options/) for the LangGraph API, which are backed by a production-grade database.
|
|
36
36
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# LangGraph API
|
|
2
2
|
|
|
3
|
-
This package implements the LangGraph API for rapid development and testing. Build and iterate on LangGraph agents with a tight feedback loop. The
|
|
3
|
+
This package implements the LangGraph API for rapid development and testing. Build and iterate on LangGraph agents with a tight feedback loop. The server is backed by a predominently in-memory data store that is persisted to local disk when the server is restarted.
|
|
4
4
|
|
|
5
5
|
For production use, see the various [deployment options](https://langchain-ai.github.io/langgraph/concepts/deployment_options/) for the LangGraph API, which are backed by a production-grade database.
|
|
6
6
|
|
|
@@ -16,6 +16,16 @@ logging.basicConfig(level=logging.INFO)
|
|
|
16
16
|
logger = logging.getLogger(__name__)
|
|
17
17
|
|
|
18
18
|
|
|
19
|
+
def _get_ls_origin() -> str | None:
|
|
20
|
+
from langsmith.client import Client
|
|
21
|
+
from langsmith.utils import tracing_is_enabled
|
|
22
|
+
|
|
23
|
+
if not tracing_is_enabled():
|
|
24
|
+
return
|
|
25
|
+
client = Client()
|
|
26
|
+
return client._host_url
|
|
27
|
+
|
|
28
|
+
|
|
19
29
|
def _get_org_id() -> str | None:
|
|
20
30
|
from langsmith.client import Client
|
|
21
31
|
from langsmith.utils import tracing_is_enabled
|
|
@@ -201,49 +211,67 @@ def run_server(
|
|
|
201
211
|
logger.info("Debugger attached. Starting server...")
|
|
202
212
|
|
|
203
213
|
local_url = f"http://{host}:{port}"
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
if
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
214
|
+
|
|
215
|
+
with patch_environment(
|
|
216
|
+
MIGRATIONS_PATH="__inmem",
|
|
217
|
+
DATABASE_URI=":memory:",
|
|
218
|
+
REDIS_URI="fake",
|
|
219
|
+
N_JOBS_PER_WORKER=str(n_jobs_per_worker if n_jobs_per_worker else 1),
|
|
220
|
+
LANGGRAPH_STORE=json.dumps(store) if store else None,
|
|
221
|
+
LANGSERVE_GRAPHS=json.dumps(graphs) if graphs else None,
|
|
222
|
+
LANGSMITH_LANGGRAPH_API_VARIANT="local_dev",
|
|
223
|
+
LANGGRAPH_AUTH=json.dumps(auth) if auth else None,
|
|
224
|
+
LANGGRAPH_HTTP=json.dumps(http) if http else None,
|
|
225
|
+
# See https://developer.chrome.com/blog/private-network-access-update-2024-03
|
|
226
|
+
ALLOW_PRIVATE_NETWORK="true",
|
|
227
|
+
**(env_vars or {}),
|
|
228
|
+
):
|
|
229
|
+
studio_origin = _get_ls_origin() or "https://smith.langchain.com"
|
|
230
|
+
studio_url = f"{studio_origin}/studio/?baseUrl={local_url}"
|
|
231
|
+
|
|
232
|
+
def _open_browser():
|
|
233
|
+
nonlocal studio_origin, studio_url
|
|
234
|
+
import time
|
|
235
|
+
import urllib.request
|
|
236
|
+
import webbrowser
|
|
237
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
238
|
+
|
|
239
|
+
thread_logger = logging.getLogger("browser_opener")
|
|
240
|
+
if not thread_logger.handlers:
|
|
241
|
+
handler = logging.StreamHandler()
|
|
242
|
+
handler.setFormatter(logging.Formatter("%(message)s"))
|
|
243
|
+
thread_logger.addHandler(handler)
|
|
244
|
+
|
|
245
|
+
with ThreadPoolExecutor(max_workers=1) as executor:
|
|
246
|
+
org_id_future = executor.submit(_get_org_id)
|
|
247
|
+
|
|
248
|
+
while True:
|
|
249
|
+
try:
|
|
250
|
+
with urllib.request.urlopen(f"{local_url}/ok") as response:
|
|
251
|
+
if response.status == 200:
|
|
252
|
+
try:
|
|
253
|
+
org_id = org_id_future.result(timeout=3.0)
|
|
254
|
+
if org_id:
|
|
255
|
+
studio_url = f"{studio_origin}/studio/?baseUrl={local_url}&organizationId={org_id}"
|
|
256
|
+
except TimeoutError as e:
|
|
257
|
+
thread_logger.debug(
|
|
258
|
+
f"Failed to get organization ID: {str(e)}"
|
|
259
|
+
)
|
|
260
|
+
pass
|
|
261
|
+
thread_logger.info(
|
|
262
|
+
f"Server started in {time.time() - start_time:.2f}s"
|
|
233
263
|
)
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
welcome = f"""
|
|
264
|
+
thread_logger.info(
|
|
265
|
+
"🎨 Opening Studio in your browser..."
|
|
266
|
+
)
|
|
267
|
+
thread_logger.info("URL: " + studio_url)
|
|
268
|
+
webbrowser.open(studio_url)
|
|
269
|
+
return
|
|
270
|
+
except urllib.error.URLError:
|
|
271
|
+
pass
|
|
272
|
+
time.sleep(0.1)
|
|
273
|
+
|
|
274
|
+
welcome = f"""
|
|
247
275
|
|
|
248
276
|
Welcome to
|
|
249
277
|
|
|
@@ -259,21 +287,8 @@ This in-memory server is designed for development and testing.
|
|
|
259
287
|
For production use, please use LangGraph Cloud.
|
|
260
288
|
|
|
261
289
|
"""
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
MIGRATIONS_PATH="__inmem",
|
|
265
|
-
DATABASE_URI=":memory:",
|
|
266
|
-
REDIS_URI="fake",
|
|
267
|
-
N_JOBS_PER_WORKER=str(n_jobs_per_worker if n_jobs_per_worker else 1),
|
|
268
|
-
LANGGRAPH_STORE=json.dumps(store) if store else None,
|
|
269
|
-
LANGSERVE_GRAPHS=json.dumps(graphs) if graphs else None,
|
|
270
|
-
LANGSMITH_LANGGRAPH_API_VARIANT="local_dev",
|
|
271
|
-
LANGGRAPH_AUTH=json.dumps(auth) if auth else None,
|
|
272
|
-
LANGGRAPH_HTTP=json.dumps(http) if http else None,
|
|
273
|
-
# See https://developer.chrome.com/blog/private-network-access-update-2024-03
|
|
274
|
-
ALLOW_PRIVATE_NETWORK="true",
|
|
275
|
-
**(env_vars or {}),
|
|
276
|
-
):
|
|
290
|
+
logger.info(welcome)
|
|
291
|
+
|
|
277
292
|
if open_browser:
|
|
278
293
|
threading.Thread(target=_open_browser, daemon=True).start()
|
|
279
294
|
supported_kwargs = {
|
|
@@ -166,9 +166,18 @@ if (
|
|
|
166
166
|
LANGSMITH_API_KEY
|
|
167
167
|
and not getenv("LANGCHAIN_TRACING_V2")
|
|
168
168
|
and not getenv("LANGCHAIN_TRACING")
|
|
169
|
+
and not getenv("LANGSMITH_TRACING_V2")
|
|
170
|
+
and not getenv("LANGSMITH_TRACING")
|
|
169
171
|
):
|
|
170
172
|
environ["LANGCHAIN_TRACING_V2"] = "true"
|
|
171
173
|
|
|
174
|
+
TRACING = (
|
|
175
|
+
env("LANGCHAIN_TRACING_V2", cast=bool, default=None)
|
|
176
|
+
or env("LANGCHAIN_TRACING", cast=bool, default=None)
|
|
177
|
+
or env("LANGSMITH_TRACING_V2", cast=bool, default=None)
|
|
178
|
+
or env("LANGSMITH_TRACING", cast=bool, default=None)
|
|
179
|
+
)
|
|
180
|
+
|
|
172
181
|
# if variant is "licensed", update to "local" if using LANGSMITH_API_KEY instead
|
|
173
182
|
|
|
174
183
|
if getenv("LANGSMITH_LANGGRAPH_API_VARIANT") == "licensed" and LANGSMITH_API_KEY:
|
|
@@ -17,7 +17,7 @@ async function main() {
|
|
|
17
17
|
z.record(z.string()).parse(JSON.parse(process.env.LANGSERVE_GRAPHS))
|
|
18
18
|
);
|
|
19
19
|
|
|
20
|
-
const GRAPH_SCHEMAS: Record<string, Record<string, GraphSchema
|
|
20
|
+
const GRAPH_SCHEMAS: Record<string, Record<string, GraphSchema> | false> = {};
|
|
21
21
|
|
|
22
22
|
try {
|
|
23
23
|
await Promise.all(
|
|
@@ -29,9 +29,12 @@ async function main() {
|
|
|
29
29
|
|
|
30
30
|
try {
|
|
31
31
|
console.info(`[${graphId}]: Extracting schema`);
|
|
32
|
-
GRAPH_SCHEMAS[graphId] = await runGraphSchemaWorker(spec
|
|
32
|
+
GRAPH_SCHEMAS[graphId] = await runGraphSchemaWorker(spec, {
|
|
33
|
+
timeoutMs: 120_000,
|
|
34
|
+
});
|
|
33
35
|
} catch (error) {
|
|
34
36
|
console.error(`[${graphId}]: Error extracting schema: ${error}`);
|
|
37
|
+
GRAPH_SCHEMAS[graphId] = false;
|
|
35
38
|
}
|
|
36
39
|
})
|
|
37
40
|
);
|
|
@@ -43,6 +43,8 @@ import {
|
|
|
43
43
|
GraphSpec,
|
|
44
44
|
filterValidGraphSpecs,
|
|
45
45
|
} from "./src/graph.mts";
|
|
46
|
+
import { asyncExitHook, gracefulExit } from "exit-hook";
|
|
47
|
+
import { awaitAllCallbacks } from "@langchain/core/callbacks/promises";
|
|
46
48
|
|
|
47
49
|
const logger = createLogger({
|
|
48
50
|
level: "debug",
|
|
@@ -76,7 +78,7 @@ const logger = createLogger({
|
|
|
76
78
|
],
|
|
77
79
|
});
|
|
78
80
|
|
|
79
|
-
let GRAPH_SCHEMA: Record<string, Record<string, GraphSchema
|
|
81
|
+
let GRAPH_SCHEMA: Record<string, Record<string, GraphSchema> | false> = {};
|
|
80
82
|
const GRAPH_RESOLVED: Record<string, CompiledGraph<string>> = {};
|
|
81
83
|
const GRAPH_SPEC: Record<string, GraphSpec> = {};
|
|
82
84
|
|
|
@@ -92,6 +94,11 @@ async function getOrExtractSchema(graphId: string) {
|
|
|
92
94
|
}
|
|
93
95
|
|
|
94
96
|
if (!GRAPH_SCHEMA[graphId]) {
|
|
97
|
+
// This is only set during build phase
|
|
98
|
+
if (GRAPH_SCHEMA[graphId] === false) {
|
|
99
|
+
throw new Error(`Failed to locate schema for "${graphId}"`);
|
|
100
|
+
}
|
|
101
|
+
|
|
95
102
|
try {
|
|
96
103
|
const timer = logger.startTimer();
|
|
97
104
|
GRAPH_SCHEMA[graphId] = await runGraphSchemaWorker(GRAPH_SPEC[graphId]);
|
|
@@ -604,12 +611,12 @@ const GetGraphPayload = z.object({
|
|
|
604
611
|
async function getGraphRequest(rawPayload: z.infer<typeof GetGraphPayload>) {
|
|
605
612
|
const { graph_id: graphId, ...payload } = rawPayload;
|
|
606
613
|
const graph = getGraph(graphId);
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
614
|
+
|
|
615
|
+
const drawable = await graph.getGraphAsync({
|
|
616
|
+
...getRunnableConfig(payload.config),
|
|
617
|
+
xray: payload.xray ?? undefined,
|
|
618
|
+
});
|
|
619
|
+
return drawable.toJSON();
|
|
613
620
|
}
|
|
614
621
|
|
|
615
622
|
const GetSubgraphsPayload = z.object({
|
|
@@ -630,7 +637,7 @@ async function getSubgraphsRequest(
|
|
|
630
637
|
|
|
631
638
|
if (!rootGraphId) throw new Error("Failed to find root graph");
|
|
632
639
|
|
|
633
|
-
for (const [name] of graph.
|
|
640
|
+
for await (const [name] of graph.getSubgraphsAsync(
|
|
634
641
|
payload.namespace ?? undefined,
|
|
635
642
|
payload.recurse ?? undefined
|
|
636
643
|
)) {
|
|
@@ -831,7 +838,8 @@ async function main() {
|
|
|
831
838
|
|
|
832
839
|
process.on("uncaughtExceptionMonitor", (error) => {
|
|
833
840
|
logger.error(error);
|
|
834
|
-
|
|
841
|
+
gracefulExit();
|
|
835
842
|
});
|
|
836
843
|
|
|
844
|
+
asyncExitHook(() => awaitAllCallbacks(), { wait: 3_000 });
|
|
837
845
|
main();
|
|
@@ -39,6 +39,8 @@ import {
|
|
|
39
39
|
GraphSpec,
|
|
40
40
|
filterValidGraphSpecs,
|
|
41
41
|
} from "./src/graph.mts";
|
|
42
|
+
import { asyncExitHook, gracefulExit } from "exit-hook";
|
|
43
|
+
import { awaitAllCallbacks } from "@langchain/core/callbacks/promises";
|
|
42
44
|
|
|
43
45
|
const logger = createLogger({
|
|
44
46
|
level: "debug",
|
|
@@ -72,7 +74,7 @@ const logger = createLogger({
|
|
|
72
74
|
],
|
|
73
75
|
});
|
|
74
76
|
|
|
75
|
-
let GRAPH_SCHEMA: Record<string, Record<string, GraphSchema
|
|
77
|
+
let GRAPH_SCHEMA: Record<string, Record<string, GraphSchema> | false> = {};
|
|
76
78
|
const GRAPH_RESOLVED: Record<string, CompiledGraph<string>> = {};
|
|
77
79
|
const GRAPH_SPEC: Record<string, GraphSpec> = {};
|
|
78
80
|
|
|
@@ -87,6 +89,11 @@ async function getOrExtractSchema(graphId: string) {
|
|
|
87
89
|
}
|
|
88
90
|
|
|
89
91
|
if (!GRAPH_SCHEMA[graphId]) {
|
|
92
|
+
// This is only set during build phase
|
|
93
|
+
if (GRAPH_SCHEMA[graphId] === false) {
|
|
94
|
+
throw new Error(`Failed to locate schema for "${graphId}"`);
|
|
95
|
+
}
|
|
96
|
+
|
|
90
97
|
try {
|
|
91
98
|
const timer = logger.startTimer();
|
|
92
99
|
GRAPH_SCHEMA[graphId] = await runGraphSchemaWorker(GRAPH_SPEC[graphId]);
|
|
@@ -208,6 +215,7 @@ async function* getRouterPackets(): AsyncGenerator<RouterPacket> {
|
|
|
208
215
|
}
|
|
209
216
|
}
|
|
210
217
|
|
|
218
|
+
const dealerSendQueue = new PQueue({ concurrency: 1 });
|
|
211
219
|
async function sendRecv<T = any>(
|
|
212
220
|
method: `${"checkpointer" | "store"}_${string}`,
|
|
213
221
|
data: unknown
|
|
@@ -216,7 +224,9 @@ async function sendRecv<T = any>(
|
|
|
216
224
|
createFuture(id);
|
|
217
225
|
|
|
218
226
|
try {
|
|
219
|
-
await
|
|
227
|
+
await dealerSendQueue.add(() =>
|
|
228
|
+
remoteDealer.send(packPlain({ method, id, data }))
|
|
229
|
+
);
|
|
220
230
|
queue.add(scheduleRead, { timeout: 10_000, throwOnTimeout: true });
|
|
221
231
|
|
|
222
232
|
return (await remoteTasks[id].promise) as T;
|
|
@@ -225,6 +235,7 @@ async function sendRecv<T = any>(
|
|
|
225
235
|
}
|
|
226
236
|
}
|
|
227
237
|
|
|
238
|
+
const routerSendQueue = new PQueue({ concurrency: 1 });
|
|
228
239
|
const createSendWithTTL = (packet: RouterPacket) => {
|
|
229
240
|
const { header, input } = packet;
|
|
230
241
|
const { method, id } = input;
|
|
@@ -232,7 +243,9 @@ const createSendWithTTL = (packet: RouterPacket) => {
|
|
|
232
243
|
let timer: NodeJS.Timeout | undefined = undefined;
|
|
233
244
|
const sendData = async (result?: { success: boolean; data: unknown }) => {
|
|
234
245
|
clearTimeout(timer);
|
|
235
|
-
await
|
|
246
|
+
await routerSendQueue.add(() =>
|
|
247
|
+
clientRouter.send([header, pack({ method, id, ...result })])
|
|
248
|
+
);
|
|
236
249
|
timer = setTimeout(() => sendData(), CLIENT_HEARTBEAT_INTERVAL_MS);
|
|
237
250
|
};
|
|
238
251
|
|
|
@@ -855,7 +868,8 @@ async function main() {
|
|
|
855
868
|
|
|
856
869
|
process.on("uncaughtExceptionMonitor", (error) => {
|
|
857
870
|
logger.error(error);
|
|
858
|
-
|
|
871
|
+
gracefulExit();
|
|
859
872
|
});
|
|
860
873
|
|
|
874
|
+
asyncExitHook(() => awaitAllCallbacks(), { wait: 3_000 });
|
|
861
875
|
main();
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"@types/json-schema": "^7.0.15",
|
|
15
15
|
"@typescript/vfs": "^1.6.0",
|
|
16
16
|
"dedent": "^1.5.3",
|
|
17
|
+
"exit-hook": "^4.0.0",
|
|
17
18
|
"hono": "^4.5.4",
|
|
18
19
|
"p-queue": "^8.0.1",
|
|
19
20
|
"p-retry": "^6.2.0",
|
|
@@ -31,5 +32,6 @@
|
|
|
31
32
|
"postgres": "^3.4.4",
|
|
32
33
|
"prettier": "^3.3.3",
|
|
33
34
|
"vitest": "^3.0.4"
|
|
34
|
-
}
|
|
35
|
-
|
|
35
|
+
},
|
|
36
|
+
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
|
37
|
+
}
|
|
@@ -2,9 +2,11 @@ import asyncio
|
|
|
2
2
|
import base64
|
|
3
3
|
import os
|
|
4
4
|
import shutil
|
|
5
|
+
import ssl
|
|
5
6
|
from collections.abc import AsyncIterator
|
|
6
7
|
from typing import Any, Literal
|
|
7
8
|
|
|
9
|
+
import certifi
|
|
8
10
|
import httpx
|
|
9
11
|
import orjson
|
|
10
12
|
import structlog
|
|
@@ -38,6 +40,7 @@ logger = structlog.stdlib.get_logger(__name__)
|
|
|
38
40
|
|
|
39
41
|
GRAPH_SOCKET = "./graph.sock"
|
|
40
42
|
REMOTE_SOCKET = "./checkpointer.sock"
|
|
43
|
+
SSL = ssl.create_default_context(cafile=certifi.where())
|
|
41
44
|
|
|
42
45
|
|
|
43
46
|
async def _client_stream(method: str, data: dict[str, Any]):
|
|
@@ -50,7 +53,7 @@ async def _client_stream(method: str, data: dict[str, Any]):
|
|
|
50
53
|
base_url="http://graph",
|
|
51
54
|
timeout=httpx.Timeout(None),
|
|
52
55
|
limits=httpx.Limits(),
|
|
53
|
-
transport=httpx.AsyncHTTPTransport(uds=GRAPH_SOCKET),
|
|
56
|
+
transport=httpx.AsyncHTTPTransport(uds=GRAPH_SOCKET, verify=SSL),
|
|
54
57
|
)
|
|
55
58
|
|
|
56
59
|
async with aconnect_sse(
|
|
@@ -77,7 +80,7 @@ async def _client_invoke(method: str, data: dict[str, Any]):
|
|
|
77
80
|
base_url="http://graph",
|
|
78
81
|
timeout=httpx.Timeout(None),
|
|
79
82
|
limits=httpx.Limits(),
|
|
80
|
-
transport=httpx.AsyncHTTPTransport(uds=GRAPH_SOCKET),
|
|
83
|
+
transport=httpx.AsyncHTTPTransport(uds=GRAPH_SOCKET, verify=SSL),
|
|
81
84
|
)
|
|
82
85
|
|
|
83
86
|
res = await _async_client.post(
|
|
@@ -612,12 +615,12 @@ async def wait_until_js_ready():
|
|
|
612
615
|
async with (
|
|
613
616
|
httpx.AsyncClient(
|
|
614
617
|
base_url="http://graph",
|
|
615
|
-
transport=httpx.AsyncHTTPTransport(uds=GRAPH_SOCKET),
|
|
618
|
+
transport=httpx.AsyncHTTPTransport(uds=GRAPH_SOCKET, verify=SSL),
|
|
616
619
|
limits=httpx.Limits(),
|
|
617
620
|
) as graph_client,
|
|
618
621
|
httpx.AsyncClient(
|
|
619
622
|
base_url="http://checkpointer",
|
|
620
|
-
transport=httpx.AsyncHTTPTransport(uds=REMOTE_SOCKET),
|
|
623
|
+
transport=httpx.AsyncHTTPTransport(uds=REMOTE_SOCKET, verify=SSL),
|
|
621
624
|
limits=httpx.Limits(),
|
|
622
625
|
) as checkpointer_client,
|
|
623
626
|
):
|
|
@@ -641,12 +644,12 @@ async def js_healthcheck():
|
|
|
641
644
|
async with (
|
|
642
645
|
httpx.AsyncClient(
|
|
643
646
|
base_url="http://graph",
|
|
644
|
-
transport=httpx.AsyncHTTPTransport(uds=GRAPH_SOCKET),
|
|
647
|
+
transport=httpx.AsyncHTTPTransport(uds=GRAPH_SOCKET, verify=SSL),
|
|
645
648
|
limits=httpx.Limits(),
|
|
646
649
|
) as graph_client,
|
|
647
650
|
httpx.AsyncClient(
|
|
648
651
|
base_url="http://checkpointer",
|
|
649
|
-
transport=httpx.AsyncHTTPTransport(uds=REMOTE_SOCKET),
|
|
652
|
+
transport=httpx.AsyncHTTPTransport(uds=REMOTE_SOCKET, verify=SSL),
|
|
650
653
|
limits=httpx.Limits(),
|
|
651
654
|
) as checkpointer_client,
|
|
652
655
|
):
|
|
@@ -82,9 +82,10 @@ export async function resolveGraph(
|
|
|
82
82
|
return { sourceFile, exportSymbol, resolved };
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
export async function runGraphSchemaWorker(
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
export async function runGraphSchemaWorker(
|
|
86
|
+
spec: GraphSpec,
|
|
87
|
+
options?: { timeoutMs?: number }
|
|
88
|
+
) {
|
|
88
89
|
return await new Promise<Record<string, GraphSchema>>((resolve, reject) => {
|
|
89
90
|
const worker = new Worker(
|
|
90
91
|
new URL("./parser/parser.worker.mjs", import.meta.url).pathname
|
|
@@ -94,7 +95,7 @@ export async function runGraphSchemaWorker(spec: GraphSpec) {
|
|
|
94
95
|
const timeoutId = setTimeout(() => {
|
|
95
96
|
worker.terminate();
|
|
96
97
|
reject(new Error("Schema extract worker timed out"));
|
|
97
|
-
},
|
|
98
|
+
}, options?.timeoutMs ?? 30_000);
|
|
98
99
|
|
|
99
100
|
worker.on("message", (result) => {
|
|
100
101
|
worker.terminate();
|
|
@@ -1032,6 +1032,11 @@ events@^3.3.0:
|
|
|
1032
1032
|
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
|
|
1033
1033
|
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
|
|
1034
1034
|
|
|
1035
|
+
exit-hook@^4.0.0:
|
|
1036
|
+
version "4.0.0"
|
|
1037
|
+
resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-4.0.0.tgz#c1e16ebd03d3166f837b1502dac755bb5c460d58"
|
|
1038
|
+
integrity sha512-Fqs7ChZm72y40wKjOFXBKg7nJZvQJmewP5/7LtePDdnah/+FH9Hp5sgMujSCMPXlxOAW2//1jrW9pnsY7o20vQ==
|
|
1039
|
+
|
|
1035
1040
|
expect-type@^1.1.0:
|
|
1036
1041
|
version "1.1.0"
|
|
1037
1042
|
resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-1.1.0.tgz#a146e414250d13dfc49eafcfd1344a4060fa4c75"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "langgraph-api"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.27"
|
|
4
4
|
description = ""
|
|
5
5
|
authors = [
|
|
6
6
|
"Nuno Campos <nuno@langchain.dev>",
|
|
@@ -23,16 +23,16 @@ python = ">=3.11.0,<4.0"
|
|
|
23
23
|
sse-starlette = ">=2.1.0,<2.2.0"
|
|
24
24
|
starlette = ">=0.38.6"
|
|
25
25
|
watchfiles = ">=0.13"
|
|
26
|
-
langgraph = ">=0.2.56,<0.
|
|
26
|
+
langgraph = ">=0.2.56,<0.4.0"
|
|
27
27
|
langgraph-checkpoint = ">=2.0.15,<3.0"
|
|
28
|
-
orjson = ">=3.
|
|
28
|
+
orjson = ">=3.9.7"
|
|
29
29
|
uvicorn = ">=0.26.0"
|
|
30
30
|
langsmith = ">=0.1.63,<0.4.0"
|
|
31
|
-
httpx = ">=0.
|
|
31
|
+
httpx = ">=0.25.0"
|
|
32
32
|
langchain-core = ">=0.2.38,<0.4.0"
|
|
33
|
-
tenacity = ">=8.
|
|
34
|
-
jsonschema-rs = "^0.
|
|
35
|
-
structlog = "^
|
|
33
|
+
tenacity = ">=8.0.0"
|
|
34
|
+
jsonschema-rs = "^0.20.0"
|
|
35
|
+
structlog = "^23.1.0"
|
|
36
36
|
pyjwt = "^2.9.0"
|
|
37
37
|
cryptography = "^43.0.3"
|
|
38
38
|
langgraph-sdk = "^0.1.53"
|
|
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.0.26 → langgraph_api-0.0.27}/langgraph_api/js/src/schema/types.template.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|