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.
Files changed (41) hide show
  1. langchain_dynamic_tools_middleware-0.2.0/.github/ISSUE_TEMPLATE/bug_report.md +31 -0
  2. langchain_dynamic_tools_middleware-0.2.0/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
  3. langchain_dynamic_tools_middleware-0.2.0/.github/PULL_REQUEST_TEMPLATE.md +16 -0
  4. langchain_dynamic_tools_middleware-0.2.0/.github/workflows/ci.yml +37 -0
  5. langchain_dynamic_tools_middleware-0.2.0/.github/workflows/publish.yml +26 -0
  6. langchain_dynamic_tools_middleware-0.2.0/.gitignore +34 -0
  7. langchain_dynamic_tools_middleware-0.2.0/.python-version +1 -0
  8. langchain_dynamic_tools_middleware-0.2.0/CHANGELOG.md +45 -0
  9. langchain_dynamic_tools_middleware-0.2.0/CONTRIBUTING.md +86 -0
  10. langchain_dynamic_tools_middleware-0.2.0/Dockerfile.dev +12 -0
  11. langchain_dynamic_tools_middleware-0.2.0/LICENSE +21 -0
  12. langchain_dynamic_tools_middleware-0.2.0/PKG-INFO +454 -0
  13. langchain_dynamic_tools_middleware-0.2.0/README.md +415 -0
  14. langchain_dynamic_tools_middleware-0.2.0/benchmarks/README.md +89 -0
  15. langchain_dynamic_tools_middleware-0.2.0/benchmarks/RESULTS.md +156 -0
  16. langchain_dynamic_tools_middleware-0.2.0/benchmarks/bfcl/data.py +207 -0
  17. langchain_dynamic_tools_middleware-0.2.0/benchmarks/bfcl/run_bfcl.py +372 -0
  18. langchain_dynamic_tools_middleware-0.2.0/benchmarks/bfcl/scoring.py +108 -0
  19. langchain_dynamic_tools_middleware-0.2.0/benchmarks/common.py +322 -0
  20. langchain_dynamic_tools_middleware-0.2.0/benchmarks/latency/run_latency.py +199 -0
  21. langchain_dynamic_tools_middleware-0.2.0/benchmarks/results/bfcl_results.json +187 -0
  22. langchain_dynamic_tools_middleware-0.2.0/benchmarks/results/latency.png +0 -0
  23. langchain_dynamic_tools_middleware-0.2.0/benchmarks/results/latency_llm_selector.json +29 -0
  24. langchain_dynamic_tools_middleware-0.2.0/benchmarks/results/latency_results.json +81 -0
  25. langchain_dynamic_tools_middleware-0.2.0/benchmarks/results/token_results.json +258 -0
  26. langchain_dynamic_tools_middleware-0.2.0/benchmarks/token_reduction/run_tokens.py +204 -0
  27. langchain_dynamic_tools_middleware-0.2.0/examples/custom_embedders.py +57 -0
  28. langchain_dynamic_tools_middleware-0.2.0/examples/quickstart.py +80 -0
  29. langchain_dynamic_tools_middleware-0.2.0/pyproject.toml +134 -0
  30. langchain_dynamic_tools_middleware-0.2.0/scripts/dev-container.sh +36 -0
  31. langchain_dynamic_tools_middleware-0.2.0/scripts/verify_zvec.py +134 -0
  32. langchain_dynamic_tools_middleware-0.2.0/src/langchain_dynamic_tools/__init__.py +26 -0
  33. langchain_dynamic_tools_middleware-0.2.0/src/langchain_dynamic_tools/_embeddings.py +306 -0
  34. langchain_dynamic_tools_middleware-0.2.0/src/langchain_dynamic_tools/_index.py +365 -0
  35. langchain_dynamic_tools_middleware-0.2.0/src/langchain_dynamic_tools/_middleware.py +298 -0
  36. langchain_dynamic_tools_middleware-0.2.0/src/langchain_dynamic_tools/py.typed +0 -0
  37. langchain_dynamic_tools_middleware-0.2.0/tests/conftest.py +312 -0
  38. langchain_dynamic_tools_middleware-0.2.0/tests/test_embeddings.py +242 -0
  39. langchain_dynamic_tools_middleware-0.2.0/tests/test_index.py +264 -0
  40. langchain_dynamic_tools_middleware-0.2.0/tests/test_middleware.py +255 -0
  41. 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,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.