langchain-core 0.3.72__py3-none-any.whl → 0.4.0.dev0__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.
Files changed (82) hide show
  1. langchain_core/_api/beta_decorator.py +1 -0
  2. langchain_core/_api/deprecation.py +2 -0
  3. langchain_core/beta/runnables/context.py +1 -0
  4. langchain_core/callbacks/base.py +23 -14
  5. langchain_core/callbacks/file.py +1 -0
  6. langchain_core/callbacks/manager.py +145 -19
  7. langchain_core/callbacks/streaming_stdout.py +4 -3
  8. langchain_core/callbacks/usage.py +15 -3
  9. langchain_core/chat_history.py +1 -0
  10. langchain_core/document_loaders/langsmith.py +2 -1
  11. langchain_core/documents/base.py +2 -0
  12. langchain_core/embeddings/fake.py +2 -0
  13. langchain_core/indexing/api.py +10 -0
  14. langchain_core/language_models/_utils.py +37 -0
  15. langchain_core/language_models/base.py +4 -1
  16. langchain_core/language_models/chat_models.py +48 -27
  17. langchain_core/language_models/fake_chat_models.py +71 -1
  18. langchain_core/language_models/llms.py +1 -0
  19. langchain_core/memory.py +1 -0
  20. langchain_core/messages/__init__.py +54 -0
  21. langchain_core/messages/ai.py +31 -18
  22. langchain_core/messages/content_blocks.py +1349 -69
  23. langchain_core/messages/human.py +1 -0
  24. langchain_core/messages/modifier.py +1 -1
  25. langchain_core/messages/tool.py +8 -83
  26. langchain_core/messages/utils.py +221 -6
  27. langchain_core/output_parsers/base.py +51 -14
  28. langchain_core/output_parsers/json.py +5 -2
  29. langchain_core/output_parsers/list.py +7 -2
  30. langchain_core/output_parsers/openai_functions.py +29 -5
  31. langchain_core/output_parsers/openai_tools.py +90 -47
  32. langchain_core/output_parsers/pydantic.py +3 -2
  33. langchain_core/output_parsers/transform.py +53 -12
  34. langchain_core/output_parsers/xml.py +14 -5
  35. langchain_core/outputs/llm_result.py +4 -1
  36. langchain_core/prompt_values.py +111 -7
  37. langchain_core/prompts/base.py +4 -0
  38. langchain_core/prompts/chat.py +3 -0
  39. langchain_core/prompts/few_shot.py +1 -0
  40. langchain_core/prompts/few_shot_with_templates.py +1 -0
  41. langchain_core/prompts/image.py +1 -0
  42. langchain_core/prompts/pipeline.py +1 -0
  43. langchain_core/prompts/prompt.py +1 -0
  44. langchain_core/prompts/structured.py +1 -0
  45. langchain_core/rate_limiters.py +1 -0
  46. langchain_core/retrievers.py +3 -0
  47. langchain_core/runnables/base.py +75 -57
  48. langchain_core/runnables/branch.py +1 -0
  49. langchain_core/runnables/config.py +2 -2
  50. langchain_core/runnables/configurable.py +2 -1
  51. langchain_core/runnables/fallbacks.py +3 -7
  52. langchain_core/runnables/graph.py +5 -3
  53. langchain_core/runnables/graph_ascii.py +1 -0
  54. langchain_core/runnables/graph_mermaid.py +1 -0
  55. langchain_core/runnables/history.py +1 -0
  56. langchain_core/runnables/passthrough.py +3 -0
  57. langchain_core/runnables/retry.py +1 -0
  58. langchain_core/runnables/router.py +1 -0
  59. langchain_core/runnables/schema.py +1 -0
  60. langchain_core/stores.py +3 -0
  61. langchain_core/tools/base.py +43 -11
  62. langchain_core/tools/convert.py +25 -3
  63. langchain_core/tools/retriever.py +8 -1
  64. langchain_core/tools/structured.py +10 -1
  65. langchain_core/tracers/base.py +14 -7
  66. langchain_core/tracers/context.py +1 -1
  67. langchain_core/tracers/core.py +27 -4
  68. langchain_core/tracers/event_stream.py +14 -3
  69. langchain_core/tracers/langchain.py +14 -3
  70. langchain_core/tracers/log_stream.py +4 -1
  71. langchain_core/utils/aiter.py +5 -0
  72. langchain_core/utils/function_calling.py +2 -1
  73. langchain_core/utils/iter.py +1 -0
  74. langchain_core/v1/__init__.py +1 -0
  75. langchain_core/v1/chat_models.py +1047 -0
  76. langchain_core/v1/messages.py +755 -0
  77. langchain_core/vectorstores/base.py +1 -0
  78. langchain_core/version.py +1 -1
  79. {langchain_core-0.3.72.dist-info → langchain_core-0.4.0.dev0.dist-info}/METADATA +1 -1
  80. {langchain_core-0.3.72.dist-info → langchain_core-0.4.0.dev0.dist-info}/RECORD +82 -79
  81. {langchain_core-0.3.72.dist-info → langchain_core-0.4.0.dev0.dist-info}/WHEEL +0 -0
  82. {langchain_core-0.3.72.dist-info → langchain_core-0.4.0.dev0.dist-info}/entry_points.txt +0 -0
@@ -8,17 +8,65 @@ from __future__ import annotations
8
8
 
9
9
  from abc import ABC, abstractmethod
10
10
  from collections.abc import Sequence
11
- from typing import Literal, cast
11
+ from typing import Literal, Union, cast
12
12
 
13
- from typing_extensions import TypedDict
13
+ from typing_extensions import TypedDict, overload
14
14
 
15
15
  from langchain_core.load.serializable import Serializable
16
16
  from langchain_core.messages import (
17
+ AIMessage,
17
18
  AnyMessage,
18
19
  BaseMessage,
19
20
  HumanMessage,
21
+ SystemMessage,
22
+ ToolMessage,
20
23
  get_buffer_string,
21
24
  )
25
+ from langchain_core.messages import content_blocks as types
26
+ from langchain_core.v1.messages import AIMessage as AIMessageV1
27
+ from langchain_core.v1.messages import HumanMessage as HumanMessageV1
28
+ from langchain_core.v1.messages import MessageV1, ResponseMetadata
29
+ from langchain_core.v1.messages import SystemMessage as SystemMessageV1
30
+ from langchain_core.v1.messages import ToolMessage as ToolMessageV1
31
+
32
+
33
+ def _convert_to_v1(message: BaseMessage) -> MessageV1:
34
+ """Best-effort conversion of a V0 AIMessage to V1."""
35
+ if isinstance(message.content, str):
36
+ content: list[types.ContentBlock] = []
37
+ if message.content:
38
+ content = [{"type": "text", "text": message.content}]
39
+ else:
40
+ content = []
41
+ for block in message.content:
42
+ if isinstance(block, str):
43
+ content.append({"type": "text", "text": block})
44
+ elif isinstance(block, dict):
45
+ content.append(cast("types.ContentBlock", block))
46
+ else:
47
+ pass
48
+
49
+ if isinstance(message, HumanMessage):
50
+ return HumanMessageV1(content=content)
51
+ if isinstance(message, AIMessage):
52
+ for tool_call in message.tool_calls:
53
+ content.append(tool_call)
54
+ return AIMessageV1(
55
+ content=content,
56
+ usage_metadata=message.usage_metadata,
57
+ response_metadata=cast("ResponseMetadata", message.response_metadata),
58
+ tool_calls=message.tool_calls,
59
+ )
60
+ if isinstance(message, SystemMessage):
61
+ return SystemMessageV1(content=content)
62
+ if isinstance(message, ToolMessage):
63
+ return ToolMessageV1(
64
+ tool_call_id=message.tool_call_id,
65
+ content=content,
66
+ artifact=message.artifact,
67
+ )
68
+ error_message = f"Unsupported message type: {type(message)}"
69
+ raise TypeError(error_message)
22
70
 
23
71
 
24
72
  class PromptValue(Serializable, ABC):
@@ -46,8 +94,18 @@ class PromptValue(Serializable, ABC):
46
94
  def to_string(self) -> str:
47
95
  """Return prompt value as string."""
48
96
 
97
+ @overload
98
+ def to_messages(
99
+ self, message_version: Literal["v0"] = "v0"
100
+ ) -> list[BaseMessage]: ...
101
+
102
+ @overload
103
+ def to_messages(self, message_version: Literal["v1"]) -> list[MessageV1]: ...
104
+
49
105
  @abstractmethod
50
- def to_messages(self) -> list[BaseMessage]:
106
+ def to_messages(
107
+ self, message_version: Literal["v0", "v1"] = "v0"
108
+ ) -> Union[Sequence[BaseMessage], Sequence[MessageV1]]:
51
109
  """Return prompt as a list of Messages."""
52
110
 
53
111
 
@@ -71,8 +129,20 @@ class StringPromptValue(PromptValue):
71
129
  """Return prompt as string."""
72
130
  return self.text
73
131
 
74
- def to_messages(self) -> list[BaseMessage]:
132
+ @overload
133
+ def to_messages(
134
+ self, message_version: Literal["v0"] = "v0"
135
+ ) -> list[BaseMessage]: ...
136
+
137
+ @overload
138
+ def to_messages(self, message_version: Literal["v1"]) -> list[MessageV1]: ...
139
+
140
+ def to_messages(
141
+ self, message_version: Literal["v0", "v1"] = "v0"
142
+ ) -> Union[Sequence[BaseMessage], Sequence[MessageV1]]:
75
143
  """Return prompt as messages."""
144
+ if message_version == "v1":
145
+ return [HumanMessageV1(content=self.text)]
76
146
  return [HumanMessage(content=self.text)]
77
147
 
78
148
 
@@ -89,8 +159,24 @@ class ChatPromptValue(PromptValue):
89
159
  """Return prompt as string."""
90
160
  return get_buffer_string(self.messages)
91
161
 
92
- def to_messages(self) -> list[BaseMessage]:
93
- """Return prompt as a list of messages."""
162
+ @overload
163
+ def to_messages(
164
+ self, message_version: Literal["v0"] = "v0"
165
+ ) -> list[BaseMessage]: ...
166
+
167
+ @overload
168
+ def to_messages(self, message_version: Literal["v1"]) -> list[MessageV1]: ...
169
+
170
+ def to_messages(
171
+ self, message_version: Literal["v0", "v1"] = "v0"
172
+ ) -> Union[Sequence[BaseMessage], Sequence[MessageV1]]:
173
+ """Return prompt as a list of messages.
174
+
175
+ Args:
176
+ message_version: The output version, either "v0" (default) or "v1".
177
+ """
178
+ if message_version == "v1":
179
+ return [_convert_to_v1(m) for m in self.messages]
94
180
  return list(self.messages)
95
181
 
96
182
  @classmethod
@@ -125,8 +211,26 @@ class ImagePromptValue(PromptValue):
125
211
  """Return prompt (image URL) as string."""
126
212
  return self.image_url["url"]
127
213
 
128
- def to_messages(self) -> list[BaseMessage]:
214
+ @overload
215
+ def to_messages(
216
+ self, message_version: Literal["v0"] = "v0"
217
+ ) -> list[BaseMessage]: ...
218
+
219
+ @overload
220
+ def to_messages(self, message_version: Literal["v1"]) -> list[MessageV1]: ...
221
+
222
+ def to_messages(
223
+ self, message_version: Literal["v0", "v1"] = "v0"
224
+ ) -> Union[Sequence[BaseMessage], Sequence[MessageV1]]:
129
225
  """Return prompt (image URL) as messages."""
226
+ if message_version == "v1":
227
+ block: types.ImageContentBlock = {
228
+ "type": "image",
229
+ "url": self.image_url["url"],
230
+ }
231
+ if "detail" in self.image_url:
232
+ block["detail"] = self.image_url["detail"]
233
+ return [HumanMessageV1(content=[block])]
130
234
  return [HumanMessage(content=[cast("dict", self.image_url)])]
131
235
 
132
236
 
@@ -307,6 +307,7 @@ class BasePromptTemplate(
307
307
  .. code-block:: python
308
308
 
309
309
  prompt.format(variable1="foo")
310
+
310
311
  """
311
312
 
312
313
  async def aformat(self, **kwargs: Any) -> FormatOutputType:
@@ -323,6 +324,7 @@ class BasePromptTemplate(
323
324
  .. code-block:: python
324
325
 
325
326
  await prompt.aformat(variable1="foo")
327
+
326
328
  """
327
329
  return self.format(**kwargs)
328
330
 
@@ -363,6 +365,7 @@ class BasePromptTemplate(
363
365
  .. code-block:: python
364
366
 
365
367
  prompt.save(file_path="path/prompt.yaml")
368
+
366
369
  """
367
370
  if self.partial_variables:
368
371
  msg = "Cannot save prompt with partial variables."
@@ -442,6 +445,7 @@ def format_document(doc: Document, prompt: BasePromptTemplate[str]) -> str:
442
445
  prompt = PromptTemplate.from_template("Page {page}: {page_content}")
443
446
  format_document(doc, prompt)
444
447
  >>> "Page 1: This is a joke"
448
+
445
449
  """
446
450
  return prompt.format(**_get_document_info(doc, prompt))
447
451
 
@@ -126,6 +126,7 @@ class MessagesPlaceholder(BaseMessagePromptTemplate):
126
126
  # -> [
127
127
  # HumanMessage(content="Hello!"),
128
128
  # ]
129
+
129
130
  """
130
131
 
131
132
  variable_name: str
@@ -1164,6 +1165,7 @@ class ChatPromptTemplate(BaseChatPromptTemplate):
1164
1165
 
1165
1166
  Returns:
1166
1167
  a chat prompt template.
1168
+
1167
1169
  """
1168
1170
  return cls(messages, template_format=template_format)
1169
1171
 
@@ -1248,6 +1250,7 @@ class ChatPromptTemplate(BaseChatPromptTemplate):
1248
1250
  template2 = template.partial(user="Lucy", name="R2D2")
1249
1251
 
1250
1252
  template2.format_messages(input="hello")
1253
+
1251
1254
  """
1252
1255
  prompt_dict = self.__dict__.copy()
1253
1256
  prompt_dict["input_variables"] = list(
@@ -357,6 +357,7 @@ class FewShotChatMessagePromptTemplate(
357
357
  from langchain_core.chat_models import ChatAnthropic
358
358
  chain = final_prompt | ChatAnthropic(model="claude-3-haiku-20240307")
359
359
  chain.invoke({"input": "What's 3+3?"})
360
+
360
361
  """
361
362
 
362
363
  input_variables: list[str] = Field(default_factory=list)
@@ -122,6 +122,7 @@ class FewShotPromptWithTemplates(StringPromptTemplate):
122
122
  .. code-block:: python
123
123
 
124
124
  prompt.format(variable1="foo")
125
+
125
126
  """
126
127
  kwargs = self._merge_partial_and_user_variables(**kwargs)
127
128
  # Get the examples to use.
@@ -90,6 +90,7 @@ class ImagePromptTemplate(BasePromptTemplate[ImageURL]):
90
90
  .. code-block:: python
91
91
 
92
92
  prompt.format(variable1="foo")
93
+
93
94
  """
94
95
  formatted = {}
95
96
  for k, v in self.template.items():
@@ -45,6 +45,7 @@ class PipelinePromptTemplate(BasePromptTemplate):
45
45
  Each PromptTemplate will be formatted and then passed
46
46
  to future prompt templates as a variable with
47
47
  the same name as `name`
48
+
48
49
  """
49
50
 
50
51
  final_prompt: BasePromptTemplate
@@ -56,6 +56,7 @@ class PromptTemplate(StringPromptTemplate):
56
56
 
57
57
  # Instantiation using initializer
58
58
  prompt = PromptTemplate(template="Say {foo}")
59
+
59
60
  """
60
61
 
61
62
  @property
@@ -115,6 +115,7 @@ class StructuredPrompt(ChatPromptTemplate):
115
115
 
116
116
  Returns:
117
117
  a structured prompt template
118
+
118
119
  """
119
120
  return cls(messages, schema, **kwargs)
120
121
 
@@ -123,6 +123,7 @@ class InMemoryRateLimiter(BaseRateLimiter):
123
123
 
124
124
 
125
125
  .. versionadded:: 0.2.24
126
+
126
127
  """ # noqa: E501
127
128
 
128
129
  def __init__(
@@ -124,6 +124,7 @@ class BaseRetriever(RunnableSerializable[RetrieverInput, RetrieverOutput], ABC):
124
124
  # Op -- (n_docs,1) -- Cosine Sim with each doc
125
125
  results = cosine_similarity(self.tfidf_array, query_vec).reshape((-1,))
126
126
  return [self.docs[i] for i in results.argsort()[-self.k :][::-1]]
127
+
127
128
  """ # noqa: E501
128
129
 
129
130
  model_config = ConfigDict(
@@ -230,6 +231,7 @@ class BaseRetriever(RunnableSerializable[RetrieverInput, RetrieverOutput], ABC):
230
231
  .. code-block:: python
231
232
 
232
233
  retriever.invoke("query")
234
+
233
235
  """
234
236
  from langchain_core.callbacks.manager import CallbackManager
235
237
 
@@ -294,6 +296,7 @@ class BaseRetriever(RunnableSerializable[RetrieverInput, RetrieverOutput], ABC):
294
296
  .. code-block:: python
295
297
 
296
298
  await retriever.ainvoke("query")
299
+
297
300
  """
298
301
  from langchain_core.callbacks.manager import AsyncCallbackManager
299
302