langchain-core 0.3.70__py3-none-any.whl → 0.3.71__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of langchain-core might be problematic. Click here for more details.

@@ -111,8 +111,9 @@ def _generate_response_from_error(error: BaseException) -> list[ChatGeneration]:
111
111
  def _format_for_tracing(messages: list[BaseMessage]) -> list[BaseMessage]:
112
112
  """Format messages for tracing in on_chat_model_start.
113
113
 
114
- For backward compatibility, we update image content blocks to OpenAI Chat
115
- Completions format.
114
+ - Update image content blocks to OpenAI Chat Completions format (backward
115
+ compatibility).
116
+ - Add "type" key to content blocks that have a single key.
116
117
 
117
118
  Args:
118
119
  messages: List of messages to format.
@@ -125,20 +126,36 @@ def _format_for_tracing(messages: list[BaseMessage]) -> list[BaseMessage]:
125
126
  message_to_trace = message
126
127
  if isinstance(message.content, list):
127
128
  for idx, block in enumerate(message.content):
128
- if (
129
- isinstance(block, dict)
130
- and block.get("type") == "image"
131
- and is_data_content_block(block)
132
- and block.get("source_type") != "id"
133
- ):
134
- if message_to_trace is message:
135
- message_to_trace = message.model_copy()
136
- # Also shallow-copy content
137
- message_to_trace.content = list(message_to_trace.content)
138
-
139
- message_to_trace.content[idx] = ( # type: ignore[index] # mypy confused by .model_copy
140
- convert_to_openai_image_block(block)
141
- )
129
+ if isinstance(block, dict):
130
+ # Update image content blocks to OpenAI # Chat Completions format.
131
+ if (
132
+ block.get("type") == "image"
133
+ and is_data_content_block(block)
134
+ and block.get("source_type") != "id"
135
+ ):
136
+ if message_to_trace is message:
137
+ # Shallow copy
138
+ message_to_trace = message.model_copy()
139
+ message_to_trace.content = list(message_to_trace.content)
140
+
141
+ message_to_trace.content[idx] = ( # type: ignore[index] # mypy confused by .model_copy
142
+ convert_to_openai_image_block(block)
143
+ )
144
+ elif len(block) == 1 and "type" not in block:
145
+ # Tracing assumes all content blocks have a "type" key. Here
146
+ # we add this key if it is missing, and there's an obvious
147
+ # choice for the type (e.g., a single key in the block).
148
+ if message_to_trace is message:
149
+ # Shallow copy
150
+ message_to_trace = message.model_copy()
151
+ message_to_trace.content = list(message_to_trace.content)
152
+ key = next(iter(block))
153
+ message_to_trace.content[idx] = { # type: ignore[index]
154
+ "type": key,
155
+ key: block[key],
156
+ }
157
+ else:
158
+ pass
142
159
  messages_to_trace.append(message_to_trace)
143
160
 
144
161
  return messages_to_trace
@@ -230,6 +230,7 @@ def ensure_config(config: Optional[RunnableConfig] = None) -> RunnableConfig:
230
230
  not key.startswith("__")
231
231
  and isinstance(value, (str, int, float, bool))
232
232
  and key not in empty["metadata"]
233
+ and key != "api_key"
233
234
  ):
234
235
  empty["metadata"][key] = value
235
236
  return empty
@@ -23,7 +23,12 @@ if TYPE_CHECKING:
23
23
  from langchain_core.utils.iter import batch_iterate
24
24
  from langchain_core.utils.loading import try_load_from_hub
25
25
  from langchain_core.utils.pydantic import pre_init
26
- from langchain_core.utils.strings import comma_list, stringify_dict, stringify_value
26
+ from langchain_core.utils.strings import (
27
+ comma_list,
28
+ sanitize_for_postgres,
29
+ stringify_dict,
30
+ stringify_value,
31
+ )
27
32
  from langchain_core.utils.utils import (
28
33
  build_extra_kwargs,
29
34
  check_package_version,
@@ -59,6 +64,7 @@ __all__ = (
59
64
  "pre_init",
60
65
  "print_text",
61
66
  "raise_for_status_with_text",
67
+ "sanitize_for_postgres",
62
68
  "secret_from_env",
63
69
  "stringify_dict",
64
70
  "stringify_value",
@@ -81,6 +87,7 @@ _dynamic_imports = {
81
87
  "try_load_from_hub": "loading",
82
88
  "pre_init": "pydantic",
83
89
  "comma_list": "strings",
90
+ "sanitize_for_postgres": "strings",
84
91
  "stringify_dict": "strings",
85
92
  "stringify_value": "strings",
86
93
  "build_extra_kwargs": "utils",
@@ -46,3 +46,26 @@ def comma_list(items: list[Any]) -> str:
46
46
  str: The comma-separated string.
47
47
  """
48
48
  return ", ".join(str(item) for item in items)
49
+
50
+
51
+ def sanitize_for_postgres(text: str, replacement: str = "") -> str:
52
+ r"""Sanitize text by removing NUL bytes that are incompatible with PostgreSQL.
53
+
54
+ PostgreSQL text fields cannot contain NUL (0x00) bytes, which can cause
55
+ psycopg.DataError when inserting documents. This function removes or replaces
56
+ such characters to ensure compatibility.
57
+
58
+ Args:
59
+ text: The text to sanitize.
60
+ replacement: String to replace NUL bytes with. Defaults to empty string.
61
+
62
+ Returns:
63
+ str: The sanitized text with NUL bytes removed or replaced.
64
+
65
+ Example:
66
+ >>> sanitize_for_postgres("Hello\\x00world")
67
+ 'Helloworld'
68
+ >>> sanitize_for_postgres("Hello\\x00world", " ")
69
+ 'Hello world'
70
+ """
71
+ return text.replace("\x00", replacement)
langchain_core/version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """langchain-core version information and utilities."""
2
2
 
3
- VERSION = "0.3.70"
3
+ VERSION = "0.3.71"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langchain-core
3
- Version: 0.3.70
3
+ Version: 0.3.71
4
4
  Summary: Building applications with LLMs through composability
5
5
  License: MIT
6
6
  Project-URL: Source Code, https://github.com/langchain-ai/langchain/tree/master/libs/core
@@ -1,6 +1,6 @@
1
- langchain_core-0.3.70.dist-info/METADATA,sha256=KfwpqFj2ZUyvXfoSsZ-ruTpsqLtCEdopcQq9CTeu_SE,5767
2
- langchain_core-0.3.70.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
- langchain_core-0.3.70.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
1
+ langchain_core-0.3.71.dist-info/METADATA,sha256=2IN2ux1bgW9OCsht-69QXdQsj95meY2WY1vmLgW19xY,5767
2
+ langchain_core-0.3.71.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
+ langchain_core-0.3.71.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
4
  langchain_core/__init__.py,sha256=AN-KPu2IuqeQGc-m9dcDfoTIvBno5-ZdUNEVwIIoZM0,709
5
5
  langchain_core/_api/__init__.py,sha256=WDOMw4faVuscjDCL5ttnRQNienJP_M9vGMmJUXS6L5w,1976
6
6
  langchain_core/_api/beta_decorator.py,sha256=osyHHMFFC4jT59CSlauU8HnVxReBfEaA-USTkvh7yAI,9942
@@ -48,7 +48,7 @@ langchain_core/indexing/in_memory.py,sha256=-qyKjAWJFWxtH_MbUu3JJct0x3R_pbHyHuxA
48
48
  langchain_core/language_models/__init__.py,sha256=j6OXr7CriShFr7BYfCWZ2kOTEZpzvlE7dNDTab75prg,3778
49
49
  langchain_core/language_models/_utils.py,sha256=uy-rdJB51K0O4txjxYe-tLGG8ZAwe3yezIiKvuDXDUU,4785
50
50
  langchain_core/language_models/base.py,sha256=hURYXnzIRP_Ib7vL5hPlWyTPbSEhwWIRGoxp7VQPSHQ,14448
51
- langchain_core/language_models/chat_models.py,sha256=EVD9F0EZ5xK7vLJ9HpqD0JBZ0GdRlPjYRbz2NmopsdA,67895
51
+ langchain_core/language_models/chat_models.py,sha256=ztNksJff6KIH8aC-lFy93tFf2mug4DarBQUU0oZv7xs,68936
52
52
  langchain_core/language_models/fake.py,sha256=h9LhVTkmYLXkJ1_VvsKhqYVpkQsM7eAr9geXF_IVkPs,3772
53
53
  langchain_core/language_models/fake_chat_models.py,sha256=QLz4VXMdIn6U5sBdZn_Lzfe1-rbebhNemQVGHnB3aBM,12994
54
54
  langchain_core/language_models/llms.py,sha256=87JTPgaRlMFhWR6sAc0N0aBMJxzV2sO3DtQz7dO0cWI,56802
@@ -109,7 +109,7 @@ langchain_core/retrievers.py,sha256=jkNUYO-_19hjKVBUYHD9pwQVjukYEE21fbHf-vtIdng,
109
109
  langchain_core/runnables/__init__.py,sha256=efTnFjwN_QSAv5ThLmKuWeu8P1BLARH-cWKZBuimfDM,3858
110
110
  langchain_core/runnables/base.py,sha256=cT1eB-s0waT4q4JFculG4AdmqYetBKB2e6DIrwCB8Nk,221543
111
111
  langchain_core/runnables/branch.py,sha256=Z0wESU2RmTFjMWam7d5CbijJ9p6ar7EJSQPh7HUHF0Q,16557
112
- langchain_core/runnables/config.py,sha256=b86vkkiJoYj-qanPRW-vXweEvAzaJKz6iLWNhyizHuk,20423
112
+ langchain_core/runnables/config.py,sha256=MSbZg8d4aGyEqNOfsJHkgN7RvgAN1fc-wgFZcd8LO8w,20456
113
113
  langchain_core/runnables/configurable.py,sha256=ReD0jHC8LYeD0Awv-s5x9in1xk8hCATYUeDCcEs0Ttk,24366
114
114
  langchain_core/runnables/fallbacks.py,sha256=nc_dq-UlmIX7LRLv8EOWPW5XX6o1ndfwG19q3SP-VGQ,24334
115
115
  langchain_core/runnables/graph.py,sha256=BzUDXoczHC21kFyD0-Gp2kndDVQbP0j1Bx-fAYTjAY0,23386
@@ -147,7 +147,7 @@ langchain_core/tracers/root_listeners.py,sha256=VRr3jnSSLYsIqYEmw9OjbjGgj4897c4f
147
147
  langchain_core/tracers/run_collector.py,sha256=Tnnz5sfKkUI6Rapj8mGjScYGkyEKRyicWOhvEXHV3qE,1622
148
148
  langchain_core/tracers/schemas.py,sha256=2gDs-9zloHTjIrMfuWsr9w9cRdZ6ZMMD_h5hCRH6xHw,3768
149
149
  langchain_core/tracers/stdout.py,sha256=aZN-yz545zj34kYfrEmYzWeSz83pbqN8wNqi-ZvS1Iw,6732
150
- langchain_core/utils/__init__.py,sha256=SXdUKDhlsZB5cusipvcPOVJU5UzccL_Zi_7TIwuD_SA,3036
150
+ langchain_core/utils/__init__.py,sha256=N0ZeV09FHvZIVITLJlqGibb0JNtmmLvvoareFtG0DuI,3169
151
151
  langchain_core/utils/_merge.py,sha256=sCYw0irypropb5Y6ZpIGxZhAmaKpsb7519Hc3pXLGWM,5763
152
152
  langchain_core/utils/aiter.py,sha256=Uz2EB-v7TAK6HVapkEgaKUmzxb8p2Az1cCUtEAa-bTM,10710
153
153
  langchain_core/utils/env.py,sha256=swKMUVFS-Jr_9KK2ToWam6qd9lt73Pz4RtRqwcaiFQw,2464
@@ -163,12 +163,12 @@ langchain_core/utils/json_schema.py,sha256=RuJUipbkwljzdjFZ4E6blJuHJObO9k2pXcxvJ
163
163
  langchain_core/utils/loading.py,sha256=7B9nuzOutgknzj5-8W6eorC9EUsNuO-1w4jh-aVf8ms,931
164
164
  langchain_core/utils/mustache.py,sha256=K_EnRcbYQMjQ-95-fP5G9rB2rCbpgcr1yn5QF6-Tr70,21253
165
165
  langchain_core/utils/pydantic.py,sha256=UFuDwQpGMZ95YFfb2coPMXva48sWn-ytQQhnqdy1ExM,17987
166
- langchain_core/utils/strings.py,sha256=LIh8uZcGlEKI_SnbOA_PsZxcU6QI5GQKTj0hxOraIv0,1016
166
+ langchain_core/utils/strings.py,sha256=0LaQiqpshHwMrWBGvNfFPc-AxihLGMM9vsQcSx3uAkI,1804
167
167
  langchain_core/utils/usage.py,sha256=EYv0poDqA7VejEsPyoA19lEt9M4L24Tppf4OPtOjGwI,1202
168
168
  langchain_core/utils/utils.py,sha256=RK9JRNsdb4mXu1XYuJFuvDqyglSpnr6ak0vb0ELc7Eo,15043
169
169
  langchain_core/vectorstores/__init__.py,sha256=5P0eoeoH5LHab64JjmEeWa6SxX4eMy-etAP1MEHsETY,804
170
170
  langchain_core/vectorstores/base.py,sha256=tClkcmbKtYw5CkwF1AEOPa304rHkYqDJ0jRlXXPPo8c,42025
171
171
  langchain_core/vectorstores/in_memory.py,sha256=lxe2bR-wFtvNN2Ii7EGOh3ON3MwqNRP996eUEek55fA,18076
172
172
  langchain_core/vectorstores/utils.py,sha256=DZUUR1xDybHDhmZJsd1V2OEPsYiFVc2nhtD4w8hw9ns,4934
173
- langchain_core/version.py,sha256=7TDx1kbBpIn7ErsHWCHivHJEbNuQaS1Q-BShaJiN5Nk,76
174
- langchain_core-0.3.70.dist-info/RECORD,,
173
+ langchain_core/version.py,sha256=CIjYNEnE7dA85UdGJA6hnOak7gPlUoYQi1qU56mcLkQ,76
174
+ langchain_core-0.3.71.dist-info/RECORD,,