🛠️ AzureAICommunity - Agent - Tool Limit Middleware
Prevent runaway tool calls by enforcing global and per-tool call limits across every AI agent completion.
Getting Started · Per-Tool Limits · Inspect Usage · How It Works
Overview
azureaicommunity-agent-tool-limit is a lightweight guard layer for AI agent pipelines built on agent-framework. During each completion it tracks every function_call content item emitted by the model and silently suppresses any calls that breach a configurable global cap or an optional per-tool cap. When calls are suppressed the optional on_limit_exceeded callback is invoked.
The middleware does not raise an exception — it drops the over-limit calls so the agent loop can continue cleanly, mirroring the behaviour of the .NET ToolLimitMiddleware.
✨ Features
| Feature | |
|---|---|
| 🔢 | Global call cap — limits the total number of tool invocations per session |
| 🔧 | Per-tool limits — set independent ceilings for individual tool names |
| 🔀 | Streaming support — works with both non-streaming and streaming responses |
| 🤫 | Silent suppression — over-limit calls are removed; no exception is thrown |
| 📣 | on_limit_exceeded callback — sync or async callback invoked when calls are blocked |
| 📊 | Usage introspection — get_current_usage() returns attempted vs allowed counts per tool |
| 🔄 | Resettable — reset() clears counters for a fresh session |
📦 Installation
pip install azureaicommunity-agent-tool-limit
Or install directly from source:
cd AgentFramework/Python/Middleware/ToolLimitMiddleware
pip install -e .
🚀 Quick Start
import asyncio
from agent_framework import tool
from agent_framework.ollama import OllamaChatClient
from tool_limit_middleware import ToolLimitMiddleware, ToolLimits
@tool
def get_weather(location: str) -> str:
return f"The weather in {location} is sunny with a high of 22°C."
async def main():
client = OllamaChatClient(model="llama3.2")
middleware = ToolLimitMiddleware(
limits=ToolLimits(global_max=5),
)
agent = client.as_agent(
name="WeatherAgent",
instructions="You are a helpful assistant with a weather tool.",
tools=[get_weather],
middleware=[middleware],
)
response = await agent.run("What is the weather in Amsterdam?")
print(response.text)
asyncio.run(main())
🔧 Per-Tool Limits
In addition to the global cap, restrict individual tools independently:
middleware = ToolLimitMiddleware(
limits=ToolLimits(
global_max=10,
per_tool_max={
"get_weather": 3,
"search_videos": 2,
},
),
on_limit_exceeded=lambda info: print("Limit hit:", info),
)
Any call to get_weather beyond 3, or to search_videos beyond 2, is silently removed — even if the global limit has not been reached.
📊 Inspect Usage
usage = middleware.get_current_usage()
print(f"Total allowed calls: {usage.total_calls} / {usage.global_limit}")
for tool_name, attempted in usage.per_tool.items():
allowed = usage.per_tool_allowed.get(tool_name, 0)
limit = usage.per_tool_limits.get(tool_name)
limit_text = f" / {limit}" if limit is not None else ""
print(f" {tool_name}: attempted={attempted} allowed={allowed}{limit_text}")
# Reset for a new session
middleware.reset()
For streaming responses, a stream_transform_hook intercepts each ChatResponseUpdate as it arrives and removes over-limit function calls in real time. The on_limit_exceeded callback is fired once via a stream_result_hook after the stream completes.
Metadata
Release files for azureaicommunity-agent-tool-limit 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| azureaicommunity_agent_tool_limit-0.1.0.tar.gz | 9.2 kB | Without provenance | Details for azureaicommunity_agent_tool_limit-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| azureaicommunity_agent_tool_limit-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for azureaicommunity_agent_tool_limit-0.1.0-py3-none-any.whl |
Total release size: 17.1 kB
Release files / azureaicommunity_agent_tool_limit-0.1.0.tar.gz
| Download URL | azureaicommunity_agent_tool_limit-0.1.0.tar.gz |
|---|---|
| Size | 9.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3288bfb79bd0b031dcd63b38088a52b0651ea9048c3f99028715ec799851ac7f
|
|
BLAKE2b-256 checksum How to use checksums |
688ca4fda2d17e07d6c4c9f6165fc7a5e5e2a3dcf00c8cd8a603ea465b723b0e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.13
|
Release files / azureaicommunity_agent_tool_limit-0.1.0-py3-none-any.whl
| Download URL | azureaicommunity_agent_tool_limit-0.1.0-py3-none-any.whl |
|---|---|
| Size | 7.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9b9d2279f96acb0605a85a490b2b88d71d5446c4a4a19bced1c2edd35d93c875
|
|
BLAKE2b-256 checksum How to use checksums |
9a71aee0dfc59a883ecfbf1663cf8aa899ca6481c4b96348f41665e2f59e8daa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.13
|
Security for azureaicommunity-agent-tool-limit 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.