langchain-dev-utils 1.2.12__tar.gz → 1.2.14__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_dev_utils-1.2.14/PKG-INFO +102 -0
- langchain_dev_utils-1.2.14/README.md +85 -0
- langchain_dev_utils-1.2.14/README_cn.md +86 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/pyproject.toml +2 -5
- langchain_dev_utils-1.2.14/src/langchain_dev_utils/__init__.py +1 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/chat_models/adapters/openai_compatible.py +63 -1
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/chat_models/base.py +0 -1
- langchain_dev_utils-1.2.14/tests/test_chat_models.py +185 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/uv.lock +221 -189
- langchain_dev_utils-1.2.12/PKG-INFO +0 -345
- langchain_dev_utils-1.2.12/README.md +0 -328
- langchain_dev_utils-1.2.12/README_cn.md +0 -328
- langchain_dev_utils-1.2.12/src/langchain_dev_utils/__init__.py +0 -1
- langchain_dev_utils-1.2.12/tests/test_chat_models.py +0 -59
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/.gitignore +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/.python-version +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/.vscode/settings.json +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/LICENSE +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/_utils.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/agents/__init__.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/agents/factory.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/agents/file_system.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/agents/middleware/__init__.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/agents/middleware/format_prompt.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/agents/middleware/model_fallback.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/agents/middleware/model_router.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/agents/middleware/plan.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/agents/middleware/summarization.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/agents/middleware/tool_call_repair.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/agents/middleware/tool_emulator.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/agents/middleware/tool_selection.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/agents/plan.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/agents/wrap.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/chat_models/__init__.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/chat_models/adapters/__init__.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/chat_models/types.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/embeddings/__init__.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/embeddings/base.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/message_convert/__init__.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/message_convert/content.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/message_convert/format.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/pipeline/__init__.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/pipeline/parallel.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/pipeline/sequential.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/pipeline/types.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/py.typed +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/tool_calling/__init__.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/tool_calling/human_in_the_loop.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/src/langchain_dev_utils/tool_calling/utils.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/tests/__init__.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/tests/test_agent.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/tests/test_human_in_the_loop.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/tests/test_load_embbeding.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/tests/test_load_model.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/tests/test_messages.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/tests/test_model_tool_emulator.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/tests/test_pipline.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/tests/test_plan_middleware.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/tests/test_router_model.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/tests/test_tool_call_repair.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/tests/test_tool_calling.py +0 -0
- {langchain_dev_utils-1.2.12 → langchain_dev_utils-1.2.14}/tests/test_wrap_agent.py +0 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: langchain-dev-utils
|
|
3
|
+
Version: 1.2.14
|
|
4
|
+
Summary: A practical utility library for LangChain and LangGraph development
|
|
5
|
+
Project-URL: Source Code, https://github.com/TBice123123/langchain-dev-utils
|
|
6
|
+
Project-URL: repository, https://github.com/TBice123123/langchain-dev-utils
|
|
7
|
+
Project-URL: documentation, https://tbice123123.github.io/langchain-dev-utils
|
|
8
|
+
Author-email: tiebingice <tiebingice123@outlook.com>
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Python: >=3.11
|
|
11
|
+
Requires-Dist: langchain>=1.1.0
|
|
12
|
+
Requires-Dist: langgraph>=1.0.0
|
|
13
|
+
Provides-Extra: standard
|
|
14
|
+
Requires-Dist: json-repair>=0.53.1; extra == 'standard'
|
|
15
|
+
Requires-Dist: langchain-openai; extra == 'standard'
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# 🦜️🧰 langchain-dev-utils
|
|
19
|
+
|
|
20
|
+
<p align="center">
|
|
21
|
+
<em>🚀 High-efficiency toolkit designed for LangChain and LangGraph developers</em>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
<p align="center">
|
|
25
|
+
📚 <a href="https://tbice123123.github.io/langchain-dev-utils/">English</a> •
|
|
26
|
+
<a href="https://tbice123123.github.io/langchain-dev-utils/zh/">中文</a>
|
|
27
|
+
</p>
|
|
28
|
+
|
|
29
|
+
[](https://pypi.org/project/langchain-dev-utils/)
|
|
30
|
+
[](https://opensource.org/licenses/MIT)
|
|
31
|
+
[](https://www.python.org/downloads)
|
|
32
|
+
[](https://pepy.tech/project/langchain-dev-utils)
|
|
33
|
+
[](https://tbice123123.github.io/langchain-dev-utils)
|
|
34
|
+
|
|
35
|
+
> This is the English version. For the Chinese version, please visit [中文版本](https://github.com/TBice123123/langchain-dev-utils/blob/master/README_cn.md)
|
|
36
|
+
|
|
37
|
+
## ✨ Why choose langchain-dev-utils?
|
|
38
|
+
|
|
39
|
+
Tired of writing repetitive code in LangChain development? `langchain-dev-utils` is the solution you need! This lightweight yet powerful toolkit is designed to enhance the development experience of LangChain and LangGraph, helping you:
|
|
40
|
+
|
|
41
|
+
- ⚡ **Boost development efficiency** - Reduce boilerplate code, allowing you to focus on core functionality
|
|
42
|
+
- 🧩 **Simplify complex workflows** - Easily manage multi-model, multi-tool, and multi-agent applications
|
|
43
|
+
- 🔧 **Enhance code quality** - Improve consistency and readability, reducing maintenance costs
|
|
44
|
+
- 🎯 **Accelerate prototype development** - Quickly implement ideas, iterate and validate faster
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
## 🎯 Core Features
|
|
48
|
+
|
|
49
|
+
- **🔌 Unified model management** - Specify model providers through strings, easily switch and combine different models
|
|
50
|
+
- **💬 Flexible message handling** - Support for chain-of-thought concatenation, streaming processing, and message formatting
|
|
51
|
+
- **🛠️ Powerful tool calling** - Built-in tool call detection, parameter parsing, and human review functionality
|
|
52
|
+
- **🤖 Efficient Agent development** - Simplify agent creation process, expand more common middleware
|
|
53
|
+
- **📊 Flexible state graph composition** - Support for serial and parallel composition of multiple StateGraphs
|
|
54
|
+
|
|
55
|
+
## ⚡ Quick Start
|
|
56
|
+
|
|
57
|
+
1. Install `langchain-dev-utils`:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install -U langchain[openai] langchain-dev-utils
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
2. Start using:
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from langchain.tools import tool
|
|
67
|
+
from langchain_core.messages import HumanMessage
|
|
68
|
+
from langchain_dev_utils.chat_models import register_model_provider, load_chat_model
|
|
69
|
+
from langchain_dev_utils.agents import create_agent
|
|
70
|
+
|
|
71
|
+
# Register model provider
|
|
72
|
+
register_model_provider("vllm", "openai-compatible", "http://localhost:8000/v1")
|
|
73
|
+
|
|
74
|
+
@tool
|
|
75
|
+
def get_current_weather(location: str) -> str:
|
|
76
|
+
"""Get the current weather for the specified location"""
|
|
77
|
+
return f"25 degrees, {location}"
|
|
78
|
+
|
|
79
|
+
# Dynamically load model using string
|
|
80
|
+
model = load_chat_model("vllm:qwen3-4b")
|
|
81
|
+
response = model.invoke("Hello")
|
|
82
|
+
print(response)
|
|
83
|
+
|
|
84
|
+
# Create agent
|
|
85
|
+
agent = create_agent("vllm:qwen3-4b", tools=[get_current_weather])
|
|
86
|
+
response = agent.invoke({"messages": [HumanMessage(content="What's the weather like in New York today?")]})
|
|
87
|
+
print(response)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**For more features of this library, please visit the [full documentation](https://tbice123123.github.io/langchain-dev-utils/)**
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
## 🛠️ GitHub Repository
|
|
94
|
+
|
|
95
|
+
Visit the [GitHub repository](https://github.com/TBice123123/langchain-dev-utils) to view the source code and report issues.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
<div align="center">
|
|
100
|
+
<p>Developed with ❤️ and ☕</p>
|
|
101
|
+
<p>If this project helps you, please give us a ⭐️</p>
|
|
102
|
+
</div>
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# 🦜️🧰 langchain-dev-utils
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<em>🚀 High-efficiency toolkit designed for LangChain and LangGraph developers</em>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
📚 <a href="https://tbice123123.github.io/langchain-dev-utils/">English</a> •
|
|
9
|
+
<a href="https://tbice123123.github.io/langchain-dev-utils/zh/">中文</a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
[](https://pypi.org/project/langchain-dev-utils/)
|
|
13
|
+
[](https://opensource.org/licenses/MIT)
|
|
14
|
+
[](https://www.python.org/downloads)
|
|
15
|
+
[](https://pepy.tech/project/langchain-dev-utils)
|
|
16
|
+
[](https://tbice123123.github.io/langchain-dev-utils)
|
|
17
|
+
|
|
18
|
+
> This is the English version. For the Chinese version, please visit [中文版本](https://github.com/TBice123123/langchain-dev-utils/blob/master/README_cn.md)
|
|
19
|
+
|
|
20
|
+
## ✨ Why choose langchain-dev-utils?
|
|
21
|
+
|
|
22
|
+
Tired of writing repetitive code in LangChain development? `langchain-dev-utils` is the solution you need! This lightweight yet powerful toolkit is designed to enhance the development experience of LangChain and LangGraph, helping you:
|
|
23
|
+
|
|
24
|
+
- ⚡ **Boost development efficiency** - Reduce boilerplate code, allowing you to focus on core functionality
|
|
25
|
+
- 🧩 **Simplify complex workflows** - Easily manage multi-model, multi-tool, and multi-agent applications
|
|
26
|
+
- 🔧 **Enhance code quality** - Improve consistency and readability, reducing maintenance costs
|
|
27
|
+
- 🎯 **Accelerate prototype development** - Quickly implement ideas, iterate and validate faster
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
## 🎯 Core Features
|
|
31
|
+
|
|
32
|
+
- **🔌 Unified model management** - Specify model providers through strings, easily switch and combine different models
|
|
33
|
+
- **💬 Flexible message handling** - Support for chain-of-thought concatenation, streaming processing, and message formatting
|
|
34
|
+
- **🛠️ Powerful tool calling** - Built-in tool call detection, parameter parsing, and human review functionality
|
|
35
|
+
- **🤖 Efficient Agent development** - Simplify agent creation process, expand more common middleware
|
|
36
|
+
- **📊 Flexible state graph composition** - Support for serial and parallel composition of multiple StateGraphs
|
|
37
|
+
|
|
38
|
+
## ⚡ Quick Start
|
|
39
|
+
|
|
40
|
+
1. Install `langchain-dev-utils`:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install -U langchain[openai] langchain-dev-utils
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
2. Start using:
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from langchain.tools import tool
|
|
50
|
+
from langchain_core.messages import HumanMessage
|
|
51
|
+
from langchain_dev_utils.chat_models import register_model_provider, load_chat_model
|
|
52
|
+
from langchain_dev_utils.agents import create_agent
|
|
53
|
+
|
|
54
|
+
# Register model provider
|
|
55
|
+
register_model_provider("vllm", "openai-compatible", "http://localhost:8000/v1")
|
|
56
|
+
|
|
57
|
+
@tool
|
|
58
|
+
def get_current_weather(location: str) -> str:
|
|
59
|
+
"""Get the current weather for the specified location"""
|
|
60
|
+
return f"25 degrees, {location}"
|
|
61
|
+
|
|
62
|
+
# Dynamically load model using string
|
|
63
|
+
model = load_chat_model("vllm:qwen3-4b")
|
|
64
|
+
response = model.invoke("Hello")
|
|
65
|
+
print(response)
|
|
66
|
+
|
|
67
|
+
# Create agent
|
|
68
|
+
agent = create_agent("vllm:qwen3-4b", tools=[get_current_weather])
|
|
69
|
+
response = agent.invoke({"messages": [HumanMessage(content="What's the weather like in New York today?")]})
|
|
70
|
+
print(response)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**For more features of this library, please visit the [full documentation](https://tbice123123.github.io/langchain-dev-utils/)**
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
## 🛠️ GitHub Repository
|
|
77
|
+
|
|
78
|
+
Visit the [GitHub repository](https://github.com/TBice123123/langchain-dev-utils) to view the source code and report issues.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
<div align="center">
|
|
83
|
+
<p>Developed with ❤️ and ☕</p>
|
|
84
|
+
<p>If this project helps you, please give us a ⭐️</p>
|
|
85
|
+
</div>
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# 🦜️🧰 langchain-dev-utils
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<em>🚀 专为 LangChain 和 LangGraph 开发者打造的高效工具库</em>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
📚 <a href="https://tbice123123.github.io/langchain-dev-utils/">English</a> •
|
|
9
|
+
<a href="https://tbice123123.github.io/langchain-dev-utils/zh/">中文</a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
[](https://pypi.org/project/langchain-dev-utils/)
|
|
13
|
+
[](https://opensource.org/licenses/MIT)
|
|
14
|
+
[](https://www.python.org/downloads)
|
|
15
|
+
[](https://pepy.tech/project/langchain-dev-utils)
|
|
16
|
+
[](https://tbice123123.github.io/langchain-dev-utils/zh/)
|
|
17
|
+
|
|
18
|
+
> 当前为中文版,英文版请访问[English Version](https://github.com/TBice123123/langchain-dev-utils/blob/master/README.md)
|
|
19
|
+
|
|
20
|
+
## ✨ 为什么选择 langchain-dev-utils?
|
|
21
|
+
|
|
22
|
+
厌倦了在 LangChain 开发中编写重复代码?`langchain-dev-utils` 正是您需要的解决方案!这个轻量但功能强大的工具库专为提升 LangChain 和 LangGraph 开发体验而设计,帮助您:
|
|
23
|
+
|
|
24
|
+
- ⚡ **提升开发效率** - 减少样板代码,让您专注于核心功能
|
|
25
|
+
- 🧩 **简化复杂流程** - 轻松管理多模型、多工具和多智能体应用
|
|
26
|
+
- 🔧 **增强代码质量** - 提高一致性和可读性,减少维护成本
|
|
27
|
+
- 🎯 **加速原型开发** - 快速实现想法,更快迭代验证
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
## 🎯 核心功能
|
|
31
|
+
|
|
32
|
+
- **🔌 统一的模型管理** - 通过字符串指定模型提供商,轻松切换和组合不同模型
|
|
33
|
+
- **💬 灵活的消息处理** - 支持思维链拼接、流式处理和消息格式化
|
|
34
|
+
- **🛠️ 强大的工具调用** - 内置工具调用检测、参数解析和人工审核功能
|
|
35
|
+
- **🤖 高效的 Agent 开发** - 简化智能体创建流程,扩充更多的常用中间件
|
|
36
|
+
- **📊 灵活的状态图组合** - 支持串行和并行方式组合多个 StateGraph
|
|
37
|
+
|
|
38
|
+
## ⚡ 快速开始
|
|
39
|
+
|
|
40
|
+
1. 安装 `langchain-dev-utils`:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install -U langchain[openai] langchain-dev-utils
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
2. 开始使用:
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from langchain.tools import tool
|
|
50
|
+
from langchain_core.messages import HumanMessage
|
|
51
|
+
from langchain_dev_utils.chat_models import register_model_provider, load_chat_model
|
|
52
|
+
from langchain_dev_utils.agents import create_agent
|
|
53
|
+
|
|
54
|
+
# 注册模型提供商
|
|
55
|
+
register_model_provider("vllm", "openai-compatible", "http://localhost:8000/v1")
|
|
56
|
+
|
|
57
|
+
@tool
|
|
58
|
+
def get_current_weather(location: str) -> str:
|
|
59
|
+
"""获取指定地点的当前天气"""
|
|
60
|
+
return f"25度,{location}"
|
|
61
|
+
|
|
62
|
+
# 使用字符串动态加载模型
|
|
63
|
+
model = load_chat_model("vllm:qwen3-4b")
|
|
64
|
+
response = model.invoke("你好")
|
|
65
|
+
print(response)
|
|
66
|
+
|
|
67
|
+
# 创建智能体
|
|
68
|
+
agent = create_agent("vllm:qwen3-4b", tools=[get_current_weather])
|
|
69
|
+
response = agent.invoke({"messages": [HumanMessage(content="今天纽约的天气如何?")]})
|
|
70
|
+
print(response)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**获取更多的本库功能,请访问[完整文档](https://tbice123123.github.io/langchain-dev-utils/zh/)**
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
## 🛠️ GitHub 仓库
|
|
77
|
+
|
|
78
|
+
访问 [GitHub 仓库](https://github.com/TBice123123/langchain-dev-utils) 查看源代码和问题。
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
<div align="center">
|
|
84
|
+
<p>由 ❤️ 和 ☕ 驱动开发</p>
|
|
85
|
+
<p>如果这个项目对您有帮助,请给我们一个 ⭐️</p>
|
|
86
|
+
</div>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "langchain-dev-utils"
|
|
3
|
-
version = "1.2.
|
|
3
|
+
version = "1.2.14"
|
|
4
4
|
description = "A practical utility library for LangChain and LangGraph development"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [{ name = "tiebingice", email = "tiebingice123@outlook.com" }]
|
|
@@ -10,7 +10,7 @@ dependencies = ["langchain>=1.1.0", "langgraph>=1.0.0"]
|
|
|
10
10
|
[project.urls]
|
|
11
11
|
"Source Code" = "https://github.com/TBice123123/langchain-dev-utils"
|
|
12
12
|
repository = "https://github.com/TBice123123/langchain-dev-utils"
|
|
13
|
-
documentation = "https://tbice123123.github.io/langchain-dev-utils
|
|
13
|
+
documentation = "https://tbice123123.github.io/langchain-dev-utils"
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
[project.optional-dependencies]
|
|
@@ -20,9 +20,6 @@ standard = ["json-repair>=0.53.1", "langchain-openai"]
|
|
|
20
20
|
requires = ["hatchling"]
|
|
21
21
|
build-backend = "hatchling.build"
|
|
22
22
|
|
|
23
|
-
[tool.uv.build-backend]
|
|
24
|
-
source-exclude = ["/data", "/docs", "mkdocs.yml"]
|
|
25
|
-
|
|
26
23
|
[tool.hatch.build]
|
|
27
24
|
exclude = ["/data", "/docs", "mkdocs.yml"]
|
|
28
25
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.2.14"
|
|
@@ -20,7 +20,13 @@ from langchain_core.callbacks import (
|
|
|
20
20
|
CallbackManagerForLLMRun,
|
|
21
21
|
)
|
|
22
22
|
from langchain_core.language_models import LangSmithParams, LanguageModelInput
|
|
23
|
-
from langchain_core.messages import
|
|
23
|
+
from langchain_core.messages import (
|
|
24
|
+
AIMessage,
|
|
25
|
+
AIMessageChunk,
|
|
26
|
+
BaseMessage,
|
|
27
|
+
HumanMessage,
|
|
28
|
+
ToolMessage,
|
|
29
|
+
)
|
|
24
30
|
from langchain_core.outputs import ChatGenerationChunk, ChatResult
|
|
25
31
|
from langchain_core.runnables import Runnable
|
|
26
32
|
from langchain_core.tools import BaseTool
|
|
@@ -63,6 +69,58 @@ def _get_last_human_message_index(messages: list[BaseMessage]) -> int:
|
|
|
63
69
|
)
|
|
64
70
|
|
|
65
71
|
|
|
72
|
+
def _transform_video_block(block: dict[str, Any]) -> dict:
|
|
73
|
+
"""Transform video block to video_url block."""
|
|
74
|
+
if "url" in block:
|
|
75
|
+
return {
|
|
76
|
+
"type": "video_url",
|
|
77
|
+
"video_url": {
|
|
78
|
+
"url": block["url"],
|
|
79
|
+
},
|
|
80
|
+
}
|
|
81
|
+
if "base64" in block or block.get("source_type") == "base64":
|
|
82
|
+
if "mime_type" not in block:
|
|
83
|
+
error_message = "mime_type key is required for base64 data."
|
|
84
|
+
raise ValueError(error_message)
|
|
85
|
+
mime_type = block["mime_type"]
|
|
86
|
+
base64_data = block["data"] if "data" in block else block["base64"]
|
|
87
|
+
return {
|
|
88
|
+
"type": "video_url",
|
|
89
|
+
"video_url": {
|
|
90
|
+
"url": f"data:{mime_type};base64,{base64_data}",
|
|
91
|
+
},
|
|
92
|
+
}
|
|
93
|
+
error_message = "Unsupported source type. Only 'url' and 'base64' are supported."
|
|
94
|
+
raise ValueError(error_message)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _process_video_input(message: BaseMessage):
|
|
98
|
+
"""
|
|
99
|
+
Process BaseMessage with video input.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
message (BaseMessage): The HumanMessage instance to process.
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
None: The method modifies the message in-place.
|
|
106
|
+
"""
|
|
107
|
+
if not message.content:
|
|
108
|
+
return message
|
|
109
|
+
content = message.content
|
|
110
|
+
|
|
111
|
+
if not isinstance(content, list):
|
|
112
|
+
return message
|
|
113
|
+
|
|
114
|
+
formatted_content = []
|
|
115
|
+
for block in content:
|
|
116
|
+
if isinstance(block, dict) and block.get("type") == "video":
|
|
117
|
+
formatted_content.append(_transform_video_block(block))
|
|
118
|
+
else:
|
|
119
|
+
formatted_content.append(block)
|
|
120
|
+
message = message.model_copy(update={"content": formatted_content})
|
|
121
|
+
return message
|
|
122
|
+
|
|
123
|
+
|
|
66
124
|
class _BaseChatOpenAICompatible(BaseChatOpenAI):
|
|
67
125
|
"""
|
|
68
126
|
Base template class for OpenAI-compatible chat model implementations.
|
|
@@ -183,6 +241,10 @@ class _BaseChatOpenAICompatible(BaseChatOpenAI):
|
|
|
183
241
|
)
|
|
184
242
|
payload_messages.append(msg_dict)
|
|
185
243
|
else:
|
|
244
|
+
if (
|
|
245
|
+
isinstance(m, HumanMessage) or isinstance(m, ToolMessage)
|
|
246
|
+
) and isinstance(m.content, list):
|
|
247
|
+
m = _process_video_input(m)
|
|
186
248
|
payload_messages.append(_convert_message_to_dict(m))
|
|
187
249
|
|
|
188
250
|
payload["messages"] = payload_messages
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
from typing import Any, cast
|
|
3
|
+
|
|
4
|
+
import httpx
|
|
5
|
+
import pytest
|
|
6
|
+
from langchain_core.language_models import BaseChatModel
|
|
7
|
+
from langchain_core.messages import AIMessage, HumanMessage, ToolMessage
|
|
8
|
+
from langchain_tests.integration_tests.chat_models import ChatModelIntegrationTests
|
|
9
|
+
|
|
10
|
+
from langchain_dev_utils.chat_models.base import load_chat_model
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TestStandard(ChatModelIntegrationTests):
|
|
14
|
+
@pytest.fixture
|
|
15
|
+
def model(self, request: Any) -> BaseChatModel:
|
|
16
|
+
"""Model fixture."""
|
|
17
|
+
extra_init_params = getattr(request, "param", None) or {}
|
|
18
|
+
if extra_init_params.get("output_version") == "v1":
|
|
19
|
+
pytest.skip("Output version v1 is not supported")
|
|
20
|
+
return self.chat_model_class(
|
|
21
|
+
**{
|
|
22
|
+
**self.standard_chat_model_params,
|
|
23
|
+
**self.chat_model_params,
|
|
24
|
+
**extra_init_params,
|
|
25
|
+
},
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def chat_model_class(self) -> type[BaseChatModel]:
|
|
30
|
+
return cast("type[BaseChatModel]", load_chat_model)
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def chat_model_params(self) -> dict:
|
|
34
|
+
return {
|
|
35
|
+
"model": "zai:glm-4.5",
|
|
36
|
+
"extra_body": {
|
|
37
|
+
"thinking": {
|
|
38
|
+
"type": "disabled",
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def has_tool_calling(self) -> bool:
|
|
45
|
+
return True
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def has_structured_output(self) -> bool:
|
|
49
|
+
return True
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def has_tool_choice(self) -> bool:
|
|
53
|
+
return False
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def supports_image_tool_message(self) -> bool:
|
|
57
|
+
return False
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def supports_json_mode(self) -> bool:
|
|
61
|
+
"""(bool) whether the chat model supports JSON mode."""
|
|
62
|
+
return False
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class TestImageProcessing:
|
|
66
|
+
@pytest.fixture(autouse=True)
|
|
67
|
+
def setup(self) -> None:
|
|
68
|
+
self.model = load_chat_model("zai:glm-4.6v")
|
|
69
|
+
self.image_url = "https://cloudcovert-1305175928.cos.ap-guangzhou.myqcloud.com/%E5%9B%BE%E7%89%87grounding.PNG"
|
|
70
|
+
self.image_data = base64.b64encode(httpx.get(self.image_url).content).decode(
|
|
71
|
+
"utf-8"
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
def test_image_url_format(self) -> None:
|
|
75
|
+
message = HumanMessage(
|
|
76
|
+
content=[
|
|
77
|
+
{"type": "text", "text": "Give a concise description of this image."},
|
|
78
|
+
{
|
|
79
|
+
"type": "image_url",
|
|
80
|
+
"image_url": {"url": f"data:image/png;base64,{self.image_data}"},
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
)
|
|
84
|
+
_ = self.model.invoke([message])
|
|
85
|
+
|
|
86
|
+
def test_image_base64_format(self) -> None:
|
|
87
|
+
message = HumanMessage(
|
|
88
|
+
content=[
|
|
89
|
+
{"type": "text", "text": "Give a concise description of this image."},
|
|
90
|
+
{
|
|
91
|
+
"type": "image",
|
|
92
|
+
"base64": self.image_data,
|
|
93
|
+
"mime_type": "image/png",
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
)
|
|
97
|
+
_ = self.model.invoke([message])
|
|
98
|
+
|
|
99
|
+
def test_image_url_direct_format(self) -> None:
|
|
100
|
+
message = HumanMessage(
|
|
101
|
+
content=[
|
|
102
|
+
{
|
|
103
|
+
"type": "text",
|
|
104
|
+
"text": "Give a concise description of this image. answer in Chinese",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"type": "image",
|
|
108
|
+
"url": self.image_url,
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
)
|
|
112
|
+
_ = self.model.invoke([message])
|
|
113
|
+
|
|
114
|
+
def test_oai_format_tool_message(self) -> None:
|
|
115
|
+
oai_format_message = ToolMessage(
|
|
116
|
+
content=[
|
|
117
|
+
{
|
|
118
|
+
"type": "image_url",
|
|
119
|
+
"image_url": {"url": f"data:image/png;base64,{self.image_data}"},
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
tool_call_id="1",
|
|
123
|
+
name="random_image",
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
messages = [
|
|
127
|
+
HumanMessage(
|
|
128
|
+
"get a random diagram using the tool and give it a concise description,answer in Chinese"
|
|
129
|
+
),
|
|
130
|
+
AIMessage(
|
|
131
|
+
[],
|
|
132
|
+
tool_calls=[
|
|
133
|
+
{
|
|
134
|
+
"type": "tool_call",
|
|
135
|
+
"id": "1",
|
|
136
|
+
"name": "random_image",
|
|
137
|
+
"args": {},
|
|
138
|
+
}
|
|
139
|
+
],
|
|
140
|
+
),
|
|
141
|
+
oai_format_message,
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
def random_image() -> str:
|
|
145
|
+
"""Return a random image."""
|
|
146
|
+
return ""
|
|
147
|
+
|
|
148
|
+
_ = self.model.bind_tools([random_image]).invoke(messages)
|
|
149
|
+
|
|
150
|
+
def test_standard_format_tool_message(self) -> None:
|
|
151
|
+
standard_format_message = ToolMessage(
|
|
152
|
+
content=[
|
|
153
|
+
{
|
|
154
|
+
"type": "image",
|
|
155
|
+
"base64": self.image_data,
|
|
156
|
+
"mime_type": "image/png",
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
tool_call_id="1",
|
|
160
|
+
name="random_image",
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
messages = [
|
|
164
|
+
HumanMessage(
|
|
165
|
+
"get a random diagram using the tool and give it a concise description,answer in Chinese"
|
|
166
|
+
),
|
|
167
|
+
AIMessage(
|
|
168
|
+
[],
|
|
169
|
+
tool_calls=[
|
|
170
|
+
{
|
|
171
|
+
"type": "tool_call",
|
|
172
|
+
"id": "1",
|
|
173
|
+
"name": "random_image",
|
|
174
|
+
"args": {},
|
|
175
|
+
}
|
|
176
|
+
],
|
|
177
|
+
),
|
|
178
|
+
standard_format_message,
|
|
179
|
+
]
|
|
180
|
+
|
|
181
|
+
def random_image() -> str:
|
|
182
|
+
"""Return a random image."""
|
|
183
|
+
return ""
|
|
184
|
+
|
|
185
|
+
_ = self.model.bind_tools([random_image]).invoke(messages)
|