bridgenode-cli 0.1.10__tar.gz → 0.1.12__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.10 → bridgenode_cli-0.1.12}/PKG-INFO +7 -3
- {bridgenode_cli-0.1.10 → bridgenode_cli-0.1.12}/README.md +6 -2
- bridgenode_cli-0.1.12/bridgenode_cli/__init__.py +6 -0
- {bridgenode_cli-0.1.10 → bridgenode_cli-0.1.12}/bridgenode_cli/__main__.py +1 -1
- {bridgenode_cli-0.1.10 → bridgenode_cli-0.1.12}/bridgenode_cli/main.py +17 -17
- {bridgenode_cli-0.1.10 → bridgenode_cli-0.1.12}/bridgenode_cli.egg-info/PKG-INFO +7 -3
- {bridgenode_cli-0.1.10 → bridgenode_cli-0.1.12}/pyproject.toml +1 -1
- {bridgenode_cli-0.1.10 → bridgenode_cli-0.1.12}/tests/test_cli.py +3 -3
- {bridgenode_cli-0.1.10 → bridgenode_cli-0.1.12}/tests/test_cli_integration.py +6 -6
- bridgenode_cli-0.1.10/bridgenode_cli/__init__.py +0 -6
- {bridgenode_cli-0.1.10 → bridgenode_cli-0.1.12}/LICENSE +0 -0
- {bridgenode_cli-0.1.10 → bridgenode_cli-0.1.12}/bridgenode_cli/py.typed +0 -0
- {bridgenode_cli-0.1.10 → bridgenode_cli-0.1.12}/bridgenode_cli.egg-info/SOURCES.txt +0 -0
- {bridgenode_cli-0.1.10 → bridgenode_cli-0.1.12}/bridgenode_cli.egg-info/dependency_links.txt +0 -0
- {bridgenode_cli-0.1.10 → bridgenode_cli-0.1.12}/bridgenode_cli.egg-info/entry_points.txt +0 -0
- {bridgenode_cli-0.1.10 → bridgenode_cli-0.1.12}/bridgenode_cli.egg-info/requires.txt +0 -0
- {bridgenode_cli-0.1.10 → bridgenode_cli-0.1.12}/bridgenode_cli.egg-info/top_level.txt +0 -0
- {bridgenode_cli-0.1.10 → bridgenode_cli-0.1.12}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bridgenode-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.12
|
|
4
4
|
Summary: Agentic AI CLI with x402 (HTTP 402) pay-per-request on Solana USDC — no API keys.
|
|
5
5
|
Author-email: BridgeNode <eli.BNx@proton.me>
|
|
6
6
|
License-Expression: MIT-0
|
|
@@ -60,8 +60,11 @@ pip install bridgenode
|
|
|
60
60
|
## Usage
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
|
+
# Free models need no wallet — and the first 2 calls to a PAID model are free
|
|
64
|
+
bridgenode chat "Hello!" --model gpt-oss-120b
|
|
65
|
+
|
|
63
66
|
# Single chat completion (payment handshake fully automatic)
|
|
64
|
-
bridgenode chat "Hello!" --model deepseek-
|
|
67
|
+
bridgenode chat "Hello!" --model deepseek-flash
|
|
65
68
|
|
|
66
69
|
# Smart routing: auto / eco / premium
|
|
67
70
|
bridgenode chat "Analyze this code" --mode auto
|
|
@@ -83,7 +86,8 @@ bridgenode models
|
|
|
83
86
|
## Configuration (.env)
|
|
84
87
|
|
|
85
88
|
```bash
|
|
86
|
-
#
|
|
89
|
+
# Optional — your Solana wallet private key (base58).
|
|
90
|
+
# Needed only for PAID requests: free models and the 2 free trials work without it.
|
|
87
91
|
BRIDGENODE_WALLET_KEY=...
|
|
88
92
|
# Optional: BRIDGENODE_BASE_URL, BRIDGENODE_MAX_PER_CALL, BRIDGENODE_DAILY_CAP
|
|
89
93
|
```
|
|
@@ -24,8 +24,11 @@ pip install bridgenode
|
|
|
24
24
|
## Usage
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
+
# Free models need no wallet — and the first 2 calls to a PAID model are free
|
|
28
|
+
bridgenode chat "Hello!" --model gpt-oss-120b
|
|
29
|
+
|
|
27
30
|
# Single chat completion (payment handshake fully automatic)
|
|
28
|
-
bridgenode chat "Hello!" --model deepseek-
|
|
31
|
+
bridgenode chat "Hello!" --model deepseek-flash
|
|
29
32
|
|
|
30
33
|
# Smart routing: auto / eco / premium
|
|
31
34
|
bridgenode chat "Analyze this code" --mode auto
|
|
@@ -47,7 +50,8 @@ bridgenode models
|
|
|
47
50
|
## Configuration (.env)
|
|
48
51
|
|
|
49
52
|
```bash
|
|
50
|
-
#
|
|
53
|
+
# Optional — your Solana wallet private key (base58).
|
|
54
|
+
# Needed only for PAID requests: free models and the 2 free trials work without it.
|
|
51
55
|
BRIDGENODE_WALLET_KEY=...
|
|
52
56
|
# Optional: BRIDGENODE_BASE_URL, BRIDGENODE_MAX_PER_CALL, BRIDGENODE_DAILY_CAP
|
|
53
57
|
```
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
"""main.py — bridgenode CLI
|
|
1
|
+
"""main.py — bridgenode CLI.
|
|
2
2
|
|
|
3
3
|
Commands:
|
|
4
4
|
- `bridgenode chat "<prompt>"` — single chat completion via the x402 handshake
|
|
5
|
-
(SDK: 402 → partial TX → PAYMENT-SIGNATURE → 200
|
|
6
|
-
- `bridgenode models` — model list + prices from GET /v1/models
|
|
5
|
+
(SDK: 402 → partial TX → PAYMENT-SIGNATURE → 200)
|
|
6
|
+
- `bridgenode models` — model list + prices from GET /v1/models
|
|
7
7
|
|
|
8
|
-
Options: --model (explicit
|
|
9
|
-
|
|
10
|
-
LLMClient
|
|
8
|
+
Options: --model (explicit), --mode auto/eco/premium (smart routing),
|
|
9
|
+
--max-tokens. All payment is hidden — uses the official
|
|
10
|
+
LLMClient. 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 from CLI arguments (key ONLY from .env
|
|
25
|
-
# None values are not passed — the SDK uses defaults
|
|
26
|
-
# otherwise timeout=None would enter the flow timeout calculation
|
|
24
|
+
"""LLMClient from CLI arguments (key ONLY from .env)."""
|
|
25
|
+
# None values are not passed — the SDK uses defaults;
|
|
26
|
+
# otherwise timeout=None would enter the flow timeout calculation
|
|
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` — model list + prices
|
|
61
|
+
"""`bridgenode models` — model list + prices.
|
|
62
62
|
|
|
63
63
|
Public endpoint (no payment) — direct HTTP, without the SDK (the SDK has
|
|
64
|
-
only chat()
|
|
64
|
+
only chat())."""
|
|
65
65
|
import httpx
|
|
66
66
|
|
|
67
67
|
base_url = (args.base_url or os.environ.get("BRIDGENODE_BASE_URL")
|
|
@@ -96,26 +96,26 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
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="Initial request timeout s (queue until 402
|
|
99
|
+
help="Initial request timeout s (queue until 402)")
|
|
100
100
|
parser.add_argument("--retry-timeout", type=float, default=None,
|
|
101
|
-
help="Retry timeout s (≤115s budget
|
|
101
|
+
help="Retry timeout s (≤115s budget)")
|
|
102
102
|
parser.add_argument("--max-per-call", type=float, default=None,
|
|
103
103
|
help="Spending policy: max USD per call (step 2)")
|
|
104
104
|
parser.add_argument("--daily-cap", type=float, default=None,
|
|
105
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="Single chat completion via x402
|
|
108
|
+
p_chat = sub.add_parser("chat", help="Single chat completion via x402")
|
|
109
109
|
p_chat.add_argument("prompt", help="Prompt text")
|
|
110
110
|
p_chat.add_argument("--model", default=None,
|
|
111
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 profile
|
|
113
|
+
help="Smart routing profile")
|
|
114
114
|
p_chat.add_argument("--max-tokens", type=int, default=None,
|
|
115
|
-
help="Max output tokens (billing upfront
|
|
115
|
+
help="Max output tokens (billing upfront)")
|
|
116
116
|
p_chat.set_defaults(func=cmd_chat)
|
|
117
117
|
|
|
118
|
-
p_models = sub.add_parser("models", help="Model list + prices
|
|
118
|
+
p_models = sub.add_parser("models", help="Model list + prices")
|
|
119
119
|
p_models.set_defaults(func=cmd_models)
|
|
120
120
|
|
|
121
121
|
return parser
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bridgenode-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.12
|
|
4
4
|
Summary: Agentic AI CLI with x402 (HTTP 402) pay-per-request on Solana USDC — no API keys.
|
|
5
5
|
Author-email: BridgeNode <eli.BNx@proton.me>
|
|
6
6
|
License-Expression: MIT-0
|
|
@@ -60,8 +60,11 @@ pip install bridgenode
|
|
|
60
60
|
## Usage
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
|
+
# Free models need no wallet — and the first 2 calls to a PAID model are free
|
|
64
|
+
bridgenode chat "Hello!" --model gpt-oss-120b
|
|
65
|
+
|
|
63
66
|
# Single chat completion (payment handshake fully automatic)
|
|
64
|
-
bridgenode chat "Hello!" --model deepseek-
|
|
67
|
+
bridgenode chat "Hello!" --model deepseek-flash
|
|
65
68
|
|
|
66
69
|
# Smart routing: auto / eco / premium
|
|
67
70
|
bridgenode chat "Analyze this code" --mode auto
|
|
@@ -83,7 +86,8 @@ bridgenode models
|
|
|
83
86
|
## Configuration (.env)
|
|
84
87
|
|
|
85
88
|
```bash
|
|
86
|
-
#
|
|
89
|
+
# Optional — your Solana wallet private key (base58).
|
|
90
|
+
# Needed only for PAID requests: free models and the 2 free trials work without it.
|
|
87
91
|
BRIDGENODE_WALLET_KEY=...
|
|
88
92
|
# Optional: BRIDGENODE_BASE_URL, BRIDGENODE_MAX_PER_CALL, BRIDGENODE_DAILY_CAP
|
|
89
93
|
```
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""test_cli.py — bridgenode CLI tests
|
|
1
|
+
"""test_cli.py — bridgenode CLI tests.
|
|
2
2
|
|
|
3
3
|
Checks command output and argument passing with a mocked LLMClient
|
|
4
4
|
(no network, no payment). Full mock-402 path — 4.4 z2.
|
|
@@ -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
|
-
"""
|
|
66
|
+
"""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
|
|
@@ -150,7 +150,7 @@ def test_client_kwargs_wired(monkeypatch):
|
|
|
150
150
|
"""CLI arguments → LLMClient kwargs (timeouts, spending policy).
|
|
151
151
|
|
|
152
152
|
Global options (--base-url etc.) — BEFORE the subcommand (argparse).
|
|
153
|
-
Checked via `chat` (the models command does not use the SDK — direct HTTP
|
|
153
|
+
Checked via `chat` (the models command does not use the SDK — direct HTTP).
|
|
154
154
|
"""
|
|
155
155
|
captured: dict = {}
|
|
156
156
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""test_cli_integration.py — CLI → real SDK path with mock 402
|
|
1
|
+
"""test_cli_integration.py — CLI → real SDK path with mock 402.
|
|
2
2
|
|
|
3
3
|
Full x402 handshake through the real `bridgenode_llm` SDK: CLI `chat` → 402
|
|
4
4
|
(PAYMENT-REQUIRED) → partial TX → PAYMENT-SIGNATURE → 200 + valid
|
|
@@ -180,12 +180,12 @@ def test_cli_chat_full_handshake(monkeypatch, _mock_http, capsys):
|
|
|
180
180
|
assert len(seen) == 2
|
|
181
181
|
assert seen[0]["has_payment"] is False
|
|
182
182
|
assert seen[1]["has_payment"] is True
|
|
183
|
-
assert seen[0]["body"] == seen[1]["body"] # price-bind
|
|
183
|
+
assert seen[0]["body"] == seen[1]["body"] # price-bind
|
|
184
184
|
assert seen[0]["body"]["model"] == "deepseek-v4-flash"
|
|
185
185
|
|
|
186
186
|
|
|
187
187
|
def test_cli_chat_mode_auto(monkeypatch, _mock_http, capsys):
|
|
188
|
-
"""CLI --mode auto → SDK mode is passed through (smart routing
|
|
188
|
+
"""CLI --mode auto → SDK mode is passed through (smart routing)."""
|
|
189
189
|
fee_kp = Keypair()
|
|
190
190
|
client_kp = Keypair()
|
|
191
191
|
seen = _install_server(_mock_http, fee_kp, str(client_kp.pubkey()))
|
|
@@ -197,7 +197,7 @@ def test_cli_chat_mode_auto(monkeypatch, _mock_http, capsys):
|
|
|
197
197
|
assert seen[0]["body"]["mode"] == "auto"
|
|
198
198
|
|
|
199
199
|
|
|
200
|
-
def
|
|
200
|
+
def test_cli_chat_receipt_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()
|
|
@@ -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: without payment
|
|
236
|
+
# ── models: without payment ───────────────────────────────────────────────
|
|
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 — direct HTTP (no SDK,
|
|
252
|
+
# models — direct HTTP (no SDK, 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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bridgenode_cli-0.1.10 → bridgenode_cli-0.1.12}/bridgenode_cli.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|