mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-18 13:45:44 +02:00
Compare commits
1338
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d45253cee8 | ||
|
|
1377e3b6ba | ||
|
|
148cf52981 | ||
|
|
9010303245 | ||
|
|
3397d8908f | ||
|
|
e005f0472b | ||
|
|
18a1d60e45 | ||
|
|
5091d5e9fe | ||
|
|
da1fae0c72 | ||
|
|
7db81d72dc | ||
|
|
4ce387ee28 | ||
|
|
b902db686d | ||
|
|
16be48079e | ||
|
|
cf3a9ad63e | ||
|
|
547830ef24 | ||
|
|
d333e52fce | ||
|
|
15fe44ddf8 | ||
|
|
b6aff521e5 | ||
|
|
35ff9f5211 | ||
|
|
d690fc3e00 | ||
|
|
3325787af7 | ||
|
|
77a3cffa7f | ||
|
|
d1f2a6c518 | ||
|
|
b984584851 | ||
|
|
bce4545021 | ||
|
|
29c317887d | ||
|
|
84a0eca935 | ||
|
|
d9ed1ef52e | ||
|
|
fda79e00ce | ||
|
|
3163a60466 | ||
|
|
ac05955222 | ||
|
|
f3fe30380c | ||
|
|
2c5ddceeb1 | ||
|
|
98976e016a | ||
|
|
ea8025b719 | ||
|
|
735a76a16c | ||
|
|
a33437964c | ||
|
|
cb9405bcee | ||
|
|
bd2268404c | ||
|
|
25f88740c1 | ||
|
|
e9809ae9c1 | ||
|
|
69311a4135 | ||
|
|
bb3193c83e | ||
|
|
7a2eb614dc | ||
|
|
7fd6931200 | ||
|
|
cbca07e3db | ||
|
|
066525b335 | ||
|
|
a1dad43602 | ||
|
|
1e8f097656 | ||
|
|
db26c915a9 | ||
|
|
9b62280fc5 | ||
|
|
515ad8d7a6 | ||
|
|
d378f0e06a | ||
|
|
740870df65 | ||
|
|
6e20c9f3f9 | ||
|
|
530544234a | ||
|
|
f11d241482 | ||
|
|
e81979827f | ||
|
|
2064ea4793 | ||
|
|
16cfeff78c | ||
|
|
4321d337d6 | ||
|
|
d56e2545a6 | ||
|
|
9a3f96c459 | ||
|
|
cb509ad6a5 | ||
|
|
e479a2c643 | ||
|
|
0caae32a40 | ||
|
|
a6b8098548 | ||
|
|
0631f19ef9 | ||
|
|
e9b0bc4d3b | ||
|
|
eb19b80d13 | ||
|
|
e5ccdd91c2 | ||
|
|
871f15a630 | ||
|
|
32aa87d4b2 | ||
|
|
55a3352e9b | ||
|
|
6adaa6cf78 | ||
|
|
28172a2767 | ||
|
|
028137a51a | ||
|
|
c3847fae6c | ||
|
|
3daa4ae466 | ||
|
|
6a36f4bf91 | ||
|
|
04a0443742 | ||
|
|
3b224df566 | ||
|
|
0a2e2b4796 | ||
|
|
0e0b3ffac5 | ||
|
|
75509bd221 | ||
|
|
f997e5eafd | ||
|
|
6337c62dc7 | ||
|
|
59992fac7c | ||
|
|
28a7ca03a9 | ||
|
|
9fe61a42d2 | ||
|
|
59ae3b873c | ||
|
|
31ba5c41ac | ||
|
|
6ddbdd0638 | ||
|
|
3f7f52ccdc | ||
|
|
ee9a34f726 | ||
|
|
72ce34e3e6 | ||
|
|
098d5ec403 | ||
|
|
45ef425d85 | ||
|
|
8c192414a2 | ||
|
|
c0db7f4d09 | ||
|
|
072f2d43eb | ||
|
|
c02a74e221 | ||
|
|
15af8a9e6c | ||
|
|
1b257b4d0a | ||
|
|
384814036e | ||
|
|
d5b0ad2cf6 | ||
|
|
8d8e514924 | ||
|
|
a37c4d6f49 | ||
|
|
4b3e07b67a | ||
|
|
6ba61cc768 | ||
|
|
5a79210904 | ||
|
|
4a60eaf32f | ||
|
|
cf7c3e7fd1 | ||
|
|
141b53ee6e | ||
|
|
37e8e00f1f | ||
|
|
a0ec9017f2 | ||
|
|
80cef60405 | ||
|
|
46cba763be | ||
|
|
830e5f4550 | ||
|
|
55e9409b6e | ||
|
|
39e65a1a62 | ||
|
|
82148e9bf2 | ||
|
|
ed09a77d9f | ||
|
|
7e267897c9 | ||
|
|
d279902156 | ||
|
|
440158b969 | ||
|
|
0cf3a64d66 | ||
|
|
953e2907d4 | ||
|
|
0a861815b7 | ||
|
|
928126f2d7 | ||
|
|
0d8fea847a | ||
|
|
b4dc3a851f | ||
|
|
7568862013 | ||
|
|
69dc5f326e | ||
|
|
90f1e66748 | ||
|
|
a910a1a341 | ||
|
|
554e763994 | ||
|
|
adff1df813 | ||
|
|
64b828def6 | ||
|
|
9196cc2da8 | ||
|
|
e13a8bc320 | ||
|
|
4b5b309152 | ||
|
|
9d5166a0d3 | ||
|
|
5b11683f4e | ||
|
|
3fae8d47c3 | ||
|
|
be9cb03dfa | ||
|
|
6926c4bcc0 | ||
|
|
c04802a344 | ||
|
|
cf7f6691cf | ||
|
|
e1140f4fad | ||
|
|
ae8afb7677 | ||
|
|
48040d8ea5 | ||
|
|
ad51bfdf71 | ||
|
|
996b120613 | ||
|
|
1093dd55c8 | ||
|
|
d794875b32 | ||
|
|
6948cf5eb8 | ||
|
|
bacc2955ae | ||
|
|
f014d96d1c | ||
|
|
7b552ebf4b | ||
|
|
1e61ddfdbe | ||
|
|
d34846dc08 | ||
|
|
06823e327f | ||
|
|
1059ef55d1 | ||
|
|
39552255c8 | ||
|
|
38bbe67469 | ||
|
|
6335963674 | ||
|
|
8a4c452317 | ||
|
|
5dc5853161 | ||
|
|
9e066554ba | ||
|
|
6ce9354ee4 | ||
|
|
211fd4337d | ||
|
|
44bf97ac0e | ||
|
|
23c73ae719 | ||
|
|
4165d479e9 | ||
|
|
c43a9a4bd0 | ||
|
|
c9613927dc | ||
|
|
c697c2aa04 | ||
|
|
3f2557c9c9 | ||
|
|
cbad17fa7d | ||
|
|
17dacb83a2 | ||
|
|
3a997be088 | ||
|
|
020d10138d | ||
|
|
303587c4ff | ||
|
|
7d4e636313 | ||
|
|
86913caf89 | ||
|
|
041faefe29 | ||
|
|
b704cf30cc | ||
|
|
3915b44180 | ||
|
|
ac1407b23c | ||
|
|
44840aa23f | ||
|
|
51242e2a32 | ||
|
|
b358e2e7cd | ||
|
|
0d91ab1474 | ||
|
|
12ae297194 | ||
|
|
0177565c6b | ||
|
|
c48d495031 | ||
|
|
22e6468af5 | ||
|
|
24bc0c0630 | ||
|
|
802e6df8df | ||
|
|
3ec55b008d | ||
|
|
e10b7c1391 | ||
|
|
31cc6b9f1d | ||
|
|
2cafb4905b | ||
|
|
fe46576d98 | ||
|
|
16c86c9de6 | ||
|
|
fca0d2d5bb | ||
|
|
c7c62f5587 | ||
|
|
956c5f68fc | ||
|
|
4908caf522 | ||
|
|
f926eada24 | ||
|
|
adc1e47028 | ||
|
|
7820b5c765 | ||
|
|
ca6f8e2042 | ||
|
|
ee61d06f8d | ||
|
|
6eeb9de46a | ||
|
|
19a91f4677 | ||
|
|
6087b1969e | ||
|
|
6cbc7e8b67 | ||
|
|
b2213e523e | ||
|
|
ac64f50383 | ||
|
|
25239891bc | ||
|
|
b7c3ac4501 | ||
|
|
09e8516689 | ||
|
|
3ca75d69b8 | ||
|
|
d48dec5452 | ||
|
|
d48b25420b | ||
|
|
12be3fac33 | ||
|
|
aed1f0ba18 | ||
|
|
07695f5c5a | ||
|
|
204c9c83f8 | ||
|
|
0bdd27ade4 | ||
|
|
ab0048981a | ||
|
|
e18f2b3795 | ||
|
|
31578cbe0e | ||
|
|
44970640d5 | ||
|
|
0f4e42474f | ||
|
|
832f9ad64e | ||
|
|
318de5bb81 | ||
|
|
a11f9b3535 | ||
|
|
29db5a8672 | ||
|
|
444faec6e6 | ||
|
|
e4a5c8fd28 | ||
|
|
0f1b0bfba3 | ||
|
|
0e79407973 | ||
|
|
efa51fe22c | ||
|
|
11f2501c98 | ||
|
|
71e6002a3c | ||
|
|
26e3ded701 | ||
|
|
4fcd1690f9 | ||
|
|
eb33a873c8 | ||
|
|
91aa66f4cf | ||
|
|
4476640702 | ||
|
|
727e3f1730 | ||
|
|
943dd28863 | ||
|
|
aa9d253978 | ||
|
|
a11c6cfe6b | ||
|
|
15c79dc3c3 | ||
|
|
a65c9f1e04 | ||
|
|
9912ae1053 | ||
|
|
7db29042b4 | ||
|
|
f8033a20c1 | ||
|
|
5e3aa495d9 | ||
|
|
a54689affd | ||
|
|
02ea523897 | ||
|
|
18c6637e6c | ||
|
|
4c02a4c501 | ||
|
|
784b6afa11 | ||
|
|
b35b892d74 | ||
|
|
e7aaf21121 | ||
|
|
54115ac796 | ||
|
|
76be64adcb | ||
|
|
2cf98725c4 | ||
|
|
a33c59626a | ||
|
|
56d3b759c7 | ||
|
|
32bf81c559 | ||
|
|
de332ec31c | ||
|
|
ce30965df4 | ||
|
|
b98a7b09a3 | ||
|
|
86b6afc982 | ||
|
|
47122ce88b | ||
|
|
002b048674 | ||
|
|
a58f5dacca | ||
|
|
cc397b1629 | ||
|
|
3a48049194 | ||
|
|
e5f0db0af3 | ||
|
|
93854ed721 | ||
|
|
83a7acc57c | ||
|
|
b218cc76a7 | ||
|
|
d021f476db | ||
|
|
d978cb0392 | ||
|
|
605fe4ea11 | ||
|
|
46907b6cf9 | ||
|
|
582856b30c | ||
|
|
e476897177 | ||
|
|
421f7c0238 | ||
|
|
3095bfce9c | ||
|
|
4cfe0b2d4c | ||
|
|
a16def5140 | ||
|
|
1e730d124c | ||
|
|
21a7105655 | ||
|
|
8c88e203bc | ||
|
|
2a1224966c | ||
|
|
c4460e5dd2 | ||
|
|
46056363b3 | ||
|
|
ba672604a6 | ||
|
|
8b1597a385 | ||
|
|
adff439d4e | ||
|
|
89b0be3a7d | ||
|
|
7ecda42b42 | ||
|
|
bd99471705 | ||
|
|
0e4dbb4c62 | ||
|
|
145220f2a8 | ||
|
|
f9c25bba07 | ||
|
|
7ecad39ecb | ||
|
|
6bfc6be307 | ||
|
|
6b9369876f | ||
|
|
c26b0e78b6 | ||
|
|
1763dd69a7 | ||
|
|
f4bd023ab1 | ||
|
|
d402bf7379 | ||
|
|
e8a73e1505 | ||
|
|
d6492ef048 | ||
|
|
38d9b39f6e | ||
|
|
be8b4a1d7f | ||
|
|
71fbd6a8b4 | ||
|
|
5375af7827 | ||
|
|
1654062957 | ||
|
|
6b707cbfc5 | ||
|
|
dd7ac00953 | ||
|
|
cd64075928 | ||
|
|
144ee31546 | ||
|
|
8bb84c7096 | ||
|
|
e83660885b | ||
|
|
c2a57385c0 | ||
|
|
3626478029 | ||
|
|
30311f3fb9 | ||
|
|
0f458fbaff | ||
|
|
13c9bfa282 | ||
|
|
b6fe3937fc | ||
|
|
d7bae594f0 | ||
|
|
5805e5709a | ||
|
|
aab6fdf3f3 | ||
|
|
be1d035aba | ||
|
|
6e228f8a9c | ||
|
|
0adbd89d9a | ||
|
|
47c37d140f | ||
|
|
fc887f7a5d | ||
|
|
bbfc2b7370 | ||
|
|
2c984dfe4e | ||
|
|
09c0d9cec3 | ||
|
|
31734fb792 | ||
|
|
eed577ee2a | ||
|
|
bba00506ea | ||
|
|
fa12538a4e | ||
|
|
c1a7bb8902 | ||
|
|
14b500d8a8 | ||
|
|
053a501db3 | ||
|
|
bbe8eacf8d | ||
|
|
931d39124c | ||
|
|
a7bb96da98 | ||
|
|
1e9a372dd7 | ||
|
|
5030f1e89c | ||
|
|
50cb387904 | ||
|
|
003b1883c9 | ||
|
|
17aebb6239 | ||
|
|
d12830e95c | ||
|
|
29b70cbf39 | ||
|
|
6b86fbb0a8 | ||
|
|
4426552c26 | ||
|
|
671f268651 | ||
|
|
e2554c9616 | ||
|
|
f1ee650489 | ||
|
|
b7e4656c91 | ||
|
|
65a41942ef | ||
|
|
c767d86c9c | ||
|
|
01331ef858 | ||
|
|
24a4c67c52 | ||
|
|
c7e43f86d4 | ||
|
|
b18d266f2c | ||
|
|
536ee7b37a | ||
|
|
901273c0e2 | ||
|
|
7bdbd62611 | ||
|
|
0b74e25f72 | ||
|
|
ff843ab005 | ||
|
|
7603809a9f | ||
|
|
f7fae7e140 | ||
|
|
651ee8bd24 | ||
|
|
54bdba2da9 | ||
|
|
7e5806cb0b | ||
|
|
66f674fead | ||
|
|
f029d615e6 | ||
|
|
bd76773b31 | ||
|
|
311fe3970c | ||
|
|
67a800dd98 | ||
|
|
9b6e6d67dc | ||
|
|
ecfb3e3850 | ||
|
|
ec71cd6fc1 | ||
|
|
aab4f0b164 | ||
|
|
2db6d9d7b5 | ||
|
|
5db71a32bf | ||
|
|
0f5df797af | ||
|
|
4c0f855329 | ||
|
|
5dc3f14e8b | ||
|
|
f25ea9ecaf | ||
|
|
9940a9f833 | ||
|
|
d175d5e4a8 | ||
|
|
74adbb744b | ||
|
|
fe63440d98 | ||
|
|
2f47d98b34 | ||
|
|
b989502c24 | ||
|
|
8507dc33f0 | ||
|
|
0d50c62283 | ||
|
|
a9073241b2 | ||
|
|
0a04262f05 | ||
|
|
381796c474 | ||
|
|
a11ba2b38a | ||
|
|
09ae5ce05d | ||
|
|
59e7751a8c | ||
|
|
a61ea101f6 | ||
|
|
b9816e31ff | ||
|
|
3ea7f9469a | ||
|
|
24e61fafa9 | ||
|
|
b52b32b38e | ||
|
|
5aefa5dc8c | ||
|
|
c86155d3d3 | ||
|
|
2b370cf3b7 | ||
|
|
839bea0f33 | ||
|
|
a03f1f7469 | ||
|
|
d7199e5874 | ||
|
|
61f2151df7 | ||
|
|
713528ffc3 | ||
|
|
7bd79c2509 | ||
|
|
9974787df6 | ||
|
|
638712a73b | ||
|
|
b8a54f6294 | ||
|
|
f2913fbcb6 | ||
|
|
cfb121ee8f | ||
|
|
d27beeed18 | ||
|
|
8045e89e09 | ||
|
|
8355a1720a | ||
|
|
c302724394 | ||
|
|
c624ff69e1 | ||
|
|
10d46acc60 | ||
|
|
35c3ba0104 | ||
|
|
0e2cd9e289 | ||
|
|
f4bd02da72 | ||
|
|
ecfbfa1b90 | ||
|
|
e5b5f9510b | ||
|
|
c6d7c80a99 | ||
|
|
fba5ca7ab9 | ||
|
|
909190cede | ||
|
|
43c8578eef | ||
|
|
56f5edb9ba | ||
|
|
41f0fd504e | ||
|
|
f141089811 | ||
|
|
38487cb158 | ||
|
|
6357d496af | ||
|
|
52bd5b13a7 | ||
|
|
b633e0a4ed | ||
|
|
c14bcb6e9f | ||
|
|
8b29dc81e0 | ||
|
|
1546eddfbe | ||
|
|
9680e35beb | ||
|
|
837f215857 | ||
|
|
e13261ac0a | ||
|
|
8ab206043c | ||
|
|
8534212a25 | ||
|
|
e39255a792 | ||
|
|
3dbe37041a | ||
|
|
e00284b386 | ||
|
|
a36d2ac77d | ||
|
|
2a46534286 | ||
|
|
4b06791b8c | ||
|
|
661e20eec4 | ||
|
|
a486eb5e75 | ||
|
|
e9d62944d3 | ||
|
|
cbd09abe58 | ||
|
|
4798443e31 | ||
|
|
ce900864fa | ||
|
|
577f95bd50 | ||
|
|
59a11c63b0 | ||
|
|
08098688d4 | ||
|
|
687ee02509 | ||
|
|
451bc038b6 | ||
|
|
c865e8c070 | ||
|
|
d74ec2c2de | ||
|
|
f70bfc6d87 | ||
|
|
c86f0af107 | ||
|
|
c6ee807de5 | ||
|
|
7256752f48 | ||
|
|
dac84951aa | ||
|
|
3aaa3e38a0 | ||
|
|
400d83708a | ||
|
|
1d9c7ef461 | ||
|
|
01e5ecedfd | ||
|
|
76199701b0 | ||
|
|
2766fccb5b | ||
|
|
6aef3e0117 | ||
|
|
c5023ba147 | ||
|
|
9a9fe2fdec | ||
|
|
effddca494 | ||
|
|
2ab59840e7 | ||
|
|
0fb65f6e67 | ||
|
|
0ecd23eec6 | ||
|
|
e137dabf22 | ||
|
|
fdc1e47aa1 | ||
|
|
866780b477 | ||
|
|
18d3fa2e15 | ||
|
|
4b0c53fb5c | ||
|
|
5183484322 | ||
|
|
8213e4719b | ||
|
|
f993dfcfcb | ||
|
|
9e31b82d8d | ||
|
|
a3c5b8fc37 | ||
|
|
1e0aebc3ec | ||
|
|
056f581342 | ||
|
|
a0d7323bec | ||
|
|
44ee0199fd | ||
|
|
1de61f6fce | ||
|
|
f33db6cec4 | ||
|
|
c72107177b | ||
|
|
f520a38d30 | ||
|
|
d0278f520c | ||
|
|
506539ac9d | ||
|
|
d6c6516f16 | ||
|
|
6f5d6d9993 | ||
|
|
8dcd058404 | ||
|
|
e3050b3a3e | ||
|
|
9e767afad7 | ||
|
|
62b35277ec | ||
|
|
931419909b | ||
|
|
e849c869cc | ||
|
|
5a580ae5ec | ||
|
|
47a0e09513 | ||
|
|
f37486efe2 | ||
|
|
fa61be9fbc | ||
|
|
08097a78bd | ||
|
|
43f610e9a6 | ||
|
|
aa1ddee67e | ||
|
|
12b46e8a69 | ||
|
|
d90f69105a | ||
|
|
fbd3b67183 | ||
|
|
6d8be543e7 | ||
|
|
1c1772f7ec | ||
|
|
ce239c784a | ||
|
|
c14c978824 | ||
|
|
ebb2823be0 | ||
|
|
25f0224f97 | ||
|
|
fdf9b0ad48 | ||
|
|
00ecccfd81 | ||
|
|
7d5452d039 | ||
|
|
2d8de54e80 | ||
|
|
32abc62bc1 | ||
|
|
e36cf4111d | ||
|
|
53a2c2bdcd | ||
|
|
2cae9337a7 | ||
|
|
b056e17b38 | ||
|
|
2855caa3eb | ||
|
|
140566e662 | ||
|
|
b7f57b1375 | ||
|
|
121c5863db | ||
|
|
1709cd3fb5 | ||
|
|
d4a1fe5a03 | ||
|
|
06e1e4ed12 | ||
|
|
1e62b175ba | ||
|
|
f89fe49f99 | ||
|
|
2e1971baf3 | ||
|
|
948027aef2 | ||
|
|
6954e63671 | ||
|
|
7f0bfdc139 | ||
|
|
0496128e6b | ||
|
|
d79b1a61e8 | ||
|
|
e227f6ce83 | ||
|
|
8a1a11fde5 | ||
|
|
c47fd171c6 | ||
|
|
1e07a9ac97 | ||
|
|
d9cc227e75 | ||
|
|
6b45a281c1 | ||
|
|
532bc71c11 | ||
|
|
dabd75f1f9 | ||
|
|
ef88b805a7 | ||
|
|
7e8a68f0f0 | ||
|
|
e20bd15580 | ||
|
|
51c57cc819 | ||
|
|
09a6450eed | ||
|
|
77fba7a571 | ||
|
|
60232eadc4 | ||
|
|
83e4e6c4c2 | ||
|
|
a6f0c665af | ||
|
|
f1a2e19144 | ||
|
|
b28e9d0a87 | ||
|
|
b3230cf6d1 | ||
|
|
1a6c3114f3 | ||
|
|
4f1bf4fa7a | ||
|
|
22fa673872 | ||
|
|
3d85f2296c | ||
|
|
5ad9cfa030 | ||
|
|
39281c866d | ||
|
|
4c3a38d324 | ||
|
|
8fc3f204ea | ||
|
|
2df2f41dc7 | ||
|
|
30e647abce | ||
|
|
b85c9961d7 | ||
|
|
1c97bddc14 | ||
|
|
97b3d1b9ac | ||
|
|
8b70da6a0f | ||
|
|
7904fdc928 | ||
|
|
ba56ba1b2a | ||
|
|
12f2a480cd | ||
|
|
532cb0a691 | ||
|
|
23e18e8c1b | ||
|
|
6d160a2865 | ||
|
|
e0b4eb6454 | ||
|
|
608ff41e78 | ||
|
|
9280e3411b | ||
|
|
36fa8e0097 | ||
|
|
f63217794d | ||
|
|
bcb11640a5 | ||
|
|
b6c3a0d0fd | ||
|
|
8b14b6a9f0 | ||
|
|
8c63cc1778 | ||
|
|
6756e91ffc | ||
|
|
3dd1e67977 | ||
|
|
fc5d919aee | ||
|
|
0369300160 | ||
|
|
245cf83b20 | ||
|
|
9bd351b80f | ||
|
|
83c3f86159 | ||
|
|
3a41a2addc | ||
|
|
3eca363c23 | ||
|
|
2f1e864570 | ||
|
|
79a1ce6804 | ||
|
|
deb99a9acb | ||
|
|
781d0cf27a | ||
|
|
8a02ddd868 | ||
|
|
5f7dcbb07a | ||
|
|
9615580a66 | ||
|
|
d45eb0f9f2 | ||
|
|
4caa483478 | ||
|
|
006305f6a8 | ||
|
|
d9b7aaa5cc | ||
|
|
d2794eda0a | ||
|
|
9cbef9b542 | ||
|
|
343dc2d37a | ||
|
|
ca0ff1d334 | ||
|
|
f5663ffa49 | ||
|
|
e7477a9315 | ||
|
|
18c083b60a | ||
|
|
2f0e3c66d1 | ||
|
|
d9ec185e72 | ||
|
|
721945b5ce | ||
|
|
87fba0ecd0 | ||
|
|
30e6b5482f | ||
|
|
77b42e0867 | ||
|
|
cbe92e3e55 | ||
|
|
70f2efc9a1 | ||
|
|
dbf5b4920e | ||
|
|
9291ae8646 | ||
|
|
2713082707 | ||
|
|
89eb938b30 | ||
|
|
26e97492b7 | ||
|
|
4c3958f0be | ||
|
|
980b592631 | ||
|
|
e494869c72 | ||
|
|
da0aac7556 | ||
|
|
a200027cda | ||
|
|
8cd57f7457 | ||
|
|
26c1f1ee7a | ||
|
|
33af251a09 | ||
|
|
17dc588c81 | ||
|
|
258060593b | ||
|
|
fbe513835f | ||
|
|
f319b1e107 | ||
|
|
cbb7348998 | ||
|
|
2d8246e7c4 | ||
|
|
e5ea4f51c7 | ||
|
|
a031f8294e | ||
|
|
7d940a4a96 | ||
|
|
6ae0c83c83 | ||
|
|
083a14c2c5 | ||
|
|
e4db5c2ca4 | ||
|
|
1d2b50e438 | ||
|
|
5146c9fcdf | ||
|
|
e8a2f7ef92 | ||
|
|
0400c5236e | ||
|
|
67f96063e2 | ||
|
|
44cdbc781f | ||
|
|
f642fb6545 | ||
|
|
ff3bc2f982 | ||
|
|
e1925a8dcb | ||
|
|
fe83a151bb | ||
|
|
d18c9449ec | ||
|
|
12a15c3cb4 | ||
|
|
189358cb91 | ||
|
|
d16004c0b6 | ||
|
|
fdf19a5be9 | ||
|
|
d24ce62c3f | ||
|
|
3ffed8d38d | ||
|
|
25d4512744 | ||
|
|
630195a108 | ||
|
|
475e16b8ed | ||
|
|
32702dea08 | ||
|
|
3db266bb93 | ||
|
|
11ce54d7e4 | ||
|
|
54a5e45d21 | ||
|
|
0ad470162c | ||
|
|
37436c5cd6 | ||
|
|
7f48428d16 | ||
|
|
d9c0a5d827 | ||
|
|
6907d1b775 | ||
|
|
bec3055561 | ||
|
|
2f535a803c | ||
|
|
fbb11a6d2e | ||
|
|
3f348e3268 | ||
|
|
6b80fa6718 | ||
|
|
82fa597e84 | ||
|
|
f6c44ec154 | ||
|
|
a03900be7a | ||
|
|
7144f7db41 | ||
|
|
8f1db66c17 | ||
|
|
c2556aa2fe | ||
|
|
d468655f62 | ||
|
|
6153c777fb | ||
|
|
a4d49b4e77 | ||
|
|
789c732866 | ||
|
|
51f85ffa84 | ||
|
|
31dd6c65a9 | ||
|
|
cb225dde7f | ||
|
|
0cb530e588 | ||
|
|
f0f3e11b0e | ||
|
|
55fbff89f4 | ||
|
|
327bb369d7 | ||
|
|
30eb2d00e2 | ||
|
|
45d1033092 | ||
|
|
5a0ae2157c | ||
|
|
e001b7a35f | ||
|
|
a41b9bb83c | ||
|
|
04f6a6ccd1 | ||
|
|
ce15790210 | ||
|
|
04b76f55a0 | ||
|
|
f52a8728ff | ||
|
|
686ee31b75 | ||
|
|
47dcb2d105 | ||
|
|
3a611fb20d | ||
|
|
baa88f3c97 | ||
|
|
79aa88812d | ||
|
|
81436ceef8 | ||
|
|
2b70dba0e0 | ||
|
|
e14a6cf98b | ||
|
|
dc0398efd1 | ||
|
|
02f1904ba7 | ||
|
|
30f852e7b2 | ||
|
|
7fc6c4b1fa | ||
|
|
7f8ec2c590 | ||
|
|
611588613d | ||
|
|
11e80210a2 | ||
|
|
60d742ea48 | ||
|
|
a7ac9ffd4e | ||
|
|
3d97b97c86 | ||
|
|
a7d1ecbb74 | ||
|
|
61f362f16e | ||
|
|
7cabc0a3dc | ||
|
|
f9cdfd3ac4 | ||
|
|
dd778f8ed6 | ||
|
|
df5d08f689 | ||
|
|
a9b94f93ee | ||
|
|
5f869b9e75 | ||
|
|
79562f3f37 | ||
|
|
081b2cbdcf | ||
|
|
70eeb2a670 | ||
|
|
0f287d986b | ||
|
|
1fd9da6718 | ||
|
|
ef6c5b4711 | ||
|
|
77fe51fbe4 | ||
|
|
70a5ef6713 | ||
|
|
17c1a8db46 | ||
|
|
97a51014c3 | ||
|
|
5a30fc6a87 | ||
|
|
1f68bd0d83 | ||
|
|
fdfc5d9cda | ||
|
|
1c3f65c931 | ||
|
|
a9f5507006 | ||
|
|
59bfa5d009 | ||
|
|
b4f11929f8 | ||
|
|
038bec2e78 | ||
|
|
01cdb60b5d | ||
|
|
5bfb9af5fe | ||
|
|
ac48612abb | ||
|
|
73fb725f0c | ||
|
|
b98a1337a5 | ||
|
|
c2a41039de | ||
|
|
33fe467d1f | ||
|
|
43b6c06f5c | ||
|
|
d81dec653d | ||
|
|
e1d8c6b113 | ||
|
|
a64f9f80c0 | ||
|
|
a879de51f1 | ||
|
|
60ab76c3e9 | ||
|
|
09e9117674 | ||
|
|
acac19b95b | ||
|
|
723bcfeaa2 | ||
|
|
c279421cbf | ||
|
|
df1e48154a | ||
|
|
d0bf7837bd | ||
|
|
a403e802fa | ||
|
|
e0a0958a60 | ||
|
|
3f1bdb9ebf | ||
|
|
b37c9d8a01 | ||
|
|
1af1911aad | ||
|
|
b4f7e06a1d | ||
|
|
1dda28f8fb | ||
|
|
cc4718c5cb | ||
|
|
0d580bdac7 | ||
|
|
a19d06e18c | ||
|
|
e16312da3f | ||
|
|
6784a5a5b1 | ||
|
|
4e0e9a4eff | ||
|
|
015bf5e0a6 | ||
|
|
85fc26db43 | ||
|
|
5fa80e2a92 | ||
|
|
5e13460604 | ||
|
|
750b97349e | ||
|
|
6230c46830 | ||
|
|
93e4c8cc1f | ||
|
|
b7e441d781 | ||
|
|
ccd8920eef | ||
|
|
0c379d6cc7 | ||
|
|
01b1080b6e | ||
|
|
62ff2eb32d | ||
|
|
1f745ca017 | ||
|
|
aa4fea48dd | ||
|
|
4fd261765a | ||
|
|
0f0e31df24 | ||
|
|
a275ab26d3 | ||
|
|
b3bf4dd43c | ||
|
|
b7fd391811 | ||
|
|
cf961a286c | ||
|
|
4b83103cf2 | ||
|
|
1a46537c3a | ||
|
|
0a49f3003b | ||
|
|
e80098e297 | ||
|
|
3d3647cd85 | ||
|
|
291379dfb9 | ||
|
|
9f93e48a67 | ||
|
|
de123d66a5 | ||
|
|
759a712f57 | ||
|
|
9f73dfa8d5 | ||
|
|
4459952e72 | ||
|
|
8ef82f3578 | ||
|
|
73e3f5a5b0 | ||
|
|
a54587cff5 | ||
|
|
63ea71548b | ||
|
|
f32cf5e984 | ||
|
|
d1aaa9de8c | ||
|
|
f40a2d71ec | ||
|
|
b5a9e9da55 | ||
|
|
1eeb90ae0d | ||
|
|
cd875291ad | ||
|
|
e9cd216887 | ||
|
|
7651f1ab1c | ||
|
|
1a492f727c | ||
|
|
6caaa8cea7 | ||
|
|
f028984b2e | ||
|
|
085395c824 | ||
|
|
19a6e894eb | ||
|
|
5570121c83 | ||
|
|
257e44ccb4 | ||
|
|
dad0f39fa4 | ||
|
|
7a326ef768 | ||
|
|
2fa2469967 | ||
|
|
de86a46b3d | ||
|
|
9733db03c5 | ||
|
|
e1f65012e6 | ||
|
|
eb593d47dd | ||
|
|
4e8f4ce440 | ||
|
|
007d7e72b1 | ||
|
|
2b77fdabee | ||
|
|
40d16593c7 | ||
|
|
ec7bbe14b2 | ||
|
|
4c6323c585 | ||
|
|
2fe38f3940 | ||
|
|
09ca964714 | ||
|
|
0663d46c47 | ||
|
|
a91dbf9b70 | ||
|
|
d93be914c7 | ||
|
|
287c29fbdc | ||
|
|
90dd2b01b6 | ||
|
|
a443b3b256 | ||
|
|
2e9aea6fc8 | ||
|
|
2895a69678 | ||
|
|
76a209835f | ||
|
|
872f54adf1 | ||
|
|
01a3c23a29 | ||
|
|
0461d45d76 | ||
|
|
7d8205633d | ||
|
|
797b919cf9 | ||
|
|
574ffb02fc | ||
|
|
771b9b28cd | ||
|
|
dcc2617396 | ||
|
|
df70e91dae | ||
|
|
b4b3ac6f57 | ||
|
|
78e6b36b1a | ||
|
|
d457ad3cc2 | ||
|
|
5c7a6689af | ||
|
|
fb01d65dc0 | ||
|
|
c75bfc1032 | ||
|
|
6dc70b703d | ||
|
|
eb09909c22 | ||
|
|
ea5ccd7a80 | ||
|
|
d52bb911a4 | ||
|
|
89a739e12b | ||
|
|
0fdf3c9daf | ||
|
|
90eab07ded | ||
|
|
962a969fba | ||
|
|
c89e84fb6a | ||
|
|
3ff1f81333 | ||
|
|
851e6d1d4c | ||
|
|
e5e659c590 | ||
|
|
8db6a78ad9 | ||
|
|
9ab5fbc0f8 | ||
|
|
c141f0fdf0 | ||
|
|
830557d6b7 | ||
|
|
e5b00cdd1e | ||
|
|
8eea7ac401 | ||
|
|
c322f7ffa6 | ||
|
|
e6c83abecd | ||
|
|
a8db511e24 | ||
|
|
84d33f9621 | ||
|
|
9220049b35 | ||
|
|
879df6b52c | ||
|
|
9b8bf70d9e | ||
|
|
aca67107c1 | ||
|
|
5fa196ab38 | ||
|
|
584d9271ce | ||
|
|
1bee33db3a | ||
|
|
a203ddecf7 | ||
|
|
5e3c326424 | ||
|
|
86407aa6e8 | ||
|
|
7a80d6cb87 | ||
|
|
70f323779e | ||
|
|
23d5162945 | ||
|
|
9d755f54e4 | ||
|
|
75cccc4fc4 | ||
|
|
dd010e9230 | ||
|
|
2d87195b59 | ||
|
|
515242d0ba | ||
|
|
3bf92d0b03 | ||
|
|
36b6cd1493 | ||
|
|
0361554fcf | ||
|
|
4332a9515d | ||
|
|
64b99c187a | ||
|
|
afa37d2059 | ||
|
|
b80933c5fb | ||
|
|
d70b659adb | ||
|
|
15f0765d60 | ||
|
|
fe538d4bcb | ||
|
|
4e26a5cf2e | ||
|
|
20f091a277 | ||
|
|
0071bd1e1c | ||
|
|
d36e6ceaaf | ||
|
|
a3feaef2eb | ||
|
|
c6fe26510e | ||
|
|
efbd02a27d | ||
|
|
a91bf116cb | ||
|
|
6a6c3ed84c | ||
|
|
988dd237d2 | ||
|
|
63f5f15c04 | ||
|
|
6fc1c602ab | ||
|
|
2b65308508 | ||
|
|
3cee1d5087 | ||
|
|
2ce2021c39 | ||
|
|
46dd424a7e | ||
|
|
363c6e2e4c | ||
|
|
784821705b | ||
|
|
65172c2a43 | ||
|
|
1130c3accb | ||
|
|
ee8653d1c5 | ||
|
|
12486d977a | ||
|
|
c87f9ab6b1 | ||
|
|
855a3d21ff | ||
|
|
d767af421b | ||
|
|
07ac016e60 | ||
|
|
4576a259dd | ||
|
|
53ec7c41b2 | ||
|
|
769f6a1925 | ||
|
|
62a36befd5 | ||
|
|
dfaff2511b | ||
|
|
1d9a0d1e4e | ||
|
|
35c7eb18ee | ||
|
|
dc09b13400 | ||
|
|
b2d8acffc4 | ||
|
|
1031e54860 | ||
|
|
7ac365ea84 | ||
|
|
5144b8f374 | ||
|
|
f4a9d17d24 | ||
|
|
f416480e9d | ||
|
|
61e47cb137 | ||
|
|
d4bbb66963 | ||
|
|
4b1b3cecb4 | ||
|
|
c6a953c02a | ||
|
|
16b955dee2 | ||
|
|
877124f7df | ||
|
|
d3a4865c0e | ||
|
|
45b5f386e5 | ||
|
|
a1ec55abc5 | ||
|
|
a3761ac522 | ||
|
|
376c58ff3b | ||
|
|
58b99c899e | ||
|
|
2ee279a977 | ||
|
|
f04ce5d1ee | ||
|
|
8f649abd0a | ||
|
|
1febec7c0d | ||
|
|
a4eb4c6942 | ||
|
|
8e1cd0e225 | ||
|
|
98935e1ffd | ||
|
|
328ef609af | ||
|
|
486d5412af | ||
|
|
abc0c8c223 | ||
|
|
5bbb9dae57 | ||
|
|
fed60e713c | ||
|
|
4f4e7a6981 | ||
|
|
f08155d60b | ||
|
|
24b16908b7 | ||
|
|
c1c2ce8f1b | ||
|
|
3efd4f3406 | ||
|
|
f122ae2eb1 | ||
|
|
3351d4f6c5 | ||
|
|
b4900341e4 | ||
|
|
05791f5dfc | ||
|
|
416dfe95da | ||
|
|
65f515e020 | ||
|
|
0d0665a6e3 | ||
|
|
93b8525dc1 | ||
|
|
aeb6f784e1 | ||
|
|
3eedeac0d4 | ||
|
|
b09e7b20b0 | ||
|
|
26ce731eab | ||
|
|
55593446f8 | ||
|
|
2d6ddd0a1d | ||
|
|
7082e2613e | ||
|
|
ceeb9636ee | ||
|
|
f7788abbb6 | ||
|
|
9bd430142a | ||
|
|
72dac006f4 | ||
|
|
54d848913f | ||
|
|
7021e81150 | ||
|
|
b977045679 | ||
|
|
a933776436 | ||
|
|
588373c2d5 | ||
|
|
267962bece | ||
|
|
4ae29b6e2a | ||
|
|
3c0de26914 | ||
|
|
a570662773 | ||
|
|
9766068896 | ||
|
|
7e8eef88ca | ||
|
|
e3e63c70c9 | ||
|
|
312f0982bc | ||
|
|
153245145e | ||
|
|
c95abd88a1 | ||
|
|
a2b357bed5 | ||
|
|
253090f34d | ||
|
|
7090d7e9a8 | ||
|
|
b3fa43e4a6 | ||
|
|
b1779cf348 | ||
|
|
26d18d3ca5 | ||
|
|
7d80176137 | ||
|
|
ca7da2fc41 | ||
|
|
12052d7d26 | ||
|
|
e3a30a9b69 | ||
|
|
ff1370a9a5 | ||
|
|
679a7365da | ||
|
|
b2522ffe19 | ||
|
|
4212a795a0 | ||
|
|
517d67aa32 | ||
|
|
feaf14765a | ||
|
|
cc6063c729 | ||
|
|
013397042e | ||
|
|
9a775d9c9f | ||
|
|
2c945ceb68 | ||
|
|
39eabd0fb8 | ||
|
|
e5cc2e2044 | ||
|
|
f00c0515e7 | ||
|
|
d87c0d4d53 | ||
|
|
fb40a974c8 | ||
|
|
d63bfc6879 | ||
|
|
97dd30711a | ||
|
|
016a9c1936 | ||
|
|
a2d6837fba | ||
|
|
f5bb2a3b04 | ||
|
|
f807b73092 | ||
|
|
167405daf2 | ||
|
|
c6360e5408 | ||
|
|
f0505155a2 | ||
|
|
886df0fa86 | ||
|
|
3f1792d6ba | ||
|
|
9208052a94 | ||
|
|
7866bd2718 | ||
|
|
7c11325e23 | ||
|
|
d99dc7d81b | ||
|
|
973ad76a58 | ||
|
|
36e49eb190 | ||
|
|
66b9a7dee7 | ||
|
|
5494855ffa | ||
|
|
38d93a324c | ||
|
|
07c65321c1 | ||
|
|
1dbdd7df2e | ||
|
|
dab29ce094 | ||
|
|
0388534b9f | ||
|
|
81077e7c3a | ||
|
|
29a0042149 | ||
|
|
e9162e2516 | ||
|
|
0f6c001c25 | ||
|
|
7f26325c87 | ||
|
|
3c4ce3f945 | ||
|
|
84ef939bf4 | ||
|
|
bdc22ea127 | ||
|
|
5abbb79e1b | ||
|
|
0a5220aa07 | ||
|
|
970e68edcc | ||
|
|
da1a80e86d | ||
|
|
c4b240e0c2 | ||
|
|
c2052d11c2 | ||
|
|
dc0281b99c | ||
|
|
3a860ad537 | ||
|
|
7051bccc30 | ||
|
|
199e41b228 | ||
|
|
229a9e19a8 | ||
|
|
3c3a1a1f35 | ||
|
|
f11127648e | ||
|
|
29f833b1a7 | ||
|
|
7a3ea42743 | ||
|
|
a94902db8a | ||
|
|
9fd152ef3a | ||
|
|
03bc9ba6e6 | ||
|
|
7fe6f88876 | ||
|
|
1d88affd29 | ||
|
|
6906e12edb | ||
|
|
7b4c29a20d | ||
|
|
16bfa80b58 | ||
|
|
cb10437c3f | ||
|
|
2bcf1c0a20 | ||
|
|
00964b18f6 | ||
|
|
0d5c6201d3 | ||
|
|
86d2847dab | ||
|
|
b3a4eaa967 | ||
|
|
87fc519ce7 | ||
|
|
ef3a1ee997 | ||
|
|
311e16dffd | ||
|
|
c83b8f6d04 | ||
|
|
62d3a85b07 | ||
|
|
810ae0ef51 | ||
|
|
2ff49d2200 | ||
|
|
d0567dc7be | ||
|
|
ea64ac5c07 | ||
|
|
090b53ccc1 | ||
|
|
0e872e7482 | ||
|
|
3ad966e057 | ||
|
|
a73f9affab | ||
|
|
89a0859928 | ||
|
|
75c502cd93 | ||
|
|
0cc45f7a35 | ||
|
|
efb1dd6a10 | ||
|
|
6edb213fe7 | ||
|
|
c0513076a2 | ||
|
|
c043f148a6 | ||
|
|
366b5e04c7 | ||
|
|
72239d2228 | ||
|
|
b7f238975a | ||
|
|
a3c45141ee | ||
|
|
f7b899a54d | ||
|
|
95477277a2 | ||
|
|
64b446f671 | ||
|
|
c2d2e44794 | ||
|
|
f60b9f3b43 | ||
|
|
e3acfa3435 | ||
|
|
0f92c89529 | ||
|
|
7cba75ec35 | ||
|
|
8408ba3a3e | ||
|
|
c8c58b30d5 | ||
|
|
b4bed3329c | ||
|
|
4eec3aa69e | ||
|
|
35e3276e34 | ||
|
|
b346f4ead8 | ||
|
|
fef748e6cc | ||
|
|
19cc95f7b6 | ||
|
|
eef65d94ac | ||
|
|
72d497e052 | ||
|
|
32f58258aa | ||
|
|
87d57b434a | ||
|
|
4bbbb7d246 | ||
|
|
c1ce3c6b5f | ||
|
|
511de6f5f6 | ||
|
|
4dc08cd724 | ||
|
|
d7b9b3b01d | ||
|
|
a82ded65c6 | ||
|
|
1ca49fa568 | ||
|
|
4eb3cd32fa | ||
|
|
80d2a315aa | ||
|
|
82c9aa8485 | ||
|
|
8ecfafefbf | ||
|
|
010564cbb3 | ||
|
|
18a3fa4a00 | ||
|
|
de8e487ff1 | ||
|
|
e5ebdff4d8 | ||
|
|
f283dac325 | ||
|
|
639501809c | ||
|
|
36e6b89081 | ||
|
|
90639e6cd7 | ||
|
|
dec0b7f439 | ||
|
|
04657408f8 | ||
|
|
971d746061 | ||
|
|
9a2ba8c8cd | ||
|
|
b50d41bbf3 | ||
|
|
b71fd5092b | ||
|
|
f9b151b67f | ||
|
|
7ba9a66301 | ||
|
|
1b85764bf6 | ||
|
|
5e4c928948 | ||
|
|
ae282e3ae1 | ||
|
|
de3b654735 | ||
|
|
d28734f287 | ||
|
|
f9409022ed | ||
|
|
8138c88b41 | ||
|
|
38332fd3c6 | ||
|
|
5606bef3dd | ||
|
|
895079bbdc | ||
|
|
6aaf80f2fd | ||
|
|
2e656d9145 | ||
|
|
1fb8e013f7 | ||
|
|
f8fe2041d9 | ||
|
|
014f8485a6 | ||
|
|
58d7eb9b17 | ||
|
|
44ff5f1a5a | ||
|
|
46f25cf926 | ||
|
|
e1467c27cb | ||
|
|
5deedfe548 | ||
|
|
30937d0406 | ||
|
|
6eb8130419 | ||
|
|
8455771eb9 | ||
|
|
39dcafcdea | ||
|
|
7854a19dac | ||
|
|
18cea39090 | ||
|
|
46ffa0e8d4 | ||
|
|
bf3098a075 | ||
|
|
cdd7899564 | ||
|
|
eeebd44a87 | ||
|
|
805f437534 | ||
|
|
782b9a7903 | ||
|
|
ecb584cbe0 | ||
|
|
1e3953d1e0 | ||
|
|
509291fc1a | ||
|
|
dbb1958be5 | ||
|
|
d261d43b39 | ||
|
|
6986a50711 | ||
|
|
e9fe3e8bd9 | ||
|
|
bdca2f590a | ||
|
|
f4801ae9ae | ||
|
|
47ea264b46 | ||
|
|
84e023e10b | ||
|
|
52f0953786 | ||
|
|
d9743f684e | ||
|
|
4aebb461e9 | ||
|
|
c2cc1e2e5e | ||
|
|
66cf2e6779 | ||
|
|
7bacb8c984 | ||
|
|
e2de59c6fb | ||
|
|
c28dc26356 | ||
|
|
ea012fb7dc | ||
|
|
18e71469e1 | ||
|
|
4b1d30906e | ||
|
|
8b36013a03 | ||
|
|
ed91572ceb | ||
|
|
4150abf18c | ||
|
|
e132dfc955 | ||
|
|
2624fc43dd | ||
|
|
0c5c2e6370 | ||
|
|
f7a93f99ef | ||
|
|
9f29bbfce8 | ||
|
|
0075080827 | ||
|
|
63318e5690 | ||
|
|
d0c12b1b7f | ||
|
|
194b4e0d9b | ||
|
|
c6c7f400ae | ||
|
|
c91e6bcc46 | ||
|
|
ca69566d67 | ||
|
|
0bedfa3628 | ||
|
|
fd82f037c6 | ||
|
|
2bacc42e01 | ||
|
|
b527b785fd | ||
|
|
c3622cb0fe | ||
|
|
d0e59f406b | ||
|
|
4cc6d789ed | ||
|
|
d6d6ab9b73 | ||
|
|
e7816eb197 | ||
|
|
4f8b69360c | ||
|
|
0718d0a660 | ||
|
|
3641e65cac | ||
|
|
b17141604d | ||
|
|
5fece1cbfc | ||
|
|
a85b7fca15 | ||
|
|
af9a09b182 | ||
|
|
75c8f99d3c | ||
|
|
46892855c5 | ||
|
|
59e8d59b7c | ||
|
|
5cb6ff79ca | ||
|
|
9c41ce0b1c | ||
|
|
61abee4bd4 | ||
|
|
43d9567c5d | ||
|
|
3923979479 | ||
|
|
5312fbd7f4 | ||
|
|
ae412bbede | ||
|
|
69c8d21ba6 | ||
|
|
2dfc4e3cc0 | ||
|
|
74c8589045 | ||
|
|
4717632ce7 | ||
|
|
726a85f26b | ||
|
|
8a0650a46b | ||
|
|
e7dc43b7ca | ||
|
|
90195af1d8 | ||
|
|
da707343dc | ||
|
|
1f5fc505c6 | ||
|
|
4c655f841e | ||
|
|
be27c96f3c | ||
|
|
5090e30f71 | ||
|
|
688de89864 | ||
|
|
62444d4c63 | ||
|
|
4a970cca8b | ||
|
|
18b9135770 | ||
|
|
d266ddb312 | ||
|
|
7a348ac19c | ||
|
|
123d93539a | ||
|
|
785e7dab3a | ||
|
|
582fb11dd4 | ||
|
|
ccfeafa975 | ||
|
|
433c382280 | ||
|
|
7352ab14a2 | ||
|
|
85a76912d3 |
@@ -7,35 +7,29 @@ body:
|
||||
value: >
|
||||
Thank you for taking the time to file a bug report.
|
||||
|
||||
Use this to report bugs in LangChain.
|
||||
|
||||
If you're not certain that your issue is due to a bug in LangChain, please use [GitHub Discussions](https://github.com/langchain-ai/langchain/discussions)
|
||||
to ask for help with your issue.
|
||||
Use this to report BUGS in LangGraph. For usage questions, feature requests and general design questions, please use [GitHub Discussions](https://github.com/langchain-ai/langgraph/discussions).
|
||||
|
||||
Relevant links to check before filing a bug report to see if your issue has already been reported, fixed or
|
||||
if there's another way to solve your problem:
|
||||
|
||||
[LangGraph documentation](https://langchain-ai.github.io/langgraph/).
|
||||
[LangGraph Github Discussions](https://github.com/langchain-ai/langgraph/discussions),
|
||||
[LangGraph Github Issues](https://github.com/langchain-ai/langgraph/issues),
|
||||
[LangGraph how-to guides](https://langchain-ai.github.io/langgraph/how-tos/).
|
||||
[LangChain documentation with the integrated search](https://python.langchain.com/docs/get_started/introduction),
|
||||
[GitHub search](https://github.com/langchain-ai/langgraph),
|
||||
[LangChain Github Discussions](https://github.com/langchain-ai/langgraph/discussions),
|
||||
[LangChain Github Issues](https://github.com/langchain-ai/langgraph/issues),
|
||||
[LangChain ChatBot](https://chat.langchain.com/)
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: Checked other resources
|
||||
description: Please confirm and check all the following options.
|
||||
description: Before submitting this issue, please confirm that you have completed all the steps below by checking each option. These steps help ensure your issue is well-defined, relevant, and actionable.
|
||||
options:
|
||||
- label: I added a very descriptive title to this issue.
|
||||
- label: This is a bug, not a usage question. For questions, please use GitHub Discussions.
|
||||
required: true
|
||||
- label: I searched the [LangGraph](https://langchain-ai.github.io/langgraph/)/LangChain documentation with the integrated search.
|
||||
- label: I added a clear and detailed title that summarizes the issue.
|
||||
required: true
|
||||
- label: I used the GitHub search to find a similar question and didn't find it.
|
||||
- label: I read what a minimal reproducible example is (https://stackoverflow.com/help/minimal-reproducible-example).
|
||||
required: true
|
||||
- label: I am sure that this is a bug in LangGraph/LangChain rather than my code.
|
||||
required: true
|
||||
- label: I am sure this is better as an issue [rather than a GitHub discussion](https://github.com/langchain-ai/langgraph/discussions/new/choose), since this is a LangGraph bug and not a design question.
|
||||
- label: I included a self-contained, minimal example that demonstrates the issue INCLUDING all the relevant imports. The code run AS IS to reproduce the issue.
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
@@ -45,14 +39,6 @@ body:
|
||||
label: Example Code
|
||||
description: |
|
||||
Please add a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with your use case.
|
||||
|
||||
If a maintainer can copy it, run it, and see it right away, there's a much higher chance that you'll be able to get help.
|
||||
|
||||
**Important!**
|
||||
|
||||
* Reduce your code to the minimum required to reproduce the issue if possible. This makes it much easier for others to help you.
|
||||
* Avoid screenshots when possible, as they are hard to read and (more importantly) don't allow others to copy-and-paste your code.
|
||||
|
||||
placeholder: |
|
||||
from langgraph.graph import StateGraph
|
||||
|
||||
@@ -92,25 +78,8 @@ body:
|
||||
attributes:
|
||||
label: System Info
|
||||
description: |
|
||||
Please share your system info with us.
|
||||
|
||||
"pip freeze | grep langchain"
|
||||
platform (windows / linux / mac)
|
||||
python version
|
||||
|
||||
OR if you're on a recent version of langchain-core you can paste the output of:
|
||||
|
||||
python -m langchain_core.sys_info
|
||||
placeholder: |
|
||||
"pip freeze | grep langgraph"
|
||||
platform
|
||||
python version
|
||||
|
||||
Alternatively, if you're on a recent version of langchain-core you can paste the output of:
|
||||
|
||||
python -m langchain_core.sys_info
|
||||
|
||||
These will only surface LangChain packages, don't forget to include any other relevant
|
||||
packages you're using (if you're not sure what's relevant, you can paste the entire output of `pip freeze`).
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
import pathlib
|
||||
import sys
|
||||
import langgraph_cli
|
||||
import langgraph_cli.docker
|
||||
import langgraph_cli.config
|
||||
|
||||
from langgraph_cli.exec import Runner, subp_exec
|
||||
from langgraph_cli.progress import Progress
|
||||
from langgraph_cli.constants import DEFAULT_PORT
|
||||
|
||||
|
||||
def test(
|
||||
config: pathlib.Path,
|
||||
port: int,
|
||||
tag: str,
|
||||
verbose: bool,
|
||||
):
|
||||
with Runner() as runner, Progress(message="Pulling...") as set:
|
||||
# check docker available
|
||||
capabilities = langgraph_cli.docker.check_capabilities(runner)
|
||||
# open config
|
||||
config_json = langgraph_cli.config.validate_config_file(config)
|
||||
|
||||
set("Running...")
|
||||
args = [
|
||||
"run",
|
||||
"--rm",
|
||||
"-p",
|
||||
f"{port}:8000",
|
||||
]
|
||||
if isinstance(config_json["env"], str):
|
||||
args.extend(
|
||||
[
|
||||
"--env-file",
|
||||
str(config.parent / config_json["env"]),
|
||||
]
|
||||
)
|
||||
else:
|
||||
for k, v in config_json["env"].items():
|
||||
args.extend(
|
||||
[
|
||||
"-e",
|
||||
f"{k}={v}",
|
||||
]
|
||||
)
|
||||
if capabilities.healthcheck_start_interval:
|
||||
args.extend(
|
||||
[
|
||||
"--health-interval",
|
||||
"5s",
|
||||
"--health-retries",
|
||||
"1",
|
||||
"--health-start-period",
|
||||
"10s",
|
||||
"--health-start-interval",
|
||||
"1s",
|
||||
]
|
||||
)
|
||||
else:
|
||||
args.extend(
|
||||
[
|
||||
"--health-interval",
|
||||
"5s",
|
||||
"--health-retries",
|
||||
"2",
|
||||
]
|
||||
)
|
||||
|
||||
_task = None
|
||||
|
||||
def on_stdout(line: str):
|
||||
nonlocal _task
|
||||
if "GET /ok" in line or "Uvicorn running on" in line:
|
||||
set("")
|
||||
sys.stdout.write(
|
||||
f"""Ready!
|
||||
- API: http://localhost:{port}
|
||||
"""
|
||||
)
|
||||
sys.stdout.flush()
|
||||
_task.cancel()
|
||||
return True
|
||||
return False
|
||||
|
||||
async def subp_exec_task(*args, **kwargs):
|
||||
nonlocal _task
|
||||
_task = asyncio.create_task(subp_exec(*args, **kwargs))
|
||||
await _task
|
||||
|
||||
try:
|
||||
runner.run(
|
||||
subp_exec_task(
|
||||
"docker",
|
||||
*args,
|
||||
tag,
|
||||
verbose=verbose,
|
||||
on_stdout=on_stdout,
|
||||
)
|
||||
)
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-t", "--tag", type=str)
|
||||
parser.add_argument("-c", "--config", type=str, default="./langgraph.json")
|
||||
parser.add_argument("-p", "--port", default=DEFAULT_PORT)
|
||||
args = parser.parse_args()
|
||||
test(pathlib.Path(args.config), args.port, args.tag, verbose=True)
|
||||
@@ -39,22 +39,36 @@ jobs:
|
||||
- name: Install cli globally
|
||||
if: steps.changed-files.outputs.all
|
||||
run: pip install -e .
|
||||
- name: Start service A
|
||||
- name: Build and test service A
|
||||
if: steps.changed-files.outputs.all
|
||||
working-directory: libs/cli/examples
|
||||
run: |
|
||||
timeout 60 langgraph test -c examples/langgraph.json --verbose || (exit "$(($? == 124 ? 0 : $?))")
|
||||
- name: Start service B
|
||||
# The build-arg isn't used; just testing that we accept other args
|
||||
langgraph build -t langgraph-test-a --base-image "langchain/langgraph-trial"
|
||||
cp .env.example .envg
|
||||
timeout 60 python ../../../.github/scripts/run_langgraph_cli_test.py -c langgraph.json -t langgraph-test-a
|
||||
- name: Build and test service B
|
||||
if: steps.changed-files.outputs.all
|
||||
working-directory: libs/cli/examples/graphs
|
||||
run: |
|
||||
timeout 60 langgraph test --verbose || (exit "$(($? == 124 ? 0 : $?))")
|
||||
- name: Start service C
|
||||
langgraph build -t langgraph-test-b --base-image "langchain/langgraph-trial"
|
||||
timeout 60 python ../../../../.github/scripts/run_langgraph_cli_test.py -t langgraph-test-b
|
||||
- name: Build and test service C
|
||||
if: steps.changed-files.outputs.all
|
||||
working-directory: libs/cli/examples/graphs_reqs_a
|
||||
run: |
|
||||
timeout 60 langgraph test --verbose || (exit "$(($? == 124 ? 0 : $?))")
|
||||
- name: Start service D
|
||||
langgraph build -t langgraph-test-c --base-image "langchain/langgraph-trial"
|
||||
timeout 60 python ../../../../.github/scripts/run_langgraph_cli_test.py -t langgraph-test-c
|
||||
- name: Build and test service D
|
||||
if: steps.changed-files.outputs.all
|
||||
working-directory: libs/cli/examples/graphs_reqs_b
|
||||
run: |
|
||||
timeout 60 langgraph test --verbose || (exit "$(($? == 124 ? 0 : $?))")
|
||||
langgraph build -t langgraph-test-d --base-image "langchain/langgraph-trial"
|
||||
timeout 60 python ../../../../.github/scripts/run_langgraph_cli_test.py -t langgraph-test-d
|
||||
|
||||
- name: Build JS service
|
||||
if: steps.changed-files.outputs.all
|
||||
working-directory: libs/cli/js-examples
|
||||
run: |
|
||||
langgraph build -t langgraph-test-e
|
||||
|
||||
@@ -42,7 +42,6 @@ jobs:
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
poetry-version: ${{ env.POETRY_VERSION }}
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
cache-key: lint-${{ inputs.working-directory }}
|
||||
|
||||
- name: Check Poetry File
|
||||
|
||||
@@ -31,7 +31,6 @@ jobs:
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
poetry-version: ${{ env.POETRY_VERSION }}
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
cache-key: test-${{ inputs.working-directory }}
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
|
||||
@@ -17,16 +17,11 @@ jobs:
|
||||
- "3.11"
|
||||
- "3.12"
|
||||
- "3.13"
|
||||
core-version:
|
||||
- "latest"
|
||||
include:
|
||||
- python-version: "3.11"
|
||||
core-version: ">=0.2.39,<0.3.0"
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: libs/langgraph
|
||||
name: "test #${{ matrix.python-version }} (langchain-core: ${{ matrix.core-version }})"
|
||||
name: "test #${{ matrix.python-version }}"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python ${{ matrix.python-version }} + Poetry ${{ env.POETRY_VERSION }}
|
||||
@@ -46,14 +41,11 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
poetry install --with dev
|
||||
if [ "${{ matrix.core-version }}" != "latest" ]; then
|
||||
poetry run pip install "langchain-core${{ matrix.core-version }}"
|
||||
fi
|
||||
|
||||
- name: Run tests
|
||||
shell: bash
|
||||
run: |
|
||||
make test
|
||||
make test_parallel
|
||||
|
||||
- name: Ensure the tests did not create any additional files
|
||||
shell: bash
|
||||
|
||||
@@ -29,7 +29,6 @@ jobs:
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
poetry-version: ${{ env.POETRY_VERSION }}
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
cache-key: release
|
||||
|
||||
# We want to keep this build stage *separate* from the release stage,
|
||||
@@ -93,3 +92,5 @@ jobs:
|
||||
# This is *only for CI use* and is *extremely dangerous* otherwise!
|
||||
# https://github.com/pypa/gh-action-pypi-publish#tolerating-release-package-file-duplicates
|
||||
skip-existing: true
|
||||
# Temp workaround since attestations are on by default as of gh-action-pypi-publish v1.11.0
|
||||
attestations: false
|
||||
|
||||
@@ -31,7 +31,6 @@ jobs:
|
||||
"libs/cli",
|
||||
"libs/checkpoint",
|
||||
"libs/checkpoint-sqlite",
|
||||
"libs/checkpoint-duckdb",
|
||||
"libs/checkpoint-postgres",
|
||||
"libs/scheduler-kafka",
|
||||
]
|
||||
@@ -44,12 +43,12 @@ jobs:
|
||||
name: cd ${{ matrix.working-directory }}
|
||||
strategy:
|
||||
matrix:
|
||||
working-directory: [
|
||||
working-directory:
|
||||
[
|
||||
"libs/cli",
|
||||
"libs/checkpoint",
|
||||
"libs/checkpoint-sqlite",
|
||||
"libs/checkpoint-duckdb",
|
||||
"libs/checkpoint-postgres"
|
||||
"libs/checkpoint-postgres",
|
||||
]
|
||||
uses: ./.github/workflows/_test.yml
|
||||
with:
|
||||
@@ -76,7 +75,7 @@ jobs:
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
python-version: "3.11"
|
||||
- name: Run check_sdk_methods script
|
||||
run: python .github/scripts/check_sdk_methods.py
|
||||
|
||||
@@ -109,9 +108,40 @@ jobs:
|
||||
- name: Build
|
||||
run: yarn build
|
||||
|
||||
test-js:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
working-directory:
|
||||
- "libs/sdk-js"
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ${{ matrix.working-directory }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Node.js (LTS)
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "20"
|
||||
cache: "yarn"
|
||||
cache-dependency-path: ${{ matrix.working-directory }}/yarn.lock
|
||||
- name: Install dependencies
|
||||
run: yarn install
|
||||
- name: Run tests
|
||||
run: yarn test
|
||||
|
||||
ci_success:
|
||||
name: "CI Success"
|
||||
needs: [lint, lint-js, test, test-langgraph, test-scheduler-kafka, integration-test]
|
||||
needs:
|
||||
[
|
||||
lint,
|
||||
lint-js,
|
||||
test,
|
||||
test-langgraph,
|
||||
test-scheduler-kafka,
|
||||
integration-test,
|
||||
test-js,
|
||||
]
|
||||
if: |
|
||||
always()
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: docs
|
||||
|
||||
jobs:
|
||||
codespell:
|
||||
name: (Check for spelling errors)
|
||||
@@ -21,18 +25,18 @@
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
pip install toml codespell jupytext
|
||||
pip install toml codespell==2.3.0 jupytext
|
||||
|
||||
- name: Extract Ignore Words List
|
||||
run: |
|
||||
# Use a Python script to extract the ignore words list from pyproject.toml
|
||||
python .github/workflows/extract_ignored_words_list.py
|
||||
python ../.github/workflows/extract_ignored_words_list.py
|
||||
id: extract_ignore_words
|
||||
|
||||
- name: Codespell
|
||||
uses: codespell-project/actions-codespell@v2
|
||||
with:
|
||||
skip: '*.ambr,*.lock,*.ipynb,*.yaml,*.zlib'
|
||||
skip: '*.ambr,*.lock,*.ipynb,*.yaml,*.zlib,*.md'
|
||||
ignore_words_list: ${{ steps.extract_ignore_words.outputs.ignore_words_list }}
|
||||
# We do this to avoid spellchecking cell outputs
|
||||
- name: Codespell Notebooks
|
||||
|
||||
@@ -21,6 +21,10 @@ concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: docs
|
||||
|
||||
jobs:
|
||||
get-changed-files:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -44,6 +48,9 @@ jobs:
|
||||
deploy:
|
||||
# needs: run-changed-notebooks
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10 # Job will be cancelled if it runs for more than 10 minutes
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.MKDOCS_GITHUB_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -56,20 +63,42 @@ jobs:
|
||||
poetry-version: ${{ env.POETRY_VERSION }}
|
||||
cache-key: docs
|
||||
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "22"
|
||||
cache: "yarn"
|
||||
cache-dependency-path: docs/yarn.lock
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
poetry install --with test
|
||||
poetry run pip install -U pytest pytest-check-links langsmith langchain GitPython
|
||||
yarn
|
||||
poetry install --with test --with docs --no-root
|
||||
poetry run pip install -U \
|
||||
pytest \
|
||||
pytest-check-links \
|
||||
GitPython \
|
||||
"git+https://${GITHUB_TOKEN}@github.com/langchain-ai/mkdocs-material-insiders.git" \
|
||||
"git+https://github.com/benjamincburns/markdown-exec.git@cc0d39d737e5ffd4b83d23cd8729d7ea16e363c8"
|
||||
|
||||
poetry run jupyter kernelspec list
|
||||
poetry run python3 -m ipykernel install --user --name=python3
|
||||
npm install -g tslab
|
||||
poetry run tslab install --python=python3
|
||||
poetry run jupyter kernelspec list
|
||||
|
||||
- name: Lint Docs
|
||||
# This step lints the docs using the existing linting set up.
|
||||
# It should be very fast and should not require any external services.
|
||||
run: make lint-docs
|
||||
- name: Build llms-text
|
||||
run: make llms-text
|
||||
- name: Build site
|
||||
run: make build-docs
|
||||
env:
|
||||
MKDOCS_GIT_COMMITTERS_APIKEY: ${{ secrets.MKDOCS_GIT_COMMITTERS_APIKEY }}
|
||||
|
||||
OPENAI_API_KEY: sf-proj-1234567890 # fake placeholder, shouldn't actually be used
|
||||
ANTHROPIC_API_KEY: sk-ant-api03-1234567890 # fake placeholder, shouldn't actually be used
|
||||
- name: Check links in notebooks
|
||||
env:
|
||||
LANGCHAIN_API_KEY: test
|
||||
@@ -78,21 +107,33 @@ jobs:
|
||||
echo "Running link check on all HTML files matching notebooks in docs directory..."
|
||||
poetry run pytest -v \
|
||||
--check-links-ignore "https://(api|web|docs)\.smith\.langchain\.com/.*" \
|
||||
--check-links-ignore "https://academy\.langchain\.com/.*" \
|
||||
--check-links-ignore "https://x.com/.*" \
|
||||
--check-links-ignore "https://github\.com/.*" \
|
||||
--check-links-ignore "http://localhost:8123/.*" \
|
||||
--check-links-ignore "http://localhost:2024.*" \
|
||||
--check-links-ignore "http://127.0.0.1:.*" \
|
||||
--check-links-ignore "/.*\.(ipynb|html)$" \
|
||||
--check-links-ignore "https://python\.langchain\.com/.*" \
|
||||
--check-links $(find docs/site -name "index.html" | grep -v 'storm/index.html')
|
||||
--check-links-ignore "https://openai\.com/.*" \
|
||||
--check-links-ignore "https://www\.uber\.com/.*" \
|
||||
--check-links-ignore "https://pepy\.tech/.*" \
|
||||
--check-links $(find site -name "index.html" | grep -v 'storm/index.html')
|
||||
|
||||
else
|
||||
echo "Fetching changes from origin/main..."
|
||||
git fetch origin main
|
||||
echo "Checking for changed notebook files..."
|
||||
CHANGED_FILES=$(git diff --name-only --diff-filter=d origin/main | grep 'docs/docs/.*\.ipynb$' | grep -v 'storm.ipynb' | sed -E 's|^docs/docs/|docs/site/|; s/\.ipynb$/\/index.html/' || true)
|
||||
CHANGED_FILES=$(git diff --name-only --diff-filter=d origin/main | grep 'docs/docs/.*\.ipynb$' | grep -v 'storm.ipynb' | sed -E 's|^docs/docs/|site/|; s/\.ipynb$/\/index.html/' || true)
|
||||
echo "Changed files: ${CHANGED_FILES}"
|
||||
if [ -n "${CHANGED_FILES}" ]; then
|
||||
echo "Running link check on HTML files matching changed notebook files..."
|
||||
poetry run pytest -v \
|
||||
--check-links-ignore "https://(api|web|docs)\.smith\.langchain\.com/.*" \
|
||||
--check-links-ignore "https://academy\.langchain\.com/.*" \
|
||||
--check-links-ignore "http://localhost:8123/.*" \
|
||||
--check-links-ignore "http://localhost:2024.*" \
|
||||
--check-links-ignore "http://127.0.0.1:.*" \
|
||||
--check-links-ignore "https://x.com/.*" \
|
||||
--check-links-ignore "https://github\.com/.*" \
|
||||
--check-links-ignore "/.*\.(ipynb|html)$" \
|
||||
@@ -108,7 +149,7 @@ jobs:
|
||||
uses: actions/configure-pages@v4
|
||||
|
||||
- name: Upload Pages Artifact
|
||||
if: github.ref == 'refs/heads/main'
|
||||
# if: github.ref == 'refs/heads/main'
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: ./docs/site/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import toml
|
||||
|
||||
pyproject_toml = toml.load("libs/langgraph/pyproject.toml")
|
||||
pyproject_toml = toml.load("pyproject.toml")
|
||||
|
||||
# Extract the ignore words list (adjust the key as per your TOML structure)
|
||||
ignore_words_list = (
|
||||
|
||||
@@ -31,7 +31,6 @@ jobs:
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
poetry-version: ${{ env.POETRY_VERSION }}
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
cache-key: release
|
||||
|
||||
# We want to keep this build stage *separate* from the release stage,
|
||||
@@ -169,7 +168,6 @@ jobs:
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
poetry-version: ${{ env.POETRY_VERSION }}
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
|
||||
- name: Import published package
|
||||
shell: bash
|
||||
@@ -256,7 +254,6 @@ jobs:
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
poetry-version: ${{ env.POETRY_VERSION }}
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
cache-key: release
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
@@ -270,6 +267,8 @@ jobs:
|
||||
packages-dir: ${{ inputs.working-directory }}/dist/
|
||||
verbose: true
|
||||
print-hash: true
|
||||
# Temp workaround since attestations are on by default as of gh-action-pypi-publish v1.11.0
|
||||
attestations: false
|
||||
|
||||
mark-release:
|
||||
needs:
|
||||
@@ -296,7 +295,6 @@ jobs:
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
poetry-version: ${{ env.POETRY_VERSION }}
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
cache-key: release
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
|
||||
@@ -11,6 +11,10 @@ on:
|
||||
schedule:
|
||||
- cron: '0 13 * * *'
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: docs
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -39,14 +43,14 @@ jobs:
|
||||
|
||||
- name: Pre-download tiktoken files
|
||||
run: |
|
||||
poetry run python docs/_scripts/download_tiktoken.py
|
||||
poetry run python _scripts/download_tiktoken.py
|
||||
|
||||
- name: Prepare notebooks
|
||||
run: |
|
||||
if [ "${{ matrix.lib-version }}" = "development" ]; then
|
||||
poetry run python docs/_scripts/prepare_notebooks_for_ci.py --comment-install-cells
|
||||
poetry run python _scripts/prepare_notebooks_for_ci.py --comment-install-cells
|
||||
else
|
||||
poetry run python docs/_scripts/prepare_notebooks_for_ci.py
|
||||
poetry run python _scripts/prepare_notebooks_for_ci.py
|
||||
fi
|
||||
|
||||
- name: Run notebooks
|
||||
@@ -63,12 +67,12 @@ jobs:
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ] || [ "${{ github.event_name }}" = "schedule" ]; then
|
||||
echo "Running all notebooks"
|
||||
./docs/_scripts/execute_notebooks.sh
|
||||
./_scripts/execute_notebooks.sh
|
||||
else
|
||||
CHANGED_FILES=$(echo '${{ inputs.changed-files }}' | tr ' ' '\n' | grep '\.ipynb$' || true)
|
||||
CHANGED_FILES=$(echo '${{ inputs.changed-files }}' | tr ' ' '\n' | sed 's|^docs/docs/|docs/|' | grep '\.ipynb$' || true)
|
||||
if [ -n "$CHANGED_FILES" ]; then
|
||||
echo "Running changed notebooks: $CHANGED_FILES"
|
||||
./docs/_scripts/execute_notebooks.sh $CHANGED_FILES
|
||||
./_scripts/execute_notebooks.sh $CHANGED_FILES
|
||||
else
|
||||
echo "No notebook files changed, skipping execution"
|
||||
fi
|
||||
|
||||
+2
-1
@@ -178,4 +178,5 @@ Untitled*.ipynb
|
||||
|
||||
Chinook.db
|
||||
|
||||
libs/langgraph/out
|
||||
.vercel
|
||||
.turbo
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ gain understanding of concepts and how they interact by showing one way to achie
|
||||
|
||||
They should **avoid** giving
|
||||
multiple permutations of ways to achieve that goal in-depth. Choice is burdensome. Instead, they should guide a new user through a recommended path to accomplishing a concrete goal. While the end result of a tutorial does not necessarily need to
|
||||
be completely production-ready, it should be useful and practically satisfy the the goal that you clearly stated in the tutorial's introduction.
|
||||
be completely production-ready, it should be useful and practically satisfy the goal that you clearly stated in the tutorial's introduction.
|
||||
|
||||
To quote the Diataxis website:
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
.PHONY: lint-docs format-docs build-docs serve-docs serve-clean-docs clean-docs codespell build-typedoc
|
||||
|
||||
build-typedoc:
|
||||
cd libs/sdk-js && yarn install --include-dev && yarn typedoc
|
||||
cd libs/sdk-js && yarn --silent concat-md --decrease-title-levels --ignore=js_ts_sdk_ref.md --start-title-level-at 2 docs > ../../docs/docs/cloud/reference/sdk/js_ts_sdk_ref.md 2>/dev/null
|
||||
# Add links to the monorepo
|
||||
sed -e '1,10s|@langchain/langgraph-sdk|[@langchain/langgraph-sdk](https://github.com/langchain-ai/langgraph/tree/main/libs/sdk-js)|g' docs/docs/cloud/reference/sdk/js_ts_sdk_ref.md > temp_file && mv temp_file docs/docs/cloud/reference/sdk/js_ts_sdk_ref.md
|
||||
|
||||
build-docs: build-typedoc
|
||||
poetry run python -m mkdocs build --clean -f docs/mkdocs.yml --strict
|
||||
|
||||
serve-clean-docs: clean-docs
|
||||
poetry run python -m mkdocs serve -c -f docs/mkdocs.yml --strict -w ./libs/langgraph
|
||||
|
||||
serve-docs: build-typedoc
|
||||
poetry run python -m mkdocs serve -f docs/mkdocs.yml -w ./libs/langgraph --dirty
|
||||
|
||||
clean-docs:
|
||||
find ./docs/docs -name "*.ipynb" -type f -delete
|
||||
rm -rf docs/site
|
||||
|
||||
## Run format against the project documentation.
|
||||
format-docs:
|
||||
poetry run ruff format docs/docs
|
||||
poetry run ruff check --fix docs/docs
|
||||
|
||||
# Check the docs for linting violations
|
||||
lint-docs:
|
||||
poetry run ruff format --check docs/docs
|
||||
poetry run ruff check docs/docs
|
||||
|
||||
codespell:
|
||||
./docs/codespell_notebooks.sh .
|
||||
|
||||
start-services:
|
||||
docker compose -f docs/test-compose.yml up -V --force-recreate --wait --remove-orphans
|
||||
|
||||
stop-services:
|
||||
docker compose -f docs/test-compose.yml down
|
||||
@@ -8,24 +8,56 @@
|
||||
⚡ Building language agents as graphs ⚡
|
||||
|
||||
> [!NOTE]
|
||||
> Looking for the JS version? Click [here](https://github.com/langchain-ai/langgraphjs) ([JS docs](https://langchain-ai.github.io/langgraphjs/)).
|
||||
> Looking for the JS version? See the [JS repo](https://github.com/langchain-ai/langgraphjs) and the [JS docs](https://langchain-ai.github.io/langgraphjs/).
|
||||
|
||||
## Overview
|
||||
|
||||
[LangGraph](https://langchain-ai.github.io/langgraph/) is a library for building stateful, multi-actor applications with LLMs, used to create agent and multi-agent workflows. Compared to other LLM frameworks, it offers these core benefits: cycles, controllability, and persistence. LangGraph allows you to define flows that involve cycles, essential for most agentic architectures, differentiating it from DAG-based solutions. As a very low-level framework, it provides fine-grained control over both the flow and state of your application, crucial for creating reliable agents. Additionally, LangGraph includes built-in persistence, enabling advanced human-in-the-loop and memory features.
|
||||
[LangGraph](https://langchain-ai.github.io/langgraph/) is a library for building
|
||||
stateful, multi-actor applications with LLMs, used to create agent and multi-agent
|
||||
workflows. Check out an introductory tutorial [here](https://langchain-ai.github.io/langgraph/tutorials/introduction/).
|
||||
|
||||
|
||||
LangGraph is inspired by [Pregel](https://research.google/pubs/pub37252/) and [Apache Beam](https://beam.apache.org/). The public interface draws inspiration from [NetworkX](https://networkx.org/documentation/latest/). LangGraph is built by LangChain Inc, the creators of LangChain, but can be used without LangChain.
|
||||
|
||||
To learn more about LangGraph, check out our first LangChain Academy course, *Introduction to LangGraph*, available for free [here](https://academy.langchain.com/courses/intro-to-langgraph).
|
||||
### Why use LangGraph?
|
||||
|
||||
### Key Features
|
||||
LangGraph powers [production-grade agents](https://www.langchain.com/built-with-langgraph), trusted by Linkedin, Uber, Klarna, GitLab, and many more. LangGraph provides fine-grained control over both the flow and state of your agent applications. It implements a central [persistence layer](https://langchain-ai.github.io/langgraph/concepts/persistence/), enabling features that are common to most agent architectures:
|
||||
|
||||
- **Cycles and Branching**: Implement loops and conditionals in your apps.
|
||||
- **Persistence**: Automatically save state after each step in the graph. Pause and resume the graph execution at any point to support error recovery, human-in-the-loop workflows, time travel and more.
|
||||
- **Human-in-the-Loop**: Interrupt graph execution to approve or edit next action planned by the agent.
|
||||
- **Streaming Support**: Stream outputs as they are produced by each node (including token streaming).
|
||||
- **Integration with LangChain**: LangGraph integrates seamlessly with [LangChain](https://github.com/langchain-ai/langchain/) and [LangSmith](https://docs.smith.langchain.com/) (but does not require them).
|
||||
- **Memory**: LangGraph persists arbitrary aspects of your application's state,
|
||||
supporting memory of conversations and other updates within and across user
|
||||
interactions;
|
||||
- **Human-in-the-loop**: Because state is checkpointed, execution can be interrupted
|
||||
and resumed, allowing for decisions, validation, and corrections at key stages via
|
||||
human input.
|
||||
|
||||
Standardizing these components allows individuals and teams to focus on the behavior
|
||||
of their agent, instead of its supporting infrastructure.
|
||||
|
||||
Through [LangGraph Platform](#langgraph-platform), LangGraph also provides tooling for
|
||||
the development, deployment, debugging, and monitoring of your applications.
|
||||
|
||||
LangGraph integrates seamlessly with
|
||||
[LangChain](https://python.langchain.com/docs/introduction/) and
|
||||
[LangSmith](https://docs.smith.langchain.com/) (but does not require them).
|
||||
|
||||
To learn more about LangGraph, check out our first LangChain Academy
|
||||
course, *Introduction to LangGraph*, available for free
|
||||
[here](https://academy.langchain.com/courses/intro-to-langgraph).
|
||||
|
||||
### LangGraph Platform
|
||||
|
||||
[LangGraph Platform](https://langchain-ai.github.io/langgraph/concepts/langgraph_platform) is infrastructure for deploying LangGraph agents. It is a commercial solution for deploying agentic applications to production, built on the open-source LangGraph framework. The LangGraph Platform consists of several components that work together to support the development, deployment, debugging, and monitoring of LangGraph applications: [LangGraph Server](https://langchain-ai.github.io/langgraph/concepts/langgraph_server) (APIs), [LangGraph SDKs](https://langchain-ai.github.io/langgraph/concepts/sdk) (clients for the APIs), [LangGraph CLI](https://langchain-ai.github.io/langgraph/concepts/langgraph_cli) (command line tool for building the server), and [LangGraph Studio](https://langchain-ai.github.io/langgraph/concepts/langgraph_studio) (UI/debugger).
|
||||
|
||||
See deployment options [here](https://langchain-ai.github.io/langgraph/concepts/deployment_options/)
|
||||
(includes a free tier).
|
||||
|
||||
Here are some common issues that arise in complex deployments, which LangGraph Platform addresses:
|
||||
|
||||
- **Streaming support**: LangGraph Server provides [multiple streaming modes](https://langchain-ai.github.io/langgraph/concepts/streaming) optimized for various application needs
|
||||
- **Background runs**: Runs agents asynchronously in the background
|
||||
- **Support for long running agents**: Infrastructure that can handle long running processes
|
||||
- **[Double texting](https://langchain-ai.github.io/langgraph/concepts/double_texting)**: Handle the case where you get two messages from the user before the agent can respond
|
||||
- **Handle burstiness**: Task queue for ensuring requests are handled consistently without loss, even under heavy loads
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -35,9 +67,7 @@ pip install -U langgraph
|
||||
|
||||
## Example
|
||||
|
||||
One of the central concepts of LangGraph is state. Each graph execution creates a state that is passed between nodes in the graph as they execute, and each node updates this internal state with its return value after it executes. The way that the graph updates its internal state is defined by either the type of graph chosen or a custom function.
|
||||
|
||||
Let's take a look at a simple example of an agent that can use a search tool.
|
||||
Let's build a tool-calling [ReAct-style](https://langchain-ai.github.io/langgraph/concepts/agentic_concepts/#react-implementation) agent that uses a search tool!
|
||||
|
||||
```shell
|
||||
pip install langchain-anthropic
|
||||
@@ -54,10 +84,72 @@ export LANGSMITH_TRACING=true
|
||||
export LANGSMITH_API_KEY=lsv2_sk_...
|
||||
```
|
||||
|
||||
```python
|
||||
from typing import Annotated, Literal, TypedDict
|
||||
The simplest way to create a tool-calling agent in LangGraph is to use `create_react_agent`:
|
||||
|
||||
<details open>
|
||||
<summary>High-level implementation</summary>
|
||||
|
||||
```python
|
||||
from langgraph.prebuilt import create_react_agent
|
||||
from langgraph.checkpoint.memory import MemorySaver
|
||||
from langchain_anthropic import ChatAnthropic
|
||||
from langchain_core.tools import tool
|
||||
|
||||
# Define the tools for the agent to use
|
||||
@tool
|
||||
def search(query: str):
|
||||
"""Call to surf the web."""
|
||||
# This is a placeholder, but don't tell the LLM that...
|
||||
if "sf" in query.lower() or "san francisco" in query.lower():
|
||||
return "It's 60 degrees and foggy."
|
||||
return "It's 90 degrees and sunny."
|
||||
|
||||
|
||||
tools = [search]
|
||||
model = ChatAnthropic(model="claude-3-5-sonnet-latest", temperature=0)
|
||||
|
||||
# Initialize memory to persist state between graph runs
|
||||
checkpointer = MemorySaver()
|
||||
|
||||
app = create_react_agent(model, tools, checkpointer=checkpointer)
|
||||
|
||||
# Use the agent
|
||||
final_state = app.invoke(
|
||||
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
|
||||
config={"configurable": {"thread_id": 42}}
|
||||
)
|
||||
final_state["messages"][-1].content
|
||||
```
|
||||
```
|
||||
"Based on the search results, I can tell you that the current weather in San Francisco is:\n\nTemperature: 60 degrees Fahrenheit\nConditions: Foggy\n\nSan Francisco is known for its microclimates and frequent fog, especially during the summer months. The temperature of 60°F (about 15.5°C) is quite typical for the city, which tends to have mild temperatures year-round. The fog, often referred to as "Karl the Fog" by locals, is a characteristic feature of San Francisco\'s weather, particularly in the mornings and evenings.\n\nIs there anything else you\'d like to know about the weather in San Francisco or any other location?"
|
||||
```
|
||||
|
||||
Now when we pass the same <code>"thread_id"</code>, the conversation context is retained via the saved state (i.e. stored list of messages)
|
||||
|
||||
```python
|
||||
final_state = app.invoke(
|
||||
{"messages": [{"role": "user", "content": "what about ny"}]},
|
||||
config={"configurable": {"thread_id": 42}}
|
||||
)
|
||||
final_state["messages"][-1].content
|
||||
```
|
||||
|
||||
```
|
||||
"Based on the search results, I can tell you that the current weather in New York City is:\n\nTemperature: 90 degrees Fahrenheit (approximately 32.2 degrees Celsius)\nConditions: Sunny\n\nThis weather is quite different from what we just saw in San Francisco. New York is experiencing much warmer temperatures right now. Here are a few points to note:\n\n1. The temperature of 90°F is quite hot, typical of summer weather in New York City.\n2. The sunny conditions suggest clear skies, which is great for outdoor activities but also means it might feel even hotter due to direct sunlight.\n3. This kind of weather in New York often comes with high humidity, which can make it feel even warmer than the actual temperature suggests.\n\nIt's interesting to see the stark contrast between San Francisco's mild, foggy weather and New York's hot, sunny conditions. This difference illustrates how varied weather can be across different parts of the United States, even on the same day.\n\nIs there anything else you'd like to know about the weather in New York or any other location?"
|
||||
```
|
||||
</details>
|
||||
|
||||
> [!TIP]
|
||||
> LangGraph is a **low-level** framework that allows you to implement any custom agent
|
||||
architectures. Click on the low-level implementation below to see how to implement a
|
||||
tool-calling agent from scratch.
|
||||
|
||||
<details>
|
||||
<summary>Low-level implementation</summary>
|
||||
|
||||
```python
|
||||
from typing import Literal
|
||||
|
||||
from langchain_core.messages import HumanMessage
|
||||
from langchain_anthropic import ChatAnthropic
|
||||
from langchain_core.tools import tool
|
||||
from langgraph.checkpoint.memory import MemorySaver
|
||||
@@ -79,7 +171,7 @@ tools = [search]
|
||||
|
||||
tool_node = ToolNode(tools)
|
||||
|
||||
model = ChatAnthropic(model="claude-3-5-sonnet-20240620", temperature=0).bind_tools(tools)
|
||||
model = ChatAnthropic(model="claude-3-5-sonnet-latest", temperature=0).bind_tools(tools)
|
||||
|
||||
# Define the function that determines whether to continue or not
|
||||
def should_continue(state: MessagesState) -> Literal["tools", END]:
|
||||
@@ -133,92 +225,102 @@ checkpointer = MemorySaver()
|
||||
# Note that we're (optionally) passing the memory when compiling the graph
|
||||
app = workflow.compile(checkpointer=checkpointer)
|
||||
|
||||
# Use the Runnable
|
||||
# Use the agent
|
||||
final_state = app.invoke(
|
||||
{"messages": [HumanMessage(content="what is the weather in sf")]},
|
||||
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
|
||||
config={"configurable": {"thread_id": 42}}
|
||||
)
|
||||
final_state["messages"][-1].content
|
||||
```
|
||||
|
||||
```
|
||||
"Based on the search results, I can tell you that the current weather in San Francisco is:\n\nTemperature: 60 degrees Fahrenheit\nConditions: Foggy\n\nSan Francisco is known for its microclimates and frequent fog, especially during the summer months. The temperature of 60°F (about 15.5°C) is quite typical for the city, which tends to have mild temperatures year-round. The fog, often referred to as "Karl the Fog" by locals, is a characteristic feature of San Francisco\'s weather, particularly in the mornings and evenings.\n\nIs there anything else you\'d like to know about the weather in San Francisco or any other location?"
|
||||
```
|
||||
<b>Step-by-step Breakdown</b>:
|
||||
|
||||
Now when we pass the same `"thread_id"`, the conversation context is retained via the saved state (i.e. stored list of messages)
|
||||
<details>
|
||||
<summary>Initialize the model and tools.</summary>
|
||||
<ul>
|
||||
<li>
|
||||
We use <code>ChatAnthropic</code> as our LLM. <strong>NOTE:</strong> we need to make sure the model knows that it has these tools available to call. We can do this by converting the LangChain tools into the format for OpenAI tool calling using the <code>.bind_tools()</code> method.
|
||||
</li>
|
||||
<li>
|
||||
We define the tools we want to use - a search tool in our case. It is really easy to create your own tools - see documentation here on how to do that <a href="https://python.langchain.com/docs/how_to/custom_tools/">here</a>.
|
||||
</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
```python
|
||||
final_state = app.invoke(
|
||||
{"messages": [HumanMessage(content="what about ny")]},
|
||||
config={"configurable": {"thread_id": 42}}
|
||||
)
|
||||
final_state["messages"][-1].content
|
||||
```
|
||||
<details>
|
||||
<summary>Initialize graph with state.</summary>
|
||||
|
||||
```
|
||||
"Based on the search results, I can tell you that the current weather in New York City is:\n\nTemperature: 90 degrees Fahrenheit (approximately 32.2 degrees Celsius)\nConditions: Sunny\n\nThis weather is quite different from what we just saw in San Francisco. New York is experiencing much warmer temperatures right now. Here are a few points to note:\n\n1. The temperature of 90°F is quite hot, typical of summer weather in New York City.\n2. The sunny conditions suggest clear skies, which is great for outdoor activities but also means it might feel even hotter due to direct sunlight.\n3. This kind of weather in New York often comes with high humidity, which can make it feel even warmer than the actual temperature suggests.\n\nIt's interesting to see the stark contrast between San Francisco's mild, foggy weather and New York's hot, sunny conditions. This difference illustrates how varied weather can be across different parts of the United States, even on the same day.\n\nIs there anything else you'd like to know about the weather in New York or any other location?"
|
||||
```
|
||||
<ul>
|
||||
<li>We initialize graph (<code>StateGraph</code>) by passing state schema (in our case <code>MessagesState</code>)</li>
|
||||
<li><code>MessagesState</code> is a prebuilt state schema that has one attribute -- a list of LangChain <code>Message</code> objects, as well as logic for merging the updates from each node into the state.</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
### Step-by-step Breakdown
|
||||
<details>
|
||||
<summary>Define graph nodes.</summary>
|
||||
|
||||
1. <details>
|
||||
<summary>Initialize the model and tools.</summary>
|
||||
There are two main nodes we need:
|
||||
|
||||
- we use `ChatAnthropic` as our LLM. **NOTE:** we need make sure the model knows that it has these tools available to call. We can do this by converting the LangChain tools into the format for OpenAI tool calling using the `.bind_tools()` method.
|
||||
- we define the tools we want to use - a search tool in our case. It is really easy to create your own tools - see documentation here on how to do that [here](https://python.langchain.com/docs/modules/agents/tools/custom_tools).
|
||||
</details>
|
||||
<ul>
|
||||
<li>The <code>agent</code> node: responsible for deciding what (if any) actions to take.</li>
|
||||
<li>The <code>tools</code> node that invokes tools: if the agent decides to take an action, this node will then execute that action.</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
2. <details>
|
||||
<summary>Initialize graph with state.</summary>
|
||||
<details>
|
||||
<summary>Define entry point and graph edges.</summary>
|
||||
|
||||
- we initialize graph (`StateGraph`) by passing state schema (in our case `MessagesState`)
|
||||
- `MessagesState` is a prebuilt state schema that has one attribute -- a list of LangChain `Message` objects, as well as logic for merging the updates from each node into the state
|
||||
</details>
|
||||
First, we need to set the entry point for graph execution - <code>agent</code> node.
|
||||
|
||||
3. <details>
|
||||
<summary>Define graph nodes.</summary>
|
||||
Then we define one normal and one conditional edge. Conditional edge means that the destination depends on the contents of the graph's state (<code>MessagesState</code>). In our case, the destination is not known until the agent (LLM) decides.
|
||||
|
||||
There are two main nodes we need:
|
||||
<ul>
|
||||
<li>Conditional edge: after the agent is called, we should either:
|
||||
<ul>
|
||||
<li>a. Run tools if the agent said to take an action, OR</li>
|
||||
<li>b. Finish (respond to the user) if the agent did not ask to run tools</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Normal edge: after the tools are invoked, the graph should always return to the agent to decide what to do next</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
- The `agent` node: responsible for deciding what (if any) actions to take.
|
||||
- The `tools` node that invokes tools: if the agent decides to take an action, this node will then execute that action.
|
||||
</details>
|
||||
<details>
|
||||
<summary>Compile the graph.</summary>
|
||||
|
||||
4. <details>
|
||||
<summary>Define entry point and graph edges.</summary>
|
||||
<ul>
|
||||
<li>
|
||||
When we compile the graph, we turn it into a LangChain
|
||||
<a href="https://python.langchain.com/docs/concepts/runnables/">Runnable</a>,
|
||||
which automatically enables calling <code>.invoke()</code>, <code>.stream()</code> and <code>.batch()</code>
|
||||
with your inputs
|
||||
</li>
|
||||
<li>
|
||||
We can also optionally pass checkpointer object for persisting state between graph runs, and enabling memory,
|
||||
human-in-the-loop workflows, time travel and more. In our case we use <code>MemorySaver</code> -
|
||||
a simple in-memory checkpointer
|
||||
</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
First, we need to set the entry point for graph execution - `agent` node.
|
||||
<details>
|
||||
<summary>Execute the graph.</summary>
|
||||
|
||||
Then we define one normal and one conditional edge. Conditional edge means that the destination depends on the contents of the graph's state (`MessageState`). In our case, the destination is not known until the agent (LLM) decides.
|
||||
|
||||
- Conditional edge: after the agent is called, we should either:
|
||||
- a. Run tools if the agent said to take an action, OR
|
||||
- b. Finish (respond to the user) if the agent did not ask to run tools
|
||||
- Normal edge: after the tools are invoked, the graph should always return to the agent to decide what to do next
|
||||
</details>
|
||||
|
||||
5. <details>
|
||||
<summary>Compile the graph.</summary>
|
||||
|
||||
- When we compile the graph, we turn it into a LangChain [Runnable](https://python.langchain.com/v0.2/docs/concepts/#runnable-interface), which automatically enables calling `.invoke()`, `.stream()` and `.batch()` with your inputs
|
||||
- We can also optionally pass checkpointer object for persisting state between graph runs, and enabling memory, human-in-the-loop workflows, time travel and more. In our case we use `MemorySaver` - a simple in-memory checkpointer
|
||||
</details>
|
||||
|
||||
6. <details>
|
||||
<summary>Execute the graph.</summary>
|
||||
|
||||
1. LangGraph adds the input message to the internal state, then passes the state to the entrypoint node, `"agent"`.
|
||||
2. The `"agent"` node executes, invoking the chat model.
|
||||
3. The chat model returns an `AIMessage`. LangGraph adds this to the state.
|
||||
4. Graph cycles the following steps until there are no more `tool_calls` on `AIMessage`:
|
||||
|
||||
- If `AIMessage` has `tool_calls`, `"tools"` node executes
|
||||
- The `"agent"` node executes again and returns `AIMessage`
|
||||
|
||||
5. Execution progresses to the special `END` value and outputs the final state.
|
||||
And as a result, we get a list of all our chat messages as output.
|
||||
</details>
|
||||
<ol>
|
||||
<li>LangGraph adds the input message to the internal state, then passes the state to the entrypoint node, <code>"agent"</code>.</li>
|
||||
<li>The <code>"agent"</code> node executes, invoking the chat model.</li>
|
||||
<li>The chat model returns an <code>AIMessage</code>. LangGraph adds this to the state.</li>
|
||||
<li>Graph cycles the following steps until there are no more <code>tool_calls</code> on <code>AIMessage</code>:
|
||||
<ul>
|
||||
<li>If <code>AIMessage</code> has <code>tool_calls</code>, <code>"tools"</code> node executes</li>
|
||||
<li>The <code>"agent"</code> node executes again and returns <code>AIMessage</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Execution progresses to the special <code>END</code> value and outputs the final state. And as a result, we get a list of all our chat messages as output.</li>
|
||||
</ol>
|
||||
</details>
|
||||
|
||||
</details>
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -226,7 +328,11 @@ final_state["messages"][-1].content
|
||||
* [How-to Guides](https://langchain-ai.github.io/langgraph/how-tos/): Accomplish specific things within LangGraph, from streaming, to adding memory & persistence, to common design patterns (branching, subgraphs, etc.), these are the place to go if you want to copy and run a specific code snippet.
|
||||
* [Conceptual Guides](https://langchain-ai.github.io/langgraph/concepts/high_level/): In-depth explanations of the key concepts and principles behind LangGraph, such as nodes, edges, state and more.
|
||||
* [API Reference](https://langchain-ai.github.io/langgraph/reference/graphs/): Review important classes and methods, simple examples of how to use the graph and checkpointing APIs, higher-level prebuilt components and more.
|
||||
* [Cloud (beta)](https://langchain-ai.github.io/langgraph/cloud/): With one click, deploy LangGraph applications to LangGraph Cloud.
|
||||
* [LangGraph Platform](https://langchain-ai.github.io/langgraph/concepts/#langgraph-platform): LangGraph Platform is a commercial solution for deploying agentic applications in production, built on the open-source LangGraph framework.
|
||||
|
||||
## Resources
|
||||
|
||||
* [Built with LangGraph](https://www.langchain.com/built-with-langgraph): Hear how industry leaders use LangGraph to ship powerful, production-ready AI applications.
|
||||
|
||||
## Contributing
|
||||
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
site/
|
||||
docs/cloud/reference/sdk/js_ts_sdk_ref.md
|
||||
|
||||
.vercel
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
.PHONY: lint-docs format-docs build-docs serve-docs serve-clean-docs clean-docs codespell build-typedoc llms-text build-prebuilt
|
||||
|
||||
build-typedoc:
|
||||
cd ../libs/sdk-js && yarn install --include-dev && yarn typedoc
|
||||
cd ../libs/sdk-js && yarn --silent concat-md --decrease-title-levels --ignore=js_ts_sdk_ref.md --start-title-level-at 2 docs > ../../docs/docs/cloud/reference/sdk/js_ts_sdk_ref.md 2>/dev/null
|
||||
# Add links to the monorepo
|
||||
sed -e '1,10s|@langchain/langgraph-sdk|[@langchain/langgraph-sdk](https://github.com/langchain-ai/langgraph/tree/main/libs/sdk-js)|g' docs/cloud/reference/sdk/js_ts_sdk_ref.md > temp_file && mv temp_file docs/cloud/reference/sdk/js_ts_sdk_ref.md
|
||||
|
||||
build-prebuilt:
|
||||
# Use to create an update to date prebuilt page.
|
||||
# Looks up download stats for each of the prebuilt packages and
|
||||
# generates the final prebuilt page.
|
||||
poetry run python -m _scripts.third_party_page.get_download_stats stats.yml
|
||||
poetry run python -m _scripts.third_party_page.create_third_party_page stats.yml docs/prebuilt.md --language python
|
||||
|
||||
build-docs: build-typedoc build-prebuilt
|
||||
poetry run python -m mkdocs build --clean -f mkdocs.yml --strict
|
||||
|
||||
llms-text:
|
||||
poetry run python _scripts/generate_llms_text.py docs/llms-full.txt
|
||||
|
||||
install-vercel-deps:
|
||||
dnf install -y python3.11
|
||||
curl -sSL https://install.python-poetry.org | python3 -
|
||||
poetry self update 1.8.5
|
||||
# don't use vercel's python - it wasn't compiled with sqlite support, and it fails when installing ipython's kernel
|
||||
poetry env use /usr/bin/python3.11
|
||||
poetry install --with docs --with test --no-root
|
||||
poetry run pip install "git+https://github.com/benjamincburns/markdown-exec.git@cc0d39d737e5ffd4b83d23cd8729d7ea16e363c8"
|
||||
poetry run python3 -m ipykernel install --name=python3
|
||||
npm install -g tslab
|
||||
poetry run tslab install --python=python3
|
||||
poetry run jupyter kernelspec list
|
||||
|
||||
|
||||
vercel-build-docs: install-vercel-deps
|
||||
make build-docs
|
||||
|
||||
|
||||
serve-clean-docs: clean-docs
|
||||
poetry run python -m mkdocs serve -c -f mkdocs.yml --strict -w ../libs/langgraph
|
||||
|
||||
serve-docs: build-typedoc
|
||||
poetry run python -m mkdocs serve -f mkdocs.yml -w ../libs/langgraph -w ../libs/checkpoint -w ../libs/sdk-py --dirty
|
||||
|
||||
clean-docs:
|
||||
find ./docs -name "*.ipynb" -type f -delete
|
||||
rm -rf site
|
||||
|
||||
## Run format against the project documentation.
|
||||
format-docs:
|
||||
poetry run ruff format docs
|
||||
poetry run ruff check --fix docs
|
||||
|
||||
# Check the docs for linting violations
|
||||
lint-docs:
|
||||
poetry run ruff format --check docs
|
||||
poetry run ruff check docs
|
||||
|
||||
codespell:
|
||||
./codespell_notebooks.sh .
|
||||
|
||||
start-services:
|
||||
docker compose -f test-compose.yml up -V --force-recreate --wait --remove-orphans
|
||||
|
||||
stop-services:
|
||||
docker compose -f test-compose.yml down
|
||||
+7
-9
@@ -19,23 +19,21 @@ make serve-docs
|
||||
If you would like to automatically execute all of the notebooks, to mimic the "Run notebooks" GHA, you can run:
|
||||
|
||||
```bash
|
||||
python docs/_scripts/prepare_notebooks_for_ci.py
|
||||
./docs/_scripts/execute_notebooks.sh
|
||||
python _scripts/prepare_notebooks_for_ci.py
|
||||
./_scripts/execute_notebooks.sh
|
||||
```
|
||||
|
||||
**Note**: if you want to run the notebooks without `%pip install` cells, you can run:
|
||||
|
||||
```bash
|
||||
python docs/_scripts/prepare_notebooks_for_ci.py --comment-install-cells
|
||||
./docs/_scripts/execute_notebooks.sh
|
||||
python _scripts/prepare_notebooks_for_ci.py --comment-install-cells
|
||||
./_scripts/execute_notebooks.sh
|
||||
```
|
||||
|
||||
`prepare_notebooks_for_ci.py` script will add VCR cassette context manager for each cell in the notebook, so that:
|
||||
* when the notebook is run for the first time, cells with network requests will be recorded to a VCR cassette file
|
||||
* when the notebook is run subsequently, the cells with network requests will be replayed from the cassettes
|
||||
|
||||
**Note**: this is currently limited only to the notebooks in `docs/docs/how-tos`
|
||||
|
||||
## Adding new notebooks
|
||||
|
||||
If you are adding a notebook with API requests, it's **recommended** to record network requests so that they can be subsequently replayed. If this is not done, the notebook runner will make API requests every time the notebook is run, which can be costly and slow.
|
||||
@@ -48,14 +46,14 @@ Then, run
|
||||
jupyter execute <path_to_notebook>
|
||||
```
|
||||
|
||||
Once the notebook is executed, you should see the new VCR cassettes recorded in `docs/cassettes` directory and discard the updated notebook.
|
||||
Once the notebook is executed, you should see the new VCR cassettes recorded in `cassettes` directory and discard the updated notebook.
|
||||
|
||||
## Updating existing notebooks
|
||||
|
||||
If you are updating an existing notebook, please make sure to remove any existing cassettes for the notebook in `docs/cassettes` directory (each cassette is prefixed with the notebook name), and then run the steps from the "Adding new notebooks" section above.
|
||||
If you are updating an existing notebook, please make sure to remove any existing cassettes for the notebook in `cassettes` directory (each cassette is prefixed with the notebook name), and then run the steps from the "Adding new notebooks" section above.
|
||||
|
||||
To delete cassettes for a notebook, you can run:
|
||||
|
||||
```bash
|
||||
rm docs/cassettes/<notebook_name>*
|
||||
rm cassettes/<notebook_name>*
|
||||
```
|
||||
@@ -0,0 +1,93 @@
|
||||
import functools
|
||||
|
||||
from urllib3 import __version__ as urllib3version # type: ignore[import-untyped]
|
||||
from urllib3 import connection # type: ignore[import-untyped]
|
||||
|
||||
|
||||
def _ensure_str(s, encoding="utf-8", errors="strict") -> str:
|
||||
if isinstance(s, str):
|
||||
return s
|
||||
|
||||
if isinstance(s, bytes):
|
||||
return s.decode(encoding, errors)
|
||||
return str(s)
|
||||
|
||||
|
||||
# Copied from https://github.com/urllib3/urllib3/blob/1c994dfc8c5d5ecaee8ed3eb585d4785f5febf6e/src/urllib3/connection.py#L231
|
||||
def request(self, method, url, body=None, headers=None):
|
||||
"""Make the request.
|
||||
|
||||
This function is based on the urllib3 request method, with modifications
|
||||
to handle potential issues when using vcrpy in concurrent workloads.
|
||||
|
||||
Args:
|
||||
self: The HTTPConnection instance.
|
||||
method (str): The HTTP method (e.g., 'GET', 'POST').
|
||||
url (str): The URL for the request.
|
||||
body (Optional[Any]): The body of the request.
|
||||
headers (Optional[dict]): Headers to send with the request.
|
||||
|
||||
Returns:
|
||||
The result of calling the parent request method.
|
||||
"""
|
||||
# Update the inner socket's timeout value to send the request.
|
||||
# This only triggers if the connection is reused.
|
||||
if getattr(self, "sock", None) is not None:
|
||||
self.sock.settimeout(self.timeout)
|
||||
|
||||
if headers is None:
|
||||
headers = {}
|
||||
else:
|
||||
# Avoid modifying the headers passed into .request()
|
||||
headers = headers.copy()
|
||||
if "user-agent" not in (_ensure_str(k.lower()) for k in headers):
|
||||
headers["User-Agent"] = connection._get_default_user_agent()
|
||||
# The above is all the same ^^^
|
||||
# The following is different:
|
||||
return self._parent_request(method, url, body=body, headers=headers)
|
||||
|
||||
|
||||
_PATCHED = False
|
||||
|
||||
|
||||
def patch_urllib3():
|
||||
"""Patch the request method of urllib3 to avoid type errors when using vcrpy.
|
||||
|
||||
In concurrent workloads (such as the tracing background queue), the
|
||||
connection pool can get in a state where an HTTPConnection is created
|
||||
before vcrpy patches the HTTPConnection class. In urllib3 >= 2.0 this isn't
|
||||
a problem since they use the proper super().request(...) syntax, but in older
|
||||
versions, super(HTTPConnection, self).request is used, resulting in a TypeError
|
||||
since self is no longer a subclass of "HTTPConnection" (which at this point
|
||||
is vcr.stubs.VCRConnection).
|
||||
|
||||
This method patches the class to fix the super() syntax to avoid mixed inheritance.
|
||||
In the case of the LangSmith tracing logic, it doesn't really matter since we always
|
||||
exclude cache checks for calls to LangSmith.
|
||||
|
||||
The patch is only applied for urllib3 versions older than 2.0.
|
||||
"""
|
||||
global _PATCHED
|
||||
if _PATCHED:
|
||||
return
|
||||
from packaging import version
|
||||
|
||||
if version.parse(urllib3version) >= version.parse("2.0"):
|
||||
_PATCHED = True
|
||||
return
|
||||
|
||||
# Lookup the parent class and its request method
|
||||
parent_class = connection.HTTPConnection.__bases__[0]
|
||||
parent_request = parent_class.request
|
||||
|
||||
def new_request(self, *args, **kwargs):
|
||||
"""Handle parent request.
|
||||
|
||||
This method binds the parent's request method to self and then
|
||||
calls our modified request function.
|
||||
"""
|
||||
self._parent_request = functools.partial(parent_request, self)
|
||||
return request(self, *args, **kwargs)
|
||||
|
||||
connection.HTTPConnection.request = new_request
|
||||
_PATCHED = True
|
||||
@@ -0,0 +1,157 @@
|
||||
"""Add typescript translation to a given markdown file."""
|
||||
|
||||
import argparse
|
||||
import re
|
||||
|
||||
import requests
|
||||
from langchain_anthropic import ChatAnthropic
|
||||
|
||||
URL = "https://gist.githubusercontent.com/eyurtsev/e7486731415463a9bc5b4682358859c8/raw/b5a5fda9c7e3387cfcb781f25082814d43675d50/gistfile1.txt"
|
||||
response = requests.get(URL)
|
||||
response.raise_for_status()
|
||||
reference_snippets = response.text
|
||||
|
||||
model = ChatAnthropic(model="claude-3-5-sonnet-latest")
|
||||
|
||||
|
||||
def _get_tqdm():
|
||||
try:
|
||||
from tqdm import tqdm
|
||||
except ImportError:
|
||||
# If not available return a simple identity function
|
||||
def tqdm(iterable, *args, **kwargs):
|
||||
return iterable
|
||||
|
||||
return tqdm
|
||||
|
||||
|
||||
_tqdm = _get_tqdm()
|
||||
|
||||
opening_pattern = re.compile(r"^\s*```python(?:\s+.*)?\s*$")
|
||||
closing_pattern = re.compile(r"^\s*```\s*$")
|
||||
|
||||
|
||||
def extract_python_snippets(markdown: str) -> list[str]:
|
||||
"""
|
||||
Extract all python code blocks (including their fence lines) from the markdown content.
|
||||
A python block is defined as any block that starts with a line containing an opening fence
|
||||
with '```python' (optionally with extra parameters) and ends with a closing fence '```'.
|
||||
"""
|
||||
snippets = []
|
||||
inside_block = False
|
||||
current_snippet = []
|
||||
|
||||
for line in markdown.splitlines(keepends=True):
|
||||
if not inside_block:
|
||||
if opening_pattern.match(line):
|
||||
inside_block = True
|
||||
current_snippet = [line]
|
||||
else:
|
||||
current_snippet.append(line)
|
||||
if closing_pattern.match(line):
|
||||
inside_block = False
|
||||
snippets.append("".join(current_snippet))
|
||||
current_snippet = []
|
||||
return snippets
|
||||
|
||||
|
||||
def translate_snippet(python_snippet: str) -> str:
|
||||
"""Translate a python code block into a TypeScript code block using Langchain.
|
||||
The response is expected to be a properly fenced TypeScript code block (i.e.
|
||||
starting with ```typescript and ending with ```).
|
||||
"""
|
||||
ai_message = model.invoke(
|
||||
[
|
||||
{
|
||||
"role": "system",
|
||||
"content": (
|
||||
f"You have access to the following up-to-date example TypeScript code "
|
||||
f"snippets that show examples of building with langgraph "
|
||||
f"and langchain:\n\n{reference_snippets}\n\n"
|
||||
"Use this context to translate the following Python code to equivalent "
|
||||
"TypeScript. Ensure that your output is a valid fenced TypeScript "
|
||||
"code block (i.e. starts with ```typescript and ends with ```)."
|
||||
),
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": f"Translate this Python snippet to TypeScript:\n\n{python_snippet}",
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
# Use a regular expression to search for a TypeScript code block in the response.
|
||||
pattern = r"```typescript\s*(.*?)\s*```"
|
||||
match = re.search(pattern, ai_message.content, re.DOTALL)
|
||||
if match:
|
||||
# Reconstruct the code block with proper fences.
|
||||
typescript_code = match.group(1).strip()
|
||||
return f"```typescript\n{typescript_code}\n```"
|
||||
else:
|
||||
raise ValueError("No TypeScript code block found in the model's response.")
|
||||
|
||||
|
||||
def insert_translations_into_markdown(
|
||||
markdown: str, typescript_snippets: list[str]
|
||||
) -> str:
|
||||
"""Walks through the original markdown content and, after each
|
||||
Python snippet block, inserts the corresponding translated TypeScript snippet.
|
||||
It assumes that the ordering of the Python snippets
|
||||
(from extract_python_snippets) matches the order they appear in the markdown.
|
||||
"""
|
||||
output_lines = []
|
||||
lines = markdown.splitlines(keepends=True)
|
||||
inside_block = False
|
||||
snippet_index = 0
|
||||
|
||||
for line in lines:
|
||||
output_lines.append(line)
|
||||
if not inside_block and opening_pattern.match(line):
|
||||
# We've encountered the start of a python code block.
|
||||
inside_block = True
|
||||
elif inside_block:
|
||||
if closing_pattern.match(line):
|
||||
# End of a python snippet block.
|
||||
inside_block = False
|
||||
if snippet_index < len(typescript_snippets):
|
||||
# Insert an extra newline for clarity, then the translated TypeScript snippet.
|
||||
output_lines.append("\n")
|
||||
output_lines.append(typescript_snippets[snippet_index])
|
||||
output_lines.append("\n")
|
||||
snippet_index += 1
|
||||
return "".join(output_lines)
|
||||
|
||||
|
||||
def main(file_path: str) -> None:
|
||||
# Read the markdown file.
|
||||
with open(file_path, "r") as f:
|
||||
markdown_content = f.read()
|
||||
|
||||
# 1. Extract all Python snippets.
|
||||
python_snippets = extract_python_snippets(markdown_content)[:1]
|
||||
|
||||
# 2. Translate each Python snippet to TypeScript.
|
||||
typescript_snippets = []
|
||||
# Replace with .batch() for faster translation
|
||||
for python_snippet in _tqdm(python_snippets):
|
||||
ts_snippet = translate_snippet(python_snippet)
|
||||
typescript_snippets.append(ts_snippet)
|
||||
|
||||
# 3. Insert the TypeScript translations after their respective Python snippets.
|
||||
updated_markdown = insert_translations_into_markdown(
|
||||
markdown_content, typescript_snippets
|
||||
)
|
||||
|
||||
# Overwrite the original markdown file with the updated content.
|
||||
with open(file_path, "w") as f:
|
||||
f.write(updated_markdown)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Translate Python snippets in a markdown file to TypeScript and insert them after each Python snippet."
|
||||
)
|
||||
parser.add_argument("file_path", type=str, help="Path to the markdown file.")
|
||||
args = parser.parse_args()
|
||||
|
||||
main(args.file_path)
|
||||
@@ -0,0 +1,75 @@
|
||||
import nock, { Definition } from "nock";
|
||||
import msgpack from "msgpack-lite";
|
||||
import zlib from "node:zlib";
|
||||
import fs from "node:fs/promises";
|
||||
import { Buffer } from "node:buffer";
|
||||
|
||||
// deno style imports here because we're running this in the deno jupyter kernel
|
||||
|
||||
interface NockCassetteData {
|
||||
hash: string;
|
||||
entries: Definition[];
|
||||
}
|
||||
|
||||
// Utility functions for compression & serialization
|
||||
function compressData(data: NockCassetteData, compressionLevel = 9): string {
|
||||
const packed = msgpack.encode(data);
|
||||
const compressed = zlib.deflateSync(packed, { level: compressionLevel });
|
||||
return compressed.toString("base64");
|
||||
}
|
||||
|
||||
function decompressData(compressedString: string): NockCassetteData {
|
||||
const decoded = Buffer.from(compressedString, "base64");
|
||||
const decompressed = zlib.inflateSync(decoded);
|
||||
return msgpack.decode(decompressed) as NockCassetteData;
|
||||
}
|
||||
|
||||
// deno-lint-ignore no-unused-vars
|
||||
class HashedCassette {
|
||||
private recording = true;
|
||||
|
||||
constructor(
|
||||
private readonly cassettePath: string,
|
||||
private readonly hash: string
|
||||
) {}
|
||||
|
||||
async enter() {
|
||||
try {
|
||||
const rawCassette = await fs.readFile(this.cassettePath, "utf-8");
|
||||
const data = decompressData(rawCassette);
|
||||
if (data.hash === this.hash) {
|
||||
this.recording = false;
|
||||
nock.disableNetConnect();
|
||||
nock.define(data.entries);
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Error && error.message.includes("ENOENT")) {
|
||||
this.recording = true;
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
nock.recorder.rec({
|
||||
dont_print: true,
|
||||
output_objects: true,
|
||||
});
|
||||
}
|
||||
|
||||
async exit() {
|
||||
if (this.recording) {
|
||||
const entries = nock.recorder.play() as Definition[];
|
||||
const data = {
|
||||
hash: this.hash,
|
||||
entries,
|
||||
};
|
||||
const compressed = compressData(data);
|
||||
await fs.writeFile(this.cassettePath, compressed);
|
||||
} else {
|
||||
nock.enableNetConnect();
|
||||
nock.restore();
|
||||
nock.cleanAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
import base64
|
||||
import os
|
||||
import zlib
|
||||
from types import TracebackType
|
||||
from typing import Optional, Any, Type
|
||||
|
||||
import msgpack
|
||||
import vcr
|
||||
|
||||
os.environ.pop("LANGCHAIN_TRACING_V2", None)
|
||||
custom_vcr = vcr.VCR()
|
||||
|
||||
|
||||
def compress_data(data: Any, compression_level: int = 9) -> str:
|
||||
packed = msgpack.packb(data, use_bin_type=True)
|
||||
compressed = zlib.compress(packed, level=compression_level)
|
||||
return base64.b64encode(compressed).decode("utf-8")
|
||||
|
||||
|
||||
def decompress_data(compressed_string: str) -> Any:
|
||||
decoded = base64.b64decode(compressed_string)
|
||||
decompressed = zlib.decompress(decoded)
|
||||
return msgpack.unpackb(decompressed, raw=False)
|
||||
|
||||
|
||||
class AdvancedCompressedSerializer:
|
||||
def serialize(self, cassette_dict: Any) -> str:
|
||||
return compress_data(cassette_dict)
|
||||
|
||||
def deserialize(self, cassette_string: str) -> Any:
|
||||
return decompress_data(cassette_string)
|
||||
|
||||
|
||||
custom_vcr.register_serializer("advanced_compressed", AdvancedCompressedSerializer())
|
||||
custom_vcr.serializer = "advanced_compressed"
|
||||
|
||||
|
||||
class HashedCassette:
|
||||
def __init__(self, cassette_path: str, hash_value: str) -> None:
|
||||
"""A context manager for using VCR cassettes with an embedded hash value.
|
||||
|
||||
Args:
|
||||
cassette_path (str): The file path of the cassette (independent of hash).
|
||||
hash_value (str): The expected hash value (e.g. a uuid string).
|
||||
|
||||
This class provides a context manager for using VCR cassettes with an embedded hash value.
|
||||
The hash value is used to ensure that the cassette matches the expected state, and if not,
|
||||
the cassette is removed or updated with the new hash value.
|
||||
"""
|
||||
self.cassette_path: str = cassette_path
|
||||
self.hash_value: str = hash_value
|
||||
self.vcr: vcr.VCR = custom_vcr
|
||||
self.cassette_context: Optional[Any] = None
|
||||
self.exited: bool = False
|
||||
|
||||
def __enter__(self) -> Any:
|
||||
self.exited: bool = False
|
||||
# Get the serializer instance from the VCR instance.
|
||||
serializer = self.vcr.serializers[self.vcr.serializer]
|
||||
# If the cassette file exists, check its embedded hash.
|
||||
if os.path.exists(self.cassette_path):
|
||||
with open(self.cassette_path, "r") as f:
|
||||
content = f.read()
|
||||
try:
|
||||
cassette_data = serializer.deserialize(content)
|
||||
except Exception as e:
|
||||
os.remove(self.cassette_path)
|
||||
else:
|
||||
existing_hash = cassette_data.get("cassette_hash")
|
||||
if existing_hash != self.hash_value:
|
||||
os.remove(self.cassette_path)
|
||||
# Now enter the VCR cassette context.
|
||||
self.cassette_context = custom_vcr.use_cassette(
|
||||
self.cassette_path,
|
||||
filter_headers=["x-api-key", "authorization"],
|
||||
record_mode="once",
|
||||
serializer="advanced_compressed",
|
||||
)
|
||||
return self.cassette_context.__enter__()
|
||||
|
||||
def __exit__(
|
||||
self,
|
||||
exc_type: Optional[Type[BaseException]] = None,
|
||||
exc_val: Optional[BaseException] = None,
|
||||
exc_tb: Optional[TracebackType] = None,
|
||||
) -> Optional[bool]:
|
||||
if self.exited:
|
||||
return
|
||||
self.exited = True
|
||||
# Exit the VCR cassette context.
|
||||
result = self.cassette_context.__exit__(exc_type, exc_val, exc_tb)
|
||||
serializer = self.vcr.serializers[self.vcr.serializer]
|
||||
# If a cassette was recorded (or updated), open and update its hash.
|
||||
if os.path.exists(self.cassette_path):
|
||||
with open(self.cassette_path, "r") as f:
|
||||
content = f.read()
|
||||
try:
|
||||
cassette_data = serializer.deserialize(content)
|
||||
except Exception as e:
|
||||
return result
|
||||
# Update the cassette data with the expected hash.
|
||||
if cassette_data.get("cassette_hash") != self.hash_value:
|
||||
cassette_data["cassette_hash"] = self.hash_value
|
||||
serialized_data = serializer.serialize(cassette_data)
|
||||
with open(self.cassette_path, "w") as f:
|
||||
f.write(serialized_data)
|
||||
return result
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Read the list of notebooks to skip from the JSON file
|
||||
SKIP_NOTEBOOKS=$(python -c "import json; print('\n'.join(json.load(open('docs/notebooks_no_execution.json'))))")
|
||||
SKIP_NOTEBOOKS=$(python -c "import json; print('\n'.join(json.load(open('notebooks_no_execution.json'))))")
|
||||
|
||||
# Function to execute a single notebook
|
||||
execute_notebook() {
|
||||
@@ -27,7 +27,7 @@ if [ $# -gt 0 ]; then
|
||||
notebooks=$(echo "$@" | tr ' ' '\n' | grep -vFf <(echo "$SKIP_NOTEBOOKS"))
|
||||
else
|
||||
# Find all notebooks and filter out those in the skip list
|
||||
notebooks=$(find docs/docs/tutorials docs/docs/how-tos -name "*.ipynb" | grep -v ".ipynb_checkpoints" | grep -vFf <(echo "$SKIP_NOTEBOOKS"))
|
||||
notebooks=$(find docs/tutorials docs/how-tos -name "*.ipynb" | grep -v ".ipynb_checkpoints" | grep -vFf <(echo "$SKIP_NOTEBOOKS"))
|
||||
fi
|
||||
|
||||
# Execute notebooks sequentially
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
import importlib
|
||||
import inspect
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
from functools import lru_cache
|
||||
from typing import List, Literal, Optional
|
||||
|
||||
from typing_extensions import TypedDict
|
||||
|
||||
import nbformat
|
||||
from nbconvert.preprocessors import Preprocessor
|
||||
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
# Base URL for all class documentation
|
||||
@@ -47,6 +44,10 @@ MANUAL_API_REFERENCES_LANGGRAPH = [
|
||||
(["langgraph.graph"], "langgraph.constants", "END", "constants"),
|
||||
(["langgraph.constants"], "langgraph.types", "Send", "types"),
|
||||
(["langgraph.constants"], "langgraph.types", "Interrupt", "types"),
|
||||
(["langgraph.constants"], "langgraph.types", "interrupt", "types"),
|
||||
(["langgraph.constants"], "langgraph.types", "Command", "types"),
|
||||
(["langgraph.func"], "langgraph.func", "entrypoint", "func"),
|
||||
(["langgraph.func"], "langgraph.func", "task", "func"),
|
||||
([], "langgraph.types", "RetryPolicy", "types"),
|
||||
([], "langgraph.checkpoint.base", "Checkpoint", "checkpoints"),
|
||||
([], "langgraph.checkpoint.base", "CheckpointMetadata", "checkpoints"),
|
||||
@@ -83,8 +84,9 @@ _IMPORT_LANGCHAIN_RE = _make_regular_expression("langchain")
|
||||
_IMPORT_LANGGRAPH_RE = _make_regular_expression("langgraph")
|
||||
|
||||
|
||||
def _get_full_module_name(module_path, class_name) -> Optional[str]:
|
||||
"""Get full module name using inspect"""
|
||||
@lru_cache(maxsize=10_000)
|
||||
def _get_full_module_name(module_path: str, class_name: str) -> Optional[str]:
|
||||
"""Get full module name using inspect, with LRU cache to memoize results."""
|
||||
try:
|
||||
module = importlib.import_module(module_path)
|
||||
class_ = getattr(module, class_name)
|
||||
@@ -95,10 +97,10 @@ def _get_full_module_name(module_path, class_name) -> Optional[str]:
|
||||
return module_path
|
||||
return module.__name__
|
||||
except AttributeError as e:
|
||||
logger.warning(f"Could not find module for {class_name}, {e}")
|
||||
logger.warning(f"API Reference: Could not find module for {class_name}, {e}")
|
||||
return None
|
||||
except ImportError as e:
|
||||
logger.warning(f"Failed to load for class {class_name}, {e}")
|
||||
logger.warning(f"API Reference: Failed to load for class {class_name}, {e}")
|
||||
return None
|
||||
|
||||
|
||||
@@ -115,10 +117,10 @@ def _get_doc_title(data: str, file_name: str) -> str:
|
||||
|
||||
|
||||
class ImportInformation(TypedDict):
|
||||
imported: str # imported class name
|
||||
source: str # module path
|
||||
docs: str # URL to the documentation
|
||||
title: str # Title of the document
|
||||
imported: str # The name of the class that was imported.
|
||||
source: str # The full module path from which the class was imported.
|
||||
docs: str # The URL pointing to the class's documentation.
|
||||
title: str # The title of the document where the import is used.
|
||||
|
||||
|
||||
def _get_imports(
|
||||
@@ -211,36 +213,73 @@ def _get_imports(
|
||||
return imports
|
||||
|
||||
|
||||
class ImportPreprocessor(Preprocessor):
|
||||
"""A preprocessor to replace imports in each Python code cell with links to their
|
||||
documentation and append the import info in a comment."""
|
||||
def get_imports(code: str, doc_title: str) -> List[ImportInformation]:
|
||||
"""Retrieve all import references from the given code for specified ecosystems.
|
||||
|
||||
def preprocess(self, nb, resources):
|
||||
self.all_imports = []
|
||||
file_name = os.path.basename(resources.get("metadata", {}).get("name", ""))
|
||||
_DOC_TITLE = _get_doc_title(nb.cells[0].source, file_name)
|
||||
Args:
|
||||
code: The source code from which to extract import references.
|
||||
doc_title: The documentation title associated with the code.
|
||||
|
||||
cells = []
|
||||
for cell in nb.cells:
|
||||
if cell.cell_type == "code":
|
||||
cells.append(cell)
|
||||
imports = _get_imports(
|
||||
cell.source, _DOC_TITLE, "langchain"
|
||||
) + _get_imports(cell.source, _DOC_TITLE, "langgraph")
|
||||
if not imports:
|
||||
continue
|
||||
Returns:
|
||||
A list of import information for each import found.
|
||||
"""
|
||||
ecosystems = ["langchain", "langgraph"]
|
||||
all_imports = []
|
||||
for package_ecosystem in ecosystems:
|
||||
all_imports.extend(_get_imports(code, doc_title, package_ecosystem))
|
||||
return all_imports
|
||||
|
||||
cells.append(
|
||||
nbformat.v4.new_markdown_cell(
|
||||
source=f"""
|
||||
<div>
|
||||
<b>API Reference:</b>
|
||||
{' | '.join(f'<a href="{imp["docs"]}">{imp["imported"]}</a>' for imp in imports)}
|
||||
</div>
|
||||
"""
|
||||
)
|
||||
)
|
||||
else:
|
||||
cells.append(cell)
|
||||
nb.cells = cells
|
||||
return nb, resources
|
||||
|
||||
def update_markdown_with_imports(markdown: str) -> str:
|
||||
"""Update markdown to include API reference links for imports in Python code blocks.
|
||||
|
||||
This function scans the markdown content for Python code blocks, extracts any imports, and appends links to their API documentation.
|
||||
|
||||
Args:
|
||||
markdown: The markdown content to process.
|
||||
|
||||
Returns:
|
||||
Updated markdown with API reference links appended to Python code blocks.
|
||||
|
||||
Example:
|
||||
Given a markdown with a Python code block:
|
||||
|
||||
```python
|
||||
from langchain.nlp import TextGenerator
|
||||
```
|
||||
This function will append an API reference link to the `TextGenerator` class from the `langchain.nlp` module if it's recognized.
|
||||
"""
|
||||
code_block_pattern = re.compile(
|
||||
r'(?P<indent>[ \t]*)```(?P<language>python|py)\n(?P<code>.*?)\n(?P=indent)```', re.DOTALL
|
||||
)
|
||||
|
||||
def replace_code_block(match: re.Match) -> str:
|
||||
"""Replace the matched code block with additional API reference links if imports are found.
|
||||
|
||||
Args:
|
||||
match (re.Match): The regex match object containing the code block.
|
||||
|
||||
Returns:
|
||||
str: The modified code block with API reference links appended if applicable.
|
||||
"""
|
||||
indent = match.group('indent')
|
||||
code_block = match.group('code')
|
||||
language = match.group('language') # Preserve the language from the regex match
|
||||
# Retrieve import information from the code block
|
||||
imports = get_imports(code_block, "__unused__")
|
||||
|
||||
original_code_block = match.group(0)
|
||||
# If no imports are found, return the original code block
|
||||
if not imports:
|
||||
return original_code_block
|
||||
|
||||
# Generate API reference links for each import
|
||||
api_links = ' | '.join(
|
||||
f'<a href="{imp["docs"]}">{imp["imported"]}</a>' for imp in imports
|
||||
)
|
||||
# Return the code block with appended API reference links
|
||||
return f'{original_code_block}\n\n{indent}API Reference: {api_links}'
|
||||
|
||||
# Apply the replace_code_block function to all matches in the markdown
|
||||
updated_markdown = code_block_pattern.sub(replace_code_block, markdown)
|
||||
return updated_markdown
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
"""Experimental script to generate consolidated llms text from the docs."""
|
||||
|
||||
import glob
|
||||
import os
|
||||
import pathlib
|
||||
|
||||
from mkdocs.structure.files import File
|
||||
from mkdocs.structure.pages import Page
|
||||
|
||||
from notebook_hooks import _on_page_markdown_with_config
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
# Get source directory (parent of HERE / docs)
|
||||
SOURCE_DIR = os.path.abspath(os.path.join(os.path.dirname(HERE), "docs"))
|
||||
|
||||
|
||||
def _make_llms_text(output_file: str) -> str:
|
||||
"""Generate a consolidated text file from markdown/notebook files for LLM training.
|
||||
|
||||
Args:
|
||||
output_file: Path to output the consolidated text file
|
||||
"""
|
||||
# Collect all markdown and notebook files
|
||||
relative_paths = [
|
||||
# Files relative to docs/docs/
|
||||
"tutorials/introduction.ipynb",
|
||||
]
|
||||
all_files = [os.path.join(SOURCE_DIR, path) for path in relative_paths]
|
||||
|
||||
all_files.extend(
|
||||
glob.glob(os.path.join(SOURCE_DIR, "how-tos/*.md"), recursive=True)
|
||||
)
|
||||
all_files.extend(
|
||||
glob.glob(os.path.join(SOURCE_DIR, "how-tos/*.ipynb"), recursive=True)
|
||||
)
|
||||
# Add all concepts
|
||||
all_files.extend(
|
||||
glob.glob(os.path.join(SOURCE_DIR, "concepts/*.md"), recursive=True)
|
||||
)
|
||||
all_files.extend(
|
||||
glob.glob(os.path.join(SOURCE_DIR, "concepts/*.ipynb"), recursive=True)
|
||||
)
|
||||
|
||||
all_content = []
|
||||
|
||||
# Process each file
|
||||
for file_path in all_files:
|
||||
print(f"Processing {file_path}")
|
||||
rel_path = os.path.relpath(file_path, SOURCE_DIR)
|
||||
|
||||
# Create File and Page objects to match mkdocs structure
|
||||
file_obj = File(
|
||||
path=rel_path, src_dir=SOURCE_DIR, dest_dir="", use_directory_urls=True
|
||||
)
|
||||
page = Page(
|
||||
title="",
|
||||
file=file_obj,
|
||||
config={},
|
||||
)
|
||||
|
||||
# Read raw content
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
|
||||
# Convert to markdown without logic to resolve API references
|
||||
processed_content = _on_page_markdown_with_config(
|
||||
content, page, add_api_references=False, remove_base64_images=True
|
||||
)
|
||||
if processed_content:
|
||||
# Add file name
|
||||
all_content.append(f"---\n{rel_path}\n---")
|
||||
# Add content
|
||||
all_content.append(processed_content)
|
||||
|
||||
# Write consolidated output
|
||||
with open(output_file, "w", encoding="utf-8") as f:
|
||||
f.write("\n\n".join(all_content))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description=(
|
||||
"Generate consolidated text file from markdown/notebook files for LLMs."
|
||||
)
|
||||
)
|
||||
parser.add_argument("output_file", help="Path to output the consolidated text file")
|
||||
|
||||
args = parser.parse_args()
|
||||
_make_llms_text(args.output_file)
|
||||
@@ -1,30 +1,54 @@
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import Literal, Optional
|
||||
|
||||
import nbformat
|
||||
from nbconvert.exporters import MarkdownExporter
|
||||
from nbconvert.preprocessors import Preprocessor
|
||||
|
||||
from generate_api_reference_links import ImportPreprocessor
|
||||
|
||||
|
||||
class EscapePreprocessor(Preprocessor):
|
||||
def __init__(self, rewrite_links: bool = True, **kwargs) -> None:
|
||||
super().__init__(**kwargs)
|
||||
self.rewrite_links = rewrite_links
|
||||
|
||||
def preprocess_cell(self, cell, resources, cell_index):
|
||||
if cell.cell_type == "markdown":
|
||||
# rewrite markdown links to html links (excluding image links)
|
||||
cell.source = re.sub(
|
||||
r"(?<!!)\[([^\]]*)\]\((?![^\)]*//)([^)]*)(?:\.ipynb)?\)",
|
||||
r'<a href="\2">\1</a>',
|
||||
cell.source,
|
||||
)
|
||||
if self.rewrite_links:
|
||||
# We'll need to adjust the logic for this to keep markdown format
|
||||
# but link to markdown files rather than ipynb files.
|
||||
cell.source = re.sub(
|
||||
r"(?<!!)\[([^\]]*)\]\((?![^\)]*//)([^)]*)(?:\.ipynb)?\)",
|
||||
r'<a href="\2">\1</a>',
|
||||
cell.source,
|
||||
)
|
||||
else:
|
||||
# Keep format but replace the .ipynb extension with .md
|
||||
cell.source = re.sub(
|
||||
r"(?<!!)\[([^\]]*)\]\((?![^\)]*//)([^)]*)(?:\.ipynb)?\)",
|
||||
r"[\1](\2.md)",
|
||||
cell.source,
|
||||
)
|
||||
|
||||
# Fix image paths in <img> tags
|
||||
cell.source = re.sub(
|
||||
r'<img\s+src="\.?/img/([^"]+)"', r'<img src="../img/\1"', cell.source
|
||||
)
|
||||
|
||||
elif cell.cell_type == "code":
|
||||
# Determine if the cell has bash or cell magic
|
||||
if cell.source.startswith("%") or cell.source.startswith("!"):
|
||||
# update metadata to denote that it's not a python cell
|
||||
cell.metadata["language_info"] = {"name": "unknown"}
|
||||
|
||||
# Remove noqa comments
|
||||
cell.source = re.sub(r"#\s*noqa.*$", "", cell.source, flags=re.MULTILINE)
|
||||
# escape ``` in code
|
||||
# This is needed because the markdown exporter will wrap code blocks in
|
||||
# triple backticks, which will break the markdown output if the code block
|
||||
# contains triple backticks.
|
||||
cell.source = cell.source.replace("```", r"\`\`\`")
|
||||
# escape ``` in output
|
||||
if "outputs" in cell:
|
||||
@@ -107,7 +131,6 @@ exporter = MarkdownExporter(
|
||||
preprocessors=[
|
||||
EscapePreprocessor,
|
||||
ExtractAttachmentsPreprocessor,
|
||||
ImportPreprocessor,
|
||||
],
|
||||
template_name="mdoutput",
|
||||
extra_template_basedirs=[
|
||||
@@ -115,12 +138,111 @@ exporter = MarkdownExporter(
|
||||
],
|
||||
)
|
||||
|
||||
md_executable = MarkdownExporter(
|
||||
preprocessors=[
|
||||
ExtractAttachmentsPreprocessor,
|
||||
EscapePreprocessor(rewrite_links=False),
|
||||
],
|
||||
template_name="md_executable",
|
||||
extra_template_basedirs=[
|
||||
os.path.join(os.path.dirname(__file__), "notebook_convert_templates")
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
def convert_notebook(
|
||||
notebook_path: Path,
|
||||
) -> Path:
|
||||
mode: Literal["markdown", "exec"] = "markdown",
|
||||
) -> str:
|
||||
with open(notebook_path) as f:
|
||||
nb = nbformat.read(f, as_version=4)
|
||||
|
||||
body, _ = exporter.from_notebook_node(nb)
|
||||
nb.metadata.mode = mode
|
||||
if mode == "markdown":
|
||||
body, _ = exporter.from_notebook_node(nb)
|
||||
else:
|
||||
body, _ = md_executable.from_notebook_node(nb)
|
||||
return body
|
||||
|
||||
|
||||
HERE = Path(__file__).parent
|
||||
DOCS = HERE.parent / "docs"
|
||||
|
||||
|
||||
# Convert notebooks to markdown
|
||||
def _convert_notebooks(
|
||||
*,
|
||||
output_dir: Optional[Path] = None,
|
||||
replace: bool = False,
|
||||
pattern: str = "*.ipynb",
|
||||
) -> None:
|
||||
"""Converting notebooks."""
|
||||
if not output_dir and not replace:
|
||||
raise ValueError("Either --output_dir or --replace must be specified")
|
||||
|
||||
output_dir_path = DOCS if replace else Path(output_dir)
|
||||
notebooks = list(DOCS.rglob(pattern))
|
||||
|
||||
file_names = [notebook.name for notebook in notebooks]
|
||||
|
||||
for notebook in notebooks:
|
||||
markdown = convert_notebook(notebook, mode="exec")
|
||||
markdown_path = output_dir_path / notebook.relative_to(DOCS).with_suffix(".md")
|
||||
markdown_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(markdown_path, "w") as f:
|
||||
f.write(markdown)
|
||||
if replace:
|
||||
notebook.unlink(missing_ok=False)
|
||||
|
||||
if replace:
|
||||
# The regex will match markdown links that point to *.ipynb files.
|
||||
# It captures:
|
||||
# group(1): the link text (inside the square brackets)
|
||||
# group(2): the file path (without the trailing .ipynb)
|
||||
link_pattern = r"(?<!!)\[([^\]]+)\]\((?![^)]*//)([^)]+)\.ipynb\)"
|
||||
|
||||
def replace_link(match: re.Match) -> str:
|
||||
link_text = match.group(1)
|
||||
link_target = match.group(2)
|
||||
# Reconstruct the file name with the .ipynb extension.
|
||||
# For example, if link_target is "foo/bar", then linked_file becomes "bar.ipynb".
|
||||
linked_file = Path(link_target).name + ".ipynb"
|
||||
# Only update if the notebook was among those converted.
|
||||
if linked_file in file_names:
|
||||
# Change the extension from .ipynb to .md
|
||||
return f"[{link_text}]({link_target}.md)"
|
||||
# Otherwise, leave the original link intact.
|
||||
return match.group(0)
|
||||
|
||||
# Process all markdown files in the output directory.
|
||||
for path in output_dir_path.rglob("*.md"):
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
new_content = re.sub(link_pattern, replace_link, content)
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
f.write(new_content)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Convert notebooks to markdown")
|
||||
parser.add_argument(
|
||||
"--output_dir",
|
||||
default=None,
|
||||
help="Directory to output markdown files",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--replace",
|
||||
action="store_true",
|
||||
help="Replace original notebooks with markdown files",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--pattern",
|
||||
default="*.ipynb",
|
||||
help="Glob pattern to match notebooks to convert",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
_convert_notebooks(
|
||||
replace=args.replace,
|
||||
output_dir=args.output_dir,
|
||||
pattern=args.pattern,
|
||||
)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"mimetypes": {
|
||||
"text/markdown": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{#https://github.com/rdbisme/nbconvert/blob/master/share/jupyter/nbconvert/templates/markdown/index.md.j2#}
|
||||
{% extends 'markdown/index.md.j2' %}
|
||||
|
||||
{% block input %}
|
||||
```
|
||||
{%- if 'magics_language' in cell.metadata -%}
|
||||
{{ cell.metadata.magics_language}}
|
||||
{%- elif 'name' in nb.metadata.get('language_info', {}) -%}
|
||||
{{ nb.metadata.language_info.name }} exec="on" source="above" session="1"
|
||||
{%- endif %}
|
||||
{{ cell.source}}
|
||||
```
|
||||
{% endblock input %}
|
||||
|
||||
{%- block traceback_line -%}
|
||||
{%- endblock traceback_line -%}
|
||||
|
||||
{%- block stream -%}
|
||||
{%- endblock stream -%}
|
||||
|
||||
{%- block data_text scoped -%}
|
||||
{%- endblock data_text -%}
|
||||
|
||||
{%- block data_html scoped -%}
|
||||
```html
|
||||
{{ output.data['text/html'] | safe }}
|
||||
```
|
||||
{%- endblock data_html -%}
|
||||
|
||||
{%- block data_jpg scoped -%}
|
||||

|
||||
{%- endblock data_jpg -%}
|
||||
|
||||
{%- block data_png scoped -%}
|
||||

|
||||
{%- endblock data_png -%}
|
||||
@@ -1,13 +1,44 @@
|
||||
import logging
|
||||
from typing import Any, Dict
|
||||
import os
|
||||
import re
|
||||
import traceback
|
||||
from typing import Any, Callable, Dict
|
||||
|
||||
from mkdocs.structure.pages import Page
|
||||
from markdown import Markdown
|
||||
from pymdownx.superfences import SuperFencesException
|
||||
from mkdocs.structure.files import Files, File
|
||||
from mkdocs.structure.pages import Page
|
||||
import posixpath
|
||||
|
||||
from markdown_exec.hooks import SessionHistoryEntry
|
||||
|
||||
from generate_api_reference_links import update_markdown_with_imports
|
||||
from notebook_convert import convert_notebook
|
||||
from setup_vcr import load_postamble, load_preamble, _hash_string
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logging.basicConfig()
|
||||
logger.setLevel(logging.INFO)
|
||||
DISABLED = os.getenv("DISABLE_NOTEBOOK_CONVERT") in ("1", "true", "True")
|
||||
|
||||
|
||||
REDIRECT_MAP = {
|
||||
# lib redirects
|
||||
"how-tos/stream-values.ipynb": "how-tos/streaming.ipynb#values",
|
||||
"how-tos/stream-updates.ipynb": "how-tos/streaming.ipynb#updates",
|
||||
"how-tos/streaming-content.ipynb": "how-tos/streaming.ipynb#custom",
|
||||
"how-tos/stream-multiple.ipynb": "how-tos/streaming.ipynb#multiple",
|
||||
"how-tos/streaming-tokens-without-langchain.ipynb": "how-tos/streaming-tokens.ipynb#example-without-langchain",
|
||||
"how-tos/streaming-from-final-node.ipynb": "how-tos/streaming-specific-nodes.ipynb",
|
||||
"how-tos/streaming-events-from-within-tools-without-langchain.ipynb": "how-tos/streaming-events-from-within-tools.ipynb#example-without-langchain",
|
||||
# cloud redirects
|
||||
"cloud/index.md": "concepts/index.md#langgraph-platform",
|
||||
"cloud/how-tos/index.md": "how-tos/index.md#langgraph-platform",
|
||||
"cloud/concepts/api.md": "concepts/langgraph_server.md",
|
||||
"cloud/concepts/cloud.md": "concepts/langgraph_cloud.md",
|
||||
"cloud/faq/studio.md": "concepts/langgraph_studio.md#studio-faqs",
|
||||
}
|
||||
|
||||
|
||||
class NotebookFile(File):
|
||||
@@ -16,6 +47,8 @@ class NotebookFile(File):
|
||||
|
||||
|
||||
def on_files(files: Files, **kwargs: Dict[str, Any]):
|
||||
if DISABLED:
|
||||
return files
|
||||
new_files = Files([])
|
||||
for file in files:
|
||||
if file.src_path.endswith(".ipynb"):
|
||||
@@ -31,10 +64,291 @@ def on_files(files: Files, **kwargs: Dict[str, Any]):
|
||||
return new_files
|
||||
|
||||
|
||||
def on_page_markdown(markdown: str, page: Page, **kwargs: Dict[str, Any]):
|
||||
def _add_path_to_code_blocks(markdown: str, page: Page) -> str:
|
||||
"""Add the path to the code blocks."""
|
||||
code_block_pattern = re.compile(
|
||||
r"(?P<indent>[ \t]*)```(?P<language>\w+)[ ]*(?P<attributes>[^\n]*)\n"
|
||||
r"(?P<code>((?:.*\n)*?))" # Capture the code inside the block using named group
|
||||
r"(?P=indent)```" # Match closing backticks with the same indentation
|
||||
)
|
||||
|
||||
def replace_code_block_header(match: re.Match) -> str:
|
||||
indent = match.group("indent")
|
||||
language = match.group("language")
|
||||
attributes = match.group("attributes").rstrip()
|
||||
|
||||
if 'exec="on"' not in attributes:
|
||||
# Return original code block
|
||||
return match.group(0)
|
||||
|
||||
code = match.group("code")
|
||||
return f'{indent}```{language} {attributes} path="{page.file.src_path}"\n{code}{indent}```'
|
||||
|
||||
return code_block_pattern.sub(replace_code_block_header, markdown)
|
||||
|
||||
|
||||
def _highlight_code_blocks(markdown: str) -> str:
|
||||
"""Find code blocks with highlight comments and add hl_lines attribute.
|
||||
|
||||
Args:
|
||||
markdown: The markdown content to process.
|
||||
|
||||
Returns:
|
||||
updated Markdown code with code blocks containing highlight comments
|
||||
updated to use the hl_lines attribute.
|
||||
"""
|
||||
# Pattern to find code blocks with highlight comments and without
|
||||
# existing hl_lines for Python and JavaScript
|
||||
# Pattern to find code blocks with highlight comments, handling optional indentation
|
||||
code_block_pattern = re.compile(
|
||||
r"(?P<indent>[ \t]*)```(?P<language>py|python|js|javascript)(?!\s+hl_lines=)\n"
|
||||
r"(?P<code>((?:.*\n)*?))" # Capture the code inside the block using named group
|
||||
r"(?P=indent)```" # Match closing backticks with the same indentation
|
||||
)
|
||||
|
||||
def replace_highlight_comments(match: re.Match) -> str:
|
||||
indent = match.group("indent")
|
||||
language = match.group("language")
|
||||
code_block = match.group("code")
|
||||
lines = code_block.split("\n")
|
||||
highlighted_lines = []
|
||||
|
||||
# Skip initial empty lines
|
||||
while lines and not lines[0].strip():
|
||||
lines.pop(0)
|
||||
|
||||
lines_to_keep = []
|
||||
|
||||
comment_syntax = (
|
||||
"# highlight-next-line"
|
||||
if language in ["py", "python"]
|
||||
else "// highlight-next-line"
|
||||
)
|
||||
|
||||
for line in lines:
|
||||
if comment_syntax in line:
|
||||
count = len(lines_to_keep) + 1
|
||||
highlighted_lines.append(str(count))
|
||||
else:
|
||||
lines_to_keep.append(line)
|
||||
|
||||
# Reconstruct the new code block
|
||||
new_code_block = "\n".join(lines_to_keep)
|
||||
|
||||
if highlighted_lines:
|
||||
return (
|
||||
f'{indent}```{language} hl_lines="{" ".join(highlighted_lines)}"\n'
|
||||
# The indent and terminating \n is already included in the code block
|
||||
f"{new_code_block}"
|
||||
f"{indent}```"
|
||||
)
|
||||
else:
|
||||
return (
|
||||
f"{indent}```{language}\n"
|
||||
# The indent and terminating \n is already included in the code block
|
||||
f"{new_code_block}"
|
||||
f"{indent}```"
|
||||
)
|
||||
|
||||
# Replace all code blocks in the markdown
|
||||
markdown = code_block_pattern.sub(replace_highlight_comments, markdown)
|
||||
return markdown
|
||||
|
||||
|
||||
def handle_vcr_setup(
|
||||
*,
|
||||
formatter: Callable,
|
||||
language: str,
|
||||
code: str,
|
||||
session: str,
|
||||
id: str,
|
||||
md: Markdown,
|
||||
**kwargs: Dict[str, Any],
|
||||
) -> Dict[str, Any]:
|
||||
"""Handle VCR setup in markdown content if necessary."""
|
||||
try:
|
||||
if kwargs.get("extra", None) is None:
|
||||
raise SuperFencesException(
|
||||
f"error while processing {language} block: extra dict is required"
|
||||
)
|
||||
|
||||
if kwargs["extra"].get("path", None) is None:
|
||||
raise SuperFencesException(
|
||||
f"error while processing {language} block: path is required"
|
||||
)
|
||||
|
||||
document_filename = kwargs["extra"]["path"]
|
||||
|
||||
if session is None or session == "" and id is None or id == "":
|
||||
id = _hash_string(code)
|
||||
|
||||
if session is not None and session != "":
|
||||
logger.info(f"new session {session} on page {document_filename}")
|
||||
|
||||
cassette_prefix = document_filename.replace(".md", "").replace(os.path.sep, "_")
|
||||
|
||||
cassette_dir = os.path.abspath(
|
||||
os.path.join(os.path.dirname(os.path.dirname(__file__)), "cassettes")
|
||||
)
|
||||
os.makedirs(cassette_dir, exist_ok=True)
|
||||
|
||||
# Build a unique cassette name.
|
||||
cassette_name = os.path.join(
|
||||
cassette_dir,
|
||||
f"{cassette_prefix}_{session if session else id}_{language}.msgpack.zlib",
|
||||
)
|
||||
|
||||
# Add context manager at start with explicit __enter__ and __exit__ calls
|
||||
|
||||
wrapped_lines = [
|
||||
load_preamble(language, code, cassette_name),
|
||||
code,
|
||||
]
|
||||
|
||||
if session is None or session == "":
|
||||
logger.info(
|
||||
f"no session, adding postamble for {language} in {document_filename}"
|
||||
)
|
||||
wrapped_lines.append(load_postamble(language))
|
||||
|
||||
transformed_source = "\n".join(wrapped_lines)
|
||||
return dict(
|
||||
transform_source=lambda code: (transformed_source, code),
|
||||
id=id,
|
||||
extra={},
|
||||
)
|
||||
except Exception as e:
|
||||
raise SuperFencesException(traceback.format_exc()) from e
|
||||
|
||||
|
||||
def handle_vcr_teardown(
|
||||
*,
|
||||
formatter: Callable,
|
||||
language: str,
|
||||
session: str,
|
||||
history: list[SessionHistoryEntry],
|
||||
):
|
||||
last_inputs = dict(history[-1].inputs)
|
||||
code = load_postamble(language)
|
||||
md = last_inputs["md"]
|
||||
html = False
|
||||
update_toc = False
|
||||
|
||||
document_filename = last_inputs.get("extra", {}).get("path", None)
|
||||
|
||||
if document_filename is None:
|
||||
logger.warning(f"no document filename found while tearing down {session}!")
|
||||
else:
|
||||
logger.info(f"tearing down {session} on {document_filename}")
|
||||
logger.info(traceback.format_stack())
|
||||
|
||||
kwargs = dict(
|
||||
code=code,
|
||||
session=session,
|
||||
id=f"{id}_vcr_end",
|
||||
md=md,
|
||||
html=html,
|
||||
update_toc=update_toc,
|
||||
extra={},
|
||||
)
|
||||
|
||||
# This doesn't actually render anything, we just call the formatter so it
|
||||
# executes in the same context as the session of which we're disposing.
|
||||
formatter(**kwargs)
|
||||
|
||||
|
||||
def _on_page_markdown_with_config(
|
||||
markdown: str,
|
||||
page: Page,
|
||||
*,
|
||||
add_api_references: bool = True,
|
||||
remove_base64_images: bool = False,
|
||||
**kwargs: Any,
|
||||
) -> str:
|
||||
if DISABLED:
|
||||
return markdown
|
||||
|
||||
if page.file.src_path.endswith(".ipynb"):
|
||||
logger.info("Processing Jupyter notebook: %s", page.file.src_path)
|
||||
body = convert_notebook(page.file.abs_src_path)
|
||||
return body
|
||||
# logger.info("Processing Jupyter notebook: %s", page.file.src_path)
|
||||
markdown = convert_notebook(page.file.abs_src_path)
|
||||
|
||||
# Append API reference links to code blocks
|
||||
if add_api_references:
|
||||
markdown = update_markdown_with_imports(markdown)
|
||||
# Apply highlight comments to code blocks
|
||||
markdown = _highlight_code_blocks(markdown)
|
||||
|
||||
# Add file path as an attribute to code blocks that are executable.
|
||||
# This file path is used to associate fixtures with the executable code
|
||||
# which can be used in CI to test the docs without making network requests.
|
||||
markdown = _add_path_to_code_blocks(markdown, page)
|
||||
|
||||
if remove_base64_images:
|
||||
# Remove base64 encoded images from markdown
|
||||
markdown = re.sub(r"!\[.*?\]\(data:image/+;base64,[^\)]+\)", "", markdown)
|
||||
|
||||
return markdown
|
||||
|
||||
|
||||
def on_page_markdown(markdown: str, page: Page, **kwargs: Dict[str, Any]):
|
||||
return _on_page_markdown_with_config(
|
||||
markdown,
|
||||
page,
|
||||
add_api_references=True,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
|
||||
# redirects
|
||||
|
||||
HTML_TEMPLATE = """
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Redirecting...</title>
|
||||
<link rel="canonical" href="{url}">
|
||||
<meta name="robots" content="noindex">
|
||||
<script>var anchor=window.location.hash.substr(1);location.href="{url}"+(anchor?"#"+anchor:"")</script>
|
||||
<meta http-equiv="refresh" content="0; url={url}">
|
||||
</head>
|
||||
<body>
|
||||
Redirecting...
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
|
||||
def write_html(site_dir, old_path, new_path):
|
||||
"""Write an HTML file in the site_dir with a meta redirect to the new page"""
|
||||
# Determine all relevant paths
|
||||
old_path_abs = os.path.join(site_dir, old_path)
|
||||
old_dir_abs = os.path.dirname(old_path_abs)
|
||||
|
||||
# Create parent directories if they don't exist
|
||||
if not os.path.exists(old_dir_abs):
|
||||
os.makedirs(old_dir_abs)
|
||||
|
||||
# Write the HTML redirect file in place of the old file
|
||||
content = HTML_TEMPLATE.format(url=new_path)
|
||||
with open(old_path_abs, "w", encoding="utf-8") as f:
|
||||
f.write(content)
|
||||
|
||||
|
||||
# Create HTML files for redirects after site dir has been built
|
||||
def on_post_build(config):
|
||||
use_directory_urls = config.get("use_directory_urls")
|
||||
for page_old, page_new in REDIRECT_MAP.items():
|
||||
page_old = page_old.replace(".ipynb", ".md")
|
||||
page_new = page_new.replace(".ipynb", ".md")
|
||||
page_new_before_hash, hash, suffix = page_new.partition("#")
|
||||
old_html_path = File(page_old, "", "", use_directory_urls).dest_path.replace(
|
||||
os.sep, "/"
|
||||
)
|
||||
new_html_path = File(page_new_before_hash, "", "", True).url
|
||||
new_html_path = (
|
||||
posixpath.relpath(new_html_path, start=posixpath.dirname(old_html_path))
|
||||
+ hash
|
||||
+ suffix
|
||||
)
|
||||
write_html(config["site_dir"], old_html_path, new_html_path)
|
||||
|
||||
@@ -7,7 +7,7 @@ import click
|
||||
import nbformat
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
NOTEBOOK_DIRS = ("docs/docs/how-tos","docs/docs/tutorials")
|
||||
NOTEBOOK_DIRS = ("docs/how-tos","docs/tutorials")
|
||||
DOCS_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
CASSETTES_PATH = os.path.join(DOCS_PATH, "cassettes")
|
||||
|
||||
@@ -19,30 +19,37 @@ BLOCKLIST_COMMANDS = (
|
||||
)
|
||||
|
||||
NOTEBOOKS_NO_CASSETTES = (
|
||||
"docs/docs/how-tos/visualization.ipynb",
|
||||
"docs/docs/how-tos/many-tools.ipynb"
|
||||
"docs/how-tos/visualization.ipynb",
|
||||
"docs/how-tos/many-tools.ipynb"
|
||||
)
|
||||
|
||||
NOTEBOOKS_NO_EXECUTION = [
|
||||
# this uses a user provided project name for langsmith
|
||||
"docs/docs/tutorials/tnt-llm/tnt-llm.ipynb",
|
||||
"docs/tutorials/tnt-llm/tnt-llm.ipynb",
|
||||
# this uses langsmith datasets
|
||||
"docs/docs/tutorials/chatbot-simulation-evaluation/langsmith-agent-simulation-evaluation.ipynb",
|
||||
"docs/tutorials/chatbot-simulation-evaluation/langsmith-agent-simulation-evaluation.ipynb",
|
||||
# this uses browser APIs
|
||||
"docs/docs/tutorials/web-navigation/web_voyager.ipynb",
|
||||
"docs/tutorials/web-navigation/web_voyager.ipynb",
|
||||
# these RAG guides use an ollama model
|
||||
"docs/docs/tutorials/rag/langgraph_adaptive_rag_local.ipynb",
|
||||
"docs/docs/tutorials/rag/langgraph_crag_local.ipynb",
|
||||
"docs/docs/tutorials/rag/langgraph_self_rag_local.ipynb",
|
||||
"docs/tutorials/rag/langgraph_adaptive_rag_local.ipynb",
|
||||
"docs/tutorials/rag/langgraph_crag_local.ipynb",
|
||||
"docs/tutorials/rag/langgraph_self_rag_local.ipynb",
|
||||
# this loads a massive dataset from gcp
|
||||
"docs/docs/tutorials/usaco/usaco.ipynb",
|
||||
"docs/tutorials/usaco/usaco.ipynb",
|
||||
# TODO: figure out why autogen notebook is not runnable (they are just hanging. possible due to code execution?)
|
||||
"docs/how-tos/autogen-integration.ipynb",
|
||||
"docs/how-tos/autogen-integration-functional.ipynb",
|
||||
# TODO: need to update these notebooks to make sure they are runnable in CI
|
||||
"docs/docs/tutorials/storm/storm.ipynb", # issues only when running with VCR
|
||||
"docs/docs/tutorials/lats/lats.ipynb", # issues only when running with VCR
|
||||
"docs/docs/tutorials/multi_agent/hierarchical_agent_teams.ipynb", # taking a very long time to run
|
||||
"docs/docs/tutorials/rag/langgraph_crag.ipynb", # flakiness from tavily
|
||||
"docs/docs/tutorials/rag/langgraph_adaptive_rag.ipynb", # Cannot create a consistent method resolution error from VCR
|
||||
"docs/docs/how-tos/map-reduce.ipynb" # flakiness from structured output, only when running with VCR
|
||||
"docs/tutorials/storm/storm.ipynb", # issues only when running with VCR
|
||||
"docs/tutorials/lats/lats.ipynb", # issues only when running with VCR
|
||||
"docs/tutorials/rag/langgraph_crag.ipynb", # flakiness from tavily
|
||||
"docs/tutorials/rag/langgraph_adaptive_rag.ipynb", # flakiness only when running in GHA
|
||||
"docs/tutorials/rag/langgraph_self_rag.ipynb", # flakiness only when running in GHA
|
||||
"docs/tutorials/rag/langgraph_agentic_rag.ipynb", # flakiness only when running in GHA
|
||||
"docs/how-tos/map-reduce.ipynb", # flakiness from structured output, only when running with VCR
|
||||
"docs/tutorials/tot/tot.ipynb",
|
||||
"docs/how-tos/visualization.ipynb",
|
||||
"docs/tutorials/llm-compiler/LLMCompiler.ipynb"
|
||||
]
|
||||
|
||||
|
||||
@@ -85,6 +92,7 @@ def add_vcr_to_notebook(
|
||||
) -> nbformat.NotebookNode:
|
||||
"""Inject `with vcr.cassette` into each code cell of the notebook."""
|
||||
|
||||
uses_langsmith = False
|
||||
# Inject VCR context manager into each code cell
|
||||
for idx, cell in enumerate(notebook.cells):
|
||||
if cell.cell_type != "code":
|
||||
@@ -119,8 +127,22 @@ def add_vcr_to_notebook(
|
||||
f" {line}" for line in lines
|
||||
)
|
||||
|
||||
if any("hub.pull" in line or "from langsmith import" in line for line in lines):
|
||||
uses_langsmith = True
|
||||
|
||||
# Add import statement
|
||||
vcr_import_lines = [
|
||||
vcr_import_lines = []
|
||||
if uses_langsmith:
|
||||
vcr_import_lines.extend([
|
||||
# patch urllib3 to handle vcr errors, see more here:
|
||||
# https://github.com/langchain-ai/langsmith-sdk/blob/main/python/langsmith/_internal/_patch.py
|
||||
"import sys",
|
||||
f"sys.path.insert(0, '{os.path.join(DOCS_PATH, '_scripts')}')",
|
||||
"import _patch as patch_urllib3",
|
||||
"patch_urllib3.patch_urllib3()",
|
||||
])
|
||||
|
||||
vcr_import_lines.extend([
|
||||
"import nest_asyncio",
|
||||
"nest_asyncio.apply()",
|
||||
"import vcr",
|
||||
@@ -150,7 +172,8 @@ def add_vcr_to_notebook(
|
||||
"",
|
||||
"custom_vcr.register_serializer('advanced_compressed', AdvancedCompressedSerializer())",
|
||||
"custom_vcr.serializer = 'advanced_compressed'",
|
||||
]
|
||||
])
|
||||
|
||||
import_cell = nbformat.v4.new_code_cell(source="\n".join(vcr_import_lines))
|
||||
import_cell.pop("id", None)
|
||||
notebook.cells.insert(0, import_cell)
|
||||
@@ -194,7 +217,7 @@ def process_notebooks(should_comment_install_cells: bool) -> None:
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing {notebook_path}: {e}")
|
||||
|
||||
with open(os.path.join(DOCS_PATH, "notebooks_no_execution.json"), "w") as f:
|
||||
with open("notebooks_no_execution.json", "w") as f:
|
||||
json.dump(NOTEBOOKS_NO_EXECUTION, f)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
# A list of patterns that, if found in a code block, will cause us to leave that block unchanged.
|
||||
import hashlib
|
||||
import os
|
||||
from textwrap import dedent
|
||||
|
||||
preambles = {
|
||||
"python": "vcr_setup_preamble.py",
|
||||
"typescript": "nock_setup_preamble.ts",
|
||||
}
|
||||
|
||||
|
||||
def _get_python_cassette_init(cassette_name: str, hash_: str) -> str:
|
||||
return dedent(
|
||||
f"""
|
||||
_cassette = HashedCassette('{cassette_name}', '{hash_}')
|
||||
_cassette.__enter__()
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def _get_typescript_cassette_init(cassette_name: str, hash_: str) -> str:
|
||||
return dedent(
|
||||
f"""
|
||||
const _cassette = new HashedCassette("{cassette_name}", "{hash_}");
|
||||
await _cassette.enter();
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def _get_python_cassette_cleanup() -> str:
|
||||
return "_cassette.__exit__()"
|
||||
|
||||
|
||||
def _get_typescript_cassette_cleanup() -> str:
|
||||
return "await _cassette.exit();"
|
||||
|
||||
|
||||
preamble_inits = {
|
||||
"python": _get_python_cassette_init,
|
||||
"py": _get_python_cassette_init,
|
||||
"typescript": _get_typescript_cassette_init,
|
||||
"ts": _get_typescript_cassette_init,
|
||||
}
|
||||
|
||||
preamble_cleanups = {
|
||||
"python": _get_python_cassette_cleanup,
|
||||
"py": _get_python_cassette_cleanup,
|
||||
"typescript": _get_typescript_cassette_cleanup,
|
||||
"ts": _get_typescript_cassette_cleanup,
|
||||
}
|
||||
|
||||
|
||||
def load_preamble(language: str, code: str, cassette_name: str) -> str:
|
||||
"""Load the source code for the preamble for a given language."""
|
||||
_assets_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "assets")
|
||||
|
||||
preamble_path = os.path.join(_assets_dir, preambles[language])
|
||||
with open(preamble_path, "r") as f:
|
||||
lines = f.readlines()
|
||||
hash_ = _hash_string(code)
|
||||
lines.append(preamble_inits[language](cassette_name, hash_))
|
||||
return "\n".join(lines).strip()
|
||||
|
||||
|
||||
def load_postamble(language: str) -> str:
|
||||
"""Load the source code for the postamble for a given language."""
|
||||
|
||||
return preamble_cleanups[language]()
|
||||
|
||||
|
||||
def _hash_string(input_string: str) -> str:
|
||||
# Encode the input string to bytes
|
||||
encoded_string = input_string.encode("utf-8")
|
||||
# Create a SHA-256 hash object
|
||||
sha256_hash = hashlib.sha256(encoded_string)
|
||||
# Get the hexadecimal digest of the hash
|
||||
return sha256_hash.hexdigest()
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
#!/usr/bin/env python
|
||||
"""Create the third party page for the documentation."""
|
||||
|
||||
import argparse
|
||||
from typing import List
|
||||
from typing import TypedDict
|
||||
|
||||
import yaml
|
||||
|
||||
MARKDOWN = """\
|
||||
[//]: # (This file is automatically generated using a script in docs/_scripts. Do not edit this file directly!)
|
||||
# 🚀 Prebuilt Agents
|
||||
|
||||
LangGraph includes a prebuilt React agent. For more information on how to use it,
|
||||
check out our [how-to guides](https://langchain-ai.github.io/langgraph/how-tos/#prebuilt-react-agent).
|
||||
|
||||
If you’re looking for other prebuilt libraries, explore the community-built options
|
||||
below. These libraries can extend LangGraph's functionality in various ways.
|
||||
|
||||
## 📚 Available Libraries
|
||||
|
||||
[//]: # (This file is automatically generated using a script in docs/_scripts. Do not edit this file directly!)
|
||||
{library_list}
|
||||
|
||||
## ✨ Contributing Your Library
|
||||
|
||||
Have you built an awesome open-source library using LangGraph? We'd love to feature
|
||||
your project on the official LangGraph documentation pages! 🏆
|
||||
|
||||
To share your project, simply open a Pull Request adding an entry for your package in our [packages.yml]({langgraph_url}) file.
|
||||
|
||||
**Guidelines**
|
||||
|
||||
- Your repo must be distributed as an installable package (e.g., PyPI for Python, npm
|
||||
for JavaScript/TypeScript, etc.) 📦
|
||||
- The repo should either use the Graph API (exposing a `StateGraph` instance) or
|
||||
the Functional API (exposing an `entrypoint`).
|
||||
- The package must include documentation (e.g., a `README.md` or docs site)
|
||||
explaining how to use it.
|
||||
|
||||
We'll review your contribution and merge it in!
|
||||
|
||||
Thanks for contributing! 🚀
|
||||
"""
|
||||
|
||||
|
||||
class ResolvedPackage(TypedDict):
|
||||
name: str
|
||||
"""The name of the package."""
|
||||
repo: str
|
||||
"""Repository ID within github. Format is: [orgname]/[repo_name]."""
|
||||
weekly_downloads: int | None
|
||||
"""The weekly download count of the package."""
|
||||
description: str
|
||||
"""A brief description of what the package does."""
|
||||
|
||||
|
||||
def generate_markdown(resolved_packages: List[ResolvedPackage], language: str) -> str:
|
||||
"""Generate the markdown content for the third party page.
|
||||
|
||||
Args:
|
||||
resolved_packages: A list of resolved package information.
|
||||
language: str
|
||||
|
||||
Returns:
|
||||
The markdown content as a string.
|
||||
"""
|
||||
# Update the URL to the actual file once the initial version is merged
|
||||
if language == "python":
|
||||
langgraph_url = (
|
||||
"https://github.com/langchain-ai/langgraph/blob/main/docs"
|
||||
"/_scripts/third_party_page/packages.yml"
|
||||
)
|
||||
elif language == "js":
|
||||
langgraph_url = (
|
||||
"https://github.com/langchain-ai/langgraphjs/blob/main/docs"
|
||||
"/_scripts/third_party/packages.yml"
|
||||
)
|
||||
else:
|
||||
raise ValueError(f"Invalid language '{language}'. Expected 'python' or 'js'.")
|
||||
|
||||
sorted_packages = sorted(
|
||||
resolved_packages, key=lambda p: p["weekly_downloads"] or 0, reverse=True
|
||||
)
|
||||
rows = [
|
||||
"| Name | GitHub URL | Description | Weekly Downloads |",
|
||||
"| --- | --- | --- | --- |",
|
||||
]
|
||||
for package in sorted_packages:
|
||||
name = f"**{package['name']}**"
|
||||
repo_url = f"[{package['repo']}](https://github.com/{package['repo']})"
|
||||
downloads = package["weekly_downloads"] or 0
|
||||
row = f"| {name} | {repo_url} | {package['description']} | {downloads} |"
|
||||
rows.append(row)
|
||||
markdown_content = MARKDOWN.format(
|
||||
library_list="\n".join(rows), langgraph_url=langgraph_url
|
||||
)
|
||||
return markdown_content
|
||||
|
||||
|
||||
def main(input_file: str, output_file: str, language: str) -> None:
|
||||
"""Main function to create the third party page.
|
||||
|
||||
Args:
|
||||
input_file: Path to the input YAML file containing resolved package information.
|
||||
output_file: Path to the output file for the third party page.
|
||||
language: The language for which to generate the third party page.
|
||||
"""
|
||||
# Parse the input YAML file
|
||||
with open(input_file, "r") as f:
|
||||
resolved_packages: List[ResolvedPackage] = yaml.safe_load(f)
|
||||
|
||||
markdown_content = generate_markdown(resolved_packages, language)
|
||||
|
||||
# Write the markdown content to the output file
|
||||
with open(output_file, "w", encoding="utf-8") as f:
|
||||
f.write(markdown_content)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Create the third party page.")
|
||||
parser.add_argument(
|
||||
"input_file",
|
||||
help="Path to the input YAML file containing resolved package information.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"output_file", help="Path to the output file for the third party page."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--language",
|
||||
choices=["python", "js"],
|
||||
default="python",
|
||||
help="The language for which to generate the third party page. Defaults to 'python'.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
main(args.input_file, args.output_file, args.language)
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env python
|
||||
"""Retrieve download count for a list of Python packages from PyPI."""
|
||||
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
from typing import TypedDict
|
||||
import pathlib
|
||||
|
||||
import requests
|
||||
import yaml
|
||||
|
||||
|
||||
class Package(TypedDict):
|
||||
"""A TypedDict representing a package"""
|
||||
|
||||
name: str
|
||||
"""The name of the package."""
|
||||
repo: str
|
||||
"""Repository ID within github. Format is: [orgname]/[repo_name]."""
|
||||
description: str
|
||||
"""A brief description of what the package does."""
|
||||
|
||||
|
||||
class ResolvedPackage(Package):
|
||||
weekly_downloads: int | None
|
||||
|
||||
|
||||
HERE = pathlib.Path(__file__).parent
|
||||
PACKAGES_FILE = HERE / "packages.yml"
|
||||
PACKAGES = yaml.safe_load(PACKAGES_FILE.read_text())['packages']
|
||||
|
||||
|
||||
def _get_weekly_downloads(packages: list[Package]) -> list[ResolvedPackage]:
|
||||
"""Retrieve the monthly download count for a list of packages from PyPIStats."""
|
||||
resolved_packages: list[ResolvedPackage] = []
|
||||
|
||||
for package in packages:
|
||||
url = f"https://pypistats.org/api/packages/{package['name']}/overall"
|
||||
|
||||
response = requests.get(url)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
|
||||
sorted_data = sorted(
|
||||
data["data"],
|
||||
key=lambda x: datetime.strptime(x["date"], "%Y-%m-%d"),
|
||||
reverse=True,
|
||||
)
|
||||
|
||||
# Sum the last 7 days of downloads
|
||||
num_downloads = sum(entry["downloads"] for entry in sorted_data[:7])
|
||||
|
||||
resolved_packages.append(
|
||||
{
|
||||
"name": package["name"],
|
||||
"repo": package["repo"],
|
||||
"weekly_downloads": num_downloads,
|
||||
"description": package["description"],
|
||||
}
|
||||
)
|
||||
|
||||
return resolved_packages
|
||||
|
||||
|
||||
|
||||
def main(output_file: str) -> None:
|
||||
"""Main function to generate package download information.
|
||||
|
||||
Args:
|
||||
output_file: Path to the output YAML file.
|
||||
"""
|
||||
resolved_packages: list[ResolvedPackage] = _get_weekly_downloads(PACKAGES)
|
||||
|
||||
if not output_file.endswith(".yml"):
|
||||
raise ValueError("Output file must have a .yml extension")
|
||||
|
||||
with open(output_file, "w") as f:
|
||||
f.write("# This file is auto-generated. Do not edit.\n")
|
||||
yaml.dump(resolved_packages, f)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate package download information."
|
||||
)
|
||||
parser.add_argument(
|
||||
"output_file",
|
||||
help=(
|
||||
"Path to the output YAML file. Example: python generate_downloads.py "
|
||||
"downloads.yml"
|
||||
),
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
main(args.output_file)
|
||||
@@ -0,0 +1,11 @@
|
||||
#A list of third-party packages to surface on the third-party page.
|
||||
packages:
|
||||
- name: "trustcall"
|
||||
repo: "hinthornw/trustcall"
|
||||
description: "Tenacious tool calling built on LangGraph"
|
||||
- name: "breeze-agent"
|
||||
repo: "andrestorres123/breeze-agent"
|
||||
description: "A streamlined research system built inspired on STORM and built on LangGraph"
|
||||
- name: "langgraph-supervisor"
|
||||
repo: "langchain-ai/langgraph-supervisor"
|
||||
description: "Build supervisor multi-agent systems with LangGraph"
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
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
|
||||
@@ -1 +0,0 @@
|
||||
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
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
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
|
||||
@@ -1 +0,0 @@
|
||||
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
|
||||
@@ -0,0 +1 @@
|
||||
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
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
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
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
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
|
||||
+1
@@ -0,0 +1 @@
|
||||
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
|
||||
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
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
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
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
|
||||
@@ -1 +1 @@
|
||||
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
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
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
|
||||
@@ -1 +0,0 @@
|
||||
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
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
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
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
eNqFVX9sE1UcH2AGCBkIWUL4IS91IJFdd+26si4IKeVHBoyNrbiNH+mud6+9W6/3jrt327oxJ+AkgEQPEkkwRoHRQh1jg8kiAjEYfkRBZCRAQYVBgBBQQEATIeK7WwdDCPaP5u6974/P+3w+33crYlVQUQUk9WkWJAwVhsXkRdVXxBS4VIMqfj8ahphHXFNRYYl3q6YIiXE8xrKal5XFyIKVkTCvIFlgrSwKZ1XZssJQVZkgVJv8iIuc70vXWcJMjQ+jEJRUSx6w0XZHJrD0RJGVRXUWBYmQPFk0FSoWsssiAkXCxlL+m2EgQkaRBCkI5jJScJbCyLwVeJAmciCCNMAhoKIwBApUSRzLAyQBAYMAUkAYTrXULzHaIQ6KRjlWZDQOUtlUDqUiSYKYshNAtNNOG30xQmISksSETUiYqRLEiK+7tI/00ESs+ipJspHAQZVVBNmgzAh2gyQEKAUFCQJEdsJCLeRMNIQgWYE84UGogpmAYVlNYbDxJHEAK5qKSWCygxUsUGFAE83EapJjHlWCJAIjkqBWQwWY+hhqAcaPNAxIPYXQBmAV+Scl8iWZrKq8SZUfAqYHHklUIlbjAIIR4lNZHoYZcoI6i0zEhAoWTGnqLGak+fSfo/auZEASEQoBTTZZjMgmdSpWiGiW+nqyZphJUCBnkJssuqRXKPJXQhaT0CX1MR4yHLHkR008UrHe9pzJdhHioIwpKLGIIw30ncFaQc4EHAyIhM44a+hquliPhyCUKUYkfEe7s/RWRpZFgWWM/SxDxuak2SgDy/PbccOTFLGqhPUOdw+OrKIImQkJ0NZsh9XeWkOpmBEkkZiaEolH9ahs7n/Te0Nm2BCpQyXnTY92J7f0jkGqvq2AYQtLnilpMK1vY5Sw07Gn97qiScRfUI95ip5vl9x82i7barNZXW3PFFYjEqtvCzCiCtuekPwkJU5mI5uinRRta+lhSSTWxry+NcdJbydelYn74MooKYk1dUUTUQQePxZLTveWwjk9av6aMqxpOlFHP+DltUxgd4ISKANj9oBtUp7DnudwglkF3mZPso33hWK0eRVi/QARZEaP+DGW16QQ5OKeF8qesDw9ljFsIplHTCWvNiKW8ao3OWiaTox/aaRCBkQwLiG9Kdvlcv1PXeMuwnq7cT6KdlF2p7f7lDmOhQnwoszu+zGJJ2rgIYgyXhL5FE9PNHhp9IvxOJwL40nQlMDp+8mzj7a5aiIq43RyPJybq0nl1UX8tII5tq9qKFZEGkdh8pGAlGmIGqwngJ9zORyuSU6bzZ5jc7rogB8GOKffxkJbLkP+t1YJjB63WW0giFBQhLs8MykPQ64cqsS0jR6bXj7PXZDvaS6jipEfEf68DOFZQhKMlkCF2FGPm63JgCswStKL3eV6ey7ryqE5cnUHnDm5rM1OzSgtbu0x0BODNBm3g/kxWh7tvpEO92keu3ZAivnr512/CF2gBzc+fvXoxoPH3NLNlb7S+7vht6+vST9Hj9h04kgl15m+I2Pmx4+nnCuvjqyffuPOssk/DfSsHFe1b+e1tVd/P1jX+cvdvDGZF/cvGzWlwTV4EOY9hVcmFj9YNG1V/uWyO3H3iT2bv5s3ck2Zf0y9tL0s/fag9MBuv8vXcv3sD6685sZ151ofvVsbqsSjr54uvtx/9rV+R7vGTF6cc2fDFw/qp743MKP4jx0ScyVSt3HZxUN7MkZknLw0v2JO6plheEvq11lz1xwZtfx6auWNv6dTbR+87b4UzP+sA9y61PXWzGOzN/x56rZn9KWOIXed9Loz87n+Z1Ibfz5Z4Ukd436jYmfHpAEVruN3bv2TNn7Yl83s4pIjV1yl9w4Pbyjoqik5G3mwFH2+70LXOzUr0xLVG6QV261DF1hOnGqvnd/VNvyvROvkrlDUUbG64dCELrrzlcaKtIWuxXuviOs+LR4QHXpAH+loj02onyWuuX5vyKrKztLVj/h7Yx/izfc3rQ4dWq9+mHbv/pDvTzfG7InXJn5y8/D5zdzDjr1lLT9e9xFZHj/ul/JbQ+HxYN+UlH8BR110QQ==
|
||||
eNqlVntQVFUYx8ByRrMZTJ0azeOqOCB32QewLtoIrtAgg2zLQ7Bgudx7dvfC3Xtu9wGuPBRMJJ3Rrppmk1qxLMKAgppmQKZWamOjvUXNHmZTM/lIx2pGGzr3sjwUfDTtHztnz/kev+/3fb9vtqaxFAoig7gRLQwnQYGkJPxDVGoaBfiSDEXp5YAXSh5E++0ZmVn1ssB0z/BIEi8mxMSQPKMnOckjIJ6h9BTyxpQaY7xQFEk3FP1FiPadDQ0t13nJpU4JlUBO1CUAo8EUGw10fVb45oVynYBYiE86WYSCDr9SCEPhJPUqFXAQ0kBEXgjgUh4KEnDLDE1yFAQuJIAimWFphnMDkgNJqQDH5CQ9sCGZpYEPySBYBSBFkRGlfjcvnKerzFeBIBqyaiKKJWUaEmYijhARx0GJMGGohniTQUUkIcQGwXKkVwMrkaUM63OKkBQoj1OAosxKorMYO6sONBQpgeFVMlXjJNBrByDnZjgIEH7xMstwZSoaTB0vQA9miCmF0YCkKFkgJfXE0UASZFHChsEMepAtQpfMao5l2EcrUyNJQthBLIMC0GpW+wjIIiRLAMcTMDEAluJvHCKV4/Gt6NFoKoKA7IOHHQWfXi2AUU2cIuWBXhJXUK7jcZsx/YzWtHKdZqmd7ip1cCQVEotQCZB5jUUfr1EnSgJuma6yEt+pDWIESKvkBoPmDzJFRcWQkjTTAeo9spfknAMtHYZwxzB9F5AXV6o5/8cS/w/w/MpGDyRprLL1fg8SJaV9iG52445DXiIgRyF1mJVW9zKGjwY0dLF4DpopdSA1YSrNJRDyBMniQQn0eiltJM+zDEWq7zHq/LUE9UOoWIY+N6syIzSlKAeS+nDE2H1Y5hww6M2xelPbUgKzxnAs1inBkhhSgNfeOwY/8CRVguMQwRWiBHqddw22QaLSkE5SGZl3hFRHRGkgBW987N7B94LMYWFApdFmH5ou+DiQzqw3GvWW9jsCiz6OUhpcJCvC9n6S+12asajNhCGeMBh39bHEYk1KHqXeYjHuxCLjsWzgygAOKclijR93BJ483hhcWO9kpPV180LIRP8C3B2lK0VgooHRAhbiHYTjxwFjfILRnGCMA8+lZ7XYgmmyhm1Ge5aANevCDUnua34j5ZG5Ekg324Zte7duoCx1S7B4kUhEcM/hZqk/FX+swWDojrivpYDHnuHUjH6z1Wp9QFzMDJSUfWp9mDzCaMkKVmleMnweTV1E7+IPogqoqDCuqAfaD2Dr84l4CJ97IIxb0j1zOG+8GYdAbJitZZv1YPsBiEGfmQ/jc2+IYDj3u+jrTTT9PpaDieu1Bve1viee5mDnCYZWOvHZaTDGZtvd0CUtKXE7KIfJlGaZv9DmWFxfypBKs1FvBG6E3CzcbUshbCReqkSmJiGlcUHeoqT0VFtLLuFARQjPUhaJZ45DHAxkQgFLU2mmWCTTeNkJMIDdHUl5yj6rwWwhjVYqzmo1zHbRLmI+3iF9YuoXi1/dlNp/jepA73b+eETHlLWjQrRPKLvhMHfOMKbWuerijImN/J7YWRWRaya98WTXmMjakKOFO8Pdo99Nzt70hT/pQuWrHftGf7NxumPeiatbxnoezzmTlrll45yC6G3Lu/6p8pVd9d5ou2KJ9LZ9+N5fm5BSVzxq9Jjzl1aEt4e/tja38FRtQou9LOqpp5dPdq5bta1+9vbNX+ZZd2zOfcs18URyS9Uzi5KnXd5TkRv1or3u0/e5npE500LXh7Ver3pCmXpa1L2SOCdj6pGmAxF/fzbizzeBvb6mfVf1MbqDrJ90viUx7uefRrak5D+WOqoo7XSg4ODeqBO/ebovFdRO3Z+jL0ytTnmEONTZVFmYTkfNnTAl7GT+tum3TK9vPdWkn/l91UcH67fc/CV7c+f2y2dvrT53efyEX7N2yEfDbh4Ly7tasSZ38jXr82eoVRbfhZCcxLrtps+dtyPyboztsV6pyXQ/SlX80BoXduTZrlvu/Tnj+BWJRyI94cevtY6v+731g08u/rG4Orz72+pNbXPck8M3TJlxquDgV/LIwI8rs1ZbNiRcH2c9XBx/KMo+6ztHa2gTK1ZW1c+9FBp5Y/m6zNsW09aT647Nw13q6QkNebv460Odj4SE/AtyqB7z
|
||||
@@ -1 +0,0 @@
|
||||
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
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
eNqNVm1sFMcZNrhGbaESDWpKqkYdTsEg4b3b+/DHuQnBmI84yBjbR2LzIXdud+5u7b2Z9c7s4YtlNXESUoVCtCHQKgktis936OKA7YBCC22skkZpMClSqxZbCamxCIKQRFFEmyil7szene0Ui9Q/rLmZ933neZ/nmfeuN5NAJtUInjegYYZMqDD+gdq9GRN1WoiyJ9JxxGJETW1paA71WaY2tjzGmEGrPR5oaG6IWcwkhqa4FRL3JLyeOKIURhFNhYmaHC8e73bFYVcbIx0IU1c18Mq+QBlwFaL4zvZul0l0xFcuiyLTxU8VwqFgJrbqAEZIBZTEEUBdBjIZiFqaCrGCQISYIGxpuqrhKGAxjYKaOsCrYuYGtcTSVZAkFsj3ASClGmXTiXF0v6tnp4BCVKSLqxQdWiqS/FK5RAnGiEk+Dlau8MkCEyNEz8PFMO7AZTCh6ck2iqCpxNpMRC2d0bZ2niwSVEQVUzMEnSK4BuTiAMJRDSNA+Elce4T3JtBw8gwTxThHWgKVAagolgmZWGEVMNOijAfmb3CDrRRFLN1J3MVznDYdmhjhCXQXMoHTs1ASwDCxGOD1TE4MQAn+n5eowwbfpTGHpjACsACPJ5pJt2hAEyFtVImhOOQddLsMLjQXQHNk63Y5kc7qf1qdXUlA0gnpAJbhsJg0HOooM7lorp4evicE0kykCnLzRXfOCiXhdqQwJ3SG+qacqDXTms7B+HqqQJ2TyK2BOMFYGB2KwxxNeTs5bObco0UcJqGJgIVhWEdOoHMFUDlChelJwDnncaKkcCvIg6eAWoZBuDvDKEmw4zwT8PpxjYrXRd078A4cIiIpd1nEws5TK+MldJicrriCghV5y67gtnf288ZXOGiuQUJTcz2ZWjQ28xz+L83ylZ3112pRCJ5TjZ09mRiCKuf0mVSMUGYP3TIOjnEbI4NJCCtEvFH7legjmlEGVBQRumQV8cocEuxsB0KGBHXu/nQuyx6EhqFriqOYRzyqgfxYkASWW4+zgj3Jef72azUFHJ4tST69MJDd/oDbN9glcbtoWOfjR9Ihh5Q2nPNTsw8MqHTwOlJ+MtrpXPLR2TGE2v31UGlo/kpJ4Xu7H5rxisCrs/dNC/PXjuxM7ZZbr8sfzlznd3u97uDQVwrTJFbs/gjUKRqaJnk6JcsnlV+SKyTZe7TAks4HDYvZfcGqiiPcoAY3IXo8zUsyi/amuCJo9K1Mfg6/1LCpoObFojtS67g69u9CMasM+CpAMzKAmITAW1kd8Ff7vGBjfWigNn9NaE4xhkImH0QRLsj6gvgZJWbhDqRma+eUfcw105YYfTqfjkzKW5CLJT7aqYAsy2Olt400ufU1LG5M+YPB4NfU5cwgZh8X/UlyUPJVhHJdlge2jYG5MnPfZHk8aYGHI7rnNpEzeArR4LbRc+Pxebdl86AlTbVP83Wb7G3ErTC0FW70d25WWqrWtTd1PuDb9uCJLknRiaVKjH+dI8kxRBezx0C5PxipQoFKRZaVgLeiUg2qKoxU+Ly+Sl9lMBDpS2jQznrdXhAlJKqjY7UbpFrIh4nU7NjGzqxr3VxTX1c70CI1kTDh/IUg5xkTjNLNyOR2tLPO1fyBmyjN05tqWu3jVUqwXEb+yojqhwF/Vbm0/uGmwYKBpg2SEtPB+dnwWDo3k/447+8/2vPNIuev+LmmerLEu/jmqjM7Tuov1T/oGnpt/ve+sXjtESm7+Ol3b6jKpUNj45Ol2vGpu5N/ORIyJtRk5N8f9Hz+6DvhJ+P6wcvqH14+/MmlxH8+PfPeuY5fNZy7XvO+8thvP1nZ0Pjz9LIy+Wd/LlnSt6e9ZWjkobLkwOA/S1t/cGhvpG/laKpPC/ZsfSez/M6WhauGwjcmjflbxy9fOdM4sf3b7T/88ubCljXhTcsmt58/0Xhh0/zS4TWn9vWu3f9i+Y4lA/eMxM2L1XhEftEzEnijevfZE3v+4Vp6pP+jez9a009vfJes+tP2k8vTB5pbSrRlidCPJ98rbr0wqN83tvvNwa6r96UeONzRS9gvVl77ou/z0/d3vrJ5aejRcPx049t68ROTOl66+tOLR0vaz5wv+c2ug4cPrPlJ3d7P1GVny61Daxd0nn72/POLVr/5+y6z/g1P82jronkfdG87uP/Y9ysf3nst8/G5Yx+eu+J5dezGzSe/2FcyrH126vWT0aKPnw1bIxuHWyYuPz/8rnzh7qmzZPzxb7E7Vi+6967++d+5+vrO3dfb9n3Y2qRc//LXJRsO4LveWjdx5dpTG0bPDv/y6f3/KklPvPDQU33H+9/eXRUuf2F04XOpn/6tNIren1pQVDQ1VVx06a9XlywoLir6L7QNJdA=
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
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
|
||||
@@ -0,0 +1 @@
|
||||
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
|
||||
@@ -1 +0,0 @@
|
||||
eNrtWHtcE3e2x0dXq7W66q3WlnWMokAzIQnhEUq7hQhKCwXlpTw2DpNfksHJzDgzIQks3hUf3PVBG9Tt3lt1a0FwqYL4WqpWqbduZdv6lhXqtvrxVam9t1d3sVp3vec3SXgotb2f2z/XD34+M/M77/M95/xOKupLkCgxPDdoG8PJSKRoGV6k6op6ES1yIkleVudAsp231GakZ2bVOEXmPbssC1JcRAQlMBqZKmFYj4bmHRESokTaXlvEWzydgyLKVHBsXog8qjhCJZewHtKdyomcQ6BMaQwSY61z6JcXmfiM9FTHvLz05JzYNJWaUIFGUeFIpTjbLJES7HGEy07JBCMRjKwm7LzL90g4JWRRExRngReJYCkZTCUsqASxvOBAnCxhcQ7KbRaR5GThNY7QwxefkWYLEmQ71kNZSiiORhZMzXA067Qgs4V3UAyHOfIL4TNyD/g5QE1xkguJ8NVKsRLqcyBSLjPNQ0w5eYBTxkHZkBQ4KK+3I8oCiVjRkC0hkUywAZd3r+CByHOkPxNShF4TCX9NCTQN9pNJHM1bGM7m3W4rZQQ1eG/FcajzHXtrwiPCG0w8xyElpd6GhQgJJMUyJajR5LOLTEWcTbZ7ayK1kdsC37I8AvLuoASBZWgKc0YUSzy3FeIoADDQ0jpJpmSnVFEL2tHHR+sdSJLAl7fTXwk4sfw71NZlIhHQ5t3C2RjO/T0KH7SxVqfTRdfOBAe972XZnWpCH01kIoHQa/UGQhcTZ9DHGYzErLQsBYFLwEoRYtM5tKAsgKofBVQqK8+yvMvsFMxKUnCxqOI4J8uqVQEo+N4CGQa0qHpAmF+mkhmZRX2tIUgCP5vsAC9Q4BRZOA0Umcvl0rBwSuNTpc7wmw3zAW0PvvpIA1cowipSDuTixYWElReJIifDYqQQOHXI6mTVhAPsYUiodjimMNokwsXIdiI1NU0iZBwdmuIIO8SCRQSoFVjkJiQacZTI8JISIxoiQRXxIoj08dqdDgiBhui1xcTyTovPIoB1CUMjxR4oP5b3YIOwHIkGdMBzL1sfLEhqn2xKcUImGY7IlJ0WhlcECSIv87JHAHaM/yKnzaY8KmLtFEaABsIk0bwIIddqjEajIVYfHQkZ6VudOGHl6t7UJIu8g0ikJIaGWPBEgr9JxBFJbjBc7GfsQxmTeRclWiQLJVMSzSBgVNJmBZlkkSKTlHky0HhIFBBJ9iSWRLG0jrYaLEUxsTGPyjIAkWQxPPvkW8kdb7VCHRLIDXwSVB5BOyWZdzCSElOCF/yhpTCWsTse3ok9VYACUUU0IyHW4ysTfMYhZNEQmdC9ENHPCCUrBMiUeQHU9iJZDTU0Q4K0Uw4WOgQIw/PFhtFiwY+8UmOI5iWPJCMHIJJaiC2BMkSU5MHWYNdEACf4wUClwaHM82wAfA5oRxi3GmI278KUavAdiYigfP8pQLTy7rNXoOzA5AT3ihDBOAA5JZDRB8Chj9ZrBwSHr4aVBmiWGQfQ6zQxxvLvnpIdIX3HJMXJdpEXGFqBQokuwt80Jd+4HFZfpswqmV+IlAmjg6aG55efCs+cMpXIY3ASKuhSIp5XvcNFlTLDAdGiRK4fNDWESXEYJ9DCExLvQAR4oYxAnDIINS4iB/q5qlxN9CqgJAniDTb314J7FyAKU5iQKEOOWc8UImWGElE71KyStB4FvTDBSsAGDZHFEzYk4zQRDh5aq1PApWDBDSSQUxHZ/ZBlOOBzKIBVgxaWxe1Z4c1SLh2EXw/C0wQpeOF5jH9ApVOALgSawGFwXCkJvxEEx7s02C/oGoqzikuK+z1fAGRm0IWpOMrh+6aoNPuvD/52bsZzyndzEJw4LmU/6gWmHEu2BCxymrW6XC5HZNwzadoZ+XKJ/Ioj2ZPMc6mq8sJ+6XsYH/kPOOez/wEM5ZcV4E5WAM8FP2T8FAB/QUCAj+ufQ+i7hlCBArEBAvwjT4vvT8o/Z8b/d2ZALguVDuLvE+YfVKS4mCUzEkW+Z1mAusWbhAPu0SyWQLMUrAZkJBlFSvgCLZP4cquFmRRQ558EP6wrWZBEi4ySNkyc8EDDxAl1MKUQWQzifr0Xkgzm47D7UCyLAAUg9GvQELCkQAErjBAvrifdOAO+WzDRczsmoDydUMlOUYTQExB1JQEpuGdCfQTCSwXMU1qopqetmiXajhyU0l0hAQJMHkaZiL3NtuxBV/tK6hkMTqFv2/etB6py3GTxDGdEhLOY7xda2IeULyqGXQZIC3vWtNdq7TC/vM0PzfYmyreboYF3swZ64MXIx/XwErTNX8mkPOCO1IBbPal0Tu8fEgJ2RGQoayOh1UQaNPodblJSZjUUlNI0vHW+tXJ/3wOBoheCHNL/Y4C3zsfc2JeGl7xb0ig6PbOfSBxp7xZKdEQbdvX9Ljo5fFHy1psyHlbnP+xVF6nR6TTG5n6CJQ9He7coldLcE+QelgaojUhSG01qdY2BKLGBVdEYZfy/LKyfBY199GYZFYs3y+/ZWJuzRMA+NNHezbyetju5hcjyHQtxh6rXL1xtLBSk3LPuk8qrt9ag1Wo7pj+SUkT4twmssTYSrrHfIxdf0WTvbuwfqTWS+ugs7GVkXJQhr4MYiNN3L/XbU4ftAYumPYKy154ANfFI6oHswVHPa/AbTTIW7wF4hv6a5Zo9T0iSZxvlWJTFuUv5WanU3LQ9bpLGc56URYpGpIIIt+ztIGJiaYNFTyFUpNWimCiLLjLaGmWI0VqtRdFFlKGopoShvA06jY6w8byNRU2mZNJEQc8hMxXYeOtnzn81IS3FtG0eOZcv4iF+WRTEmYNJEvhBo0FRDRUuojpgn5sw37s7ljZGaS0xtNESY4UBrSeTcufuCACoByC1uD30+8XiyGPPTF41PEj5N2R1zqfcp8lj/r4+zFwdtO4/Yl9d2RUiaByrwyNSOuPPLNd1BlfnR7h+u3GzPeTooQm79v1RW/HixOq2v7y7Qbq6+mDO+7mrGt7ovvs/a0e6FjffO9d0fu2W/MWll/6cfvx++c3c7Nx9Tx991Tt8b9bZ7Kv20RnT/q3oVENjaff4d5KuqKo2WdNtx62Hw7zHjv3sdxt/vnhxd0vDcx+mhDF7vvn2yxe3ntpeGDF5VRddef0n0fGJ/9nxYuSy2nUp4xMrQuq6b6823R53YOaU0Rteen7wlI8bl6bqk9dP0rxPVUy5FecOv1j3VvDw20OnRG0oO9P6uHCk5mc17WOyFoyvnqT1HL0cGubOy7y8ub5WXxkS9teh76S6hyS8f2td91lN46nsUn1lenD4UGPy4kXrn/z8q8cS1zbX//rWKHf1iek3Q44WP3Gy8kxFaHgUvW3z5JoVT8ddeeJc3k+1K4PnF3G/vzyxOcRte2J4fIHm87YaY0HXkLCLu9/6YIiQ+eShLm3tpDpNy5Olh6eNuXFjpu7YE19F11THXHj3rbKWoZfnRb995vj2k7uMB660dT5evPXO/sLOyC+LF623fh0+rmH9Vy2TVX9pr3xqUOWUn+SGesnM9qWFpe8t/6xx4+EdZOKCrtBx35wwrFvz++D45IOXJi460r7ysdJVbR+uvUFUjb3aOrjYgu7Gr0g9Qc9eOSU4NDQxdN972SP/KqafcCW9MfE3e7f+y8b/agwuPrf37JoXputubDp2cXRnK78szlot3gsJKa54ecmXn2yfW71julATevviRzk749etHtlSU3/0tHpS3ow/hWdTq+NTnh58ZfvBBUcvV2Scb7XMulGouim9cm/JjtemDS4Lm9dOhpUFqy/QE4aWHth8+IXNrLrlyvHpSftGzW3JuRr6vPrukszN9W3n7780L7Jl3vKJu5fJdZP2mcP36ytafzV/6TNTr7boznakvFl3P+FmVd6FKHTixOmnli2aGLvwcfG1r5/6+pru1/unsi0t8SPOCM8NWjG7zDMpJl/IO1UlPl13y6ie88m1X/zuXJr3sPd6rnfWv7LPTDk5NNET/Oz6vPhR3pikTW1LY1fn15wbFrucP/jGrmOJFaPj7rau2t+2Lazzb0uIKxltBktO+5o11lGbcuhPf9MUwlfeqfQ0ndplLLAkhjVrynYV76yakHs9c4Jq43n0JpeZ39naOu7K4Huc0FV2b7KFzTftfL3xyFTh28qy48NHVH34BZU0Zu/18ubItcIo/esj04QLKbrfLvuo7kTVZeFgRNWuNUz3rZduP/PhgVub9r186bhj6QJNZ1n6YbrEYjBHR68YrU84f+jFjleiN5fbn18+fRp/1jV+2JBEj22C6XJqyHMxacKgqe6Smux3pSrZ9sX0vJSMisrThk+m1rV3XHr30j9s3zbtOfPayqB/50fMiQu/9qv9Xo1pQor65pg5jqYRHwimr70zPv7Fhajww8MmhBo7m56d0uXYPbJpzKmPT78VnHF9wbX6/dnZ+z7fM8s4/oNV42+v2RD+t5kbgqdHRL46TD3qzu0zmYd2hsXMP998PPWnUds+GXuySWe8eeRA16Vka35428kdf9gxpFqK3WkbN7/b+nrNOxvHxlJznz+5YHJR67MH15lD54dGu375VE7o+49v23px57X2nMoZk/Z+dOeEaU77lht7NkXPGlRTfvq/g8gtd8k5fxLWuis+Gzvee2jrwb9n5r4dX/DmXmP2qpXVh9p19cW3E7+4ZV+Xs8rwx3m59J3Clm/ylhtWl27/pSml4UjE8WNdK2e9UN59496f+c//MSQo6P79IUHd11LTXSOCgv4XTCOo8w==
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
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
|
||||
@@ -1 +0,0 @@
|
||||
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
|
||||
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
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
|
||||
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
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
|
||||
+1
@@ -0,0 +1 @@
|
||||
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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user