wolverine-ai 5.3.5 → 5.4.1
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/bin/wolverine.js
CHANGED
|
@@ -246,9 +246,12 @@ if (args.includes("--backups")) {
|
|
|
246
246
|
const scriptPath = args.find(a => !a.startsWith("--")) || "server/index.js";
|
|
247
247
|
|
|
248
248
|
// Initialize server/ from template if it doesn't exist (first run)
|
|
249
|
-
const { initServer } = require("../src/core/init-server");
|
|
249
|
+
const { initServer, ensureX402Deps } = require("../src/core/init-server");
|
|
250
250
|
initServer(process.cwd(), scriptPath);
|
|
251
251
|
|
|
252
|
+
// Ensure x402 payment deps are installed (if vault exists)
|
|
253
|
+
ensureX402Deps(process.cwd());
|
|
254
|
+
|
|
252
255
|
// System detection (for analytics + dashboard, NOT for forking)
|
|
253
256
|
// Wolverine runs as a single process manager. If users want clustering,
|
|
254
257
|
// they handle it inside their server (e.g. @fastify/cluster, pm2 cluster mode).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wolverine-ai",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.4.1",
|
|
4
4
|
"description": "Self-healing Node.js server framework powered by AI. Catches crashes, diagnoses errors, generates fixes, verifies, and restarts — automatically.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -60,7 +60,8 @@
|
|
|
60
60
|
"dotenv": "^16.4.7",
|
|
61
61
|
"fastify": "^5.8.4",
|
|
62
62
|
"openai": "^4.73.0",
|
|
63
|
-
"x402": "^1.1.0"
|
|
63
|
+
"x402": "^1.1.0",
|
|
64
|
+
"viem": "^2.0.0"
|
|
64
65
|
},
|
|
65
66
|
"optionalDependencies": {
|
|
66
67
|
"@coinbase/cdp-sdk": "^1.46.1",
|
|
@@ -71,8 +72,7 @@
|
|
|
71
72
|
"ethers": "^6.0.0",
|
|
72
73
|
"ioredis": "^5.0.0",
|
|
73
74
|
"pg": "^8.0.0",
|
|
74
|
-
"stripe": "^18.0.0"
|
|
75
|
-
"viem": "^2.0.0"
|
|
75
|
+
"stripe": "^18.0.0"
|
|
76
76
|
},
|
|
77
77
|
"engines": {
|
|
78
78
|
"node": ">=18.0.0"
|
package/src/brain/brain.js
CHANGED
|
@@ -190,13 +190,17 @@ const SEED_DOCS = [
|
|
|
190
190
|
metadata: { topic: "notifications" },
|
|
191
191
|
},
|
|
192
192
|
{
|
|
193
|
-
text: "x402 paid APIs — turn any route into a paid API with one flag. Register the plugin
|
|
193
|
+
text: "x402 paid APIs — turn any route into a paid API with one flag. Register the plugin: fastify.register(require('wolverine-ai/src/middleware/x402-fastify')). Add { config: { x402: { price: '$0.10' } } } to any route. Routes WITHOUT x402 config are unaffected. Two modes: (1) Fixed price: { x402: { price: '$0.10' } }. (2) Variable price: { x402: { variable: true, min: '$1', max: '$10000', priceField: 'dollars' } }. Uses @coinbase/x402 facilitator (built-in, no auth config needed) + x402/verify for payment verification and on-chain settlement. Protocol is x402 v1 — network must be 'base' (NOT 'eip155:8453'). Payment header: X-PAYMENT or payment-signature (base64 JSON). Verify happens in preHandler hook, settle happens in onSend hook (after handler succeeds). Vault wallet auto-detected as payTo. Requires: Node 22+, CDP_API_KEY_ID + CDP_API_KEY_SECRET in .env.local (get free at cdp.coinbase.com), npm packages @coinbase/x402 + x402 + viem. CRITICAL SETUP NOTES: (1) network MUST be 'base' not 'eip155:8453' — the v1 SDK uses human-readable names. (2) Do NOT set a facilitator URL in settings.json — the @coinbase/x402 package has it built-in. (3) paymentRequirements.resource must be a full URL (https://host/path) not 'POST /path'. (4) paymentRequirements.asset must be checksummed via viem's getAddress(). (5) paymentRequirements.extra must be { name: 'USD Coin', version: '2' } for USDC EIP-712 domain. (6) maxAmountRequired must match the user's payment value for variable pricing. (7) Frontend payment payload format: { x402Version: 1, scheme: 'exact', network: 'base', payload: { authorization: { from, to, value (decimal string), validAfter (string), validBefore (string), nonce (0x hex) }, signature } }. Dashboard tracks x402 payments, revenue by route, USDC/ETH balances.",
|
|
194
194
|
metadata: { topic: "x402-paid-apis" },
|
|
195
195
|
},
|
|
196
196
|
{
|
|
197
|
-
text: "x402 examples — making a paid API is as simple as adding a route. FREE route
|
|
197
|
+
text: "x402 examples — making a paid API is as simple as adding a route. FREE route: fastify.get('/api/data', async (req) => { return getData(); }). PAID route: fastify.get('/api/premium', { config: { x402: { price: '$0.01' } } }, async (req) => { return { data: 'premium', paid: req.x402?.amount }; }). CREDIT PURCHASE: fastify.post('/buy', { config: { x402: { variable: true, min: '$1', max: '$10000', priceField: 'dollars' } } }, async (req) => { const credits = parseFloat(req.x402.amount.replace('$','')) * 100; return { credits }; }). Frontend integration: sign EIP-3009 TransferWithAuthorization with eth_signTypedData_v4, build payload as { x402Version: 1, scheme: 'exact', network: 'base', payload: { authorization: {...}, signature } }, base64 encode, send as X-PAYMENT header. Values MUST be decimal strings ('1000000' for $1) NOT hex ('0xf4240'). validAfter = String(now - 600), validBefore = String(now + 300). The facilitator verifies signature then settles on-chain (calls transferWithAuthorization on USDC contract). Handler only runs after verification passes. Settlement happens after handler returns success (onSend hook). req.x402 = { paid: true, amount: '$5.00', from: '0x...', txHash, settled: true }.",
|
|
198
198
|
metadata: { topic: "x402-examples" },
|
|
199
199
|
},
|
|
200
|
+
{
|
|
201
|
+
text: "x402 troubleshooting — common issues and fixes. (1) 'Invalid network': using 'eip155:8453' instead of 'base' — the @coinbase/x402 v1 SDK uses human-readable network names. (2) 'Unauthorized' from facilitator: either wrong CDP_API_KEY_ID/SECRET, or a facilitator URL override in settings.json pointing to api.cdp.coinbase.com (remove it, let the built-in handle auth). (3) '400 Bad Request': payload format mismatch — ensure x402Version:1, scheme:'exact', network:'base'. Don't use exact.evm.decodePayment() on the server, parse the base64 JSON directly. (4) 'invalid_exact_evm_payload_signature': the EIP-712 signature is wrong — check that the frontend signs with the correct domain (name:'USD Coin', version:'2', chainId:8453, verifyingContract:USDC address). (5) USDC not moving: the old middleware only verified signatures without calling the facilitator settle — must use @coinbase/x402 facilitator which handles verify+settle. (6) Frontend value showing as hex (0xf4240): must use decimal strings. (7) SDK not loading: @coinbase/x402 + x402 are ESM packages, need Node 22+. On Node 18 they fail with ERR_REQUIRE_ESM. (8) Packages disappearing after --update: add @coinbase/x402, x402, viem to package.json dependencies so npm install preserves them.",
|
|
202
|
+
metadata: { topic: "x402-troubleshooting" },
|
|
203
|
+
},
|
|
200
204
|
{
|
|
201
205
|
text: "MCP integration: connect external tools via Model Context Protocol. Configure in .wolverine/mcp.json with per-server tool allowlists. Security: arg sanitization (secrets redacted before sending to MCP servers), result injection scanning, rate limiting per server, audit logging. Tools appear as mcp__server__tool in the agent. Supports stdio and HTTP transports.",
|
|
202
206
|
metadata: { topic: "mcp" },
|
package/src/core/init-server.js
CHANGED
|
@@ -55,4 +55,38 @@ function _copyDir(src, dest) {
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Ensure x402 payment dependencies are installed.
|
|
60
|
+
* Called on startup — checks if @coinbase/x402 is resolvable.
|
|
61
|
+
* Auto-installs if vault is initialized (user wants x402).
|
|
62
|
+
*/
|
|
63
|
+
function ensureX402Deps(cwd) {
|
|
64
|
+
// Check if x402 packages are needed
|
|
65
|
+
const vaultPath = path.join(cwd, ".wolverine", "vault", "eth.vault");
|
|
66
|
+
const hasVault = fs.existsSync(vaultPath);
|
|
67
|
+
if (!hasVault) return; // No vault = no x402 needed
|
|
68
|
+
|
|
69
|
+
// Check if already installed
|
|
70
|
+
try {
|
|
71
|
+
require.resolve("@coinbase/x402");
|
|
72
|
+
require.resolve("x402");
|
|
73
|
+
return; // Already installed
|
|
74
|
+
} catch {}
|
|
75
|
+
|
|
76
|
+
// Auto-install x402 deps
|
|
77
|
+
console.log(chalk.blue(" 📦 Installing x402 payment dependencies..."));
|
|
78
|
+
try {
|
|
79
|
+
const { execSync } = require("child_process");
|
|
80
|
+
execSync("npm install @coinbase/x402 x402 viem --no-save --ignore-engines 2>/dev/null", {
|
|
81
|
+
cwd,
|
|
82
|
+
stdio: "pipe",
|
|
83
|
+
timeout: 60000,
|
|
84
|
+
});
|
|
85
|
+
console.log(chalk.green(" ✅ x402 dependencies installed"));
|
|
86
|
+
} catch (err) {
|
|
87
|
+
console.log(chalk.yellow(` ⚠️ x402 dep install failed: ${err.message?.slice(0, 80)}`));
|
|
88
|
+
console.log(chalk.gray(" Run manually: npm install @coinbase/x402 x402 viem"));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
module.exports = { initServer, ensureX402Deps };
|
|
@@ -160,8 +160,6 @@ async function x402Plugin(fastify, opts) {
|
|
|
160
160
|
// Verify via facilitator
|
|
161
161
|
try {
|
|
162
162
|
console.log(` 💰 x402 verify: from=${decodedPayment.payload?.authorization?.from} value=${decodedPayment.payload?.authorization?.value} network=${decodedPayment.network}`);
|
|
163
|
-
console.log(` 💰 x402 payload: ${JSON.stringify(decodedPayment).slice(0, 300)}`);
|
|
164
|
-
console.log(` 💰 x402 requirements: ${JSON.stringify(actualRequirements).slice(0, 300)}`);
|
|
165
163
|
const verifyResult = await _facilitatorClient.verify(decodedPayment, actualRequirements);
|
|
166
164
|
if (!verifyResult.isValid) {
|
|
167
165
|
console.log(` ⚠️ x402 verify failed: ${verifyResult.invalidReason} ${verifyResult.invalidMessage || ""}`);
|
|
@@ -5,9 +5,7 @@
|
|
|
5
5
|
"env": "development"
|
|
6
6
|
},
|
|
7
7
|
|
|
8
|
-
"_docs_models": "Each task wolverine performs uses a specific model role. You can mix providers freely — provider is auto-detected from the model name (claude-* → Anthropic, gpt-* → OpenAI). Using the same model across roles maximizes prompt cache hits and reduces cost. View per-role cost, speed, and token analytics on the wolverine dashboard at localhost:3001/analytics",
|
|
9
8
|
"models": {
|
|
10
|
-
"_docs": "reasoning: deep error analysis & root cause diagnosis | coding: generates code fixes (fast path, no tools) | chat: summaries & brain compression | tool: agent tool-calling during complex heals | classifier: error type classification | audit: security & injection scanning | compacting: context window compression | research: deep investigation & web research",
|
|
11
9
|
"reasoning": "claude-sonnet-4-6",
|
|
12
10
|
"coding": "claude-sonnet-4-6",
|
|
13
11
|
"chat": "claude-sonnet-4-6",
|
|
@@ -18,23 +16,19 @@
|
|
|
18
16
|
"research": "claude-sonnet-4-6"
|
|
19
17
|
},
|
|
20
18
|
|
|
21
|
-
"_docs_embedding": "Vector embedding model for the brain's memory system. Used to store and recall past fixes. text-embedding-3-small is the default (requires OPENAI_API_KEY). wolverine-embedding-1 routes through wolverine credits at 2x markup.",
|
|
22
19
|
"embedding": "text-embedding-3-small",
|
|
23
20
|
|
|
24
|
-
"_docs_server": "port: server listen port (must be 3000 for wolverine) | maxRetries: consecutive crash restarts before giving up | maxMemoryMB: OOM threshold — process killed and healed if exceeded",
|
|
25
21
|
"server": {
|
|
26
22
|
"port": 3000,
|
|
27
23
|
"maxRetries": 3,
|
|
28
24
|
"maxMemoryMB": 512
|
|
29
25
|
},
|
|
30
26
|
|
|
31
|
-
"_docs_telemetry": "Heartbeat reports server health (memory, CPU, routes, repair stats) to the dashboard every heartbeatIntervalMs. Disable if running fully offline.",
|
|
32
27
|
"telemetry": {
|
|
33
28
|
"enabled": true,
|
|
34
29
|
"heartbeatIntervalMs": 60000
|
|
35
30
|
},
|
|
36
31
|
|
|
37
|
-
"_docs_rateLimiting": "AI call budget to prevent runaway costs. maxCallsPerWindow: total AI calls allowed in windowMs. minGapMs: minimum delay between calls. maxTokensPerHour: hard token ceiling across all models.",
|
|
38
32
|
"rateLimiting": {
|
|
39
33
|
"maxCallsPerWindow": 32,
|
|
40
34
|
"windowMs": 100000,
|
|
@@ -42,7 +36,6 @@
|
|
|
42
36
|
"maxTokensPerHour": 1000000
|
|
43
37
|
},
|
|
44
38
|
|
|
45
|
-
"_docs_healthCheck": "Probes server liveness. intervalMs: check frequency. timeoutMs: max wait for response. failThreshold: consecutive failures before triggering heal. startDelayMs: grace period after boot before first check.",
|
|
46
39
|
"healthCheck": {
|
|
47
40
|
"intervalMs": 15000,
|
|
48
41
|
"timeoutMs": 5000,
|
|
@@ -50,14 +43,12 @@
|
|
|
50
43
|
"startDelayMs": 10000
|
|
51
44
|
},
|
|
52
45
|
|
|
53
|
-
"_docs_errorMonitor": "Tracks caught 500 errors per route. defaultThreshold: how many 500s on one route before triggering a heal. windowMs: error counting window. cooldownMs: minimum time between heals on the same route.",
|
|
54
46
|
"errorMonitor": {
|
|
55
47
|
"defaultThreshold": 1,
|
|
56
48
|
"windowMs": 30000,
|
|
57
49
|
"cooldownMs": 60000
|
|
58
50
|
},
|
|
59
51
|
|
|
60
|
-
"_docs_autoUpdate": "Auto-updates wolverine framework from git. Only updates src/ and bin/ — never touches your server/ code. Checks every intervalMs.",
|
|
61
52
|
"autoUpdate": {
|
|
62
53
|
"enabled": false,
|
|
63
54
|
"intervalMs": 300000
|
|
@@ -68,7 +59,6 @@
|
|
|
68
59
|
"cors": ["http://localhost:3000"]
|
|
69
60
|
},
|
|
70
61
|
|
|
71
|
-
"_docs_dashboard": "Dashboard serves on port+1 (default 3001). Configure WOLVERINE_ADMIN_KEY in .env.local for the agent command interface.",
|
|
72
62
|
"dashboard": {},
|
|
73
63
|
|
|
74
64
|
"cors": {
|