langchain-core 1.0.5__py3-none-any.whl → 1.0.7__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.
@@ -19,9 +19,66 @@ if TYPE_CHECKING:
19
19
  from collections.abc import Callable, Sequence
20
20
 
21
21
  try:
22
- from jinja2 import Environment, meta
22
+ from jinja2 import meta
23
+ from jinja2.exceptions import SecurityError
23
24
  from jinja2.sandbox import SandboxedEnvironment
24
25
 
26
+ class _RestrictedSandboxedEnvironment(SandboxedEnvironment):
27
+ """A more restrictive Jinja2 sandbox that blocks all attribute/method access.
28
+
29
+ This sandbox only allows simple variable lookups, no attribute or method access.
30
+ This prevents template injection attacks via methods like parse_raw().
31
+ """
32
+
33
+ def is_safe_attribute(self, _obj: Any, _attr: str, _value: Any) -> bool:
34
+ """Block ALL attribute access for security.
35
+
36
+ Only allow accessing variables directly from the context dict,
37
+ no attribute access on those objects.
38
+
39
+ Args:
40
+ _obj: The object being accessed (unused, always blocked).
41
+ _attr: The attribute name (unused, always blocked).
42
+ _value: The attribute value (unused, always blocked).
43
+
44
+ Returns:
45
+ False - all attribute access is blocked.
46
+ """
47
+ # Block all attribute access
48
+ return False
49
+
50
+ def is_safe_callable(self, _obj: Any) -> bool:
51
+ """Block all method calls for security.
52
+
53
+ Args:
54
+ _obj: The object being checked (unused, always blocked).
55
+
56
+ Returns:
57
+ False - all callables are blocked.
58
+ """
59
+ return False
60
+
61
+ def getattr(self, obj: Any, attribute: str) -> Any:
62
+ """Override getattr to block all attribute access.
63
+
64
+ Args:
65
+ obj: The object.
66
+ attribute: The attribute name.
67
+
68
+ Returns:
69
+ Never returns.
70
+
71
+ Raises:
72
+ SecurityError: Always, to block attribute access.
73
+ """
74
+ msg = (
75
+ f"Access to attributes is not allowed in templates. "
76
+ f"Attempted to access '{attribute}' on {type(obj).__name__}. "
77
+ f"Use only simple variable names like {{{{variable}}}} "
78
+ f"without dots or methods."
79
+ )
80
+ raise SecurityError(msg)
81
+
25
82
  _HAS_JINJA2 = True
26
83
  except ImportError:
27
84
  _HAS_JINJA2 = False
@@ -61,14 +118,10 @@ def jinja2_formatter(template: str, /, **kwargs: Any) -> str:
61
118
  )
62
119
  raise ImportError(msg)
63
120
 
64
- # This uses a sandboxed environment to prevent arbitrary code execution.
65
- # Jinja2 uses an opt-out rather than opt-in approach for sand-boxing.
66
- # Please treat this sand-boxing as a best-effort approach rather than
67
- # a guarantee of security.
68
- # We recommend to never use jinja2 templates with untrusted inputs.
69
- # https://jinja.palletsprojects.com/en/3.1.x/sandbox/
70
- # approach not a guarantee of security.
71
- return SandboxedEnvironment().from_string(template).render(**kwargs)
121
+ # Use a restricted sandbox that blocks ALL attribute/method access
122
+ # Only simple variable lookups like {{variable}} are allowed
123
+ # Attribute access like {{variable.attr}} or {{variable.method()}} is blocked
124
+ return _RestrictedSandboxedEnvironment().from_string(template).render(**kwargs)
72
125
 
73
126
 
74
127
  def validate_jinja2(template: str, input_variables: list[str]) -> None:
@@ -103,7 +156,7 @@ def _get_jinja2_variables_from_template(template: str) -> set[str]:
103
156
  "Please install it with `pip install jinja2`."
104
157
  )
105
158
  raise ImportError(msg)
106
- env = Environment() # noqa: S701
159
+ env = _RestrictedSandboxedEnvironment()
107
160
  ast = env.parse(template)
108
161
  return meta.find_undeclared_variables(ast)
109
162
 
@@ -273,6 +326,30 @@ def get_template_variables(template: str, template_format: str) -> list[str]:
273
326
  msg = f"Unsupported template format: {template_format}"
274
327
  raise ValueError(msg)
275
328
 
329
+ # For f-strings, block attribute access and indexing syntax
330
+ # This prevents template injection attacks via accessing dangerous attributes
331
+ if template_format == "f-string":
332
+ for var in input_variables:
333
+ # Formatter().parse() returns field names with dots/brackets if present
334
+ # e.g., "obj.attr" or "obj[0]" - we need to block these
335
+ if "." in var or "[" in var or "]" in var:
336
+ msg = (
337
+ f"Invalid variable name {var!r} in f-string template. "
338
+ f"Variable names cannot contain attribute "
339
+ f"access (.) or indexing ([])."
340
+ )
341
+ raise ValueError(msg)
342
+
343
+ # Block variable names that are all digits (e.g., "0", "100")
344
+ # These are interpreted as positional arguments, not keyword arguments
345
+ if var.isdigit():
346
+ msg = (
347
+ f"Invalid variable name {var!r} in f-string template. "
348
+ f"Variable names cannot be all digits as they are interpreted "
349
+ f"as positional arguments."
350
+ )
351
+ raise ValueError(msg)
352
+
276
353
  return sorted(input_variables)
277
354
 
278
355
 
@@ -641,6 +641,7 @@ class Graph:
641
641
  retry_delay: float = 1.0,
642
642
  frontmatter_config: dict[str, Any] | None = None,
643
643
  base_url: str | None = None,
644
+ proxies: dict[str, str] | None = None,
644
645
  ) -> bytes:
645
646
  """Draw the graph as a PNG image using Mermaid.
646
647
 
@@ -673,11 +674,10 @@ class Graph:
673
674
  }
674
675
  ```
675
676
  base_url: The base URL of the Mermaid server for rendering via API.
676
-
677
+ proxies: HTTP/HTTPS proxies for requests (e.g. `{"http": "http://127.0.0.1:7890"}`).
677
678
 
678
679
  Returns:
679
680
  The PNG image as bytes.
680
-
681
681
  """
682
682
  # Import locally to prevent circular import
683
683
  from langchain_core.runnables.graph_mermaid import ( # noqa: PLC0415
@@ -698,6 +698,7 @@ class Graph:
698
698
  padding=padding,
699
699
  max_retries=max_retries,
700
700
  retry_delay=retry_delay,
701
+ proxies=proxies,
701
702
  base_url=base_url,
702
703
  )
703
704
 
@@ -281,6 +281,7 @@ def draw_mermaid_png(
281
281
  max_retries: int = 1,
282
282
  retry_delay: float = 1.0,
283
283
  base_url: str | None = None,
284
+ proxies: dict[str, str] | None = None,
284
285
  ) -> bytes:
285
286
  """Draws a Mermaid graph as PNG using provided syntax.
286
287
 
@@ -293,6 +294,7 @@ def draw_mermaid_png(
293
294
  max_retries: Maximum number of retries (MermaidDrawMethod.API).
294
295
  retry_delay: Delay between retries (MermaidDrawMethod.API).
295
296
  base_url: Base URL for the Mermaid.ink API.
297
+ proxies: HTTP/HTTPS proxies for requests (e.g. `{"http": "http://127.0.0.1:7890"}`).
296
298
 
297
299
  Returns:
298
300
  PNG image bytes.
@@ -314,6 +316,7 @@ def draw_mermaid_png(
314
316
  max_retries=max_retries,
315
317
  retry_delay=retry_delay,
316
318
  base_url=base_url,
319
+ proxies=proxies,
317
320
  )
318
321
  else:
319
322
  supported_methods = ", ".join([m.value for m in MermaidDrawMethod])
@@ -405,6 +408,7 @@ def _render_mermaid_using_api(
405
408
  file_type: Literal["jpeg", "png", "webp"] | None = "png",
406
409
  max_retries: int = 1,
407
410
  retry_delay: float = 1.0,
411
+ proxies: dict[str, str] | None = None,
408
412
  base_url: str | None = None,
409
413
  ) -> bytes:
410
414
  """Renders Mermaid graph using the Mermaid.INK API."""
@@ -445,7 +449,7 @@ def _render_mermaid_using_api(
445
449
 
446
450
  for attempt in range(max_retries + 1):
447
451
  try:
448
- response = requests.get(image_url, timeout=10)
452
+ response = requests.get(image_url, timeout=10, proxies=proxies)
449
453
  if response.status_code == requests.codes.ok:
450
454
  img_bytes = response.content
451
455
  if output_file_path is not None:
@@ -386,6 +386,8 @@ class ToolException(Exception): # noqa: N818
386
386
 
387
387
  ArgsSchema = TypeBaseModel | dict[str, Any]
388
388
 
389
+ _EMPTY_SET: frozenset[str] = frozenset()
390
+
389
391
 
390
392
  class BaseTool(RunnableSerializable[str | dict | ToolCall, Any]):
391
393
  """Base class for all LangChain tools.
@@ -569,6 +571,11 @@ class ChildTool(BaseTool):
569
571
  self.name, full_schema, fields, fn_description=self.description
570
572
  )
571
573
 
574
+ @functools.cached_property
575
+ def _injected_args_keys(self) -> frozenset[str]:
576
+ # base implementation doesn't manage injected args
577
+ return _EMPTY_SET
578
+
572
579
  # --- Runnable ---
573
580
 
574
581
  @override
@@ -649,6 +656,7 @@ class ChildTool(BaseTool):
649
656
  if isinstance(input_args, dict):
650
657
  return tool_input
651
658
  if issubclass(input_args, BaseModel):
659
+ # Check args_schema for InjectedToolCallId
652
660
  for k, v in get_all_basemodel_annotations(input_args).items():
653
661
  if _is_injected_arg_type(v, injected_type=InjectedToolCallId):
654
662
  if tool_call_id is None:
@@ -664,6 +672,7 @@ class ChildTool(BaseTool):
664
672
  result = input_args.model_validate(tool_input)
665
673
  result_dict = result.model_dump()
666
674
  elif issubclass(input_args, BaseModelV1):
675
+ # Check args_schema for InjectedToolCallId
667
676
  for k, v in get_all_basemodel_annotations(input_args).items():
668
677
  if _is_injected_arg_type(v, injected_type=InjectedToolCallId):
669
678
  if tool_call_id is None:
@@ -683,9 +692,25 @@ class ChildTool(BaseTool):
683
692
  f"args_schema must be a Pydantic BaseModel, got {self.args_schema}"
684
693
  )
685
694
  raise NotImplementedError(msg)
686
- return {
687
- k: getattr(result, k) for k, v in result_dict.items() if k in tool_input
695
+ validated_input = {
696
+ k: getattr(result, k) for k in result_dict if k in tool_input
688
697
  }
698
+ for k in self._injected_args_keys:
699
+ if k == "tool_call_id":
700
+ if tool_call_id is None:
701
+ msg = (
702
+ "When tool includes an InjectedToolCallId "
703
+ "argument, tool must always be invoked with a full "
704
+ "model ToolCall of the form: {'args': {...}, "
705
+ "'name': '...', 'type': 'tool_call', "
706
+ "'tool_call_id': '...'}"
707
+ )
708
+ raise ValueError(msg)
709
+ validated_input[k] = tool_call_id
710
+ if k in tool_input:
711
+ injected_val = tool_input[k]
712
+ validated_input[k] = injected_val
713
+ return validated_input
689
714
  return tool_input
690
715
 
691
716
  @abstractmethod
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import functools
5
6
  import textwrap
6
7
  from collections.abc import Awaitable, Callable
7
8
  from inspect import signature
@@ -21,10 +22,12 @@ from langchain_core.callbacks import (
21
22
  )
22
23
  from langchain_core.runnables import RunnableConfig, run_in_executor
23
24
  from langchain_core.tools.base import (
25
+ _EMPTY_SET,
24
26
  FILTERED_ARGS,
25
27
  ArgsSchema,
26
28
  BaseTool,
27
29
  _get_runnable_config_param,
30
+ _is_injected_arg_type,
28
31
  create_schema_from_function,
29
32
  )
30
33
  from langchain_core.utils.pydantic import is_basemodel_subclass
@@ -241,6 +244,17 @@ class StructuredTool(BaseTool):
241
244
  **kwargs,
242
245
  )
243
246
 
247
+ @functools.cached_property
248
+ def _injected_args_keys(self) -> frozenset[str]:
249
+ fn = self.func or self.coroutine
250
+ if fn is None:
251
+ return _EMPTY_SET
252
+ return frozenset(
253
+ k
254
+ for k, v in signature(fn).parameters.items()
255
+ if _is_injected_arg_type(v.annotation)
256
+ )
257
+
244
258
 
245
259
  def _filter_schema_args(func: Callable) -> list[str]:
246
260
  filter_args = list(FILTERED_ARGS)
@@ -374,15 +374,29 @@ def _get_key(
374
374
  if resolved_scope in (0, False):
375
375
  return resolved_scope
376
376
  # Move into the scope
377
- try:
378
- # Try subscripting (Normal dictionaries)
379
- resolved_scope = cast("dict[str, Any]", resolved_scope)[child]
380
- except (TypeError, AttributeError):
377
+ if isinstance(resolved_scope, dict):
381
378
  try:
382
- resolved_scope = getattr(resolved_scope, child)
383
- except (TypeError, AttributeError):
384
- # Try as a list
385
- resolved_scope = resolved_scope[int(child)] # type: ignore[index]
379
+ resolved_scope = resolved_scope[child]
380
+ except (KeyError, TypeError):
381
+ # Key not found - will be caught by outer try-except
382
+ msg = f"Key {child!r} not found in dict"
383
+ raise KeyError(msg) from None
384
+ elif isinstance(resolved_scope, (list, tuple)):
385
+ try:
386
+ resolved_scope = resolved_scope[int(child)]
387
+ except (ValueError, IndexError, TypeError):
388
+ # Invalid index - will be caught by outer try-except
389
+ msg = f"Invalid index {child!r} for list/tuple"
390
+ raise IndexError(msg) from None
391
+ else:
392
+ # Reject everything else for security
393
+ # This prevents traversing into arbitrary Python objects
394
+ msg = (
395
+ f"Cannot traverse into {type(resolved_scope).__name__}. "
396
+ "Mustache templates only support dict, list, and tuple. "
397
+ f"Got: {type(resolved_scope)}"
398
+ )
399
+ raise TypeError(msg) # noqa: TRY301
386
400
 
387
401
  try:
388
402
  # This allows for custom falsy data types
@@ -393,8 +407,9 @@ def _get_key(
393
407
  if resolved_scope in (0, False):
394
408
  return resolved_scope
395
409
  return resolved_scope or ""
396
- except (AttributeError, KeyError, IndexError, ValueError):
410
+ except (AttributeError, KeyError, IndexError, ValueError, TypeError):
397
411
  # We couldn't find the key in the current scope
412
+ # TypeError: Attempted to traverse into non-dict/list type
398
413
  # We'll try again on the next pass
399
414
  pass
400
415
 
langchain_core/version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """langchain-core version information and utilities."""
2
2
 
3
- VERSION = "1.0.5"
3
+ VERSION = "1.0.7"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langchain-core
3
- Version: 1.0.5
3
+ Version: 1.0.7
4
4
  Summary: Building applications with LLMs through composability
5
5
  Project-URL: Homepage, https://docs.langchain.com/
6
6
  Project-URL: Documentation, https://reference.langchain.com/python/langchain_core/
@@ -15,7 +15,7 @@ langchain_core/retrievers.py,sha256=SXnCc_85rNcLeMa-SjvkijXpFw-I7SVTWYgV1gJQimg,
15
15
  langchain_core/stores.py,sha256=g8aa_VvXf93-Q25QMXX_sBoKC99nu3FtyC4INOUJ3WY,9181
16
16
  langchain_core/structured_query.py,sha256=mat7BKovKjckzMn3-I1El49yeGjg3cqk4ptpJHAPA-4,5123
17
17
  langchain_core/sys_info.py,sha256=SEFI7XL2qpx1lis6cB45o6ZKtRCZWVXwEngU3UGMgrE,3806
18
- langchain_core/version.py,sha256=jWWKpYGZRCxjUlsDuTeoAT_Xmifcmm8HFZDQo6Pc1a4,75
18
+ langchain_core/version.py,sha256=cFzsjswCa-CtIr7XINgrfnB5V6ZQT05GwZLHnpGKNV0,75
19
19
  langchain_core/_api/__init__.py,sha256=PYm_j7qRRKh5ca0TTra5UF-nko3ieZZZ5EeAFAinm3o,1973
20
20
  langchain_core/_api/beta_decorator.py,sha256=IJgG2_kRb2eBmvHfarDjanJY4k1jwoPJWSOHZ5SLB4U,8664
21
21
  langchain_core/_api/deprecation.py,sha256=nReAhxZ1dBwLhHdGAaqqRpf7aLQJ1dw4UtqmrRqeNLE,20296
@@ -106,7 +106,7 @@ langchain_core/prompts/image.py,sha256=L_5yGsI68Y0pwthA3AS0mQXFMXtvW_kBRItFS6Vpk
106
106
  langchain_core/prompts/loading.py,sha256=hvNsDvqLz5wJA1EywW2wCwKUhJgUzNcIKfp5VEVOEGc,6889
107
107
  langchain_core/prompts/message.py,sha256=3BdmchS6Y0DCo5edE-R3qcbSqfpbv_AGwE5UcYZ6gU8,2636
108
108
  langchain_core/prompts/prompt.py,sha256=TcQZNc-Y6c7CMJwY1HwMvRYU4NcbMdCw6YS37Tc3pWk,10948
109
- langchain_core/prompts/string.py,sha256=hTkXW-SoN4vo_PbOlK_RxXzXhoRQQRucCBJ7F0bFuTE,11012
109
+ langchain_core/prompts/string.py,sha256=CAx6sPPXpbHVPe9hwDbmZPKIPxJf4nfvmtGw5xW1CYM,14047
110
110
  langchain_core/prompts/structured.py,sha256=Uzh1PBLXzGyZ-4m4W-cMHz8nqL1XmMri8OOkoSSJiq8,5790
111
111
  langchain_core/runnables/__init__.py,sha256=efTnFjwN_QSAv5ThLmKuWeu8P1BLARH-cWKZBuimfDM,3858
112
112
  langchain_core/runnables/base.py,sha256=vUR1HWB28OkWBWNm03qLCYaewCAWrNguqH9ob-7vJsY,216503
@@ -114,9 +114,9 @@ langchain_core/runnables/branch.py,sha256=Wviy59agVKhbwD_GlMZz-HP5pXZgw5oI5MJb1n
114
114
  langchain_core/runnables/config.py,sha256=w2f2BeYbiXIuXxYJCrmSDIh7LgwSyF-7p92W-sxrbKU,19103
115
115
  langchain_core/runnables/configurable.py,sha256=1FalcSplZ2EITuV-g-TxMoDiS3eZT32OF33ZLjxftd0,24053
116
116
  langchain_core/runnables/fallbacks.py,sha256=60WZ8RoIlE69HsYqAyLncbdh0OhcBxbwvV3NYZogdyk,24468
117
- langchain_core/runnables/graph.py,sha256=0Zhv5saaIQL1NvfESvkhRIYJGCfJBdrWQZg65jZrK9w,22923
117
+ langchain_core/runnables/graph.py,sha256=7u6LPc6Ih3f6REbyGrRE1R3lacHBTdrt1RPXBAXIdog,23094
118
118
  langchain_core/runnables/graph_ascii.py,sha256=F6EzMEL7yWpZxox1fIMvt3v5-uCp6ISbAAkniin9jIc,10333
119
- langchain_core/runnables/graph_mermaid.py,sha256=k615r8Q641pb_rpjTlmVc5fTlMco-1IIxQI8t3kBceE,16725
119
+ langchain_core/runnables/graph_mermaid.py,sha256=hUy4QLzrd3xPks5x9wAahd9TSbk-pHbrkV2zo8b0IfU,16950
120
120
  langchain_core/runnables/graph_png.py,sha256=pdt7_sRPJw38vkKixdb1yYB78kaxIA5ijnAdjJFt3l4,6473
121
121
  langchain_core/runnables/history.py,sha256=5vvSniD6rjPai3bnxp2WxyTMW2jSHxqN0cZflnjoJs4,24264
122
122
  langchain_core/runnables/passthrough.py,sha256=OwSGfJAz1uh54ORppmrQozMe5xDOpM2iB2HhjGkdnjo,26230
@@ -125,12 +125,12 @@ langchain_core/runnables/router.py,sha256=oY_PZb3Mh5Z7j4eBVMO_sXP_f6EapxV0NHknhd
125
125
  langchain_core/runnables/schema.py,sha256=elc_pen9QvLkM2MoH7QqjRMqDS0yylwjvbl_gdeOD5Y,5719
126
126
  langchain_core/runnables/utils.py,sha256=NLdqnRI8abuOrLZrSJZcJ1r0MQuVzn983q5EUQAlTmk,22188
127
127
  langchain_core/tools/__init__.py,sha256=qe2E9VwZ7hpdkToz96oSJ080a0de9oQwSO9FP1XnmM0,2518
128
- langchain_core/tools/base.py,sha256=ejOqr0b-gJC1keQ666HgJv0kl_Q-F2WLhFs5UXlk5ts,51395
128
+ langchain_core/tools/base.py,sha256=wkVdCPMFb1o5Vt2a0NL30KLOu59KLpleLa7vdVqHs-o,52537
129
129
  langchain_core/tools/convert.py,sha256=xuvdirFB3a3A_qPN14-msXAvVt0dSUPMzD9iQUZzX8E,16258
130
130
  langchain_core/tools/render.py,sha256=gD3pXYWjCaDKsYq_MZ-yCRXl1wUJbOh6dJobda9VjYM,1817
131
131
  langchain_core/tools/retriever.py,sha256=hPdBhK8QBK2bRpyNMtq7VtA1qnTRQurRMRjPbVDNG-k,3791
132
132
  langchain_core/tools/simple.py,sha256=U9R5jIUcZMXKMV5Ezu8G2MX_0ot2nrtvhjgaGHkA53o,6623
133
- langchain_core/tools/structured.py,sha256=KV9u6S33rI0VBPwpA6ZmPtt08j8LZjMDnEgX5EhiDaw,9205
133
+ langchain_core/tools/structured.py,sha256=jKvolVZCWcdjKCiCY92zyrRqST520T0VmmEnS-HqoEo,9602
134
134
  langchain_core/tracers/__init__.py,sha256=Yf0CQ-IcBa8f9lu0wMA_looT6Q8we3C0yd-xMP3c0Sc,1362
135
135
  langchain_core/tracers/_streaming.py,sha256=U9pWQDJNUDH4oOYF3zvUMUtgkCecJzXQvfo-wYARmhQ,982
136
136
  langchain_core/tracers/base.py,sha256=cywwNDlynmidmhOCQ8A1J0qhnvN_orWNB8z2UjvCEGs,25454
@@ -158,7 +158,7 @@ langchain_core/utils/interactive_env.py,sha256=LBgNICNAwgwDMOdlVD12TtZfSboPOKXaB
158
158
  langchain_core/utils/iter.py,sha256=jqtyfA2129a5ftfuRovpUBEslCGaeuiiGr8bkT-iozI,7300
159
159
  langchain_core/utils/json.py,sha256=twJgPBf86nwZzZDt3LoLbO5YOutWMt49GxpmG_pAoDQ,6571
160
160
  langchain_core/utils/json_schema.py,sha256=d0yHW6D_IoM7sLGOLxSGcSpAnaYROaqbwmjk7XhvZZ4,9071
161
- langchain_core/utils/mustache.py,sha256=2LgatBIOa1bGU4EaL5xrS076NWqfQkB4Mtencmc3mtQ,21262
161
+ langchain_core/utils/mustache.py,sha256=aSA8olMczoiVgqx7RUZBRdekJxkGdrQyPnstJMdIDQM,22139
162
162
  langchain_core/utils/pydantic.py,sha256=-xFQM2DAFy9cPkUHCYP87buXdnIYofeYaqZEs-FbQg8,18474
163
163
  langchain_core/utils/strings.py,sha256=DGhj7CxgxcYIdvMu3Ug93BtayNFaRvyIecgIaxZOa1g,1721
164
164
  langchain_core/utils/usage.py,sha256=vB674Eu69xDGx6JBJlySp6cnePkxCD0Wz26mi502NAM,1211
@@ -167,6 +167,6 @@ langchain_core/vectorstores/__init__.py,sha256=5P0eoeoH5LHab64JjmEeWa6SxX4eMy-et
167
167
  langchain_core/vectorstores/base.py,sha256=ZEY2EBnm5hZciYUTic_f-QoMGLU120jbolIbzZqQmjs,40757
168
168
  langchain_core/vectorstores/in_memory.py,sha256=R71jJ5_RCyViyvndLJ6SSwRiiECl6KpVbcVVGPFyUVM,15692
169
169
  langchain_core/vectorstores/utils.py,sha256=XXpQ2mxado6vrLmZWVTstcxrurBtoHcBZEORITAHWw0,4931
170
- langchain_core-1.0.5.dist-info/METADATA,sha256=RPittwRuncOHvKwbUfW1xlDr1CN2ZmsVQ8AbMIg_5XU,3629
171
- langchain_core-1.0.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
172
- langchain_core-1.0.5.dist-info/RECORD,,
170
+ langchain_core-1.0.7.dist-info/METADATA,sha256=DLZXMp4BNz8rZKLE7EBBXoK36AccxNRcbbOqTgxTnwU,3629
171
+ langchain_core-1.0.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
172
+ langchain_core-1.0.7.dist-info/RECORD,,