wolverine-ai 3.7.3 → 3.7.5
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 +2 -1
- package/package.json +1 -1
- package/src/agent/agent-engine.js +2 -2
- package/src/core/ai-client.js +14 -1
- package/src/core/config.js +1 -0
- package/src/core/models.js +5 -2
- package/src/notifications/notifier.js +7 -1
package/bin/wolverine.js
CHANGED
|
@@ -144,9 +144,10 @@ console.log(chalk.yellow.bold("\n 🐺 Wolverine Node.js — Autonomous Server
|
|
|
144
144
|
logSystemInfo(systemInfo);
|
|
145
145
|
console.log("");
|
|
146
146
|
|
|
147
|
-
console.log(chalk.bold(
|
|
147
|
+
console.log(chalk.bold(` Models (${config.provider}):`));
|
|
148
148
|
logModelConfig(chalk);
|
|
149
149
|
console.log("");
|
|
150
|
+
console.log(chalk.gray(` Provider: ${config.provider}`));
|
|
150
151
|
console.log(chalk.gray(` Script: ${scriptPath}`));
|
|
151
152
|
console.log(chalk.gray(` Port: ${config.server.port}`));
|
|
152
153
|
console.log(chalk.gray(` Retries: ${config.server.maxRetries}`));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wolverine-ai",
|
|
3
|
-
"version": "3.7.
|
|
3
|
+
"version": "3.7.5",
|
|
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": {
|
|
@@ -414,7 +414,7 @@ class AgentEngine {
|
|
|
414
414
|
}
|
|
415
415
|
|
|
416
416
|
let response;
|
|
417
|
-
const AI_CALL_TIMEOUT_MS =
|
|
417
|
+
const AI_CALL_TIMEOUT_MS = parseInt(process.env.WOLVERINE_AI_CALL_TIMEOUT_MS, 10) || 90000; // 90s per API call — self-hosted GPU needs more time
|
|
418
418
|
try {
|
|
419
419
|
response = await Promise.race([
|
|
420
420
|
aiCallWithHistory({
|
|
@@ -423,7 +423,7 @@ class AgentEngine {
|
|
|
423
423
|
tools: allTools,
|
|
424
424
|
maxTokens: 4096,
|
|
425
425
|
}),
|
|
426
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error(
|
|
426
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(`AI call timed out after ${AI_CALL_TIMEOUT_MS / 1000}s`)), AI_CALL_TIMEOUT_MS)),
|
|
427
427
|
]);
|
|
428
428
|
} catch (err) {
|
|
429
429
|
console.log(chalk.red(` Agent API error: ${err.message}`));
|
package/src/core/ai-client.js
CHANGED
|
@@ -169,7 +169,20 @@ async function _withRetry(fn, maxRetries = 3) {
|
|
|
169
169
|
try {
|
|
170
170
|
return await fn();
|
|
171
171
|
} catch (err) {
|
|
172
|
-
const
|
|
172
|
+
const msg = (err.message || "").toLowerCase();
|
|
173
|
+
const code = (err.code || "").toLowerCase();
|
|
174
|
+
|
|
175
|
+
// Permanent billing/quota errors — never retry, surface immediately
|
|
176
|
+
const isBillingError = err.status === 402
|
|
177
|
+
|| /insufficient.*(quota|credits|funds)/i.test(msg)
|
|
178
|
+
|| /billing_hard_limit|insufficient_quota|quota_exceeded/i.test(msg)
|
|
179
|
+
|| /billing_hard_limit|insufficient_quota|quota_exceeded/i.test(code);
|
|
180
|
+
if (isBillingError) {
|
|
181
|
+
console.log(chalk.red(` 💳 Billing error (not retrying): ${err.message}`));
|
|
182
|
+
throw err;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const isRateLimit = err.status === 429 || code === "rate_limit_exceeded";
|
|
173
186
|
const isServerError = err.status >= 500;
|
|
174
187
|
if ((isRateLimit || isServerError) && attempt < maxRetries) {
|
|
175
188
|
const delay = Math.min(1000 * Math.pow(2, attempt) + Math.random() * 1000, 30000);
|
package/src/core/config.js
CHANGED
|
@@ -43,6 +43,7 @@ function loadConfig() {
|
|
|
43
43
|
classifier: process.env.CLASSIFIER_MODEL || modelSource.classifier || "gpt-4o-mini",
|
|
44
44
|
audit: process.env.AUDIT_MODEL || modelSource.audit || "gpt-4o-mini",
|
|
45
45
|
compacting: process.env.COMPACTING_MODEL || modelSource.compacting || "gpt-4o-mini",
|
|
46
|
+
utility: process.env.COMPACTING_MODEL || modelSource.compacting || "gpt-4o-mini",
|
|
46
47
|
research: process.env.RESEARCH_MODEL || modelSource.research || "gpt-4o",
|
|
47
48
|
embedding: process.env.TEXT_EMBEDDING_MODEL || modelSource.embedding || "text-embedding-3-small",
|
|
48
49
|
},
|
package/src/core/models.js
CHANGED
|
@@ -119,9 +119,12 @@ function getModel(role) {
|
|
|
119
119
|
function getModelConfig() {
|
|
120
120
|
const config = {};
|
|
121
121
|
for (const [role, def] of Object.entries(MODEL_ROLES)) {
|
|
122
|
+
const resolved = getModel(role);
|
|
123
|
+
const fromEnv = !!process.env[def.envKey];
|
|
124
|
+
const fromDefault = resolved === def.default;
|
|
122
125
|
config[role] = {
|
|
123
|
-
model:
|
|
124
|
-
source:
|
|
126
|
+
model: resolved,
|
|
127
|
+
source: fromEnv ? "env" : fromDefault ? "default" : "settings",
|
|
125
128
|
tier: def.tier,
|
|
126
129
|
};
|
|
127
130
|
}
|
|
@@ -29,11 +29,17 @@ const HUMAN_REQUIRED_PATTERNS = [
|
|
|
29
29
|
{ pattern: /(api|auth|token|key|credential).*(expired|revoked|rotated|invalid)/i, category: "auth", hint: "Credential has expired or been revoked" },
|
|
30
30
|
{ pattern: /authentication\s+failed/i, category: "auth", hint: "Authentication failed — check credentials" },
|
|
31
31
|
|
|
32
|
-
// Billing/Quota
|
|
32
|
+
// Billing/Quota — covers OpenAI, Anthropic, Wolverine, and generic patterns
|
|
33
33
|
{ pattern: /429\s*(too many|rate limit)/i, category: "billing", hint: "Rate limit hit — may need to upgrade plan or wait" },
|
|
34
34
|
{ pattern: /(quota|limit|credits?)\s*(exceeded|exhausted|depleted)/i, category: "billing", hint: "Usage quota or credits exhausted" },
|
|
35
35
|
{ pattern: /billing.*(?:issue|error|failed|inactive)/i, category: "billing", hint: "Billing issue on the account" },
|
|
36
36
|
{ pattern: /insufficient.*(funds|credits|quota)/i, category: "billing", hint: "Insufficient credits or funds" },
|
|
37
|
+
{ pattern: /billing_hard_limit_reached/i, category: "billing", hint: "OpenAI billing hard limit reached — add payment method or raise limit" },
|
|
38
|
+
{ pattern: /insufficient_quota/i, category: "billing", hint: "API quota exhausted — check billing dashboard" },
|
|
39
|
+
{ pattern: /rate_limit_exceeded/i, category: "billing", hint: "API rate limit exceeded — wait or upgrade plan" },
|
|
40
|
+
{ pattern: /402\s*(payment|required)/i, category: "billing", hint: "Payment required — check billing status" },
|
|
41
|
+
{ pattern: /exceeded.*(?:budget|spending|token)/i, category: "billing", hint: "Spending or token budget exceeded" },
|
|
42
|
+
{ pattern: /overloaded_error/i, category: "billing", hint: "Anthropic API overloaded — retry later" },
|
|
37
43
|
|
|
38
44
|
// External service failures
|
|
39
45
|
{ pattern: /ECONNREFUSED/i, category: "service", hint: "External service connection refused — is it running?" },
|