langgraph-runtime-inmem 0.6.13__py3-none-any.whl → 0.8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- langgraph_runtime_inmem/__init__.py +1 -1
- langgraph_runtime_inmem/ops.py +131 -12
- {langgraph_runtime_inmem-0.6.13.dist-info → langgraph_runtime_inmem-0.8.0.dist-info}/METADATA +1 -1
- {langgraph_runtime_inmem-0.6.13.dist-info → langgraph_runtime_inmem-0.8.0.dist-info}/RECORD +5 -5
- {langgraph_runtime_inmem-0.6.13.dist-info → langgraph_runtime_inmem-0.8.0.dist-info}/WHEEL +0 -0
langgraph_runtime_inmem/ops.py
CHANGED
|
@@ -34,10 +34,12 @@ if typing.TYPE_CHECKING:
|
|
|
34
34
|
from langgraph_api.config import ThreadTTLConfig
|
|
35
35
|
from langgraph_api.schema import (
|
|
36
36
|
Assistant,
|
|
37
|
+
AssistantSelectField,
|
|
37
38
|
Checkpoint,
|
|
38
39
|
Config,
|
|
39
40
|
Context,
|
|
40
41
|
Cron,
|
|
42
|
+
CronSelectField,
|
|
41
43
|
DeprecatedInterrupt,
|
|
42
44
|
IfNotExists,
|
|
43
45
|
MetadataInput,
|
|
@@ -46,14 +48,17 @@ if typing.TYPE_CHECKING:
|
|
|
46
48
|
OnConflictBehavior,
|
|
47
49
|
QueueStats,
|
|
48
50
|
Run,
|
|
51
|
+
RunSelectField,
|
|
49
52
|
RunStatus,
|
|
50
53
|
StreamMode,
|
|
51
54
|
Thread,
|
|
55
|
+
ThreadSelectField,
|
|
52
56
|
ThreadStatus,
|
|
53
57
|
ThreadUpdateResponse,
|
|
54
58
|
)
|
|
55
59
|
from langgraph_api.schema import Interrupt as InterruptSchema
|
|
56
60
|
from langgraph_api.serde import Fragment
|
|
61
|
+
from langgraph_api.utils import AsyncConnectionProto
|
|
57
62
|
|
|
58
63
|
|
|
59
64
|
logger = structlog.stdlib.get_logger(__name__)
|
|
@@ -136,6 +141,7 @@ class Assistants(Authenticated):
|
|
|
136
141
|
offset: int,
|
|
137
142
|
sort_by: str | None = None,
|
|
138
143
|
sort_order: str | None = None,
|
|
144
|
+
select: list[AssistantSelectField] | None = None,
|
|
139
145
|
ctx: Auth.types.BaseAuthContext | None = None,
|
|
140
146
|
) -> tuple[AsyncIterator[Assistant], int]:
|
|
141
147
|
metadata = metadata if metadata is not None else {}
|
|
@@ -178,6 +184,7 @@ class Assistants(Authenticated):
|
|
|
178
184
|
else:
|
|
179
185
|
filtered_assistants.sort(key=lambda x: x.get(sort_by), reverse=reverse)
|
|
180
186
|
else:
|
|
187
|
+
sort_by = "created_at"
|
|
181
188
|
# Default sorting by created_at in descending order
|
|
182
189
|
filtered_assistants.sort(key=lambda x: x["created_at"], reverse=True)
|
|
183
190
|
|
|
@@ -187,14 +194,21 @@ class Assistants(Authenticated):
|
|
|
187
194
|
|
|
188
195
|
async def assistant_iterator() -> AsyncIterator[Assistant]:
|
|
189
196
|
for assistant in paginated_assistants:
|
|
190
|
-
|
|
197
|
+
if select:
|
|
198
|
+
# Filter to only selected fields
|
|
199
|
+
filtered_assistant = {
|
|
200
|
+
k: v for k, v in assistant.items() if k in select
|
|
201
|
+
}
|
|
202
|
+
yield filtered_assistant
|
|
203
|
+
else:
|
|
204
|
+
yield assistant
|
|
191
205
|
|
|
192
206
|
return assistant_iterator(), cur
|
|
193
207
|
|
|
194
208
|
@staticmethod
|
|
195
209
|
async def get(
|
|
196
210
|
conn: InMemConnectionProto,
|
|
197
|
-
assistant_id: UUID,
|
|
211
|
+
assistant_id: UUID | str,
|
|
198
212
|
ctx: Auth.types.BaseAuthContext | None = None,
|
|
199
213
|
) -> AsyncIterator[Assistant]:
|
|
200
214
|
"""Get an assistant by ID."""
|
|
@@ -217,7 +231,7 @@ class Assistants(Authenticated):
|
|
|
217
231
|
@staticmethod
|
|
218
232
|
async def put(
|
|
219
233
|
conn: InMemConnectionProto,
|
|
220
|
-
assistant_id: UUID,
|
|
234
|
+
assistant_id: UUID | str,
|
|
221
235
|
*,
|
|
222
236
|
graph_id: str,
|
|
223
237
|
config: Config,
|
|
@@ -597,6 +611,37 @@ class Assistants(Authenticated):
|
|
|
597
611
|
|
|
598
612
|
return _yield_versions()
|
|
599
613
|
|
|
614
|
+
@staticmethod
|
|
615
|
+
async def count(
|
|
616
|
+
conn: InMemConnectionProto,
|
|
617
|
+
*,
|
|
618
|
+
graph_id: str | None = None,
|
|
619
|
+
metadata: MetadataInput = None,
|
|
620
|
+
ctx: Auth.types.BaseAuthContext | None = None,
|
|
621
|
+
) -> int:
|
|
622
|
+
"""Get count of assistants."""
|
|
623
|
+
metadata = metadata if metadata is not None else {}
|
|
624
|
+
filters = await Assistants.handle_event(
|
|
625
|
+
ctx,
|
|
626
|
+
"search",
|
|
627
|
+
Auth.types.AssistantsSearch(
|
|
628
|
+
graph_id=graph_id, metadata=metadata, limit=0, offset=0
|
|
629
|
+
),
|
|
630
|
+
)
|
|
631
|
+
|
|
632
|
+
count = 0
|
|
633
|
+
for assistant in conn.store["assistants"]:
|
|
634
|
+
if (
|
|
635
|
+
(not graph_id or assistant["graph_id"] == graph_id)
|
|
636
|
+
and (
|
|
637
|
+
not metadata or is_jsonb_contained(assistant["metadata"], metadata)
|
|
638
|
+
)
|
|
639
|
+
and (not filters or _check_filter_match(assistant["metadata"], filters))
|
|
640
|
+
):
|
|
641
|
+
count += 1
|
|
642
|
+
|
|
643
|
+
return count
|
|
644
|
+
|
|
600
645
|
|
|
601
646
|
def is_jsonb_contained(superset: dict[str, Any], subset: dict[str, Any]) -> bool:
|
|
602
647
|
"""
|
|
@@ -680,7 +725,7 @@ def _patch_interrupt(
|
|
|
680
725
|
"value": interrupt.value,
|
|
681
726
|
"resumable": interrupt.resumable,
|
|
682
727
|
"ns": interrupt.ns,
|
|
683
|
-
"when": interrupt.when,
|
|
728
|
+
"when": interrupt.when, # type: ignore[unresolved-attribute]
|
|
684
729
|
}
|
|
685
730
|
|
|
686
731
|
|
|
@@ -698,6 +743,7 @@ class Threads(Authenticated):
|
|
|
698
743
|
offset: int,
|
|
699
744
|
sort_by: str | None = None,
|
|
700
745
|
sort_order: str | None = None,
|
|
746
|
+
select: list[ThreadSelectField] | None = None,
|
|
701
747
|
ctx: Auth.types.BaseAuthContext | None = None,
|
|
702
748
|
) -> tuple[AsyncIterator[Thread], int]:
|
|
703
749
|
threads = conn.store["threads"]
|
|
@@ -747,6 +793,7 @@ class Threads(Authenticated):
|
|
|
747
793
|
filtered_threads, key=lambda x: x.get(sort_by), reverse=reverse
|
|
748
794
|
)
|
|
749
795
|
else:
|
|
796
|
+
sort_by = "created_at"
|
|
750
797
|
# Default sorting by created_at in descending order
|
|
751
798
|
sorted_threads = sorted(
|
|
752
799
|
filtered_threads, key=lambda x: x["updated_at"], reverse=True
|
|
@@ -758,7 +805,12 @@ class Threads(Authenticated):
|
|
|
758
805
|
|
|
759
806
|
async def thread_iterator() -> AsyncIterator[Thread]:
|
|
760
807
|
for thread in paginated_threads:
|
|
761
|
-
|
|
808
|
+
if select:
|
|
809
|
+
# Filter to only selected fields
|
|
810
|
+
filtered_thread = {k: v for k, v in thread.items() if k in select}
|
|
811
|
+
yield filtered_thread
|
|
812
|
+
else:
|
|
813
|
+
yield thread
|
|
762
814
|
|
|
763
815
|
return thread_iterator(), cursor
|
|
764
816
|
|
|
@@ -822,7 +874,7 @@ class Threads(Authenticated):
|
|
|
822
874
|
@staticmethod
|
|
823
875
|
async def put(
|
|
824
876
|
conn: InMemConnectionProto,
|
|
825
|
-
thread_id: UUID,
|
|
877
|
+
thread_id: UUID | str,
|
|
826
878
|
*,
|
|
827
879
|
metadata: MetadataInput,
|
|
828
880
|
if_exists: OnConflictBehavior,
|
|
@@ -1559,6 +1611,53 @@ class Threads(Authenticated):
|
|
|
1559
1611
|
|
|
1560
1612
|
return []
|
|
1561
1613
|
|
|
1614
|
+
@staticmethod
|
|
1615
|
+
async def count(
|
|
1616
|
+
conn: InMemConnectionProto,
|
|
1617
|
+
*,
|
|
1618
|
+
metadata: MetadataInput = None,
|
|
1619
|
+
values: MetadataInput = None,
|
|
1620
|
+
status: ThreadStatus | None = None,
|
|
1621
|
+
ctx: Auth.types.BaseAuthContext | None = None,
|
|
1622
|
+
) -> int:
|
|
1623
|
+
"""Get count of threads."""
|
|
1624
|
+
threads = conn.store["threads"]
|
|
1625
|
+
metadata = metadata if metadata is not None else {}
|
|
1626
|
+
values = values if values is not None else {}
|
|
1627
|
+
filters = await Threads.handle_event(
|
|
1628
|
+
ctx,
|
|
1629
|
+
"search",
|
|
1630
|
+
Auth.types.ThreadsSearch(
|
|
1631
|
+
metadata=metadata,
|
|
1632
|
+
values=values,
|
|
1633
|
+
status=status,
|
|
1634
|
+
limit=0,
|
|
1635
|
+
offset=0,
|
|
1636
|
+
),
|
|
1637
|
+
)
|
|
1638
|
+
|
|
1639
|
+
count = 0
|
|
1640
|
+
for thread in threads:
|
|
1641
|
+
if filters and not _check_filter_match(thread["metadata"], filters):
|
|
1642
|
+
continue
|
|
1643
|
+
|
|
1644
|
+
if metadata and not is_jsonb_contained(thread["metadata"], metadata):
|
|
1645
|
+
continue
|
|
1646
|
+
|
|
1647
|
+
if (
|
|
1648
|
+
values
|
|
1649
|
+
and "values" in thread
|
|
1650
|
+
and not is_jsonb_contained(thread["values"], values)
|
|
1651
|
+
):
|
|
1652
|
+
continue
|
|
1653
|
+
|
|
1654
|
+
if status and thread.get("status") != status:
|
|
1655
|
+
continue
|
|
1656
|
+
|
|
1657
|
+
count += 1
|
|
1658
|
+
|
|
1659
|
+
return count
|
|
1660
|
+
|
|
1562
1661
|
|
|
1563
1662
|
RUN_LOCK = asyncio.Lock()
|
|
1564
1663
|
|
|
@@ -1724,7 +1823,7 @@ class Runs(Authenticated):
|
|
|
1724
1823
|
|
|
1725
1824
|
@staticmethod
|
|
1726
1825
|
async def put(
|
|
1727
|
-
conn: InMemConnectionProto,
|
|
1826
|
+
conn: InMemConnectionProto | AsyncConnectionProto,
|
|
1728
1827
|
assistant_id: UUID,
|
|
1729
1828
|
kwargs: dict,
|
|
1730
1829
|
*,
|
|
@@ -2068,8 +2167,8 @@ class Runs(Authenticated):
|
|
|
2068
2167
|
|
|
2069
2168
|
@staticmethod
|
|
2070
2169
|
async def cancel(
|
|
2071
|
-
conn: InMemConnectionProto,
|
|
2072
|
-
run_ids: Sequence[UUID] | None = None,
|
|
2170
|
+
conn: InMemConnectionProto | AsyncConnectionProto,
|
|
2171
|
+
run_ids: Sequence[UUID | str] | None = None,
|
|
2073
2172
|
*,
|
|
2074
2173
|
action: Literal["interrupt", "rollback"] = "interrupt",
|
|
2075
2174
|
thread_id: UUID | None = None,
|
|
@@ -2233,6 +2332,7 @@ class Runs(Authenticated):
|
|
|
2233
2332
|
limit: int = 10,
|
|
2234
2333
|
offset: int = 0,
|
|
2235
2334
|
status: RunStatus | None = None,
|
|
2335
|
+
select: list[RunSelectField] | None = None,
|
|
2236
2336
|
ctx: Auth.types.BaseAuthContext | None = None,
|
|
2237
2337
|
) -> AsyncIterator[Run]:
|
|
2238
2338
|
"""List all runs by thread."""
|
|
@@ -2260,7 +2360,12 @@ class Runs(Authenticated):
|
|
|
2260
2360
|
|
|
2261
2361
|
async def _return():
|
|
2262
2362
|
for run in sliced_runs:
|
|
2263
|
-
|
|
2363
|
+
if select:
|
|
2364
|
+
# Filter to only selected fields
|
|
2365
|
+
filtered_run = {k: v for k, v in run.items() if k in select}
|
|
2366
|
+
yield filtered_run
|
|
2367
|
+
else:
|
|
2368
|
+
yield run
|
|
2264
2369
|
|
|
2265
2370
|
return _return()
|
|
2266
2371
|
|
|
@@ -2432,7 +2537,7 @@ class Runs(Authenticated):
|
|
|
2432
2537
|
|
|
2433
2538
|
@staticmethod
|
|
2434
2539
|
async def publish(
|
|
2435
|
-
run_id: UUID,
|
|
2540
|
+
run_id: UUID | str,
|
|
2436
2541
|
event: str,
|
|
2437
2542
|
message: bytes,
|
|
2438
2543
|
*,
|
|
@@ -2533,10 +2638,24 @@ class Crons:
|
|
|
2533
2638
|
thread_id: UUID | None,
|
|
2534
2639
|
limit: int,
|
|
2535
2640
|
offset: int,
|
|
2641
|
+
select: list[CronSelectField] | None = None,
|
|
2536
2642
|
ctx: Auth.types.BaseAuthContext | None = None,
|
|
2537
|
-
|
|
2643
|
+
sort_by: str | None = None,
|
|
2644
|
+
sort_order: Literal["asc", "desc"] | None = None,
|
|
2645
|
+
) -> tuple[AsyncIterator[Cron], int]:
|
|
2538
2646
|
raise NotImplementedError
|
|
2539
2647
|
|
|
2648
|
+
@staticmethod
|
|
2649
|
+
async def count(
|
|
2650
|
+
conn: InMemConnectionProto,
|
|
2651
|
+
*,
|
|
2652
|
+
assistant_id: UUID | None = None,
|
|
2653
|
+
thread_id: UUID | None = None,
|
|
2654
|
+
ctx: Auth.types.BaseAuthContext | None = None,
|
|
2655
|
+
) -> int:
|
|
2656
|
+
"""Get count of crons."""
|
|
2657
|
+
raise NotImplementedError("The in-mem server does not implement Crons.")
|
|
2658
|
+
|
|
2540
2659
|
|
|
2541
2660
|
async def cancel_run(
|
|
2542
2661
|
thread_id: UUID, run_id: UUID, ctx: Auth.types.BaseAuthContext | None = None
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
langgraph_runtime_inmem/__init__.py,sha256=
|
|
1
|
+
langgraph_runtime_inmem/__init__.py,sha256=ZCa8w1LAQPb9BIGUaaEwW1hak0vidcMAUArcD_C1lyU,310
|
|
2
2
|
langgraph_runtime_inmem/checkpoint.py,sha256=nc1G8DqVdIu-ibjKTqXfbPfMbAsKjPObKqegrSzo6Po,4432
|
|
3
3
|
langgraph_runtime_inmem/database.py,sha256=G_6L2khpRDSpS2Vs_SujzHayODcwG5V2IhFP7LLBXgw,6349
|
|
4
4
|
langgraph_runtime_inmem/inmem_stream.py,sha256=UWk1srLF44HZPPbRdArGGhsy0MY0UOJKSIxBSO7Hosc,5138
|
|
5
5
|
langgraph_runtime_inmem/lifespan.py,sha256=t0w2MX2dGxe8yNtSX97Z-d2pFpllSLS4s1rh2GJDw5M,3557
|
|
6
6
|
langgraph_runtime_inmem/metrics.py,sha256=HhO0RC2bMDTDyGBNvnd2ooLebLA8P1u5oq978Kp_nAA,392
|
|
7
|
-
langgraph_runtime_inmem/ops.py,sha256=
|
|
7
|
+
langgraph_runtime_inmem/ops.py,sha256=pV2IHiis4ydYFtroOfX-FcQjhXvk5O1ESuy2kk7mbyI,98064
|
|
8
8
|
langgraph_runtime_inmem/queue.py,sha256=33qfFKPhQicZ1qiibllYb-bTFzUNSN2c4bffPACP5es,9952
|
|
9
9
|
langgraph_runtime_inmem/retry.py,sha256=XmldOP4e_H5s264CagJRVnQMDFcEJR_dldVR1Hm5XvM,763
|
|
10
10
|
langgraph_runtime_inmem/store.py,sha256=rTfL1JJvd-j4xjTrL8qDcynaWF6gUJ9-GDVwH0NBD_I,3506
|
|
11
|
-
langgraph_runtime_inmem-0.
|
|
12
|
-
langgraph_runtime_inmem-0.
|
|
13
|
-
langgraph_runtime_inmem-0.
|
|
11
|
+
langgraph_runtime_inmem-0.8.0.dist-info/METADATA,sha256=hg_MVwCcdeCjZrYul77k4J5y5ByIUDOtTqqUOQbyqDs,565
|
|
12
|
+
langgraph_runtime_inmem-0.8.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
13
|
+
langgraph_runtime_inmem-0.8.0.dist-info/RECORD,,
|
|
File without changes
|