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.
@@ -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
+ [![PyPI version](https://img.shields.io/pypi/v/bridgenode-cli.svg)](https://pypi.org/project/bridgenode-cli/)
33
+ [![Downloads](https://img.shields.io/pypi/dm/bridgenode-cli.svg)](https://pypi.org/project/bridgenode-cli/)
34
+ [![License: MIT-0](https://img.shields.io/badge/License-MIT--0-yellow.svg)](https://opensource.org/license/mit-0/)
35
+ [![Python versions](https://img.shields.io/pypi/pyversions/bridgenode-cli.svg)](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
+ [![PyPI version](https://img.shields.io/pypi/v/bridgenode-cli.svg)](https://pypi.org/project/bridgenode-cli/)
4
+ [![Downloads](https://img.shields.io/pypi/dm/bridgenode-cli.svg)](https://pypi.org/project/bridgenode-cli/)
5
+ [![License: MIT-0](https://img.shields.io/badge/License-MIT--0-yellow.svg)](https://opensource.org/license/mit-0/)
6
+ [![Python versions](https://img.shields.io/pypi/pyversions/bridgenode-cli.svg)](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).
1
+ """main.py — bridgenode CLI (§8.4, fix.md 4.4 step 1).
2
2
 
3
- Komandos:
4
- - `bridgenode chat "<prompt>"` — vienas chat completion per x402 handshake
5
- (SDK: 402 → dalinis TX → PAYMENT-SIGNATURE → 200; §4.1)
6
- - `bridgenode models` — modelių sąrašas + kainos iš GET /v1/models (§5.2)
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
- Parinktys: --model (explicit, §5.1), --mode auto/eco/premium (smart routing,
9
- §5.1/§5.8), --max-tokens. Visas mokėjimas paslėptas — naudojamas oficialus
10
- LLMClient (P4). Klaidos → stderr + exit 1; sėkmė → stdout + exit 0.
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 iš CLI argumentų (raktas TIK iš .env, §8.4)."""
25
- # None reikšmės neperduodamos — SDK naudoja default'us (§8.5);
26
- # kitaip timeout=None patektų į flow timeout skaičiavimą (Ž42)
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` — modelių sąrašas + kainos (§5.2).
61
+ """`bridgenode models` — model list + prices (§5.2).
62
62
 
63
- Viešas endpointas (be mokėjimo) — tiesioginis HTTP, be SDK (SDK turi
64
- tik chat(), protokolas §8.4)."""
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, mokėjimas Solana USDC per x402. "
93
- "Jokių API key."
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="Pradinio request'o timeout s (eilė iki 402, §5.7)")
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 biudžetas, §4.3)")
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 (ž2)")
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 (ž2)")
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="Vienas chat completion per x402 (§4.1)")
109
- p_chat.add_argument("prompt", help="Prompt tekstas")
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 (žr. `bridgenode models`)")
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 profilis (§5.1/§5.8)")
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 tokenų (billing upfront, §4.2)")
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="Modelių sąrašas + kainos (§5.2)")
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
+ [![PyPI version](https://img.shields.io/pypi/v/bridgenode-cli.svg)](https://pypi.org/project/bridgenode-cli/)
33
+ [![Downloads](https://img.shields.io/pypi/dm/bridgenode-cli.svg)](https://pypi.org/project/bridgenode-cli/)
34
+ [![License: MIT-0](https://img.shields.io/badge/License-MIT--0-yellow.svg)](https://opensource.org/license/mit-0/)
35
+ [![Python versions](https://img.shields.io/pypi/pyversions/bridgenode-cli.svg)](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)
@@ -1,7 +1,9 @@
1
+ LICENSE
1
2
  README.md
2
3
  pyproject.toml
3
4
  bridgenode_cli/__init__.py
4
5
  bridgenode_cli/main.py
6
+ bridgenode_cli/py.typed
5
7
  bridgenode_cli.egg-info/PKG-INFO
6
8
  bridgenode_cli.egg-info/SOURCES.txt
7
9
  bridgenode_cli.egg-info/dependency_links.txt
@@ -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 testai (fix.md 4.4 ž1).
1
+ """test_cli.py — bridgenode CLI tests (fix.md 4.4 z1).
2
2
 
3
- Tikrina komandų išvedimą ir argumentų perdavimą su mock'intu LLMClient
4
- (jokio tinklo, jokio mokėjimo). Pilnas mock-402 kelias — 4.4 ž2.
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 NEVEIKIA: __init__ `from .main import main`
16
- # shadow'ina submodulį — cli tampa funkcija. Naudojam importlib.
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 pakaitalas — fiksuoja kvietimus, grąžina fiktyvius atsakymus."""
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": "Labas!"},
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 "Labas!" in out
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: abu perduodami — konfliktą sprendžia serveris (model laimi)."""
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 == [] # jokio kvietimo — klaida prieš SDK
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 argumentai → LLMClient kwargs (timeout'ai, spending policy).
150
+ """CLI arguments → LLMClient kwargs (timeouts, spending policy).
151
151
 
152
- Globalios parinktys (--base-url ir kt.) — PRIEŠ subkomandą (argparse).
153
- Tikrinama per `chat` (models komanda SDK nenaudoja — tiesioginis HTTP, §5.2).
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 → realus SDK kelias su mock 402 (fix.md 4.4 ž2).
1
+ """test_cli_integration.py — CLI → real SDK path with mock 402 (fix.md 4.4 z2).
2
2
 
3
- Pilnas x402 handshake per tikrą `bridgenode_llm` SDK: CLI `chat` → 402
4
- (PAYMENT-REQUIRED) → dalinis TX → PAYMENT-SIGNATURE → 200 + validus
5
- PAYMENT-RESPONSE kvitas (fee payer pasirašo MŪSŲ TX žinutę). RPC (mint
6
- metadata) mock'inta. Jokio realaus tinklo, jokio realaus mokėjimo.
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
- """Validus PAYMENT-RESPONSE kvitas: fee payer pasirašo MŪSŲ TX žinutę."""
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": "Labas!"},
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 be RPC (SDK scheme reikalauja, testai be tinklo)."""
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 (visi SDK request'ai per mock serverį)."""
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 serveris: 402 → validus kvitas → 200. Grąžina (handler, seen)."""
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: pilnas x402 handshake per realų SDK ────────────────────────────────
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 → realus SDK: 402 → TX → PAYMENT-SIGNATURE → 200 + kvitas."""
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 "Labas!" in capsys.readouterr().out
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 perduodamas (smart routing §5.1)."""
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
- """Suklastotas kvitas → CLI error (exit 1) — Free-Riding apsauga veikia."""
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
- # Perrašom kvitą po serverio atsakymo — netikras parašas (kito rakto)
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) # ne fee payer'io raktas
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: be mokėjimo (§5.2) ───────────────────────────────────────────────
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 — tiesioginis HTTP (be SDK, §5.2 viešas endpointas)
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
@@ -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,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