@antseed/cli 0.1.0
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.
- package/.env.example +15 -0
- package/README.md +169 -0
- package/dist/cli/commands/balance.d.ts +3 -0
- package/dist/cli/commands/balance.d.ts.map +1 -0
- package/dist/cli/commands/balance.js +64 -0
- package/dist/cli/commands/balance.js.map +1 -0
- package/dist/cli/commands/browse.d.ts +7 -0
- package/dist/cli/commands/browse.d.ts.map +1 -0
- package/dist/cli/commands/browse.js +100 -0
- package/dist/cli/commands/browse.js.map +1 -0
- package/dist/cli/commands/config.d.ts +20 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +239 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/connect.d.ts +14 -0
- package/dist/cli/commands/connect.d.ts.map +1 -0
- package/dist/cli/commands/connect.js +298 -0
- package/dist/cli/commands/connect.js.map +1 -0
- package/dist/cli/commands/connect.test.d.ts +2 -0
- package/dist/cli/commands/connect.test.d.ts.map +1 -0
- package/dist/cli/commands/connect.test.js +54 -0
- package/dist/cli/commands/connect.test.js.map +1 -0
- package/dist/cli/commands/dashboard.d.ts +6 -0
- package/dist/cli/commands/dashboard.d.ts.map +1 -0
- package/dist/cli/commands/dashboard.js +48 -0
- package/dist/cli/commands/dashboard.js.map +1 -0
- package/dist/cli/commands/deposit.d.ts +3 -0
- package/dist/cli/commands/deposit.d.ts.map +1 -0
- package/dist/cli/commands/deposit.js +48 -0
- package/dist/cli/commands/deposit.js.map +1 -0
- package/dist/cli/commands/dev.d.ts +3 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/dev.js +94 -0
- package/dist/cli/commands/dev.js.map +1 -0
- package/dist/cli/commands/init.d.ts +3 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +91 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/plugin-create.d.ts +11 -0
- package/dist/cli/commands/plugin-create.d.ts.map +1 -0
- package/dist/cli/commands/plugin-create.js +201 -0
- package/dist/cli/commands/plugin-create.js.map +1 -0
- package/dist/cli/commands/plugin-create.test.d.ts +2 -0
- package/dist/cli/commands/plugin-create.test.d.ts.map +1 -0
- package/dist/cli/commands/plugin-create.test.js +53 -0
- package/dist/cli/commands/plugin-create.test.js.map +1 -0
- package/dist/cli/commands/plugin.d.ts +3 -0
- package/dist/cli/commands/plugin.d.ts.map +1 -0
- package/dist/cli/commands/plugin.js +279 -0
- package/dist/cli/commands/plugin.js.map +1 -0
- package/dist/cli/commands/plugin.test.d.ts +2 -0
- package/dist/cli/commands/plugin.test.d.ts.map +1 -0
- package/dist/cli/commands/plugin.test.js +53 -0
- package/dist/cli/commands/plugin.test.js.map +1 -0
- package/dist/cli/commands/profile.d.ts +10 -0
- package/dist/cli/commands/profile.d.ts.map +1 -0
- package/dist/cli/commands/profile.js +89 -0
- package/dist/cli/commands/profile.js.map +1 -0
- package/dist/cli/commands/seed.d.ts +11 -0
- package/dist/cli/commands/seed.d.ts.map +1 -0
- package/dist/cli/commands/seed.js +397 -0
- package/dist/cli/commands/seed.js.map +1 -0
- package/dist/cli/commands/seed.test.d.ts +2 -0
- package/dist/cli/commands/seed.test.d.ts.map +1 -0
- package/dist/cli/commands/seed.test.js +57 -0
- package/dist/cli/commands/seed.test.js.map +1 -0
- package/dist/cli/commands/status.d.ts +8 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +55 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/types.d.ts +14 -0
- package/dist/cli/commands/types.d.ts.map +1 -0
- package/dist/cli/commands/types.js +41 -0
- package/dist/cli/commands/types.js.map +1 -0
- package/dist/cli/commands/withdraw.d.ts +3 -0
- package/dist/cli/commands/withdraw.d.ts.map +1 -0
- package/dist/cli/commands/withdraw.js +48 -0
- package/dist/cli/commands/withdraw.js.map +1 -0
- package/dist/cli/formatters.d.ts +29 -0
- package/dist/cli/formatters.d.ts.map +1 -0
- package/dist/cli/formatters.js +67 -0
- package/dist/cli/formatters.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +41 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/shutdown.d.ts +11 -0
- package/dist/cli/shutdown.d.ts.map +1 -0
- package/dist/cli/shutdown.js +34 -0
- package/dist/cli/shutdown.js.map +1 -0
- package/dist/config/defaults.d.ts +6 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +48 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/effective.d.ts +26 -0
- package/dist/config/effective.d.ts.map +1 -0
- package/dist/config/effective.js +84 -0
- package/dist/config/effective.js.map +1 -0
- package/dist/config/effective.test.d.ts +2 -0
- package/dist/config/effective.test.d.ts.map +1 -0
- package/dist/config/effective.test.js +65 -0
- package/dist/config/effective.test.js.map +1 -0
- package/dist/config/loader.d.ts +12 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +212 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/loader.test.d.ts +2 -0
- package/dist/config/loader.test.d.ts.map +1 -0
- package/dist/config/loader.test.js +77 -0
- package/dist/config/loader.test.js.map +1 -0
- package/dist/config/types.d.ts +133 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/config/validation.d.ts +10 -0
- package/dist/config/validation.d.ts.map +1 -0
- package/dist/config/validation.js +50 -0
- package/dist/config/validation.js.map +1 -0
- package/dist/env/load-env.d.ts +6 -0
- package/dist/env/load-env.d.ts.map +1 -0
- package/dist/env/load-env.js +18 -0
- package/dist/env/load-env.js.map +1 -0
- package/dist/plugins/loader.d.ts +7 -0
- package/dist/plugins/loader.d.ts.map +1 -0
- package/dist/plugins/loader.js +70 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/manager.d.ts +11 -0
- package/dist/plugins/manager.d.ts.map +1 -0
- package/dist/plugins/manager.js +52 -0
- package/dist/plugins/manager.js.map +1 -0
- package/dist/plugins/registry.d.ts +8 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +39 -0
- package/dist/plugins/registry.js.map +1 -0
- package/dist/proxy/buyer-proxy.d.ts +30 -0
- package/dist/proxy/buyer-proxy.d.ts.map +1 -0
- package/dist/proxy/buyer-proxy.js +488 -0
- package/dist/proxy/buyer-proxy.js.map +1 -0
- package/dist/status/node-status.d.ts +22 -0
- package/dist/status/node-status.d.ts.map +1 -0
- package/dist/status/node-status.js +83 -0
- package/dist/status/node-status.js.map +1 -0
- package/package.json +39 -0
- package/src/cli/commands/balance.ts +77 -0
- package/src/cli/commands/browse.ts +113 -0
- package/src/cli/commands/config.ts +271 -0
- package/src/cli/commands/connect.test.ts +69 -0
- package/src/cli/commands/connect.ts +342 -0
- package/src/cli/commands/dashboard.ts +59 -0
- package/src/cli/commands/deposit.ts +61 -0
- package/src/cli/commands/dev.ts +107 -0
- package/src/cli/commands/init.ts +99 -0
- package/src/cli/commands/plugin-create.test.ts +60 -0
- package/src/cli/commands/plugin-create.ts +230 -0
- package/src/cli/commands/plugin.test.ts +55 -0
- package/src/cli/commands/plugin.ts +295 -0
- package/src/cli/commands/profile.ts +95 -0
- package/src/cli/commands/seed.test.ts +70 -0
- package/src/cli/commands/seed.ts +447 -0
- package/src/cli/commands/status.ts +73 -0
- package/src/cli/commands/types.ts +56 -0
- package/src/cli/commands/withdraw.ts +61 -0
- package/src/cli/formatters.ts +64 -0
- package/src/cli/index.ts +46 -0
- package/src/cli/shutdown.ts +38 -0
- package/src/config/defaults.ts +49 -0
- package/src/config/effective.test.ts +80 -0
- package/src/config/effective.ts +119 -0
- package/src/config/loader.test.ts +95 -0
- package/src/config/loader.ts +251 -0
- package/src/config/types.ts +139 -0
- package/src/config/validation.ts +78 -0
- package/src/env/load-env.ts +20 -0
- package/src/plugins/loader.ts +96 -0
- package/src/plugins/manager.ts +66 -0
- package/src/plugins/registry.ts +45 -0
- package/src/proxy/buyer-proxy.ts +604 -0
- package/src/status/node-status.ts +105 -0
- package/tsconfig.json +9 -0
package/.env.example
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Enable verbose runtime logs across packages (0/1)
|
|
2
|
+
ANTSEED_DEBUG=0
|
|
3
|
+
|
|
4
|
+
# Dashboard frontend debug logs (0/1)
|
|
5
|
+
VITE_ANTSEED_DEBUG=0
|
|
6
|
+
|
|
7
|
+
# Optional: override env file path for runtime env loading
|
|
8
|
+
# ANTSEED_ENV_FILE=.env
|
|
9
|
+
|
|
10
|
+
# Settlement runtime (requires config.payments.crypto in config.json)
|
|
11
|
+
# ANTSEED_ENABLE_SETTLEMENT=true
|
|
12
|
+
# ANTSEED_SETTLEMENT_IDLE_MS=30000
|
|
13
|
+
# ANTSEED_DEFAULT_ESCROW_USDC=1
|
|
14
|
+
# ANTSEED_AUTO_FUND_ESCROW=true
|
|
15
|
+
# ANTSEED_SELLER_WALLET_ADDRESS=0x...
|
package/README.md
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Antseed CLI + Dashboard
|
|
2
|
+
|
|
3
|
+
Command-line interface and web dashboard for the Antseed Network -- a P2P marketplace for reselling idle LLM plan capacity.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
| Command | Description |
|
|
8
|
+
|---------|-------------|
|
|
9
|
+
| `antseed init` | Install trusted provider and router plugins |
|
|
10
|
+
| `antseed seed` | Start seeding your idle LLM capacity to the P2P network |
|
|
11
|
+
| `antseed connect` | Start the buyer proxy and connect to sellers |
|
|
12
|
+
| `antseed plugin add <pkg>` | Install a provider or router plugin from npm |
|
|
13
|
+
| `antseed plugin remove <name>` | Remove an installed plugin |
|
|
14
|
+
| `antseed plugin list` | List installed plugins |
|
|
15
|
+
| `antseed status` | Show current node status |
|
|
16
|
+
| `antseed config` | Manage configuration (`show`, `set`, `seller show/set`, `buyer show/set`, `init`) |
|
|
17
|
+
| `antseed dashboard` | Start the web dashboard for monitoring and configuration |
|
|
18
|
+
| `antseed dev` | Run seller + buyer locally for development and testing |
|
|
19
|
+
| `antseed browse` | Browse available models, prices, and reputation on the network |
|
|
20
|
+
|
|
21
|
+
## Plugins
|
|
22
|
+
|
|
23
|
+
Antseed uses an open plugin ecosystem. Plugins are installed into `~/.antseed/plugins/` via npm.
|
|
24
|
+
|
|
25
|
+
**Providers** connect your node to an upstream AI API (seeder mode):
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
antseed plugin add @antseed/provider-anthropic # API key auth
|
|
29
|
+
antseed plugin add @antseed/provider-claude-code # Claude Code keychain auth
|
|
30
|
+
antseed seed --provider anthropic
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Routers** select peers and proxy requests (consumer mode):
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
antseed plugin add @antseed/router-local-proxy
|
|
37
|
+
antseed connect --router local-proxy
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Run `antseed init` to install all trusted plugins interactively.
|
|
41
|
+
|
|
42
|
+
## Configuration
|
|
43
|
+
|
|
44
|
+
Configuration is stored at `~/.antseed/config.json` by default. Use `-c` / `--config` to specify an alternative path.
|
|
45
|
+
|
|
46
|
+
Runtime env variables are loaded via `dotenv` from `.env.local` and `.env` in the current working directory.
|
|
47
|
+
See `.env.example` for supported keys.
|
|
48
|
+
|
|
49
|
+
Enable debug logs with either:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
antseed -v <command>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
or:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
ANTSEED_DEBUG=1 antseed <command>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
For dashboard frontend debug logging, set:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
VITE_ANTSEED_DEBUG=1
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Initialize a new config:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
antseed config init
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Pricing is configured in USD per 1M tokens with role-specific defaults and optional provider/model overrides:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"seller": {
|
|
78
|
+
"pricing": {
|
|
79
|
+
"defaults": {
|
|
80
|
+
"inputUsdPerMillion": 10,
|
|
81
|
+
"outputUsdPerMillion": 10
|
|
82
|
+
},
|
|
83
|
+
"providers": {
|
|
84
|
+
"anthropic": {
|
|
85
|
+
"models": {
|
|
86
|
+
"claude-sonnet-4-5-20250929": {
|
|
87
|
+
"inputUsdPerMillion": 12,
|
|
88
|
+
"outputUsdPerMillion": 18
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"buyer": {
|
|
96
|
+
"preferredProviders": ["anthropic", "openai"],
|
|
97
|
+
"maxPricing": {
|
|
98
|
+
"defaults": {
|
|
99
|
+
"inputUsdPerMillion": 100,
|
|
100
|
+
"outputUsdPerMillion": 100
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Role-first config examples:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# Seller defaults
|
|
111
|
+
antseed config seller set pricing.defaults.inputUsdPerMillion 12
|
|
112
|
+
antseed config seller set pricing.defaults.outputUsdPerMillion 36
|
|
113
|
+
|
|
114
|
+
# Seller per-model override for a provider
|
|
115
|
+
antseed config seller set pricing.providers.anthropic.models '{"claude-sonnet-4-5-20250929":{"inputUsdPerMillion":14,"outputUsdPerMillion":42}}'
|
|
116
|
+
|
|
117
|
+
# Buyer preferences and max pricing
|
|
118
|
+
antseed config buyer set preferredProviders '["anthropic","openai"]'
|
|
119
|
+
antseed config buyer set maxPricing.defaults.inputUsdPerMillion 25
|
|
120
|
+
antseed config buyer set maxPricing.defaults.outputUsdPerMillion 75
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Runtime-only overrides (do not write your config file):
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
antseed seed --provider anthropic --input-usd-per-million 10 --output-usd-per-million 30
|
|
127
|
+
antseed connect --router local-proxy --max-input-usd-per-million 20 --max-output-usd-per-million 60
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Settlement Runtime (Seeder)
|
|
131
|
+
|
|
132
|
+
`antseed seed` can enable automatic session settlement when payment config is present.
|
|
133
|
+
`antseed connect` can also enable buyer-side escrow/session locking with the same payment config.
|
|
134
|
+
|
|
135
|
+
Common runtime env controls:
|
|
136
|
+
- `ANTSEED_ENABLE_SETTLEMENT=true|false`
|
|
137
|
+
- `ANTSEED_SETTLEMENT_IDLE_MS=30000`
|
|
138
|
+
- `ANTSEED_DEFAULT_ESCROW_USDC=1`
|
|
139
|
+
- `ANTSEED_AUTO_FUND_ESCROW=true|false`
|
|
140
|
+
- `ANTSEED_SELLER_WALLET_ADDRESS=0x...`
|
|
141
|
+
|
|
142
|
+
Crypto settlement also requires `config.payments.crypto` values in your config file:
|
|
143
|
+
- `chainId` (`base` or `arbitrum`)
|
|
144
|
+
- `rpcUrl`
|
|
145
|
+
- `escrowContractAddress`
|
|
146
|
+
- `usdcContractAddress`
|
|
147
|
+
|
|
148
|
+
If `ANTSEED_ENABLE_SETTLEMENT` is not explicitly set and the RPC endpoint is unreachable,
|
|
149
|
+
the CLI now auto-disables settlement for that run and logs a warning instead of looping RPC network-detection errors.
|
|
150
|
+
Set `ANTSEED_ENABLE_SETTLEMENT=true` to force-enable settlement checks.
|
|
151
|
+
|
|
152
|
+
Runtime behavior:
|
|
153
|
+
- session opens -> optional escrow deposit
|
|
154
|
+
- session finalizes -> exact on-chain split settlement (`seller payout + platform fee + buyer refund remainder`)
|
|
155
|
+
- no receipts -> escrow refund path
|
|
156
|
+
|
|
157
|
+
Provider-specific options are configured via each plugin's config schema (see `antseed plugin add --help`).
|
|
158
|
+
|
|
159
|
+
## Development
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
npm install
|
|
163
|
+
npm run build
|
|
164
|
+
npm run dev
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Links
|
|
168
|
+
|
|
169
|
+
- Node SDK: `@antseed/node` (`../node`)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"balance.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/balance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmBzC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyD7D"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { getGlobalOptions } from './types.js';
|
|
4
|
+
import { loadConfig } from '../../config/loader.js';
|
|
5
|
+
import { loadOrCreateIdentity, BaseEscrowClient, identityToEvmAddress, } from '@antseed/node';
|
|
6
|
+
/** Format USDC base units (6 decimals) to human-readable string. */
|
|
7
|
+
function formatUsdc(baseUnits) {
|
|
8
|
+
const whole = baseUnits / 1000000n;
|
|
9
|
+
const frac = baseUnits % 1000000n;
|
|
10
|
+
const fracStr = frac.toString().padStart(6, '0').replace(/0+$/, '') || '0';
|
|
11
|
+
return `${whole}.${fracStr}`;
|
|
12
|
+
}
|
|
13
|
+
export function registerBalanceCommand(program) {
|
|
14
|
+
program
|
|
15
|
+
.command('balance')
|
|
16
|
+
.description('Show escrow balance for your wallet')
|
|
17
|
+
.option('--json', 'output as JSON', false)
|
|
18
|
+
.action(async (options) => {
|
|
19
|
+
const globalOpts = getGlobalOptions(program);
|
|
20
|
+
const config = await loadConfig(globalOpts.config);
|
|
21
|
+
const payments = config.payments;
|
|
22
|
+
if (!payments?.crypto) {
|
|
23
|
+
console.error(chalk.red('Error: No crypto payment configuration found.'));
|
|
24
|
+
console.error(chalk.dim('Configure payments.crypto in your config file or run: antseed init'));
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
const identity = await loadOrCreateIdentity(globalOpts.dataDir);
|
|
28
|
+
const address = identityToEvmAddress(identity);
|
|
29
|
+
const escrowClient = new BaseEscrowClient({
|
|
30
|
+
rpcUrl: payments.crypto.rpcUrl,
|
|
31
|
+
contractAddress: payments.crypto.escrowContractAddress,
|
|
32
|
+
usdcAddress: payments.crypto.usdcContractAddress,
|
|
33
|
+
});
|
|
34
|
+
const spinner = ora('Fetching balance...').start();
|
|
35
|
+
try {
|
|
36
|
+
const account = await escrowClient.getBuyerAccount(address);
|
|
37
|
+
const usdcBalance = await escrowClient.getUSDCBalance(address);
|
|
38
|
+
spinner.stop();
|
|
39
|
+
if (options.json) {
|
|
40
|
+
console.log(JSON.stringify({
|
|
41
|
+
address,
|
|
42
|
+
walletUSDC: formatUsdc(usdcBalance),
|
|
43
|
+
escrowDeposited: formatUsdc(account.deposited),
|
|
44
|
+
escrowCommitted: formatUsdc(account.committed),
|
|
45
|
+
escrowAvailable: formatUsdc(account.available),
|
|
46
|
+
}, null, 2));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
console.log(chalk.bold('Wallet: ') + chalk.cyan(address));
|
|
50
|
+
console.log('');
|
|
51
|
+
console.log(chalk.bold('USDC Balance (wallet): ') + chalk.green(formatUsdc(usdcBalance) + ' USDC'));
|
|
52
|
+
console.log('');
|
|
53
|
+
console.log(chalk.bold('Escrow Account:'));
|
|
54
|
+
console.log(` Deposited: ${chalk.green(formatUsdc(account.deposited) + ' USDC')}`);
|
|
55
|
+
console.log(` Committed: ${chalk.yellow(formatUsdc(account.committed) + ' USDC')}`);
|
|
56
|
+
console.log(` Available: ${chalk.green(formatUsdc(account.available) + ' USDC')}`);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
spinner.fail(chalk.red(`Failed to fetch balance: ${err.message}`));
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=balance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"balance.js","sourceRoot":"","sources":["../../../src/cli/commands/balance.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* Register the `antseed browse` command on the Commander program.
|
|
4
|
+
* Discovers peers on the network and displays available models, prices, and reputation.
|
|
5
|
+
*/
|
|
6
|
+
export declare function registerBrowseCommand(program: Command): void;
|
|
7
|
+
//# sourceMappingURL=browse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browse.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/browse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmBzC;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyF5D"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import Table from 'cli-table3';
|
|
4
|
+
import { getGlobalOptions } from './types.js';
|
|
5
|
+
import { loadConfig } from '../../config/loader.js';
|
|
6
|
+
import { AntseedNode } from '@antseed/node';
|
|
7
|
+
import { parseBootstrapList, toBootstrapConfig } from '@antseed/node/discovery';
|
|
8
|
+
function getReputationColor(reputation) {
|
|
9
|
+
if (reputation >= 80) {
|
|
10
|
+
return chalk.green;
|
|
11
|
+
}
|
|
12
|
+
if (reputation >= 50) {
|
|
13
|
+
return chalk.yellow;
|
|
14
|
+
}
|
|
15
|
+
return chalk.red;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Register the `antseed browse` command on the Commander program.
|
|
19
|
+
* Discovers peers on the network and displays available models, prices, and reputation.
|
|
20
|
+
*/
|
|
21
|
+
export function registerBrowseCommand(program) {
|
|
22
|
+
program
|
|
23
|
+
.command('browse')
|
|
24
|
+
.description('Browse available models, prices, and reputation on the P2P network')
|
|
25
|
+
.option('-m, --model <model>', 'filter by model name')
|
|
26
|
+
.option('--json', 'output as JSON', false)
|
|
27
|
+
.action(async (options) => {
|
|
28
|
+
const globalOpts = getGlobalOptions(program);
|
|
29
|
+
const config = await loadConfig(globalOpts.config);
|
|
30
|
+
const bootstrapNodes = config.network.bootstrapNodes.length > 0
|
|
31
|
+
? toBootstrapConfig(parseBootstrapList(config.network.bootstrapNodes))
|
|
32
|
+
: undefined;
|
|
33
|
+
const spinner = ora('Discovering peers on the network...').start();
|
|
34
|
+
const node = new AntseedNode({
|
|
35
|
+
role: 'buyer',
|
|
36
|
+
bootstrapNodes,
|
|
37
|
+
});
|
|
38
|
+
try {
|
|
39
|
+
await node.start();
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
spinner.fail(chalk.red(`Failed to connect to network: ${err.message}`));
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const peers = await node.discoverPeers(options.model);
|
|
47
|
+
spinner.succeed(chalk.green(`Found ${peers.length} peer(s)`));
|
|
48
|
+
if (peers.length === 0) {
|
|
49
|
+
console.log(chalk.dim('No peers found. Try again later or check your bootstrap nodes.'));
|
|
50
|
+
await node.stop();
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (options.json) {
|
|
54
|
+
console.log(JSON.stringify(peers, null, 2));
|
|
55
|
+
await node.stop();
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// Display peers in a table
|
|
59
|
+
const table = new Table({
|
|
60
|
+
head: [
|
|
61
|
+
chalk.bold('Peer ID'),
|
|
62
|
+
chalk.bold('Providers'),
|
|
63
|
+
chalk.bold('Input $/1M'),
|
|
64
|
+
chalk.bold('Output $/1M'),
|
|
65
|
+
chalk.bold('Reputation'),
|
|
66
|
+
chalk.bold('Load'),
|
|
67
|
+
],
|
|
68
|
+
colWidths: [16, 18, 14, 14, 12, 10],
|
|
69
|
+
});
|
|
70
|
+
for (const peer of peers) {
|
|
71
|
+
const reputation = peer.reputationScore ?? 0;
|
|
72
|
+
const repLabel = `${reputation}%`;
|
|
73
|
+
const repColor = getReputationColor(reputation);
|
|
74
|
+
const load = peer.currentLoad !== undefined && peer.maxConcurrency !== undefined
|
|
75
|
+
? `${peer.currentLoad}/${peer.maxConcurrency}`
|
|
76
|
+
: chalk.dim('n/a');
|
|
77
|
+
table.push([
|
|
78
|
+
chalk.dim(peer.peerId.slice(0, 12) + '...'),
|
|
79
|
+
peer.providers.join(', '),
|
|
80
|
+
peer.defaultInputUsdPerMillion !== undefined
|
|
81
|
+
? `$${peer.defaultInputUsdPerMillion.toFixed(2)}`
|
|
82
|
+
: chalk.dim('n/a'),
|
|
83
|
+
peer.defaultOutputUsdPerMillion !== undefined
|
|
84
|
+
? `$${peer.defaultOutputUsdPerMillion.toFixed(2)}`
|
|
85
|
+
: chalk.dim('n/a'),
|
|
86
|
+
repColor(repLabel),
|
|
87
|
+
load,
|
|
88
|
+
]);
|
|
89
|
+
}
|
|
90
|
+
console.log('');
|
|
91
|
+
console.log(table.toString());
|
|
92
|
+
console.log('');
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
spinner.fail(chalk.red(`Discovery failed: ${err.message}`));
|
|
96
|
+
}
|
|
97
|
+
await node.stop();
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=browse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browse.js","sourceRoot":"","sources":["../../../src/cli/commands/browse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import type { AntseedConfig, ProviderConfig, ProviderType } from '../../config/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Register the `antseed config` command and its subcommands.
|
|
5
|
+
*/
|
|
6
|
+
export declare function registerConfigCommand(program: Command): void;
|
|
7
|
+
/**
|
|
8
|
+
* Redact sensitive fields (auth values) from config for display.
|
|
9
|
+
*/
|
|
10
|
+
export declare function redactConfig(config: AntseedConfig): Record<string, unknown>;
|
|
11
|
+
/**
|
|
12
|
+
* Set a nested config value by dot-separated key path.
|
|
13
|
+
* @example setConfigValue(config, 'seller.reserveFloor', '20')
|
|
14
|
+
*/
|
|
15
|
+
export declare function setConfigValue(config: Record<string, unknown>, key: string, value: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Build a ProviderConfig with default endpoint and auth header for known providers.
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildProviderConfig(type: ProviderType, authValue: string, customEndpoint?: string): ProviderConfig;
|
|
20
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGzF;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyI5D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAW3E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CA4BhG;AA8CD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,YAAY,EAClB,SAAS,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,MAAM,GACtB,cAAc,CAoBhB"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { getGlobalOptions } from './types.js';
|
|
3
|
+
import { loadConfig, saveConfig } from '../../config/loader.js';
|
|
4
|
+
import { assertValidConfig } from '../../config/validation.js';
|
|
5
|
+
/**
|
|
6
|
+
* Register the `antseed config` command and its subcommands.
|
|
7
|
+
*/
|
|
8
|
+
export function registerConfigCommand(program) {
|
|
9
|
+
const configCmd = program
|
|
10
|
+
.command('config')
|
|
11
|
+
.description('Manage Antseed configuration');
|
|
12
|
+
// antseed config show
|
|
13
|
+
configCmd
|
|
14
|
+
.command('show')
|
|
15
|
+
.description('Display current configuration (credentials redacted)')
|
|
16
|
+
.action(async () => {
|
|
17
|
+
const globalOpts = getGlobalOptions(program);
|
|
18
|
+
const config = await loadConfig(globalOpts.config);
|
|
19
|
+
const redacted = redactConfig(config);
|
|
20
|
+
console.log(JSON.stringify(redacted, null, 2));
|
|
21
|
+
});
|
|
22
|
+
// antseed config set <key> <value>
|
|
23
|
+
configCmd
|
|
24
|
+
.command('set <key> <value>')
|
|
25
|
+
.description('Set a configuration value (e.g., seller.reserveFloor 20)')
|
|
26
|
+
.action(async (key, value) => {
|
|
27
|
+
try {
|
|
28
|
+
const globalOpts = getGlobalOptions(program);
|
|
29
|
+
const config = await loadConfig(globalOpts.config);
|
|
30
|
+
const validKeys = getValidConfigKeys(config);
|
|
31
|
+
if (!validKeys.includes(key)) {
|
|
32
|
+
console.error(chalk.red(`Invalid config key: ${key}`));
|
|
33
|
+
console.error(chalk.dim(`Available keys: ${validKeys.join(', ')}`));
|
|
34
|
+
process.exitCode = 1;
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
setConfigValue(config, key, value);
|
|
38
|
+
assertValidConfig(config);
|
|
39
|
+
await saveConfig(globalOpts.config, config);
|
|
40
|
+
console.log(chalk.green(`Set ${key} = ${value}`));
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
console.error(chalk.red(`Error: ${err.message}`));
|
|
44
|
+
process.exitCode = 1;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
const sellerCmd = configCmd
|
|
48
|
+
.command('seller')
|
|
49
|
+
.description('Role-scoped seller configuration commands');
|
|
50
|
+
sellerCmd
|
|
51
|
+
.command('show')
|
|
52
|
+
.description('Display seller configuration')
|
|
53
|
+
.action(async () => {
|
|
54
|
+
const globalOpts = getGlobalOptions(program);
|
|
55
|
+
const config = await loadConfig(globalOpts.config);
|
|
56
|
+
console.log(JSON.stringify(config.seller, null, 2));
|
|
57
|
+
});
|
|
58
|
+
sellerCmd
|
|
59
|
+
.command('set <key> <value>')
|
|
60
|
+
.description('Set seller configuration value (e.g., pricing.defaults.inputUsdPerMillion 12)')
|
|
61
|
+
.action(async (key, value) => {
|
|
62
|
+
await setRoleScopedValue(program, 'seller', key, value);
|
|
63
|
+
});
|
|
64
|
+
const buyerCmd = configCmd
|
|
65
|
+
.command('buyer')
|
|
66
|
+
.description('Role-scoped buyer configuration commands');
|
|
67
|
+
buyerCmd
|
|
68
|
+
.command('show')
|
|
69
|
+
.description('Display buyer configuration')
|
|
70
|
+
.action(async () => {
|
|
71
|
+
const globalOpts = getGlobalOptions(program);
|
|
72
|
+
const config = await loadConfig(globalOpts.config);
|
|
73
|
+
console.log(JSON.stringify(config.buyer, null, 2));
|
|
74
|
+
});
|
|
75
|
+
buyerCmd
|
|
76
|
+
.command('set <key> <value>')
|
|
77
|
+
.description('Set buyer configuration value (e.g., preferredProviders [\"anthropic\",\"openai\"])')
|
|
78
|
+
.action(async (key, value) => {
|
|
79
|
+
await setRoleScopedValue(program, 'buyer', key, value);
|
|
80
|
+
});
|
|
81
|
+
// antseed config add-provider
|
|
82
|
+
configCmd
|
|
83
|
+
.command('add-provider')
|
|
84
|
+
.description('Add a new provider credential')
|
|
85
|
+
.requiredOption('-t, --type <type>', 'provider type (anthropic, openai, google, moonshot)')
|
|
86
|
+
.requiredOption('-k, --key <key>', 'API key or auth token')
|
|
87
|
+
.option('-e, --endpoint <url>', 'custom API endpoint URL')
|
|
88
|
+
.action(async (options) => {
|
|
89
|
+
const knownTypes = ['anthropic', 'openai', 'google', 'moonshot'];
|
|
90
|
+
if (!knownTypes.includes(options.type)) {
|
|
91
|
+
console.error(chalk.red(`Unknown provider type: ${options.type}`));
|
|
92
|
+
console.error(chalk.dim(`Known types: ${knownTypes.join(', ')}`));
|
|
93
|
+
process.exitCode = 1;
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const globalOpts = getGlobalOptions(program);
|
|
97
|
+
const config = await loadConfig(globalOpts.config);
|
|
98
|
+
const provider = buildProviderConfig(options.type, options.key, options.endpoint);
|
|
99
|
+
config.providers.push(provider);
|
|
100
|
+
await saveConfig(globalOpts.config, config);
|
|
101
|
+
console.log(chalk.green(`Added ${options.type} provider`));
|
|
102
|
+
});
|
|
103
|
+
// antseed config remove-provider <type>
|
|
104
|
+
configCmd
|
|
105
|
+
.command('remove-provider <type>')
|
|
106
|
+
.description('Remove a provider credential by type')
|
|
107
|
+
.action(async (type) => {
|
|
108
|
+
const globalOpts = getGlobalOptions(program);
|
|
109
|
+
const config = await loadConfig(globalOpts.config);
|
|
110
|
+
const before = config.providers.length;
|
|
111
|
+
config.providers = config.providers.filter((p) => p.type !== type);
|
|
112
|
+
const removed = before - config.providers.length;
|
|
113
|
+
await saveConfig(globalOpts.config, config);
|
|
114
|
+
if (removed > 0) {
|
|
115
|
+
console.log(chalk.green(`Removed ${removed} ${type} provider(s)`));
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
console.log(chalk.yellow(`No ${type} provider found`));
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
// antseed config init
|
|
122
|
+
configCmd
|
|
123
|
+
.command('init')
|
|
124
|
+
.description('Initialize a new config file with defaults')
|
|
125
|
+
.action(async () => {
|
|
126
|
+
const globalOpts = getGlobalOptions(program);
|
|
127
|
+
const { createDefaultConfig } = await import('../../config/defaults.js');
|
|
128
|
+
const config = createDefaultConfig();
|
|
129
|
+
await saveConfig(globalOpts.config, config);
|
|
130
|
+
console.log(chalk.green(`Config initialized at ${globalOpts.config}`));
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Redact sensitive fields (auth values) from config for display.
|
|
135
|
+
*/
|
|
136
|
+
export function redactConfig(config) {
|
|
137
|
+
const clone = JSON.parse(JSON.stringify(config));
|
|
138
|
+
const providers = clone['providers'];
|
|
139
|
+
for (const provider of providers ?? []) {
|
|
140
|
+
if (provider['authValue']) {
|
|
141
|
+
const val = provider['authValue'];
|
|
142
|
+
provider['authValue'] = val.slice(0, 8) + '...' + val.slice(-4);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return clone;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Set a nested config value by dot-separated key path.
|
|
149
|
+
* @example setConfigValue(config, 'seller.reserveFloor', '20')
|
|
150
|
+
*/
|
|
151
|
+
export function setConfigValue(config, key, value) {
|
|
152
|
+
const parts = key.split('.');
|
|
153
|
+
let current = config;
|
|
154
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
155
|
+
const part = parts[i];
|
|
156
|
+
if (typeof current[part] !== 'object' || current[part] === null) {
|
|
157
|
+
throw new Error(`Invalid config key: ${key}`);
|
|
158
|
+
}
|
|
159
|
+
current = current[part];
|
|
160
|
+
}
|
|
161
|
+
const lastKey = parts[parts.length - 1];
|
|
162
|
+
const trimmed = value.trim();
|
|
163
|
+
if ((trimmed.startsWith('{') && trimmed.endsWith('}')) ||
|
|
164
|
+
(trimmed.startsWith('[') && trimmed.endsWith(']'))) {
|
|
165
|
+
try {
|
|
166
|
+
current[lastKey] = JSON.parse(trimmed);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
throw new Error(`Invalid JSON value for ${key}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Auto-parse numeric scalars
|
|
174
|
+
const numVal = Number(trimmed);
|
|
175
|
+
current[lastKey] = Number.isNaN(numVal) ? value : numVal;
|
|
176
|
+
}
|
|
177
|
+
function getValidConfigKeys(config, prefix = '') {
|
|
178
|
+
const keys = [];
|
|
179
|
+
for (const [k, v] of Object.entries(config)) {
|
|
180
|
+
if (k === 'providers' || k === 'plugins')
|
|
181
|
+
continue;
|
|
182
|
+
const path = prefix ? `${prefix}.${k}` : k;
|
|
183
|
+
if (v && typeof v === 'object' && !Array.isArray(v)) {
|
|
184
|
+
keys.push(...getValidConfigKeys(v, path));
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
keys.push(path);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return keys;
|
|
191
|
+
}
|
|
192
|
+
async function setRoleScopedValue(program, role, key, value) {
|
|
193
|
+
try {
|
|
194
|
+
const globalOpts = getGlobalOptions(program);
|
|
195
|
+
const config = await loadConfig(globalOpts.config);
|
|
196
|
+
const fullKey = `${role}.${key}`;
|
|
197
|
+
const validKeys = getValidConfigKeys(config);
|
|
198
|
+
if (!validKeys.includes(fullKey)) {
|
|
199
|
+
console.error(chalk.red(`Invalid ${role} config key: ${key}`));
|
|
200
|
+
const scopedKeys = validKeys
|
|
201
|
+
.filter((path) => path.startsWith(`${role}.`))
|
|
202
|
+
.map((path) => path.slice(role.length + 1));
|
|
203
|
+
console.error(chalk.dim(`Available ${role} keys: ${scopedKeys.join(', ')}`));
|
|
204
|
+
process.exitCode = 1;
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
setConfigValue(config, fullKey, value);
|
|
208
|
+
assertValidConfig(config);
|
|
209
|
+
await saveConfig(globalOpts.config, config);
|
|
210
|
+
console.log(chalk.green(`Set ${fullKey} = ${value}`));
|
|
211
|
+
}
|
|
212
|
+
catch (err) {
|
|
213
|
+
console.error(chalk.red(`Error: ${err.message}`));
|
|
214
|
+
process.exitCode = 1;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Build a ProviderConfig with default endpoint and auth header for known providers.
|
|
219
|
+
*/
|
|
220
|
+
export function buildProviderConfig(type, authValue, customEndpoint) {
|
|
221
|
+
const defaults = {
|
|
222
|
+
anthropic: { endpoint: 'https://api.anthropic.com', authHeaderName: 'x-api-key' },
|
|
223
|
+
openai: { endpoint: 'https://api.openai.com', authHeaderName: 'Authorization' },
|
|
224
|
+
google: { endpoint: 'https://generativelanguage.googleapis.com', authHeaderName: 'x-goog-api-key' },
|
|
225
|
+
moonshot: { endpoint: 'https://api.moonshot.cn', authHeaderName: 'Authorization' },
|
|
226
|
+
};
|
|
227
|
+
const fallbackDefaults = {
|
|
228
|
+
endpoint: customEndpoint ?? '',
|
|
229
|
+
authHeaderName: 'Authorization',
|
|
230
|
+
};
|
|
231
|
+
const def = defaults[type] ?? fallbackDefaults;
|
|
232
|
+
return {
|
|
233
|
+
type,
|
|
234
|
+
endpoint: customEndpoint ?? def.endpoint,
|
|
235
|
+
authHeaderName: def.authHeaderName,
|
|
236
|
+
authValue,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=config.js.map
|