wolverine-ai 3.7.6 → 3.7.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wolverine-ai",
3
- "version": "3.7.6",
3
+ "version": "3.7.8",
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": {
@@ -331,6 +331,7 @@ class AgentEngine {
331
331
  this.logger = options.logger;
332
332
  this.cwd = options.cwd || process.cwd();
333
333
  this.mcp = options.mcp || null; // McpRegistry for external tools
334
+ this.category = options.category || "tool"; // Analytics category for token tracking
334
335
 
335
336
  // Budget constraints (claw-code: QueryEngineConfig)
336
337
  this.maxTurns = options.maxTurns || 15;
@@ -422,6 +423,7 @@ class AgentEngine {
422
423
  messages: this.messages,
423
424
  tools: allTools,
424
425
  maxTokens: 4096,
426
+ category: this.category,
425
427
  }),
426
428
  new Promise((_, reject) => setTimeout(() => reject(new Error(`AI call timed out after ${AI_CALL_TIMEOUT_MS / 1000}s`)), AI_CALL_TIMEOUT_MS)),
427
429
  ]);
@@ -97,6 +97,8 @@ async function spawnAgent(type, task, options = {}) {
97
97
  });
98
98
  }
99
99
 
100
+ // Map sub-agent type to analytics category: triage agents = classifier, fix/db = coding
101
+ const categoryMap = { explore: "classifier", plan: "classifier", verify: "classifier", research: "research", fix: "coding", database: "coding", security: "audit" };
100
102
  const agent = new AgentEngine({
101
103
  sandbox: options.sandbox,
102
104
  logger: options.logger,
@@ -104,6 +106,7 @@ async function spawnAgent(type, task, options = {}) {
104
106
  mcp: options.mcp,
105
107
  maxTurns: config.maxTurns,
106
108
  maxTokens: config.maxTokens,
109
+ category: categoryMap[type] || "tool",
107
110
  });
108
111
 
109
112
  // Override the system prompt for this agent type
@@ -114,7 +114,7 @@ const SEED_DOCS = [
114
114
  metadata: { topic: "sub-agent-tools" },
115
115
  },
116
116
  {
117
- text: "Heal pipeline escalation with cost optimization: Iteration 1 uses fast path (CODING_MODEL). For simple errors (TypeError/ReferenceError/SyntaxError), verifier trusts syntax+boot and skips route probe — ErrorMonitor is safety net. This prevents false-rejection cascades that waste tokens. Iteration 2 uses single agent (REASONING_MODEL, 4 turns for simple errors, 8 for complex). Iteration 3+ uses sub-agents with Haiku for triage (explore/plan/verify/research use classifier model) and only fixer uses coding model 90% cheaper. Token budgets capped by error complexity: simple=20K, moderate=50K, complex=100K. Context compacted every 3 agent turns to prevent token blowup (95K→20K). Prior attempt summaries passed between iterations instead of full context. Brain checked for cached fix patterns before starting AI.",
117
+ text: "Heal pipeline escalation with cost optimization: Iteration 1 uses fast path (CODING_MODEL, tracked as 'coding' category). For simple errors (TypeError/ReferenceError/SyntaxError), verifier trusts syntax+boot and skips route probe — ErrorMonitor is safety net. Iteration 2 uses single agent (REASONING_MODEL, 4 turns for simple, 8 for complex, tracked as 'tool' category). Iteration 3+ uses sub-agents: explore/plan/verify use classifier model (tracked as 'classifier'), fixer uses coding model (tracked as 'coding'), research sub-agent tracked as 'research', security as 'audit'. All calls billed through unified credit system framework authenticates as a normal API user via WOLVERINE_API_KEY through the billing proxy. Billing errors (402, insufficient_quota) immediately stop healing, no token waste.",
118
118
  metadata: { topic: "heal-escalation" },
119
119
  },
120
120
  {
@@ -146,7 +146,7 @@ const SEED_DOCS = [
146
146
  metadata: { topic: "fastify" },
147
147
  },
148
148
  {
149
- text: "npm package: wolverine-ai on npmjs.com. Install: npm i wolverine-ai. CLI: npx wolverine server/index.js. v1.0.0, 79 files, 125KB compressed. Includes src/, bin/, server/, examples/. GitHub: https://github.com/bobbyswhip/Wolverine",
149
+ text: "npm package: wolverine-ai on npmjs.com (v3.7.7). Install: npm i wolverine-ai. CLI: npx wolverine server/index.js. 85 files, 190KB compressed. Includes src/, bin/, examples/. Server directory created from src/templates/server/ on first run (never overwritten). GitHub: https://github.com/bobbyswhip/Wolverine. Unified billing: all AI calls route through inference proxy with credit-based billing. WOLVERINE_API_KEY authenticates through billing proxy, WOLVERINE_GPU_KEY for direct GPU access. 3 providers: openai, anthropic, wolverine (self-hosted GPU via Vast.ai).",
150
150
  metadata: { topic: "npm-package" },
151
151
  },
152
152
  {
@@ -162,7 +162,7 @@ const SEED_DOCS = [
162
162
  metadata: { topic: "smart-edit" },
163
163
  },
164
164
  {
165
- text: "Token tracking: every AI call tracked with input/output tokens, USD cost, latencyMs, and success/failure. Per-model KPIs: avgLatencyMs, minLatencyMs, maxLatencyMs, tokensPerSecond, successRate, costPerCall, successes, failures. Aggregated by model, by category, by tool, by provider (openai/anthropic). Persisted to .wolverine/usage.json + .wolverine/usage-history.jsonl. Pricing includes both OpenAI (gpt-5.x, o4, codex) and Anthropic (opus-4, sonnet-4, haiku-4) families. Customizable via .wolverine/pricing.json. Telemetry sends all per-model performance data to platform backend for fleet-wide cost:speed:reliability analysis.",
165
+ text: "Token tracking: every AI call tracked with input/output tokens, USD cost, latencyMs, and success/failure. Per-model KPIs: avgLatencyMs, minLatencyMs, maxLatencyMs, tokensPerSecond, successRate, costPerCall, successes, failures. Aggregated by model, by category, by tool, by provider (openai/anthropic/wolverine). 9 analytics categories match the 9 settings.json model roles: reasoning (deep debugging), coding (fast path repair + fix sub-agents), chat (dashboard), tool (main agent with tool use), classifier (triage sub-agents: explore/plan/verify), audit (injection scan + security sub-agent), compacting (brain text compression), research (research agent + research sub-agent), embedding (brain vector embeddings). All categories tracked in byModelCategory cross-reference for per-task model comparison. Persisted to .wolverine/usage.json + .wolverine/usage-history.jsonl. Telemetry sends all per-model performance data to platform backend for fleet-wide analytics.",
166
166
  metadata: { topic: "token-tracking" },
167
167
  },
168
168
  {
@@ -1,4 +1,4 @@
1
- const { getClient, aiCall, detectProvider } = require("../core/ai-client");
1
+ const { getClient, aiCall, detectProvider, _trackEmbedding } = require("../core/ai-client");
2
2
  const { getModel } = require("../core/models");
3
3
 
4
4
  /**
@@ -45,12 +45,14 @@ async function embed(text) {
45
45
  const openai = getClient("openai");
46
46
  const model = getModel("embedding");
47
47
 
48
+ const startMs = Date.now();
48
49
  const response = await openai.embeddings.create({
49
50
  model,
50
51
  input: text,
51
52
  });
52
53
 
53
54
  const embedding = response.data[0].embedding;
55
+ _trackEmbedding(model, response.usage, Date.now() - startMs, true);
54
56
  _cacheSet(text, embedding);
55
57
  return embedding;
56
58
  }
@@ -83,10 +85,12 @@ async function embedBatch(texts) {
83
85
  const openai = getClient("openai");
84
86
  const model = getModel("embedding");
85
87
 
88
+ const startMs = Date.now();
86
89
  const response = await openai.embeddings.create({
87
90
  model,
88
91
  input: uncached,
89
92
  });
93
+ _trackEmbedding(model, response.usage, Date.now() - startMs, true);
90
94
 
91
95
  // Sort by index to maintain order
92
96
  const sorted = response.data.sort((a, b) => a.index - b.index);
@@ -32,6 +32,12 @@ function _track(model, category, usage, tool, latencyMs, success) {
32
32
  _tracker.record(model, category, input, output, tool, latencyMs, success, cacheCreation, cacheRead);
33
33
  }
34
34
 
35
+ function _trackEmbedding(model, usage, latencyMs, success) {
36
+ if (!_tracker) return;
37
+ const input = usage?.prompt_tokens || usage?.total_tokens || 0;
38
+ _tracker.record(model, "embedding", input, 0, null, latencyMs, success, 0, 0);
39
+ }
40
+
35
41
  // ── Client Management ──
36
42
 
37
43
  function getClient(provider) {
@@ -619,4 +625,4 @@ Include both if needed, or just one.`;
619
625
  }
620
626
  }
621
627
 
622
- module.exports = { requestRepair, getClient, tokenParam, aiCall, aiCallWithHistory, isResponsesModel, isAnthropicModel, setTokenTracker, getTrackerSnapshot, detectProvider };
628
+ module.exports = { requestRepair, getClient, tokenParam, aiCall, aiCallWithHistory, isResponsesModel, isAnthropicModel, setTokenTracker, getTrackerSnapshot, detectProvider, _trackEmbedding };