langgraph-api 0.1.23__py3-none-any.whl → 0.2.1__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/__init__.py +1 -1
- langgraph_api/api/mcp.py +29 -9
- langgraph_api/js/.prettierrc +1 -1
- langgraph_api/js/src/graph.mts +6 -6
- langgraph_api/js/src/parser/parser.worker.mjs +1 -1
- langgraph_api/js/src/parser/schema/types.mts +60 -60
- langgraph_api/js/src/utils/serde.mts +1 -1
- langgraph_api/js/tests/auth.test.mts +51 -51
- langgraph_api/js/tests/graphs/agent.mts +6 -6
- langgraph_api/js/tests/graphs/auth.mts +1 -1
- langgraph_api/js/tests/graphs/command.mts +1 -1
- langgraph_api/js/tests/graphs/delay.mts +1 -1
- langgraph_api/js/tests/graphs/nested.mts +3 -3
- langgraph_api/js/tests/graphs/weather.mts +1 -1
- langgraph_api/js/tests/utils.mts +2 -2
- langgraph_api/models/run.py +1 -0
- {langgraph_api-0.1.23.dist-info → langgraph_api-0.2.1.dist-info}/METADATA +2 -2
- {langgraph_api-0.1.23.dist-info → langgraph_api-0.2.1.dist-info}/RECORD +22 -22
- openapi.json +12 -0
- {langgraph_api-0.1.23.dist-info → langgraph_api-0.2.1.dist-info}/LICENSE +0 -0
- {langgraph_api-0.1.23.dist-info → langgraph_api-0.2.1.dist-info}/WHEEL +0 -0
- {langgraph_api-0.1.23.dist-info → langgraph_api-0.2.1.dist-info}/entry_points.txt +0 -0
|
@@ -6,13 +6,13 @@ import { SignJWT } from "jose";
|
|
|
6
6
|
|
|
7
7
|
const sql = postgres(
|
|
8
8
|
process.env.POSTGRES_URI ??
|
|
9
|
-
"postgres://postgres:postgres@127.0.0.1:5433/postgres?sslmode=disable"
|
|
9
|
+
"postgres://postgres:postgres@127.0.0.1:5433/postgres?sslmode=disable",
|
|
10
10
|
);
|
|
11
11
|
|
|
12
12
|
const config = { configurable: { user_id: "123" } };
|
|
13
13
|
|
|
14
14
|
const SECRET_KEY = new TextEncoder().encode(
|
|
15
|
-
"09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
|
|
15
|
+
"09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7",
|
|
16
16
|
);
|
|
17
17
|
const ALGORITHM = "HS256";
|
|
18
18
|
|
|
@@ -37,19 +37,19 @@ beforeAll(async () => {
|
|
|
37
37
|
it("unauthenticated user", async () => {
|
|
38
38
|
const client = await createJwtClient("wfh", ["me"]);
|
|
39
39
|
await expect(client.assistants.create({ graphId: "agent" })).rejects.toThrow(
|
|
40
|
-
"HTTP 401"
|
|
40
|
+
"HTTP 401",
|
|
41
41
|
);
|
|
42
42
|
});
|
|
43
43
|
|
|
44
44
|
it("create assistant with forbidden scopes", async () => {
|
|
45
45
|
let user = await createJwtClient("johndoe");
|
|
46
46
|
await expect(user.assistants.create({ graphId: "agent" })).rejects.toThrow(
|
|
47
|
-
"HTTP 403"
|
|
47
|
+
"HTTP 403",
|
|
48
48
|
);
|
|
49
49
|
|
|
50
50
|
user = await createJwtClient("johndoe", ["foo"]);
|
|
51
51
|
await expect(user.assistants.create({ graphId: "agent" })).rejects.toThrow(
|
|
52
|
-
"HTTP 403"
|
|
52
|
+
"HTTP 403",
|
|
53
53
|
);
|
|
54
54
|
|
|
55
55
|
user = await createJwtClient("johndoe", ["assistants:write"]);
|
|
@@ -75,7 +75,7 @@ it("get thread history from unauthorized user", async () => {
|
|
|
75
75
|
|
|
76
76
|
const user2 = await createJwtClient("alice", ["me"]);
|
|
77
77
|
await expect(
|
|
78
|
-
user2.runs.wait(thread.thread_id, "agent", { input, config })
|
|
78
|
+
user2.runs.wait(thread.thread_id, "agent", { input, config }),
|
|
79
79
|
).rejects.toThrow("HTTP 404");
|
|
80
80
|
});
|
|
81
81
|
|
|
@@ -89,7 +89,7 @@ it("add run to unauthorized thread", async () => {
|
|
|
89
89
|
|
|
90
90
|
const user2 = await createJwtClient("alice", ["me"]);
|
|
91
91
|
await expect(
|
|
92
|
-
user2.runs.wait(thread.thread_id, "agent", { input, config })
|
|
92
|
+
user2.runs.wait(thread.thread_id, "agent", { input, config }),
|
|
93
93
|
).rejects.toThrow("HTTP 404");
|
|
94
94
|
});
|
|
95
95
|
|
|
@@ -103,12 +103,12 @@ it("asssistant access control", async () => {
|
|
|
103
103
|
await expect(
|
|
104
104
|
otherUser.assistants.update(assistant.assistant_id, {
|
|
105
105
|
metadata: { foo: "bar" },
|
|
106
|
-
})
|
|
106
|
+
}),
|
|
107
107
|
).rejects.toThrow("HTTP 404");
|
|
108
108
|
|
|
109
109
|
// Other user can't delete the assistant
|
|
110
110
|
await expect(
|
|
111
|
-
otherUser.assistants.delete(assistant.assistant_id)
|
|
111
|
+
otherUser.assistants.delete(assistant.assistant_id),
|
|
112
112
|
).rejects.toThrow("HTTP 404");
|
|
113
113
|
});
|
|
114
114
|
|
|
@@ -120,12 +120,12 @@ it("thread operations auth", async () => {
|
|
|
120
120
|
|
|
121
121
|
// Other user can't update thread
|
|
122
122
|
await expect(
|
|
123
|
-
otherUser.threads.update(thread.thread_id, { metadata: { foo: "bar" } })
|
|
123
|
+
otherUser.threads.update(thread.thread_id, { metadata: { foo: "bar" } }),
|
|
124
124
|
).rejects.toThrow("HTTP 404");
|
|
125
125
|
|
|
126
126
|
// Other user can't delete thread
|
|
127
127
|
await expect(otherUser.threads.delete(thread.thread_id)).rejects.toThrow(
|
|
128
|
-
"HTTP 404"
|
|
128
|
+
"HTTP 404",
|
|
129
129
|
);
|
|
130
130
|
});
|
|
131
131
|
|
|
@@ -142,7 +142,7 @@ it("run streaming auth", async () => {
|
|
|
142
142
|
});
|
|
143
143
|
|
|
144
144
|
const chunks = await gatherIterator(
|
|
145
|
-
otherUser.runs.joinStream(thread.thread_id, run.run_id)
|
|
145
|
+
otherUser.runs.joinStream(thread.thread_id, run.run_id),
|
|
146
146
|
);
|
|
147
147
|
|
|
148
148
|
expect(chunks).toMatchObject([
|
|
@@ -176,17 +176,17 @@ it("store auth", async () => {
|
|
|
176
176
|
|
|
177
177
|
// Test store access control
|
|
178
178
|
await expect(userA.store.getItem(["ALL"], "key_one")).rejects.toThrow(
|
|
179
|
-
"HTTP 403"
|
|
179
|
+
"HTTP 403",
|
|
180
180
|
);
|
|
181
181
|
await expect(
|
|
182
|
-
userA.store.putItem(["ALL"], "key_one", { foo: "bar" })
|
|
182
|
+
userA.store.putItem(["ALL"], "key_one", { foo: "bar" }),
|
|
183
183
|
).rejects.toThrow("HTTP 403");
|
|
184
184
|
await expect(userA.store.deleteItem(["ALL"], "key_one")).rejects.toThrow(
|
|
185
|
-
"HTTP 403"
|
|
185
|
+
"HTTP 403",
|
|
186
186
|
);
|
|
187
187
|
await expect(userA.store.searchItems(["ALL"])).rejects.toThrow("HTTP 403");
|
|
188
188
|
await expect(userA.store.listNamespaces({ prefix: ["ALL"] })).rejects.toThrow(
|
|
189
|
-
"HTTP 403"
|
|
189
|
+
"HTTP 403",
|
|
190
190
|
);
|
|
191
191
|
|
|
192
192
|
// Test owner can access their own store
|
|
@@ -199,7 +199,7 @@ it("store auth", async () => {
|
|
|
199
199
|
});
|
|
200
200
|
|
|
201
201
|
expect(
|
|
202
|
-
await userA.store.listNamespaces({ prefix: ["johndoe"] })
|
|
202
|
+
await userA.store.listNamespaces({ prefix: ["johndoe"] }),
|
|
203
203
|
).toMatchObject({ namespaces: [["johndoe"]] });
|
|
204
204
|
|
|
205
205
|
// Test other user can access their own store
|
|
@@ -210,11 +210,11 @@ it("store auth", async () => {
|
|
|
210
210
|
items: [{ key: "key_one", value: { text: "test user B" } }],
|
|
211
211
|
});
|
|
212
212
|
expect(await userB.store.listNamespaces({ prefix: ["alice"] })).toMatchObject(
|
|
213
|
-
{ namespaces: [["alice"]] }
|
|
213
|
+
{ namespaces: [["alice"]] },
|
|
214
214
|
);
|
|
215
215
|
});
|
|
216
216
|
|
|
217
|
-
it("run cancellation", async () => {
|
|
217
|
+
it("run cancellation", { retry: 3 }, async () => {
|
|
218
218
|
const owner = await createJwtClient("johndoe", ["me"]);
|
|
219
219
|
const otherUser = await createJwtClient("alice", ["me"]);
|
|
220
220
|
|
|
@@ -227,7 +227,7 @@ it("run cancellation", async () => {
|
|
|
227
227
|
|
|
228
228
|
// Other user can't cancel the run
|
|
229
229
|
await expect(
|
|
230
|
-
otherUser.runs.cancel(thread.thread_id, run.run_id)
|
|
230
|
+
otherUser.runs.cancel(thread.thread_id, run.run_id),
|
|
231
231
|
).rejects.toThrow("HTTP 404");
|
|
232
232
|
|
|
233
233
|
// Owner can cancel their own run
|
|
@@ -246,13 +246,13 @@ it("get assistant ownership", async () => {
|
|
|
246
246
|
|
|
247
247
|
// Another user cannot get this assistant
|
|
248
248
|
await expect(
|
|
249
|
-
otherUser.assistants.get(assistant.assistant_id)
|
|
249
|
+
otherUser.assistants.get(assistant.assistant_id),
|
|
250
250
|
).rejects.toThrow("HTTP 404");
|
|
251
251
|
|
|
252
252
|
// Test invalid assistant IDs
|
|
253
253
|
const nonexistantUuid = crypto.randomUUID();
|
|
254
254
|
await expect(owner.assistants.get(nonexistantUuid)).rejects.toThrow(
|
|
255
|
-
"HTTP 404"
|
|
255
|
+
"HTTP 404",
|
|
256
256
|
);
|
|
257
257
|
});
|
|
258
258
|
|
|
@@ -270,7 +270,7 @@ it("get assistant graph", async () => {
|
|
|
270
270
|
|
|
271
271
|
// Another user can't access the graph
|
|
272
272
|
await expect(
|
|
273
|
-
otherUser.assistants.getGraph(assistant.assistant_id)
|
|
273
|
+
otherUser.assistants.getGraph(assistant.assistant_id),
|
|
274
274
|
).rejects.toThrow("HTTP 404");
|
|
275
275
|
});
|
|
276
276
|
|
|
@@ -301,10 +301,10 @@ it("thread state operations", async () => {
|
|
|
301
301
|
|
|
302
302
|
// Another user cannot access or modify state
|
|
303
303
|
await expect(otherUser.threads.getState(thread.thread_id)).rejects.toThrow(
|
|
304
|
-
"HTTP 404"
|
|
304
|
+
"HTTP 404",
|
|
305
305
|
);
|
|
306
306
|
await expect(
|
|
307
|
-
otherUser.threads.updateState(thread.thread_id, { values: { sleep: 432 } })
|
|
307
|
+
otherUser.threads.updateState(thread.thread_id, { values: { sleep: 432 } }),
|
|
308
308
|
).rejects.toThrow("HTTP 404");
|
|
309
309
|
});
|
|
310
310
|
|
|
@@ -324,7 +324,7 @@ it("run operations", async () => {
|
|
|
324
324
|
// Owner can list runs
|
|
325
325
|
const runs = await owner.runs.list(thread.thread_id);
|
|
326
326
|
expect(runs).toMatchObject(
|
|
327
|
-
expect.arrayContaining([expect.objectContaining({ run_id: run.run_id })])
|
|
327
|
+
expect.arrayContaining([expect.objectContaining({ run_id: run.run_id })]),
|
|
328
328
|
);
|
|
329
329
|
|
|
330
330
|
// Owner can get specific run
|
|
@@ -333,18 +333,18 @@ it("run operations", async () => {
|
|
|
333
333
|
|
|
334
334
|
// Another user cannot access runs, cancel or delete a run not owned by them
|
|
335
335
|
await expect(otherUser.runs.list(thread.thread_id)).rejects.toThrow(
|
|
336
|
-
"HTTP 404"
|
|
336
|
+
"HTTP 404",
|
|
337
337
|
);
|
|
338
338
|
await expect(
|
|
339
|
-
otherUser.runs.get(thread.thread_id, run.run_id)
|
|
339
|
+
otherUser.runs.get(thread.thread_id, run.run_id),
|
|
340
340
|
).rejects.toThrow("HTTP 404");
|
|
341
341
|
|
|
342
342
|
await expect(
|
|
343
|
-
otherUser.runs.cancel(thread.thread_id, run.run_id, true)
|
|
343
|
+
otherUser.runs.cancel(thread.thread_id, run.run_id, true),
|
|
344
344
|
).rejects.toThrow("HTTP 404");
|
|
345
345
|
|
|
346
346
|
await expect(
|
|
347
|
-
otherUser.runs.delete(thread.thread_id, run.run_id)
|
|
347
|
+
otherUser.runs.delete(thread.thread_id, run.run_id),
|
|
348
348
|
).rejects.toThrow("HTTP 404");
|
|
349
349
|
|
|
350
350
|
// Owner can cancel run
|
|
@@ -353,7 +353,7 @@ it("run operations", async () => {
|
|
|
353
353
|
// Owner can delete run
|
|
354
354
|
await owner.runs.delete(thread.thread_id, run.run_id);
|
|
355
355
|
await expect(owner.runs.get(thread.thread_id, run.run_id)).rejects.toThrow(
|
|
356
|
-
"HTTP 404"
|
|
356
|
+
"HTTP 404",
|
|
357
357
|
);
|
|
358
358
|
});
|
|
359
359
|
|
|
@@ -367,7 +367,7 @@ it("create run in other user thread", async () => {
|
|
|
367
367
|
};
|
|
368
368
|
|
|
369
369
|
await expect(
|
|
370
|
-
otherUser.runs.create(thread.thread_id, "agent", { input, config })
|
|
370
|
+
otherUser.runs.create(thread.thread_id, "agent", { input, config }),
|
|
371
371
|
).rejects.toThrow("HTTP 404");
|
|
372
372
|
});
|
|
373
373
|
|
|
@@ -388,7 +388,7 @@ it("list runs other user thread", async () => {
|
|
|
388
388
|
|
|
389
389
|
// Other user cannot list runs
|
|
390
390
|
await expect(otherUser.runs.list(thread.thread_id)).rejects.toThrow(
|
|
391
|
-
"HTTP 404"
|
|
391
|
+
"HTTP 404",
|
|
392
392
|
);
|
|
393
393
|
});
|
|
394
394
|
|
|
@@ -404,7 +404,7 @@ it("get run other user thread", async () => {
|
|
|
404
404
|
|
|
405
405
|
// Other user attempts to get the run
|
|
406
406
|
await expect(
|
|
407
|
-
otherUser.runs.get(thread.thread_id, run.run_id)
|
|
407
|
+
otherUser.runs.get(thread.thread_id, run.run_id),
|
|
408
408
|
).rejects.toThrow("HTTP 404");
|
|
409
409
|
});
|
|
410
410
|
|
|
@@ -420,7 +420,7 @@ it("join run other user thread", async () => {
|
|
|
420
420
|
|
|
421
421
|
// Other user tries to join the run
|
|
422
422
|
await expect(
|
|
423
|
-
otherUser.runs.join(thread.thread_id, run.run_id)
|
|
423
|
+
otherUser.runs.join(thread.thread_id, run.run_id),
|
|
424
424
|
).rejects.toThrow("HTTP 404");
|
|
425
425
|
});
|
|
426
426
|
|
|
@@ -434,7 +434,7 @@ it("wait run other user thread", async () => {
|
|
|
434
434
|
|
|
435
435
|
// Other user tries to wait on run result
|
|
436
436
|
await expect(
|
|
437
|
-
otherUser.runs.wait(thread.thread_id, "agent", { input, config })
|
|
437
|
+
otherUser.runs.wait(thread.thread_id, "agent", { input, config }),
|
|
438
438
|
).rejects.toThrow("HTTP 404");
|
|
439
439
|
});
|
|
440
440
|
|
|
@@ -450,7 +450,7 @@ it("stream run other user thread", async () => {
|
|
|
450
450
|
|
|
451
451
|
// Other user tries to join_stream
|
|
452
452
|
const chunks = await gatherIterator(
|
|
453
|
-
otherUser.runs.joinStream(thread.thread_id, run.run_id)
|
|
453
|
+
otherUser.runs.joinStream(thread.thread_id, run.run_id),
|
|
454
454
|
);
|
|
455
455
|
expect(chunks).toHaveLength(1);
|
|
456
456
|
expect(chunks).toMatchObject([
|
|
@@ -470,7 +470,7 @@ it("cancel run other user thread", { retry: 3 }, async () => {
|
|
|
470
470
|
});
|
|
471
471
|
|
|
472
472
|
await expect(
|
|
473
|
-
otherUser.runs.cancel(thread.thread_id, run.run_id)
|
|
473
|
+
otherUser.runs.cancel(thread.thread_id, run.run_id),
|
|
474
474
|
).rejects.toThrow("HTTP 404");
|
|
475
475
|
|
|
476
476
|
await owner.runs.cancel(thread.thread_id, run.run_id);
|
|
@@ -488,7 +488,7 @@ it("delete run other user thread", async () => {
|
|
|
488
488
|
});
|
|
489
489
|
|
|
490
490
|
await expect(
|
|
491
|
-
otherUser.runs.delete(thread.thread_id, run.run_id)
|
|
491
|
+
otherUser.runs.delete(thread.thread_id, run.run_id),
|
|
492
492
|
).rejects.toThrow("HTTP 404");
|
|
493
493
|
|
|
494
494
|
await owner.runs.cancel(thread.thread_id, run.run_id);
|
|
@@ -503,7 +503,7 @@ it("update thread state other user", async () => {
|
|
|
503
503
|
|
|
504
504
|
// Other user tries to update state
|
|
505
505
|
await expect(
|
|
506
|
-
otherUser.threads.updateState(thread.thread_id, newState)
|
|
506
|
+
otherUser.threads.updateState(thread.thread_id, newState),
|
|
507
507
|
).rejects.toThrow("HTTP 404");
|
|
508
508
|
});
|
|
509
509
|
|
|
@@ -528,7 +528,7 @@ it("get checkpoint other user", async () => {
|
|
|
528
528
|
}
|
|
529
529
|
|
|
530
530
|
await expect(
|
|
531
|
-
otherUser.threads.getState(thread.thread_id, checkpointId)
|
|
531
|
+
otherUser.threads.getState(thread.thread_id, checkpointId),
|
|
532
532
|
).rejects.toThrow("HTTP 404");
|
|
533
533
|
});
|
|
534
534
|
|
|
@@ -544,10 +544,10 @@ it("assistant version leakage", async () => {
|
|
|
544
544
|
expect(result.metadata?.foo).toBe(someId);
|
|
545
545
|
|
|
546
546
|
await expect(
|
|
547
|
-
otherUser.assistants.getVersions(assistant.assistant_id)
|
|
547
|
+
otherUser.assistants.getVersions(assistant.assistant_id),
|
|
548
548
|
).rejects.toThrow("HTTP 404");
|
|
549
549
|
await expect(
|
|
550
|
-
otherUser.assistants.setLatest(assistant.assistant_id, 1)
|
|
550
|
+
otherUser.assistants.setLatest(assistant.assistant_id, 1),
|
|
551
551
|
).rejects.toThrow("HTTP 404");
|
|
552
552
|
});
|
|
553
553
|
|
|
@@ -562,7 +562,7 @@ it("assistant set latest", async () => {
|
|
|
562
562
|
expect(updated.metadata?.foo).toBe("bar");
|
|
563
563
|
|
|
564
564
|
await expect(
|
|
565
|
-
otherUser.assistants.setLatest(assistant.assistant_id, 1)
|
|
565
|
+
otherUser.assistants.setLatest(assistant.assistant_id, 1),
|
|
566
566
|
).rejects.toThrow("HTTP 404");
|
|
567
567
|
|
|
568
568
|
const result = await owner.assistants.setLatest(assistant.assistant_id, 1);
|
|
@@ -580,18 +580,18 @@ it("assistant search filtering", async () => {
|
|
|
580
580
|
// each user should only see their own assistants
|
|
581
581
|
const results1 = await user1.assistants.search();
|
|
582
582
|
expect(results1).toContainEqual(
|
|
583
|
-
expect.objectContaining({ assistant_id: assistant1.assistant_id })
|
|
583
|
+
expect.objectContaining({ assistant_id: assistant1.assistant_id }),
|
|
584
584
|
);
|
|
585
585
|
expect(results1).not.toContainEqual(
|
|
586
|
-
expect.objectContaining({ assistant_id: assistant2.assistant_id })
|
|
586
|
+
expect.objectContaining({ assistant_id: assistant2.assistant_id }),
|
|
587
587
|
);
|
|
588
588
|
|
|
589
589
|
const results2 = await user2.assistants.search();
|
|
590
590
|
expect(results2).toContainEqual(
|
|
591
|
-
expect.objectContaining({ assistant_id: assistant2.assistant_id })
|
|
591
|
+
expect.objectContaining({ assistant_id: assistant2.assistant_id }),
|
|
592
592
|
);
|
|
593
593
|
expect(results2).not.toContainEqual(
|
|
594
|
-
expect.objectContaining({ assistant_id: assistant1.assistant_id })
|
|
594
|
+
expect.objectContaining({ assistant_id: assistant1.assistant_id }),
|
|
595
595
|
);
|
|
596
596
|
});
|
|
597
597
|
|
|
@@ -603,7 +603,7 @@ it("thread copy authorization", async () => {
|
|
|
603
603
|
|
|
604
604
|
// Other user can't copy the thread
|
|
605
605
|
await expect(otherUser.threads.copy(thread.thread_id)).rejects.toThrow(
|
|
606
|
-
"HTTP 409"
|
|
606
|
+
"HTTP 409",
|
|
607
607
|
);
|
|
608
608
|
|
|
609
609
|
// Owner can copy the thread
|
|
@@ -623,7 +623,7 @@ it("thread history authorization", async () => {
|
|
|
623
623
|
expect(history).toHaveLength(5);
|
|
624
624
|
|
|
625
625
|
await expect(otherUser.threads.getHistory(thread.thread_id)).rejects.toThrow(
|
|
626
|
-
"HTTP 404"
|
|
626
|
+
"HTTP 404",
|
|
627
627
|
);
|
|
628
628
|
});
|
|
629
629
|
|
|
@@ -641,7 +641,7 @@ it("test stateless runs", async () => {
|
|
|
641
641
|
|
|
642
642
|
expect(values).not.toBeNull();
|
|
643
643
|
const chunks = await gatherIterator(
|
|
644
|
-
owner.runs.stream(null, assistant.assistant_id, { input, config })
|
|
644
|
+
owner.runs.stream(null, assistant.assistant_id, { input, config }),
|
|
645
645
|
);
|
|
646
646
|
|
|
647
647
|
expect(chunks.find((i) => i.event === "error")).not.toBeDefined();
|
|
@@ -37,7 +37,7 @@ class StableFakeListChatModel extends FakeListChatModel {
|
|
|
37
37
|
async *_streamResponseChunks(
|
|
38
38
|
_messages: BaseMessage[],
|
|
39
39
|
options: this["ParsedCallOptions"],
|
|
40
|
-
runManager?: CallbackManagerForLLMRun
|
|
40
|
+
runManager?: CallbackManagerForLLMRun,
|
|
41
41
|
): AsyncGenerator<ChatGenerationChunk> {
|
|
42
42
|
const response = this._currentResponse();
|
|
43
43
|
this._incrementResponse();
|
|
@@ -68,7 +68,7 @@ class StableFakeListChatModel extends FakeListChatModel {
|
|
|
68
68
|
undefined,
|
|
69
69
|
undefined,
|
|
70
70
|
undefined,
|
|
71
|
-
{ chunk }
|
|
71
|
+
{ chunk },
|
|
72
72
|
);
|
|
73
73
|
}
|
|
74
74
|
}
|
|
@@ -88,7 +88,7 @@ const getModel = (threadId: string) => {
|
|
|
88
88
|
|
|
89
89
|
const agentNode = async (
|
|
90
90
|
state: typeof GraphAnnotationInput.State,
|
|
91
|
-
config: LangGraphRunnableConfig
|
|
91
|
+
config: LangGraphRunnableConfig,
|
|
92
92
|
) => {
|
|
93
93
|
if (state.interrupt) interrupt("i want to interrupt");
|
|
94
94
|
|
|
@@ -120,7 +120,7 @@ const agentNode = async (
|
|
|
120
120
|
|
|
121
121
|
const toolNode = async (
|
|
122
122
|
state: typeof GraphAnnotationInput.State,
|
|
123
|
-
config: LangGraphRunnableConfig
|
|
123
|
+
config: LangGraphRunnableConfig,
|
|
124
124
|
) => {
|
|
125
125
|
const store = config.store;
|
|
126
126
|
let sharedStateFromStoreConfig: Record<string, any> | null = null;
|
|
@@ -144,7 +144,7 @@ const toolNode = async (
|
|
|
144
144
|
|
|
145
145
|
const checkSharedStateNode = async (
|
|
146
146
|
_: typeof GraphAnnotationInput.State,
|
|
147
|
-
config: LangGraphRunnableConfig
|
|
147
|
+
config: LangGraphRunnableConfig,
|
|
148
148
|
): Promise<Partial<typeof GraphAnnotationInput.State>> => {
|
|
149
149
|
const store = config.store;
|
|
150
150
|
const namespace = ["inputtedState", "data"];
|
|
@@ -174,7 +174,7 @@ const workflow = new StateGraph(
|
|
|
174
174
|
input: GraphAnnotationInput,
|
|
175
175
|
output: GraphAnnotationOutput,
|
|
176
176
|
},
|
|
177
|
-
Annotation.Root({ model_name: Annotation<string> })
|
|
177
|
+
Annotation.Root({ model_name: Annotation<string> }),
|
|
178
178
|
)
|
|
179
179
|
.addNode("agent", agentNode)
|
|
180
180
|
.addNode("tool", toolNode)
|
|
@@ -2,7 +2,7 @@ import { Auth, HTTPException } from "@langchain/langgraph-sdk/auth";
|
|
|
2
2
|
import { JWTPayload, jwtVerify } from "jose";
|
|
3
3
|
|
|
4
4
|
const SECRET_KEY = new TextEncoder().encode(
|
|
5
|
-
"09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
|
|
5
|
+
"09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7",
|
|
6
6
|
);
|
|
7
7
|
const ALGORITHM = "HS256";
|
|
8
8
|
|
|
@@ -6,7 +6,7 @@ const child = new StateGraph(
|
|
|
6
6
|
reducer: (a, b) => a.concat(b),
|
|
7
7
|
}),
|
|
8
8
|
child: Annotation<"child_one" | "child_two">,
|
|
9
|
-
})
|
|
9
|
+
}),
|
|
10
10
|
)
|
|
11
11
|
.addNode("c_one", () => ({ messages: ["Entered c_one node"] }))
|
|
12
12
|
.addNode("c_two", () => ({ messages: ["Entered c_two node"] }))
|
|
@@ -20,7 +20,7 @@ const parent = new StateGraph(
|
|
|
20
20
|
reducer: (a, b) => a.concat(b),
|
|
21
21
|
}),
|
|
22
22
|
parent: Annotation<"parent_one" | "parent_two">,
|
|
23
|
-
})
|
|
23
|
+
}),
|
|
24
24
|
)
|
|
25
25
|
.addNode("p_one", () => ({ messages: ["Entered p_one node"] }))
|
|
26
26
|
.addNode("p_two", child.compile())
|
|
@@ -33,7 +33,7 @@ const grandParent = new StateGraph(
|
|
|
33
33
|
messages: Annotation<string[]>({
|
|
34
34
|
reducer: (a, b) => a.concat(b),
|
|
35
35
|
}),
|
|
36
|
-
})
|
|
36
|
+
}),
|
|
37
37
|
)
|
|
38
38
|
.addNode("gp_one", () => ({ messages: ["Entered gp_one node"] }))
|
|
39
39
|
.addNode("gp_two", parent.compile())
|
|
@@ -49,7 +49,7 @@ const router = new StateGraph(routerState)
|
|
|
49
49
|
if (route === "weather") return "weather_graph";
|
|
50
50
|
return "normal_llm_node";
|
|
51
51
|
},
|
|
52
|
-
["weather_graph", "normal_llm_node"]
|
|
52
|
+
["weather_graph", "normal_llm_node"],
|
|
53
53
|
)
|
|
54
54
|
.addEdge("weather_graph", END)
|
|
55
55
|
.addEdge("normal_llm_node", END);
|
langgraph_api/js/tests/utils.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export async function gatherIterator<T>(
|
|
2
|
-
i: AsyncIterable<T> | Promise<AsyncIterable<T
|
|
2
|
+
i: AsyncIterable<T> | Promise<AsyncIterable<T>>,
|
|
3
3
|
): Promise<Array<T>> {
|
|
4
4
|
const out: T[] = [];
|
|
5
5
|
for await (const item of await i) out.push(item);
|
|
@@ -8,7 +8,7 @@ export async function gatherIterator<T>(
|
|
|
8
8
|
|
|
9
9
|
export function findLast<T, S extends T>(
|
|
10
10
|
lst: Array<T>,
|
|
11
|
-
predicate: (item: T) => item is S
|
|
11
|
+
predicate: (item: T) => item is S,
|
|
12
12
|
): S | undefined {
|
|
13
13
|
for (let i = lst.length - 1; i >= 0; i--) {
|
|
14
14
|
if (predicate(lst[i])) return lst[i] as S;
|
langgraph_api/models/run.py
CHANGED
|
@@ -302,6 +302,7 @@ async def create_valid_run(
|
|
|
302
302
|
"feedback_keys": payload.get("feedback_keys"),
|
|
303
303
|
"temporary": temporary,
|
|
304
304
|
"subgraphs": payload.get("stream_subgraphs", False),
|
|
305
|
+
"checkpoint_during": payload.get("checkpoint_during", False),
|
|
305
306
|
},
|
|
306
307
|
metadata=payload.get("metadata"),
|
|
307
308
|
status="pending",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: langgraph-api
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary:
|
|
5
5
|
License: Elastic-2.0
|
|
6
6
|
Author: Nuno Campos
|
|
@@ -19,7 +19,7 @@ Requires-Dist: langchain-core (>=0.2.38) ; python_version < "4.0"
|
|
|
19
19
|
Requires-Dist: langgraph (>=0.2.56) ; python_version < "4.0"
|
|
20
20
|
Requires-Dist: langgraph-checkpoint (>=2.0.23) ; python_version < "4.0"
|
|
21
21
|
Requires-Dist: langgraph-runtime-inmem (>=0.0.7)
|
|
22
|
-
Requires-Dist: langgraph-sdk (>=0.1.
|
|
22
|
+
Requires-Dist: langgraph-sdk (>=0.1.66,<0.2.0) ; python_version < "4.0"
|
|
23
23
|
Requires-Dist: langsmith (>=0.1.63)
|
|
24
24
|
Requires-Dist: orjson (>=3.9.7)
|
|
25
25
|
Requires-Dist: pyjwt (>=2.9.0,<3.0.0)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
|
|
2
|
-
langgraph_api/__init__.py,sha256=
|
|
2
|
+
langgraph_api/__init__.py,sha256=HfjVOrpTnmZ-xVFCYSVmX50EXaBQeJteUHG-PD6iQs8,22
|
|
3
3
|
langgraph_api/api/__init__.py,sha256=IKKMrC5gCHTzjprbg8jgZDrAJRuqJfSUgEkZAgh3l-M,5771
|
|
4
4
|
langgraph_api/api/assistants.py,sha256=6oYFRKlvqheJQGbWjFhQOUnnSbvsbrdMYLRJP7WtSRo,14481
|
|
5
|
-
langgraph_api/api/mcp.py,sha256=
|
|
5
|
+
langgraph_api/api/mcp.py,sha256=RvRYgANqRzNQzSmgjNkq4RlKTtoEJYil04ot9lsmEtE,14352
|
|
6
6
|
langgraph_api/api/meta.py,sha256=sTgkhE-DaFWpERG6F7KelZfDsmJAiVc4j5dg50tDkSo,2950
|
|
7
7
|
langgraph_api/api/openapi.py,sha256=OGwzPpYO4e98iqtgL7UEfzI6jP4zXahJ1R-7VgOSZeg,11046
|
|
8
8
|
langgraph_api/api/runs.py,sha256=dhHZ3xu7V0anftqzXaOYnhVEryJpVeqzu60MFiUw4u8,18010
|
|
@@ -26,7 +26,7 @@ langgraph_api/errors.py,sha256=Bu_i5drgNTyJcLiyrwVE_6-XrSU50BHf9TDpttki9wQ,1690
|
|
|
26
26
|
langgraph_api/graph.py,sha256=YyWCPtoI9VDV0knjCMUFoH4r9OFVsAiv5K8FzbziMqs,21488
|
|
27
27
|
langgraph_api/http.py,sha256=gYbxxjY8aLnsXeJymcJ7G7Nj_yToOGpPYQqmZ1_ggfA,5240
|
|
28
28
|
langgraph_api/js/.gitignore,sha256=l5yI6G_V6F1600I1IjiUKn87f4uYIrBAYU1MOyBBhg4,59
|
|
29
|
-
langgraph_api/js/.prettierrc,sha256=
|
|
29
|
+
langgraph_api/js/.prettierrc,sha256=0es3ovvyNIqIw81rPQsdt1zCQcOdBqyR_DMbFE4Ifms,19
|
|
30
30
|
langgraph_api/js/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
31
|
langgraph_api/js/base.py,sha256=gjY6K8avI03OrI-Hy6a311fQ_EG5r_x8hUYlc7uqxdE,534
|
|
32
32
|
langgraph_api/js/build.mts,sha256=ceHRr_Io_9otkDOSgHuKbGnOUu4AX2jPj8APTTa9UjM,2741
|
|
@@ -37,40 +37,40 @@ langgraph_api/js/global.d.ts,sha256=j4GhgtQSZ5_cHzjSPcHgMJ8tfBThxrH-pUOrrJGteOU,
|
|
|
37
37
|
langgraph_api/js/package.json,sha256=5gtQpj0mXh069X5fWJFWp-jt7Sb3RQUPVpe4m8Q0KHE,1289
|
|
38
38
|
langgraph_api/js/remote.py,sha256=ipAITSDyh-kNau37nfRg-PSB-6Lbtax3UJap8-lLZdw,35729
|
|
39
39
|
langgraph_api/js/schema.py,sha256=7idnv7URlYUdSNMBXQcw7E4SxaPxCq_Oxwnlml8q5ik,408
|
|
40
|
-
langgraph_api/js/src/graph.mts,sha256=
|
|
40
|
+
langgraph_api/js/src/graph.mts,sha256=_xKhdO2WAwsieoezFqTCcx1IDeHeN6GSMv0lyBsakKI,3485
|
|
41
41
|
langgraph_api/js/src/load.hooks.mjs,sha256=xNVHq75W0Lk6MUKl1pQYrx-wtQ8_neiUyI6SO-k0ecM,2235
|
|
42
42
|
langgraph_api/js/src/parser/parser.mts,sha256=iW5G-YIVIuwuFsfn_GS3_CZsjpa00SxypICfPf2SN9Q,14156
|
|
43
|
-
langgraph_api/js/src/parser/parser.worker.mjs,sha256=
|
|
44
|
-
langgraph_api/js/src/parser/schema/types.mts,sha256=
|
|
43
|
+
langgraph_api/js/src/parser/parser.worker.mjs,sha256=Byo65U2aI3FtZaUwRRq65xBpwornoR6ldak333jxH4c,387
|
|
44
|
+
langgraph_api/js/src/parser/schema/types.mts,sha256=Vx34tLAncRnITwAVe1wABFgM86TpByMLQ5y5pnit4tI,62693
|
|
45
45
|
langgraph_api/js/src/parser/schema/types.template.mts,sha256=Dbjj_8d-OubqH4QY_OaxSu8ocZ4dVjI94oncL20fqtk,2235
|
|
46
46
|
langgraph_api/js/src/preload.mjs,sha256=ORV7xwMuZcXWL6jQxNAcCYp8GZVYIvVJbUhmle8jbno,759
|
|
47
47
|
langgraph_api/js/src/utils/files.mts,sha256=MXC-3gy0pkS82AjPBoUN83jY_qg37WSAPHOA7DwfB4M,141
|
|
48
48
|
langgraph_api/js/src/utils/importMap.mts,sha256=pX4TGOyUpuuWF82kXcxcv3-8mgusRezOGe6Uklm2O5A,1644
|
|
49
49
|
langgraph_api/js/src/utils/pythonSchemas.mts,sha256=98IW7Z_VP7L_CHNRMb3_MsiV3BgLE2JsWQY_PQcRR3o,685
|
|
50
|
-
langgraph_api/js/src/utils/serde.mts,sha256=
|
|
50
|
+
langgraph_api/js/src/utils/serde.mts,sha256=D9o6MwTgwPezC_DEmsWS5NnLPnjPMVWIb1I1D4QPEPo,743
|
|
51
51
|
langgraph_api/js/sse.py,sha256=lsfp4nyJyA1COmlKG9e2gJnTttf_HGCB5wyH8OZBER8,4105
|
|
52
52
|
langgraph_api/js/tests/api.test.mts,sha256=qjHkSdgTDiBauhxRD4yNMufD5xfZh9BNZ7nD7hTgyzo,68125
|
|
53
|
-
langgraph_api/js/tests/auth.test.mts,sha256=
|
|
53
|
+
langgraph_api/js/tests/auth.test.mts,sha256=mMhKe9ggJw4BgUqzSVwqYY3HLMXXEBZ23iiKK8Yq1mM,21678
|
|
54
54
|
langgraph_api/js/tests/compose-postgres.auth.yml,sha256=iPfJbCeYZdV6GiRLiDn_f7qgpG4TyyGaQ4lV-ZXr6Qk,1768
|
|
55
55
|
langgraph_api/js/tests/compose-postgres.yml,sha256=w4B3YRS0QEnTcZH2-MY0DYvR_c5GcER0uDa1Ga_knf8,1960
|
|
56
56
|
langgraph_api/js/tests/graphs/.gitignore,sha256=26J8MarZNXh7snXD5eTpV3CPFTht5Znv8dtHYCLNfkw,12
|
|
57
57
|
langgraph_api/js/tests/graphs/agent.css,sha256=QgcOC0W7IBsrg4pSqqpull-WTgtULZfx_lF_5ZxLdag,23
|
|
58
|
-
langgraph_api/js/tests/graphs/agent.mts,sha256=
|
|
58
|
+
langgraph_api/js/tests/graphs/agent.mts,sha256=0CizKahPnDg5JB9_zGyZRQc7RCM19SV4FiWxscLAWY0,5402
|
|
59
59
|
langgraph_api/js/tests/graphs/agent.ui.tsx,sha256=JDFJdpdIS6rglkXTaROSb1Is0j1kt5wN9ML8W4cuht8,175
|
|
60
60
|
langgraph_api/js/tests/graphs/agent_simple.mts,sha256=EDaQXM5x73HhcHoujezOX5C27uZdGdtfMVBE9o4hleE,2998
|
|
61
|
-
langgraph_api/js/tests/graphs/auth.mts,sha256=
|
|
62
|
-
langgraph_api/js/tests/graphs/command.mts,sha256=
|
|
63
|
-
langgraph_api/js/tests/graphs/delay.mts,sha256=
|
|
61
|
+
langgraph_api/js/tests/graphs/auth.mts,sha256=MS7pyla1bHRT5Ll-6-vxqcr6-kjbMorn4wG7LlMiOzg,3196
|
|
62
|
+
langgraph_api/js/tests/graphs/command.mts,sha256=HAliqio19XXSe4nTxKMCCIm7uUc0jPvvs6KUW16Cqhc,1164
|
|
63
|
+
langgraph_api/js/tests/graphs/delay.mts,sha256=LPZSex0AJO_Bcp1qtS6P92VRVN9rBZQQLBSsPUd6gOc,704
|
|
64
64
|
langgraph_api/js/tests/graphs/dynamic.mts,sha256=Wf_-keF7lkEfp_iyI45nlFGCeU8ARLQ8axc0LXh7TyE,659
|
|
65
65
|
langgraph_api/js/tests/graphs/error.mts,sha256=l4tk89449dj1BnEF_0ZcfPt0Ikk1gl8L1RaSnRfr3xo,487
|
|
66
66
|
langgraph_api/js/tests/graphs/http.mts,sha256=64xbMlLA58323zOX68Zh57zIB5Zl8ZCqEWRPNdJ-oJs,2171
|
|
67
67
|
langgraph_api/js/tests/graphs/langgraph.json,sha256=h6hV1wkNEUIpLBX9JOUKqtIBvbhvzyLEuWtBIHteseg,265
|
|
68
|
-
langgraph_api/js/tests/graphs/nested.mts,sha256=
|
|
68
|
+
langgraph_api/js/tests/graphs/nested.mts,sha256=e06kFzcX2zEJlb7e5B6kMnuZn6sfvsO7PCcYGkkV-8U,1248
|
|
69
69
|
langgraph_api/js/tests/graphs/package.json,sha256=8kgqWdZJCwekCqjsSrhbLrAPZ2vEy1DmcC8EQnwJMDU,262
|
|
70
|
-
langgraph_api/js/tests/graphs/weather.mts,sha256=
|
|
70
|
+
langgraph_api/js/tests/graphs/weather.mts,sha256=Gef9dCXxoVgNa4Ba0AcoptodYV85Ed2CGcleUB9BRMk,1656
|
|
71
71
|
langgraph_api/js/tests/graphs/yarn.lock,sha256=HDLJKx47Y-csPzA5eYUMVHWE8fMKrZgrc4SEkQAYYCE,11201
|
|
72
72
|
langgraph_api/js/tests/parser.test.mts,sha256=BBKUTveZnf-RI6B9XfTBLqy6tp84ddyu1tN3z041IAs,27900
|
|
73
|
-
langgraph_api/js/tests/utils.mts,sha256=
|
|
73
|
+
langgraph_api/js/tests/utils.mts,sha256=Jk1ZZmllNgSS6FJlSs9VaQxHqCEUzkqB5rRQwTSAOP4,441
|
|
74
74
|
langgraph_api/js/tsconfig.json,sha256=imCYqVnqFpaBoZPx8k1nO4slHIWBFsSlmCYhO73cpBs,341
|
|
75
75
|
langgraph_api/js/ui.py,sha256=XNT8iBcyT8XmbIqSQUWd-j_00HsaWB2vRTVabwFBkik,2439
|
|
76
76
|
langgraph_api/js/yarn.lock,sha256=OEj5JbffHe8opUAki0eH_0XJbVmgasv9zcHhGeI0g0w,84019
|
|
@@ -80,7 +80,7 @@ langgraph_api/middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
|
|
|
80
80
|
langgraph_api/middleware/http_logger.py,sha256=aj4mdisRobFePkD3Iy6-w_Mujwx4TQRaEhPvSd6HgLk,3284
|
|
81
81
|
langgraph_api/middleware/private_network.py,sha256=eYgdyU8AzU2XJu362i1L8aSFoQRiV7_aLBPw7_EgeqI,2111
|
|
82
82
|
langgraph_api/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
83
|
-
langgraph_api/models/run.py,sha256=
|
|
83
|
+
langgraph_api/models/run.py,sha256=5jfTrSvezstFzP1vSVMPgS2yYLePtZbvtnCFhcMf0v4,13167
|
|
84
84
|
langgraph_api/patch.py,sha256=Dgs0PXHytekX4SUL6KsjjN0hHcOtGLvv1GRGbh6PswU,1408
|
|
85
85
|
langgraph_api/queue_entrypoint.py,sha256=gjtajZfnDXhsi7JElfmkY-p0ENBiKBDJ4Ugiw-exapw,1839
|
|
86
86
|
langgraph_api/route.py,sha256=fM4qYCGbmH0a3_cV8uKocb1sLklehxO6HhdRXqLK6OM,4421
|
|
@@ -100,9 +100,9 @@ langgraph_license/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
|
|
|
100
100
|
langgraph_license/validation.py,sha256=ZKraAVJArAABKqrmHN-EN18ncoNUmRm500Yt1Sc7tUA,537
|
|
101
101
|
langgraph_runtime/__init__.py,sha256=O4GgSmu33c-Pr8Xzxj_brcK5vkm70iNTcyxEjICFZxA,1075
|
|
102
102
|
logging.json,sha256=3RNjSADZmDq38eHePMm1CbP6qZ71AmpBtLwCmKU9Zgo,379
|
|
103
|
-
openapi.json,sha256=
|
|
104
|
-
langgraph_api-0.1.
|
|
105
|
-
langgraph_api-0.1.
|
|
106
|
-
langgraph_api-0.1.
|
|
107
|
-
langgraph_api-0.1.
|
|
108
|
-
langgraph_api-0.1.
|
|
103
|
+
openapi.json,sha256=BMQQYQaTAvCCIqB5YSjriXRHmX9cVsWPWPNfEBs-_kA,133200
|
|
104
|
+
langgraph_api-0.2.1.dist-info/LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
|
|
105
|
+
langgraph_api-0.2.1.dist-info/METADATA,sha256=kwJldMbtg9R4-P56cwNUpX_S78I12S2xsfmWx0HfxBA,4235
|
|
106
|
+
langgraph_api-0.2.1.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
|
107
|
+
langgraph_api-0.2.1.dist-info/entry_points.txt,sha256=3EYLgj89DfzqJHHYGxPH4A_fEtClvlRbWRUHaXO7hj4,77
|
|
108
|
+
langgraph_api-0.2.1.dist-info/RECORD,,
|