bridgenode-llm 0.1.0__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_llm-0.1.0/.gitattributes +19 -0
- bridgenode_llm-0.1.0/.gitignore +66 -0
- bridgenode_llm-0.1.0/AGENTS.md +137 -0
- bridgenode_llm-0.1.0/CHANGELOG.md +1321 -0
- bridgenode_llm-0.1.0/CLAUDE.md +62 -0
- bridgenode_llm-0.1.0/CONTRIBUTING.md +37 -0
- bridgenode_llm-0.1.0/LICENSE +21 -0
- bridgenode_llm-0.1.0/PKG-INFO +1728 -0
- bridgenode_llm-0.1.0/README.md +1689 -0
- bridgenode_llm-0.1.0/VERSION +1 -0
- bridgenode_llm-0.1.0/brand-numbers.json +34 -0
- bridgenode_llm-0.1.0/bridgenode_llm/__init__.py +305 -0
- bridgenode_llm-0.1.0/bridgenode_llm/anthropic_client.py +201 -0
- bridgenode_llm-0.1.0/bridgenode_llm/billing.py +188 -0
- bridgenode_llm-0.1.0/bridgenode_llm/cache.py +510 -0
- bridgenode_llm-0.1.0/bridgenode_llm/client.py +3763 -0
- bridgenode_llm-0.1.0/bridgenode_llm/image.py +481 -0
- bridgenode_llm-0.1.0/bridgenode_llm/music.py +269 -0
- bridgenode_llm-0.1.0/bridgenode_llm/phone.py +324 -0
- bridgenode_llm-0.1.0/bridgenode_llm/portrait.py +311 -0
- bridgenode_llm-0.1.0/bridgenode_llm/price.py +305 -0
- bridgenode_llm-0.1.0/bridgenode_llm/realface.py +480 -0
- bridgenode_llm-0.1.0/bridgenode_llm/router.py +645 -0
- bridgenode_llm-0.1.0/bridgenode_llm/rpc.py +401 -0
- bridgenode_llm-0.1.0/bridgenode_llm/search.py +215 -0
- bridgenode_llm-0.1.0/bridgenode_llm/solana_client.py +4662 -0
- bridgenode_llm-0.1.0/bridgenode_llm/solana_wallet.py +577 -0
- bridgenode_llm-0.1.0/bridgenode_llm/speech.py +358 -0
- bridgenode_llm-0.1.0/bridgenode_llm/surf.py +418 -0
- bridgenode_llm-0.1.0/bridgenode_llm/tx_log.py +389 -0
- bridgenode_llm-0.1.0/bridgenode_llm/types.py +896 -0
- bridgenode_llm-0.1.0/bridgenode_llm/validation.py +611 -0
- bridgenode_llm-0.1.0/bridgenode_llm/video.py +531 -0
- bridgenode_llm-0.1.0/bridgenode_llm/voice.py +368 -0
- bridgenode_llm-0.1.0/bridgenode_llm/wallet.py +709 -0
- bridgenode_llm-0.1.0/bridgenode_llm/x402.py +272 -0
- bridgenode_llm-0.1.0/docs/plans/2026-02-27-solana-client.md +1010 -0
- bridgenode_llm-0.1.0/examples/arbitrage_analyzer.py +277 -0
- bridgenode_llm-0.1.0/examples/benchmark_claude.py +290 -0
- bridgenode_llm-0.1.0/examples/sweep_all_chat_models.py +706 -0
- bridgenode_llm-0.1.0/examples/sweep_all_media_models.py +457 -0
- bridgenode_llm-0.1.0/pyproject.toml +81 -0
- bridgenode_llm-0.1.0/pytest.ini +16 -0
- bridgenode_llm-0.1.0/scripts/sync-brand-numbers.mjs +256 -0
- bridgenode_llm-0.1.0/tests/__init__.py +1 -0
- bridgenode_llm-0.1.0/tests/helpers.py +151 -0
- bridgenode_llm-0.1.0/tests/integration/EXA_E2E_TEST_NOTE.md +123 -0
- bridgenode_llm-0.1.0/tests/integration/__init__.py +1 -0
- bridgenode_llm-0.1.0/tests/integration/conftest.py +26 -0
- bridgenode_llm-0.1.0/tests/integration/test_production_api.py +315 -0
- bridgenode_llm-0.1.0/tests/unit/__init__.py +1 -0
- bridgenode_llm-0.1.0/tests/unit/test_client.py +180 -0
- bridgenode_llm-0.1.0/tests/unit/test_cost_log.py +196 -0
- bridgenode_llm-0.1.0/tests/unit/test_image_edit.py +102 -0
- bridgenode_llm-0.1.0/tests/unit/test_image_parameter_validation.py +93 -0
- bridgenode_llm-0.1.0/tests/unit/test_image_poll.py +271 -0
- bridgenode_llm-0.1.0/tests/unit/test_invalid_message_fail_fast.py +129 -0
- bridgenode_llm-0.1.0/tests/unit/test_paid_request_error_prefix.py +137 -0
- bridgenode_llm-0.1.0/tests/unit/test_passthrough_defi_dex_modal.py +156 -0
- bridgenode_llm-0.1.0/tests/unit/test_payment_error_helper.py +108 -0
- bridgenode_llm-0.1.0/tests/unit/test_portrait.py +46 -0
- bridgenode_llm-0.1.0/tests/unit/test_realface.py +97 -0
- bridgenode_llm-0.1.0/tests/unit/test_response_cost.py +57 -0
- bridgenode_llm-0.1.0/tests/unit/test_rpc.py +141 -0
- bridgenode_llm-0.1.0/tests/unit/test_settled_payment.py +373 -0
- bridgenode_llm-0.1.0/tests/unit/test_solana_client.py +79 -0
- bridgenode_llm-0.1.0/tests/unit/test_solana_max_tokens.py +86 -0
- bridgenode_llm-0.1.0/tests/unit/test_solana_media.py +727 -0
- bridgenode_llm-0.1.0/tests/unit/test_solana_retry_classification.py +124 -0
- bridgenode_llm-0.1.0/tests/unit/test_solana_settled_payment.py +65 -0
- bridgenode_llm-0.1.0/tests/unit/test_solana_timeout_routing.py +257 -0
- bridgenode_llm-0.1.0/tests/unit/test_solana_wallet.py +50 -0
- bridgenode_llm-0.1.0/tests/unit/test_speech.py +94 -0
- bridgenode_llm-0.1.0/tests/unit/test_spend_limits.py +203 -0
- bridgenode_llm-0.1.0/tests/unit/test_streaming.py +792 -0
- bridgenode_llm-0.1.0/tests/unit/test_streaming_solana.py +302 -0
- bridgenode_llm-0.1.0/tests/unit/test_tx_log.py +229 -0
- bridgenode_llm-0.1.0/tests/unit/test_validation.py +405 -0
- bridgenode_llm-0.1.0/tests/unit/test_version_consistency.py +49 -0
- bridgenode_llm-0.1.0/tests/unit/test_video_params.py +156 -0
- bridgenode_llm-0.1.0/tests/unit/test_wallet_selection.py +294 -0
- bridgenode_llm-0.1.0/tests/unit/test_x402.py +317 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Normalize line endings in the repository. Without this the working tree's
|
|
2
|
+
# native endings leak into commits: 3 files were converted CRLF->LF inside an
|
|
3
|
+
# unrelated behavioural fix, inflating that diff from 51 real lines to 1045 and
|
|
4
|
+
# burying the change under formatting noise. 14 other tracked files were still
|
|
5
|
+
# CRLF, so the next contributor would have regenerated it.
|
|
6
|
+
* text=auto
|
|
7
|
+
|
|
8
|
+
# Binary formats git must not touch.
|
|
9
|
+
*.png binary
|
|
10
|
+
*.jpg binary
|
|
11
|
+
*.jpeg binary
|
|
12
|
+
*.gif binary
|
|
13
|
+
*.ico binary
|
|
14
|
+
*.pdf binary
|
|
15
|
+
*.woff binary
|
|
16
|
+
*.woff2 binary
|
|
17
|
+
*.mp3 binary
|
|
18
|
+
*.mp4 binary
|
|
19
|
+
*.wav binary
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Distribution / packaging
|
|
7
|
+
.Python
|
|
8
|
+
build/
|
|
9
|
+
develop-eggs/
|
|
10
|
+
dist/
|
|
11
|
+
downloads/
|
|
12
|
+
eggs/
|
|
13
|
+
.eggs/
|
|
14
|
+
lib/
|
|
15
|
+
lib64/
|
|
16
|
+
parts/
|
|
17
|
+
sdist/
|
|
18
|
+
var/
|
|
19
|
+
wheels/
|
|
20
|
+
*.egg-info/
|
|
21
|
+
.installed.cfg
|
|
22
|
+
*.egg
|
|
23
|
+
|
|
24
|
+
# Virtual environments
|
|
25
|
+
venv/
|
|
26
|
+
env/
|
|
27
|
+
.venv/
|
|
28
|
+
.env/
|
|
29
|
+
|
|
30
|
+
# Environment files
|
|
31
|
+
.env
|
|
32
|
+
.env.local
|
|
33
|
+
.env.*.local
|
|
34
|
+
|
|
35
|
+
# IDE
|
|
36
|
+
.vscode/
|
|
37
|
+
.idea/
|
|
38
|
+
*.swp
|
|
39
|
+
*.swo
|
|
40
|
+
|
|
41
|
+
# OS
|
|
42
|
+
.DS_Store
|
|
43
|
+
Thumbs.db
|
|
44
|
+
|
|
45
|
+
# Test / coverage
|
|
46
|
+
.coverage
|
|
47
|
+
.pytest_cache/
|
|
48
|
+
htmlcov/
|
|
49
|
+
.tox/
|
|
50
|
+
.nox/
|
|
51
|
+
|
|
52
|
+
# mypy
|
|
53
|
+
.mypy_cache/
|
|
54
|
+
|
|
55
|
+
# Jupyter
|
|
56
|
+
.ipynb_checkpoints/
|
|
57
|
+
|
|
58
|
+
# Local Claude Code config (machine-specific allowlists)
|
|
59
|
+
.claude/settings.local.json
|
|
60
|
+
|
|
61
|
+
# Sweep / test-run artifacts
|
|
62
|
+
sweep-*.json
|
|
63
|
+
sweep-*.log
|
|
64
|
+
|
|
65
|
+
# Ruff cache
|
|
66
|
+
.ruff_cache/
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Guidance for AI coding agents working with the BlockRun Python SDK.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
**blockrun-llm** is a Python SDK for pay-per-request access to AI models (GPT, Claude, Gemini, DeepSeek, NVIDIA) via x402 micropayments on Base. **Includes 8 fully-free NVIDIA-hosted models** — DeepSeek V4 Flash (1M ctx), Nemotron Nano Omni (vision), Qwen3 Next + Coder, Llama 4 Maverick, Mistral Small 4, plus `gpt-oss-120b/20b` (hidden from `/v1/models` but direct calls still work). Accessible via `routing_profile="free"` or any `nvidia/*` model id.
|
|
8
|
+
|
|
9
|
+
**Package:** `blockrun-llm` (PyPI)
|
|
10
|
+
**Python:** >=3.9
|
|
11
|
+
**Network:** Base (Chain ID: 8453)
|
|
12
|
+
**Payment:** USDC via x402 v2 (or $0 for `nvidia/*` free tier)
|
|
13
|
+
|
|
14
|
+
## Repository Structure
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
blockrun-llm/
|
|
18
|
+
├── blockrun_llm/
|
|
19
|
+
│ ├── __init__.py # Package exports
|
|
20
|
+
│ ├── client.py # LLMClient, AsyncLLMClient
|
|
21
|
+
│ ├── anthropic_client.py # AnthropicClient (official SDK wrapper)
|
|
22
|
+
│ ├── solana_client.py # SolanaLLMClient (Solana payments)
|
|
23
|
+
│ ├── router.py # ClawRouter smart routing
|
|
24
|
+
│ ├── image.py # Image generation client
|
|
25
|
+
│ ├── types.py # Pydantic models and type definitions
|
|
26
|
+
│ ├── validation.py # Input validation utilities
|
|
27
|
+
│ ├── wallet.py # Wallet operations (signing, address)
|
|
28
|
+
│ ├── solana_wallet.py # Solana wallet utilities
|
|
29
|
+
│ ├── cache.py # Response caching & cost logging
|
|
30
|
+
│ └── x402.py # x402 payment protocol implementation
|
|
31
|
+
├── tests/
|
|
32
|
+
│ ├── unit/ # Unit tests (no API calls)
|
|
33
|
+
│ └── integration/ # Integration tests (requires funded wallet)
|
|
34
|
+
├── examples/ # Usage examples
|
|
35
|
+
├── pyproject.toml # Package configuration (hatchling)
|
|
36
|
+
└── README.md
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Development Commands
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Setup
|
|
43
|
+
python -m venv .venv
|
|
44
|
+
source .venv/bin/activate
|
|
45
|
+
pip install -e ".[dev]"
|
|
46
|
+
|
|
47
|
+
# Testing
|
|
48
|
+
pytest tests/unit # Unit tests only (no API key needed)
|
|
49
|
+
pytest tests/unit --cov # With coverage
|
|
50
|
+
pytest # All tests (requires BRIDGENODE_WALLET_KEY)
|
|
51
|
+
|
|
52
|
+
# Code Quality
|
|
53
|
+
black blockrun_llm/ # Format code
|
|
54
|
+
ruff check blockrun_llm/ # Lint
|
|
55
|
+
mypy blockrun_llm/ # Type check
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Code Conventions
|
|
59
|
+
|
|
60
|
+
### Style
|
|
61
|
+
- Black formatter (line-length: 100)
|
|
62
|
+
- Ruff linter
|
|
63
|
+
- Type hints required (mypy strict mode)
|
|
64
|
+
|
|
65
|
+
### Architecture
|
|
66
|
+
- `LLMClient` - Synchronous client
|
|
67
|
+
- `AsyncLLMClient` - Async client with context manager
|
|
68
|
+
- All API calls go through x402 payment flow
|
|
69
|
+
|
|
70
|
+
### Error Handling
|
|
71
|
+
- `APIError` - General API errors
|
|
72
|
+
- `PaymentError` - Payment-specific errors
|
|
73
|
+
- Errors are sanitized to prevent key leakage
|
|
74
|
+
|
|
75
|
+
## Key Files
|
|
76
|
+
|
|
77
|
+
| File | Purpose |
|
|
78
|
+
|------|---------|
|
|
79
|
+
| `client.py` | Main client classes with `chat()`, `chat_completion()`, `list_models()` |
|
|
80
|
+
| `x402.py` | x402 payment protocol (402 handling, payment signing) |
|
|
81
|
+
| `wallet.py` | Private key management, transaction signing |
|
|
82
|
+
| `validation.py` | Input validation for keys, URLs, parameters |
|
|
83
|
+
| `types.py` | Pydantic models for API requests/responses |
|
|
84
|
+
|
|
85
|
+
## Testing
|
|
86
|
+
|
|
87
|
+
### Unit Tests
|
|
88
|
+
No API key or funded wallet required:
|
|
89
|
+
```bash
|
|
90
|
+
pytest tests/unit -v
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Integration Tests
|
|
94
|
+
Requires `BRIDGENODE_WALLET_KEY` with funded Base wallet (~$1 USDC):
|
|
95
|
+
```bash
|
|
96
|
+
export BRIDGENODE_WALLET_KEY=0x...
|
|
97
|
+
pytest tests/integration -v
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Local Billing / Cost Tracking
|
|
101
|
+
Every paid call writes to `~/.blockrun/cost_log.jsonl` with model / wallet /
|
|
102
|
+
network metadata. To audit spending:
|
|
103
|
+
```bash
|
|
104
|
+
python -m bridgenode_llm.billing summary --group-by model
|
|
105
|
+
python -m bridgenode_llm.billing export csv --from 2026-05-01 --output may.csv
|
|
106
|
+
```
|
|
107
|
+
Programmatic access via `from bridgenode_llm import get_cost_log_summary,
|
|
108
|
+
export_cost_log_csv, export_cost_log_json`. Per-machine only; for
|
|
109
|
+
organization-wide accounting query the gateway's ledger.
|
|
110
|
+
|
|
111
|
+
### End-to-End Model Sweeps
|
|
112
|
+
Before a release or after router/catalog changes:
|
|
113
|
+
```bash
|
|
114
|
+
python examples/sweep_all_chat_models.py --output-json sweep-results.json
|
|
115
|
+
python examples/sweep_all_media_models.py --output-json sweep-media-results.json
|
|
116
|
+
```
|
|
117
|
+
Each script captures per-model status / latency / token counts / per-call
|
|
118
|
+
cost and exits non-zero if any expected-to-work model fails. The chat sweep
|
|
119
|
+
also runs a forward-compat diff against `/v1/models` to flag new IDs not in
|
|
120
|
+
the sweep list. Video is excluded from the media sweep by design.
|
|
121
|
+
|
|
122
|
+
## Publishing
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Build
|
|
126
|
+
python -m build
|
|
127
|
+
|
|
128
|
+
# Upload to PyPI
|
|
129
|
+
twine upload dist/*
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Security Notes
|
|
133
|
+
|
|
134
|
+
- Private keys never leave the machine (local signing only)
|
|
135
|
+
- Validate private key format before use
|
|
136
|
+
- HTTPS required for production API URLs
|
|
137
|
+
- Never log or expose private keys in errors
|