langchain 1.2.4__tar.gz → 1.2.5__tar.gz
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.
- {langchain-1.2.4 → langchain-1.2.5}/PKG-INFO +2 -2
- {langchain-1.2.4 → langchain-1.2.5}/langchain/__init__.py +1 -1
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/middleware/summarization.py +61 -8
- {langchain-1.2.4 → langchain-1.2.5}/pyproject.toml +2 -2
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/test_summarization.py +70 -0
- langchain-1.2.5/tests/unit_tests/agents/test_agent_name.py +219 -0
- {langchain-1.2.4 → langchain-1.2.5}/uv.lock +2 -2
- langchain-1.2.4/tests/unit_tests/agents/test_agent_name.py +0 -105
- {langchain-1.2.4 → langchain-1.2.5}/.gitignore +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/LICENSE +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/Makefile +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/README.md +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/extended_testing_deps.txt +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/factory.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/middleware/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/middleware/_execution.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/middleware/_redaction.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/middleware/_retry.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/middleware/context_editing.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/middleware/file_search.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/middleware/human_in_the_loop.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/middleware/model_call_limit.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/middleware/model_fallback.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/middleware/model_retry.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/middleware/pii.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/middleware/shell_tool.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/middleware/todo.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/middleware/tool_call_limit.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/middleware/tool_emulator.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/middleware/tool_retry.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/middleware/tool_selection.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/middleware/types.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/agents/structured_output.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/chat_models/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/chat_models/base.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/embeddings/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/embeddings/base.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/messages/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/py.typed +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/rate_limiters/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/tools/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/langchain/tools/tool_node.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/scripts/check_imports.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/cassettes/test_inference_to_native_output[False].yaml.gz +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/cassettes/test_inference_to_native_output[True].yaml.gz +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/cassettes/test_inference_to_tool_output[False].yaml.gz +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/cassettes/test_inference_to_tool_output[True].yaml.gz +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/cassettes/test_strict_mode[False].yaml.gz +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/cassettes/test_strict_mode[True].yaml.gz +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/integration_tests/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/integration_tests/agents/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/integration_tests/agents/middleware/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/integration_tests/agents/middleware/test_shell_tool_integration.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/integration_tests/cache/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/integration_tests/cache/fake_embeddings.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/integration_tests/chat_models/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/integration_tests/chat_models/test_base.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/integration_tests/conftest.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/integration_tests/embeddings/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/integration_tests/embeddings/test_base.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/integration_tests/test_compile.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/__snapshots__/test_middleware_agent.ambr +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/__snapshots__/test_middleware_decorators.ambr +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/__snapshots__/test_middleware_framework.ambr +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/__snapshots__/test_return_direct_graph.ambr +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/any_str.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/compose-postgres.yml +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/compose-redis.yml +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/conftest.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/conftest_checkpointer.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/conftest_store.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/memory_assert.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/messages.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/__snapshots__/test_middleware_decorators.ambr +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/__snapshots__/test_middleware_diagram.ambr +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/__snapshots__/test_middleware_framework.ambr +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/core/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/core/__snapshots__/test_decorators.ambr +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/core/__snapshots__/test_diagram.ambr +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/core/__snapshots__/test_framework.ambr +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/core/test_composition.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/core/test_decorators.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/core/test_diagram.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/core/test_framework.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/core/test_overrides.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/core/test_sync_async_wrappers.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/core/test_tools.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/core/test_wrap_model_call.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/core/test_wrap_tool_call.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/test_context_editing.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/test_file_search.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/test_human_in_the_loop.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/test_model_call_limit.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/test_model_fallback.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/test_model_retry.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/test_pii.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/test_shell_execution_policies.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/test_shell_tool.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/test_structured_output_retry.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/test_todo.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/test_tool_call_limit.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/test_tool_emulator.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/test_tool_retry.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/test_tool_selection.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/model.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/specifications/responses.json +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/specifications/return_direct.json +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/test_create_agent_tool_validation.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/test_injected_runtime_create_agent.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/test_kwargs_tool_runtime_injection.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/test_react_agent.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/test_response_format.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/test_response_format_integration.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/test_responses.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/test_responses_spec.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/test_return_direct_graph.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/test_return_direct_spec.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/test_state_schema.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/test_system_message.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/utils.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/chat_models/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/chat_models/test_chat_models.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/conftest.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/embeddings/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/embeddings/test_base.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/embeddings/test_imports.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/test_dependencies.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/test_imports.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/test_pytest_config.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/test_version.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/tools/__init__.py +0 -0
- {langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/tools/test_imports.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: langchain
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.5
|
|
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/langchain/
|
|
@@ -12,7 +12,7 @@ Project-URL: Reddit, https://www.reddit.com/r/LangChain/
|
|
|
12
12
|
License: MIT
|
|
13
13
|
License-File: LICENSE
|
|
14
14
|
Requires-Python: <4.0.0,>=3.10.0
|
|
15
|
-
Requires-Dist: langchain-core<2.0.0,>=1.2.
|
|
15
|
+
Requires-Dist: langchain-core<2.0.0,>=1.2.7
|
|
16
16
|
Requires-Dist: langgraph<1.1.0,>=1.0.2
|
|
17
17
|
Requires-Dist: pydantic<3.0.0,>=2.7.4
|
|
18
18
|
Provides-Extra: anthropic
|
|
@@ -19,6 +19,8 @@ from langchain_core.messages.utils import (
|
|
|
19
19
|
get_buffer_string,
|
|
20
20
|
trim_messages,
|
|
21
21
|
)
|
|
22
|
+
from langchain_core.runnables.config import RunnableConfig, merge_configs
|
|
23
|
+
from langgraph.config import get_config
|
|
22
24
|
from langgraph.graph.message import (
|
|
23
25
|
REMOVE_ALL_MESSAGES,
|
|
24
26
|
)
|
|
@@ -40,12 +42,27 @@ Your sole objective in this task is to extract the highest quality/most relevant
|
|
|
40
42
|
|
|
41
43
|
<objective_information>
|
|
42
44
|
You're nearing the total number of input tokens you can accept, so you must extract the highest quality/most relevant pieces of information from your conversation history.
|
|
43
|
-
This context will then overwrite the conversation history presented below. Because of this, ensure the context you extract is only the most important information to your overall goal.
|
|
45
|
+
This context will then overwrite the conversation history presented below. Because of this, ensure the context you extract is only the most important information to continue working toward your overall goal.
|
|
44
46
|
</objective_information>
|
|
45
47
|
|
|
46
48
|
<instructions>
|
|
47
|
-
The conversation history below will be replaced with the context you extract in this step.
|
|
49
|
+
The conversation history below will be replaced with the context you extract in this step.
|
|
48
50
|
You want to ensure that you don't repeat any actions you've already completed, so the context you extract from the conversation history should be focused on the most important information to your overall goal.
|
|
51
|
+
|
|
52
|
+
You should structure your summary using the following sections. Each section acts as a checklist - you must populate it with relevant information or explicitly state "None" if there is nothing to report for that section:
|
|
53
|
+
|
|
54
|
+
## SESSION INTENT
|
|
55
|
+
What is the user's primary goal or request? What overall task are you trying to accomplish? This should be concise but complete enough to understand the purpose of the entire session.
|
|
56
|
+
|
|
57
|
+
## SUMMARY
|
|
58
|
+
Extract and record all of the most important context from the conversation history. Include important choices, conclusions, or strategies determined during this conversation. Include the reasoning behind key decisions. Document any rejected options and why they were not pursued.
|
|
59
|
+
|
|
60
|
+
## ARTIFACTS
|
|
61
|
+
What artifacts, files, or resources were created, modified, or accessed during this conversation? For file modifications, list specific file paths and briefly describe the changes made to each. This section prevents silent loss of artifact information.
|
|
62
|
+
|
|
63
|
+
## NEXT STEPS
|
|
64
|
+
What specific tasks remain to be completed to achieve the session intent? What should you do next?
|
|
65
|
+
|
|
49
66
|
</instructions>
|
|
50
67
|
|
|
51
68
|
The user will message you with the full message history you'll be extracting context from, to then replace. Carefully read over it all, and think deeply about what information is most important to your overall goal that should be saved:
|
|
@@ -269,7 +286,7 @@ class SummarizationMiddleware(AgentMiddleware):
|
|
|
269
286
|
raise ValueError(msg)
|
|
270
287
|
|
|
271
288
|
@override
|
|
272
|
-
def before_model(self, state: AgentState[Any],
|
|
289
|
+
def before_model(self, state: AgentState[Any], _runtime: Runtime) -> dict[str, Any] | None:
|
|
273
290
|
"""Process messages before model invocation, potentially triggering summarization.
|
|
274
291
|
|
|
275
292
|
Args:
|
|
@@ -306,7 +323,7 @@ class SummarizationMiddleware(AgentMiddleware):
|
|
|
306
323
|
|
|
307
324
|
@override
|
|
308
325
|
async def abefore_model(
|
|
309
|
-
self, state: AgentState[Any],
|
|
326
|
+
self, state: AgentState[Any], _runtime: Runtime
|
|
310
327
|
) -> dict[str, Any] | None:
|
|
311
328
|
"""Process messages before model invocation, potentially triggering summarization.
|
|
312
329
|
|
|
@@ -563,7 +580,11 @@ class SummarizationMiddleware(AgentMiddleware):
|
|
|
563
580
|
return idx
|
|
564
581
|
|
|
565
582
|
def _create_summary(self, messages_to_summarize: list[AnyMessage]) -> str:
|
|
566
|
-
"""Generate summary for the given messages.
|
|
583
|
+
"""Generate summary for the given messages.
|
|
584
|
+
|
|
585
|
+
Args:
|
|
586
|
+
messages_to_summarize: Messages to summarize.
|
|
587
|
+
"""
|
|
567
588
|
if not messages_to_summarize:
|
|
568
589
|
return "No previous conversation history."
|
|
569
590
|
|
|
@@ -575,14 +596,33 @@ class SummarizationMiddleware(AgentMiddleware):
|
|
|
575
596
|
# message objects
|
|
576
597
|
formatted_messages = get_buffer_string(trimmed_messages)
|
|
577
598
|
|
|
599
|
+
# Merge parent config with summarization metadata.
|
|
600
|
+
# Use get_config() to get the current LangGraph config which contains
|
|
601
|
+
# langgraph_checkpoint_ns - required by StreamMessagesHandler to properly
|
|
602
|
+
# track the model call and propagate metadata (including lc_source) to
|
|
603
|
+
# stream chunks.
|
|
578
604
|
try:
|
|
579
|
-
|
|
605
|
+
base_config: RunnableConfig = get_config()
|
|
606
|
+
except RuntimeError:
|
|
607
|
+
# Fallback if called outside a runnable context
|
|
608
|
+
base_config = {}
|
|
609
|
+
config = merge_configs(base_config, {"metadata": {"lc_source": "summarization"}})
|
|
610
|
+
|
|
611
|
+
try:
|
|
612
|
+
response = self.model.invoke(
|
|
613
|
+
self.summary_prompt.format(messages=formatted_messages),
|
|
614
|
+
config=config,
|
|
615
|
+
)
|
|
580
616
|
return response.text.strip()
|
|
581
617
|
except Exception as e:
|
|
582
618
|
return f"Error generating summary: {e!s}"
|
|
583
619
|
|
|
584
620
|
async def _acreate_summary(self, messages_to_summarize: list[AnyMessage]) -> str:
|
|
585
|
-
"""Generate summary for the given messages.
|
|
621
|
+
"""Generate summary for the given messages.
|
|
622
|
+
|
|
623
|
+
Args:
|
|
624
|
+
messages_to_summarize: Messages to summarize.
|
|
625
|
+
"""
|
|
586
626
|
if not messages_to_summarize:
|
|
587
627
|
return "No previous conversation history."
|
|
588
628
|
|
|
@@ -594,9 +634,22 @@ class SummarizationMiddleware(AgentMiddleware):
|
|
|
594
634
|
# message objects
|
|
595
635
|
formatted_messages = get_buffer_string(trimmed_messages)
|
|
596
636
|
|
|
637
|
+
# Merge parent config with summarization metadata.
|
|
638
|
+
# Use get_config() to get the current LangGraph config which contains
|
|
639
|
+
# langgraph_checkpoint_ns - required by StreamMessagesHandler to properly
|
|
640
|
+
# track the model call and propagate metadata (including lc_source) to
|
|
641
|
+
# stream chunks.
|
|
642
|
+
try:
|
|
643
|
+
base_config: RunnableConfig = get_config()
|
|
644
|
+
except RuntimeError:
|
|
645
|
+
# Fallback if called outside a runnable context
|
|
646
|
+
base_config = {}
|
|
647
|
+
config = merge_configs(base_config, {"metadata": {"lc_source": "summarization"}})
|
|
648
|
+
|
|
597
649
|
try:
|
|
598
650
|
response = await self.model.ainvoke(
|
|
599
|
-
self.summary_prompt.format(messages=formatted_messages)
|
|
651
|
+
self.summary_prompt.format(messages=formatted_messages),
|
|
652
|
+
config=config,
|
|
600
653
|
)
|
|
601
654
|
return response.text.strip()
|
|
602
655
|
except Exception as e:
|
|
@@ -9,10 +9,10 @@ license = { text = "MIT" }
|
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = []
|
|
11
11
|
|
|
12
|
-
version = "1.2.
|
|
12
|
+
version = "1.2.5"
|
|
13
13
|
requires-python = ">=3.10.0,<4.0.0"
|
|
14
14
|
dependencies = [
|
|
15
|
-
"langchain-core>=1.2.
|
|
15
|
+
"langchain-core>=1.2.7,<2.0.0",
|
|
16
16
|
"langgraph>=1.0.2,<1.1.0",
|
|
17
17
|
"pydantic>=2.7.4,<3.0.0",
|
|
18
18
|
]
|
|
@@ -1214,3 +1214,73 @@ def test_usage_metadata_trigger() -> None:
|
|
|
1214
1214
|
]
|
|
1215
1215
|
)
|
|
1216
1216
|
assert not middleware._should_summarize(messages, 0)
|
|
1217
|
+
|
|
1218
|
+
|
|
1219
|
+
class ConfigCapturingModel(BaseChatModel):
|
|
1220
|
+
"""Mock model that captures the config passed to invoke/ainvoke."""
|
|
1221
|
+
|
|
1222
|
+
captured_configs: list[RunnableConfig | None] = Field(default_factory=list, exclude=True)
|
|
1223
|
+
|
|
1224
|
+
@override
|
|
1225
|
+
def invoke(
|
|
1226
|
+
self,
|
|
1227
|
+
input: LanguageModelInput,
|
|
1228
|
+
config: RunnableConfig | None = None,
|
|
1229
|
+
*,
|
|
1230
|
+
stop: list[str] | None = None,
|
|
1231
|
+
**kwargs: Any,
|
|
1232
|
+
) -> AIMessage:
|
|
1233
|
+
self.captured_configs.append(config)
|
|
1234
|
+
return AIMessage(content="Summary")
|
|
1235
|
+
|
|
1236
|
+
@override
|
|
1237
|
+
async def ainvoke(
|
|
1238
|
+
self,
|
|
1239
|
+
input: LanguageModelInput,
|
|
1240
|
+
config: RunnableConfig | None = None,
|
|
1241
|
+
*,
|
|
1242
|
+
stop: list[str] | None = None,
|
|
1243
|
+
**kwargs: Any,
|
|
1244
|
+
) -> AIMessage:
|
|
1245
|
+
self.captured_configs.append(config)
|
|
1246
|
+
return AIMessage(content="Summary")
|
|
1247
|
+
|
|
1248
|
+
@override
|
|
1249
|
+
def _generate(
|
|
1250
|
+
self,
|
|
1251
|
+
messages: list[BaseMessage],
|
|
1252
|
+
stop: list[str] | None = None,
|
|
1253
|
+
run_manager: CallbackManagerForLLMRun | None = None,
|
|
1254
|
+
**kwargs: Any,
|
|
1255
|
+
) -> ChatResult:
|
|
1256
|
+
return ChatResult(generations=[ChatGeneration(message=AIMessage(content="Summary"))])
|
|
1257
|
+
|
|
1258
|
+
@property
|
|
1259
|
+
def _llm_type(self) -> str:
|
|
1260
|
+
return "config-capturing"
|
|
1261
|
+
|
|
1262
|
+
|
|
1263
|
+
@pytest.mark.parametrize("use_async", [False, True], ids=["sync", "async"])
|
|
1264
|
+
async def test_create_summary_passes_lc_source_metadata(use_async: bool) -> None: # noqa: FBT001
|
|
1265
|
+
"""Test that summary creation passes `lc_source` metadata to the model.
|
|
1266
|
+
|
|
1267
|
+
When called outside a LangGraph runnable context, `get_config()` raises
|
|
1268
|
+
`RuntimeError`. The middleware catches this and still passes the `lc_source`
|
|
1269
|
+
metadata to the model.
|
|
1270
|
+
"""
|
|
1271
|
+
model = ConfigCapturingModel()
|
|
1272
|
+
model.captured_configs = [] # Reset for this test
|
|
1273
|
+
middleware = SummarizationMiddleware(model=model, trigger=("tokens", 1000))
|
|
1274
|
+
messages: list[AnyMessage] = [HumanMessage(content="Hello"), AIMessage(content="Hi")]
|
|
1275
|
+
|
|
1276
|
+
if use_async:
|
|
1277
|
+
summary = await middleware._acreate_summary(messages)
|
|
1278
|
+
else:
|
|
1279
|
+
summary = middleware._create_summary(messages)
|
|
1280
|
+
|
|
1281
|
+
assert summary == "Summary"
|
|
1282
|
+
assert len(model.captured_configs) == 1
|
|
1283
|
+
config = model.captured_configs[0]
|
|
1284
|
+
assert config is not None
|
|
1285
|
+
assert "metadata" in config
|
|
1286
|
+
assert config["metadata"]["lc_source"] == "summarization"
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"""Test agent name parameter in create_agent.
|
|
2
|
+
|
|
3
|
+
This module tests that the name parameter correctly sets .name on AIMessage outputs.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from langchain_core.messages import (
|
|
9
|
+
AIMessage,
|
|
10
|
+
HumanMessage,
|
|
11
|
+
ToolCall,
|
|
12
|
+
)
|
|
13
|
+
from langchain_core.tools import tool
|
|
14
|
+
|
|
15
|
+
from langchain.agents import create_agent
|
|
16
|
+
from tests.unit_tests.agents.model import FakeToolCallingModel
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@tool
|
|
20
|
+
def simple_tool(x: int) -> str:
|
|
21
|
+
"""Simple tool for basic tests."""
|
|
22
|
+
return f"Result: {x}"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_agent_name_set_on_ai_message() -> None:
|
|
26
|
+
"""Test that agent name is set on AIMessage when name is provided."""
|
|
27
|
+
tool_calls: list[list[ToolCall]] = [[]]
|
|
28
|
+
agent = create_agent(
|
|
29
|
+
model=FakeToolCallingModel(tool_calls=tool_calls),
|
|
30
|
+
name="test_agent",
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
result = agent.invoke({"messages": [HumanMessage("Hello")]})
|
|
34
|
+
|
|
35
|
+
ai_messages = [m for m in result["messages"] if isinstance(m, AIMessage)]
|
|
36
|
+
assert len(ai_messages) == 1
|
|
37
|
+
assert ai_messages[0].name == "test_agent"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_agent_name_not_set_when_none() -> None:
|
|
41
|
+
"""Test that AIMessage.name is not set when name is not provided."""
|
|
42
|
+
tool_calls: list[list[ToolCall]] = [[]]
|
|
43
|
+
agent = create_agent(
|
|
44
|
+
model=FakeToolCallingModel(tool_calls=tool_calls),
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
result = agent.invoke({"messages": [HumanMessage("Hello")]})
|
|
48
|
+
|
|
49
|
+
ai_messages = [m for m in result["messages"] if isinstance(m, AIMessage)]
|
|
50
|
+
assert len(ai_messages) == 1
|
|
51
|
+
assert ai_messages[0].name is None
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def test_agent_name_on_multiple_iterations() -> None:
|
|
55
|
+
"""Test that agent name is set on all AIMessages in multi-turn conversation."""
|
|
56
|
+
agent = create_agent(
|
|
57
|
+
model=FakeToolCallingModel(
|
|
58
|
+
tool_calls=[[{"args": {"x": 1}, "id": "call_1", "name": "simple_tool"}], []]
|
|
59
|
+
),
|
|
60
|
+
tools=[simple_tool],
|
|
61
|
+
name="multi_turn_agent",
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
result = agent.invoke({"messages": [HumanMessage("Call a tool")]})
|
|
65
|
+
|
|
66
|
+
ai_messages = [m for m in result["messages"] if isinstance(m, AIMessage)]
|
|
67
|
+
assert len(ai_messages) == 2
|
|
68
|
+
for msg in ai_messages:
|
|
69
|
+
assert msg.name == "multi_turn_agent"
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
async def test_agent_name_async() -> None:
|
|
73
|
+
"""Test that agent name is set on AIMessage in async execution."""
|
|
74
|
+
tool_calls: list[list[ToolCall]] = [[]]
|
|
75
|
+
agent = create_agent(
|
|
76
|
+
model=FakeToolCallingModel(tool_calls=tool_calls),
|
|
77
|
+
name="async_agent",
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
result = await agent.ainvoke({"messages": [HumanMessage("Hello async")]})
|
|
81
|
+
|
|
82
|
+
ai_messages = [m for m in result["messages"] if isinstance(m, AIMessage)]
|
|
83
|
+
assert len(ai_messages) == 1
|
|
84
|
+
assert ai_messages[0].name == "async_agent"
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
async def test_agent_name_async_multiple_iterations() -> None:
|
|
88
|
+
"""Test that agent name is set on all AIMessages in async multi-turn."""
|
|
89
|
+
agent = create_agent(
|
|
90
|
+
model=FakeToolCallingModel(
|
|
91
|
+
tool_calls=[[{"args": {"x": 5}, "id": "call_1", "name": "simple_tool"}], []]
|
|
92
|
+
),
|
|
93
|
+
tools=[simple_tool],
|
|
94
|
+
name="async_multi_agent",
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
result = await agent.ainvoke({"messages": [HumanMessage("Call tool async")]})
|
|
98
|
+
|
|
99
|
+
ai_messages = [m for m in result["messages"] if isinstance(m, AIMessage)]
|
|
100
|
+
assert len(ai_messages) == 2
|
|
101
|
+
for msg in ai_messages:
|
|
102
|
+
assert msg.name == "async_multi_agent"
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# Tests for lc_agent_name in streaming metadata
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def test_lc_agent_name_in_stream_metadata() -> None:
|
|
109
|
+
"""Test that lc_agent_name is included in metadata when streaming with name."""
|
|
110
|
+
tool_calls: list[list[ToolCall]] = [[]]
|
|
111
|
+
agent = create_agent(
|
|
112
|
+
model=FakeToolCallingModel(tool_calls=tool_calls),
|
|
113
|
+
name="streaming_agent",
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
metadata_with_agent_name = []
|
|
117
|
+
for _chunk, metadata in agent.stream(
|
|
118
|
+
{"messages": [HumanMessage("Hello")]},
|
|
119
|
+
stream_mode="messages",
|
|
120
|
+
):
|
|
121
|
+
if "lc_agent_name" in metadata:
|
|
122
|
+
metadata_with_agent_name.append(metadata["lc_agent_name"])
|
|
123
|
+
|
|
124
|
+
assert len(metadata_with_agent_name) > 0
|
|
125
|
+
assert all(name == "streaming_agent" for name in metadata_with_agent_name)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def test_lc_agent_name_not_in_stream_metadata_when_name_not_provided() -> None:
|
|
129
|
+
"""Test that lc_agent_name is not in metadata when name is not provided."""
|
|
130
|
+
tool_calls: list[list[ToolCall]] = [[]]
|
|
131
|
+
agent = create_agent(
|
|
132
|
+
model=FakeToolCallingModel(tool_calls=tool_calls),
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
for _chunk, metadata in agent.stream(
|
|
136
|
+
{"messages": [HumanMessage("Hello")]},
|
|
137
|
+
stream_mode="messages",
|
|
138
|
+
):
|
|
139
|
+
assert "lc_agent_name" not in metadata
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def test_lc_agent_name_in_stream_metadata_multiple_iterations() -> None:
|
|
143
|
+
"""Test that lc_agent_name is in metadata for all stream events in multi-turn."""
|
|
144
|
+
agent = create_agent(
|
|
145
|
+
model=FakeToolCallingModel(
|
|
146
|
+
tool_calls=[[{"args": {"x": 1}, "id": "call_1", "name": "simple_tool"}], []]
|
|
147
|
+
),
|
|
148
|
+
tools=[simple_tool],
|
|
149
|
+
name="multi_turn_streaming_agent",
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
metadata_with_agent_name = []
|
|
153
|
+
for _chunk, metadata in agent.stream(
|
|
154
|
+
{"messages": [HumanMessage("Call a tool")]},
|
|
155
|
+
stream_mode="messages",
|
|
156
|
+
):
|
|
157
|
+
if "lc_agent_name" in metadata:
|
|
158
|
+
metadata_with_agent_name.append(metadata["lc_agent_name"])
|
|
159
|
+
|
|
160
|
+
# Should have metadata entries for messages from both iterations
|
|
161
|
+
assert len(metadata_with_agent_name) > 0
|
|
162
|
+
assert all(name == "multi_turn_streaming_agent" for name in metadata_with_agent_name)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
async def test_lc_agent_name_in_astream_metadata() -> None:
|
|
166
|
+
"""Test that lc_agent_name is included in metadata when async streaming with name."""
|
|
167
|
+
tool_calls: list[list[ToolCall]] = [[]]
|
|
168
|
+
agent = create_agent(
|
|
169
|
+
model=FakeToolCallingModel(tool_calls=tool_calls),
|
|
170
|
+
name="async_streaming_agent",
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
metadata_with_agent_name = []
|
|
174
|
+
async for _chunk, metadata in agent.astream(
|
|
175
|
+
{"messages": [HumanMessage("Hello async")]},
|
|
176
|
+
stream_mode="messages",
|
|
177
|
+
):
|
|
178
|
+
if "lc_agent_name" in metadata:
|
|
179
|
+
metadata_with_agent_name.append(metadata["lc_agent_name"])
|
|
180
|
+
|
|
181
|
+
assert len(metadata_with_agent_name) > 0
|
|
182
|
+
assert all(name == "async_streaming_agent" for name in metadata_with_agent_name)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
async def test_lc_agent_name_not_in_astream_metadata_when_name_not_provided() -> None:
|
|
186
|
+
"""Test that lc_agent_name is not in async stream metadata when name not provided."""
|
|
187
|
+
tool_calls: list[list[ToolCall]] = [[]]
|
|
188
|
+
agent = create_agent(
|
|
189
|
+
model=FakeToolCallingModel(tool_calls=tool_calls),
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
async for _chunk, metadata in agent.astream(
|
|
193
|
+
{"messages": [HumanMessage("Hello async")]},
|
|
194
|
+
stream_mode="messages",
|
|
195
|
+
):
|
|
196
|
+
assert "lc_agent_name" not in metadata
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
async def test_lc_agent_name_in_astream_metadata_multiple_iterations() -> None:
|
|
200
|
+
"""Test that lc_agent_name is in metadata for all async stream events in multi-turn."""
|
|
201
|
+
agent = create_agent(
|
|
202
|
+
model=FakeToolCallingModel(
|
|
203
|
+
tool_calls=[[{"args": {"x": 5}, "id": "call_1", "name": "simple_tool"}], []]
|
|
204
|
+
),
|
|
205
|
+
tools=[simple_tool],
|
|
206
|
+
name="async_multi_turn_streaming_agent",
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
metadata_with_agent_name = []
|
|
210
|
+
async for _chunk, metadata in agent.astream(
|
|
211
|
+
{"messages": [HumanMessage("Call tool async")]},
|
|
212
|
+
stream_mode="messages",
|
|
213
|
+
):
|
|
214
|
+
if "lc_agent_name" in metadata:
|
|
215
|
+
metadata_with_agent_name.append(metadata["lc_agent_name"])
|
|
216
|
+
|
|
217
|
+
# Should have metadata entries for messages from both iterations
|
|
218
|
+
assert len(metadata_with_agent_name) > 0
|
|
219
|
+
assert all(name == "async_multi_turn_streaming_agent" for name in metadata_with_agent_name)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
version = 1
|
|
2
|
-
revision =
|
|
2
|
+
revision = 2
|
|
3
3
|
requires-python = ">=3.10.0, <4.0.0"
|
|
4
4
|
resolution-markers = [
|
|
5
5
|
"python_full_version >= '3.14' and platform_python_implementation == 'PyPy'",
|
|
@@ -1863,7 +1863,7 @@ wheels = [
|
|
|
1863
1863
|
|
|
1864
1864
|
[[package]]
|
|
1865
1865
|
name = "langchain"
|
|
1866
|
-
version = "1.2.
|
|
1866
|
+
version = "1.2.5"
|
|
1867
1867
|
source = { editable = "." }
|
|
1868
1868
|
dependencies = [
|
|
1869
1869
|
{ name = "langchain-core" },
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
"""Test agent name parameter in create_agent.
|
|
2
|
-
|
|
3
|
-
This module tests that the name parameter correctly sets .name on AIMessage outputs.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
from __future__ import annotations
|
|
7
|
-
|
|
8
|
-
import pytest
|
|
9
|
-
from langchain_core.messages import (
|
|
10
|
-
AIMessage,
|
|
11
|
-
HumanMessage,
|
|
12
|
-
ToolCall,
|
|
13
|
-
)
|
|
14
|
-
from langchain_core.tools import tool
|
|
15
|
-
|
|
16
|
-
from langchain.agents import create_agent
|
|
17
|
-
from tests.unit_tests.agents.model import FakeToolCallingModel
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@tool
|
|
21
|
-
def simple_tool(x: int) -> str:
|
|
22
|
-
"""Simple tool for basic tests."""
|
|
23
|
-
return f"Result: {x}"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def test_agent_name_set_on_ai_message() -> None:
|
|
27
|
-
"""Test that agent name is set on AIMessage when name is provided."""
|
|
28
|
-
tool_calls: list[list[ToolCall]] = [[]]
|
|
29
|
-
agent = create_agent(
|
|
30
|
-
model=FakeToolCallingModel(tool_calls=tool_calls),
|
|
31
|
-
name="test_agent",
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
result = agent.invoke({"messages": [HumanMessage("Hello")]})
|
|
35
|
-
|
|
36
|
-
ai_messages = [m for m in result["messages"] if isinstance(m, AIMessage)]
|
|
37
|
-
assert len(ai_messages) == 1
|
|
38
|
-
assert ai_messages[0].name == "test_agent"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def test_agent_name_not_set_when_none() -> None:
|
|
42
|
-
"""Test that AIMessage.name is not set when name is not provided."""
|
|
43
|
-
tool_calls: list[list[ToolCall]] = [[]]
|
|
44
|
-
agent = create_agent(
|
|
45
|
-
model=FakeToolCallingModel(tool_calls=tool_calls),
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
result = agent.invoke({"messages": [HumanMessage("Hello")]})
|
|
49
|
-
|
|
50
|
-
ai_messages = [m for m in result["messages"] if isinstance(m, AIMessage)]
|
|
51
|
-
assert len(ai_messages) == 1
|
|
52
|
-
assert ai_messages[0].name is None
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def test_agent_name_on_multiple_iterations() -> None:
|
|
56
|
-
"""Test that agent name is set on all AIMessages in multi-turn conversation."""
|
|
57
|
-
agent = create_agent(
|
|
58
|
-
model=FakeToolCallingModel(
|
|
59
|
-
tool_calls=[[{"args": {"x": 1}, "id": "call_1", "name": "simple_tool"}], []]
|
|
60
|
-
),
|
|
61
|
-
tools=[simple_tool],
|
|
62
|
-
name="multi_turn_agent",
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
result = agent.invoke({"messages": [HumanMessage("Call a tool")]})
|
|
66
|
-
|
|
67
|
-
ai_messages = [m for m in result["messages"] if isinstance(m, AIMessage)]
|
|
68
|
-
assert len(ai_messages) == 2
|
|
69
|
-
for msg in ai_messages:
|
|
70
|
-
assert msg.name == "multi_turn_agent"
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
@pytest.mark.asyncio
|
|
74
|
-
async def test_agent_name_async() -> None:
|
|
75
|
-
"""Test that agent name is set on AIMessage in async execution."""
|
|
76
|
-
tool_calls: list[list[ToolCall]] = [[]]
|
|
77
|
-
agent = create_agent(
|
|
78
|
-
model=FakeToolCallingModel(tool_calls=tool_calls),
|
|
79
|
-
name="async_agent",
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
result = await agent.ainvoke({"messages": [HumanMessage("Hello async")]})
|
|
83
|
-
|
|
84
|
-
ai_messages = [m for m in result["messages"] if isinstance(m, AIMessage)]
|
|
85
|
-
assert len(ai_messages) == 1
|
|
86
|
-
assert ai_messages[0].name == "async_agent"
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
@pytest.mark.asyncio
|
|
90
|
-
async def test_agent_name_async_multiple_iterations() -> None:
|
|
91
|
-
"""Test that agent name is set on all AIMessages in async multi-turn."""
|
|
92
|
-
agent = create_agent(
|
|
93
|
-
model=FakeToolCallingModel(
|
|
94
|
-
tool_calls=[[{"args": {"x": 5}, "id": "call_1", "name": "simple_tool"}], []]
|
|
95
|
-
),
|
|
96
|
-
tools=[simple_tool],
|
|
97
|
-
name="async_multi_agent",
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
result = await agent.ainvoke({"messages": [HumanMessage("Call tool async")]})
|
|
101
|
-
|
|
102
|
-
ai_messages = [m for m in result["messages"] if isinstance(m, AIMessage)]
|
|
103
|
-
assert len(ai_messages) == 2
|
|
104
|
-
for msg in ai_messages:
|
|
105
|
-
assert msg.name == "async_multi_agent"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain-1.2.4 → langchain-1.2.5}/tests/cassettes/test_inference_to_native_output[False].yaml.gz
RENAMED
|
File without changes
|
{langchain-1.2.4 → langchain-1.2.5}/tests/cassettes/test_inference_to_native_output[True].yaml.gz
RENAMED
|
File without changes
|
{langchain-1.2.4 → langchain-1.2.5}/tests/cassettes/test_inference_to_tool_output[False].yaml.gz
RENAMED
|
File without changes
|
{langchain-1.2.4 → langchain-1.2.5}/tests/cassettes/test_inference_to_tool_output[True].yaml.gz
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/__snapshots__/test_middleware_agent.ambr
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/core/test_composition.py
RENAMED
|
File without changes
|
{langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/core/test_decorators.py
RENAMED
|
File without changes
|
|
File without changes
|
{langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/core/test_framework.py
RENAMED
|
File without changes
|
{langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/core/test_overrides.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/core/test_wrap_model_call.py
RENAMED
|
File without changes
|
{langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/core/test_wrap_tool_call.py
RENAMED
|
File without changes
|
{langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/test_pii.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/middleware/implementations/test_todo.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/specifications/return_direct.json
RENAMED
|
File without changes
|
{langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/test_create_agent_tool_validation.py
RENAMED
|
File without changes
|
{langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/test_injected_runtime_create_agent.py
RENAMED
|
File without changes
|
{langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/test_kwargs_tool_runtime_injection.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain-1.2.4 → langchain-1.2.5}/tests/unit_tests/agents/test_response_format_integration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|