langchain-dev-utils 1.4.0__tar.gz → 1.4.2__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.4.0 → langchain_dev_utils-1.4.2}/.vscode/settings.json +2 -1
- langchain_dev_utils-1.4.2/AGENTS.md +173 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/PKG-INFO +2 -1
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/pyproject.toml +16 -4
- langchain_dev_utils-1.4.2/src/langchain_dev_utils/__init__.py +1 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/_utils.py +41 -2
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/agents/middleware/__init__.py +5 -3
- langchain_dev_utils-1.4.2/src/langchain_dev_utils/agents/middleware/format_prompt.py +156 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/agents/middleware/handoffs.py +18 -9
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/agents/middleware/model_router.py +9 -1
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/agents/middleware/tool_call_repair.py +3 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/agents/wrap.py +1 -1
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/chat_models/adapters/openai_compatible.py +7 -3
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/tests/test_embedding.py +4 -4
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/tests/test_handoffs_middleware.py +1 -7
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/tests/test_load_embbeding.py +0 -1
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/tests/utils/register.py +0 -4
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/uv.lock +79 -1
- langchain_dev_utils-1.4.0/src/langchain_dev_utils/__init__.py +0 -1
- langchain_dev_utils-1.4.0/src/langchain_dev_utils/agents/middleware/format_prompt.py +0 -66
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/.gitignore +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/.python-version +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/LICENSE +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/README.md +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/README_cn.md +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/agents/__init__.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/agents/factory.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/agents/middleware/model_fallback.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/agents/middleware/plan.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/agents/middleware/summarization.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/agents/middleware/tool_emulator.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/agents/middleware/tool_selection.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/chat_models/__init__.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/chat_models/adapters/__init__.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/chat_models/adapters/create_utils.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/chat_models/adapters/register_profiles.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/chat_models/base.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/chat_models/types.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/embeddings/__init__.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/embeddings/adapters/__init__.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/embeddings/adapters/create_utils.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/embeddings/adapters/openai_compatible.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/embeddings/base.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/graph/__init__.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/graph/parallel.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/graph/sequential.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/graph/types.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/message_convert/__init__.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/message_convert/content.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/message_convert/format.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/pipeline/__init__.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/pipeline/parallel.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/pipeline/sequential.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/pipeline/types.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/py.typed +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/tool_calling/__init__.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/tool_calling/human_in_the_loop.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/tool_calling/utils.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/tests/__init__.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/tests/test_agent.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/tests/test_chat_models.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/tests/test_graph.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/tests/test_human_in_the_loop.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/tests/test_load_model.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/tests/test_messages.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/tests/test_model_tool_emulator.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/tests/test_plan_middleware.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/tests/test_router_model.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/tests/test_tool_call_repair.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/tests/test_tool_calling.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/tests/test_wrap_agent.py +0 -0
- {langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/tests/utils/__init__.py +0 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Agentic Coding Guidelines for langchain-dev-utils
|
|
2
|
+
|
|
3
|
+
This file provides guidelines for AI agents working in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
A Python utility library for LangChain and LangGraph development. Uses hatchling build system, uv for package management, ruff for linting, and pytest for testing.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Build/Lint/Test Commands
|
|
12
|
+
|
|
13
|
+
### Package Management (uv)
|
|
14
|
+
```bash
|
|
15
|
+
# Install dependencies
|
|
16
|
+
uv sync
|
|
17
|
+
|
|
18
|
+
# Install with optional dependencies
|
|
19
|
+
uv sync --extra standard
|
|
20
|
+
|
|
21
|
+
# Install dev dependencies
|
|
22
|
+
uv sync --group dev
|
|
23
|
+
|
|
24
|
+
# Install test dependencies
|
|
25
|
+
uv sync --group tests
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Linting & Formatting (ruff)
|
|
29
|
+
```bash
|
|
30
|
+
# Check linting
|
|
31
|
+
uv run ruff check .
|
|
32
|
+
|
|
33
|
+
# Check specific file
|
|
34
|
+
uv run ruff check src/langchain_dev_utils/path/to/file.py
|
|
35
|
+
|
|
36
|
+
# Fix auto-fixable issues
|
|
37
|
+
uv run ruff check --fix .
|
|
38
|
+
|
|
39
|
+
# Format code
|
|
40
|
+
uv run ruff format .
|
|
41
|
+
|
|
42
|
+
# Format specific file
|
|
43
|
+
uv run ruff format src/langchain_dev_utils/path/to/file.py
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Testing (pytest)
|
|
47
|
+
```bash
|
|
48
|
+
# Run all tests
|
|
49
|
+
uv run pytest
|
|
50
|
+
|
|
51
|
+
# Run with verbose output
|
|
52
|
+
uv run pytest -v
|
|
53
|
+
|
|
54
|
+
# Run specific test file
|
|
55
|
+
uv run pytest tests/test_agent.py
|
|
56
|
+
|
|
57
|
+
# Run specific test function
|
|
58
|
+
uv run pytest tests/test_agent.py::test_prebuilt_agent
|
|
59
|
+
|
|
60
|
+
# Run specific test class
|
|
61
|
+
uv run pytest tests/test_chat_models.py::TestImageProcessing
|
|
62
|
+
|
|
63
|
+
# Run with asyncio support (automatically configured)
|
|
64
|
+
uv run pytest -s
|
|
65
|
+
|
|
66
|
+
# Run tests matching pattern
|
|
67
|
+
uv run pytest -k "test_load"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Build
|
|
71
|
+
```bash
|
|
72
|
+
# Build package
|
|
73
|
+
uv build
|
|
74
|
+
|
|
75
|
+
# Build wheel only
|
|
76
|
+
uv build --wheel
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Code Style Guidelines
|
|
82
|
+
|
|
83
|
+
### Imports
|
|
84
|
+
- Use absolute imports for external packages
|
|
85
|
+
- Use relative imports within the package (e.g., `from ..chat_models import ...`)
|
|
86
|
+
- Group imports: stdlib → third-party → local
|
|
87
|
+
- Ruff handles import sorting automatically
|
|
88
|
+
|
|
89
|
+
### Type Hints
|
|
90
|
+
- Use type hints for all function parameters and return types
|
|
91
|
+
- Use `Optional[Type]` or `Type | None` for nullable types (both acceptable)
|
|
92
|
+
- Use `Any` sparingly and only when necessary
|
|
93
|
+
- Use `Sequence`, `Mapping` for generic collections
|
|
94
|
+
- Use generics with TypeVars where appropriate
|
|
95
|
+
|
|
96
|
+
### Naming Conventions
|
|
97
|
+
- `snake_case` for functions, methods, variables
|
|
98
|
+
- `PascalCase` for classes
|
|
99
|
+
- `UPPER_CASE` for constants
|
|
100
|
+
- `_leading_underscore` for private/internal functions
|
|
101
|
+
- Leading double underscore for name mangling when needed
|
|
102
|
+
|
|
103
|
+
### Docstrings
|
|
104
|
+
- Use Google-style docstrings
|
|
105
|
+
- Include Args, Returns, Raises sections for public functions
|
|
106
|
+
- Include Examples section for complex functions
|
|
107
|
+
- Keep docstrings under 100 characters per line when possible
|
|
108
|
+
|
|
109
|
+
### Code Structure
|
|
110
|
+
- Maximum line length: 88 characters (ruff enforces, E501 ignored)
|
|
111
|
+
- Use trailing commas in multi-line structures
|
|
112
|
+
- Two blank lines between top-level functions/classes
|
|
113
|
+
- One blank line between methods
|
|
114
|
+
|
|
115
|
+
### Error Handling
|
|
116
|
+
- Use specific exception types, not bare `except:`
|
|
117
|
+
- Provide descriptive error messages with f-strings
|
|
118
|
+
- Use `raise ValueError(msg)` pattern with descriptive messages
|
|
119
|
+
- Avoid bare `raise` statements
|
|
120
|
+
|
|
121
|
+
### Async Code
|
|
122
|
+
- Use `pytest.mark.asyncio` for async test functions
|
|
123
|
+
- Use `async`/`await` consistently
|
|
124
|
+
- Prefer `asyncio` primitives from standard library
|
|
125
|
+
|
|
126
|
+
### Ruff Configuration
|
|
127
|
+
- Enabled rules: E, F, I, PGH003, T201
|
|
128
|
+
- Import sorting (I) is enforced
|
|
129
|
+
- No print statements in production code (T201)
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Testing Guidelines
|
|
134
|
+
|
|
135
|
+
- Tests live in `tests/` directory
|
|
136
|
+
- Test files named `test_*.py`
|
|
137
|
+
- Test functions named `test_*`
|
|
138
|
+
- Use pytest fixtures for setup/teardown
|
|
139
|
+
- Use `pytest.mark.asyncio` for async tests
|
|
140
|
+
- Mock external API calls in unit tests
|
|
141
|
+
- Integration tests use actual APIs (marked implicitly by test names)
|
|
142
|
+
- Tests use `langchain-tests` for standard integration test suites
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Project Structure
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
langchain-dev-utils/
|
|
150
|
+
├── src/langchain_dev_utils/ # Source code
|
|
151
|
+
│ ├── agents/ # Agent utilities
|
|
152
|
+
│ ├── chat_models/ # Chat model utilities
|
|
153
|
+
│ ├── embeddings/ # Embedding utilities
|
|
154
|
+
│ ├── graph/ # Graph utilities
|
|
155
|
+
│ ├── message_convert/ # Message conversion
|
|
156
|
+
│ ├── pipeline/ # Pipeline utilities (deprecated since v1.4.0, will be removed in v1.5.0)
|
|
157
|
+
│ └── tool_calling/ # Tool calling utilities
|
|
158
|
+
├── tests/ # Test files
|
|
159
|
+
├── docs/ # Documentation
|
|
160
|
+
├── pyproject.toml # Project configuration
|
|
161
|
+
└── uv.lock # Dependency lock file
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Dependencies
|
|
167
|
+
|
|
168
|
+
- Core: langchain, langchain-core, langgraph
|
|
169
|
+
- Optional: jinja2, json-repair, langchain-openai
|
|
170
|
+
- Dev: ruff, dashscope, langchain-model-profiles
|
|
171
|
+
- Test: python-dotenv, langchain-tests, langchain-deepseek, langchain-qwq, langchain-ollama, langchain-community
|
|
172
|
+
|
|
173
|
+
Python version: >=3.11
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: langchain-dev-utils
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.2
|
|
4
4
|
Summary: A practical utility library for LangChain and LangGraph development
|
|
5
5
|
Project-URL: Source Code, https://github.com/TBice123123/langchain-dev-utils
|
|
6
6
|
Project-URL: repository, https://github.com/TBice123123/langchain-dev-utils
|
|
@@ -12,6 +12,7 @@ Requires-Dist: langchain-core>=1.2.5
|
|
|
12
12
|
Requires-Dist: langchain>=1.2.0
|
|
13
13
|
Requires-Dist: langgraph>=1.0.0
|
|
14
14
|
Provides-Extra: standard
|
|
15
|
+
Requires-Dist: jinja2>=3.1.6; extra == 'standard'
|
|
15
16
|
Requires-Dist: json-repair>=0.53.1; extra == 'standard'
|
|
16
17
|
Requires-Dist: langchain-openai; extra == 'standard'
|
|
17
18
|
Description-Content-Type: text/markdown
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "langchain-dev-utils"
|
|
3
|
-
version = "1.4.
|
|
3
|
+
version = "1.4.2"
|
|
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" }]
|
|
7
7
|
requires-python = ">=3.11"
|
|
8
|
-
dependencies = [
|
|
8
|
+
dependencies = [
|
|
9
|
+
"langchain>=1.2.0",
|
|
10
|
+
"langchain-core>=1.2.5",
|
|
11
|
+
"langgraph>=1.0.0",
|
|
12
|
+
]
|
|
9
13
|
|
|
10
14
|
[project.urls]
|
|
11
15
|
"Source Code" = "https://github.com/TBice123123/langchain-dev-utils"
|
|
@@ -14,7 +18,11 @@ documentation = "https://tbice123123.github.io/langchain-dev-utils"
|
|
|
14
18
|
|
|
15
19
|
|
|
16
20
|
[project.optional-dependencies]
|
|
17
|
-
standard = [
|
|
21
|
+
standard = [
|
|
22
|
+
"jinja2>=3.1.6",
|
|
23
|
+
"json-repair>=0.53.1",
|
|
24
|
+
"langchain-openai",
|
|
25
|
+
]
|
|
18
26
|
|
|
19
27
|
[build-system]
|
|
20
28
|
requires = ["hatchling"]
|
|
@@ -30,7 +38,11 @@ python_files = ["test_*.py"]
|
|
|
30
38
|
python_functions = ["test_*"]
|
|
31
39
|
|
|
32
40
|
[dependency-groups]
|
|
33
|
-
dev = [
|
|
41
|
+
dev = [
|
|
42
|
+
"dashscope>=1.25.9",
|
|
43
|
+
"langchain-model-profiles>=0.0.5",
|
|
44
|
+
"ruff>=0.14.5",
|
|
45
|
+
]
|
|
34
46
|
docs = [
|
|
35
47
|
"jupyter>=1.1.1",
|
|
36
48
|
"mkdocs-material>=9.7.0",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.4.2"
|
|
@@ -1,11 +1,48 @@
|
|
|
1
1
|
from importlib import util
|
|
2
2
|
from typing import Literal, Optional, cast
|
|
3
3
|
|
|
4
|
+
from langchain_core.tools import BaseTool
|
|
4
5
|
from langgraph.graph import StateGraph
|
|
5
6
|
from langgraph.graph.state import StateNode
|
|
6
7
|
from pydantic import BaseModel
|
|
7
8
|
|
|
8
9
|
|
|
10
|
+
def _duplicate_tools(tools: list[BaseTool]) -> list[BaseTool]:
|
|
11
|
+
"""Duplicate tools with the same name.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
tools (list[BaseTool]): The list of tools.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
list[BaseTool]: The duplicated tools.
|
|
18
|
+
"""
|
|
19
|
+
tool_name_set = set()
|
|
20
|
+
duplicated_tools = []
|
|
21
|
+
for tool_obj in tools:
|
|
22
|
+
if tool_obj.name not in tool_name_set:
|
|
23
|
+
duplicated_tools.append(tool_obj)
|
|
24
|
+
tool_name_set.add(tool_obj.name)
|
|
25
|
+
return duplicated_tools
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _merge_tools(tools: list[BaseTool]) -> list[BaseTool]:
|
|
29
|
+
"""Merge tools with the same name.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
tools (list[BaseTool]): The list of tools.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
list[BaseTool]: The merged tools.
|
|
36
|
+
"""
|
|
37
|
+
tool_name_set = set()
|
|
38
|
+
merged_tools = []
|
|
39
|
+
for tool_obj in tools:
|
|
40
|
+
if tool_obj.name not in tool_name_set:
|
|
41
|
+
merged_tools.append(tool_obj)
|
|
42
|
+
tool_name_set.add(tool_obj.name)
|
|
43
|
+
return merged_tools
|
|
44
|
+
|
|
45
|
+
|
|
9
46
|
def _transform_node_to_tuple(
|
|
10
47
|
node: StateNode | tuple[str, StateNode],
|
|
11
48
|
) -> tuple[str, StateNode]:
|
|
@@ -23,13 +60,15 @@ def _transform_node_to_tuple(
|
|
|
23
60
|
|
|
24
61
|
|
|
25
62
|
def _check_pkg_install(
|
|
26
|
-
pkg: Literal["langchain_openai", "json_repair"],
|
|
63
|
+
pkg: Literal["langchain_openai", "json_repair", "jinja2"],
|
|
27
64
|
) -> None:
|
|
28
65
|
if not util.find_spec(pkg):
|
|
29
66
|
if pkg == "langchain_openai":
|
|
30
67
|
msg = "Please install langchain_dev_utils[standard],when use 'openai-compatible'"
|
|
31
|
-
|
|
68
|
+
elif pkg == "json_repair":
|
|
32
69
|
msg = "Please install langchain_dev_utils[standard] to use ToolCallRepairMiddleware."
|
|
70
|
+
else:
|
|
71
|
+
msg = "Please install langchain_dev_utils[standard] to use FormatPromptMiddleware."
|
|
33
72
|
raise ImportError(msg)
|
|
34
73
|
|
|
35
74
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
from .format_prompt import format_prompt
|
|
1
|
+
from .format_prompt import FormatPromptMiddleware, format_prompt
|
|
2
2
|
from .handoffs import HandoffAgentMiddleware
|
|
3
3
|
from .model_fallback import ModelFallbackMiddleware
|
|
4
4
|
from .model_router import ModelRouterMiddleware
|
|
5
5
|
from .plan import PlanMiddleware
|
|
6
6
|
from .summarization import SummarizationMiddleware
|
|
7
|
-
from .tool_call_repair import ToolCallRepairMiddleware
|
|
7
|
+
from .tool_call_repair import ToolCallRepairMiddleware, tool_call_repair
|
|
8
8
|
from .tool_emulator import LLMToolEmulator
|
|
9
9
|
from .tool_selection import LLMToolSelectorMiddleware
|
|
10
10
|
|
|
@@ -16,6 +16,8 @@ __all__ = [
|
|
|
16
16
|
"LLMToolEmulator",
|
|
17
17
|
"ModelRouterMiddleware",
|
|
18
18
|
"ToolCallRepairMiddleware",
|
|
19
|
-
"
|
|
19
|
+
"FormatPromptMiddleware",
|
|
20
20
|
"HandoffAgentMiddleware",
|
|
21
|
+
"tool_call_repair",
|
|
22
|
+
"format_prompt",
|
|
21
23
|
]
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
from typing import Awaitable, Callable, Literal
|
|
2
|
+
|
|
3
|
+
from langchain.agents.middleware import ModelRequest
|
|
4
|
+
from langchain.agents.middleware.types import (
|
|
5
|
+
AgentMiddleware,
|
|
6
|
+
ModelCallResult,
|
|
7
|
+
ModelResponse,
|
|
8
|
+
)
|
|
9
|
+
from langchain_core.messages import SystemMessage
|
|
10
|
+
from langchain_core.prompts.string import get_template_variables
|
|
11
|
+
|
|
12
|
+
from langchain_dev_utils._utils import _check_pkg_install
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class FormatPromptMiddleware(AgentMiddleware):
|
|
16
|
+
"""Format the system prompt with variables from state and context.
|
|
17
|
+
|
|
18
|
+
This middleware function extracts template variables from the system prompt
|
|
19
|
+
and populates them with values from the agent's state and runtime context.
|
|
20
|
+
Variables are first resolved from the state, then from the context if not found.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
template_format: The format of the template. Defaults to "f-string".
|
|
24
|
+
|
|
25
|
+
Example:
|
|
26
|
+
|
|
27
|
+
# Use format_prompt middleware instance rather than FormatPromptMiddleware class (Recommended)
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from langchain_dev_utils.agents.middleware import format_prompt
|
|
31
|
+
from langchain.agents import create_agent
|
|
32
|
+
from langchain_core.messages import HumanMessage
|
|
33
|
+
from dataclasses import dataclass
|
|
34
|
+
|
|
35
|
+
@dataclass
|
|
36
|
+
class Context:
|
|
37
|
+
name: str
|
|
38
|
+
user: str
|
|
39
|
+
|
|
40
|
+
agent = create_agent(
|
|
41
|
+
model=model,
|
|
42
|
+
tools=tools,
|
|
43
|
+
system_prompt="You are a helpful assistant. Your name is {name}. Your user is {user}.",
|
|
44
|
+
middleware=[format_prompt],
|
|
45
|
+
context_schema=Context,
|
|
46
|
+
)
|
|
47
|
+
agent.invoke(
|
|
48
|
+
{
|
|
49
|
+
"messages": [HumanMessage(content="Hello")],
|
|
50
|
+
},
|
|
51
|
+
context=Context(name="assistant", user="Tom"),
|
|
52
|
+
)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
# Use FormatPromptMiddleware class(Use when template_format is jinja2)
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from langchain_dev_utils.agents.middleware import FormatPromptMiddleware
|
|
59
|
+
from langchain.agents import create_agent
|
|
60
|
+
from langchain_core.messages import HumanMessage
|
|
61
|
+
from dataclasses import dataclass
|
|
62
|
+
|
|
63
|
+
@dataclass
|
|
64
|
+
class Context:
|
|
65
|
+
name: str
|
|
66
|
+
user: str
|
|
67
|
+
|
|
68
|
+
agent = create_agent(
|
|
69
|
+
model=model,
|
|
70
|
+
tools=tools,
|
|
71
|
+
system_prompt="You are a helpful assistant. Your name is {{ name }}. Your user is {{ user }}.",
|
|
72
|
+
middleware=[FormatPromptMiddleware(template_format="jinja2")],
|
|
73
|
+
context_schema=Context,
|
|
74
|
+
)
|
|
75
|
+
agent.invoke(
|
|
76
|
+
{
|
|
77
|
+
"messages": [HumanMessage(content="Hello")],
|
|
78
|
+
},
|
|
79
|
+
context=Context(name="assistant", user="Tom"),
|
|
80
|
+
)
|
|
81
|
+
```
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
def __init__(
|
|
85
|
+
self,
|
|
86
|
+
*,
|
|
87
|
+
template_format: Literal["f-string", "jinja2"] = "f-string",
|
|
88
|
+
) -> None:
|
|
89
|
+
super().__init__()
|
|
90
|
+
|
|
91
|
+
self.template_format = template_format
|
|
92
|
+
|
|
93
|
+
if template_format == "jinja2":
|
|
94
|
+
_check_pkg_install("jinja2")
|
|
95
|
+
|
|
96
|
+
def _format_prompt(self, request: ModelRequest) -> str:
|
|
97
|
+
"""Add the plan system prompt to the system message."""
|
|
98
|
+
system_msg = request.system_message
|
|
99
|
+
if system_msg is None:
|
|
100
|
+
raise ValueError(
|
|
101
|
+
"system_message must be provided,while use format_prompt in middleware."
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
system_prompt = "\n".join(
|
|
105
|
+
[content.get("text", "") for content in system_msg.content_blocks]
|
|
106
|
+
)
|
|
107
|
+
variables = get_template_variables(system_prompt, self.template_format)
|
|
108
|
+
|
|
109
|
+
format_params = {}
|
|
110
|
+
|
|
111
|
+
state = request.state
|
|
112
|
+
for key in variables:
|
|
113
|
+
if var := state.get(key, None):
|
|
114
|
+
format_params[key] = var
|
|
115
|
+
|
|
116
|
+
other_var_keys = set(variables) - set(format_params.keys())
|
|
117
|
+
|
|
118
|
+
if other_var_keys:
|
|
119
|
+
context = request.runtime.context
|
|
120
|
+
if context is not None:
|
|
121
|
+
for key in other_var_keys:
|
|
122
|
+
if var := getattr(context, key, None):
|
|
123
|
+
format_params[key] = var
|
|
124
|
+
|
|
125
|
+
if self.template_format == "jinja2":
|
|
126
|
+
from jinja2 import Template
|
|
127
|
+
|
|
128
|
+
template = Template(system_prompt)
|
|
129
|
+
return template.render(**format_params)
|
|
130
|
+
else:
|
|
131
|
+
return system_prompt.format(**format_params)
|
|
132
|
+
|
|
133
|
+
def wrap_model_call(
|
|
134
|
+
self,
|
|
135
|
+
request: ModelRequest,
|
|
136
|
+
handler: Callable[[ModelRequest], ModelResponse],
|
|
137
|
+
) -> ModelCallResult:
|
|
138
|
+
"""Update the system prompt with variables from state and context."""
|
|
139
|
+
prompt = self._format_prompt(request)
|
|
140
|
+
request = request.override(system_message=SystemMessage(content=prompt))
|
|
141
|
+
return handler(request)
|
|
142
|
+
|
|
143
|
+
async def awrap_model_call(
|
|
144
|
+
self,
|
|
145
|
+
request: ModelRequest,
|
|
146
|
+
handler: Callable[[ModelRequest], Awaitable[ModelResponse]],
|
|
147
|
+
) -> ModelCallResult:
|
|
148
|
+
"""Update the system prompt with variables from state and context."""
|
|
149
|
+
prompt = self._format_prompt(request)
|
|
150
|
+
override_request = request.override(
|
|
151
|
+
system_message=SystemMessage(content=prompt)
|
|
152
|
+
)
|
|
153
|
+
return await handler(override_request)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
format_prompt = FormatPromptMiddleware()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Awaitable, Callable, Literal, cast
|
|
2
2
|
|
|
3
3
|
from langchain.agents import AgentState
|
|
4
4
|
from langchain.agents.middleware import AgentMiddleware, ModelRequest, ModelResponse
|
|
@@ -9,6 +9,7 @@ from langchain_core.messages import SystemMessage, ToolMessage
|
|
|
9
9
|
from langgraph.types import Command
|
|
10
10
|
from typing_extensions import NotRequired, Optional, TypedDict
|
|
11
11
|
|
|
12
|
+
from langchain_dev_utils._utils import _duplicate_tools, _merge_tools
|
|
12
13
|
from langchain_dev_utils.chat_models import load_chat_model
|
|
13
14
|
|
|
14
15
|
|
|
@@ -19,7 +20,7 @@ class MultiAgentState(AgentState):
|
|
|
19
20
|
class AgentConfig(TypedDict):
|
|
20
21
|
model: NotRequired[str | BaseChatModel]
|
|
21
22
|
prompt: str | SystemMessage
|
|
22
|
-
tools: NotRequired[list[BaseTool
|
|
23
|
+
tools: NotRequired[list[BaseTool]]
|
|
23
24
|
default: NotRequired[bool]
|
|
24
25
|
handoffs: list[str] | Literal["all"]
|
|
25
26
|
|
|
@@ -176,7 +177,16 @@ class HandoffAgentMiddleware(AgentMiddleware):
|
|
|
176
177
|
agents_config,
|
|
177
178
|
handoffs_tools,
|
|
178
179
|
)
|
|
179
|
-
|
|
180
|
+
|
|
181
|
+
all_tools = [
|
|
182
|
+
*handoffs_tools,
|
|
183
|
+
]
|
|
184
|
+
|
|
185
|
+
for agent_name in agents_config:
|
|
186
|
+
tools = agents_config.get(agent_name, {}).get("tools", [])
|
|
187
|
+
all_tools.extend(tools)
|
|
188
|
+
|
|
189
|
+
self.tools = _merge_tools(all_tools)
|
|
180
190
|
|
|
181
191
|
def _get_override_request(self, request: ModelRequest) -> ModelRequest:
|
|
182
192
|
active_agent_name = request.state.get("active_agent", self.default_agent_name)
|
|
@@ -184,15 +194,14 @@ class HandoffAgentMiddleware(AgentMiddleware):
|
|
|
184
194
|
_config = self.agents_config[active_agent_name]
|
|
185
195
|
|
|
186
196
|
params = {}
|
|
187
|
-
if _config.get("model"):
|
|
188
|
-
model = _config.get("model")
|
|
197
|
+
if model := _config.get("model"):
|
|
189
198
|
if isinstance(model, str):
|
|
190
199
|
model = load_chat_model(model)
|
|
191
200
|
params["model"] = model
|
|
192
|
-
if _config.get("prompt"):
|
|
193
|
-
params["system_prompt"] =
|
|
194
|
-
if _config.get("tools"):
|
|
195
|
-
params["tools"] =
|
|
201
|
+
if prompt := _config.get("prompt"):
|
|
202
|
+
params["system_prompt"] = prompt
|
|
203
|
+
if tools := _config.get("tools"):
|
|
204
|
+
params["tools"] = _duplicate_tools(tools)
|
|
196
205
|
|
|
197
206
|
if params:
|
|
198
207
|
return request.override(**params)
|
|
@@ -10,6 +10,7 @@ from langgraph.runtime import Runtime
|
|
|
10
10
|
from pydantic import BaseModel, Field
|
|
11
11
|
from typing_extensions import TypedDict
|
|
12
12
|
|
|
13
|
+
from langchain_dev_utils._utils import _duplicate_tools, _merge_tools
|
|
13
14
|
from langchain_dev_utils.chat_models import load_chat_model
|
|
14
15
|
from langchain_dev_utils.message_convert import format_sequence
|
|
15
16
|
|
|
@@ -120,6 +121,13 @@ class ModelRouterMiddleware(AgentMiddleware):
|
|
|
120
121
|
|
|
121
122
|
self.router_prompt = router_prompt
|
|
122
123
|
|
|
124
|
+
all_tools = []
|
|
125
|
+
for model in model_list:
|
|
126
|
+
if tools := model.get("tools"):
|
|
127
|
+
all_tools.extend(tools)
|
|
128
|
+
|
|
129
|
+
self.tools = _merge_tools(all_tools)
|
|
130
|
+
|
|
123
131
|
def _select_model(self, messages: list[AnyMessage]):
|
|
124
132
|
response = cast(
|
|
125
133
|
SelectModel,
|
|
@@ -174,7 +182,7 @@ class ModelRouterMiddleware(AgentMiddleware):
|
|
|
174
182
|
model = load_chat_model(select_model_name)
|
|
175
183
|
override_kwargs["model"] = model
|
|
176
184
|
if model_values["tools"] is not None:
|
|
177
|
-
override_kwargs["tools"] = model_values["tools"]
|
|
185
|
+
override_kwargs["tools"] = _duplicate_tools(model_values["tools"])
|
|
178
186
|
if model_values["system_prompt"] is not None:
|
|
179
187
|
override_kwargs["system_message"] = SystemMessage(
|
|
180
188
|
content=model_values["system_prompt"]
|
{langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/agents/wrap.py
RENAMED
|
@@ -17,7 +17,7 @@ def _process_input(request: str, runtime: ToolRuntime) -> str:
|
|
|
17
17
|
def _process_output(
|
|
18
18
|
request: str, response: dict[str, Any], runtime: ToolRuntime
|
|
19
19
|
) -> Any:
|
|
20
|
-
return response["messages"][-1].
|
|
20
|
+
return response["messages"][-1].text
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
def get_subagent_name(runtime: ToolRuntime) -> str:
|
|
@@ -261,6 +261,8 @@ class _BaseChatOpenAICompatible(BaseChatOpenAI):
|
|
|
261
261
|
payload_messages.append(_convert_message_to_dict(m))
|
|
262
262
|
|
|
263
263
|
payload["messages"] = payload_messages
|
|
264
|
+
if "tools" in payload and len(payload["tools"]) == 0:
|
|
265
|
+
payload.pop("tools")
|
|
264
266
|
return payload
|
|
265
267
|
|
|
266
268
|
@model_validator(mode="after")
|
|
@@ -302,6 +304,8 @@ class _BaseChatOpenAICompatible(BaseChatOpenAI):
|
|
|
302
304
|
ModelProfile,
|
|
303
305
|
_get_profile_by_provider_and_model(self._provider, self.model_name),
|
|
304
306
|
)
|
|
307
|
+
if "json_schema" in self.supported_response_format:
|
|
308
|
+
self.profile.update({"structured_output": True})
|
|
305
309
|
return self
|
|
306
310
|
|
|
307
311
|
def _create_chat_result(
|
|
@@ -347,9 +351,9 @@ class _BaseChatOpenAICompatible(BaseChatOpenAI):
|
|
|
347
351
|
if isinstance(model_extra, dict) and (
|
|
348
352
|
reasoning := model_extra.get("reasoning")
|
|
349
353
|
):
|
|
350
|
-
rtn.generations[0].message.additional_kwargs[
|
|
351
|
-
|
|
352
|
-
|
|
354
|
+
rtn.generations[0].message.additional_kwargs[
|
|
355
|
+
"reasoning_content"
|
|
356
|
+
] = reasoning
|
|
353
357
|
|
|
354
358
|
return rtn
|
|
355
359
|
|
|
@@ -5,8 +5,8 @@ from langchain_tests.integration_tests.embeddings import EmbeddingsIntegrationTe
|
|
|
5
5
|
|
|
6
6
|
from langchain_dev_utils.embeddings.adapters import create_openai_compatible_embedding
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
"
|
|
8
|
+
ZAIEmbeddings = create_openai_compatible_embedding(
|
|
9
|
+
"zai", embedding_model_cls_name="ZAIEmbeddings"
|
|
10
10
|
)
|
|
11
11
|
|
|
12
12
|
|
|
@@ -14,9 +14,9 @@ class TestStandard(EmbeddingsIntegrationTests):
|
|
|
14
14
|
@property
|
|
15
15
|
def embeddings_class(self) -> type[Embeddings]:
|
|
16
16
|
"""Embeddings class."""
|
|
17
|
-
return cast("type[Embeddings]",
|
|
17
|
+
return cast("type[Embeddings]", ZAIEmbeddings)
|
|
18
18
|
|
|
19
19
|
@property
|
|
20
20
|
def embedding_model_params(self) -> dict[str, Any]:
|
|
21
21
|
"""Embeddings model parameters."""
|
|
22
|
-
return {"model": "
|
|
22
|
+
return {"model": "embedding-3"}
|
|
@@ -6,9 +6,7 @@ from langgraph.checkpoint.memory import InMemorySaver
|
|
|
6
6
|
from langgraph.types import Command
|
|
7
7
|
|
|
8
8
|
from langchain_dev_utils.agents import create_agent
|
|
9
|
-
from langchain_dev_utils.agents.middleware import
|
|
10
|
-
HandoffAgentMiddleware,
|
|
11
|
-
)
|
|
9
|
+
from langchain_dev_utils.agents.middleware import HandoffAgentMiddleware
|
|
12
10
|
from langchain_dev_utils.agents.middleware.handoffs import AgentConfig
|
|
13
11
|
from langchain_dev_utils.chat_models import load_chat_model
|
|
14
12
|
|
|
@@ -91,10 +89,6 @@ def test_handoffs_middleware():
|
|
|
91
89
|
handoffs_tool_overrides=handoffs_tool_map,
|
|
92
90
|
)
|
|
93
91
|
],
|
|
94
|
-
tools=[
|
|
95
|
-
get_current_time,
|
|
96
|
-
run_code,
|
|
97
|
-
],
|
|
98
92
|
checkpointer=InMemorySaver(),
|
|
99
93
|
)
|
|
100
94
|
|
|
@@ -27,10 +27,6 @@ def register_all_model_providers():
|
|
|
27
27
|
def register_all_embeddings_providers():
|
|
28
28
|
batch_register_embeddings_provider(
|
|
29
29
|
[
|
|
30
|
-
{
|
|
31
|
-
"provider_name": "siliconflow",
|
|
32
|
-
"embeddings_model": "openai-compatible",
|
|
33
|
-
},
|
|
34
30
|
{"provider_name": "dashscope", "embeddings_model": DashScopeEmbeddings},
|
|
35
31
|
]
|
|
36
32
|
)
|
|
@@ -483,6 +483,80 @@ wheels = [
|
|
|
483
483
|
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417", size = 7294, upload-time = "2025-07-25T14:02:02.896Z" },
|
|
484
484
|
]
|
|
485
485
|
|
|
486
|
+
[[package]]
|
|
487
|
+
name = "cryptography"
|
|
488
|
+
version = "46.0.4"
|
|
489
|
+
source = { registry = "https://pypi.mirrors.ustc.edu.cn/simple/" }
|
|
490
|
+
dependencies = [
|
|
491
|
+
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
|
|
492
|
+
]
|
|
493
|
+
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/78/19/f748958276519adf6a0c1e79e7b8860b4830dda55ccdf29f2719b5fc499c/cryptography-46.0.4.tar.gz", hash = "sha256:bfd019f60f8abc2ed1b9be4ddc21cfef059c841d86d710bb69909a688cbb8f59", size = 749301, upload-time = "2026-01-28T00:24:37.379Z" }
|
|
494
|
+
wheels = [
|
|
495
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/8d/99/157aae7949a5f30d51fcb1a9851e8ebd5c74bf99b5285d8bb4b8b9ee641e/cryptography-46.0.4-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:281526e865ed4166009e235afadf3a4c4cba6056f99336a99efba65336fd5485", size = 7173686, upload-time = "2026-01-28T00:23:07.515Z" },
|
|
496
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/87/91/874b8910903159043b5c6a123b7e79c4559ddd1896e38967567942635778/cryptography-46.0.4-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5f14fba5bf6f4390d7ff8f086c566454bff0411f6d8aa7af79c88b6f9267aecc", size = 4275871, upload-time = "2026-01-28T00:23:09.439Z" },
|
|
497
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/c0/35/690e809be77896111f5b195ede56e4b4ed0435b428c2f2b6d35046fbb5e8/cryptography-46.0.4-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:47bcd19517e6389132f76e2d5303ded6cf3f78903da2158a671be8de024f4cd0", size = 4423124, upload-time = "2026-01-28T00:23:11.529Z" },
|
|
498
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/1a/5b/a26407d4f79d61ca4bebaa9213feafdd8806dc69d3d290ce24996d3cfe43/cryptography-46.0.4-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:01df4f50f314fbe7009f54046e908d1754f19d0c6d3070df1e6268c5a4af09fa", size = 4277090, upload-time = "2026-01-28T00:23:13.123Z" },
|
|
499
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/0c/d8/4bb7aec442a9049827aa34cee1aa83803e528fa55da9a9d45d01d1bb933e/cryptography-46.0.4-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5aa3e463596b0087b3da0dbe2b2487e9fc261d25da85754e30e3b40637d61f81", size = 4947652, upload-time = "2026-01-28T00:23:14.554Z" },
|
|
500
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/2b/08/f83e2e0814248b844265802d081f2fac2f1cbe6cd258e72ba14ff006823a/cryptography-46.0.4-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:0a9ad24359fee86f131836a9ac3bffc9329e956624a2d379b613f8f8abaf5255", size = 4455157, upload-time = "2026-01-28T00:23:16.443Z" },
|
|
501
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/0a/05/19d849cf4096448779d2dcc9bb27d097457dac36f7273ffa875a93b5884c/cryptography-46.0.4-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:dc1272e25ef673efe72f2096e92ae39dea1a1a450dd44918b15351f72c5a168e", size = 3981078, upload-time = "2026-01-28T00:23:17.838Z" },
|
|
502
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/e6/89/f7bac81d66ba7cde867a743ea5b37537b32b5c633c473002b26a226f703f/cryptography-46.0.4-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:de0f5f4ec8711ebc555f54735d4c673fc34b65c44283895f1a08c2b49d2fd99c", size = 4276213, upload-time = "2026-01-28T00:23:19.257Z" },
|
|
503
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/da/9f/7133e41f24edd827020ad21b068736e792bc68eecf66d93c924ad4719fb3/cryptography-46.0.4-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:eeeb2e33d8dbcccc34d64651f00a98cb41b2dc69cef866771a5717e6734dfa32", size = 4912190, upload-time = "2026-01-28T00:23:21.244Z" },
|
|
504
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/a6/f7/6d43cbaddf6f65b24816e4af187d211f0bc536a29961f69faedc48501d8e/cryptography-46.0.4-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:3d425eacbc9aceafd2cb429e42f4e5d5633c6f873f5e567077043ef1b9bbf616", size = 4454641, upload-time = "2026-01-28T00:23:22.866Z" },
|
|
505
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/9e/4f/ebd0473ad656a0ac912a16bd07db0f5d85184924e14fc88feecae2492834/cryptography-46.0.4-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:91627ebf691d1ea3976a031b61fb7bac1ccd745afa03602275dda443e11c8de0", size = 4405159, upload-time = "2026-01-28T00:23:25.278Z" },
|
|
506
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/d1/f7/7923886f32dc47e27adeff8246e976d77258fd2aa3efdd1754e4e323bf49/cryptography-46.0.4-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2d08bc22efd73e8854b0b7caff402d735b354862f1145d7be3b9c0f740fef6a0", size = 4666059, upload-time = "2026-01-28T00:23:26.766Z" },
|
|
507
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/eb/a7/0fca0fd3591dffc297278a61813d7f661a14243dd60f499a7a5b48acb52a/cryptography-46.0.4-cp311-abi3-win32.whl", hash = "sha256:82a62483daf20b8134f6e92898da70d04d0ef9a75829d732ea1018678185f4f5", size = 3026378, upload-time = "2026-01-28T00:23:28.317Z" },
|
|
508
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/2d/12/652c84b6f9873f0909374864a57b003686c642ea48c84d6c7e2c515e6da5/cryptography-46.0.4-cp311-abi3-win_amd64.whl", hash = "sha256:6225d3ebe26a55dbc8ead5ad1265c0403552a63336499564675b29eb3184c09b", size = 3478614, upload-time = "2026-01-28T00:23:30.275Z" },
|
|
509
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/b9/27/542b029f293a5cce59349d799d4d8484b3b1654a7b9a0585c266e974a488/cryptography-46.0.4-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:485e2b65d25ec0d901bca7bcae0f53b00133bf3173916d8e421f6fddde103908", size = 7116417, upload-time = "2026-01-28T00:23:31.958Z" },
|
|
510
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/f8/f5/559c25b77f40b6bf828eabaf988efb8b0e17b573545edb503368ca0a2a03/cryptography-46.0.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:078e5f06bd2fa5aea5a324f2a09f914b1484f1d0c2a4d6a8a28c74e72f65f2da", size = 4264508, upload-time = "2026-01-28T00:23:34.264Z" },
|
|
511
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/49/a1/551fa162d33074b660dc35c9bc3616fefa21a0e8c1edd27b92559902e408/cryptography-46.0.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dce1e4f068f03008da7fa51cc7abc6ddc5e5de3e3d1550334eaf8393982a5829", size = 4409080, upload-time = "2026-01-28T00:23:35.793Z" },
|
|
512
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/b0/6a/4d8d129a755f5d6df1bbee69ea2f35ebfa954fa1847690d1db2e8bca46a5/cryptography-46.0.4-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:2067461c80271f422ee7bdbe79b9b4be54a5162e90345f86a23445a0cf3fd8a2", size = 4270039, upload-time = "2026-01-28T00:23:37.263Z" },
|
|
513
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/4c/f5/ed3fcddd0a5e39321e595e144615399e47e7c153a1fb8c4862aec3151ff9/cryptography-46.0.4-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:c92010b58a51196a5f41c3795190203ac52edfd5dc3ff99149b4659eba9d2085", size = 4926748, upload-time = "2026-01-28T00:23:38.884Z" },
|
|
514
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/43/ae/9f03d5f0c0c00e85ecb34f06d3b79599f20630e4db91b8a6e56e8f83d410/cryptography-46.0.4-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:829c2b12bbc5428ab02d6b7f7e9bbfd53e33efd6672d21341f2177470171ad8b", size = 4442307, upload-time = "2026-01-28T00:23:40.56Z" },
|
|
515
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/8b/22/e0f9f2dae8040695103369cf2283ef9ac8abe4d51f68710bec2afd232609/cryptography-46.0.4-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:62217ba44bf81b30abaeda1488686a04a702a261e26f87db51ff61d9d3510abd", size = 3959253, upload-time = "2026-01-28T00:23:42.827Z" },
|
|
516
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/01/5b/6a43fcccc51dae4d101ac7d378a8724d1ba3de628a24e11bf2f4f43cba4d/cryptography-46.0.4-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:9c2da296c8d3415b93e6053f5a728649a87a48ce084a9aaf51d6e46c87c7f2d2", size = 4269372, upload-time = "2026-01-28T00:23:44.655Z" },
|
|
517
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/17/b7/0f6b8c1dd0779df2b526e78978ff00462355e31c0a6f6cff8a3e99889c90/cryptography-46.0.4-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:9b34d8ba84454641a6bf4d6762d15847ecbd85c1316c0a7984e6e4e9f748ec2e", size = 4891908, upload-time = "2026-01-28T00:23:46.48Z" },
|
|
518
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/83/17/259409b8349aa10535358807a472c6a695cf84f106022268d31cea2b6c97/cryptography-46.0.4-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:df4a817fa7138dd0c96c8c8c20f04b8aaa1fac3bbf610913dcad8ea82e1bfd3f", size = 4441254, upload-time = "2026-01-28T00:23:48.403Z" },
|
|
519
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/9c/fe/e4a1b0c989b00cee5ffa0764401767e2d1cf59f45530963b894129fd5dce/cryptography-46.0.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:b1de0ebf7587f28f9190b9cb526e901bf448c9e6a99655d2b07fff60e8212a82", size = 4396520, upload-time = "2026-01-28T00:23:50.26Z" },
|
|
520
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/b3/81/ba8fd9657d27076eb40d6a2f941b23429a3c3d2f56f5a921d6b936a27bc9/cryptography-46.0.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9b4d17bc7bd7cdd98e3af40b441feaea4c68225e2eb2341026c84511ad246c0c", size = 4651479, upload-time = "2026-01-28T00:23:51.674Z" },
|
|
521
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/00/03/0de4ed43c71c31e4fe954edd50b9d28d658fef56555eba7641696370a8e2/cryptography-46.0.4-cp314-cp314t-win32.whl", hash = "sha256:c411f16275b0dea722d76544a61d6421e2cc829ad76eec79280dbdc9ddf50061", size = 3001986, upload-time = "2026-01-28T00:23:53.485Z" },
|
|
522
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/5c/70/81830b59df7682917d7a10f833c4dab2a5574cd664e86d18139f2b421329/cryptography-46.0.4-cp314-cp314t-win_amd64.whl", hash = "sha256:728fedc529efc1439eb6107b677f7f7558adab4553ef8669f0d02d42d7b959a7", size = 3468288, upload-time = "2026-01-28T00:23:55.09Z" },
|
|
523
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/56/f7/f648fdbb61d0d45902d3f374217451385edc7e7768d1b03ff1d0e5ffc17b/cryptography-46.0.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a9556ba711f7c23f77b151d5798f3ac44a13455cc68db7697a1096e6d0563cab", size = 7169583, upload-time = "2026-01-28T00:23:56.558Z" },
|
|
524
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/d8/cc/8f3224cbb2a928de7298d6ed4790f5ebc48114e02bdc9559196bfb12435d/cryptography-46.0.4-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8bf75b0259e87fa70bddc0b8b4078b76e7fd512fd9afae6c1193bcf440a4dbef", size = 4275419, upload-time = "2026-01-28T00:23:58.364Z" },
|
|
525
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/17/43/4a18faa7a872d00e4264855134ba82d23546c850a70ff209e04ee200e76f/cryptography-46.0.4-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3c268a3490df22270955966ba236d6bc4a8f9b6e4ffddb78aac535f1a5ea471d", size = 4419058, upload-time = "2026-01-28T00:23:59.867Z" },
|
|
526
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/ee/64/6651969409821d791ba12346a124f55e1b76f66a819254ae840a965d4b9c/cryptography-46.0.4-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:812815182f6a0c1d49a37893a303b44eaac827d7f0d582cecfc81b6427f22973", size = 4278151, upload-time = "2026-01-28T00:24:01.731Z" },
|
|
527
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/20/0b/a7fce65ee08c3c02f7a8310cc090a732344066b990ac63a9dfd0a655d321/cryptography-46.0.4-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:a90e43e3ef65e6dcf969dfe3bb40cbf5aef0d523dff95bfa24256be172a845f4", size = 4939441, upload-time = "2026-01-28T00:24:03.175Z" },
|
|
528
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/db/a7/20c5701e2cd3e1dfd7a19d2290c522a5f435dd30957d431dcb531d0f1413/cryptography-46.0.4-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a05177ff6296644ef2876fce50518dffb5bcdf903c85250974fc8bc85d54c0af", size = 4451617, upload-time = "2026-01-28T00:24:05.403Z" },
|
|
529
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/00/dc/3e16030ea9aa47b63af6524c354933b4fb0e352257c792c4deeb0edae367/cryptography-46.0.4-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:daa392191f626d50f1b136c9b4cf08af69ca8279d110ea24f5c2700054d2e263", size = 3977774, upload-time = "2026-01-28T00:24:06.851Z" },
|
|
530
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/42/c8/ad93f14118252717b465880368721c963975ac4b941b7ef88f3c56bf2897/cryptography-46.0.4-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:e07ea39c5b048e085f15923511d8121e4a9dc45cee4e3b970ca4f0d338f23095", size = 4277008, upload-time = "2026-01-28T00:24:08.926Z" },
|
|
531
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/00/cf/89c99698151c00a4631fbfcfcf459d308213ac29e321b0ff44ceeeac82f1/cryptography-46.0.4-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:d5a45ddc256f492ce42a4e35879c5e5528c09cd9ad12420828c972951d8e016b", size = 4903339, upload-time = "2026-01-28T00:24:12.009Z" },
|
|
532
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/03/c3/c90a2cb358de4ac9309b26acf49b2a100957e1ff5cc1e98e6c4996576710/cryptography-46.0.4-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:6bb5157bf6a350e5b28aee23beb2d84ae6f5be390b2f8ee7ea179cda077e1019", size = 4451216, upload-time = "2026-01-28T00:24:13.975Z" },
|
|
533
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/96/2c/8d7f4171388a10208671e181ca43cdc0e596d8259ebacbbcfbd16de593da/cryptography-46.0.4-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:dd5aba870a2c40f87a3af043e0dee7d9eb02d4aff88a797b48f2b43eff8c3ab4", size = 4404299, upload-time = "2026-01-28T00:24:16.169Z" },
|
|
534
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/e9/23/cbb2036e450980f65c6e0a173b73a56ff3bccd8998965dea5cc9ddd424a5/cryptography-46.0.4-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:93d8291da8d71024379ab2cb0b5c57915300155ad42e07f76bea6ad838d7e59b", size = 4664837, upload-time = "2026-01-28T00:24:17.629Z" },
|
|
535
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/0a/21/f7433d18fe6d5845329cbdc597e30caf983229c7a245bcf54afecc555938/cryptography-46.0.4-cp38-abi3-win32.whl", hash = "sha256:0563655cb3c6d05fb2afe693340bc050c30f9f34e15763361cf08e94749401fc", size = 3009779, upload-time = "2026-01-28T00:24:20.198Z" },
|
|
536
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/3a/6a/bd2e7caa2facffedf172a45c1a02e551e6d7d4828658c9a245516a598d94/cryptography-46.0.4-cp38-abi3-win_amd64.whl", hash = "sha256:fa0900b9ef9c49728887d1576fd8d9e7e3ea872fa9b25ef9b64888adc434e976", size = 3466633, upload-time = "2026-01-28T00:24:21.851Z" },
|
|
537
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/59/e0/f9c6c53e1f2a1c2507f00f2faba00f01d2f334b35b0fbfe5286715da2184/cryptography-46.0.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:766330cce7416c92b5e90c3bb71b1b79521760cdcfc3a6a1a182d4c9fab23d2b", size = 3476316, upload-time = "2026-01-28T00:24:24.144Z" },
|
|
538
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/27/7a/f8d2d13227a9a1a9fe9c7442b057efecffa41f1e3c51d8622f26b9edbe8f/cryptography-46.0.4-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c236a44acfb610e70f6b3e1c3ca20ff24459659231ef2f8c48e879e2d32b73da", size = 4216693, upload-time = "2026-01-28T00:24:25.758Z" },
|
|
539
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/c5/de/3787054e8f7972658370198753835d9d680f6cd4a39df9f877b57f0dd69c/cryptography-46.0.4-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:8a15fb869670efa8f83cbffbc8753c1abf236883225aed74cd179b720ac9ec80", size = 4382765, upload-time = "2026-01-28T00:24:27.577Z" },
|
|
540
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/8a/5f/60e0afb019973ba6a0b322e86b3d61edf487a4f5597618a430a2a15f2d22/cryptography-46.0.4-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:fdc3daab53b212472f1524d070735b2f0c214239df131903bae1d598016fa822", size = 4216066, upload-time = "2026-01-28T00:24:29.056Z" },
|
|
541
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/81/8e/bf4a0de294f147fee66f879d9bae6f8e8d61515558e3d12785dd90eca0be/cryptography-46.0.4-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:44cc0675b27cadb71bdbb96099cca1fa051cd11d2ade09e5cd3a2edb929ed947", size = 4382025, upload-time = "2026-01-28T00:24:30.681Z" },
|
|
542
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/79/f4/9ceb90cfd6a3847069b0b0b353fd3075dc69b49defc70182d8af0c4ca390/cryptography-46.0.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:be8c01a7d5a55f9a47d1888162b76c8f49d62b234d88f0ff91a9fbebe32ffbc3", size = 3406043, upload-time = "2026-01-28T00:24:32.236Z" },
|
|
543
|
+
]
|
|
544
|
+
|
|
545
|
+
[[package]]
|
|
546
|
+
name = "dashscope"
|
|
547
|
+
version = "1.25.9"
|
|
548
|
+
source = { registry = "https://pypi.mirrors.ustc.edu.cn/simple/" }
|
|
549
|
+
dependencies = [
|
|
550
|
+
{ name = "aiohttp" },
|
|
551
|
+
{ name = "certifi" },
|
|
552
|
+
{ name = "cryptography" },
|
|
553
|
+
{ name = "requests" },
|
|
554
|
+
{ name = "websocket-client" },
|
|
555
|
+
]
|
|
556
|
+
wheels = [
|
|
557
|
+
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/03/bf/503587663b909427c1906b3b75fc2982bf9e42161d8b687f6e38ad12d042/dashscope-1.25.9-py3-none-any.whl", hash = "sha256:03b587bcb58a2f0a76fa5102925c16609b50af176198af0aeb0fd85aa44d6cfe", size = 1335755, upload-time = "2026-01-21T06:58:14.496Z" },
|
|
558
|
+
]
|
|
559
|
+
|
|
486
560
|
[[package]]
|
|
487
561
|
name = "dataclasses-json"
|
|
488
562
|
version = "0.6.7"
|
|
@@ -1365,7 +1439,7 @@ wheels = [
|
|
|
1365
1439
|
|
|
1366
1440
|
[[package]]
|
|
1367
1441
|
name = "langchain-dev-utils"
|
|
1368
|
-
version = "1.
|
|
1442
|
+
version = "1.4.1"
|
|
1369
1443
|
source = { editable = "." }
|
|
1370
1444
|
dependencies = [
|
|
1371
1445
|
{ name = "langchain" },
|
|
@@ -1375,12 +1449,14 @@ dependencies = [
|
|
|
1375
1449
|
|
|
1376
1450
|
[package.optional-dependencies]
|
|
1377
1451
|
standard = [
|
|
1452
|
+
{ name = "jinja2" },
|
|
1378
1453
|
{ name = "json-repair" },
|
|
1379
1454
|
{ name = "langchain-openai" },
|
|
1380
1455
|
]
|
|
1381
1456
|
|
|
1382
1457
|
[package.dev-dependencies]
|
|
1383
1458
|
dev = [
|
|
1459
|
+
{ name = "dashscope" },
|
|
1384
1460
|
{ name = "langchain-model-profiles" },
|
|
1385
1461
|
{ name = "ruff" },
|
|
1386
1462
|
]
|
|
@@ -1400,6 +1476,7 @@ tests = [
|
|
|
1400
1476
|
|
|
1401
1477
|
[package.metadata]
|
|
1402
1478
|
requires-dist = [
|
|
1479
|
+
{ name = "jinja2", marker = "extra == 'standard'", specifier = ">=3.1.6" },
|
|
1403
1480
|
{ name = "json-repair", marker = "extra == 'standard'", specifier = ">=0.53.1" },
|
|
1404
1481
|
{ name = "langchain", specifier = ">=1.2.0" },
|
|
1405
1482
|
{ name = "langchain-core", specifier = ">=1.2.5" },
|
|
@@ -1410,6 +1487,7 @@ provides-extras = ["standard"]
|
|
|
1410
1487
|
|
|
1411
1488
|
[package.metadata.requires-dev]
|
|
1412
1489
|
dev = [
|
|
1490
|
+
{ name = "dashscope", specifier = ">=1.25.9" },
|
|
1413
1491
|
{ name = "langchain-model-profiles", specifier = ">=0.0.5" },
|
|
1414
1492
|
{ name = "ruff", specifier = ">=0.14.5" },
|
|
1415
1493
|
]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.4.0"
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
from langchain.agents.middleware import ModelRequest, dynamic_prompt
|
|
2
|
-
from langchain_core.prompts.string import get_template_variables
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
@dynamic_prompt
|
|
6
|
-
def format_prompt(request: ModelRequest) -> str:
|
|
7
|
-
"""Format the system prompt with variables from state and context.
|
|
8
|
-
|
|
9
|
-
This middleware function extracts template variables from the system prompt
|
|
10
|
-
and populates them with values from the agent's state and runtime context.
|
|
11
|
-
Variables are first resolved from the state, then from the context if not found.
|
|
12
|
-
|
|
13
|
-
Example:
|
|
14
|
-
>>> from langchain_dev_utils.agents.middleware import format_prompt
|
|
15
|
-
>>> from langchain.agents import create_agent
|
|
16
|
-
>>> from langchain_core.messages import HumanMessage
|
|
17
|
-
>>> from dataclasses import dataclass
|
|
18
|
-
>>>
|
|
19
|
-
>>> @dataclass
|
|
20
|
-
... class Context:
|
|
21
|
-
... name: str
|
|
22
|
-
... user: str
|
|
23
|
-
>>>
|
|
24
|
-
>>> agent=create_agent(
|
|
25
|
-
... model=model,
|
|
26
|
-
... tools=tools,
|
|
27
|
-
... system_prompt="You are a helpful assistant. Your name is {name}. Your user is {user}.",
|
|
28
|
-
... middleware=[format_prompt],
|
|
29
|
-
... context_schema=Context,
|
|
30
|
-
... )
|
|
31
|
-
>>> agent.invoke(
|
|
32
|
-
... {
|
|
33
|
-
... "messages": [HumanMessage(content="Hello")],
|
|
34
|
-
... },
|
|
35
|
-
... context=Context(name="assistant", user="Tom"),
|
|
36
|
-
... )
|
|
37
|
-
|
|
38
|
-
"""
|
|
39
|
-
system_msg = request.system_message
|
|
40
|
-
if system_msg is None:
|
|
41
|
-
raise ValueError(
|
|
42
|
-
"system_message must be provided,while use format_prompt in middleware."
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
system_prompt = "\n".join(
|
|
46
|
-
[content.get("text", "") for content in system_msg.content_blocks]
|
|
47
|
-
)
|
|
48
|
-
variables = get_template_variables(system_prompt, "f-string")
|
|
49
|
-
|
|
50
|
-
format_params = {}
|
|
51
|
-
|
|
52
|
-
state = request.state
|
|
53
|
-
for key in variables:
|
|
54
|
-
if var := state.get(key, None):
|
|
55
|
-
format_params[key] = var
|
|
56
|
-
|
|
57
|
-
other_var_keys = set(variables) - set(format_params.keys())
|
|
58
|
-
|
|
59
|
-
if other_var_keys:
|
|
60
|
-
context = request.runtime.context
|
|
61
|
-
if context is not None:
|
|
62
|
-
for key in other_var_keys:
|
|
63
|
-
if var := getattr(context, key, None):
|
|
64
|
-
format_params[key] = var
|
|
65
|
-
|
|
66
|
-
return system_prompt.format(**format_params)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/agents/__init__.py
RENAMED
|
File without changes
|
{langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/agents/factory.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
|
{langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/chat_models/base.py
RENAMED
|
File without changes
|
{langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/chat_models/types.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/embeddings/base.py
RENAMED
|
File without changes
|
{langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/graph/__init__.py
RENAMED
|
File without changes
|
{langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/graph/parallel.py
RENAMED
|
File without changes
|
{langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/graph/sequential.py
RENAMED
|
File without changes
|
{langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/graph/types.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/pipeline/__init__.py
RENAMED
|
File without changes
|
{langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/pipeline/parallel.py
RENAMED
|
File without changes
|
|
File without changes
|
{langchain_dev_utils-1.4.0 → langchain_dev_utils-1.4.2}/src/langchain_dev_utils/pipeline/types.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
|