nodebench-mcp 2.70.0 → 3.0.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/README.md +95 -41
- package/dist/agents/alertRouter.d.ts +38 -0
- package/dist/agents/alertRouter.js +151 -0
- package/dist/agents/alertRouter.js.map +1 -0
- package/dist/agents/entityMemory.d.ts +40 -0
- package/dist/agents/entityMemory.js +64 -0
- package/dist/agents/entityMemory.js.map +1 -0
- package/dist/agents/subAgents.d.ts +35 -0
- package/dist/agents/subAgents.js +62 -0
- package/dist/agents/subAgents.js.map +1 -0
- package/dist/benchmarks/benchmarkRunner.js +14 -0
- package/dist/benchmarks/benchmarkRunner.js.map +1 -1
- package/dist/benchmarks/chainEval.js +107 -0
- package/dist/benchmarks/chainEval.js.map +1 -1
- package/dist/benchmarks/llmJudgeEval.js +85 -0
- package/dist/benchmarks/llmJudgeEval.js.map +1 -1
- package/dist/benchmarks/searchQualityEval.js +118 -5
- package/dist/benchmarks/searchQualityEval.js.map +1 -1
- package/dist/cli/search.d.ts +13 -0
- package/dist/cli/search.js +130 -0
- package/dist/cli/search.js.map +1 -0
- package/dist/db.d.ts +6 -2
- package/dist/db.js +470 -3
- package/dist/db.js.map +1 -1
- package/dist/index.js +349 -64
- package/dist/index.js.map +1 -1
- package/dist/profiler/behaviorStore.d.ts +97 -0
- package/dist/profiler/behaviorStore.js +276 -0
- package/dist/profiler/behaviorStore.js.map +1 -0
- package/dist/profiler/eventCollector.d.ts +119 -0
- package/dist/profiler/eventCollector.js +267 -0
- package/dist/profiler/eventCollector.js.map +1 -0
- package/dist/profiler/index.d.ts +15 -0
- package/dist/profiler/index.js +16 -0
- package/dist/profiler/index.js.map +1 -0
- package/dist/profiler/mcpProxy.d.ts +49 -0
- package/dist/profiler/mcpProxy.js +123 -0
- package/dist/profiler/mcpProxy.js.map +1 -0
- package/dist/profiler/modelRouter.d.ts +30 -0
- package/dist/profiler/modelRouter.js +99 -0
- package/dist/profiler/modelRouter.js.map +1 -0
- package/dist/profiler/otelReceiver.d.ts +17 -0
- package/dist/profiler/otelReceiver.js +62 -0
- package/dist/profiler/otelReceiver.js.map +1 -0
- package/dist/profiler/proofEngine.d.ts +41 -0
- package/dist/profiler/proofEngine.js +93 -0
- package/dist/profiler/proofEngine.js.map +1 -0
- package/dist/profiler/workflowTemplates.d.ts +41 -0
- package/dist/profiler/workflowTemplates.js +95 -0
- package/dist/profiler/workflowTemplates.js.map +1 -0
- package/dist/providers/localMemoryProvider.js +3 -2
- package/dist/providers/localMemoryProvider.js.map +1 -1
- package/dist/runtimeConfig.d.ts +11 -0
- package/dist/runtimeConfig.js +27 -0
- package/dist/runtimeConfig.js.map +1 -0
- package/dist/security/auditLog.js +8 -3
- package/dist/security/auditLog.js.map +1 -1
- package/dist/subconscious/blocks.d.ts +43 -0
- package/dist/subconscious/blocks.js +158 -0
- package/dist/subconscious/blocks.js.map +1 -0
- package/dist/subconscious/classifier.d.ts +22 -0
- package/dist/subconscious/classifier.js +118 -0
- package/dist/subconscious/classifier.js.map +1 -0
- package/dist/subconscious/graphEngine.d.ts +65 -0
- package/dist/subconscious/graphEngine.js +234 -0
- package/dist/subconscious/graphEngine.js.map +1 -0
- package/dist/subconscious/index.d.ts +19 -0
- package/dist/subconscious/index.js +20 -0
- package/dist/subconscious/index.js.map +1 -0
- package/dist/subconscious/tools.d.ts +5 -0
- package/dist/subconscious/tools.js +255 -0
- package/dist/subconscious/tools.js.map +1 -0
- package/dist/subconscious/whisperPolicy.d.ts +20 -0
- package/dist/subconscious/whisperPolicy.js +171 -0
- package/dist/subconscious/whisperPolicy.js.map +1 -0
- package/dist/sweep/engine.d.ts +27 -0
- package/dist/sweep/engine.js +244 -0
- package/dist/sweep/engine.js.map +1 -0
- package/dist/sweep/index.d.ts +9 -0
- package/dist/sweep/index.js +8 -0
- package/dist/sweep/index.js.map +1 -0
- package/dist/sweep/sources/github_trending.d.ts +6 -0
- package/dist/sweep/sources/github_trending.js +37 -0
- package/dist/sweep/sources/github_trending.js.map +1 -0
- package/dist/sweep/sources/hackernews.d.ts +7 -0
- package/dist/sweep/sources/hackernews.js +57 -0
- package/dist/sweep/sources/hackernews.js.map +1 -0
- package/dist/sweep/sources/openbb_finance.d.ts +9 -0
- package/dist/sweep/sources/openbb_finance.js +46 -0
- package/dist/sweep/sources/openbb_finance.js.map +1 -0
- package/dist/sweep/sources/producthunt.d.ts +6 -0
- package/dist/sweep/sources/producthunt.js +41 -0
- package/dist/sweep/sources/producthunt.js.map +1 -0
- package/dist/sweep/sources/web_signals.d.ts +7 -0
- package/dist/sweep/sources/web_signals.js +63 -0
- package/dist/sweep/sources/web_signals.js.map +1 -0
- package/dist/sweep/sources/yahoo_finance.d.ts +6 -0
- package/dist/sweep/sources/yahoo_finance.js +47 -0
- package/dist/sweep/sources/yahoo_finance.js.map +1 -0
- package/dist/sweep/types.d.ts +50 -0
- package/dist/sweep/types.js +9 -0
- package/dist/sweep/types.js.map +1 -0
- package/dist/sync/founderEpisodeStore.d.ts +98 -0
- package/dist/sync/founderEpisodeStore.js +230 -0
- package/dist/sync/founderEpisodeStore.js.map +1 -0
- package/dist/sync/hyperloopArchive.d.ts +51 -0
- package/dist/sync/hyperloopArchive.js +153 -0
- package/dist/sync/hyperloopArchive.js.map +1 -0
- package/dist/sync/hyperloopEval.d.ts +123 -0
- package/dist/sync/hyperloopEval.js +389 -0
- package/dist/sync/hyperloopEval.js.map +1 -0
- package/dist/sync/hyperloopEval.test.d.ts +4 -0
- package/dist/sync/hyperloopEval.test.js +60 -0
- package/dist/sync/hyperloopEval.test.js.map +1 -0
- package/dist/sync/protocol.d.ts +172 -0
- package/dist/sync/protocol.js +9 -0
- package/dist/sync/protocol.js.map +1 -0
- package/dist/sync/sessionMemory.d.ts +47 -0
- package/dist/sync/sessionMemory.js +138 -0
- package/dist/sync/sessionMemory.js.map +1 -0
- package/dist/sync/store.d.ts +384 -0
- package/dist/sync/store.js +1435 -0
- package/dist/sync/store.js.map +1 -0
- package/dist/sync/store.test.d.ts +4 -0
- package/dist/sync/store.test.js +43 -0
- package/dist/sync/store.test.js.map +1 -0
- package/dist/sync/syncBridgeClient.d.ts +30 -0
- package/dist/sync/syncBridgeClient.js +172 -0
- package/dist/sync/syncBridgeClient.js.map +1 -0
- package/dist/tools/autonomousDeliveryTools.d.ts +2 -0
- package/dist/tools/autonomousDeliveryTools.js +1104 -0
- package/dist/tools/autonomousDeliveryTools.js.map +1 -0
- package/dist/tools/claudeCodeIngestTools.d.ts +10 -0
- package/dist/tools/claudeCodeIngestTools.js +347 -0
- package/dist/tools/claudeCodeIngestTools.js.map +1 -0
- package/dist/tools/coreWorkflowTools.d.ts +2 -0
- package/dist/tools/coreWorkflowTools.js +488 -0
- package/dist/tools/coreWorkflowTools.js.map +1 -0
- package/dist/tools/deltaTools.d.ts +15 -0
- package/dist/tools/deltaTools.js +1522 -0
- package/dist/tools/deltaTools.js.map +1 -0
- package/dist/tools/entityLookupTools.d.ts +14 -0
- package/dist/tools/entityLookupTools.js +159 -0
- package/dist/tools/entityLookupTools.js.map +1 -0
- package/dist/tools/entityTemporalTools.d.ts +12 -0
- package/dist/tools/entityTemporalTools.js +330 -0
- package/dist/tools/entityTemporalTools.js.map +1 -0
- package/dist/tools/founderLocalPipeline.d.ts +215 -0
- package/dist/tools/founderLocalPipeline.js +1516 -2
- package/dist/tools/founderLocalPipeline.js.map +1 -1
- package/dist/tools/founderOperatingModel.d.ts +120 -0
- package/dist/tools/founderOperatingModel.js +469 -0
- package/dist/tools/founderOperatingModel.js.map +1 -0
- package/dist/tools/founderOperatingModelTools.d.ts +2 -0
- package/dist/tools/founderOperatingModelTools.js +169 -0
- package/dist/tools/founderOperatingModelTools.js.map +1 -0
- package/dist/tools/founderStrategicOpsTools.d.ts +2 -0
- package/dist/tools/founderStrategicOpsTools.js +1310 -0
- package/dist/tools/founderStrategicOpsTools.js.map +1 -0
- package/dist/tools/graphifyTools.d.ts +19 -0
- package/dist/tools/graphifyTools.js +375 -0
- package/dist/tools/graphifyTools.js.map +1 -0
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.js +4 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/monteCarloTools.d.ts +16 -0
- package/dist/tools/monteCarloTools.js +225 -0
- package/dist/tools/monteCarloTools.js.map +1 -0
- package/dist/tools/packetCompilerTools.d.ts +12 -0
- package/dist/tools/packetCompilerTools.js +322 -0
- package/dist/tools/packetCompilerTools.js.map +1 -0
- package/dist/tools/planSynthesisTools.d.ts +15 -0
- package/dist/tools/planSynthesisTools.js +455 -0
- package/dist/tools/planSynthesisTools.js.map +1 -0
- package/dist/tools/profilerTools.d.ts +20 -0
- package/dist/tools/profilerTools.js +364 -0
- package/dist/tools/profilerTools.js.map +1 -0
- package/dist/tools/savingsTools.d.ts +11 -0
- package/dist/tools/savingsTools.js +155 -0
- package/dist/tools/savingsTools.js.map +1 -0
- package/dist/tools/scenarioCompilerTools.d.ts +14 -0
- package/dist/tools/scenarioCompilerTools.js +290 -0
- package/dist/tools/scenarioCompilerTools.js.map +1 -0
- package/dist/tools/sharedContextTools.d.ts +2 -0
- package/dist/tools/sharedContextTools.js +423 -0
- package/dist/tools/sharedContextTools.js.map +1 -0
- package/dist/tools/sitemapTools.d.ts +15 -0
- package/dist/tools/sitemapTools.js +560 -0
- package/dist/tools/sitemapTools.js.map +1 -0
- package/dist/tools/sweepTools.d.ts +9 -0
- package/dist/tools/sweepTools.js +112 -0
- package/dist/tools/sweepTools.js.map +1 -0
- package/dist/tools/syncBridgeTools.d.ts +2 -0
- package/dist/tools/syncBridgeTools.js +258 -0
- package/dist/tools/syncBridgeTools.js.map +1 -0
- package/dist/tools/toolRegistry.js +1216 -49
- package/dist/tools/toolRegistry.js.map +1 -1
- package/dist/tools/workspaceTools.d.ts +19 -0
- package/dist/tools/workspaceTools.js +762 -0
- package/dist/tools/workspaceTools.js.map +1 -0
- package/dist/toolsetRegistry.js +88 -2
- package/dist/toolsetRegistry.js.map +1 -1
- package/package.json +36 -36
- package/rules/nodebench-agentic-reliability.md +32 -0
- package/rules/nodebench-analyst-diagnostic.md +25 -0
- package/rules/nodebench-auto-qa.md +31 -0
- package/rules/nodebench-completion-traceability.md +22 -0
- package/rules/nodebench-flywheel-continuous.md +25 -0
- package/rules/nodebench-pre-release-review.md +24 -0
- package/rules/nodebench-qa-dogfood.md +26 -0
- package/rules/nodebench-scenario-testing.md +30 -0
- package/rules/nodebench-self-direction.md +23 -0
- package/rules/nodebench-self-judge-loop.md +24 -0
- package/scripts/install.sh +215 -0
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* profilerTools.ts — Founder Operating Profiler
|
|
3
|
+
*
|
|
4
|
+
* Intercepts MCP tool calls, logs cost/latency/patterns, and surfaces
|
|
5
|
+
* optimization intelligence. This is the meta-layer that makes NodeBench
|
|
6
|
+
* indispensable for agent-native builders.
|
|
7
|
+
*
|
|
8
|
+
* What it profiles:
|
|
9
|
+
* - Tool call sequences (what chains do users run)
|
|
10
|
+
* - Cost patterns (which tools/models are expensive, which are redundant)
|
|
11
|
+
* - Context reuse (what gets rebuilt that should be cached)
|
|
12
|
+
* - Query patterns (repeated questions, similar intents)
|
|
13
|
+
* - Workflow efficiency (shortest valid path vs actual path)
|
|
14
|
+
*
|
|
15
|
+
* Architecture principle:
|
|
16
|
+
* - LLM for interpretation (pattern detection, optimization suggestions)
|
|
17
|
+
* - Deterministic code for control (logging, storage, budget enforcement)
|
|
18
|
+
*/
|
|
19
|
+
import { genId } from "../db.js";
|
|
20
|
+
// ── Cost estimates per tool category ──────────────────────────────────
|
|
21
|
+
const COST_PER_CALL = {
|
|
22
|
+
web_search: 0.008,
|
|
23
|
+
fetch_url: 0.002,
|
|
24
|
+
enrich_entity: 0.015,
|
|
25
|
+
run_deep_sim: 0.05,
|
|
26
|
+
build_claim_graph: 0.03,
|
|
27
|
+
extract_variables: 0.02,
|
|
28
|
+
generate_countermodels: 0.04,
|
|
29
|
+
rank_interventions: 0.02,
|
|
30
|
+
score_compounding: 0.02,
|
|
31
|
+
render_decision_memo: 0.01,
|
|
32
|
+
founder_local_weekly_reset: 0.005,
|
|
33
|
+
founder_local_synthesize: 0.01,
|
|
34
|
+
founder_local_gather: 0.003,
|
|
35
|
+
discover_tools: 0.001,
|
|
36
|
+
get_tool_quick_ref: 0.001,
|
|
37
|
+
// Default for unknown tools
|
|
38
|
+
_default: 0.005,
|
|
39
|
+
};
|
|
40
|
+
function estimateCost(toolName) {
|
|
41
|
+
return COST_PER_CALL[toolName] ?? COST_PER_CALL._default;
|
|
42
|
+
}
|
|
43
|
+
// ── In-memory profiling store (bounded) ──────────────────────────────
|
|
44
|
+
const MAX_RECORDS = 5000;
|
|
45
|
+
const MAX_SESSIONS = 200;
|
|
46
|
+
const toolCallLog = [];
|
|
47
|
+
const sessionProfiles = new Map();
|
|
48
|
+
function addToolCall(record) {
|
|
49
|
+
toolCallLog.push(record);
|
|
50
|
+
if (toolCallLog.length > MAX_RECORDS) {
|
|
51
|
+
toolCallLog.splice(0, toolCallLog.length - MAX_RECORDS);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function getOrCreateSession(sessionId) {
|
|
55
|
+
let profile = sessionProfiles.get(sessionId);
|
|
56
|
+
if (!profile) {
|
|
57
|
+
if (sessionProfiles.size >= MAX_SESSIONS) {
|
|
58
|
+
// Evict oldest session
|
|
59
|
+
const oldest = sessionProfiles.keys().next().value;
|
|
60
|
+
if (oldest)
|
|
61
|
+
sessionProfiles.delete(oldest);
|
|
62
|
+
}
|
|
63
|
+
profile = {
|
|
64
|
+
sessionId,
|
|
65
|
+
totalCalls: 0,
|
|
66
|
+
totalDurationMs: 0,
|
|
67
|
+
totalCostUsd: 0,
|
|
68
|
+
uniqueTools: [],
|
|
69
|
+
toolChain: [],
|
|
70
|
+
redundantCalls: 0,
|
|
71
|
+
reusedContext: 0,
|
|
72
|
+
optimizationScore: 100,
|
|
73
|
+
};
|
|
74
|
+
sessionProfiles.set(sessionId, profile);
|
|
75
|
+
}
|
|
76
|
+
return profile;
|
|
77
|
+
}
|
|
78
|
+
// ── Redundancy detection ─────────────────────────────────────────────
|
|
79
|
+
function isRedundant(toolName, args, sessionId) {
|
|
80
|
+
const recentCalls = toolCallLog
|
|
81
|
+
.filter(r => r.sessionId === sessionId && r.toolName === toolName)
|
|
82
|
+
.slice(-10);
|
|
83
|
+
const argsStr = JSON.stringify(args);
|
|
84
|
+
const thirtyMinAgo = Date.now() - 30 * 60 * 1000;
|
|
85
|
+
return recentCalls.some(r => r.startMs > thirtyMinAgo && JSON.stringify(r.args) === argsStr);
|
|
86
|
+
}
|
|
87
|
+
// ── Pattern detection ────────────────────────────────────────────────
|
|
88
|
+
function detectPatterns(sessionId) {
|
|
89
|
+
const suggestions = [];
|
|
90
|
+
const session = sessionProfiles.get(sessionId);
|
|
91
|
+
if (!session || session.totalCalls < 3)
|
|
92
|
+
return suggestions;
|
|
93
|
+
// 1. Redundant calls
|
|
94
|
+
if (session.redundantCalls > 0) {
|
|
95
|
+
suggestions.push({
|
|
96
|
+
type: "redundant_call",
|
|
97
|
+
description: `${session.redundantCalls} tool calls were identical to recent calls. Results could be cached.`,
|
|
98
|
+
estimatedSavings: {
|
|
99
|
+
calls: session.redundantCalls,
|
|
100
|
+
costUsd: session.redundantCalls * 0.005,
|
|
101
|
+
latencyMs: session.redundantCalls * 2000,
|
|
102
|
+
},
|
|
103
|
+
confidence: 90,
|
|
104
|
+
actionable: "Enable NodeBench result caching for repeated queries within 30-minute windows.",
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
// 2. Repeated tool chains
|
|
108
|
+
const chain = session.toolChain;
|
|
109
|
+
if (chain.length >= 6) {
|
|
110
|
+
// Look for repeated subsequences of length 3+
|
|
111
|
+
for (let len = 3; len <= Math.min(5, Math.floor(chain.length / 2)); len++) {
|
|
112
|
+
const last = chain.slice(-len).join(",");
|
|
113
|
+
const prior = chain.slice(-(len * 2), -len).join(",");
|
|
114
|
+
if (last === prior) {
|
|
115
|
+
suggestions.push({
|
|
116
|
+
type: "workflow_shortcut",
|
|
117
|
+
description: `Detected repeated ${len}-step sequence: ${chain.slice(-len).join(" → ")}. This can be automated.`,
|
|
118
|
+
estimatedSavings: { calls: len, latencyMs: len * 1500 },
|
|
119
|
+
confidence: 75,
|
|
120
|
+
actionable: "Save this as a reusable workflow in NodeBench.",
|
|
121
|
+
});
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// 3. Expensive tool usage
|
|
127
|
+
const expensiveCalls = toolCallLog
|
|
128
|
+
.filter(r => r.sessionId === sessionId && r.costEstimateUsd > 0.02)
|
|
129
|
+
.length;
|
|
130
|
+
if (expensiveCalls > 3) {
|
|
131
|
+
suggestions.push({
|
|
132
|
+
type: "cheaper_model",
|
|
133
|
+
description: `${expensiveCalls} calls used expensive tools. Some may work with Gemini Flash Lite instead.`,
|
|
134
|
+
estimatedSavings: {
|
|
135
|
+
costUsd: expensiveCalls * 0.015,
|
|
136
|
+
tokens: expensiveCalls * 500,
|
|
137
|
+
},
|
|
138
|
+
confidence: 60,
|
|
139
|
+
actionable: "Consider using lighter models for classification and extraction tasks.",
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
return suggestions;
|
|
143
|
+
}
|
|
144
|
+
// ── Query pattern analysis ───────────────────────────────────────────
|
|
145
|
+
function getQueryPatterns() {
|
|
146
|
+
// Find repeated queries (by tool args similarity)
|
|
147
|
+
const queryMap = new Map();
|
|
148
|
+
for (const record of toolCallLog) {
|
|
149
|
+
if (record.toolName === "web_search" || record.toolName === "enrich_entity") {
|
|
150
|
+
const key = `${record.toolName}:${JSON.stringify(record.args).substring(0, 100)}`;
|
|
151
|
+
queryMap.set(key, (queryMap.get(key) ?? 0) + 1);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const repeatedQueries = Array.from(queryMap.entries())
|
|
155
|
+
.filter(([, count]) => count > 1)
|
|
156
|
+
.sort((a, b) => b[1] - a[1])
|
|
157
|
+
.slice(0, 10)
|
|
158
|
+
.map(([query, count]) => ({ query, count }));
|
|
159
|
+
// Top tools by usage
|
|
160
|
+
const toolStats = new Map();
|
|
161
|
+
for (const record of toolCallLog) {
|
|
162
|
+
const stats = toolStats.get(record.toolName) ?? { count: 0, totalLatency: 0, totalCost: 0 };
|
|
163
|
+
stats.count++;
|
|
164
|
+
stats.totalLatency += record.durationMs;
|
|
165
|
+
stats.totalCost += record.costEstimateUsd;
|
|
166
|
+
toolStats.set(record.toolName, stats);
|
|
167
|
+
}
|
|
168
|
+
const topTools = Array.from(toolStats.entries())
|
|
169
|
+
.sort((a, b) => b[1].count - a[1].count)
|
|
170
|
+
.slice(0, 15)
|
|
171
|
+
.map(([tool, stats]) => ({
|
|
172
|
+
tool,
|
|
173
|
+
count: stats.count,
|
|
174
|
+
avgLatencyMs: Math.round(stats.totalLatency / stats.count),
|
|
175
|
+
totalCostUsd: Math.round(stats.totalCost * 1000) / 1000,
|
|
176
|
+
}));
|
|
177
|
+
return { repeatedQueries, topTools };
|
|
178
|
+
}
|
|
179
|
+
// ── MCP Tools ────────────────────────────────────────────────────────
|
|
180
|
+
export const profilerTools = [
|
|
181
|
+
{
|
|
182
|
+
name: "log_tool_call",
|
|
183
|
+
description: "Log an MCP tool call for profiling. Called automatically by the NodeBench gateway to track tool usage patterns, cost, and latency. Returns whether the call was redundant.",
|
|
184
|
+
inputSchema: {
|
|
185
|
+
type: "object",
|
|
186
|
+
properties: {
|
|
187
|
+
sessionId: { type: "string", description: "Session or conversation ID" },
|
|
188
|
+
toolName: { type: "string", description: "Name of the MCP tool called" },
|
|
189
|
+
args: { type: "object", description: "Tool input arguments" },
|
|
190
|
+
durationMs: { type: "number", description: "How long the call took" },
|
|
191
|
+
success: { type: "boolean", description: "Whether the call succeeded" },
|
|
192
|
+
modelUsed: { type: "string", description: "LLM model used (if applicable)" },
|
|
193
|
+
tokenEstimate: { type: "number", description: "Estimated tokens consumed" },
|
|
194
|
+
},
|
|
195
|
+
required: ["sessionId", "toolName", "durationMs", "success"],
|
|
196
|
+
},
|
|
197
|
+
handler: async (args) => {
|
|
198
|
+
const sessionId = String(args.sessionId ?? "unknown");
|
|
199
|
+
const toolName = String(args.toolName ?? "unknown");
|
|
200
|
+
const toolArgs = args.args ?? {};
|
|
201
|
+
const durationMs = Number(args.durationMs ?? 0);
|
|
202
|
+
const success = Boolean(args.success);
|
|
203
|
+
const modelUsed = args.modelUsed ? String(args.modelUsed) : undefined;
|
|
204
|
+
const tokenEstimate = args.tokenEstimate ? Number(args.tokenEstimate) : undefined;
|
|
205
|
+
const redundant = isRedundant(toolName, toolArgs, sessionId);
|
|
206
|
+
const costEstimate = estimateCost(toolName);
|
|
207
|
+
const record = {
|
|
208
|
+
id: genId("prof"),
|
|
209
|
+
sessionId,
|
|
210
|
+
toolName,
|
|
211
|
+
args: toolArgs,
|
|
212
|
+
result: { success, tokenEstimate },
|
|
213
|
+
startMs: Date.now() - durationMs,
|
|
214
|
+
durationMs,
|
|
215
|
+
costEstimateUsd: costEstimate,
|
|
216
|
+
modelUsed,
|
|
217
|
+
timestamp: new Date().toISOString(),
|
|
218
|
+
};
|
|
219
|
+
addToolCall(record);
|
|
220
|
+
// Update session profile
|
|
221
|
+
const session = getOrCreateSession(sessionId);
|
|
222
|
+
session.totalCalls++;
|
|
223
|
+
session.totalDurationMs += durationMs;
|
|
224
|
+
session.totalCostUsd += costEstimate;
|
|
225
|
+
session.toolChain.push(toolName);
|
|
226
|
+
if (session.toolChain.length > 100)
|
|
227
|
+
session.toolChain.splice(0, 50);
|
|
228
|
+
if (!session.uniqueTools.includes(toolName))
|
|
229
|
+
session.uniqueTools.push(toolName);
|
|
230
|
+
if (redundant)
|
|
231
|
+
session.redundantCalls++;
|
|
232
|
+
return {
|
|
233
|
+
logged: true,
|
|
234
|
+
redundant,
|
|
235
|
+
callNumber: session.totalCalls,
|
|
236
|
+
sessionCostSoFar: Math.round(session.totalCostUsd * 1000) / 1000,
|
|
237
|
+
suggestion: redundant ? "This call is identical to a recent one. Consider caching." : null,
|
|
238
|
+
};
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
name: "get_session_profile",
|
|
243
|
+
description: "Get the efficiency profile for the current session. Shows total calls, cost, latency, redundancy, and optimization suggestions.",
|
|
244
|
+
inputSchema: {
|
|
245
|
+
type: "object",
|
|
246
|
+
properties: {
|
|
247
|
+
sessionId: { type: "string", description: "Session ID to profile" },
|
|
248
|
+
},
|
|
249
|
+
required: ["sessionId"],
|
|
250
|
+
},
|
|
251
|
+
handler: async (args) => {
|
|
252
|
+
const sessionId = String(args.sessionId ?? "unknown");
|
|
253
|
+
const session = sessionProfiles.get(sessionId);
|
|
254
|
+
if (!session) {
|
|
255
|
+
return { error: false, message: "No profile data yet. Use tools to build a profile.", totalCalls: 0 };
|
|
256
|
+
}
|
|
257
|
+
const suggestions = detectPatterns(sessionId);
|
|
258
|
+
return {
|
|
259
|
+
...session,
|
|
260
|
+
totalCostUsd: Math.round(session.totalCostUsd * 1000) / 1000,
|
|
261
|
+
suggestions,
|
|
262
|
+
efficiency: {
|
|
263
|
+
redundancyRate: session.totalCalls > 0 ? Math.round((session.redundantCalls / session.totalCalls) * 100) : 0,
|
|
264
|
+
avgLatencyMs: session.totalCalls > 0 ? Math.round(session.totalDurationMs / session.totalCalls) : 0,
|
|
265
|
+
costPerCall: session.totalCalls > 0 ? Math.round((session.totalCostUsd / session.totalCalls) * 1000) / 1000 : 0,
|
|
266
|
+
},
|
|
267
|
+
};
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
name: "get_usage_insights",
|
|
272
|
+
description: "Get aggregate usage insights across all sessions. Shows top tools, repeated queries, cost breakdown, and optimization opportunities. This is the founder operating intelligence layer.",
|
|
273
|
+
inputSchema: {
|
|
274
|
+
type: "object",
|
|
275
|
+
properties: {
|
|
276
|
+
daysBack: { type: "number", description: "How many days of data to analyze (default: 7)" },
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
handler: async (args) => {
|
|
280
|
+
const patterns = getQueryPatterns();
|
|
281
|
+
const totalSessions = sessionProfiles.size;
|
|
282
|
+
const totalCalls = toolCallLog.length;
|
|
283
|
+
const totalCost = toolCallLog.reduce((sum, r) => sum + r.costEstimateUsd, 0);
|
|
284
|
+
const totalLatency = toolCallLog.reduce((sum, r) => sum + r.durationMs, 0);
|
|
285
|
+
const redundantTotal = Array.from(sessionProfiles.values()).reduce((sum, s) => sum + s.redundantCalls, 0);
|
|
286
|
+
// Find the most common tool chains
|
|
287
|
+
const chainCounts = new Map();
|
|
288
|
+
for (const session of sessionProfiles.values()) {
|
|
289
|
+
const chain = session.toolChain;
|
|
290
|
+
for (let i = 0; i < chain.length - 2; i++) {
|
|
291
|
+
const triplet = `${chain[i]} → ${chain[i + 1]} → ${chain[i + 2]}`;
|
|
292
|
+
chainCounts.set(triplet, (chainCounts.get(triplet) ?? 0) + 1);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
const topChains = Array.from(chainCounts.entries())
|
|
296
|
+
.sort((a, b) => b[1] - a[1])
|
|
297
|
+
.slice(0, 5)
|
|
298
|
+
.map(([chain, count]) => ({ chain, count }));
|
|
299
|
+
return {
|
|
300
|
+
overview: {
|
|
301
|
+
totalSessions,
|
|
302
|
+
totalCalls,
|
|
303
|
+
totalCostUsd: Math.round(totalCost * 1000) / 1000,
|
|
304
|
+
totalLatencyMs: totalLatency,
|
|
305
|
+
avgCallsPerSession: totalSessions > 0 ? Math.round(totalCalls / totalSessions) : 0,
|
|
306
|
+
redundantCallRate: totalCalls > 0 ? Math.round((redundantTotal / totalCalls) * 100) : 0,
|
|
307
|
+
},
|
|
308
|
+
topTools: patterns.topTools,
|
|
309
|
+
repeatedQueries: patterns.repeatedQueries,
|
|
310
|
+
topChains,
|
|
311
|
+
recommendations: [
|
|
312
|
+
redundantTotal > 5 ? `${redundantTotal} redundant calls detected. Enable caching to save ~$${Math.round(redundantTotal * 0.005 * 100) / 100}/week.` : null,
|
|
313
|
+
patterns.topTools.some(t => t.avgLatencyMs > 5000) ? `Some tools average >5s. Consider async dispatch or cheaper model alternatives.` : null,
|
|
314
|
+
topChains.length > 0 ? `Most common workflow: ${topChains[0].chain} (${topChains[0].count}x). Save as reusable template.` : null,
|
|
315
|
+
].filter(Boolean),
|
|
316
|
+
};
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
name: "suggest_optimizations",
|
|
321
|
+
description: "Analyze the current session and suggest specific optimizations: cheaper models, cached results, workflow shortcuts, and reusable patterns.",
|
|
322
|
+
inputSchema: {
|
|
323
|
+
type: "object",
|
|
324
|
+
properties: {
|
|
325
|
+
sessionId: { type: "string", description: "Session to optimize" },
|
|
326
|
+
},
|
|
327
|
+
required: ["sessionId"],
|
|
328
|
+
},
|
|
329
|
+
handler: async (args) => {
|
|
330
|
+
const sessionId = String(args.sessionId ?? "unknown");
|
|
331
|
+
const suggestions = detectPatterns(sessionId);
|
|
332
|
+
const session = sessionProfiles.get(sessionId);
|
|
333
|
+
if (!session || session.totalCalls < 2) {
|
|
334
|
+
return {
|
|
335
|
+
suggestions: [],
|
|
336
|
+
message: "Keep using tools — optimization suggestions appear after 3+ tool calls.",
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
// Calculate potential savings
|
|
340
|
+
const totalPotentialSavings = suggestions.reduce((sum, s) => ({
|
|
341
|
+
calls: sum.calls + (s.estimatedSavings.calls ?? 0),
|
|
342
|
+
costUsd: sum.costUsd + (s.estimatedSavings.costUsd ?? 0),
|
|
343
|
+
latencyMs: sum.latencyMs + (s.estimatedSavings.latencyMs ?? 0),
|
|
344
|
+
}), { calls: 0, costUsd: 0, latencyMs: 0 });
|
|
345
|
+
return {
|
|
346
|
+
sessionStats: {
|
|
347
|
+
totalCalls: session.totalCalls,
|
|
348
|
+
totalCostUsd: Math.round(session.totalCostUsd * 1000) / 1000,
|
|
349
|
+
redundancyRate: `${Math.round((session.redundantCalls / session.totalCalls) * 100)}%`,
|
|
350
|
+
},
|
|
351
|
+
suggestions,
|
|
352
|
+
potentialSavings: {
|
|
353
|
+
calls: totalPotentialSavings.calls,
|
|
354
|
+
costUsd: Math.round(totalPotentialSavings.costUsd * 1000) / 1000,
|
|
355
|
+
latencyMs: totalPotentialSavings.latencyMs,
|
|
356
|
+
summary: totalPotentialSavings.calls > 0
|
|
357
|
+
? `Save ${totalPotentialSavings.calls} calls, ~$${Math.round(totalPotentialSavings.costUsd * 100) / 100}, ~${Math.round(totalPotentialSavings.latencyMs / 1000)}s per session`
|
|
358
|
+
: "No optimizations needed — your workflow is efficient.",
|
|
359
|
+
},
|
|
360
|
+
};
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
];
|
|
364
|
+
//# sourceMappingURL=profilerTools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profilerTools.js","sourceRoot":"","sources":["../../src/tools/profilerTools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Savings Tools — Token/time/cost savings comparison
|
|
3
|
+
*
|
|
4
|
+
* Reads analytics DB to compute ROI metrics:
|
|
5
|
+
* - Total tokens used vs saved (TOON compression)
|
|
6
|
+
* - Time saved vs manual workflow
|
|
7
|
+
* - Cost estimates
|
|
8
|
+
* - Before/after delta between sessions
|
|
9
|
+
*/
|
|
10
|
+
import type { McpTool } from "../types.js";
|
|
11
|
+
export declare const savingsTools: McpTool[];
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Savings Tools — Token/time/cost savings comparison
|
|
3
|
+
*
|
|
4
|
+
* Reads analytics DB to compute ROI metrics:
|
|
5
|
+
* - Total tokens used vs saved (TOON compression)
|
|
6
|
+
* - Time saved vs manual workflow
|
|
7
|
+
* - Cost estimates
|
|
8
|
+
* - Before/after delta between sessions
|
|
9
|
+
*/
|
|
10
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
11
|
+
async function getAnalyticsDbSafe() {
|
|
12
|
+
try {
|
|
13
|
+
const os = await import("node:os");
|
|
14
|
+
const path = await import("node:path");
|
|
15
|
+
const fs = await import("node:fs");
|
|
16
|
+
const dbPath = path.join(os.homedir(), ".nodebench", "analytics.db");
|
|
17
|
+
if (!fs.existsSync(dbPath))
|
|
18
|
+
return null;
|
|
19
|
+
const Database = (await import("better-sqlite3")).default;
|
|
20
|
+
return new Database(dbPath, { readonly: true });
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// ─── Tools ────────────────────────────────────────────────────────────────────
|
|
27
|
+
export const savingsTools = [
|
|
28
|
+
{
|
|
29
|
+
name: "compare_savings",
|
|
30
|
+
description: "Compare token usage, time savings, and cost estimates. Optionally compare two sessions for before/after ROI. Shows total tool calls, tokens, estimated time saved, and cost.",
|
|
31
|
+
inputSchema: {
|
|
32
|
+
type: "object",
|
|
33
|
+
properties: {
|
|
34
|
+
session_id: {
|
|
35
|
+
type: "string",
|
|
36
|
+
description: "Specific session to analyze (omit for all-time stats)",
|
|
37
|
+
},
|
|
38
|
+
compare_session_id: {
|
|
39
|
+
type: "string",
|
|
40
|
+
description: "Second session ID for before/after comparison",
|
|
41
|
+
},
|
|
42
|
+
days: {
|
|
43
|
+
type: "number",
|
|
44
|
+
description: "Limit to last N days (default: 30)",
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
annotations: { readOnlyHint: true },
|
|
49
|
+
handler: async (args) => {
|
|
50
|
+
const db = await getAnalyticsDbSafe();
|
|
51
|
+
if (!db) {
|
|
52
|
+
return {
|
|
53
|
+
error: "No analytics data found. Use NodeBench MCP tools first to generate usage data.",
|
|
54
|
+
suggestion: "Run some tools, then call compare_savings() to see your ROI.",
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
const days = args.days ?? 30;
|
|
59
|
+
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
|
|
60
|
+
// Check if tool_call_log table exists
|
|
61
|
+
const tableCheck = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='tool_call_log'").get();
|
|
62
|
+
if (!tableCheck) {
|
|
63
|
+
db.close();
|
|
64
|
+
return {
|
|
65
|
+
error: "Analytics table not initialized yet. Run some tools first.",
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
// Get column info to handle schema variations
|
|
69
|
+
const columns = db.prepare("PRAGMA table_info(tool_call_log)").all();
|
|
70
|
+
const columnNames = new Set(columns.map((c) => c.name));
|
|
71
|
+
const hasTokens = columnNames.has("tokens_used");
|
|
72
|
+
const hasDuration = columnNames.has("duration_ms");
|
|
73
|
+
const hasSession = columnNames.has("session_id");
|
|
74
|
+
const hasTimestamp = columnNames.has("timestamp") || columnNames.has("called_at");
|
|
75
|
+
const timestampCol = columnNames.has("timestamp") ? "timestamp" : "called_at";
|
|
76
|
+
// Build query based on available columns
|
|
77
|
+
function getStats(sessionFilter) {
|
|
78
|
+
let where = hasTimestamp ? `WHERE ${timestampCol} > ?` : "WHERE 1=1";
|
|
79
|
+
const params = hasTimestamp ? [cutoff] : [];
|
|
80
|
+
if (sessionFilter && hasSession) {
|
|
81
|
+
where += " AND session_id = ?";
|
|
82
|
+
params.push(sessionFilter);
|
|
83
|
+
}
|
|
84
|
+
const totalCalls = db.prepare(`SELECT COUNT(*) as cnt FROM tool_call_log ${where}`).get(...params);
|
|
85
|
+
let avgDuration = 0;
|
|
86
|
+
if (hasDuration) {
|
|
87
|
+
const durResult = db.prepare(`SELECT AVG(duration_ms) as avg_dur FROM tool_call_log ${where}`).get(...params);
|
|
88
|
+
avgDuration = durResult?.avg_dur ?? 0;
|
|
89
|
+
}
|
|
90
|
+
let totalTokens = 0;
|
|
91
|
+
if (hasTokens) {
|
|
92
|
+
const tokResult = db.prepare(`SELECT SUM(tokens_used) as total FROM tool_call_log ${where}`).get(...params);
|
|
93
|
+
totalTokens = tokResult?.total ?? 0;
|
|
94
|
+
}
|
|
95
|
+
// Top tools
|
|
96
|
+
const topTools = db.prepare(`SELECT tool_name, COUNT(*) as calls${hasDuration ? ", AVG(duration_ms) as avg_ms" : ""} FROM tool_call_log ${where} GROUP BY tool_name ORDER BY calls DESC LIMIT 10`).all(...params);
|
|
97
|
+
// Error rate
|
|
98
|
+
const hasSuccess = columnNames.has("success");
|
|
99
|
+
let errorRate = 0;
|
|
100
|
+
if (hasSuccess) {
|
|
101
|
+
const errResult = db.prepare(`SELECT COUNT(*) as errs FROM tool_call_log ${where} AND success = 0`).get(...params);
|
|
102
|
+
errorRate = totalCalls.cnt > 0 ? (errResult.errs / totalCalls.cnt) * 100 : 0;
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
totalCalls: totalCalls.cnt,
|
|
106
|
+
avgDurationMs: Math.round(avgDuration),
|
|
107
|
+
totalTokens,
|
|
108
|
+
topTools,
|
|
109
|
+
errorRate: Math.round(errorRate * 10) / 10,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
const stats = getStats(args.session_id);
|
|
113
|
+
// Cost estimates (rough: $0.003 per 1K tokens for Claude Haiku, $0.015 for Sonnet)
|
|
114
|
+
const estimatedCost = (stats.totalTokens / 1000) * 0.003;
|
|
115
|
+
// Time savings estimate (assume 5 min manual per tool call)
|
|
116
|
+
const manualMinutes = stats.totalCalls * 5;
|
|
117
|
+
const automatedMinutes = (stats.totalCalls * stats.avgDurationMs) / 60_000;
|
|
118
|
+
const timeSavedMinutes = Math.max(0, manualMinutes - automatedMinutes);
|
|
119
|
+
// TOON savings estimate (~40% compression)
|
|
120
|
+
const toonSavedTokens = Math.round(stats.totalTokens * 0.4);
|
|
121
|
+
const result = {
|
|
122
|
+
period: `Last ${days} days`,
|
|
123
|
+
totalToolCalls: stats.totalCalls,
|
|
124
|
+
avgLatencyMs: stats.avgDurationMs,
|
|
125
|
+
totalTokens: stats.totalTokens,
|
|
126
|
+
toonSavedTokens,
|
|
127
|
+
estimatedCostUsd: Math.round(estimatedCost * 100) / 100,
|
|
128
|
+
timeSavedMinutes: Math.round(timeSavedMinutes),
|
|
129
|
+
timeSavedHours: Math.round(timeSavedMinutes / 60 * 10) / 10,
|
|
130
|
+
errorRate: `${stats.errorRate}%`,
|
|
131
|
+
topTools: stats.topTools,
|
|
132
|
+
};
|
|
133
|
+
// Comparison mode
|
|
134
|
+
if (args.compare_session_id && hasSession) {
|
|
135
|
+
const compareStats = getStats(args.compare_session_id);
|
|
136
|
+
result.comparison = {
|
|
137
|
+
baseSession: args.session_id || "all",
|
|
138
|
+
compareSession: args.compare_session_id,
|
|
139
|
+
callsDelta: stats.totalCalls - compareStats.totalCalls,
|
|
140
|
+
tokensDelta: stats.totalTokens - compareStats.totalTokens,
|
|
141
|
+
latencyDelta: stats.avgDurationMs - compareStats.avgDurationMs,
|
|
142
|
+
errorRateDelta: stats.errorRate - compareStats.errorRate,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
db.close();
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
db.close();
|
|
150
|
+
return { error: `Analytics query failed: ${e.message}` };
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
];
|
|
155
|
+
//# sourceMappingURL=savingsTools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"savingsTools.js","sourceRoot":"","sources":["../../src/tools/savingsTools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* scenarioCompilerTools.ts — MiroFish-essence scenario compiler.
|
|
3
|
+
*
|
|
4
|
+
* Compresses swarm simulation into structured passes:
|
|
5
|
+
* 1. Map entities, workflows, incentives, timelines
|
|
6
|
+
* 2. Identify live constraints and tensions
|
|
7
|
+
* 3. Generate 3-7 future branches (not 3000 agents)
|
|
8
|
+
* 4. Score each branch by probability, impact, decisiveness
|
|
9
|
+
*
|
|
10
|
+
* This is the "preemptive predictive history" layer:
|
|
11
|
+
* Right context, right order, better odds of right judgment. Never certainty.
|
|
12
|
+
*/
|
|
13
|
+
import type { McpTool } from "../types.js";
|
|
14
|
+
export declare const scenarioCompilerTools: McpTool[];
|