bridgenode-cli 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.
- bridgenode_cli-0.1.2/LICENSE +16 -0
- bridgenode_cli-0.1.2/PKG-INFO +97 -0
- bridgenode_cli-0.1.2/README.md +68 -0
- {bridgenode_cli-0.1.0 → bridgenode_cli-0.1.2}/bridgenode_cli/main.py +26 -26
- bridgenode_cli-0.1.2/bridgenode_cli/py.typed +0 -0
- bridgenode_cli-0.1.2/bridgenode_cli.egg-info/PKG-INFO +97 -0
- {bridgenode_cli-0.1.0 → bridgenode_cli-0.1.2}/bridgenode_cli.egg-info/SOURCES.txt +2 -0
- bridgenode_cli-0.1.2/pyproject.toml +51 -0
- {bridgenode_cli-0.1.0 → bridgenode_cli-0.1.2}/tests/test_cli.py +13 -13
- {bridgenode_cli-0.1.0 → bridgenode_cli-0.1.2}/tests/test_cli_integration.py +19 -19
- bridgenode_cli-0.1.0/PKG-INFO +0 -65
- bridgenode_cli-0.1.0/README.md +0 -55
- bridgenode_cli-0.1.0/bridgenode_cli.egg-info/PKG-INFO +0 -65
- bridgenode_cli-0.1.0/pyproject.toml +0 -24
- {bridgenode_cli-0.1.0 → bridgenode_cli-0.1.2}/bridgenode_cli/__init__.py +0 -0
- {bridgenode_cli-0.1.0 → bridgenode_cli-0.1.2}/bridgenode_cli.egg-info/dependency_links.txt +0 -0
- {bridgenode_cli-0.1.0 → bridgenode_cli-0.1.2}/bridgenode_cli.egg-info/entry_points.txt +0 -0
- {bridgenode_cli-0.1.0 → bridgenode_cli-0.1.2}/bridgenode_cli.egg-info/requires.txt +0 -0
- {bridgenode_cli-0.1.0 → bridgenode_cli-0.1.2}/bridgenode_cli.egg-info/top_level.txt +0 -0
- {bridgenode_cli-0.1.0 → bridgenode_cli-0.1.2}/setup.cfg +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
MIT No Attribution
|
|
2
|
+
|
|
3
|
+
Copyright 2026 BridgeNode
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
|
6
|
+
software and associated documentation files (the "Software"), to deal in the Software
|
|
7
|
+
without restriction, including without limitation the rights to use, copy, modify,
|
|
8
|
+
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
|
9
|
+
permit persons to whom the Software is furnished to do so.
|
|
10
|
+
|
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
12
|
+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
13
|
+
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
14
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
15
|
+
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
|
16
|
+
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bridgenode-cli
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: BridgeNode CLI — AI inference with x402 payment on Solana USDC. No API keys.
|
|
5
|
+
Author-email: BridgeNode <eli.BNx@proton.me>
|
|
6
|
+
License-Expression: MIT-0
|
|
7
|
+
Project-URL: Homepage, https://bridgenode.cc
|
|
8
|
+
Project-URL: Repository, https://github.com/applefanaimail-blip/bridgenode-llm
|
|
9
|
+
Project-URL: Documentation, https://bridgenode.cc/llms.txt
|
|
10
|
+
Keywords: x402,solana,usdc,ai,llm,cli,agents,payment,bridgenode,openai-compatible,chat,inference,micropayments
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: bridgenode-llm>=0.1.0
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=9.1.1; extra == "dev"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# bridgenode-cli
|
|
31
|
+
|
|
32
|
+
[](https://pypi.org/project/bridgenode-cli/)
|
|
33
|
+
[](https://pypi.org/project/bridgenode-cli/)
|
|
34
|
+
[](https://opensource.org/license/mit-0/)
|
|
35
|
+
[](https://pypi.org/project/bridgenode-cli/)
|
|
36
|
+
|
|
37
|
+
BridgeNode CLI — AI inference without API keys. Pay per request with **Solana USDC via x402**. The payment handshake is fully automatic, and fees are sponsored — no SOL needed.
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install bridgenode-cli
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Or install the full toolkit (SDK + CLI):
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install bridgenode
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Usage
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Single chat completion (payment handshake fully automatic)
|
|
55
|
+
bridgenode chat "Hello!" --model deepseek-v4-flash
|
|
56
|
+
|
|
57
|
+
# Smart routing: auto / eco / premium
|
|
58
|
+
bridgenode chat "Analyze this code" --mode auto
|
|
59
|
+
|
|
60
|
+
# Model list + prices (no payment)
|
|
61
|
+
bridgenode models
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Options
|
|
65
|
+
|
|
66
|
+
| Option | Description |
|
|
67
|
+
|---|---|
|
|
68
|
+
| `--model` | Explicit model id (see `bridgenode models`) |
|
|
69
|
+
| `--mode` | `auto` / `eco` / `premium` (smart routing) |
|
|
70
|
+
| `--max-tokens` | Max output tokens (billed upfront) |
|
|
71
|
+
| `--base-url` | Base URL (default: `BRIDGENODE_BASE_URL` / https://bridgenode.cc/v1) |
|
|
72
|
+
| `--max-per-call` / `--daily-cap` | Spending policy (fail-closed) |
|
|
73
|
+
|
|
74
|
+
## Configuration (.env)
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Required — your Solana wallet private key (base58)
|
|
78
|
+
BRIDGENODE_WALLET_KEY=...
|
|
79
|
+
# Optional: BRIDGENODE_BASE_URL, BRIDGENODE_MAX_PER_CALL, BRIDGENODE_DAILY_CAP
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Security
|
|
83
|
+
|
|
84
|
+
- **Receipt verification:** every response receipt is verified — invalid receipt → error.
|
|
85
|
+
- **Spending policy (fail-closed):** max USD per call / per day — checked BEFORE signing.
|
|
86
|
+
|
|
87
|
+
## Requirements
|
|
88
|
+
|
|
89
|
+
- Python ≥ 3.11
|
|
90
|
+
- A Solana wallet with a USDC token account (ATA)
|
|
91
|
+
|
|
92
|
+
## Links
|
|
93
|
+
|
|
94
|
+
- Website: https://bridgenode.cc
|
|
95
|
+
- Models & prices: https://bridgenode.cc/v1/models
|
|
96
|
+
- Documentation: https://bridgenode.cc/llms.txt
|
|
97
|
+
- Protocol: x402 V2 (https://docs.x402.org)
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# bridgenode-cli
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/bridgenode-cli/)
|
|
4
|
+
[](https://pypi.org/project/bridgenode-cli/)
|
|
5
|
+
[](https://opensource.org/license/mit-0/)
|
|
6
|
+
[](https://pypi.org/project/bridgenode-cli/)
|
|
7
|
+
|
|
8
|
+
BridgeNode CLI — AI inference without API keys. Pay per request with **Solana USDC via x402**. The payment handshake is fully automatic, and fees are sponsored — no SOL needed.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pip install bridgenode-cli
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Or install the full toolkit (SDK + CLI):
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install bridgenode
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Single chat completion (payment handshake fully automatic)
|
|
26
|
+
bridgenode chat "Hello!" --model deepseek-v4-flash
|
|
27
|
+
|
|
28
|
+
# Smart routing: auto / eco / premium
|
|
29
|
+
bridgenode chat "Analyze this code" --mode auto
|
|
30
|
+
|
|
31
|
+
# Model list + prices (no payment)
|
|
32
|
+
bridgenode models
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Options
|
|
36
|
+
|
|
37
|
+
| Option | Description |
|
|
38
|
+
|---|---|
|
|
39
|
+
| `--model` | Explicit model id (see `bridgenode models`) |
|
|
40
|
+
| `--mode` | `auto` / `eco` / `premium` (smart routing) |
|
|
41
|
+
| `--max-tokens` | Max output tokens (billed upfront) |
|
|
42
|
+
| `--base-url` | Base URL (default: `BRIDGENODE_BASE_URL` / https://bridgenode.cc/v1) |
|
|
43
|
+
| `--max-per-call` / `--daily-cap` | Spending policy (fail-closed) |
|
|
44
|
+
|
|
45
|
+
## Configuration (.env)
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Required — your Solana wallet private key (base58)
|
|
49
|
+
BRIDGENODE_WALLET_KEY=...
|
|
50
|
+
# Optional: BRIDGENODE_BASE_URL, BRIDGENODE_MAX_PER_CALL, BRIDGENODE_DAILY_CAP
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Security
|
|
54
|
+
|
|
55
|
+
- **Receipt verification:** every response receipt is verified — invalid receipt → error.
|
|
56
|
+
- **Spending policy (fail-closed):** max USD per call / per day — checked BEFORE signing.
|
|
57
|
+
|
|
58
|
+
## Requirements
|
|
59
|
+
|
|
60
|
+
- Python ≥ 3.11
|
|
61
|
+
- A Solana wallet with a USDC token account (ATA)
|
|
62
|
+
|
|
63
|
+
## Links
|
|
64
|
+
|
|
65
|
+
- Website: https://bridgenode.cc
|
|
66
|
+
- Models & prices: https://bridgenode.cc/v1/models
|
|
67
|
+
- Documentation: https://bridgenode.cc/llms.txt
|
|
68
|
+
- Protocol: x402 V2 (https://docs.x402.org)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
"""main.py — bridgenode CLI (§8.4, fix.md 4.4
|
|
1
|
+
"""main.py — bridgenode CLI (§8.4, fix.md 4.4 step 1).
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
- `bridgenode chat "<prompt>"` —
|
|
5
|
-
(SDK: 402 →
|
|
6
|
-
- `bridgenode models` —
|
|
3
|
+
Commands:
|
|
4
|
+
- `bridgenode chat "<prompt>"` — single chat completion via the x402 handshake
|
|
5
|
+
(SDK: 402 → partial TX → PAYMENT-SIGNATURE → 200; §4.1)
|
|
6
|
+
- `bridgenode models` — model list + prices from GET /v1/models (§5.2)
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
§5.1/§5.8), --max-tokens.
|
|
10
|
-
LLMClient (P4).
|
|
8
|
+
Options: --model (explicit, §5.1), --mode auto/eco/premium (smart routing,
|
|
9
|
+
§5.1/§5.8), --max-tokens. All payment is hidden — uses the official
|
|
10
|
+
LLMClient (P4). Errors → stderr + exit 1; success → stdout + exit 0.
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
13
|
from __future__ import annotations
|
|
@@ -21,9 +21,9 @@ from bridgenode_llm import BridgenodeError, LLMClient
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
def _client(args: argparse.Namespace) -> LLMClient:
|
|
24
|
-
"""LLMClient
|
|
25
|
-
# None
|
|
26
|
-
#
|
|
24
|
+
"""LLMClient from CLI arguments (key ONLY from .env, §8.4)."""
|
|
25
|
+
# None values are not passed — the SDK uses defaults (§8.5);
|
|
26
|
+
# otherwise timeout=None would enter the flow timeout calculation (item 42)
|
|
27
27
|
kwargs: dict[str, Any] = {}
|
|
28
28
|
if args.base_url:
|
|
29
29
|
kwargs["base_url"] = args.base_url
|
|
@@ -58,10 +58,10 @@ def cmd_chat(args: argparse.Namespace) -> int:
|
|
|
58
58
|
|
|
59
59
|
|
|
60
60
|
def cmd_models(args: argparse.Namespace) -> int:
|
|
61
|
-
"""`bridgenode models` —
|
|
61
|
+
"""`bridgenode models` — model list + prices (§5.2).
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
Public endpoint (no payment) — direct HTTP, without the SDK (the SDK has
|
|
64
|
+
only chat(), protocol §8.4)."""
|
|
65
65
|
import httpx
|
|
66
66
|
|
|
67
67
|
base_url = (args.base_url or os.environ.get("BRIDGENODE_BASE_URL")
|
|
@@ -89,33 +89,33 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
89
89
|
parser = argparse.ArgumentParser(
|
|
90
90
|
prog="bridgenode",
|
|
91
91
|
description=(
|
|
92
|
-
"BridgeNode CLI — AI inference,
|
|
93
|
-
"
|
|
92
|
+
"BridgeNode CLI — AI inference, payment via Solana USDC x402. "
|
|
93
|
+
"No API keys."
|
|
94
94
|
),
|
|
95
95
|
)
|
|
96
96
|
parser.add_argument("--base-url", default=None,
|
|
97
97
|
help="Base URL (default: BRIDGENODE_BASE_URL / https://bridgenode.cc/v1)")
|
|
98
98
|
parser.add_argument("--initial-timeout", type=float, default=None,
|
|
99
|
-
help="
|
|
99
|
+
help="Initial request timeout s (queue until 402, §5.7)")
|
|
100
100
|
parser.add_argument("--retry-timeout", type=float, default=None,
|
|
101
|
-
help="Retry timeout s (≤115s
|
|
101
|
+
help="Retry timeout s (≤115s budget, §4.3)")
|
|
102
102
|
parser.add_argument("--max-per-call", type=float, default=None,
|
|
103
|
-
help="Spending policy: max USD per call (
|
|
103
|
+
help="Spending policy: max USD per call (step 2)")
|
|
104
104
|
parser.add_argument("--daily-cap", type=float, default=None,
|
|
105
|
-
help="Spending policy: max USD per day (
|
|
105
|
+
help="Spending policy: max USD per day (step 2)")
|
|
106
106
|
sub = parser.add_subparsers(dest="command", required=True)
|
|
107
107
|
|
|
108
|
-
p_chat = sub.add_parser("chat", help="
|
|
109
|
-
p_chat.add_argument("prompt", help="Prompt
|
|
108
|
+
p_chat = sub.add_parser("chat", help="Single chat completion via x402 (§4.1)")
|
|
109
|
+
p_chat.add_argument("prompt", help="Prompt text")
|
|
110
110
|
p_chat.add_argument("--model", default=None,
|
|
111
|
-
help="Explicit model id (
|
|
111
|
+
help="Explicit model id (see `bridgenode models`)")
|
|
112
112
|
p_chat.add_argument("--mode", choices=["auto", "eco", "premium"], default=None,
|
|
113
|
-
help="Smart routing
|
|
113
|
+
help="Smart routing profile (§5.1/§5.8)")
|
|
114
114
|
p_chat.add_argument("--max-tokens", type=int, default=None,
|
|
115
|
-
help="Max output
|
|
115
|
+
help="Max output tokens (billing upfront, §4.2)")
|
|
116
116
|
p_chat.set_defaults(func=cmd_chat)
|
|
117
117
|
|
|
118
|
-
p_models = sub.add_parser("models", help="
|
|
118
|
+
p_models = sub.add_parser("models", help="Model list + prices (§5.2)")
|
|
119
119
|
p_models.set_defaults(func=cmd_models)
|
|
120
120
|
|
|
121
121
|
return parser
|
|
File without changes
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bridgenode-cli
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: BridgeNode CLI — AI inference with x402 payment on Solana USDC. No API keys.
|
|
5
|
+
Author-email: BridgeNode <eli.BNx@proton.me>
|
|
6
|
+
License-Expression: MIT-0
|
|
7
|
+
Project-URL: Homepage, https://bridgenode.cc
|
|
8
|
+
Project-URL: Repository, https://github.com/applefanaimail-blip/bridgenode-llm
|
|
9
|
+
Project-URL: Documentation, https://bridgenode.cc/llms.txt
|
|
10
|
+
Keywords: x402,solana,usdc,ai,llm,cli,agents,payment,bridgenode,openai-compatible,chat,inference,micropayments
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: bridgenode-llm>=0.1.0
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=9.1.1; extra == "dev"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# bridgenode-cli
|
|
31
|
+
|
|
32
|
+
[](https://pypi.org/project/bridgenode-cli/)
|
|
33
|
+
[](https://pypi.org/project/bridgenode-cli/)
|
|
34
|
+
[](https://opensource.org/license/mit-0/)
|
|
35
|
+
[](https://pypi.org/project/bridgenode-cli/)
|
|
36
|
+
|
|
37
|
+
BridgeNode CLI — AI inference without API keys. Pay per request with **Solana USDC via x402**. The payment handshake is fully automatic, and fees are sponsored — no SOL needed.
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install bridgenode-cli
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Or install the full toolkit (SDK + CLI):
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install bridgenode
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Usage
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Single chat completion (payment handshake fully automatic)
|
|
55
|
+
bridgenode chat "Hello!" --model deepseek-v4-flash
|
|
56
|
+
|
|
57
|
+
# Smart routing: auto / eco / premium
|
|
58
|
+
bridgenode chat "Analyze this code" --mode auto
|
|
59
|
+
|
|
60
|
+
# Model list + prices (no payment)
|
|
61
|
+
bridgenode models
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Options
|
|
65
|
+
|
|
66
|
+
| Option | Description |
|
|
67
|
+
|---|---|
|
|
68
|
+
| `--model` | Explicit model id (see `bridgenode models`) |
|
|
69
|
+
| `--mode` | `auto` / `eco` / `premium` (smart routing) |
|
|
70
|
+
| `--max-tokens` | Max output tokens (billed upfront) |
|
|
71
|
+
| `--base-url` | Base URL (default: `BRIDGENODE_BASE_URL` / https://bridgenode.cc/v1) |
|
|
72
|
+
| `--max-per-call` / `--daily-cap` | Spending policy (fail-closed) |
|
|
73
|
+
|
|
74
|
+
## Configuration (.env)
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Required — your Solana wallet private key (base58)
|
|
78
|
+
BRIDGENODE_WALLET_KEY=...
|
|
79
|
+
# Optional: BRIDGENODE_BASE_URL, BRIDGENODE_MAX_PER_CALL, BRIDGENODE_DAILY_CAP
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Security
|
|
83
|
+
|
|
84
|
+
- **Receipt verification:** every response receipt is verified — invalid receipt → error.
|
|
85
|
+
- **Spending policy (fail-closed):** max USD per call / per day — checked BEFORE signing.
|
|
86
|
+
|
|
87
|
+
## Requirements
|
|
88
|
+
|
|
89
|
+
- Python ≥ 3.11
|
|
90
|
+
- A Solana wallet with a USDC token account (ATA)
|
|
91
|
+
|
|
92
|
+
## Links
|
|
93
|
+
|
|
94
|
+
- Website: https://bridgenode.cc
|
|
95
|
+
- Models & prices: https://bridgenode.cc/v1/models
|
|
96
|
+
- Documentation: https://bridgenode.cc/llms.txt
|
|
97
|
+
- Protocol: x402 V2 (https://docs.x402.org)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "bridgenode-cli"
|
|
3
|
+
version = "0.1.2"
|
|
4
|
+
description = "BridgeNode CLI — AI inference with x402 payment on Solana USDC. No API keys."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
license = "MIT-0"
|
|
8
|
+
license-files = ["LICENSE"]
|
|
9
|
+
authors = [
|
|
10
|
+
{ name = "BridgeNode", email = "eli.BNx@proton.me" },
|
|
11
|
+
]
|
|
12
|
+
keywords = ["x402", "solana", "usdc", "ai", "llm", "cli", "agents", "payment", "bridgenode", "openai-compatible", "chat", "inference", "micropayments"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 4 - Beta",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"Operating System :: OS Independent",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Programming Language :: Python :: 3.14",
|
|
23
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
24
|
+
"Typing :: Typed",
|
|
25
|
+
]
|
|
26
|
+
dependencies = [
|
|
27
|
+
"bridgenode-llm>=0.1.0",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.optional-dependencies]
|
|
31
|
+
dev = [
|
|
32
|
+
"pytest>=9.1.1",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.urls]
|
|
36
|
+
Homepage = "https://bridgenode.cc"
|
|
37
|
+
Repository = "https://github.com/applefanaimail-blip/bridgenode-llm"
|
|
38
|
+
Documentation = "https://bridgenode.cc/llms.txt"
|
|
39
|
+
|
|
40
|
+
[project.scripts]
|
|
41
|
+
bridgenode = "bridgenode_cli.main:main"
|
|
42
|
+
|
|
43
|
+
[build-system]
|
|
44
|
+
requires = ["setuptools>=75"]
|
|
45
|
+
build-backend = "setuptools.build_meta"
|
|
46
|
+
|
|
47
|
+
[tool.setuptools.packages.find]
|
|
48
|
+
include = ["bridgenode_cli*"]
|
|
49
|
+
|
|
50
|
+
[tool.setuptools.package-data]
|
|
51
|
+
bridgenode_cli = ["py.typed"]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
"""test_cli.py — bridgenode CLI
|
|
1
|
+
"""test_cli.py — bridgenode CLI tests (fix.md 4.4 z1).
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
(
|
|
3
|
+
Checks command output and argument passing with a mocked LLMClient
|
|
4
|
+
(no network, no payment). Full mock-402 path — 4.4 z2.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
@@ -12,13 +12,13 @@ import pytest
|
|
|
12
12
|
|
|
13
13
|
from bridgenode_llm import BridgenodeError
|
|
14
14
|
|
|
15
|
-
# ⚠️ import bridgenode_cli.main as cli
|
|
16
|
-
#
|
|
15
|
+
# ⚠️ import bridgenode_cli.main as cli DOES NOT WORK: __init__ `from .main import main`
|
|
16
|
+
# shadows the submodule — cli becomes a function. We use importlib.
|
|
17
17
|
cli = importlib.import_module("bridgenode_cli.main")
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class FakeClient:
|
|
21
|
-
"""LLMClient
|
|
21
|
+
"""LLMClient stand-in — records calls, returns fake responses."""
|
|
22
22
|
|
|
23
23
|
def __init__(self, **kwargs):
|
|
24
24
|
self.kwargs = kwargs
|
|
@@ -30,7 +30,7 @@ class FakeClient:
|
|
|
30
30
|
"id": "cmpl-1",
|
|
31
31
|
"object": "chat.completion",
|
|
32
32
|
"choices": [{"index": 0,
|
|
33
|
-
"message": {"role": "assistant", "content": "
|
|
33
|
+
"message": {"role": "assistant", "content": "Hello!"},
|
|
34
34
|
"finish_reason": "stop"}],
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -48,7 +48,7 @@ def test_chat_prints_content(fake_client, capsys):
|
|
|
48
48
|
rc = cli.main(["chat", "Labas pasauli", "--model", "deepseek-v4-flash"])
|
|
49
49
|
assert rc == 0
|
|
50
50
|
out = capsys.readouterr().out
|
|
51
|
-
assert "
|
|
51
|
+
assert "Hello!" in out
|
|
52
52
|
assert fake_client.chat_calls[0][0] == "deepseek-v4-flash"
|
|
53
53
|
assert fake_client.chat_calls[0][1] == [
|
|
54
54
|
{"role": "user", "content": "Labas pasauli"}]
|
|
@@ -63,7 +63,7 @@ def test_chat_mode_passed(fake_client, capsys):
|
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
def test_chat_model_and_mode(fake_client):
|
|
66
|
-
"""§5.1:
|
|
66
|
+
"""§5.1: both are passed through — the server resolves the conflict (model wins)."""
|
|
67
67
|
rc = cli.main(["chat", "hi", "--model", "deepseek-v4-flash",
|
|
68
68
|
"--mode", "premium"])
|
|
69
69
|
assert rc == 0
|
|
@@ -83,7 +83,7 @@ def test_chat_requires_model_or_mode(fake_client, capsys):
|
|
|
83
83
|
rc = cli.main(["chat", "hi"])
|
|
84
84
|
assert rc == 2
|
|
85
85
|
assert "model or --mode" in capsys.readouterr().err
|
|
86
|
-
assert fake_client.chat_calls == [] #
|
|
86
|
+
assert fake_client.chat_calls == [] # no call — error before SDK
|
|
87
87
|
|
|
88
88
|
|
|
89
89
|
def test_chat_error_exit_1(fake_client, monkeypatch, capsys):
|
|
@@ -147,10 +147,10 @@ def test_missing_prompt_exits_2(capsys):
|
|
|
147
147
|
|
|
148
148
|
|
|
149
149
|
def test_client_kwargs_wired(monkeypatch):
|
|
150
|
-
"""CLI
|
|
150
|
+
"""CLI arguments → LLMClient kwargs (timeouts, spending policy).
|
|
151
151
|
|
|
152
|
-
|
|
153
|
-
|
|
152
|
+
Global options (--base-url etc.) — BEFORE the subcommand (argparse).
|
|
153
|
+
Checked via `chat` (the models command does not use the SDK — direct HTTP, §5.2).
|
|
154
154
|
"""
|
|
155
155
|
captured: dict = {}
|
|
156
156
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"""test_cli_integration.py — CLI →
|
|
1
|
+
"""test_cli_integration.py — CLI → real SDK path with mock 402 (fix.md 4.4 z2).
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
(PAYMENT-REQUIRED) →
|
|
5
|
-
PAYMENT-RESPONSE
|
|
6
|
-
metadata)
|
|
3
|
+
Full x402 handshake through the real `bridgenode_llm` SDK: CLI `chat` → 402
|
|
4
|
+
(PAYMENT-REQUIRED) → partial TX → PAYMENT-SIGNATURE → 200 + valid
|
|
5
|
+
PAYMENT-RESPONSE receipt (fee payer signs OUR TX message). RPC (mint
|
|
6
|
+
metadata) mocked. No real network, no real payment.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
9
|
from __future__ import annotations
|
|
@@ -81,7 +81,7 @@ def _envelope(pay_to: str, fee_payer: str, amount: str = "2000") -> dict:
|
|
|
81
81
|
|
|
82
82
|
def _receipt_header(payment_header: str, fee_payer_kp: Keypair,
|
|
83
83
|
client_wallet: str, amount: str = "2000") -> str:
|
|
84
|
-
"""
|
|
84
|
+
"""Valid PAYMENT-RESPONSE receipt: fee payer signs OUR TX message."""
|
|
85
85
|
payload = PaymentPayload.model_validate_json(base64.b64decode(payment_header))
|
|
86
86
|
tx = VersionedTransaction.from_bytes(
|
|
87
87
|
base64.b64decode(payload.payload["transaction"]))
|
|
@@ -105,7 +105,7 @@ def _openai_response() -> dict:
|
|
|
105
105
|
"created": 1,
|
|
106
106
|
"model": "deepseek-v4-flash",
|
|
107
107
|
"choices": [{"index": 0,
|
|
108
|
-
"message": {"role": "assistant", "content": "
|
|
108
|
+
"message": {"role": "assistant", "content": "Hello!"},
|
|
109
109
|
"finish_reason": "stop"}],
|
|
110
110
|
"usage": {"prompt_tokens": 10, "completion_tokens": 5, "total_tokens": 15},
|
|
111
111
|
}
|
|
@@ -113,7 +113,7 @@ def _openai_response() -> dict:
|
|
|
113
113
|
|
|
114
114
|
@pytest.fixture(autouse=True)
|
|
115
115
|
def _mock_mint_metadata(monkeypatch):
|
|
116
|
-
"""Mint metadata
|
|
116
|
+
"""Mint metadata without RPC (the SDK scheme requires it, tests without network)."""
|
|
117
117
|
def fake(client, network, mint, cache):
|
|
118
118
|
return MintMetadata(decimals=6, token_program=Pubkey.from_string(TOKEN_PROGRAM))
|
|
119
119
|
monkeypatch.setattr(
|
|
@@ -122,7 +122,7 @@ def _mock_mint_metadata(monkeypatch):
|
|
|
122
122
|
|
|
123
123
|
@pytest.fixture()
|
|
124
124
|
def _mock_http(monkeypatch):
|
|
125
|
-
"""httpx.Client → MockTransport (
|
|
125
|
+
"""httpx.Client → MockTransport (all SDK requests through the mock server)."""
|
|
126
126
|
real_client = httpx.Client
|
|
127
127
|
state: dict = {"transport": None}
|
|
128
128
|
|
|
@@ -135,7 +135,7 @@ def _mock_http(monkeypatch):
|
|
|
135
135
|
|
|
136
136
|
|
|
137
137
|
def _install_server(state: dict, fee_kp: Keypair, client_wallet: str):
|
|
138
|
-
"""Mock
|
|
138
|
+
"""Mock server: 402 → valid receipt → 200. Returns (handler, seen)."""
|
|
139
139
|
seen: list[dict] = []
|
|
140
140
|
|
|
141
141
|
def handler(request: httpx.Request) -> httpx.Response:
|
|
@@ -163,10 +163,10 @@ def _install_server(state: dict, fee_kp: Keypair, client_wallet: str):
|
|
|
163
163
|
return seen
|
|
164
164
|
|
|
165
165
|
|
|
166
|
-
# ── chat:
|
|
166
|
+
# ── chat: full x402 handshake through the real SDK ────────────────────────────────
|
|
167
167
|
|
|
168
168
|
def test_cli_chat_full_handshake(monkeypatch, _mock_http, capsys):
|
|
169
|
-
"""CLI chat →
|
|
169
|
+
"""CLI chat → real SDK: 402 → TX → PAYMENT-SIGNATURE → 200 + receipt."""
|
|
170
170
|
fee_kp = Keypair()
|
|
171
171
|
client_kp = Keypair()
|
|
172
172
|
seen = _install_server(_mock_http, fee_kp, str(client_kp.pubkey()))
|
|
@@ -176,7 +176,7 @@ def test_cli_chat_full_handshake(monkeypatch, _mock_http, capsys):
|
|
|
176
176
|
"chat", "Labas pasauli", "--model", "deepseek-v4-flash"])
|
|
177
177
|
|
|
178
178
|
assert rc == 0
|
|
179
|
-
assert "
|
|
179
|
+
assert "Hello!" in capsys.readouterr().out
|
|
180
180
|
assert len(seen) == 2
|
|
181
181
|
assert seen[0]["has_payment"] is False
|
|
182
182
|
assert seen[1]["has_payment"] is True
|
|
@@ -185,7 +185,7 @@ def test_cli_chat_full_handshake(monkeypatch, _mock_http, capsys):
|
|
|
185
185
|
|
|
186
186
|
|
|
187
187
|
def test_cli_chat_mode_auto(monkeypatch, _mock_http, capsys):
|
|
188
|
-
"""CLI --mode auto → SDK mode
|
|
188
|
+
"""CLI --mode auto → SDK mode is passed through (smart routing §5.1)."""
|
|
189
189
|
fee_kp = Keypair()
|
|
190
190
|
client_kp = Keypair()
|
|
191
191
|
seen = _install_server(_mock_http, fee_kp, str(client_kp.pubkey()))
|
|
@@ -198,13 +198,13 @@ def test_cli_chat_mode_auto(monkeypatch, _mock_http, capsys):
|
|
|
198
198
|
|
|
199
199
|
|
|
200
200
|
def test_cli_chat_kvitas_verify_fail(monkeypatch, _mock_http, capsys):
|
|
201
|
-
"""
|
|
201
|
+
"""Forged receipt → CLI error (exit 1) — Free-Riding protection works."""
|
|
202
202
|
fee_kp = Keypair()
|
|
203
203
|
client_kp = Keypair()
|
|
204
204
|
fake_kp = Keypair()
|
|
205
205
|
seen = _install_server(_mock_http, fee_kp, str(client_kp.pubkey()))
|
|
206
206
|
|
|
207
|
-
#
|
|
207
|
+
# Rewrite the receipt after the server response — fake signature (of another key)
|
|
208
208
|
original = _mock_http["transport"].handler
|
|
209
209
|
|
|
210
210
|
def tampered(request: httpx.Request) -> httpx.Response:
|
|
@@ -215,7 +215,7 @@ def test_cli_chat_kvitas_verify_fail(monkeypatch, _mock_http, capsys):
|
|
|
215
215
|
tx = VersionedTransaction.from_bytes(
|
|
216
216
|
base64.b64decode(payload.payload["transaction"]))
|
|
217
217
|
msg = bytes([0x80]) + bytes(tx.message)
|
|
218
|
-
fake_sig = fake_kp.sign_message(msg) #
|
|
218
|
+
fake_sig = fake_kp.sign_message(msg) # not the fee payer's key
|
|
219
219
|
settle = SettleResponse(
|
|
220
220
|
success=True, transaction=str(fake_sig), network=NETWORK,
|
|
221
221
|
payer=str(client_kp.pubkey()), amount="2000")
|
|
@@ -233,7 +233,7 @@ def test_cli_chat_kvitas_verify_fail(monkeypatch, _mock_http, capsys):
|
|
|
233
233
|
assert "does not match our TX" in capsys.readouterr().err
|
|
234
234
|
|
|
235
235
|
|
|
236
|
-
# ── models:
|
|
236
|
+
# ── models: without payment (§5.2) ───────────────────────────────────────────────
|
|
237
237
|
|
|
238
238
|
def test_cli_models_integration(monkeypatch, capsys):
|
|
239
239
|
import httpx
|
|
@@ -249,7 +249,7 @@ def test_cli_models_integration(monkeypatch, capsys):
|
|
|
249
249
|
"context_window": 131072, "max_output_tokens": 32768},
|
|
250
250
|
]})
|
|
251
251
|
|
|
252
|
-
# models —
|
|
252
|
+
# models — direct HTTP (no SDK, §5.2 public endpoint)
|
|
253
253
|
monkeypatch.setattr(httpx, "get", fake_get)
|
|
254
254
|
rc = cli.main(["--base-url", API_BASE, "models"])
|
|
255
255
|
assert rc == 0
|
bridgenode_cli-0.1.0/PKG-INFO
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: bridgenode-cli
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: BridgeNode CLI — AI inference su x402 mokėjimu (Solana USDC). Jokių API key.
|
|
5
|
-
Requires-Python: >=3.11
|
|
6
|
-
Description-Content-Type: text/markdown
|
|
7
|
-
Requires-Dist: bridgenode-llm>=0.1.0
|
|
8
|
-
Provides-Extra: dev
|
|
9
|
-
Requires-Dist: pytest>=9.1.1; extra == "dev"
|
|
10
|
-
|
|
11
|
-
# bridgenode-cli
|
|
12
|
-
|
|
13
|
-
BridgeNode CLI — AI inference be API key. Mokėjimas: **Solana USDC per x402** (automatinis handshake, fee sponsorship — SOL nereikia).
|
|
14
|
-
|
|
15
|
-
## Diegimas
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
pip install bridgenode-cli
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## Naudojimas
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
# Vienas chat completion (x402 handshake paslėptas, §4.1)
|
|
25
|
-
bridgenode chat "Labas!" --model deepseek-v4-flash
|
|
26
|
-
|
|
27
|
-
# Smart routing (§5.1/§5.8): auto / eco / premium
|
|
28
|
-
bridgenode chat "Išanalizuok šį kodą" --mode auto
|
|
29
|
-
|
|
30
|
-
# Modelių sąrašas + kainos (§5.2) — be mokėjimo
|
|
31
|
-
bridgenode models
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## Parinktys
|
|
35
|
-
|
|
36
|
-
| Parinktis | Aprašas |
|
|
37
|
-
|---|---|
|
|
38
|
-
| `--model` | Explicit model id (žr. `bridgenode models`) |
|
|
39
|
-
| `--mode` | `auto` / `eco` / `premium` (smart routing) |
|
|
40
|
-
| `--max-tokens` | Max output tokenų (billing upfront, §4.2) |
|
|
41
|
-
| `--base-url` | Base URL (default: `BRIDGENODE_BASE_URL` / https://bridgenode.cc/v1) |
|
|
42
|
-
| `--max-per-call` / `--daily-cap` | Spending policy (fail-closed) |
|
|
43
|
-
|
|
44
|
-
## .env
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
# Privalomas — jūsų Solana wallet private key (base58)
|
|
48
|
-
BRIDGENODE_WALLET_KEY=...
|
|
49
|
-
# Neprivalomi: BRIDGENODE_BASE_URL, BRIDGENODE_MAX_PER_CALL, BRIDGENODE_DAILY_CAP
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Apsaugos
|
|
53
|
-
|
|
54
|
-
- **Kvito verifikacija (Free-Riding apsauga):** po 200 tikrinamas `PAYMENT-RESPONSE` — netikras kvitas → klaida.
|
|
55
|
-
- **Spending policy (fail-closed):** max USD per call / per day — tikrinama PRIEŠ pasirašant.
|
|
56
|
-
|
|
57
|
-
## Reikalavimai
|
|
58
|
-
|
|
59
|
-
- Python ≥ 3.11
|
|
60
|
-
- Solana wallet su USDC ATA (rent — agento atsakomybė, §3.3)
|
|
61
|
-
|
|
62
|
-
## Nuorodos
|
|
63
|
-
|
|
64
|
-
- Tinklalapis: https://bridgenode.cc
|
|
65
|
-
- Protokolas: x402 V2 (docs.x402.org)
|
bridgenode_cli-0.1.0/README.md
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# bridgenode-cli
|
|
2
|
-
|
|
3
|
-
BridgeNode CLI — AI inference be API key. Mokėjimas: **Solana USDC per x402** (automatinis handshake, fee sponsorship — SOL nereikia).
|
|
4
|
-
|
|
5
|
-
## Diegimas
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
pip install bridgenode-cli
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Naudojimas
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
# Vienas chat completion (x402 handshake paslėptas, §4.1)
|
|
15
|
-
bridgenode chat "Labas!" --model deepseek-v4-flash
|
|
16
|
-
|
|
17
|
-
# Smart routing (§5.1/§5.8): auto / eco / premium
|
|
18
|
-
bridgenode chat "Išanalizuok šį kodą" --mode auto
|
|
19
|
-
|
|
20
|
-
# Modelių sąrašas + kainos (§5.2) — be mokėjimo
|
|
21
|
-
bridgenode models
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Parinktys
|
|
25
|
-
|
|
26
|
-
| Parinktis | Aprašas |
|
|
27
|
-
|---|---|
|
|
28
|
-
| `--model` | Explicit model id (žr. `bridgenode models`) |
|
|
29
|
-
| `--mode` | `auto` / `eco` / `premium` (smart routing) |
|
|
30
|
-
| `--max-tokens` | Max output tokenų (billing upfront, §4.2) |
|
|
31
|
-
| `--base-url` | Base URL (default: `BRIDGENODE_BASE_URL` / https://bridgenode.cc/v1) |
|
|
32
|
-
| `--max-per-call` / `--daily-cap` | Spending policy (fail-closed) |
|
|
33
|
-
|
|
34
|
-
## .env
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
# Privalomas — jūsų Solana wallet private key (base58)
|
|
38
|
-
BRIDGENODE_WALLET_KEY=...
|
|
39
|
-
# Neprivalomi: BRIDGENODE_BASE_URL, BRIDGENODE_MAX_PER_CALL, BRIDGENODE_DAILY_CAP
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Apsaugos
|
|
43
|
-
|
|
44
|
-
- **Kvito verifikacija (Free-Riding apsauga):** po 200 tikrinamas `PAYMENT-RESPONSE` — netikras kvitas → klaida.
|
|
45
|
-
- **Spending policy (fail-closed):** max USD per call / per day — tikrinama PRIEŠ pasirašant.
|
|
46
|
-
|
|
47
|
-
## Reikalavimai
|
|
48
|
-
|
|
49
|
-
- Python ≥ 3.11
|
|
50
|
-
- Solana wallet su USDC ATA (rent — agento atsakomybė, §3.3)
|
|
51
|
-
|
|
52
|
-
## Nuorodos
|
|
53
|
-
|
|
54
|
-
- Tinklalapis: https://bridgenode.cc
|
|
55
|
-
- Protokolas: x402 V2 (docs.x402.org)
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: bridgenode-cli
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: BridgeNode CLI — AI inference su x402 mokėjimu (Solana USDC). Jokių API key.
|
|
5
|
-
Requires-Python: >=3.11
|
|
6
|
-
Description-Content-Type: text/markdown
|
|
7
|
-
Requires-Dist: bridgenode-llm>=0.1.0
|
|
8
|
-
Provides-Extra: dev
|
|
9
|
-
Requires-Dist: pytest>=9.1.1; extra == "dev"
|
|
10
|
-
|
|
11
|
-
# bridgenode-cli
|
|
12
|
-
|
|
13
|
-
BridgeNode CLI — AI inference be API key. Mokėjimas: **Solana USDC per x402** (automatinis handshake, fee sponsorship — SOL nereikia).
|
|
14
|
-
|
|
15
|
-
## Diegimas
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
pip install bridgenode-cli
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## Naudojimas
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
# Vienas chat completion (x402 handshake paslėptas, §4.1)
|
|
25
|
-
bridgenode chat "Labas!" --model deepseek-v4-flash
|
|
26
|
-
|
|
27
|
-
# Smart routing (§5.1/§5.8): auto / eco / premium
|
|
28
|
-
bridgenode chat "Išanalizuok šį kodą" --mode auto
|
|
29
|
-
|
|
30
|
-
# Modelių sąrašas + kainos (§5.2) — be mokėjimo
|
|
31
|
-
bridgenode models
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## Parinktys
|
|
35
|
-
|
|
36
|
-
| Parinktis | Aprašas |
|
|
37
|
-
|---|---|
|
|
38
|
-
| `--model` | Explicit model id (žr. `bridgenode models`) |
|
|
39
|
-
| `--mode` | `auto` / `eco` / `premium` (smart routing) |
|
|
40
|
-
| `--max-tokens` | Max output tokenų (billing upfront, §4.2) |
|
|
41
|
-
| `--base-url` | Base URL (default: `BRIDGENODE_BASE_URL` / https://bridgenode.cc/v1) |
|
|
42
|
-
| `--max-per-call` / `--daily-cap` | Spending policy (fail-closed) |
|
|
43
|
-
|
|
44
|
-
## .env
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
# Privalomas — jūsų Solana wallet private key (base58)
|
|
48
|
-
BRIDGENODE_WALLET_KEY=...
|
|
49
|
-
# Neprivalomi: BRIDGENODE_BASE_URL, BRIDGENODE_MAX_PER_CALL, BRIDGENODE_DAILY_CAP
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Apsaugos
|
|
53
|
-
|
|
54
|
-
- **Kvito verifikacija (Free-Riding apsauga):** po 200 tikrinamas `PAYMENT-RESPONSE` — netikras kvitas → klaida.
|
|
55
|
-
- **Spending policy (fail-closed):** max USD per call / per day — tikrinama PRIEŠ pasirašant.
|
|
56
|
-
|
|
57
|
-
## Reikalavimai
|
|
58
|
-
|
|
59
|
-
- Python ≥ 3.11
|
|
60
|
-
- Solana wallet su USDC ATA (rent — agento atsakomybė, §3.3)
|
|
61
|
-
|
|
62
|
-
## Nuorodos
|
|
63
|
-
|
|
64
|
-
- Tinklalapis: https://bridgenode.cc
|
|
65
|
-
- Protokolas: x402 V2 (docs.x402.org)
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
[project]
|
|
2
|
-
name = "bridgenode-cli"
|
|
3
|
-
version = "0.1.0"
|
|
4
|
-
description = "BridgeNode CLI — AI inference su x402 mokėjimu (Solana USDC). Jokių API key."
|
|
5
|
-
readme = "README.md"
|
|
6
|
-
requires-python = ">=3.11"
|
|
7
|
-
dependencies = [
|
|
8
|
-
"bridgenode-llm>=0.1.0",
|
|
9
|
-
]
|
|
10
|
-
|
|
11
|
-
[project.optional-dependencies]
|
|
12
|
-
dev = [
|
|
13
|
-
"pytest>=9.1.1",
|
|
14
|
-
]
|
|
15
|
-
|
|
16
|
-
[project.scripts]
|
|
17
|
-
bridgenode = "bridgenode_cli.main:main"
|
|
18
|
-
|
|
19
|
-
[build-system]
|
|
20
|
-
requires = ["setuptools>=75"]
|
|
21
|
-
build-backend = "setuptools.build_meta"
|
|
22
|
-
|
|
23
|
-
[tool.setuptools.packages.find]
|
|
24
|
-
include = ["bridgenode_cli*"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|