langgraph-runtime-inmem 0.19.0__py3-none-any.whl → 0.20.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.
@@ -9,7 +9,7 @@ from langgraph_runtime_inmem import (
9
9
  store,
10
10
  )
11
11
 
12
- __version__ = "0.19.0"
12
+ __version__ = "0.20.0"
13
13
  __all__ = [
14
14
  "ops",
15
15
  "database",
@@ -628,6 +628,7 @@ class Assistants(Authenticated):
628
628
  conn: InMemConnectionProto,
629
629
  *,
630
630
  graph_id: str | None = None,
631
+ name: str | None = None,
631
632
  metadata: MetadataInput = None,
632
633
  ctx: Auth.types.BaseAuthContext | None = None,
633
634
  ) -> int:
@@ -645,6 +646,7 @@ class Assistants(Authenticated):
645
646
  for assistant in conn.store["assistants"]:
646
647
  if (
647
648
  (not graph_id or assistant["graph_id"] == graph_id)
649
+ and (not name or name.lower() in assistant["name"].lower())
648
650
  and (
649
651
  not metadata or is_jsonb_contained(assistant["metadata"], metadata)
650
652
  )
@@ -2849,6 +2851,7 @@ class Crons:
2849
2851
  thread_id: UUID | None = None,
2850
2852
  on_run_completed: Literal["delete", "keep"] | None = None,
2851
2853
  end_time: datetime | None = None,
2854
+ metadata: dict | None = None,
2852
2855
  ctx: Auth.types.BaseAuthContext | None = None,
2853
2856
  ) -> AsyncIterator[Cron]:
2854
2857
  raise NotImplementedError
@@ -2939,19 +2942,154 @@ def _delete_checkpoints_for_thread(
2939
2942
  )
2940
2943
 
2941
2944
 
2942
- def _check_filter_match(metadata: dict, filters: Auth.types.FilterType | None) -> bool:
2945
+ def _validate_filter_structure(
2946
+ filters: Auth.types.FilterType | None,
2947
+ nesting_level: int = 0,
2948
+ ) -> None:
2949
+ """Validate the structure of filter conditions without checking matches.
2950
+
2951
+ Args:
2952
+ filters: The filter conditions to validate
2953
+ nesting_level: Current depth of nested operators (max 2)
2954
+
2955
+ Raises:
2956
+ HTTPException: If the filter structure is invalid
2957
+ """
2958
+ if nesting_level > 2:
2959
+ raise HTTPException(
2960
+ status_code=500,
2961
+ detail="Your auth handler returned a filter with too many nested operators. The maximum depth for nested operators is 2. Please simplify your filter.",
2962
+ )
2963
+
2964
+ if not filters:
2965
+ return
2966
+
2967
+ # Handle $or operator
2968
+ if "$or" in filters:
2969
+ or_groups = filters["$or"]
2970
+ if not isinstance(or_groups, list) or not len(or_groups) >= 2:
2971
+ raise HTTPException(
2972
+ status_code=500,
2973
+ detail="Your auth handler returned a filter with an invalid $or operator. The $or operator must be a list of at least 2 filter objects. Check the filter returned by your auth handler.",
2974
+ )
2975
+
2976
+ # Recursively validate all groups
2977
+ for group in or_groups:
2978
+ _validate_filter_structure(group, nesting_level=nesting_level + 1)
2979
+
2980
+ # Validate remaining filters (implicit AND with the $or)
2981
+ remaining_filters = {k: v for k, v in filters.items() if k != "$or"}
2982
+ if remaining_filters:
2983
+ _validate_filter_structure(
2984
+ remaining_filters, nesting_level=nesting_level + 1
2985
+ )
2986
+
2987
+ # Handle $and operator
2988
+ if "$and" in filters:
2989
+ and_groups = filters["$and"]
2990
+ if not isinstance(and_groups, list) or not len(and_groups) >= 2:
2991
+ raise HTTPException(
2992
+ status_code=500,
2993
+ detail="Your auth handler returned a filter with an invalid $and operator. The $and operator must be a list of at least 2 filter objects. Check the filter returned by your auth handler.",
2994
+ )
2995
+
2996
+ # Recursively validate all groups
2997
+ for group in and_groups:
2998
+ _validate_filter_structure(group, nesting_level=nesting_level + 1)
2999
+
3000
+ # Validate remaining filters (implicit AND with the $and)
3001
+ remaining_filters = {k: v for k, v in filters.items() if k != "$and"}
3002
+ if remaining_filters:
3003
+ _validate_filter_structure(
3004
+ remaining_filters, nesting_level=nesting_level + 1
3005
+ )
3006
+
3007
+
3008
+ def _check_filter_match(
3009
+ metadata: dict,
3010
+ filters: Auth.types.FilterType | None,
3011
+ nesting_level: int = 0,
3012
+ ) -> bool:
2943
3013
  """Check if metadata matches the filter conditions.
2944
3014
 
2945
3015
  Args:
2946
3016
  metadata: The metadata to check
2947
3017
  filters: The filter conditions to apply
3018
+ nesting_level: Current depth of nested operators (max 2)
2948
3019
 
2949
3020
  Returns:
2950
3021
  True if the metadata matches all filter conditions, False otherwise
2951
3022
  """
3023
+ if nesting_level > 2:
3024
+ raise HTTPException(
3025
+ status_code=500,
3026
+ detail="Your auth handler returned a filter with too many nested operators. The maximum depth for nested operators is 2. Please simplify your filter.",
3027
+ )
3028
+
2952
3029
  if not filters:
2953
3030
  return True
2954
3031
 
3032
+ # Handle $or operator
3033
+ if "$or" in filters:
3034
+ or_groups = filters["$or"]
3035
+ if not isinstance(or_groups, list) or not len(or_groups) >= 2:
3036
+ raise HTTPException(
3037
+ status_code=500,
3038
+ detail="Your auth handler returned a filter with an invalid $or operator. The $or operator must be a list of at least 2 filter objects. Check the filter returned by your auth handler.",
3039
+ )
3040
+
3041
+ # Validate all groups first to ensure nesting limits are respected
3042
+ # (even if we short-circuit during matching)
3043
+ for group in or_groups:
3044
+ _validate_filter_structure(group, nesting_level=nesting_level + 1)
3045
+
3046
+ # At least one group must match
3047
+ or_match = False
3048
+ for group in or_groups:
3049
+ if _check_filter_match(metadata, group, nesting_level=nesting_level + 1):
3050
+ or_match = True
3051
+ break
3052
+
3053
+ if not or_match:
3054
+ return False
3055
+
3056
+ # Check remaining filters (implicit AND with the $or)
3057
+ remaining_filters = {k: v for k, v in filters.items() if k != "$or"}
3058
+ if remaining_filters:
3059
+ return _check_filter_match(
3060
+ metadata, remaining_filters, nesting_level=nesting_level + 1
3061
+ )
3062
+ return True
3063
+
3064
+ # Handle $and operator
3065
+ if "$and" in filters:
3066
+ and_groups = filters["$and"]
3067
+ if not isinstance(and_groups, list) or not len(and_groups) >= 2:
3068
+ raise HTTPException(
3069
+ status_code=500,
3070
+ detail="Your auth handler returned a filter with an invalid $and operator. The $and operator must be a list of at least 2 filter objects. Check the filter returned by your auth handler.",
3071
+ )
3072
+
3073
+ # Validate all groups first to ensure nesting limits are respected
3074
+ for group in and_groups:
3075
+ _validate_filter_structure(group, nesting_level=nesting_level + 1)
3076
+
3077
+ # All groups must match
3078
+ for group in and_groups:
3079
+ if not _check_filter_match(
3080
+ metadata, group, nesting_level=nesting_level + 1
3081
+ ):
3082
+ return False
3083
+
3084
+ # Check remaining filters (implicit AND with the $and)
3085
+ remaining_filters = {k: v for k, v in filters.items() if k != "$and"}
3086
+ if remaining_filters:
3087
+ return _check_filter_match(
3088
+ metadata, remaining_filters, nesting_level=nesting_level + 1
3089
+ )
3090
+ return True
3091
+
3092
+ # Regular filter logic (implicit AND)
2955
3093
  for key, value in filters.items():
2956
3094
  if isinstance(value, dict):
2957
3095
  op = next(iter(value))
@@ -156,6 +156,15 @@ def _enable_blockbuster():
156
156
  bb = BlockBuster(excluded_modules=[])
157
157
 
158
158
  bb.functions["os.path.abspath"].can_block_in("inspect.py", "getmodule")
159
+ for fn in (
160
+ "os.access",
161
+ "os.getcwd",
162
+ "os.unlink",
163
+ "os.write",
164
+ ):
165
+ bb.functions[fn].can_block_in(
166
+ "langgraph_api/api/profile.py", "_profile_with_pyspy"
167
+ )
159
168
 
160
169
  for module, func in (
161
170
  ("memory/__init__.py", "sync"),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langgraph-runtime-inmem
3
- Version: 0.19.0
3
+ Version: 0.20.0
4
4
  Summary: Inmem implementation for the LangGraph API server.
5
5
  Author-email: Will Fu-Hinthorn <will@langchain.dev>
6
6
  License: Elastic-2.0
@@ -1,13 +1,13 @@
1
- langgraph_runtime_inmem/__init__.py,sha256=0BIs1nkaj3_LrNv5Rn9zRPO-KeI1bc0YYx5ZxleIq8c,311
1
+ langgraph_runtime_inmem/__init__.py,sha256=w7zaO_iI7aRQ_FockgyKE0A6MGU7U1IOdmyjgLDMp2I,311
2
2
  langgraph_runtime_inmem/checkpoint.py,sha256=nc1G8DqVdIu-ibjKTqXfbPfMbAsKjPObKqegrSzo6Po,4432
3
3
  langgraph_runtime_inmem/database.py,sha256=g2XYa5KN-T8MbDeFH9sfUApDG62Wp4BACumVnDtxYhI,6403
4
4
  langgraph_runtime_inmem/inmem_stream.py,sha256=PFLWbsxU8RqbT5mYJgNk6v5q6TWJRIY1hkZWhJF8nkI,9094
5
5
  langgraph_runtime_inmem/lifespan.py,sha256=fCoYcN_h0cxmj6-muC-f0csPdSpyepZuGRD1yBrq4XM,4755
6
6
  langgraph_runtime_inmem/metrics.py,sha256=_YiSkLnhQvHpMktk38SZo0abyL-5GihfVAtBo0-lFIc,403
7
- langgraph_runtime_inmem/ops.py,sha256=lDR4b-N4pALnMPPc61lpACce1Up-u5U9R5sO0hPTIAw,109276
8
- langgraph_runtime_inmem/queue.py,sha256=17HBZrYaxJg_k4NoabToYD_J6cqVzyHpWIz3VzGg_14,9363
7
+ langgraph_runtime_inmem/ops.py,sha256=qNK_-isTB92kQi3vVSt84__gMG02JUqmkNh-9LURexo,114772
8
+ langgraph_runtime_inmem/queue.py,sha256=WM6ZJu25QPVjFXeJYW06GALLUgRsnRrA4YdypR0oG0U,9584
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.19.0.dist-info/METADATA,sha256=opTbJKPl-tNZseiVB7djNcdOCfoyPCesrjz3QFoB4Hs,570
12
- langgraph_runtime_inmem-0.19.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
13
- langgraph_runtime_inmem-0.19.0.dist-info/RECORD,,
11
+ langgraph_runtime_inmem-0.20.0.dist-info/METADATA,sha256=na8rNZ91-jm6wjZXr04LH-AGpUSM7LRpWIkUdrWTeSM,570
12
+ langgraph_runtime_inmem-0.20.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
13
+ langgraph_runtime_inmem-0.20.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.27.0
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any