langchain-core 1.0.0rc3__py3-none-any.whl → 1.0.2__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.
- langchain_core/agents.py +2 -4
- langchain_core/caches.py +16 -7
- langchain_core/callbacks/base.py +0 -4
- langchain_core/callbacks/manager.py +0 -11
- langchain_core/chat_history.py +5 -5
- langchain_core/document_loaders/base.py +6 -4
- langchain_core/document_loaders/blob_loaders.py +1 -1
- langchain_core/document_loaders/langsmith.py +9 -13
- langchain_core/documents/__init__.py +24 -3
- langchain_core/documents/base.py +72 -61
- langchain_core/documents/compressor.py +6 -6
- langchain_core/documents/transformers.py +6 -6
- langchain_core/embeddings/fake.py +2 -2
- langchain_core/example_selectors/semantic_similarity.py +7 -7
- langchain_core/exceptions.py +2 -2
- langchain_core/indexing/__init__.py +1 -1
- langchain_core/indexing/api.py +62 -62
- langchain_core/indexing/base.py +20 -22
- langchain_core/indexing/in_memory.py +2 -4
- langchain_core/language_models/__init__.py +6 -5
- langchain_core/language_models/base.py +7 -8
- langchain_core/language_models/chat_models.py +84 -78
- langchain_core/language_models/fake_chat_models.py +1 -1
- langchain_core/language_models/llms.py +20 -18
- langchain_core/load/dump.py +6 -8
- langchain_core/load/serializable.py +4 -1
- langchain_core/messages/__init__.py +9 -0
- langchain_core/messages/ai.py +11 -7
- langchain_core/messages/base.py +4 -0
- langchain_core/messages/block_translators/google_genai.py +5 -3
- langchain_core/messages/content.py +4 -4
- langchain_core/messages/utils.py +17 -17
- langchain_core/output_parsers/__init__.py +17 -1
- langchain_core/output_parsers/base.py +3 -0
- langchain_core/output_parsers/format_instructions.py +9 -4
- langchain_core/output_parsers/json.py +5 -2
- langchain_core/output_parsers/list.py +16 -16
- langchain_core/output_parsers/openai_tools.py +2 -2
- langchain_core/output_parsers/pydantic.py +1 -1
- langchain_core/output_parsers/string.py +3 -3
- langchain_core/output_parsers/xml.py +28 -25
- langchain_core/outputs/generation.py +2 -3
- langchain_core/prompt_values.py +0 -6
- langchain_core/prompts/base.py +5 -3
- langchain_core/prompts/chat.py +60 -52
- langchain_core/prompts/string.py +5 -2
- langchain_core/prompts/structured.py +12 -8
- langchain_core/rate_limiters.py +1 -3
- langchain_core/retrievers.py +41 -37
- langchain_core/runnables/base.py +25 -29
- langchain_core/runnables/branch.py +9 -9
- langchain_core/runnables/config.py +2 -4
- langchain_core/runnables/configurable.py +3 -3
- langchain_core/runnables/fallbacks.py +1 -1
- langchain_core/runnables/graph.py +7 -3
- langchain_core/runnables/retry.py +1 -1
- langchain_core/runnables/schema.py +2 -5
- langchain_core/runnables/utils.py +3 -3
- langchain_core/stores.py +4 -6
- langchain_core/tools/base.py +68 -14
- langchain_core/tools/convert.py +8 -7
- langchain_core/tools/retriever.py +6 -5
- langchain_core/tools/structured.py +7 -5
- langchain_core/tracers/event_stream.py +4 -1
- langchain_core/tracers/log_stream.py +6 -3
- langchain_core/utils/function_calling.py +8 -0
- langchain_core/utils/json_schema.py +1 -1
- langchain_core/utils/strings.py +1 -4
- langchain_core/utils/utils.py +12 -5
- langchain_core/vectorstores/base.py +130 -130
- langchain_core/vectorstores/in_memory.py +4 -4
- langchain_core/vectorstores/utils.py +1 -1
- langchain_core/version.py +1 -1
- {langchain_core-1.0.0rc3.dist-info → langchain_core-1.0.2.dist-info}/METADATA +8 -7
- {langchain_core-1.0.0rc3.dist-info → langchain_core-1.0.2.dist-info}/RECORD +76 -76
- {langchain_core-1.0.0rc3.dist-info → langchain_core-1.0.2.dist-info}/WHEEL +0 -0
|
@@ -838,13 +838,13 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
|
|
|
838
838
|
1. Take advantage of batched calls,
|
|
839
839
|
2. Need more output from the model than just the top generated value,
|
|
840
840
|
3. Are building chains that are agnostic to the underlying language model
|
|
841
|
-
|
|
841
|
+
type (e.g., pure text completion models vs chat models).
|
|
842
842
|
|
|
843
843
|
Args:
|
|
844
844
|
messages: List of list of messages.
|
|
845
845
|
stop: Stop words to use when generating. Model output is cut off at the
|
|
846
846
|
first occurrence of any of these substrings.
|
|
847
|
-
callbacks: Callbacks to pass through. Used for executing additional
|
|
847
|
+
callbacks: `Callbacks` to pass through. Used for executing additional
|
|
848
848
|
functionality, such as logging or streaming, throughout generation.
|
|
849
849
|
tags: The tags to apply.
|
|
850
850
|
metadata: The metadata to apply.
|
|
@@ -854,8 +854,8 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
|
|
|
854
854
|
to the model provider API call.
|
|
855
855
|
|
|
856
856
|
Returns:
|
|
857
|
-
An LLMResult
|
|
858
|
-
|
|
857
|
+
An `LLMResult`, which contains a list of candidate `Generations` for each
|
|
858
|
+
input prompt and additional model provider-specific output.
|
|
859
859
|
|
|
860
860
|
"""
|
|
861
861
|
ls_structured_output_format = kwargs.pop(
|
|
@@ -956,13 +956,13 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
|
|
|
956
956
|
1. Take advantage of batched calls,
|
|
957
957
|
2. Need more output from the model than just the top generated value,
|
|
958
958
|
3. Are building chains that are agnostic to the underlying language model
|
|
959
|
-
|
|
959
|
+
type (e.g., pure text completion models vs chat models).
|
|
960
960
|
|
|
961
961
|
Args:
|
|
962
962
|
messages: List of list of messages.
|
|
963
963
|
stop: Stop words to use when generating. Model output is cut off at the
|
|
964
964
|
first occurrence of any of these substrings.
|
|
965
|
-
callbacks: Callbacks to pass through. Used for executing additional
|
|
965
|
+
callbacks: `Callbacks` to pass through. Used for executing additional
|
|
966
966
|
functionality, such as logging or streaming, throughout generation.
|
|
967
967
|
tags: The tags to apply.
|
|
968
968
|
metadata: The metadata to apply.
|
|
@@ -972,8 +972,8 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
|
|
|
972
972
|
to the model provider API call.
|
|
973
973
|
|
|
974
974
|
Returns:
|
|
975
|
-
An LLMResult
|
|
976
|
-
|
|
975
|
+
An `LLMResult`, which contains a list of candidate `Generations` for each
|
|
976
|
+
input prompt and additional model provider-specific output.
|
|
977
977
|
|
|
978
978
|
"""
|
|
979
979
|
ls_structured_output_format = kwargs.pop(
|
|
@@ -1510,17 +1510,21 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
|
|
|
1510
1510
|
If `schema` is a Pydantic class then the model output will be a
|
|
1511
1511
|
Pydantic instance of that class, and the model-generated fields will be
|
|
1512
1512
|
validated by the Pydantic class. Otherwise the model output will be a
|
|
1513
|
-
dict and will not be validated.
|
|
1514
|
-
|
|
1515
|
-
|
|
1513
|
+
dict and will not be validated.
|
|
1514
|
+
|
|
1515
|
+
See `langchain_core.utils.function_calling.convert_to_openai_tool` for
|
|
1516
|
+
more on how to properly specify types and descriptions of schema fields
|
|
1517
|
+
when specifying a Pydantic or `TypedDict` class.
|
|
1516
1518
|
|
|
1517
1519
|
include_raw:
|
|
1518
1520
|
If `False` then only the parsed structured output is returned. If
|
|
1519
1521
|
an error occurs during model output parsing it will be raised. If `True`
|
|
1520
1522
|
then both the raw model response (a `BaseMessage`) and the parsed model
|
|
1521
1523
|
response will be returned. If an error occurs during output parsing it
|
|
1522
|
-
will be caught and returned as well.
|
|
1523
|
-
|
|
1524
|
+
will be caught and returned as well.
|
|
1525
|
+
|
|
1526
|
+
The final output is always a `dict` with keys `'raw'`, `'parsed'`, and
|
|
1527
|
+
`'parsing_error'`.
|
|
1524
1528
|
|
|
1525
1529
|
Raises:
|
|
1526
1530
|
ValueError: If there are any unsupported `kwargs`.
|
|
@@ -1528,97 +1532,99 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
|
|
|
1528
1532
|
`with_structured_output()`.
|
|
1529
1533
|
|
|
1530
1534
|
Returns:
|
|
1531
|
-
A Runnable that takes same inputs as a
|
|
1535
|
+
A `Runnable` that takes same inputs as a
|
|
1536
|
+
`langchain_core.language_models.chat.BaseChatModel`. If `include_raw` is
|
|
1537
|
+
`False` and `schema` is a Pydantic class, `Runnable` outputs an instance
|
|
1538
|
+
of `schema` (i.e., a Pydantic object). Otherwise, if `include_raw` is
|
|
1539
|
+
`False` then `Runnable` outputs a `dict`.
|
|
1532
1540
|
|
|
1533
|
-
If `include_raw` is
|
|
1534
|
-
an instance of `schema` (i.e., a Pydantic object).
|
|
1541
|
+
If `include_raw` is `True`, then `Runnable` outputs a `dict` with keys:
|
|
1535
1542
|
|
|
1536
|
-
|
|
1543
|
+
- `'raw'`: `BaseMessage`
|
|
1544
|
+
- `'parsed'`: `None` if there was a parsing error, otherwise the type
|
|
1545
|
+
depends on the `schema` as described above.
|
|
1546
|
+
- `'parsing_error'`: `BaseException | None`
|
|
1537
1547
|
|
|
1538
|
-
|
|
1548
|
+
Example: Pydantic schema (`include_raw=False`):
|
|
1539
1549
|
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
depends on the `schema` as described above.
|
|
1543
|
-
- `'parsing_error'`: BaseException | None
|
|
1550
|
+
```python
|
|
1551
|
+
from pydantic import BaseModel
|
|
1544
1552
|
|
|
1545
|
-
Example: Pydantic schema (include_raw=False):
|
|
1546
|
-
```python
|
|
1547
|
-
from pydantic import BaseModel
|
|
1548
1553
|
|
|
1554
|
+
class AnswerWithJustification(BaseModel):
|
|
1555
|
+
'''An answer to the user question along with justification for the answer.'''
|
|
1549
1556
|
|
|
1550
|
-
|
|
1551
|
-
|
|
1557
|
+
answer: str
|
|
1558
|
+
justification: str
|
|
1552
1559
|
|
|
1553
|
-
answer: str
|
|
1554
|
-
justification: str
|
|
1555
1560
|
|
|
1561
|
+
model = ChatModel(model="model-name", temperature=0)
|
|
1562
|
+
structured_model = model.with_structured_output(AnswerWithJustification)
|
|
1556
1563
|
|
|
1557
|
-
|
|
1558
|
-
|
|
1564
|
+
structured_model.invoke(
|
|
1565
|
+
"What weighs more a pound of bricks or a pound of feathers"
|
|
1566
|
+
)
|
|
1559
1567
|
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1568
|
+
# -> AnswerWithJustification(
|
|
1569
|
+
# answer='They weigh the same',
|
|
1570
|
+
# justification='Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ.'
|
|
1571
|
+
# )
|
|
1572
|
+
```
|
|
1563
1573
|
|
|
1564
|
-
|
|
1565
|
-
# answer='They weigh the same',
|
|
1566
|
-
# justification='Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ.'
|
|
1567
|
-
# )
|
|
1568
|
-
```
|
|
1574
|
+
Example: Pydantic schema (`include_raw=True`):
|
|
1569
1575
|
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
from pydantic import BaseModel
|
|
1576
|
+
```python
|
|
1577
|
+
from pydantic import BaseModel
|
|
1573
1578
|
|
|
1574
1579
|
|
|
1575
|
-
|
|
1576
|
-
|
|
1580
|
+
class AnswerWithJustification(BaseModel):
|
|
1581
|
+
'''An answer to the user question along with justification for the answer.'''
|
|
1577
1582
|
|
|
1578
|
-
|
|
1579
|
-
|
|
1583
|
+
answer: str
|
|
1584
|
+
justification: str
|
|
1580
1585
|
|
|
1581
1586
|
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1587
|
+
model = ChatModel(model="model-name", temperature=0)
|
|
1588
|
+
structured_model = model.with_structured_output(
|
|
1589
|
+
AnswerWithJustification, include_raw=True
|
|
1590
|
+
)
|
|
1586
1591
|
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1592
|
+
structured_model.invoke(
|
|
1593
|
+
"What weighs more a pound of bricks or a pound of feathers"
|
|
1594
|
+
)
|
|
1595
|
+
# -> {
|
|
1596
|
+
# 'raw': AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_Ao02pnFYXD6GN1yzc0uXPsvF', 'function': {'arguments': '{"answer":"They weigh the same.","justification":"Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ."}', 'name': 'AnswerWithJustification'}, 'type': 'function'}]}),
|
|
1597
|
+
# 'parsed': AnswerWithJustification(answer='They weigh the same.', justification='Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ.'),
|
|
1598
|
+
# 'parsing_error': None
|
|
1599
|
+
# }
|
|
1600
|
+
```
|
|
1596
1601
|
|
|
1597
|
-
Example:
|
|
1598
|
-
```python
|
|
1599
|
-
from pydantic import BaseModel
|
|
1600
|
-
from langchain_core.utils.function_calling import convert_to_openai_tool
|
|
1602
|
+
Example: `dict` schema (`include_raw=False`):
|
|
1601
1603
|
|
|
1604
|
+
```python
|
|
1605
|
+
from pydantic import BaseModel
|
|
1606
|
+
from langchain_core.utils.function_calling import convert_to_openai_tool
|
|
1602
1607
|
|
|
1603
|
-
class AnswerWithJustification(BaseModel):
|
|
1604
|
-
'''An answer to the user question along with justification for the answer.'''
|
|
1605
1608
|
|
|
1606
|
-
|
|
1607
|
-
|
|
1609
|
+
class AnswerWithJustification(BaseModel):
|
|
1610
|
+
'''An answer to the user question along with justification for the answer.'''
|
|
1608
1611
|
|
|
1612
|
+
answer: str
|
|
1613
|
+
justification: str
|
|
1609
1614
|
|
|
1610
|
-
dict_schema = convert_to_openai_tool(AnswerWithJustification)
|
|
1611
|
-
model = ChatModel(model="model-name", temperature=0)
|
|
1612
|
-
structured_model = model.with_structured_output(dict_schema)
|
|
1613
1615
|
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1616
|
+
dict_schema = convert_to_openai_tool(AnswerWithJustification)
|
|
1617
|
+
model = ChatModel(model="model-name", temperature=0)
|
|
1618
|
+
structured_model = model.with_structured_output(dict_schema)
|
|
1619
|
+
|
|
1620
|
+
structured_model.invoke(
|
|
1621
|
+
"What weighs more a pound of bricks or a pound of feathers"
|
|
1622
|
+
)
|
|
1623
|
+
# -> {
|
|
1624
|
+
# 'answer': 'They weigh the same',
|
|
1625
|
+
# 'justification': 'Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume and density of the two substances differ.'
|
|
1626
|
+
# }
|
|
1627
|
+
```
|
|
1622
1628
|
|
|
1623
1629
|
!!! warning "Behavior changed in 0.2.26"
|
|
1624
1630
|
Added support for TypedDict class.
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
"""Base interface for large language models to expose.
|
|
1
|
+
"""Base interface for traditional large language models (LLMs) to expose.
|
|
2
|
+
|
|
3
|
+
These are traditionally older models (newer models generally are chat models).
|
|
4
|
+
"""
|
|
2
5
|
|
|
3
6
|
from __future__ import annotations
|
|
4
7
|
|
|
@@ -91,13 +94,17 @@ def create_base_retry_decorator(
|
|
|
91
94
|
if isinstance(run_manager, AsyncCallbackManagerForLLMRun):
|
|
92
95
|
coro = run_manager.on_retry(retry_state)
|
|
93
96
|
try:
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
# and be awaited somewhere
|
|
98
|
-
loop.create_task(coro) # noqa: RUF006
|
|
99
|
-
else:
|
|
97
|
+
try:
|
|
98
|
+
loop = asyncio.get_event_loop()
|
|
99
|
+
except RuntimeError:
|
|
100
100
|
asyncio.run(coro)
|
|
101
|
+
else:
|
|
102
|
+
if loop.is_running():
|
|
103
|
+
# TODO: Fix RUF006 - this task should have a reference
|
|
104
|
+
# and be awaited somewhere
|
|
105
|
+
loop.create_task(coro) # noqa: RUF006
|
|
106
|
+
else:
|
|
107
|
+
asyncio.run(coro)
|
|
101
108
|
except Exception as e:
|
|
102
109
|
_log_error_once(f"Error in on_retry: {e}")
|
|
103
110
|
else:
|
|
@@ -841,7 +848,7 @@ class BaseLLM(BaseLanguageModel[str], ABC):
|
|
|
841
848
|
prompts: List of string prompts.
|
|
842
849
|
stop: Stop words to use when generating. Model output is cut off at the
|
|
843
850
|
first occurrence of any of these substrings.
|
|
844
|
-
callbacks: Callbacks to pass through. Used for executing additional
|
|
851
|
+
callbacks: `Callbacks` to pass through. Used for executing additional
|
|
845
852
|
functionality, such as logging or streaming, throughout generation.
|
|
846
853
|
tags: List of tags to associate with each prompt. If provided, the length
|
|
847
854
|
of the list must match the length of the prompts list.
|
|
@@ -861,8 +868,8 @@ class BaseLLM(BaseLanguageModel[str], ABC):
|
|
|
861
868
|
`run_name` (if provided) does not match the length of prompts.
|
|
862
869
|
|
|
863
870
|
Returns:
|
|
864
|
-
An LLMResult
|
|
865
|
-
prompt and additional model provider-specific output.
|
|
871
|
+
An `LLMResult`, which contains a list of candidate `Generations` for each
|
|
872
|
+
input prompt and additional model provider-specific output.
|
|
866
873
|
"""
|
|
867
874
|
if not isinstance(prompts, list):
|
|
868
875
|
msg = (
|
|
@@ -1111,7 +1118,7 @@ class BaseLLM(BaseLanguageModel[str], ABC):
|
|
|
1111
1118
|
prompts: List of string prompts.
|
|
1112
1119
|
stop: Stop words to use when generating. Model output is cut off at the
|
|
1113
1120
|
first occurrence of any of these substrings.
|
|
1114
|
-
callbacks: Callbacks to pass through. Used for executing additional
|
|
1121
|
+
callbacks: `Callbacks` to pass through. Used for executing additional
|
|
1115
1122
|
functionality, such as logging or streaming, throughout generation.
|
|
1116
1123
|
tags: List of tags to associate with each prompt. If provided, the length
|
|
1117
1124
|
of the list must match the length of the prompts list.
|
|
@@ -1130,8 +1137,8 @@ class BaseLLM(BaseLanguageModel[str], ABC):
|
|
|
1130
1137
|
`run_name` (if provided) does not match the length of prompts.
|
|
1131
1138
|
|
|
1132
1139
|
Returns:
|
|
1133
|
-
An LLMResult
|
|
1134
|
-
prompt and additional model provider-specific output.
|
|
1140
|
+
An `LLMResult`, which contains a list of candidate `Generations` for each
|
|
1141
|
+
input prompt and additional model provider-specific output.
|
|
1135
1142
|
"""
|
|
1136
1143
|
if isinstance(metadata, list):
|
|
1137
1144
|
metadata = [
|
|
@@ -1387,11 +1394,6 @@ class LLM(BaseLLM):
|
|
|
1387
1394
|
`astream` will use `_astream` if provided, otherwise it will implement
|
|
1388
1395
|
a fallback behavior that will use `_stream` if `_stream` is implemented,
|
|
1389
1396
|
and use `_acall` if `_stream` is not implemented.
|
|
1390
|
-
|
|
1391
|
-
Please see the following guide for more information on how to
|
|
1392
|
-
implement a custom LLM:
|
|
1393
|
-
|
|
1394
|
-
https://python.langchain.com/docs/how_to/custom_llm/
|
|
1395
1397
|
"""
|
|
1396
1398
|
|
|
1397
1399
|
@abstractmethod
|
langchain_core/load/dump.py
CHANGED
|
@@ -17,7 +17,7 @@ def default(obj: Any) -> Any:
|
|
|
17
17
|
obj: The object to serialize to json if it is a Serializable object.
|
|
18
18
|
|
|
19
19
|
Returns:
|
|
20
|
-
A
|
|
20
|
+
A JSON serializable object or a SerializedNotImplemented object.
|
|
21
21
|
"""
|
|
22
22
|
if isinstance(obj, Serializable):
|
|
23
23
|
return obj.to_json()
|
|
@@ -38,7 +38,7 @@ def _dump_pydantic_models(obj: Any) -> Any:
|
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
def dumps(obj: Any, *, pretty: bool = False, **kwargs: Any) -> str:
|
|
41
|
-
"""Return a
|
|
41
|
+
"""Return a JSON string representation of an object.
|
|
42
42
|
|
|
43
43
|
Args:
|
|
44
44
|
obj: The object to dump.
|
|
@@ -47,7 +47,7 @@ def dumps(obj: Any, *, pretty: bool = False, **kwargs: Any) -> str:
|
|
|
47
47
|
**kwargs: Additional arguments to pass to `json.dumps`
|
|
48
48
|
|
|
49
49
|
Returns:
|
|
50
|
-
A
|
|
50
|
+
A JSON string representation of the object.
|
|
51
51
|
|
|
52
52
|
Raises:
|
|
53
53
|
ValueError: If `default` is passed as a kwarg.
|
|
@@ -71,14 +71,12 @@ def dumps(obj: Any, *, pretty: bool = False, **kwargs: Any) -> str:
|
|
|
71
71
|
def dumpd(obj: Any) -> Any:
|
|
72
72
|
"""Return a dict representation of an object.
|
|
73
73
|
|
|
74
|
-
!!! note
|
|
75
|
-
Unfortunately this function is not as efficient as it could be because it first
|
|
76
|
-
dumps the object to a json string and then loads it back into a dictionary.
|
|
77
|
-
|
|
78
74
|
Args:
|
|
79
75
|
obj: The object to dump.
|
|
80
76
|
|
|
81
77
|
Returns:
|
|
82
|
-
|
|
78
|
+
Dictionary that can be serialized to json using `json.dumps`.
|
|
83
79
|
"""
|
|
80
|
+
# Unfortunately this function is not as efficient as it could be because it first
|
|
81
|
+
# dumps the object to a json string and then loads it back into a dictionary.
|
|
84
82
|
return json.loads(dumps(obj))
|
|
@@ -97,11 +97,14 @@ class Serializable(BaseModel, ABC):
|
|
|
97
97
|
by default. This is to prevent accidental serialization of objects that should
|
|
98
98
|
not be serialized.
|
|
99
99
|
- `get_lc_namespace`: Get the namespace of the LangChain object.
|
|
100
|
+
|
|
100
101
|
During deserialization, this namespace is used to identify
|
|
101
102
|
the correct class to instantiate.
|
|
103
|
+
|
|
102
104
|
Please see the `Reviver` class in `langchain_core.load.load` for more details.
|
|
103
105
|
During deserialization an additional mapping is handle classes that have moved
|
|
104
106
|
or been renamed across package versions.
|
|
107
|
+
|
|
105
108
|
- `lc_secrets`: A map of constructor argument names to secret ids.
|
|
106
109
|
- `lc_attributes`: List of additional attribute names that should be included
|
|
107
110
|
as part of the serialized representation.
|
|
@@ -194,7 +197,7 @@ class Serializable(BaseModel, ABC):
|
|
|
194
197
|
ValueError: If the class has deprecated attributes.
|
|
195
198
|
|
|
196
199
|
Returns:
|
|
197
|
-
A
|
|
200
|
+
A JSON serializable object or a `SerializedNotImplemented` object.
|
|
198
201
|
"""
|
|
199
202
|
if not self.is_lc_serializable():
|
|
200
203
|
return self.to_json_not_implemented()
|
|
@@ -9,6 +9,9 @@ if TYPE_CHECKING:
|
|
|
9
9
|
from langchain_core.messages.ai import (
|
|
10
10
|
AIMessage,
|
|
11
11
|
AIMessageChunk,
|
|
12
|
+
InputTokenDetails,
|
|
13
|
+
OutputTokenDetails,
|
|
14
|
+
UsageMetadata,
|
|
12
15
|
)
|
|
13
16
|
from langchain_core.messages.base import (
|
|
14
17
|
BaseMessage,
|
|
@@ -87,10 +90,12 @@ __all__ = (
|
|
|
87
90
|
"HumanMessage",
|
|
88
91
|
"HumanMessageChunk",
|
|
89
92
|
"ImageContentBlock",
|
|
93
|
+
"InputTokenDetails",
|
|
90
94
|
"InvalidToolCall",
|
|
91
95
|
"MessageLikeRepresentation",
|
|
92
96
|
"NonStandardAnnotation",
|
|
93
97
|
"NonStandardContentBlock",
|
|
98
|
+
"OutputTokenDetails",
|
|
94
99
|
"PlainTextContentBlock",
|
|
95
100
|
"ReasoningContentBlock",
|
|
96
101
|
"RemoveMessage",
|
|
@@ -104,6 +109,7 @@ __all__ = (
|
|
|
104
109
|
"ToolCallChunk",
|
|
105
110
|
"ToolMessage",
|
|
106
111
|
"ToolMessageChunk",
|
|
112
|
+
"UsageMetadata",
|
|
107
113
|
"VideoContentBlock",
|
|
108
114
|
"_message_from_dict",
|
|
109
115
|
"convert_to_messages",
|
|
@@ -145,6 +151,7 @@ _dynamic_imports = {
|
|
|
145
151
|
"HumanMessageChunk": "human",
|
|
146
152
|
"NonStandardAnnotation": "content",
|
|
147
153
|
"NonStandardContentBlock": "content",
|
|
154
|
+
"OutputTokenDetails": "ai",
|
|
148
155
|
"PlainTextContentBlock": "content",
|
|
149
156
|
"ReasoningContentBlock": "content",
|
|
150
157
|
"RemoveMessage": "modifier",
|
|
@@ -154,12 +161,14 @@ _dynamic_imports = {
|
|
|
154
161
|
"SystemMessage": "system",
|
|
155
162
|
"SystemMessageChunk": "system",
|
|
156
163
|
"ImageContentBlock": "content",
|
|
164
|
+
"InputTokenDetails": "ai",
|
|
157
165
|
"InvalidToolCall": "tool",
|
|
158
166
|
"TextContentBlock": "content",
|
|
159
167
|
"ToolCall": "tool",
|
|
160
168
|
"ToolCallChunk": "tool",
|
|
161
169
|
"ToolMessage": "tool",
|
|
162
170
|
"ToolMessageChunk": "tool",
|
|
171
|
+
"UsageMetadata": "ai",
|
|
163
172
|
"VideoContentBlock": "content",
|
|
164
173
|
"AnyMessage": "utils",
|
|
165
174
|
"MessageLikeRepresentation": "utils",
|
langchain_core/messages/ai.py
CHANGED
|
@@ -48,10 +48,10 @@ class InputTokenDetails(TypedDict, total=False):
|
|
|
48
48
|
}
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
!!! version-added "Added in version 0.3.9"
|
|
52
|
-
|
|
53
51
|
May also hold extra provider-specific keys.
|
|
54
52
|
|
|
53
|
+
!!! version-added "Added in version 0.3.9"
|
|
54
|
+
|
|
55
55
|
"""
|
|
56
56
|
|
|
57
57
|
audio: int
|
|
@@ -83,6 +83,8 @@ class OutputTokenDetails(TypedDict, total=False):
|
|
|
83
83
|
}
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
+
May also hold extra provider-specific keys.
|
|
87
|
+
|
|
86
88
|
!!! version-added "Added in version 0.3.9"
|
|
87
89
|
|
|
88
90
|
"""
|
|
@@ -124,6 +126,10 @@ class UsageMetadata(TypedDict):
|
|
|
124
126
|
!!! warning "Behavior changed in 0.3.9"
|
|
125
127
|
Added `input_token_details` and `output_token_details`.
|
|
126
128
|
|
|
129
|
+
!!! note "LangSmith SDK"
|
|
130
|
+
The LangSmith SDK also has a `UsageMetadata` class. While the two share fields,
|
|
131
|
+
LangSmith's `UsageMetadata` has additional fields to capture cost information
|
|
132
|
+
used by the LangSmith platform.
|
|
127
133
|
"""
|
|
128
134
|
|
|
129
135
|
input_tokens: int
|
|
@@ -131,7 +137,7 @@ class UsageMetadata(TypedDict):
|
|
|
131
137
|
output_tokens: int
|
|
132
138
|
"""Count of output (or completion) tokens. Sum of all output token types."""
|
|
133
139
|
total_tokens: int
|
|
134
|
-
"""Total token count. Sum of input_tokens + output_tokens
|
|
140
|
+
"""Total token count. Sum of `input_tokens` + `output_tokens`."""
|
|
135
141
|
input_token_details: NotRequired[InputTokenDetails]
|
|
136
142
|
"""Breakdown of input token counts.
|
|
137
143
|
|
|
@@ -141,7 +147,6 @@ class UsageMetadata(TypedDict):
|
|
|
141
147
|
"""Breakdown of output token counts.
|
|
142
148
|
|
|
143
149
|
Does *not* need to sum to full output token count. Does *not* need to have all keys.
|
|
144
|
-
|
|
145
150
|
"""
|
|
146
151
|
|
|
147
152
|
|
|
@@ -153,7 +158,6 @@ class AIMessage(BaseMessage):
|
|
|
153
158
|
This message represents the output of the model and consists of both
|
|
154
159
|
the raw output as returned by the model and standardized fields
|
|
155
160
|
(e.g., tool calls, usage metadata) added by the LangChain framework.
|
|
156
|
-
|
|
157
161
|
"""
|
|
158
162
|
|
|
159
163
|
tool_calls: list[ToolCall] = []
|
|
@@ -651,13 +655,13 @@ def add_ai_message_chunks(
|
|
|
651
655
|
chunk_id = id_
|
|
652
656
|
break
|
|
653
657
|
else:
|
|
654
|
-
# second pass: prefer lc_run-*
|
|
658
|
+
# second pass: prefer lc_run-* IDs over lc_* IDs
|
|
655
659
|
for id_ in candidates:
|
|
656
660
|
if id_ and id_.startswith(LC_ID_PREFIX):
|
|
657
661
|
chunk_id = id_
|
|
658
662
|
break
|
|
659
663
|
else:
|
|
660
|
-
# third pass: take any remaining
|
|
664
|
+
# third pass: take any remaining ID (auto-generated lc_* IDs)
|
|
661
665
|
for id_ in candidates:
|
|
662
666
|
if id_:
|
|
663
667
|
chunk_id = id_
|
langchain_core/messages/base.py
CHANGED
|
@@ -93,6 +93,10 @@ class BaseMessage(Serializable):
|
|
|
93
93
|
"""Base abstract message class.
|
|
94
94
|
|
|
95
95
|
Messages are the inputs and outputs of a chat model.
|
|
96
|
+
|
|
97
|
+
Examples include [`HumanMessage`][langchain.messages.HumanMessage],
|
|
98
|
+
[`AIMessage`][langchain.messages.AIMessage], and
|
|
99
|
+
[`SystemMessage`][langchain.messages.SystemMessage].
|
|
96
100
|
"""
|
|
97
101
|
|
|
98
102
|
content: str | list[str | dict]
|
|
@@ -282,7 +282,7 @@ def _convert_to_v1_from_genai(message: AIMessage) -> list[types.ContentBlock]:
|
|
|
282
282
|
standard content blocks for returning.
|
|
283
283
|
|
|
284
284
|
Args:
|
|
285
|
-
message: The AIMessage or AIMessageChunk to convert.
|
|
285
|
+
message: The `AIMessage` or `AIMessageChunk` to convert.
|
|
286
286
|
|
|
287
287
|
Returns:
|
|
288
288
|
List of standard content blocks derived from the message content.
|
|
@@ -368,7 +368,7 @@ def _convert_to_v1_from_genai(message: AIMessage) -> list[types.ContentBlock]:
|
|
|
368
368
|
else:
|
|
369
369
|
# Assume it's raw base64 without data URI
|
|
370
370
|
try:
|
|
371
|
-
# Validate base64 and decode for
|
|
371
|
+
# Validate base64 and decode for MIME type detection
|
|
372
372
|
decoded_bytes = base64.b64decode(url, validate=True)
|
|
373
373
|
|
|
374
374
|
image_url_b64_block = {
|
|
@@ -379,7 +379,7 @@ def _convert_to_v1_from_genai(message: AIMessage) -> list[types.ContentBlock]:
|
|
|
379
379
|
try:
|
|
380
380
|
import filetype # type: ignore[import-not-found] # noqa: PLC0415
|
|
381
381
|
|
|
382
|
-
# Guess
|
|
382
|
+
# Guess MIME type based on file bytes
|
|
383
383
|
mime_type = None
|
|
384
384
|
kind = filetype.guess(decoded_bytes)
|
|
385
385
|
if kind:
|
|
@@ -458,6 +458,8 @@ def _convert_to_v1_from_genai(message: AIMessage) -> list[types.ContentBlock]:
|
|
|
458
458
|
if outcome is not None:
|
|
459
459
|
server_tool_result_block["extras"]["outcome"] = outcome
|
|
460
460
|
converted_blocks.append(server_tool_result_block)
|
|
461
|
+
elif item_type == "text":
|
|
462
|
+
converted_blocks.append(cast("types.TextContentBlock", item))
|
|
461
463
|
else:
|
|
462
464
|
# Unknown type, preserve as non-standard
|
|
463
465
|
converted_blocks.append({"type": "non_standard", "value": item})
|
|
@@ -644,7 +644,7 @@ class AudioContentBlock(TypedDict):
|
|
|
644
644
|
|
|
645
645
|
|
|
646
646
|
class PlainTextContentBlock(TypedDict):
|
|
647
|
-
"""Plaintext data (e.g., from a document).
|
|
647
|
+
"""Plaintext data (e.g., from a `.txt` or `.md` document).
|
|
648
648
|
|
|
649
649
|
!!! note
|
|
650
650
|
A `PlainTextContentBlock` existed in `langchain-core<1.0.0`. Although the
|
|
@@ -767,7 +767,7 @@ class FileContentBlock(TypedDict):
|
|
|
767
767
|
|
|
768
768
|
|
|
769
769
|
class NonStandardContentBlock(TypedDict):
|
|
770
|
-
"""Provider-specific data.
|
|
770
|
+
"""Provider-specific content data.
|
|
771
771
|
|
|
772
772
|
This block contains data for which there is not yet a standard type.
|
|
773
773
|
|
|
@@ -802,7 +802,7 @@ class NonStandardContentBlock(TypedDict):
|
|
|
802
802
|
"""
|
|
803
803
|
|
|
804
804
|
value: dict[str, Any]
|
|
805
|
-
"""Provider-specific data."""
|
|
805
|
+
"""Provider-specific content data."""
|
|
806
806
|
|
|
807
807
|
index: NotRequired[int | str]
|
|
808
808
|
"""Index of block in aggregate response. Used during streaming."""
|
|
@@ -1399,7 +1399,7 @@ def create_non_standard_block(
|
|
|
1399
1399
|
"""Create a `NonStandardContentBlock`.
|
|
1400
1400
|
|
|
1401
1401
|
Args:
|
|
1402
|
-
value: Provider-specific data.
|
|
1402
|
+
value: Provider-specific content data.
|
|
1403
1403
|
id: Content block identifier. Generated automatically if not provided.
|
|
1404
1404
|
index: Index of block in aggregate response. Used during streaming.
|
|
1405
1405
|
|