@blockrun/clawrouter 0.12.95 → 0.12.96
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/dist/auth.d.ts +82 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +388 -0
- package/dist/auth.js.map +1 -0
- package/dist/balance.d.ts +97 -0
- package/dist/balance.d.ts.map +1 -0
- package/dist/balance.js +157 -0
- package/dist/balance.js.map +1 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +256 -54994
- package/dist/cli.js.map +1 -1
- package/dist/compression/codebook.d.ts +24 -0
- package/dist/compression/codebook.d.ts.map +1 -0
- package/dist/compression/codebook.js +119 -0
- package/dist/compression/codebook.js.map +1 -0
- package/dist/compression/index.d.ts +33 -0
- package/dist/compression/index.d.ts.map +1 -0
- package/dist/compression/index.js +246 -0
- package/dist/compression/index.js.map +1 -0
- package/dist/compression/layers/deduplication.d.ts +28 -0
- package/dist/compression/layers/deduplication.d.ts.map +1 -0
- package/dist/compression/layers/deduplication.js +101 -0
- package/dist/compression/layers/deduplication.js.map +1 -0
- package/dist/compression/layers/dictionary.d.ts +21 -0
- package/dist/compression/layers/dictionary.d.ts.map +1 -0
- package/dist/compression/layers/dictionary.js +73 -0
- package/dist/compression/layers/dictionary.js.map +1 -0
- package/dist/compression/layers/dynamic-codebook.d.ts +26 -0
- package/dist/compression/layers/dynamic-codebook.d.ts.map +1 -0
- package/dist/compression/layers/dynamic-codebook.js +149 -0
- package/dist/compression/layers/dynamic-codebook.js.map +1 -0
- package/dist/compression/layers/json-compact.d.ts +23 -0
- package/dist/compression/layers/json-compact.d.ts.map +1 -0
- package/dist/compression/layers/json-compact.js +79 -0
- package/dist/compression/layers/json-compact.js.map +1 -0
- package/dist/compression/layers/observation.d.ts +21 -0
- package/dist/compression/layers/observation.d.ts.map +1 -0
- package/dist/compression/layers/observation.js +130 -0
- package/dist/compression/layers/observation.js.map +1 -0
- package/dist/compression/layers/paths.d.ts +24 -0
- package/dist/compression/layers/paths.d.ts.map +1 -0
- package/dist/compression/layers/paths.js +110 -0
- package/dist/compression/layers/paths.js.map +1 -0
- package/dist/compression/layers/whitespace.d.ts +27 -0
- package/dist/compression/layers/whitespace.d.ts.map +1 -0
- package/dist/compression/layers/whitespace.js +60 -0
- package/dist/compression/layers/whitespace.js.map +1 -0
- package/dist/compression/types.d.ts +84 -0
- package/dist/compression/types.d.ts.map +1 -0
- package/dist/compression/types.js +27 -0
- package/dist/compression/types.js.map +1 -0
- package/dist/config.d.ts +12 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +22 -0
- package/dist/config.js.map +1 -0
- package/dist/dedup.d.ts +34 -0
- package/dist/dedup.d.ts.map +1 -0
- package/dist/dedup.js +150 -0
- package/dist/dedup.js.map +1 -0
- package/dist/doctor.d.ts +8 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +375 -0
- package/dist/doctor.js.map +1 -0
- package/dist/error-classification.test.d.ts +2 -0
- package/dist/error-classification.test.d.ts.map +1 -0
- package/dist/error-classification.test.js +59 -0
- package/dist/error-classification.test.js.map +1 -0
- package/dist/errors.d.ts +54 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +85 -0
- package/dist/errors.js.map +1 -0
- package/dist/exclude-models.d.ts +28 -0
- package/dist/exclude-models.d.ts.map +1 -0
- package/dist/exclude-models.integration.test.d.ts +2 -0
- package/dist/exclude-models.integration.test.d.ts.map +1 -0
- package/dist/exclude-models.integration.test.js +46 -0
- package/dist/exclude-models.integration.test.js.map +1 -0
- package/dist/exclude-models.js +70 -0
- package/dist/exclude-models.js.map +1 -0
- package/dist/exclude-models.test.d.ts +5 -0
- package/dist/exclude-models.test.d.ts.map +1 -0
- package/dist/exclude-models.test.js +95 -0
- package/dist/exclude-models.test.js.map +1 -0
- package/dist/fs-read.d.ts +11 -0
- package/dist/fs-read.d.ts.map +1 -0
- package/dist/fs-read.js +47 -0
- package/dist/fs-read.js.map +1 -0
- package/dist/index.d.ts +34 -1368
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1071 -56194
- package/dist/index.js.map +1 -1
- package/dist/journal.d.ts +67 -0
- package/dist/journal.d.ts.map +1 -0
- package/dist/journal.js +184 -0
- package/dist/journal.js.map +1 -0
- package/dist/journal.test.d.ts +2 -0
- package/dist/journal.test.d.ts.map +1 -0
- package/dist/journal.test.js +201 -0
- package/dist/journal.test.js.map +1 -0
- package/dist/logger.d.ts +33 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +35 -0
- package/dist/logger.js.map +1 -0
- package/dist/models.d.ts +107 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +941 -0
- package/dist/models.js.map +1 -0
- package/dist/models.test.d.ts +2 -0
- package/dist/models.test.d.ts.map +1 -0
- package/dist/models.test.js +38 -0
- package/dist/models.test.js.map +1 -0
- package/dist/partners/index.d.ts +8 -0
- package/dist/partners/index.d.ts.map +1 -0
- package/dist/partners/index.js +6 -0
- package/dist/partners/index.js.map +1 -0
- package/dist/partners/registry.d.ts +51 -0
- package/dist/partners/registry.d.ts.map +1 -0
- package/dist/partners/registry.js +256 -0
- package/dist/partners/registry.js.map +1 -0
- package/dist/partners/tools.d.ts +24 -0
- package/dist/partners/tools.d.ts.map +1 -0
- package/dist/partners/tools.js +97 -0
- package/dist/partners/tools.js.map +1 -0
- package/dist/payment-preauth.d.ts +17 -0
- package/dist/payment-preauth.d.ts.map +1 -0
- package/dist/payment-preauth.js +102 -0
- package/dist/payment-preauth.js.map +1 -0
- package/dist/provider.d.ts +19 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +45 -0
- package/dist/provider.js.map +1 -0
- package/dist/proxy.d.ts +210 -0
- package/dist/proxy.d.ts.map +1 -0
- package/dist/proxy.debrand.test.d.ts +2 -0
- package/dist/proxy.debrand.test.d.ts.map +1 -0
- package/dist/proxy.debrand.test.js +101 -0
- package/dist/proxy.debrand.test.js.map +1 -0
- package/dist/proxy.degraded-response.test.d.ts +2 -0
- package/dist/proxy.degraded-response.test.d.ts.map +1 -0
- package/dist/proxy.degraded-response.test.js +105 -0
- package/dist/proxy.degraded-response.test.js.map +1 -0
- package/dist/proxy.image-download.test.d.ts +2 -0
- package/dist/proxy.image-download.test.d.ts.map +1 -0
- package/dist/proxy.image-download.test.js +92 -0
- package/dist/proxy.image-download.test.js.map +1 -0
- package/dist/proxy.js +3810 -0
- package/dist/proxy.js.map +1 -0
- package/dist/proxy.models-endpoint.test.d.ts +2 -0
- package/dist/proxy.models-endpoint.test.d.ts.map +1 -0
- package/dist/proxy.models-endpoint.test.js +19 -0
- package/dist/proxy.models-endpoint.test.js.map +1 -0
- package/dist/proxy.multiturn-thinking.test.d.ts +2 -0
- package/dist/proxy.multiturn-thinking.test.d.ts.map +1 -0
- package/dist/proxy.multiturn-thinking.test.js +82 -0
- package/dist/proxy.multiturn-thinking.test.js.map +1 -0
- package/dist/proxy.payment-chain-reuse.test.d.ts +2 -0
- package/dist/proxy.payment-chain-reuse.test.d.ts.map +1 -0
- package/dist/proxy.payment-chain-reuse.test.js +30 -0
- package/dist/proxy.payment-chain-reuse.test.js.map +1 -0
- package/dist/proxy.solana-resilience.test.d.ts +12 -0
- package/dist/proxy.solana-resilience.test.d.ts.map +1 -0
- package/dist/proxy.solana-resilience.test.js +39 -0
- package/dist/proxy.solana-resilience.test.js.map +1 -0
- package/dist/report.d.ts +6 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +44 -0
- package/dist/report.js.map +1 -0
- package/dist/response-cache.advanced.test.d.ts +2 -0
- package/dist/response-cache.advanced.test.d.ts.map +1 -0
- package/dist/response-cache.advanced.test.js +566 -0
- package/dist/response-cache.advanced.test.js.map +1 -0
- package/dist/response-cache.d.ts +85 -0
- package/dist/response-cache.d.ts.map +1 -0
- package/dist/response-cache.edge-cases.test.d.ts +2 -0
- package/dist/response-cache.edge-cases.test.d.ts.map +1 -0
- package/dist/response-cache.edge-cases.test.js +488 -0
- package/dist/response-cache.edge-cases.test.js.map +1 -0
- package/dist/response-cache.extreme.test.d.ts +2 -0
- package/dist/response-cache.extreme.test.d.ts.map +1 -0
- package/dist/response-cache.extreme.test.js +561 -0
- package/dist/response-cache.extreme.test.js.map +1 -0
- package/dist/response-cache.js +240 -0
- package/dist/response-cache.js.map +1 -0
- package/dist/response-cache.test.d.ts +2 -0
- package/dist/response-cache.test.d.ts.map +1 -0
- package/dist/response-cache.test.js +242 -0
- package/dist/response-cache.test.js.map +1 -0
- package/dist/retry.d.ts +42 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +99 -0
- package/dist/retry.js.map +1 -0
- package/dist/router/config.d.ts +11 -0
- package/dist/router/config.d.ts.map +1 -0
- package/dist/router/config.js +1215 -0
- package/dist/router/config.js.map +1 -0
- package/dist/router/index.d.ts +18 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/index.js +19 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/llm-classifier.d.ts +29 -0
- package/dist/router/llm-classifier.d.ts.map +1 -0
- package/dist/router/llm-classifier.js +99 -0
- package/dist/router/llm-classifier.js.map +1 -0
- package/dist/router/rules.d.ts +12 -0
- package/dist/router/rules.d.ts.map +1 -0
- package/dist/router/rules.js +202 -0
- package/dist/router/rules.js.map +1 -0
- package/dist/router/selector.d.ts +58 -0
- package/dist/router/selector.d.ts.map +1 -0
- package/dist/router/selector.js +165 -0
- package/dist/router/selector.js.map +1 -0
- package/dist/router/selector.test.d.ts +2 -0
- package/dist/router/selector.test.d.ts.map +1 -0
- package/dist/router/selector.test.js +67 -0
- package/dist/router/selector.test.js.map +1 -0
- package/dist/router/strategy.d.ts +19 -0
- package/dist/router/strategy.d.ts.map +1 -0
- package/dist/router/strategy.js +138 -0
- package/dist/router/strategy.js.map +1 -0
- package/dist/router/strategy.test.d.ts +2 -0
- package/dist/router/strategy.test.d.ts.map +1 -0
- package/dist/router/strategy.test.js +131 -0
- package/dist/router/strategy.test.js.map +1 -0
- package/dist/router/types.d.ts +127 -0
- package/dist/router/types.d.ts.map +1 -0
- package/dist/router/types.js +11 -0
- package/dist/router/types.js.map +1 -0
- package/dist/session.d.ts +124 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +256 -0
- package/dist/session.js.map +1 -0
- package/dist/session.test.d.ts +2 -0
- package/dist/session.test.d.ts.map +1 -0
- package/dist/session.test.js +163 -0
- package/dist/session.test.js.map +1 -0
- package/dist/solana-balance.d.ts +48 -0
- package/dist/solana-balance.d.ts.map +1 -0
- package/dist/solana-balance.js +142 -0
- package/dist/solana-balance.js.map +1 -0
- package/dist/spend-control.d.ts +112 -0
- package/dist/spend-control.d.ts.map +1 -0
- package/dist/spend-control.js +278 -0
- package/dist/spend-control.js.map +1 -0
- package/dist/spend-control.test.d.ts +5 -0
- package/dist/spend-control.test.d.ts.map +1 -0
- package/dist/spend-control.test.js +210 -0
- package/dist/spend-control.test.js.map +1 -0
- package/dist/stats.d.ts +64 -0
- package/dist/stats.d.ts.map +1 -0
- package/dist/stats.js +295 -0
- package/dist/stats.js.map +1 -0
- package/dist/types.d.ts +150 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/update-hint.test.d.ts +9 -0
- package/dist/update-hint.test.d.ts.map +1 -0
- package/dist/update-hint.test.js +156 -0
- package/dist/update-hint.test.js.map +1 -0
- package/dist/updater.d.ts +10 -0
- package/dist/updater.d.ts.map +1 -0
- package/dist/updater.js +55 -0
- package/dist/updater.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +16 -0
- package/dist/version.js.map +1 -0
- package/dist/wallet.d.ts +52 -0
- package/dist/wallet.d.ts.map +1 -0
- package/dist/wallet.js +93 -0
- package/dist/wallet.js.map +1 -0
- package/dist/wallet.test.d.ts +6 -0
- package/dist/wallet.test.d.ts.map +1 -0
- package/dist/wallet.test.js +117 -0
- package/dist/wallet.test.js.map +1 -0
- package/dist/x402-sdk.test.d.ts +6 -0
- package/dist/x402-sdk.test.d.ts.map +1 -0
- package/dist/x402-sdk.test.js +161 -0
- package/dist/x402-sdk.test.js.map +1 -0
- package/package.json +1 -1
- package/scripts/e2e-multiturn.mjs +4 -1
package/dist/doctor.js
ADDED
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BlockRun Doctor - AI-Powered Diagnostics
|
|
3
|
+
*
|
|
4
|
+
* Collects system diagnostics and sends to Claude Opus 4.6 for analysis.
|
|
5
|
+
* Works independently of OpenClaw - direct x402 payment to BlockRun API.
|
|
6
|
+
*/
|
|
7
|
+
import { platform, arch, freemem, totalmem } from "node:os";
|
|
8
|
+
import { createPublicClient, http } from "viem";
|
|
9
|
+
import { base } from "viem/chains";
|
|
10
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
11
|
+
import { wrapFetchWithPayment, x402Client } from "@x402/fetch";
|
|
12
|
+
import { registerExactEvmScheme } from "@x402/evm/exact/client";
|
|
13
|
+
import { toClientEvmSigner } from "@x402/evm";
|
|
14
|
+
import { resolveOrGenerateWalletKey, resolvePaymentChain, WALLET_FILE } from "./auth.js";
|
|
15
|
+
import { BalanceMonitor } from "./balance.js";
|
|
16
|
+
import { getSolanaAddress } from "./wallet.js";
|
|
17
|
+
import { getStats } from "./stats.js";
|
|
18
|
+
import { getProxyPort } from "./proxy.js";
|
|
19
|
+
import { VERSION } from "./version.js";
|
|
20
|
+
// Helpers
|
|
21
|
+
function formatBytes(bytes) {
|
|
22
|
+
const gb = bytes / (1024 * 1024 * 1024);
|
|
23
|
+
return `${gb.toFixed(1)}GB`;
|
|
24
|
+
}
|
|
25
|
+
function green(text) {
|
|
26
|
+
return `\x1b[32m✓\x1b[0m ${text}`;
|
|
27
|
+
}
|
|
28
|
+
function red(text) {
|
|
29
|
+
return `\x1b[31m✗\x1b[0m ${text}`;
|
|
30
|
+
}
|
|
31
|
+
function yellow(text) {
|
|
32
|
+
return `\x1b[33m⚠\x1b[0m ${text}`;
|
|
33
|
+
}
|
|
34
|
+
// Collect system info
|
|
35
|
+
function collectSystemInfo() {
|
|
36
|
+
return {
|
|
37
|
+
os: `${platform()} ${arch()}`,
|
|
38
|
+
arch: arch(),
|
|
39
|
+
nodeVersion: process.version,
|
|
40
|
+
memoryFree: formatBytes(freemem()),
|
|
41
|
+
memoryTotal: formatBytes(totalmem()),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
// Collect wallet info
|
|
45
|
+
async function collectWalletInfo() {
|
|
46
|
+
try {
|
|
47
|
+
const { key, address, source, solanaPrivateKeyBytes } = await resolveOrGenerateWalletKey();
|
|
48
|
+
if (!key || !address) {
|
|
49
|
+
return {
|
|
50
|
+
exists: false,
|
|
51
|
+
valid: false,
|
|
52
|
+
address: null,
|
|
53
|
+
solanaAddress: null,
|
|
54
|
+
balance: null,
|
|
55
|
+
isLow: false,
|
|
56
|
+
isEmpty: true,
|
|
57
|
+
source: null,
|
|
58
|
+
paymentChain: "base",
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// Derive Solana address if mnemonic-based wallet
|
|
62
|
+
let solanaAddress = null;
|
|
63
|
+
if (solanaPrivateKeyBytes) {
|
|
64
|
+
try {
|
|
65
|
+
solanaAddress = await getSolanaAddress(solanaPrivateKeyBytes);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// Non-fatal
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Check balance on the active payment chain
|
|
72
|
+
const paymentChain = await resolvePaymentChain();
|
|
73
|
+
try {
|
|
74
|
+
let balanceInfo;
|
|
75
|
+
if (paymentChain === "solana" && solanaAddress) {
|
|
76
|
+
const { SolanaBalanceMonitor } = await import("./solana-balance.js");
|
|
77
|
+
const monitor = new SolanaBalanceMonitor(solanaAddress);
|
|
78
|
+
balanceInfo = await monitor.checkBalance();
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
const monitor = new BalanceMonitor(address);
|
|
82
|
+
balanceInfo = await monitor.checkBalance();
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
exists: true,
|
|
86
|
+
valid: true,
|
|
87
|
+
address,
|
|
88
|
+
solanaAddress,
|
|
89
|
+
balance: balanceInfo.balanceUSD,
|
|
90
|
+
isLow: balanceInfo.isLow,
|
|
91
|
+
isEmpty: balanceInfo.isEmpty,
|
|
92
|
+
source,
|
|
93
|
+
paymentChain,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return {
|
|
98
|
+
exists: true,
|
|
99
|
+
valid: true,
|
|
100
|
+
address,
|
|
101
|
+
solanaAddress,
|
|
102
|
+
balance: null,
|
|
103
|
+
isLow: false,
|
|
104
|
+
isEmpty: false,
|
|
105
|
+
source,
|
|
106
|
+
paymentChain,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return {
|
|
112
|
+
exists: false,
|
|
113
|
+
valid: false,
|
|
114
|
+
address: null,
|
|
115
|
+
solanaAddress: null,
|
|
116
|
+
balance: null,
|
|
117
|
+
isLow: false,
|
|
118
|
+
isEmpty: true,
|
|
119
|
+
source: null,
|
|
120
|
+
paymentChain: "base",
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Collect network info
|
|
125
|
+
async function collectNetworkInfo() {
|
|
126
|
+
const port = getProxyPort();
|
|
127
|
+
// Check BlockRun API
|
|
128
|
+
let blockrunReachable = false;
|
|
129
|
+
let blockrunLatency = null;
|
|
130
|
+
try {
|
|
131
|
+
const start = Date.now();
|
|
132
|
+
const response = await fetch("https://blockrun.ai/api/v1/models", {
|
|
133
|
+
method: "GET",
|
|
134
|
+
signal: AbortSignal.timeout(10000),
|
|
135
|
+
});
|
|
136
|
+
blockrunLatency = Date.now() - start;
|
|
137
|
+
blockrunReachable = response.ok || response.status === 402;
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
// blockrunReachable already false
|
|
141
|
+
}
|
|
142
|
+
// Check local proxy
|
|
143
|
+
let proxyRunning = false;
|
|
144
|
+
try {
|
|
145
|
+
const response = await fetch(`http://127.0.0.1:${port}/health`, {
|
|
146
|
+
method: "GET",
|
|
147
|
+
signal: AbortSignal.timeout(3000),
|
|
148
|
+
});
|
|
149
|
+
proxyRunning = response.ok;
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
// proxyRunning already false
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
blockrunApi: { reachable: blockrunReachable, latencyMs: blockrunLatency },
|
|
156
|
+
localProxy: { running: proxyRunning, port },
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
// Collect log info
|
|
160
|
+
async function collectLogInfo() {
|
|
161
|
+
try {
|
|
162
|
+
const stats = await getStats(1); // Last 1 day
|
|
163
|
+
return {
|
|
164
|
+
requestsLast24h: stats.totalRequests,
|
|
165
|
+
costLast24h: `$${stats.totalCost.toFixed(4)}`,
|
|
166
|
+
errorsFound: 0, // TODO: parse error logs
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
return {
|
|
171
|
+
requestsLast24h: 0,
|
|
172
|
+
costLast24h: "$0.00",
|
|
173
|
+
errorsFound: 0,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Identify issues
|
|
178
|
+
function identifyIssues(result) {
|
|
179
|
+
const issues = [];
|
|
180
|
+
if (!result.wallet.exists) {
|
|
181
|
+
issues.push("No wallet found");
|
|
182
|
+
}
|
|
183
|
+
if (result.wallet.isEmpty) {
|
|
184
|
+
const chain = result.wallet.paymentChain === "solana" ? "Solana" : "Base";
|
|
185
|
+
issues.push(`Wallet is empty - need to fund with USDC on ${chain}`);
|
|
186
|
+
if (result.wallet.paymentChain === "base" && result.wallet.solanaAddress) {
|
|
187
|
+
issues.push("Tip: if you funded Solana, run /wallet solana to switch chains");
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
else if (result.wallet.isLow) {
|
|
191
|
+
issues.push("Wallet balance is low (< $1.00)");
|
|
192
|
+
}
|
|
193
|
+
if (!result.network.blockrunApi.reachable) {
|
|
194
|
+
issues.push("Cannot reach BlockRun API - check internet connection");
|
|
195
|
+
}
|
|
196
|
+
if (!result.network.localProxy.running) {
|
|
197
|
+
issues.push(`Local proxy not running on port ${result.network.localProxy.port}`);
|
|
198
|
+
}
|
|
199
|
+
return issues;
|
|
200
|
+
}
|
|
201
|
+
// Print diagnostics to terminal
|
|
202
|
+
function printDiagnostics(result) {
|
|
203
|
+
console.log("\n🔍 Collecting diagnostics...\n");
|
|
204
|
+
// System
|
|
205
|
+
console.log("System");
|
|
206
|
+
console.log(` ${green(`OS: ${result.system.os}`)}`);
|
|
207
|
+
console.log(` ${green(`Node: ${result.system.nodeVersion}`)}`);
|
|
208
|
+
console.log(` ${green(`Memory: ${result.system.memoryFree} free / ${result.system.memoryTotal}`)}`);
|
|
209
|
+
// Wallet
|
|
210
|
+
console.log("\nWallet");
|
|
211
|
+
if (result.wallet.exists && result.wallet.valid) {
|
|
212
|
+
console.log(` ${green(`Key: ${WALLET_FILE} (${result.wallet.source})`)}`);
|
|
213
|
+
console.log(` ${green(`EVM Address: ${result.wallet.address}`)}`);
|
|
214
|
+
if (result.wallet.solanaAddress) {
|
|
215
|
+
console.log(` ${green(`Solana Address: ${result.wallet.solanaAddress}`)}`);
|
|
216
|
+
}
|
|
217
|
+
const chainLabel = result.wallet.paymentChain === "solana" ? "Solana" : "Base";
|
|
218
|
+
console.log(` ${green(`Chain: ${chainLabel}`)}`);
|
|
219
|
+
if (result.wallet.isEmpty) {
|
|
220
|
+
console.log(` ${red(`Balance: $0.00 - NEED TO FUND WITH USDC ON ${chainLabel.toUpperCase()}!`)}`);
|
|
221
|
+
if (result.wallet.paymentChain === "base" && result.wallet.solanaAddress) {
|
|
222
|
+
console.log(` ${yellow(`Tip: funded Solana instead? Run /wallet solana to switch`)}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
else if (result.wallet.isLow) {
|
|
226
|
+
console.log(` ${yellow(`Balance: ${result.wallet.balance} (low)`)}`);
|
|
227
|
+
}
|
|
228
|
+
else if (result.wallet.balance) {
|
|
229
|
+
console.log(` ${green(`Balance: ${result.wallet.balance}`)}`);
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
console.log(` ${yellow(`Balance: checking...`)}`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
console.log(` ${red("No wallet found")}`);
|
|
237
|
+
}
|
|
238
|
+
// Network
|
|
239
|
+
console.log("\nNetwork");
|
|
240
|
+
if (result.network.blockrunApi.reachable) {
|
|
241
|
+
console.log(` ${green(`BlockRun API: reachable (${result.network.blockrunApi.latencyMs}ms)`)}`);
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
console.log(` ${red("BlockRun API: unreachable")}`);
|
|
245
|
+
}
|
|
246
|
+
if (result.network.localProxy.running) {
|
|
247
|
+
console.log(` ${green(`Local proxy: running on :${result.network.localProxy.port}`)}`);
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
console.log(` ${red(`Local proxy: not running on :${result.network.localProxy.port}`)}`);
|
|
251
|
+
}
|
|
252
|
+
// Logs
|
|
253
|
+
console.log("\nLogs");
|
|
254
|
+
console.log(` ${green(`Last 24h: ${result.logs.requestsLast24h} requests, ${result.logs.costLast24h} spent`)}`);
|
|
255
|
+
if (result.logs.errorsFound > 0) {
|
|
256
|
+
console.log(` ${yellow(`${result.logs.errorsFound} errors found in logs`)}`);
|
|
257
|
+
}
|
|
258
|
+
// Issues summary
|
|
259
|
+
if (result.issues.length > 0) {
|
|
260
|
+
console.log("\n⚠️ Issues Found:");
|
|
261
|
+
for (const issue of result.issues) {
|
|
262
|
+
console.log(` • ${issue}`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
const DOCTOR_MODELS = {
|
|
267
|
+
sonnet: {
|
|
268
|
+
id: "anthropic/claude-sonnet-4.6",
|
|
269
|
+
name: "Claude Sonnet 4.6",
|
|
270
|
+
cost: "~$0.003",
|
|
271
|
+
},
|
|
272
|
+
opus: {
|
|
273
|
+
id: "anthropic/claude-opus-4.6",
|
|
274
|
+
name: "Claude Opus 4.6",
|
|
275
|
+
cost: "~$0.01",
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
// Send to AI for analysis
|
|
279
|
+
async function analyzeWithAI(diagnostics, userQuestion, model = "sonnet") {
|
|
280
|
+
// Check if wallet has funds
|
|
281
|
+
if (diagnostics.wallet.isEmpty) {
|
|
282
|
+
console.log("\n💳 Wallet is empty - cannot call AI for analysis.");
|
|
283
|
+
console.log(` Fund your EVM wallet with USDC on Base: ${diagnostics.wallet.address}`);
|
|
284
|
+
if (diagnostics.wallet.solanaAddress) {
|
|
285
|
+
console.log(` Fund your Solana wallet with USDC: ${diagnostics.wallet.solanaAddress}`);
|
|
286
|
+
}
|
|
287
|
+
console.log(" Get USDC: https://www.coinbase.com/price/usd-coin");
|
|
288
|
+
console.log(" Bridge to Base: https://bridge.base.org\n");
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
const modelConfig = DOCTOR_MODELS[model];
|
|
292
|
+
console.log(`\n📤 Sending to ${modelConfig.name} (${modelConfig.cost})...\n`);
|
|
293
|
+
try {
|
|
294
|
+
const { key } = await resolveOrGenerateWalletKey();
|
|
295
|
+
const account = privateKeyToAccount(key);
|
|
296
|
+
const publicClient = createPublicClient({ chain: base, transport: http() });
|
|
297
|
+
const evmSigner = toClientEvmSigner(account, publicClient);
|
|
298
|
+
const x402 = new x402Client();
|
|
299
|
+
registerExactEvmScheme(x402, { signer: evmSigner });
|
|
300
|
+
const paymentFetch = wrapFetchWithPayment(fetch, x402);
|
|
301
|
+
const response = await paymentFetch("https://blockrun.ai/api/v1/chat/completions", {
|
|
302
|
+
method: "POST",
|
|
303
|
+
headers: { "Content-Type": "application/json" },
|
|
304
|
+
body: JSON.stringify({
|
|
305
|
+
model: modelConfig.id,
|
|
306
|
+
stream: false,
|
|
307
|
+
messages: [
|
|
308
|
+
{
|
|
309
|
+
role: "system",
|
|
310
|
+
content: `You are a technical support expert for BlockRun and ClawRouter.
|
|
311
|
+
Analyze the diagnostics and:
|
|
312
|
+
1. Identify the root cause of any issues
|
|
313
|
+
2. Provide specific, actionable fix commands (bash)
|
|
314
|
+
3. Explain why the issue occurred briefly
|
|
315
|
+
4. Be concise but thorough
|
|
316
|
+
5. Format commands in code blocks`,
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
role: "user",
|
|
320
|
+
content: userQuestion
|
|
321
|
+
? `Here are my system diagnostics:\n\n${JSON.stringify(diagnostics, null, 2)}\n\nUser's question: ${userQuestion}`
|
|
322
|
+
: `Here are my system diagnostics:\n\n${JSON.stringify(diagnostics, null, 2)}\n\nPlease analyze and help me fix any issues.`,
|
|
323
|
+
},
|
|
324
|
+
],
|
|
325
|
+
max_tokens: 1000,
|
|
326
|
+
}),
|
|
327
|
+
});
|
|
328
|
+
if (!response.ok) {
|
|
329
|
+
const text = await response.text();
|
|
330
|
+
console.log(`Error: ${response.status} - ${text}`);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
const data = await response.json();
|
|
334
|
+
const content = data.choices?.[0]?.message?.content;
|
|
335
|
+
if (content) {
|
|
336
|
+
console.log("🤖 AI Analysis:\n");
|
|
337
|
+
console.log(content);
|
|
338
|
+
console.log();
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
console.log("Error: No response from AI");
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
catch (err) {
|
|
345
|
+
console.log(`\nError calling AI: ${err instanceof Error ? err.message : String(err)}`);
|
|
346
|
+
console.log("Try again or check your wallet balance.\n");
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
// Main entry point
|
|
350
|
+
export async function runDoctor(userQuestion, model = "sonnet") {
|
|
351
|
+
console.log(`\n🩺 BlockRun Doctor v${VERSION}\n`);
|
|
352
|
+
// Collect all diagnostics
|
|
353
|
+
const [system, wallet, network, logs] = await Promise.all([
|
|
354
|
+
collectSystemInfo(),
|
|
355
|
+
collectWalletInfo(),
|
|
356
|
+
collectNetworkInfo(),
|
|
357
|
+
collectLogInfo(),
|
|
358
|
+
]);
|
|
359
|
+
const result = {
|
|
360
|
+
version: VERSION,
|
|
361
|
+
timestamp: new Date().toISOString(),
|
|
362
|
+
system,
|
|
363
|
+
wallet,
|
|
364
|
+
network,
|
|
365
|
+
logs,
|
|
366
|
+
issues: [],
|
|
367
|
+
};
|
|
368
|
+
// Identify issues
|
|
369
|
+
result.issues = identifyIssues(result);
|
|
370
|
+
// Print to terminal
|
|
371
|
+
printDiagnostics(result);
|
|
372
|
+
// Send to AI for analysis
|
|
373
|
+
await analyzeWithAI(result, userQuestion, model);
|
|
374
|
+
}
|
|
375
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-classification.test.d.ts","sourceRoot":"","sources":["../src/error-classification.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import { categorizeError } from "./proxy.js";
|
|
3
|
+
describe("categorizeError", () => {
|
|
4
|
+
it("classifies 401 as auth_failure", () => {
|
|
5
|
+
expect(categorizeError(401, "Unauthorized")).toBe("auth_failure");
|
|
6
|
+
expect(categorizeError(401, "api key invalid")).toBe("auth_failure");
|
|
7
|
+
expect(categorizeError(401, "")).toBe("auth_failure");
|
|
8
|
+
});
|
|
9
|
+
it("classifies 403 with quota body as quota_exceeded", () => {
|
|
10
|
+
expect(categorizeError(403, "plan limit reached")).toBe("quota_exceeded");
|
|
11
|
+
expect(categorizeError(403, "quota exceeded for this month")).toBe("quota_exceeded");
|
|
12
|
+
expect(categorizeError(403, "subscription required")).toBe("quota_exceeded");
|
|
13
|
+
});
|
|
14
|
+
it("classifies 403 without quota body as auth_failure", () => {
|
|
15
|
+
expect(categorizeError(403, "Forbidden")).toBe("auth_failure");
|
|
16
|
+
expect(categorizeError(403, "")).toBe("auth_failure");
|
|
17
|
+
});
|
|
18
|
+
it("classifies 402 as payment_error", () => {
|
|
19
|
+
expect(categorizeError(402, "payment required")).toBe("payment_error");
|
|
20
|
+
expect(categorizeError(402, "")).toBe("payment_error");
|
|
21
|
+
});
|
|
22
|
+
it("classifies 429 as rate_limited", () => {
|
|
23
|
+
expect(categorizeError(429, "rate limit exceeded")).toBe("rate_limited");
|
|
24
|
+
expect(categorizeError(429, "")).toBe("rate_limited");
|
|
25
|
+
});
|
|
26
|
+
it("classifies 529 as overloaded", () => {
|
|
27
|
+
expect(categorizeError(529, "")).toBe("overloaded");
|
|
28
|
+
expect(categorizeError(529, "overloaded")).toBe("overloaded");
|
|
29
|
+
});
|
|
30
|
+
it("classifies 503 with overload body as overloaded", () => {
|
|
31
|
+
expect(categorizeError(503, "service overloaded, try again")).toBe("overloaded");
|
|
32
|
+
expect(categorizeError(503, "over capacity")).toBe("overloaded");
|
|
33
|
+
expect(categorizeError(503, "too many requests")).toBe("overloaded");
|
|
34
|
+
});
|
|
35
|
+
it("classifies 503 without overload body as server_error", () => {
|
|
36
|
+
expect(categorizeError(503, "service unavailable")).toBe("server_error");
|
|
37
|
+
expect(categorizeError(503, "")).toBe("server_error");
|
|
38
|
+
});
|
|
39
|
+
it("classifies 5xx as server_error", () => {
|
|
40
|
+
expect(categorizeError(500, "internal server error")).toBe("server_error");
|
|
41
|
+
expect(categorizeError(502, "bad gateway")).toBe("server_error");
|
|
42
|
+
expect(categorizeError(504, "gateway timeout")).toBe("server_error");
|
|
43
|
+
});
|
|
44
|
+
it("classifies 413 with size body as config_error", () => {
|
|
45
|
+
expect(categorizeError(413, "request too large")).toBe("config_error");
|
|
46
|
+
expect(categorizeError(413, "payload too large")).toBe("config_error");
|
|
47
|
+
});
|
|
48
|
+
it("classifies 200 as null (not a provider error)", () => {
|
|
49
|
+
expect(categorizeError(200, "ok")).toBeNull();
|
|
50
|
+
});
|
|
51
|
+
it("classifies bare 400 with no pattern match as null", () => {
|
|
52
|
+
expect(categorizeError(400, "bad request")).toBeNull();
|
|
53
|
+
});
|
|
54
|
+
it("classifies 400 with billing body as config_error", () => {
|
|
55
|
+
expect(categorizeError(400, "billing issue with account")).toBe("config_error");
|
|
56
|
+
expect(categorizeError(400, "insufficient balance")).toBe("config_error");
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
//# sourceMappingURL=error-classification.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-classification.test.js","sourceRoot":"","sources":["../src/error-classification.test.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed Error Classes for ClawRouter
|
|
3
|
+
*
|
|
4
|
+
* Provides structured errors for balance-related failures with
|
|
5
|
+
* all necessary information for user-friendly error messages.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Thrown when wallet has insufficient USDC balance for a request.
|
|
9
|
+
*/
|
|
10
|
+
export declare class InsufficientFundsError extends Error {
|
|
11
|
+
readonly code: "INSUFFICIENT_FUNDS";
|
|
12
|
+
readonly currentBalanceUSD: string;
|
|
13
|
+
readonly requiredUSD: string;
|
|
14
|
+
readonly walletAddress: string;
|
|
15
|
+
constructor(opts: {
|
|
16
|
+
currentBalanceUSD: string;
|
|
17
|
+
requiredUSD: string;
|
|
18
|
+
walletAddress: string;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Thrown when wallet has no USDC balance (or effectively zero).
|
|
23
|
+
*/
|
|
24
|
+
export declare class EmptyWalletError extends Error {
|
|
25
|
+
readonly code: "EMPTY_WALLET";
|
|
26
|
+
readonly walletAddress: string;
|
|
27
|
+
constructor(walletAddress: string);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Type guard to check if an error is InsufficientFundsError.
|
|
31
|
+
*/
|
|
32
|
+
export declare function isInsufficientFundsError(error: unknown): error is InsufficientFundsError;
|
|
33
|
+
/**
|
|
34
|
+
* Type guard to check if an error is EmptyWalletError.
|
|
35
|
+
*/
|
|
36
|
+
export declare function isEmptyWalletError(error: unknown): error is EmptyWalletError;
|
|
37
|
+
/**
|
|
38
|
+
* Type guard to check if an error is a balance-related error.
|
|
39
|
+
*/
|
|
40
|
+
export declare function isBalanceError(error: unknown): error is InsufficientFundsError | EmptyWalletError;
|
|
41
|
+
/**
|
|
42
|
+
* Thrown when RPC call fails (network error, node down, etc).
|
|
43
|
+
* Distinguishes infrastructure failures from actual empty wallets.
|
|
44
|
+
*/
|
|
45
|
+
export declare class RpcError extends Error {
|
|
46
|
+
readonly code: "RPC_ERROR";
|
|
47
|
+
readonly originalError: unknown;
|
|
48
|
+
constructor(message: string, originalError?: unknown);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Type guard to check if an error is RpcError.
|
|
52
|
+
*/
|
|
53
|
+
export declare function isRpcError(error: unknown): error is RpcError;
|
|
54
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,IAAI,EAAG,oBAAoB,CAAU;IAC9C,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;gBAEnB,IAAI,EAAE;QAAE,iBAAiB,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE;CAa5F;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAG,cAAc,CAAU;IACxC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;gBAEnB,aAAa,EAAE,MAAM;CAYlC;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,sBAAsB,CAExF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,gBAAgB,CAE5E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,sBAAsB,GAAG,gBAAgB,CAEjG;AAED;;;GAGG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,IAAI,EAAG,WAAW,CAAU;IACrC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;gBAEpB,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,OAAO;CAKrD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed Error Classes for ClawRouter
|
|
3
|
+
*
|
|
4
|
+
* Provides structured errors for balance-related failures with
|
|
5
|
+
* all necessary information for user-friendly error messages.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Thrown when wallet has insufficient USDC balance for a request.
|
|
9
|
+
*/
|
|
10
|
+
export class InsufficientFundsError extends Error {
|
|
11
|
+
code = "INSUFFICIENT_FUNDS";
|
|
12
|
+
currentBalanceUSD;
|
|
13
|
+
requiredUSD;
|
|
14
|
+
walletAddress;
|
|
15
|
+
constructor(opts) {
|
|
16
|
+
const msg = [
|
|
17
|
+
`Insufficient balance. Current: ${opts.currentBalanceUSD}, Required: ${opts.requiredUSD}`,
|
|
18
|
+
`Options:`,
|
|
19
|
+
` 1. Fund wallet: ${opts.walletAddress}`,
|
|
20
|
+
` 2. Use free model: /model free`,
|
|
21
|
+
].join("\n");
|
|
22
|
+
super(msg);
|
|
23
|
+
this.name = "InsufficientFundsError";
|
|
24
|
+
this.currentBalanceUSD = opts.currentBalanceUSD;
|
|
25
|
+
this.requiredUSD = opts.requiredUSD;
|
|
26
|
+
this.walletAddress = opts.walletAddress;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Thrown when wallet has no USDC balance (or effectively zero).
|
|
31
|
+
*/
|
|
32
|
+
export class EmptyWalletError extends Error {
|
|
33
|
+
code = "EMPTY_WALLET";
|
|
34
|
+
walletAddress;
|
|
35
|
+
constructor(walletAddress) {
|
|
36
|
+
const msg = [
|
|
37
|
+
`No USDC balance.`,
|
|
38
|
+
`Options:`,
|
|
39
|
+
` 1. Fund wallet: ${walletAddress}`,
|
|
40
|
+
` 2. Use free model: /model free`,
|
|
41
|
+
` 3. Uninstall: bash ~/.openclaw/extensions/clawrouter/scripts/uninstall.sh`,
|
|
42
|
+
].join("\n");
|
|
43
|
+
super(msg);
|
|
44
|
+
this.name = "EmptyWalletError";
|
|
45
|
+
this.walletAddress = walletAddress;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Type guard to check if an error is InsufficientFundsError.
|
|
50
|
+
*/
|
|
51
|
+
export function isInsufficientFundsError(error) {
|
|
52
|
+
return error instanceof Error && error.code === "INSUFFICIENT_FUNDS";
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Type guard to check if an error is EmptyWalletError.
|
|
56
|
+
*/
|
|
57
|
+
export function isEmptyWalletError(error) {
|
|
58
|
+
return error instanceof Error && error.code === "EMPTY_WALLET";
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Type guard to check if an error is a balance-related error.
|
|
62
|
+
*/
|
|
63
|
+
export function isBalanceError(error) {
|
|
64
|
+
return isInsufficientFundsError(error) || isEmptyWalletError(error);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Thrown when RPC call fails (network error, node down, etc).
|
|
68
|
+
* Distinguishes infrastructure failures from actual empty wallets.
|
|
69
|
+
*/
|
|
70
|
+
export class RpcError extends Error {
|
|
71
|
+
code = "RPC_ERROR";
|
|
72
|
+
originalError;
|
|
73
|
+
constructor(message, originalError) {
|
|
74
|
+
super(`RPC error: ${message}. Check network connectivity.`);
|
|
75
|
+
this.name = "RpcError";
|
|
76
|
+
this.originalError = originalError;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Type guard to check if an error is RpcError.
|
|
81
|
+
*/
|
|
82
|
+
export function isRpcError(error) {
|
|
83
|
+
return error instanceof Error && error.code === "RPC_ERROR";
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IACtC,IAAI,GAAG,oBAA6B,CAAC;IACrC,iBAAiB,CAAS;IAC1B,WAAW,CAAS;IACpB,aAAa,CAAS;IAE/B,YAAY,IAA+E;QACzF,MAAM,GAAG,GAAG;YACV,kCAAkC,IAAI,CAAC,iBAAiB,eAAe,IAAI,CAAC,WAAW,EAAE;YACzF,UAAU;YACV,qBAAqB,IAAI,CAAC,aAAa,EAAE;YACzC,kCAAkC;SACnC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,KAAK,CAAC,GAAG,CAAC,CAAC;QACX,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,CAAC;QAChD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACpC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;IAC1C,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAChC,IAAI,GAAG,cAAuB,CAAC;IAC/B,aAAa,CAAS;IAE/B,YAAY,aAAqB;QAC/B,MAAM,GAAG,GAAG;YACV,kBAAkB;YAClB,UAAU;YACV,qBAAqB,aAAa,EAAE;YACpC,kCAAkC;YAClC,6EAA6E;SAC9E,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,KAAK,CAAC,GAAG,CAAC,CAAC;QACX,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACrC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,KAAc;IACrD,OAAO,KAAK,YAAY,KAAK,IAAK,KAAgC,CAAC,IAAI,KAAK,oBAAoB,CAAC;AACnG,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,OAAO,KAAK,YAAY,KAAK,IAAK,KAA0B,CAAC,IAAI,KAAK,cAAc,CAAC;AACvF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,OAAO,wBAAwB,CAAC,KAAK,CAAC,IAAI,kBAAkB,CAAC,KAAK,CAAC,CAAC;AACtE,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACxB,IAAI,GAAG,WAAoB,CAAC;IAC5B,aAAa,CAAU;IAEhC,YAAY,OAAe,EAAE,aAAuB;QAClD,KAAK,CAAC,cAAc,OAAO,+BAA+B,CAAC,CAAC;QAC5D,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACrC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,KAAK,YAAY,KAAK,IAAK,KAAkB,CAAC,IAAI,KAAK,WAAW,CAAC;AAC5E,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exclude-models persistence module.
|
|
3
|
+
*
|
|
4
|
+
* Manages a user-configurable list of model IDs that the smart router
|
|
5
|
+
* should never select. Stored as a sorted JSON array on disk.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Load the exclude list from disk.
|
|
9
|
+
* Returns an empty set if the file does not exist.
|
|
10
|
+
*/
|
|
11
|
+
export declare function loadExcludeList(filePath?: string): Set<string>;
|
|
12
|
+
/**
|
|
13
|
+
* Add a model to the exclude list.
|
|
14
|
+
* Resolves aliases before persisting.
|
|
15
|
+
* @returns The resolved model ID.
|
|
16
|
+
*/
|
|
17
|
+
export declare function addExclusion(model: string, filePath?: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Remove a model from the exclude list.
|
|
20
|
+
* Resolves aliases before removing.
|
|
21
|
+
* @returns true if the model was present and removed, false otherwise.
|
|
22
|
+
*/
|
|
23
|
+
export declare function removeExclusion(model: string, filePath?: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Clear the entire exclude list.
|
|
26
|
+
*/
|
|
27
|
+
export declare function clearExclusions(filePath?: string): void;
|
|
28
|
+
//# sourceMappingURL=exclude-models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exclude-models.d.ts","sourceRoot":"","sources":["../src/exclude-models.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,GAAE,MAA0B,GAAG,GAAG,CAAC,MAAM,CAAC,CAWjF;AAYD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,GAAE,MAA0B,GAAG,MAAM,CAMxF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,GAAE,MAA0B,GAAG,OAAO,CAQ5F;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,GAAE,MAA0B,GAAG,IAAI,CAE1E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exclude-models.integration.test.d.ts","sourceRoot":"","sources":["../src/exclude-models.integration.test.ts"],"names":[],"mappings":""}
|