langgraph-api 0.0.16__py3-none-any.whl → 0.0.18__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.
Potentially problematic release.
This version of langgraph-api might be problematic. Click here for more details.
- langgraph_api/api/assistants.py +49 -17
- langgraph_api/auth/custom.py +5 -1
- langgraph_api/auth/noop.py +9 -1
- langgraph_api/config.py +59 -14
- langgraph_api/cron_scheduler.py +7 -4
- langgraph_api/js/client.mts +5 -1
- langgraph_api/js/client.new.mts +5 -1
- langgraph_api/js/package.json +1 -1
- langgraph_api/js/tests/api.test.mts +34 -0
- langgraph_api/js/tests/graphs/agent.mts +56 -3
- langgraph_api/js/yarn.lock +9 -9
- langgraph_api/models/run.py +8 -2
- langgraph_api/queue.py +21 -11
- langgraph_api/server.py +5 -0
- langgraph_api/stream.py +1 -1
- langgraph_api/utils.py +3 -1
- {langgraph_api-0.0.16.dist-info → langgraph_api-0.0.18.dist-info}/METADATA +1 -1
- {langgraph_api-0.0.16.dist-info → langgraph_api-0.0.18.dist-info}/RECORD +22 -22
- openapi.json +24 -0
- {langgraph_api-0.0.16.dist-info → langgraph_api-0.0.18.dist-info}/LICENSE +0 -0
- {langgraph_api-0.0.16.dist-info → langgraph_api-0.0.18.dist-info}/WHEEL +0 -0
- {langgraph_api-0.0.16.dist-info → langgraph_api-0.0.18.dist-info}/entry_points.txt +0 -0
langgraph_api/api/assistants.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import Any
|
|
2
2
|
from uuid import uuid4
|
|
3
3
|
|
|
4
|
+
import structlog
|
|
4
5
|
from langchain_core.runnables.utils import create_model
|
|
5
6
|
from langgraph.pregel import Pregel
|
|
6
7
|
from starlette.exceptions import HTTPException
|
|
@@ -23,6 +24,8 @@ from langgraph_storage.database import connect
|
|
|
23
24
|
from langgraph_storage.ops import Assistants
|
|
24
25
|
from langgraph_storage.retry import retry_db
|
|
25
26
|
|
|
27
|
+
logger = structlog.stdlib.get_logger(__name__)
|
|
28
|
+
|
|
26
29
|
|
|
27
30
|
def _state_jsonschema(graph: Pregel) -> dict | None:
|
|
28
31
|
fields: dict = {}
|
|
@@ -39,11 +42,17 @@ def _state_jsonschema(graph: Pregel) -> dict | None:
|
|
|
39
42
|
def _graph_schemas(graph: Pregel) -> dict:
|
|
40
43
|
try:
|
|
41
44
|
input_schema = graph.get_input_jsonschema()
|
|
42
|
-
except Exception:
|
|
45
|
+
except Exception as e:
|
|
46
|
+
logger.warning(
|
|
47
|
+
f"Failed to get input schema for graph {graph.name} with error: `{str(e)}`"
|
|
48
|
+
)
|
|
43
49
|
input_schema = None
|
|
44
50
|
try:
|
|
45
51
|
output_schema = graph.get_output_jsonschema()
|
|
46
|
-
except Exception:
|
|
52
|
+
except Exception as e:
|
|
53
|
+
logger.warning(
|
|
54
|
+
f"Failed to get output schema for graph {graph.name} with error: `{str(e)}`"
|
|
55
|
+
)
|
|
47
56
|
output_schema = None
|
|
48
57
|
state_schema = _state_jsonschema(graph)
|
|
49
58
|
try:
|
|
@@ -52,7 +61,10 @@ def _graph_schemas(graph: Pregel) -> dict:
|
|
|
52
61
|
if "configurable" in graph.config_schema().__fields__
|
|
53
62
|
else {}
|
|
54
63
|
)
|
|
55
|
-
except Exception:
|
|
64
|
+
except Exception as e:
|
|
65
|
+
logger.warning(
|
|
66
|
+
f"Failed to get config schema for graph {graph.name} with error: `{str(e)}`"
|
|
67
|
+
)
|
|
56
68
|
config_schema = None
|
|
57
69
|
return {
|
|
58
70
|
"input_schema": input_schema,
|
|
@@ -141,7 +153,13 @@ async def get_assistant_graph(
|
|
|
141
153
|
if isinstance(graph, BaseRemotePregel):
|
|
142
154
|
drawable_graph = await graph.fetch_graph(xray=xray)
|
|
143
155
|
return ApiResponse(drawable_graph.to_json())
|
|
144
|
-
|
|
156
|
+
|
|
157
|
+
try:
|
|
158
|
+
return ApiResponse(graph.get_graph(xray=xray).to_json())
|
|
159
|
+
except NotImplementedError:
|
|
160
|
+
raise HTTPException(
|
|
161
|
+
422, detail="The graph does not support visualization"
|
|
162
|
+
) from None
|
|
145
163
|
|
|
146
164
|
|
|
147
165
|
@retry_db
|
|
@@ -167,16 +185,21 @@ async def get_assistant_subgraphs(
|
|
|
167
185
|
)
|
|
168
186
|
)
|
|
169
187
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
188
|
+
try:
|
|
189
|
+
return ApiResponse(
|
|
190
|
+
{
|
|
191
|
+
ns: _graph_schemas(subgraph)
|
|
192
|
+
async for ns, subgraph in graph.aget_subgraphs(
|
|
193
|
+
namespace=namespace,
|
|
194
|
+
recurse=request.query_params.get("recurse", "False")
|
|
195
|
+
in ("true", "True"),
|
|
196
|
+
)
|
|
197
|
+
}
|
|
198
|
+
)
|
|
199
|
+
except NotImplementedError:
|
|
200
|
+
raise HTTPException(
|
|
201
|
+
422, detail="The graph does not support visualization"
|
|
202
|
+
) from None
|
|
180
203
|
|
|
181
204
|
|
|
182
205
|
@retry_db
|
|
@@ -205,11 +228,17 @@ async def get_assistant_schemas(
|
|
|
205
228
|
|
|
206
229
|
try:
|
|
207
230
|
input_schema = graph.get_input_schema().schema()
|
|
208
|
-
except Exception:
|
|
231
|
+
except Exception as e:
|
|
232
|
+
logger.warning(
|
|
233
|
+
f"Failed to get input schema for graph {graph.name} with error: `{str(e)}`"
|
|
234
|
+
)
|
|
209
235
|
input_schema = None
|
|
210
236
|
try:
|
|
211
237
|
output_schema = graph.get_output_schema().schema()
|
|
212
|
-
except Exception:
|
|
238
|
+
except Exception as e:
|
|
239
|
+
logger.warning(
|
|
240
|
+
f"Failed to get output schema for graph {graph.name} with error: `{str(e)}`"
|
|
241
|
+
)
|
|
213
242
|
output_schema = None
|
|
214
243
|
|
|
215
244
|
state_schema = _state_jsonschema(graph)
|
|
@@ -219,8 +248,11 @@ async def get_assistant_schemas(
|
|
|
219
248
|
if "configurable" in graph.config_schema().__fields__
|
|
220
249
|
else {}
|
|
221
250
|
)
|
|
222
|
-
except Exception:
|
|
251
|
+
except Exception as e:
|
|
223
252
|
config_schema = None
|
|
253
|
+
logger.warning(
|
|
254
|
+
f"Failed to get config schema for graph {graph.name} with error: `{str(e)}`"
|
|
255
|
+
)
|
|
224
256
|
return ApiResponse(
|
|
225
257
|
{
|
|
226
258
|
"graph_id": assistant["graph_id"],
|
langgraph_api/auth/custom.py
CHANGED
|
@@ -16,7 +16,6 @@ from starlette.authentication import (
|
|
|
16
16
|
AuthenticationBackend,
|
|
17
17
|
AuthenticationError,
|
|
18
18
|
BaseUser,
|
|
19
|
-
SimpleUser,
|
|
20
19
|
)
|
|
21
20
|
from starlette.concurrency import run_in_threadpool
|
|
22
21
|
from starlette.exceptions import HTTPException
|
|
@@ -478,6 +477,11 @@ class ProxyUser(BaseUser):
|
|
|
478
477
|
return getattr(self._user, name)
|
|
479
478
|
|
|
480
479
|
|
|
480
|
+
class SimpleUser(ProxyUser):
|
|
481
|
+
def __init__(self, username: str):
|
|
482
|
+
super().__init__(DotDict({"identity": username}))
|
|
483
|
+
|
|
484
|
+
|
|
481
485
|
def _normalize_auth_response(
|
|
482
486
|
response: Any,
|
|
483
487
|
) -> tuple[AuthCredentials, BaseUser]:
|
langgraph_api/auth/noop.py
CHANGED
|
@@ -2,11 +2,19 @@ from starlette.authentication import (
|
|
|
2
2
|
AuthCredentials,
|
|
3
3
|
AuthenticationBackend,
|
|
4
4
|
BaseUser,
|
|
5
|
-
|
|
5
|
+
)
|
|
6
|
+
from starlette.authentication import (
|
|
7
|
+
UnauthenticatedUser as StarletteUnauthenticatedUser,
|
|
6
8
|
)
|
|
7
9
|
from starlette.requests import HTTPConnection
|
|
8
10
|
|
|
9
11
|
|
|
12
|
+
class UnauthenticatedUser(StarletteUnauthenticatedUser):
|
|
13
|
+
@property
|
|
14
|
+
def identity(self) -> str:
|
|
15
|
+
return ""
|
|
16
|
+
|
|
17
|
+
|
|
10
18
|
class NoopAuthBackend(AuthenticationBackend):
|
|
11
19
|
async def authenticate(
|
|
12
20
|
self, conn: HTTPConnection
|
langgraph_api/config.py
CHANGED
|
@@ -6,6 +6,16 @@ from starlette.datastructures import CommaSeparatedStrings
|
|
|
6
6
|
|
|
7
7
|
env = Config()
|
|
8
8
|
|
|
9
|
+
|
|
10
|
+
def _parse_json(json: str | None) -> dict | None:
|
|
11
|
+
if not json:
|
|
12
|
+
return None
|
|
13
|
+
parsed = orjson.loads(json)
|
|
14
|
+
if not parsed:
|
|
15
|
+
return None
|
|
16
|
+
return parsed
|
|
17
|
+
|
|
18
|
+
|
|
9
19
|
STATS_INTERVAL_SECS = env("STATS_INTERVAL_SECS", cast=int, default=60)
|
|
10
20
|
HTTP_CONCURRENCY = env("HTTP_CONCURRENCY", cast=int, default=10)
|
|
11
21
|
|
|
@@ -21,10 +31,57 @@ REDIS_MAX_CONNECTIONS = env("REDIS_MAX_CONNECTIONS", cast=int, default=500)
|
|
|
21
31
|
# server
|
|
22
32
|
|
|
23
33
|
CORS_ALLOW_ORIGINS = env("CORS_ALLOW_ORIGINS", cast=CommaSeparatedStrings, default="*")
|
|
34
|
+
CORS_CONFIG = env("CORS_CONFIG", cast=_parse_json, default=None)
|
|
35
|
+
"""
|
|
36
|
+
{
|
|
37
|
+
"type": "object",
|
|
38
|
+
"properties": {
|
|
39
|
+
"allow_origins": {
|
|
40
|
+
"type": "array",
|
|
41
|
+
"items": {"type": "string"},
|
|
42
|
+
"default": []
|
|
43
|
+
},
|
|
44
|
+
"allow_methods": {
|
|
45
|
+
"type": "array",
|
|
46
|
+
"items": {"type": "string"},
|
|
47
|
+
"default": ["GET"]
|
|
48
|
+
},
|
|
49
|
+
"allow_headers": {
|
|
50
|
+
"type": "array",
|
|
51
|
+
"items": {"type": "string"},
|
|
52
|
+
"default": []
|
|
53
|
+
},
|
|
54
|
+
"allow_credentials": {
|
|
55
|
+
"type": "boolean",
|
|
56
|
+
"default": false
|
|
57
|
+
},
|
|
58
|
+
"allow_origin_regex": {
|
|
59
|
+
"type": ["string", "null"],
|
|
60
|
+
"default": null
|
|
61
|
+
},
|
|
62
|
+
"expose_headers": {
|
|
63
|
+
"type": "array",
|
|
64
|
+
"items": {"type": "string"},
|
|
65
|
+
"default": []
|
|
66
|
+
},
|
|
67
|
+
"max_age": {
|
|
68
|
+
"type": "integer",
|
|
69
|
+
"default": 600
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
"""
|
|
74
|
+
if CORS_CONFIG is not None and CORS_ALLOW_ORIGINS != "*":
|
|
75
|
+
raise ValueError("CORS_CONFIG and CORS_ALLOW_ORIGINS cannot be set together")
|
|
24
76
|
|
|
25
77
|
# queue
|
|
26
78
|
|
|
27
|
-
BG_JOB_NO_DELAY = env("BG_JOB_NO_DELAY", cast=bool, default=
|
|
79
|
+
BG_JOB_NO_DELAY = env("BG_JOB_NO_DELAY", cast=bool, default=None)
|
|
80
|
+
BG_JOB_DELAY = env("BG_JOB_DELAY", cast=float, default=0.5)
|
|
81
|
+
if BG_JOB_NO_DELAY is True:
|
|
82
|
+
BG_JOB_DELAY = 0
|
|
83
|
+
|
|
84
|
+
|
|
28
85
|
N_JOBS_PER_WORKER = env("N_JOBS_PER_WORKER", cast=int, default=10)
|
|
29
86
|
BG_JOB_TIMEOUT_SECS = env("BG_JOB_TIMEOUT_SECS", cast=float, default=3600)
|
|
30
87
|
FF_CRONS_ENABLED = env("FF_CRONS_ENABLED", cast=bool, default=True)
|
|
@@ -33,18 +90,7 @@ FF_JS_ZEROMQ_ENABLED = env("FF_JS_ZEROMQ_ENABLED", cast=bool, default=False)
|
|
|
33
90
|
# auth
|
|
34
91
|
|
|
35
92
|
LANGGRAPH_AUTH_TYPE = env("LANGGRAPH_AUTH_TYPE", cast=str, default="noop")
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def _parse_auth(auth: str | None) -> dict | None:
|
|
39
|
-
if not auth:
|
|
40
|
-
return None
|
|
41
|
-
parsed = orjson.loads(auth)
|
|
42
|
-
if not parsed:
|
|
43
|
-
return None
|
|
44
|
-
return parsed
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
LANGGRAPH_AUTH = env("LANGGRAPH_AUTH", cast=_parse_auth, default=None)
|
|
93
|
+
LANGGRAPH_AUTH = env("LANGGRAPH_AUTH", cast=_parse_json, default=None)
|
|
48
94
|
LANGSMITH_TENANT_ID = env("LANGSMITH_TENANT_ID", cast=str, default=None)
|
|
49
95
|
LANGSMITH_AUTH_VERIFY_TENANT_ID = env(
|
|
50
96
|
"LANGSMITH_AUTH_VERIFY_TENANT_ID",
|
|
@@ -52,7 +98,6 @@ LANGSMITH_AUTH_VERIFY_TENANT_ID = env(
|
|
|
52
98
|
default=LANGSMITH_TENANT_ID is not None,
|
|
53
99
|
)
|
|
54
100
|
|
|
55
|
-
|
|
56
101
|
if LANGGRAPH_AUTH_TYPE == "langsmith":
|
|
57
102
|
LANGSMITH_AUTH_ENDPOINT = env("LANGSMITH_AUTH_ENDPOINT", cast=str)
|
|
58
103
|
LANGSMITH_TENANT_ID = env("LANGSMITH_TENANT_ID", cast=str)
|
langgraph_api/cron_scheduler.py
CHANGED
|
@@ -3,10 +3,10 @@ from random import random
|
|
|
3
3
|
|
|
4
4
|
import structlog
|
|
5
5
|
from langchain_core.runnables.config import run_in_executor
|
|
6
|
-
from starlette.authentication import SimpleUser
|
|
7
6
|
|
|
8
7
|
from langgraph_api.models.run import create_valid_run
|
|
9
|
-
from langgraph_api.
|
|
8
|
+
from langgraph_api.queue import set_auth_ctx_for_run
|
|
9
|
+
from langgraph_api.utils import next_cron_date
|
|
10
10
|
from langgraph_storage.database import connect
|
|
11
11
|
from langgraph_storage.ops import Crons
|
|
12
12
|
from langgraph_storage.retry import retry_db
|
|
@@ -23,10 +23,13 @@ async def cron_scheduler():
|
|
|
23
23
|
try:
|
|
24
24
|
async with connect() as conn:
|
|
25
25
|
async for cron in Crons.next(conn):
|
|
26
|
-
|
|
26
|
+
run_payload = cron["payload"]
|
|
27
|
+
|
|
28
|
+
async with set_auth_ctx_for_run(
|
|
29
|
+
run_payload, user_id=cron["user_id"]
|
|
30
|
+
):
|
|
27
31
|
logger.debug(f"Scheduling cron run {cron}")
|
|
28
32
|
try:
|
|
29
|
-
run_payload = cron["payload"]
|
|
30
33
|
run = await create_valid_run(
|
|
31
34
|
conn,
|
|
32
35
|
thread_id=(
|
langgraph_api/js/client.mts
CHANGED
|
@@ -446,6 +446,7 @@ const StreamModeSchema = z.union([
|
|
|
446
446
|
const ExtraStreamModeSchema = z.union([
|
|
447
447
|
StreamModeSchema,
|
|
448
448
|
z.literal("messages"),
|
|
449
|
+
z.literal("messages-tuple"),
|
|
449
450
|
]);
|
|
450
451
|
|
|
451
452
|
const StreamEventsPayload = z.object({
|
|
@@ -476,11 +477,14 @@ async function* streamEventsRequest(
|
|
|
476
477
|
? payload.stream_mode
|
|
477
478
|
: [payload.stream_mode];
|
|
478
479
|
|
|
479
|
-
const graphStreamMode: Set<"updates" | "debug" | "values"> =
|
|
480
|
+
const graphStreamMode: Set<"updates" | "debug" | "values" | "messages"> =
|
|
481
|
+
new Set();
|
|
480
482
|
if (payload.stream_mode) {
|
|
481
483
|
for (const mode of userStreamMode) {
|
|
482
484
|
if (mode === "messages") {
|
|
483
485
|
graphStreamMode.add("values");
|
|
486
|
+
} else if (mode === "messages-tuple") {
|
|
487
|
+
graphStreamMode.add("messages");
|
|
484
488
|
} else {
|
|
485
489
|
graphStreamMode.add(mode);
|
|
486
490
|
}
|
langgraph_api/js/client.new.mts
CHANGED
|
@@ -504,6 +504,7 @@ const StreamModeSchema = z.union([
|
|
|
504
504
|
const ExtraStreamModeSchema = z.union([
|
|
505
505
|
StreamModeSchema,
|
|
506
506
|
z.literal("messages"),
|
|
507
|
+
z.literal("messages-tuple"),
|
|
507
508
|
]);
|
|
508
509
|
|
|
509
510
|
const StreamEventsPayload = z.object({
|
|
@@ -534,11 +535,14 @@ async function* streamEventsRequest(
|
|
|
534
535
|
? payload.stream_mode
|
|
535
536
|
: [payload.stream_mode];
|
|
536
537
|
|
|
537
|
-
const graphStreamMode: Set<"updates" | "debug" | "values"> =
|
|
538
|
+
const graphStreamMode: Set<"updates" | "debug" | "values" | "messages"> =
|
|
539
|
+
new Set();
|
|
538
540
|
if (payload.stream_mode) {
|
|
539
541
|
for (const mode of userStreamMode) {
|
|
540
542
|
if (mode === "messages") {
|
|
541
543
|
graphStreamMode.add("values");
|
|
544
|
+
} else if (mode === "messages-tuple") {
|
|
545
|
+
graphStreamMode.add("messages");
|
|
542
546
|
} else {
|
|
543
547
|
graphStreamMode.add(mode);
|
|
544
548
|
}
|
langgraph_api/js/package.json
CHANGED
|
@@ -686,6 +686,40 @@ describe("runs", () => {
|
|
|
686
686
|
expect(run.status).toBe("success");
|
|
687
687
|
});
|
|
688
688
|
|
|
689
|
+
it.concurrent("stream messages tuple", async () => {
|
|
690
|
+
const assistant = await client.assistants.create({ graphId: "agent" });
|
|
691
|
+
const thread = await client.threads.create();
|
|
692
|
+
const input = {
|
|
693
|
+
messages: [{ type: "human", content: "foo", id: "initial-message" }],
|
|
694
|
+
};
|
|
695
|
+
const stream = await client.runs.stream(
|
|
696
|
+
thread.thread_id,
|
|
697
|
+
assistant.assistant_id,
|
|
698
|
+
{ input, streamMode: "messages-tuple", config: globalConfig }
|
|
699
|
+
);
|
|
700
|
+
|
|
701
|
+
const chunks = await gatherIterator(stream);
|
|
702
|
+
const runId = findLast(chunks, (i) => i.event === "metadata")?.data.run_id;
|
|
703
|
+
expect(runId).not.toBeNull();
|
|
704
|
+
|
|
705
|
+
const messages = chunks
|
|
706
|
+
.filter((i) => i.event === "messages")
|
|
707
|
+
.map((i) => i.data[0]);
|
|
708
|
+
|
|
709
|
+
expect(messages).toHaveLength("begin".length + "end".length + 1);
|
|
710
|
+
expect(messages).toMatchObject([
|
|
711
|
+
..."begin".split("").map((c) => ({ content: c })),
|
|
712
|
+
{ content: "tool_call__begin" },
|
|
713
|
+
..."end".split("").map((c) => ({ content: c })),
|
|
714
|
+
]);
|
|
715
|
+
|
|
716
|
+
const seenEventTypes = new Set(chunks.map((i) => i.event));
|
|
717
|
+
expect(seenEventTypes).toEqual(new Set(["metadata", "messages"]));
|
|
718
|
+
|
|
719
|
+
const run = await client.runs.get(thread.thread_id, runId as string);
|
|
720
|
+
expect(run.status).toBe("success");
|
|
721
|
+
});
|
|
722
|
+
|
|
689
723
|
it.concurrent("stream mixed modes", async () => {
|
|
690
724
|
const assistant = await client.assistants.create({ graphId: "agent" });
|
|
691
725
|
const thread = await client.threads.create();
|
|
@@ -6,11 +6,13 @@ import {
|
|
|
6
6
|
END,
|
|
7
7
|
messagesStateReducer,
|
|
8
8
|
SharedValue,
|
|
9
|
-
LangGraphRunnableConfig,
|
|
10
9
|
interrupt,
|
|
10
|
+
type LangGraphRunnableConfig,
|
|
11
11
|
} from "@langchain/langgraph";
|
|
12
12
|
import { FakeListChatModel } from "@langchain/core/utils/testing";
|
|
13
|
-
|
|
13
|
+
import { ChatGenerationChunk } from "@langchain/core/outputs";
|
|
14
|
+
import { v4 as uuidv4 } from "uuid";
|
|
15
|
+
import { CallbackManagerForLLMRun } from "@langchain/core/callbacks/manager";
|
|
14
16
|
const GraphAnnotationOutput = Annotation.Root({
|
|
15
17
|
messages: Annotation<BaseMessage[]>({
|
|
16
18
|
reducer: messagesStateReducer,
|
|
@@ -20,6 +22,7 @@ const GraphAnnotationOutput = Annotation.Root({
|
|
|
20
22
|
interrupt: Annotation<boolean>(),
|
|
21
23
|
keyOne: Annotation<string | null>(),
|
|
22
24
|
keyTwo: Annotation<string | null>(),
|
|
25
|
+
sleep: Annotation<number | null>(),
|
|
23
26
|
});
|
|
24
27
|
|
|
25
28
|
const GraphAnnotationInput = Annotation.Root({
|
|
@@ -28,13 +31,58 @@ const GraphAnnotationInput = Annotation.Root({
|
|
|
28
31
|
sharedStateFromStoreConfig: Annotation<Record<string, any> | null>,
|
|
29
32
|
});
|
|
30
33
|
|
|
34
|
+
class StableFakeListChatModel extends FakeListChatModel {
|
|
35
|
+
streamMessageId: string = uuidv4();
|
|
36
|
+
|
|
37
|
+
async *_streamResponseChunks(
|
|
38
|
+
_messages: BaseMessage[],
|
|
39
|
+
options: this["ParsedCallOptions"],
|
|
40
|
+
runManager?: CallbackManagerForLLMRun
|
|
41
|
+
): AsyncGenerator<ChatGenerationChunk> {
|
|
42
|
+
const response = this._currentResponse();
|
|
43
|
+
this._incrementResponse();
|
|
44
|
+
this.streamMessageId = uuidv4();
|
|
45
|
+
|
|
46
|
+
if (this.emitCustomEvent) {
|
|
47
|
+
await runManager?.handleCustomEvent("some_test_event", {
|
|
48
|
+
someval: true,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
for await (const text of response) {
|
|
53
|
+
await this._sleepIfRequested();
|
|
54
|
+
if (options?.thrownErrorString) {
|
|
55
|
+
throw new Error(options.thrownErrorString);
|
|
56
|
+
}
|
|
57
|
+
const chunk = this._createResponseChunk(text);
|
|
58
|
+
|
|
59
|
+
// ensure stable ID
|
|
60
|
+
chunk.message.id = this.streamMessageId;
|
|
61
|
+
chunk.message.lc_kwargs.id = this.streamMessageId;
|
|
62
|
+
|
|
63
|
+
yield chunk;
|
|
64
|
+
|
|
65
|
+
void runManager?.handleLLMNewToken(
|
|
66
|
+
text,
|
|
67
|
+
undefined,
|
|
68
|
+
undefined,
|
|
69
|
+
undefined,
|
|
70
|
+
undefined,
|
|
71
|
+
{ chunk }
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
31
77
|
// For shared state
|
|
32
78
|
const namespace = ["sharedState", "data"];
|
|
33
79
|
const key = "user_id";
|
|
34
80
|
|
|
35
81
|
const modelMap: Record<string, FakeListChatModel> = {};
|
|
36
82
|
const getModel = (threadId: string) => {
|
|
37
|
-
modelMap[threadId] ??= new
|
|
83
|
+
modelMap[threadId] ??= new StableFakeListChatModel({
|
|
84
|
+
responses: ["begin", "end"],
|
|
85
|
+
});
|
|
38
86
|
return modelMap[threadId];
|
|
39
87
|
};
|
|
40
88
|
|
|
@@ -44,6 +92,11 @@ const agentNode = async (
|
|
|
44
92
|
) => {
|
|
45
93
|
if (state.interrupt) interrupt("i want to interrupt");
|
|
46
94
|
|
|
95
|
+
if (state.sleep != null && state.messages.at(-1)?.getType() === "human") {
|
|
96
|
+
const sleep = state.sleep;
|
|
97
|
+
await new Promise((resolve) => setTimeout(resolve, sleep * 1000));
|
|
98
|
+
}
|
|
99
|
+
|
|
47
100
|
const model = getModel(config.configurable?.thread_id ?? "$");
|
|
48
101
|
const response = await model.invoke(state.messages);
|
|
49
102
|
const sharedStateValue = state.sharedState?.data?.user_id ?? null;
|
langgraph_api/js/yarn.lock
CHANGED
|
@@ -1486,10 +1486,10 @@ nanoid@^3.3.7:
|
|
|
1486
1486
|
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
|
|
1487
1487
|
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
|
|
1488
1488
|
|
|
1489
|
-
node-addon-api@^8.
|
|
1490
|
-
version "8.
|
|
1491
|
-
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-8.
|
|
1492
|
-
integrity sha512-
|
|
1489
|
+
node-addon-api@^8.3.0:
|
|
1490
|
+
version "8.3.0"
|
|
1491
|
+
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-8.3.0.tgz#ec3763f18befc1cdf66d11e157ce44d5eddc0603"
|
|
1492
|
+
integrity sha512-8VOpLHFrOQlAH+qA0ZzuGRlALRA6/LVh8QJldbrC4DY0hXoMP0l4Acq8TzFC018HztWiRqyCEj2aTWY2UvnJUg==
|
|
1493
1493
|
|
|
1494
1494
|
node-int64@^0.4.0:
|
|
1495
1495
|
version "0.4.0"
|
|
@@ -2173,13 +2173,13 @@ yallist@^4.0.0:
|
|
|
2173
2173
|
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
|
|
2174
2174
|
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
|
2175
2175
|
|
|
2176
|
-
zeromq@^6.
|
|
2177
|
-
version "6.
|
|
2178
|
-
resolved "https://registry.yarnpkg.com/zeromq/-/zeromq-6.
|
|
2179
|
-
integrity sha512-
|
|
2176
|
+
zeromq@^6.3.0:
|
|
2177
|
+
version "6.3.0"
|
|
2178
|
+
resolved "https://registry.yarnpkg.com/zeromq/-/zeromq-6.3.0.tgz#19ffa286d128cc317847b5d615c079a67e3bae48"
|
|
2179
|
+
integrity sha512-PG61AT4Y37NGJHSrp5SG2m4cKtRirso/5mm4Yf7l+upgNZZAugrGdhENsM5IcLS+WVVzbWVjEsLKpgLj/31SWQ==
|
|
2180
2180
|
dependencies:
|
|
2181
2181
|
"@aminya/cmake-ts" "^0.3.0-aminya.7"
|
|
2182
|
-
node-addon-api "^8.
|
|
2182
|
+
node-addon-api "^8.3.0"
|
|
2183
2183
|
|
|
2184
2184
|
zod-to-json-schema@^3.22.3:
|
|
2185
2185
|
version "3.23.5"
|
langgraph_api/models/run.py
CHANGED
|
@@ -8,7 +8,7 @@ from langgraph.checkpoint.base.id import uuid6
|
|
|
8
8
|
from starlette.authentication import BaseUser
|
|
9
9
|
from starlette.exceptions import HTTPException
|
|
10
10
|
|
|
11
|
-
from langgraph_api.graph import get_assistant_id
|
|
11
|
+
from langgraph_api.graph import GRAPHS, get_assistant_id
|
|
12
12
|
from langgraph_api.schema import (
|
|
13
13
|
All,
|
|
14
14
|
Config,
|
|
@@ -92,7 +92,13 @@ def ensure_ids(
|
|
|
92
92
|
assistant_id if isinstance(assistant_id, UUID) else UUID(assistant_id)
|
|
93
93
|
]
|
|
94
94
|
except ValueError:
|
|
95
|
-
|
|
95
|
+
keys = ", ".join(GRAPHS.keys())
|
|
96
|
+
raise HTTPException(
|
|
97
|
+
status_code=422,
|
|
98
|
+
detail=f"Invalid assistant: '{assistant_id}'. Must be either:\n"
|
|
99
|
+
f"- A valid assistant UUID, or\n"
|
|
100
|
+
f"- One of the registered graphs: {keys}",
|
|
101
|
+
) from None
|
|
96
102
|
if thread_id:
|
|
97
103
|
try:
|
|
98
104
|
results.append(
|
langgraph_api/queue.py
CHANGED
|
@@ -2,14 +2,13 @@ import asyncio
|
|
|
2
2
|
from collections.abc import AsyncGenerator
|
|
3
3
|
from contextlib import AsyncExitStack, asynccontextmanager
|
|
4
4
|
from datetime import UTC, datetime
|
|
5
|
-
from random import random
|
|
6
5
|
from typing import TypedDict, cast
|
|
7
6
|
|
|
8
7
|
import structlog
|
|
9
8
|
from langgraph.pregel.debug import CheckpointPayload, TaskResultPayload
|
|
10
9
|
|
|
11
|
-
from langgraph_api.auth.custom import normalize_user
|
|
12
|
-
from langgraph_api.config import
|
|
10
|
+
from langgraph_api.auth.custom import SimpleUser, normalize_user
|
|
11
|
+
from langgraph_api.config import BG_JOB_DELAY, STATS_INTERVAL_SECS
|
|
13
12
|
from langgraph_api.errors import (
|
|
14
13
|
UserInterrupt,
|
|
15
14
|
UserRollback,
|
|
@@ -127,13 +126,13 @@ async def queue(concurrency: int, timeout: float):
|
|
|
127
126
|
else:
|
|
128
127
|
semaphore.release()
|
|
129
128
|
await exit.aclose()
|
|
130
|
-
await asyncio.sleep(
|
|
129
|
+
await asyncio.sleep(BG_JOB_DELAY)
|
|
131
130
|
except Exception as exc:
|
|
132
131
|
# keep trying to run the scheduler indefinitely
|
|
133
132
|
logger.exception("Background worker scheduler failed", exc_info=exc)
|
|
134
133
|
semaphore.release()
|
|
135
134
|
await exit.aclose()
|
|
136
|
-
await asyncio.sleep(
|
|
135
|
+
await asyncio.sleep(BG_JOB_DELAY)
|
|
137
136
|
finally:
|
|
138
137
|
logger.info("Shutting down background workers")
|
|
139
138
|
for task in WORKERS:
|
|
@@ -157,12 +156,13 @@ class WorkerResult(TypedDict):
|
|
|
157
156
|
|
|
158
157
|
|
|
159
158
|
@asynccontextmanager
|
|
160
|
-
async def set_auth_ctx_for_run(
|
|
159
|
+
async def set_auth_ctx_for_run(
|
|
160
|
+
run_kwargs: dict, user_id: str | None = None
|
|
161
|
+
) -> AsyncGenerator[None, None]:
|
|
162
|
+
# user_id is a fallback.
|
|
161
163
|
try:
|
|
162
|
-
user =
|
|
163
|
-
permissions =
|
|
164
|
-
"langgraph_auth_permissions"
|
|
165
|
-
]
|
|
164
|
+
user = run_kwargs["config"]["configurable"]["langgraph_auth_user"]
|
|
165
|
+
permissions = run_kwargs["config"]["configurable"]["langgraph_auth_permissions"]
|
|
166
166
|
if user is not None:
|
|
167
167
|
user = normalize_user(user)
|
|
168
168
|
async with with_user(user, permissions):
|
|
@@ -171,6 +171,16 @@ async def set_auth_ctx_for_run(run: Run) -> AsyncGenerator[None, None]:
|
|
|
171
171
|
yield None
|
|
172
172
|
|
|
173
173
|
except KeyError:
|
|
174
|
+
if user_id is not None:
|
|
175
|
+
await logger.ainfo(
|
|
176
|
+
"Setting auth to backup user_id",
|
|
177
|
+
user_id=user_id,
|
|
178
|
+
)
|
|
179
|
+
async with with_user(SimpleUser(user_id)):
|
|
180
|
+
yield None
|
|
181
|
+
else:
|
|
182
|
+
yield None
|
|
183
|
+
except Exception:
|
|
174
184
|
pass
|
|
175
185
|
|
|
176
186
|
|
|
@@ -191,7 +201,7 @@ async def worker(
|
|
|
191
201
|
run_started_at = datetime.now(UTC)
|
|
192
202
|
run_ended_at: str | None = None
|
|
193
203
|
|
|
194
|
-
async with set_auth_ctx_for_run(run), Runs.enter(run_id) as done, exit:
|
|
204
|
+
async with set_auth_ctx_for_run(run["kwargs"]), Runs.enter(run_id) as done, exit:
|
|
195
205
|
temporary = run["kwargs"].get("temporary", False)
|
|
196
206
|
run_created_at = run["created_at"].isoformat()
|
|
197
207
|
await logger.ainfo(
|
langgraph_api/server.py
CHANGED
|
@@ -33,6 +33,11 @@ app = Starlette(
|
|
|
33
33
|
allow_credentials=True,
|
|
34
34
|
allow_methods=["*"],
|
|
35
35
|
allow_headers=["*"],
|
|
36
|
+
)
|
|
37
|
+
if config.CORS_CONFIG is None
|
|
38
|
+
else Middleware(
|
|
39
|
+
CORSMiddleware,
|
|
40
|
+
**config.CORS_CONFIG,
|
|
36
41
|
),
|
|
37
42
|
Middleware(LicenseValidationMiddleware),
|
|
38
43
|
Middleware(AccessLoggerMiddleware, logger=logger),
|
langgraph_api/stream.py
CHANGED
|
@@ -130,7 +130,7 @@ async def astream_state(
|
|
|
130
130
|
stream_modes_set: set[StreamMode] = set(stream_mode) - {"events"}
|
|
131
131
|
if "debug" not in stream_modes_set:
|
|
132
132
|
stream_modes_set.add("debug")
|
|
133
|
-
if "messages-tuple" in stream_modes_set:
|
|
133
|
+
if "messages-tuple" in stream_modes_set and not isinstance(graph, BaseRemotePregel):
|
|
134
134
|
stream_modes_set.remove("messages-tuple")
|
|
135
135
|
stream_modes_set.add("messages")
|
|
136
136
|
# attach attempt metadata
|
langgraph_api/utils.py
CHANGED
|
@@ -6,9 +6,11 @@ from datetime import datetime
|
|
|
6
6
|
from typing import Any, Protocol, TypeAlias, TypeVar
|
|
7
7
|
|
|
8
8
|
from langgraph_sdk import Auth
|
|
9
|
-
from starlette.authentication import AuthCredentials, BaseUser
|
|
9
|
+
from starlette.authentication import AuthCredentials, BaseUser
|
|
10
10
|
from starlette.exceptions import HTTPException
|
|
11
11
|
|
|
12
|
+
from langgraph_api.auth.custom import SimpleUser
|
|
13
|
+
|
|
12
14
|
T = TypeVar("T")
|
|
13
15
|
Row: TypeAlias = dict[str, Any]
|
|
14
16
|
AuthContext = contextvars.ContextVar[Auth.types.BaseAuthContext | None](
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
|
|
2
2
|
langgraph_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
langgraph_api/api/__init__.py,sha256=zAdS_0jgjmCJK6E0VwEuNcNRkaknMXfQ2C_OES5tEI4,2066
|
|
4
|
-
langgraph_api/api/assistants.py,sha256=
|
|
4
|
+
langgraph_api/api/assistants.py,sha256=9wngelDC9vnSs2vYGTHDSCLf5KNds-6mgP1BWnfoY2M,12865
|
|
5
5
|
langgraph_api/api/meta.py,sha256=hueasWpTDQ6xYLo9Bzt2jhNH8XQRzreH8FTeFfnRoxQ,2700
|
|
6
6
|
langgraph_api/api/openapi.py,sha256=AUxfnD5hlRp7s-0g2hBC5dNSNk3HTwOLeJiF489DT44,2762
|
|
7
7
|
langgraph_api/api/runs.py,sha256=wAzPXi_kcYB9BcLBL4FXgkBohWwCPIpe4XERnsnWnsA,16042
|
|
@@ -9,16 +9,16 @@ langgraph_api/api/store.py,sha256=VzAJVOwO0IxosBB7km5TTf2rhlWGyPkVz_LpvbxetVY,54
|
|
|
9
9
|
langgraph_api/api/threads.py,sha256=taU61XPcCEhBPCYPZcMDsgVDwwWUWJs8p-PrXFXWY48,8661
|
|
10
10
|
langgraph_api/asyncio.py,sha256=2fOlx-cZvuj1gQ867Kw1R_wsBsl9jdHYHcUtK2a-x-U,6264
|
|
11
11
|
langgraph_api/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
-
langgraph_api/auth/custom.py,sha256=
|
|
12
|
+
langgraph_api/auth/custom.py,sha256=juCwlVxjWnCzcWI6Amae_4NfIOFtY39kaJ_zPF5AJaw,21025
|
|
13
13
|
langgraph_api/auth/langsmith/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
14
|
langgraph_api/auth/langsmith/backend.py,sha256=InScaL-HYCnxYEauhxU198gRZV9pJn9SzzBoR9Edn7g,2654
|
|
15
15
|
langgraph_api/auth/langsmith/client.py,sha256=eKchvAom7hdkUXauD8vHNceBDDUijrFgdTV8bKd7x4Q,3998
|
|
16
16
|
langgraph_api/auth/middleware.py,sha256=qc7SbaFoeWaqxS1wbjZ2PPQ4iI2p9T0shWL7c6g0ed4,1636
|
|
17
|
-
langgraph_api/auth/noop.py,sha256=
|
|
17
|
+
langgraph_api/auth/noop.py,sha256=Bk6Nf3p8D_iMVy_OyfPlyiJp_aEwzL-sHrbxoXpCbac,586
|
|
18
18
|
langgraph_api/auth/studio_user.py,sha256=FzFQRROKDlA9JjtBuwyZvk6Mbwno5M9RVYjDO6FU3F8,186
|
|
19
19
|
langgraph_api/cli.py,sha256=7vQQiD3F50r-8KkbuFjwIz8LLbdKUTd4xZGUJPiO3yQ,11688
|
|
20
|
-
langgraph_api/config.py,sha256=
|
|
21
|
-
langgraph_api/cron_scheduler.py,sha256=
|
|
20
|
+
langgraph_api/config.py,sha256=YDGkyZQRdG2QRYwSwPKC9J3UOhq7Diy_ZdypAL-vbrw,4034
|
|
21
|
+
langgraph_api/cron_scheduler.py,sha256=MW41-TSGUe5OuXycFTy7Ax7ypxHVAv-0ImLonRT8h8o,2629
|
|
22
22
|
langgraph_api/errors.py,sha256=Bu_i5drgNTyJcLiyrwVE_6-XrSU50BHf9TDpttki9wQ,1690
|
|
23
23
|
langgraph_api/graph.py,sha256=FombjYQkqj8jrXJFEVkl3m2UyFcq5nSVNswR2HoRsQY,16385
|
|
24
24
|
langgraph_api/http.py,sha256=XrbyxpjtfSvnaWWh5ZLGpgZmY83WoDCrP_1GPguNiXI,4712
|
|
@@ -26,11 +26,11 @@ langgraph_api/http_logger.py,sha256=Sxo_q-65tElauRvkzVLt9lJojgNdgtcHGBYD0IRyX7M,
|
|
|
26
26
|
langgraph_api/js/.gitignore,sha256=qAah3Fq0HWAlfRj5ktZyC6QRQIsAolGLRGcRukA1XJI,33
|
|
27
27
|
langgraph_api/js/base.py,sha256=BpE8-xkUp8HFPRjSKx1tfUQubvoV4jYl6OwZdre3veI,209
|
|
28
28
|
langgraph_api/js/build.mts,sha256=sAZXB3xVSoG8exJ1ZEytFyikRmEsXJ_0OlLjDDgD79o,1342
|
|
29
|
-
langgraph_api/js/client.mts,sha256=
|
|
30
|
-
langgraph_api/js/client.new.mts,sha256=
|
|
29
|
+
langgraph_api/js/client.mts,sha256=yFc4aeV5wm7N_z_K8gIukVXo6pHUBnp2Mlryl9B-yrA,22654
|
|
30
|
+
langgraph_api/js/client.new.mts,sha256=54n0xc9SSDnrJDPsN_JcUKcRJJyQVIYuUrkKw3XDcio,23628
|
|
31
31
|
langgraph_api/js/errors.py,sha256=Cm1TKWlUCwZReDC5AQ6SgNIVGD27Qov2xcgHyf8-GXo,361
|
|
32
32
|
langgraph_api/js/global.d.ts,sha256=zR_zLYfpzyPfxpEFth5RgZoyfGulIXyZYPRf7cU0K0Y,106
|
|
33
|
-
langgraph_api/js/package.json,sha256=
|
|
33
|
+
langgraph_api/js/package.json,sha256=i2wjOE0_u1DdUvlc7Ulgj-tg06kjKCsFL99nQKF7vQk,840
|
|
34
34
|
langgraph_api/js/remote.py,sha256=D9cqcEgXau-fm_trpNwCHMra5BXntgUa469lgs_a9JQ,622
|
|
35
35
|
langgraph_api/js/remote_new.py,sha256=T_Vr8459bax1C9xxqz_ZYmGivq5Vhspg2Iu9TL0Qc-Q,22707
|
|
36
36
|
langgraph_api/js/remote_old.py,sha256=2a-3ooAYUZs8aPsfnXafbBd4pP7lRmokoU7TiO7P9Js,22546
|
|
@@ -45,10 +45,10 @@ langgraph_api/js/src/schema/types.template.mts,sha256=c-FA0Ykzp4KvPyYA6a-hDf60Kd
|
|
|
45
45
|
langgraph_api/js/src/utils/importMap.mts,sha256=pX4TGOyUpuuWF82kXcxcv3-8mgusRezOGe6Uklm2O5A,1644
|
|
46
46
|
langgraph_api/js/src/utils/pythonSchemas.mts,sha256=98IW7Z_VP7L_CHNRMb3_MsiV3BgLE2JsWQY_PQcRR3o,685
|
|
47
47
|
langgraph_api/js/src/utils/serde.mts,sha256=OuyyO9btvwWd55rU_H4x91dFEJiaPxL-lL9O6Zgo908,742
|
|
48
|
-
langgraph_api/js/tests/api.test.mts,sha256=
|
|
48
|
+
langgraph_api/js/tests/api.test.mts,sha256=qJdISmuKo7AWZmR4thY9eq8h4EL5bWKlhI5x7LCJ8dQ,56919
|
|
49
49
|
langgraph_api/js/tests/compose-postgres.yml,sha256=pbNfeqVUqhWILBuUdwAgQOYsVU_fgkCVm0YlTgU8og8,1721
|
|
50
50
|
langgraph_api/js/tests/graphs/.gitignore,sha256=26J8MarZNXh7snXD5eTpV3CPFTht5Znv8dtHYCLNfkw,12
|
|
51
|
-
langgraph_api/js/tests/graphs/agent.mts,sha256=
|
|
51
|
+
langgraph_api/js/tests/graphs/agent.mts,sha256=E9WMv0alMv0njUEECqEsqoRk9NXJUgXW7SyQJ3GOZ8k,5396
|
|
52
52
|
langgraph_api/js/tests/graphs/delay.mts,sha256=CFneKxqI4bGGK0lYjSbe80QirowPQlsRSuhDUKfydhk,703
|
|
53
53
|
langgraph_api/js/tests/graphs/error.mts,sha256=l4tk89449dj1BnEF_0ZcfPt0Ikk1gl8L1RaSnRfr3xo,487
|
|
54
54
|
langgraph_api/js/tests/graphs/langgraph.json,sha256=frxd7ZWILdeMYSZgUBH6UO-IR7I2YJSOfOlx2mnO1sI,189
|
|
@@ -58,22 +58,22 @@ langgraph_api/js/tests/graphs/weather.mts,sha256=A7mLK3xW8h5B-ZyJNAyX2M2fJJwzPJz
|
|
|
58
58
|
langgraph_api/js/tests/graphs/yarn.lock,sha256=q-1S--E5VWLYtkSv03shqtNzeDDv-N_J-N26FszLsjs,7903
|
|
59
59
|
langgraph_api/js/tests/parser.test.mts,sha256=3zAbboUNhI-cY3hj4Ssr7J-sQXCBTeeI1ItrkG0Ftuk,26257
|
|
60
60
|
langgraph_api/js/tests/utils.mts,sha256=2kTybJ3O7Yfe1q3ehDouqV54ibXkNzsPZ_wBZLJvY-4,421
|
|
61
|
-
langgraph_api/js/yarn.lock,sha256=
|
|
61
|
+
langgraph_api/js/yarn.lock,sha256=4cFZXkAYtsdCO7nPBDNHehQ1kv3hYMRXwwXutupMHs8,103690
|
|
62
62
|
langgraph_api/lifespan.py,sha256=Uj7NV-NqxxD1fgx_umM9pVqclcy-VlqrIxDljyj2he0,1820
|
|
63
63
|
langgraph_api/logging.py,sha256=tiDNrEFwqaIdL5ywZv908OXlzzfXsPCws9GXeoFtBV8,3367
|
|
64
64
|
langgraph_api/metadata.py,sha256=mih2G7ScQxiqyUlbksVXkqR3Oo-pM1b6lXtzOsgR1sw,3044
|
|
65
65
|
langgraph_api/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
66
|
-
langgraph_api/models/run.py,sha256=
|
|
66
|
+
langgraph_api/models/run.py,sha256=1TzTmagDXFQD_LhIMRdguZHmrPSzztq1wiMjF63d2fc,9843
|
|
67
67
|
langgraph_api/patch.py,sha256=94ddcTSZJe22JcpjxiSNjFZdYVnmeoWjk4IX4iBSoyk,1249
|
|
68
|
-
langgraph_api/queue.py,sha256=
|
|
68
|
+
langgraph_api/queue.py,sha256=qRuM09mz8o7CkrBIwg-9lV3SW0TehdVGgeXvHc_adYk,13647
|
|
69
69
|
langgraph_api/route.py,sha256=fM4qYCGbmH0a3_cV8uKocb1sLklehxO6HhdRXqLK6OM,4421
|
|
70
70
|
langgraph_api/schema.py,sha256=4aZCFY-dxd_nTot71bdcd9S8QCIgKajuRyj0p2QfgJ4,5291
|
|
71
71
|
langgraph_api/serde.py,sha256=VoJ7Z1IuqrQGXFzEP1qijAITtWCrmjtVqlCRuScjXJI,3533
|
|
72
|
-
langgraph_api/server.py,sha256=
|
|
72
|
+
langgraph_api/server.py,sha256=OrFCbFMIL7L7K8Id4lNEI6soFBwCdcIN4maSwSfsj1o,1657
|
|
73
73
|
langgraph_api/sse.py,sha256=2wNodCOP2eg7a9mpSu0S3FQ0CHk2BBV_vv0UtIgJIcc,4034
|
|
74
74
|
langgraph_api/state.py,sha256=8jx4IoTCOjTJuwzuXJKKFwo1VseHjNnw_CCq4x1SW14,2284
|
|
75
|
-
langgraph_api/stream.py,sha256=
|
|
76
|
-
langgraph_api/utils.py,sha256=
|
|
75
|
+
langgraph_api/stream.py,sha256=MUYYNgwtLs1Mhq1dm12zda7j8uFYir49umigK6CnuXU,11944
|
|
76
|
+
langgraph_api/utils.py,sha256=aIHPp_yu-NFUzs0jzNRm6mcqoZmtbLMZl1ugFmwWTss,2692
|
|
77
77
|
langgraph_api/validation.py,sha256=McizHlz-Ez8Jhdbc79mbPSde7GIuf2Jlbjx2yv_l6dA,4475
|
|
78
78
|
langgraph_license/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
79
79
|
langgraph_license/middleware.py,sha256=_ODIYzQkymr6W9_Fp9wtf1kAQspnpsmr53xuzyF2GA0,612
|
|
@@ -87,9 +87,9 @@ langgraph_storage/retry.py,sha256=uvYFuXJ-T6S1QY1ZwkZHyZQbsvS-Ab68LSbzbUUSI2E,69
|
|
|
87
87
|
langgraph_storage/store.py,sha256=D-p3cWc_umamkKp-6Cz3cAriSACpvM5nxUIvND6PuxE,2710
|
|
88
88
|
langgraph_storage/ttl_dict.py,sha256=FlpEY8EANeXWKo_G5nmIotPquABZGyIJyk6HD9u6vqY,1533
|
|
89
89
|
logging.json,sha256=3RNjSADZmDq38eHePMm1CbP6qZ71AmpBtLwCmKU9Zgo,379
|
|
90
|
-
openapi.json,sha256=
|
|
91
|
-
langgraph_api-0.0.
|
|
92
|
-
langgraph_api-0.0.
|
|
93
|
-
langgraph_api-0.0.
|
|
94
|
-
langgraph_api-0.0.
|
|
95
|
-
langgraph_api-0.0.
|
|
90
|
+
openapi.json,sha256=L1Ap1o6oAg2vKqjWohq4gl1-GpxezjlddS_oZHjS-xE,125227
|
|
91
|
+
langgraph_api-0.0.18.dist-info/LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
|
|
92
|
+
langgraph_api-0.0.18.dist-info/METADATA,sha256=k6oxmbw-_QEHL7VOaAdecVtt7tkw7ccF6A4ywpGYYUk,4041
|
|
93
|
+
langgraph_api-0.0.18.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
94
|
+
langgraph_api-0.0.18.dist-info/entry_points.txt,sha256=3EYLgj89DfzqJHHYGxPH4A_fEtClvlRbWRUHaXO7hj4,77
|
|
95
|
+
langgraph_api-0.0.18.dist-info/RECORD,,
|
openapi.json
CHANGED
|
@@ -3317,6 +3317,18 @@
|
|
|
3317
3317
|
{
|
|
3318
3318
|
"type": "object"
|
|
3319
3319
|
},
|
|
3320
|
+
{
|
|
3321
|
+
"type": "array"
|
|
3322
|
+
},
|
|
3323
|
+
{
|
|
3324
|
+
"type": "string"
|
|
3325
|
+
},
|
|
3326
|
+
{
|
|
3327
|
+
"type": "number"
|
|
3328
|
+
},
|
|
3329
|
+
{
|
|
3330
|
+
"type": "boolean"
|
|
3331
|
+
},
|
|
3320
3332
|
{
|
|
3321
3333
|
"type": "null"
|
|
3322
3334
|
}
|
|
@@ -3532,6 +3544,18 @@
|
|
|
3532
3544
|
{
|
|
3533
3545
|
"type": "object"
|
|
3534
3546
|
},
|
|
3547
|
+
{
|
|
3548
|
+
"type": "array"
|
|
3549
|
+
},
|
|
3550
|
+
{
|
|
3551
|
+
"type": "string"
|
|
3552
|
+
},
|
|
3553
|
+
{
|
|
3554
|
+
"type": "number"
|
|
3555
|
+
},
|
|
3556
|
+
{
|
|
3557
|
+
"type": "boolean"
|
|
3558
|
+
},
|
|
3535
3559
|
{
|
|
3536
3560
|
"type": "null"
|
|
3537
3561
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|