agent-framework-botsrated 0.1.0__tar.gz → 0.1.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.
- {agent_framework_botsrated-0.1.0 → agent_framework_botsrated-0.1.2}/PKG-INFO +8 -6
- {agent_framework_botsrated-0.1.0 → agent_framework_botsrated-0.1.2}/README.md +6 -4
- {agent_framework_botsrated-0.1.0 → agent_framework_botsrated-0.1.2}/pyproject.toml +2 -2
- {agent_framework_botsrated-0.1.0 → agent_framework_botsrated-0.1.2}/src/agent_framework_botsrated/__init__.py +6 -1
- {agent_framework_botsrated-0.1.0 → agent_framework_botsrated-0.1.2}/src/agent_framework_botsrated/_middleware.py +3 -1
- {agent_framework_botsrated-0.1.0 → agent_framework_botsrated-0.1.2}/tests/test_middleware.py +11 -0
- agent_framework_botsrated-0.1.0/catalog-pr/PR_BODY.md +0 -38
- {agent_framework_botsrated-0.1.0 → agent_framework_botsrated-0.1.2}/.gitignore +0 -0
- {agent_framework_botsrated-0.1.0 → agent_framework_botsrated-0.1.2}/LICENSE +0 -0
- {agent_framework_botsrated-0.1.0 → agent_framework_botsrated-0.1.2}/examples/quickstart.py +0 -0
- {agent_framework_botsrated-0.1.0 → agent_framework_botsrated-0.1.2}/src/agent_framework_botsrated/py.typed +0 -0
- {agent_framework_botsrated-0.1.0 → agent_framework_botsrated-0.1.2}/tests/conftest.py +0 -0
- {agent_framework_botsrated-0.1.0 → agent_framework_botsrated-0.1.2}/tests/test_live.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: agent-framework-botsrated
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: BotsRated pre-payment check for Microsoft Agent Framework: function middleware that checks an x402 payTo with the free BotsRated preflight before a payment tool runs.
|
|
5
5
|
Project-URL: Homepage, https://botsrated.com
|
|
6
6
|
Project-URL: Repository, https://github.com/botsrated/botsrated
|
|
@@ -11,7 +11,7 @@ License-File: LICENSE
|
|
|
11
11
|
Keywords: agent-framework,base,botsrated,microsoft-agent-framework,middleware,payments,usdc,x402
|
|
12
12
|
Requires-Python: >=3.10
|
|
13
13
|
Requires-Dist: agent-framework-core<2,>=1.22
|
|
14
|
-
Requires-Dist: botsrated<0.2,>=0.1.
|
|
14
|
+
Requires-Dist: botsrated<0.2,>=0.1.5
|
|
15
15
|
Provides-Extra: mcp
|
|
16
16
|
Requires-Dist: mcp<3,>=1.24; extra == 'mcp'
|
|
17
17
|
Requires-Dist: tenacity<10,>=9.1.4; extra == 'mcp'
|
|
@@ -30,12 +30,12 @@ Maintained by BotsRated, not by Microsoft. Issues: https://github.com/botsrated/
|
|
|
30
30
|
## Install
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
pip install
|
|
33
|
+
pip install agent-framework-botsrated
|
|
34
34
|
# with the hosted MCP server example:
|
|
35
|
-
pip install "agent-framework-botsrated[mcp]
|
|
35
|
+
pip install "agent-framework-botsrated[mcp]"
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
Requires Python 3.10+, `agent-framework-core>=1.22,<2` and [`botsrated`](https://pypi.org/project/botsrated/) 0.1.2
|
|
38
|
+
Requires Python 3.10+, `agent-framework-core>=1.22,<2` and [`botsrated`](https://pypi.org/project/botsrated/) 0.1.5+ (below 0.2).
|
|
39
39
|
Tested with agent-framework-core 1.22.0 (with mcp 1.30) and 1.23.0 (with mcp 2.3). agent-framework-core 1.22 can't
|
|
40
40
|
initialize MCP sessions with mcp 2.x, so pin `mcp<2` there if you use the hosted MCP server.
|
|
41
41
|
|
|
@@ -79,7 +79,9 @@ Default policy (from `botsrated.GuardPolicy`, configurable through `guard=PrePay
|
|
|
79
79
|
|
|
80
80
|
The middleware checks what the payment tool was asked to pay. If your tool fetches the 402 itself and signs it, also
|
|
81
81
|
register `botsrated.PrePaymentGuard().x402_hook` on your `x402Client`'s `on_before_payment_creation` so the check
|
|
82
|
-
runs on the exact quote being signed.
|
|
82
|
+
runs on the exact quote being signed, and make the request through `guard.wrap_get(...)` (or inside
|
|
83
|
+
`with botsrated.paying_request(url):`) so the guard checks the host actually being paid rather than the
|
|
84
|
+
seller-supplied 402 `resource.url` (botsrated 0.1.5+).
|
|
83
85
|
|
|
84
86
|
## Tool: let the model check a payment option
|
|
85
87
|
|
|
@@ -11,12 +11,12 @@ Maintained by BotsRated, not by Microsoft. Issues: https://github.com/botsrated/
|
|
|
11
11
|
## Install
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
pip install
|
|
14
|
+
pip install agent-framework-botsrated
|
|
15
15
|
# with the hosted MCP server example:
|
|
16
|
-
pip install "agent-framework-botsrated[mcp]
|
|
16
|
+
pip install "agent-framework-botsrated[mcp]"
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
Requires Python 3.10+, `agent-framework-core>=1.22,<2` and [`botsrated`](https://pypi.org/project/botsrated/) 0.1.2
|
|
19
|
+
Requires Python 3.10+, `agent-framework-core>=1.22,<2` and [`botsrated`](https://pypi.org/project/botsrated/) 0.1.5+ (below 0.2).
|
|
20
20
|
Tested with agent-framework-core 1.22.0 (with mcp 1.30) and 1.23.0 (with mcp 2.3). agent-framework-core 1.22 can't
|
|
21
21
|
initialize MCP sessions with mcp 2.x, so pin `mcp<2` there if you use the hosted MCP server.
|
|
22
22
|
|
|
@@ -60,7 +60,9 @@ Default policy (from `botsrated.GuardPolicy`, configurable through `guard=PrePay
|
|
|
60
60
|
|
|
61
61
|
The middleware checks what the payment tool was asked to pay. If your tool fetches the 402 itself and signs it, also
|
|
62
62
|
register `botsrated.PrePaymentGuard().x402_hook` on your `x402Client`'s `on_before_payment_creation` so the check
|
|
63
|
-
runs on the exact quote being signed.
|
|
63
|
+
runs on the exact quote being signed, and make the request through `guard.wrap_get(...)` (or inside
|
|
64
|
+
`with botsrated.paying_request(url):`) so the guard checks the host actually being paid rather than the
|
|
65
|
+
seller-supplied 402 `resource.url` (botsrated 0.1.5+).
|
|
64
66
|
|
|
65
67
|
## Tool: let the model check a payment option
|
|
66
68
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "agent-framework-botsrated"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.2"
|
|
4
4
|
description = "BotsRated pre-payment check for Microsoft Agent Framework: function middleware that checks an x402 payTo with the free BotsRated preflight before a payment tool runs."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
7
7
|
requires-python = ">=3.10"
|
|
8
|
-
dependencies = ["agent-framework-core>=1.22,<2", "botsrated>=0.1.
|
|
8
|
+
dependencies = ["agent-framework-core>=1.22,<2", "botsrated>=0.1.5,<0.2"]
|
|
9
9
|
keywords = ["agent-framework", "microsoft-agent-framework", "middleware", "x402", "botsrated", "payments", "base", "usdc"]
|
|
10
10
|
|
|
11
11
|
[project.optional-dependencies]
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""BotsRated pre-payment checks for Microsoft Agent Framework (Python)."""
|
|
2
2
|
|
|
3
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
4
|
+
|
|
3
5
|
from agent_framework_botsrated._middleware import (
|
|
4
6
|
DECISION_METADATA_KEY,
|
|
5
7
|
BotsRatedPaymentBlocked,
|
|
@@ -25,4 +27,7 @@ __all__ = [
|
|
|
25
27
|
"decision_to_dict",
|
|
26
28
|
"default_quote_extractor",
|
|
27
29
|
]
|
|
28
|
-
|
|
30
|
+
try:
|
|
31
|
+
__version__ = version("agent-framework-botsrated")
|
|
32
|
+
except PackageNotFoundError: # running from a source tree without an install
|
|
33
|
+
__version__ = "0+unknown"
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
6
|
import json
|
|
7
|
+
import re
|
|
7
8
|
from collections.abc import Awaitable, Callable, Collection, Mapping
|
|
8
9
|
from dataclasses import dataclass
|
|
9
10
|
from typing import Annotated, Any, Literal
|
|
@@ -52,7 +53,8 @@ def default_quote_extractor(args: Mapping[str, Any]) -> PaymentQuote:
|
|
|
52
53
|
if not isinstance(url, str) or not isinstance(pay_to, str) or amount is None:
|
|
53
54
|
missing = [n for n, v in (("url", url), ("pay_to", pay_to), ("amount", amount)) if v is None]
|
|
54
55
|
raise ValueError(f"payment arguments are missing or not text: {', '.join(missing) or 'url/pay_to'}")
|
|
55
|
-
|
|
56
|
+
# ASCII digits only: str.isdigit() also accepts e.g. Arabic-Indic or full-width digits.
|
|
57
|
+
if isinstance(amount, bool) or re.fullmatch(r"[0-9]+", str(amount)) is None:
|
|
56
58
|
raise ValueError("amount must be an integer number of atomic units")
|
|
57
59
|
network = _first(args, "network") or DEFAULT_NETWORK
|
|
58
60
|
scheme = _first(args, "scheme") or "exact"
|
{agent_framework_botsrated-0.1.0 → agent_framework_botsrated-0.1.2}/tests/test_middleware.py
RENAMED
|
@@ -161,6 +161,9 @@ async def test_unreachable_botsrated_follows_guard_fail_open_setting() -> None:
|
|
|
161
161
|
{"url": SELLER, "pay_to": GOOD},
|
|
162
162
|
{"url": SELLER, "pay_to": GOOD, "amount": "1.5"},
|
|
163
163
|
{"url": SELLER, "pay_to": GOOD, "amount": True},
|
|
164
|
+
{"url": SELLER, "pay_to": GOOD, "amount": "\u0661\u0660\u0660\u0660"},
|
|
165
|
+
{"url": SELLER, "pay_to": GOOD, "amount": "\uff11\uff10"},
|
|
166
|
+
{"url": SELLER, "pay_to": GOOD, "amount": "1\u00b2"},
|
|
164
167
|
{"pay_to": GOOD, "amount": "1"},
|
|
165
168
|
{"url": 5, "pay_to": GOOD, "amount": "1"},
|
|
166
169
|
],
|
|
@@ -178,3 +181,11 @@ def test_default_extractor_reads_camel_case() -> None:
|
|
|
178
181
|
def test_needs_a_payment_tool() -> None:
|
|
179
182
|
with pytest.raises(ValueError):
|
|
180
183
|
BotsRatedPaymentMiddleware([])
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def test_version_comes_from_package_metadata() -> None:
|
|
187
|
+
from importlib.metadata import version
|
|
188
|
+
|
|
189
|
+
import agent_framework_botsrated
|
|
190
|
+
|
|
191
|
+
assert agent_framework_botsrated.__version__ == version("agent-framework-botsrated") == "0.1.2"
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
### Motivation & Context
|
|
2
|
-
|
|
3
|
-
I work on BotsRated (https://botsrated.com), so I'm affiliated with the project this row lists. BotsRated probes paid x402 sellers on Base and records the payTo wallet each one quotes. This PR adds our Agent Framework integration to the Middleware section of the Python catalog.
|
|
4
|
-
|
|
5
|
-
The integration is published for the Python SDK. `agent-framework-botsrated` 0.1.0 is in our public MIT repository at https://github.com/botsrated/botsrated/tree/main/integrations/microsoft-agent-framework. You install it with `pip install "agent-framework-botsrated @ git+https://github.com/botsrated/botsrated#subdirectory=integrations/microsoft-agent-framework"`. It isn't on PyPI yet; its dependency [`botsrated`](https://pypi.org/project/botsrated/) is. The package works like this:
|
|
6
|
-
|
|
7
|
-
- `BotsRatedPaymentMiddleware` subclasses `FunctionMiddleware` and only checks the payment functions you name. It reads the quote (url, pay_to, amount, network) from the call's arguments, or uses an extractor you supply. It then asks BotsRated's free preflight (no key, no wallet) whether that payTo was observed for the seller.
|
|
8
|
-
- If the payTo wasn't observed, or the quote can't be read, the call never reaches `call_next`. The reason becomes the call's result so the model reads it. With `on_block="raise"`, the run ends with a `MiddlewareFailure` subclass instead. The decision is stored in `context.metadata["botsrated_decision"]`.
|
|
9
|
-
- `botsrated_check_payment_tool()` is a `FunctionTool` the model can call to check a payment option itself.
|
|
10
|
-
|
|
11
|
-
The row links to the integration's README, and issues go to https://github.com/botsrated/botsrated/issues/new. I'm not listing our hosted MCP server, because the catalog excludes standard MCP servers.
|
|
12
|
-
|
|
13
|
-
Testing: 17 tests ran with agent-framework-core 1.23.0 and 1.22.0, using a scripted chat client built on `FunctionInvocationLayer` and `ChatMiddlewareLayer`, so no model API key was needed. 13 tests run offline. 4 tests are live and call the real free BotsRated preflight and the hosted MCP server. A payment call with an unknown payTo was blocked without running, and a call with the payTo BotsRated observed for the seller ran. The payment function is a stub, so nothing was paid. To reproduce in a minute with no API key, clone the repository, `pip install -e integrations/microsoft-agent-framework`, then run `python integrations/microsoft-agent-framework/examples/quickstart.py`.
|
|
14
|
-
|
|
15
|
-
### Description & Review Guide
|
|
16
|
-
|
|
17
|
-
- **What are the major changes?** One row in the Middleware section of `python/samples/community-projects.md`, in alphabetical order between ACGS and Tracekit.
|
|
18
|
-
- **What is the impact of these changes?** Documentation only.
|
|
19
|
-
- **What do you want reviewers to focus on?** The wording of the row. I'm happy to change it or move it.
|
|
20
|
-
|
|
21
|
-
### Related Issue
|
|
22
|
-
|
|
23
|
-
N/A - trivial change: one catalog row in the format the catalog criteria define, no code.
|
|
24
|
-
|
|
25
|
-
### AI Assistance
|
|
26
|
-
|
|
27
|
-
- [ ] No material AI assistance was used.
|
|
28
|
-
- [x] This is an AI-assisted contribution. I reviewed, understood, and verified all submitted content and accept responsibility for it.
|
|
29
|
-
|
|
30
|
-
AI assistance details: an AI assistant drafted the catalog row, this description, and the linked integration's code, tests and README. I tested them as described above.
|
|
31
|
-
|
|
32
|
-
### Contribution Checklist
|
|
33
|
-
|
|
34
|
-
- [ ] The code builds clean without any errors or warnings
|
|
35
|
-
- [ ] All unit tests pass, and I have added new tests where possible
|
|
36
|
-
- [x] The PR follows the [Contribution Guidelines](https://github.com/microsoft/agent-framework/blob/main/CONTRIBUTING.md)
|
|
37
|
-
- [x] This PR links to an agreed issue with no competing open PR, or the Related Issue section documents a trivial-change or repository-automation exception.
|
|
38
|
-
- [x] **This is not a breaking change.** If it _is_ a breaking change, add the `breaking change` label (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|