langchain-dynamic-tools-middleware 0.2.0__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_dynamic_tools_middleware-0.2.0/.github/ISSUE_TEMPLATE/bug_report.md +31 -0
- langchain_dynamic_tools_middleware-0.2.0/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
- langchain_dynamic_tools_middleware-0.2.0/.github/PULL_REQUEST_TEMPLATE.md +16 -0
- langchain_dynamic_tools_middleware-0.2.0/.github/workflows/ci.yml +37 -0
- langchain_dynamic_tools_middleware-0.2.0/.github/workflows/publish.yml +26 -0
- langchain_dynamic_tools_middleware-0.2.0/.gitignore +34 -0
- langchain_dynamic_tools_middleware-0.2.0/.python-version +1 -0
- langchain_dynamic_tools_middleware-0.2.0/CHANGELOG.md +45 -0
- langchain_dynamic_tools_middleware-0.2.0/CONTRIBUTING.md +86 -0
- langchain_dynamic_tools_middleware-0.2.0/Dockerfile.dev +12 -0
- langchain_dynamic_tools_middleware-0.2.0/LICENSE +21 -0
- langchain_dynamic_tools_middleware-0.2.0/PKG-INFO +454 -0
- langchain_dynamic_tools_middleware-0.2.0/README.md +415 -0
- langchain_dynamic_tools_middleware-0.2.0/benchmarks/README.md +89 -0
- langchain_dynamic_tools_middleware-0.2.0/benchmarks/RESULTS.md +156 -0
- langchain_dynamic_tools_middleware-0.2.0/benchmarks/bfcl/data.py +207 -0
- langchain_dynamic_tools_middleware-0.2.0/benchmarks/bfcl/run_bfcl.py +372 -0
- langchain_dynamic_tools_middleware-0.2.0/benchmarks/bfcl/scoring.py +108 -0
- langchain_dynamic_tools_middleware-0.2.0/benchmarks/common.py +322 -0
- langchain_dynamic_tools_middleware-0.2.0/benchmarks/latency/run_latency.py +199 -0
- langchain_dynamic_tools_middleware-0.2.0/benchmarks/results/bfcl_results.json +187 -0
- langchain_dynamic_tools_middleware-0.2.0/benchmarks/results/latency.png +0 -0
- langchain_dynamic_tools_middleware-0.2.0/benchmarks/results/latency_llm_selector.json +29 -0
- langchain_dynamic_tools_middleware-0.2.0/benchmarks/results/latency_results.json +81 -0
- langchain_dynamic_tools_middleware-0.2.0/benchmarks/results/token_results.json +258 -0
- langchain_dynamic_tools_middleware-0.2.0/benchmarks/token_reduction/run_tokens.py +204 -0
- langchain_dynamic_tools_middleware-0.2.0/examples/custom_embedders.py +57 -0
- langchain_dynamic_tools_middleware-0.2.0/examples/quickstart.py +80 -0
- langchain_dynamic_tools_middleware-0.2.0/pyproject.toml +134 -0
- langchain_dynamic_tools_middleware-0.2.0/scripts/dev-container.sh +36 -0
- langchain_dynamic_tools_middleware-0.2.0/scripts/verify_zvec.py +134 -0
- langchain_dynamic_tools_middleware-0.2.0/src/langchain_dynamic_tools/__init__.py +26 -0
- langchain_dynamic_tools_middleware-0.2.0/src/langchain_dynamic_tools/_embeddings.py +306 -0
- langchain_dynamic_tools_middleware-0.2.0/src/langchain_dynamic_tools/_index.py +365 -0
- langchain_dynamic_tools_middleware-0.2.0/src/langchain_dynamic_tools/_middleware.py +298 -0
- langchain_dynamic_tools_middleware-0.2.0/src/langchain_dynamic_tools/py.typed +0 -0
- langchain_dynamic_tools_middleware-0.2.0/tests/conftest.py +312 -0
- langchain_dynamic_tools_middleware-0.2.0/tests/test_embeddings.py +242 -0
- langchain_dynamic_tools_middleware-0.2.0/tests/test_index.py +264 -0
- langchain_dynamic_tools_middleware-0.2.0/tests/test_middleware.py +255 -0
- langchain_dynamic_tools_middleware-0.2.0/uv.lock +4941 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Something is broken
|
|
4
|
+
labels: bug
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
**What happened**
|
|
8
|
+
|
|
9
|
+
A clear description of the bug.
|
|
10
|
+
|
|
11
|
+
**What you expected**
|
|
12
|
+
|
|
13
|
+
What should have happened instead.
|
|
14
|
+
|
|
15
|
+
**How to reproduce**
|
|
16
|
+
|
|
17
|
+
Steps, a code snippet, or a small script that shows the problem. If it
|
|
18
|
+
involves tools, include the tool definitions and the message the agent was
|
|
19
|
+
handling.
|
|
20
|
+
|
|
21
|
+
**Environment**
|
|
22
|
+
|
|
23
|
+
- Package version:
|
|
24
|
+
- Python version:
|
|
25
|
+
- Operating system:
|
|
26
|
+
- How the agent is built (model, other middleware in the stack):
|
|
27
|
+
|
|
28
|
+
**Logs**
|
|
29
|
+
|
|
30
|
+
Anything printed to the console, especially warnings from
|
|
31
|
+
`langchain_dynamic_tools`.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: An idea to make this better
|
|
4
|
+
labels: enhancement
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
**The problem you are solving**
|
|
8
|
+
|
|
9
|
+
What are you trying to do that the middleware does not support yet?
|
|
10
|
+
|
|
11
|
+
**Your suggestion**
|
|
12
|
+
|
|
13
|
+
What you would like to exist, and how you would use it.
|
|
14
|
+
|
|
15
|
+
**Alternatives you considered**
|
|
16
|
+
|
|
17
|
+
Anything else you tried or thought about.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
## What this pull request does
|
|
2
|
+
|
|
3
|
+
One or two sentences describing the change.
|
|
4
|
+
|
|
5
|
+
## How it was tested
|
|
6
|
+
|
|
7
|
+
Commands you ran (tests, lint, benchmarks) and what you saw. New behavior
|
|
8
|
+
needs a test; changed benchmark claims need fresh numbers from the harness.
|
|
9
|
+
|
|
10
|
+
## Checklist
|
|
11
|
+
|
|
12
|
+
- [ ] Tests pass: `uv run pytest`
|
|
13
|
+
- [ ] Lint passes: `uv run ruff check .`
|
|
14
|
+
- [ ] Types pass: `uv run mypy`
|
|
15
|
+
- [ ] Documentation updated where needed
|
|
16
|
+
- [ ] No em-dashes in docs or comments (project style)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
strategy:
|
|
11
|
+
fail-fast: false
|
|
12
|
+
matrix:
|
|
13
|
+
os: [ubuntu-latest, macos-latest]
|
|
14
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
15
|
+
runs-on: ${{ matrix.os }}
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: ${{ matrix.python-version }}
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: uv sync --all-extras
|
|
26
|
+
|
|
27
|
+
- name: Lint
|
|
28
|
+
run: uv run ruff check .
|
|
29
|
+
|
|
30
|
+
- name: Type check
|
|
31
|
+
run: uv run mypy
|
|
32
|
+
|
|
33
|
+
- name: Test
|
|
34
|
+
run: uv run pytest
|
|
35
|
+
|
|
36
|
+
- name: Build check
|
|
37
|
+
run: uv build
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
publish:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
environment: pypi
|
|
12
|
+
permissions:
|
|
13
|
+
id-token: write
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Install uv
|
|
18
|
+
uses: astral-sh/setup-uv@v5
|
|
19
|
+
|
|
20
|
+
- name: Build sdist and wheel
|
|
21
|
+
run: uv build
|
|
22
|
+
|
|
23
|
+
- name: Publish to PyPI
|
|
24
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
25
|
+
with:
|
|
26
|
+
attestations: true
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.eggs/
|
|
6
|
+
build/
|
|
7
|
+
dist/
|
|
8
|
+
|
|
9
|
+
# Virtual environments
|
|
10
|
+
.venv/
|
|
11
|
+
venv/
|
|
12
|
+
|
|
13
|
+
# Tooling caches
|
|
14
|
+
.pytest_cache/
|
|
15
|
+
.mypy_cache/
|
|
16
|
+
.ruff_cache/
|
|
17
|
+
.coverage
|
|
18
|
+
coverage.xml
|
|
19
|
+
htmlcov/
|
|
20
|
+
|
|
21
|
+
# zvec collections created by examples and benchmarks
|
|
22
|
+
.dynamicToolsMiddleware/
|
|
23
|
+
*.zvec/
|
|
24
|
+
|
|
25
|
+
# Downloaded benchmark datasets (refetched by the harness as needed)
|
|
26
|
+
benchmarks/bfcl/data/
|
|
27
|
+
|
|
28
|
+
# Editors and OS
|
|
29
|
+
.idea/
|
|
30
|
+
.vscode/
|
|
31
|
+
.DS_Store
|
|
32
|
+
|
|
33
|
+
# Environment
|
|
34
|
+
.env
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.10
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
|
+
|
|
8
|
+
## [0.2.0] - 2026-09-13
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `LangChainDenseEmbedder`, an adapter that lets any standard LangChain
|
|
13
|
+
`Embeddings` object (e.g. `OpenAIEmbeddings`) be used as `dense_embedder`.
|
|
14
|
+
`ToolVectorIndex` applies it automatically; `dense_dim` doubles as the
|
|
15
|
+
explicit dimension so no probing API call is needed.
|
|
16
|
+
- `dense_dim` parameter on `DynamicToolSelectorMiddleware`, forwarded to the
|
|
17
|
+
index.
|
|
18
|
+
- Multi-turn aware search query: the latest user message is used, plus the
|
|
19
|
+
previous one when the latest is a very short follow-up. Queries are capped
|
|
20
|
+
at 2000 characters.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Benchmark harness: set the missing category on shared args (every BFCL
|
|
25
|
+
entry used to fail), unique index directory per parallel entry (zvec lock
|
|
26
|
+
collisions), per-block checkpointing for token runs, `--configs` filter for
|
|
27
|
+
rerunning single blocks, and per-block error samples in saved results.
|
|
28
|
+
|
|
29
|
+
## [0.1.0] - 2026-09-11
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- `DynamicToolSelectorMiddleware`, a LangChain agent middleware that indexes
|
|
34
|
+
every tool into a local zvec collection with hybrid dense and sparse
|
|
35
|
+
embeddings and hands the model only the top-k most relevant tools per step.
|
|
36
|
+
- `ToolVectorIndex`, the zvec-backed index with incremental sync, reciprocal
|
|
37
|
+
rank fusion of dense and sparse rankings, and collection lifecycle handling.
|
|
38
|
+
- `DefaultDenseEmbedder` and `DefaultSparseEmbedder`, thin wrappers around the
|
|
39
|
+
local models that ship with zvec (all-MiniLM-L6-v2 and SPLADE), plus
|
|
40
|
+
protocols for plugging in any embedding backend.
|
|
41
|
+
- `render_tool_text`, the compact tool representation used for embedding.
|
|
42
|
+
- Graceful degradation: search failures fall back to all tools unless the
|
|
43
|
+
caller opts into raising.
|
|
44
|
+
- Benchmark suite: BFCL accuracy harness, selection latency at scale, and
|
|
45
|
+
token reduction measurements with committed, reproducible results.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for wanting to help. This guide covers setup, the workflow, and the
|
|
4
|
+
house style.
|
|
5
|
+
|
|
6
|
+
## Setup
|
|
7
|
+
|
|
8
|
+
You need Python 3.10 or newer and [uv](https://docs.astral.sh/uv/).
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
git clone https://github.com/RauhanAhmed/langchain-dynamic-tools-middleware.git
|
|
12
|
+
cd langchain-dynamic-tools-middleware
|
|
13
|
+
uv sync --all-extras
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
That installs the package (editable), the dev tools, the local embedding
|
|
17
|
+
models, and the benchmark extras.
|
|
18
|
+
|
|
19
|
+
### A note on platforms
|
|
20
|
+
|
|
21
|
+
zvec, the vector engine underneath this package, publishes wheels for Linux
|
|
22
|
+
(x86_64 and aarch64), macOS ARM64, and Windows x86_64. If you are on one of
|
|
23
|
+
those, `uv sync` just works. On an Intel Mac there are no zvec wheels, so run
|
|
24
|
+
everything through the Linux dev container instead:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
./scripts/dev-container.sh uv sync --all-extras
|
|
28
|
+
./scripts/dev-container.sh uv run pytest
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The container mounts the repository and keeps its virtual environment and
|
|
32
|
+
model caches in Docker volumes, so nothing pollutes your checkout.
|
|
33
|
+
|
|
34
|
+
## Everyday commands
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
uv run pytest # fast tests, no model downloads
|
|
38
|
+
uv run pytest -m local # adds the real local model smoke test
|
|
39
|
+
uv run ruff check . # lint
|
|
40
|
+
uv run mypy # strict type check of the package
|
|
41
|
+
uv build # sdist and wheel
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Tests
|
|
45
|
+
|
|
46
|
+
Fast tests use deterministic fake embedders so they run offline in seconds.
|
|
47
|
+
The `local` marker runs the real embedding models once; keep anything that
|
|
48
|
+
downloads a model or calls an API behind that marker.
|
|
49
|
+
|
|
50
|
+
New behavior needs a test. If you touch the middleware, cover both the sync
|
|
51
|
+
and async paths.
|
|
52
|
+
|
|
53
|
+
## Benchmarks
|
|
54
|
+
|
|
55
|
+
The benchmark suite lives in `benchmarks/` and produces the numbers committed
|
|
56
|
+
in `benchmarks/RESULTS.md`. Runs use real components: the real zvec engine,
|
|
57
|
+
the real local embedding models, and live model calls.
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
uv run python -m benchmarks.latency.run_latency
|
|
61
|
+
uv run python -m benchmarks.token_reduction.run_tokens
|
|
62
|
+
uv run python -m benchmarks.bfcl.run_bfcl --categories simple --limit 50
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
API keys come from environment variables or a `.env` file (never committed).
|
|
66
|
+
If your change affects selection quality, latency, or token usage, rerun the
|
|
67
|
+
relevant benchmark and update `RESULTS.md` with the fresh numbers and the
|
|
68
|
+
exact command you ran.
|
|
69
|
+
|
|
70
|
+
## House style
|
|
71
|
+
|
|
72
|
+
- No em-dashes anywhere: README, docstrings, comments, changelog entries.
|
|
73
|
+
Use commas, colons, or parentheses instead.
|
|
74
|
+
- Plain, direct prose. Short sentences. Say what the code does.
|
|
75
|
+
- Every public function and class gets a docstring with one short example.
|
|
76
|
+
- Type hints everywhere; `mypy --strict` runs on the package.
|
|
77
|
+
- Keep the public API small. Internal modules start with an underscore.
|
|
78
|
+
|
|
79
|
+
## Pull requests
|
|
80
|
+
|
|
81
|
+
1. Fork, branch, make the change with tests.
|
|
82
|
+
2. Run the full check locally: `uv run ruff check .`, `uv run mypy`,
|
|
83
|
+
`uv run pytest`.
|
|
84
|
+
3. Open a pull request describing what changed and how you verified it.
|
|
85
|
+
|
|
86
|
+
Small, focused pull requests get reviewed faster.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Development container for platforms without native zvec wheels, such as
|
|
2
|
+
# Intel macOS. zvec ships wheels for Linux x86_64 and aarch64, macOS ARM64,
|
|
3
|
+
# and Windows x86_64. Everything (tests, lint, benchmarks) runs fine in here.
|
|
4
|
+
FROM python:3.10-slim
|
|
5
|
+
|
|
6
|
+
ENV UV_PROJECT_ENVIRONMENT=/opt/venv \
|
|
7
|
+
UV_LINK_MODE=copy \
|
|
8
|
+
PYTHONUNBUFFERED=1
|
|
9
|
+
|
|
10
|
+
COPY --from=ghcr.io/astral-sh/uv:0.11.14 /uv /uvx /bin/
|
|
11
|
+
|
|
12
|
+
WORKDIR /workspace
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rauhan Ahmed Siddiqui
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|