nodebench-mcp 2.15.0 → 2.18.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/LICENSE +21 -0
- package/NODEBENCH_AGENTS.md +2 -2
- package/README.md +514 -82
- package/dist/__tests__/analytics.test.d.ts +11 -0
- package/dist/__tests__/analytics.test.js +546 -0
- package/dist/__tests__/analytics.test.js.map +1 -0
- package/dist/__tests__/architectComplex.test.d.ts +1 -0
- package/dist/__tests__/architectComplex.test.js +375 -0
- package/dist/__tests__/architectComplex.test.js.map +1 -0
- package/dist/__tests__/architectSmoke.test.d.ts +1 -0
- package/dist/__tests__/architectSmoke.test.js +92 -0
- package/dist/__tests__/architectSmoke.test.js.map +1 -0
- package/dist/__tests__/dynamicLoading.test.d.ts +1 -0
- package/dist/__tests__/dynamicLoading.test.js +278 -0
- package/dist/__tests__/dynamicLoading.test.js.map +1 -0
- package/dist/__tests__/evalHarness.test.js +7 -2
- package/dist/__tests__/evalHarness.test.js.map +1 -1
- package/dist/__tests__/gaiaCapabilityEval.test.js +229 -12
- package/dist/__tests__/gaiaCapabilityEval.test.js.map +1 -1
- package/dist/__tests__/gaiaCapabilityMediaEval.test.js +194 -109
- package/dist/__tests__/gaiaCapabilityMediaEval.test.js.map +1 -1
- package/dist/__tests__/helpers/answerMatch.js +22 -22
- package/dist/__tests__/presetRealWorldBench.test.js +11 -2
- package/dist/__tests__/presetRealWorldBench.test.js.map +1 -1
- package/dist/__tests__/tools.test.js +10 -4
- package/dist/__tests__/tools.test.js.map +1 -1
- package/dist/__tests__/toolsetGatingEval.test.js +12 -4
- package/dist/__tests__/toolsetGatingEval.test.js.map +1 -1
- package/dist/analytics/index.d.ts +10 -0
- package/dist/analytics/index.js +11 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/analytics/projectDetector.d.ts +19 -0
- package/dist/analytics/projectDetector.js +259 -0
- package/dist/analytics/projectDetector.js.map +1 -0
- package/dist/analytics/schema.d.ts +57 -0
- package/dist/analytics/schema.js +157 -0
- package/dist/analytics/schema.js.map +1 -0
- package/dist/analytics/smartPreset.d.ts +63 -0
- package/dist/analytics/smartPreset.js +300 -0
- package/dist/analytics/smartPreset.js.map +1 -0
- package/dist/analytics/toolTracker.d.ts +59 -0
- package/dist/analytics/toolTracker.js +163 -0
- package/dist/analytics/toolTracker.js.map +1 -0
- package/dist/analytics/usageStats.d.ts +64 -0
- package/dist/analytics/usageStats.js +252 -0
- package/dist/analytics/usageStats.js.map +1 -0
- package/dist/db.js +359 -321
- package/dist/db.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +653 -84
- package/dist/index.js.map +1 -1
- package/dist/tools/architectTools.d.ts +15 -0
- package/dist/tools/architectTools.js +304 -0
- package/dist/tools/architectTools.js.map +1 -0
- package/dist/tools/critterTools.js +14 -14
- package/dist/tools/emailTools.d.ts +15 -0
- package/dist/tools/emailTools.js +664 -0
- package/dist/tools/emailTools.js.map +1 -0
- package/dist/tools/metaTools.js +660 -0
- package/dist/tools/metaTools.js.map +1 -1
- package/dist/tools/parallelAgentTools.js +176 -176
- package/dist/tools/patternTools.js +11 -11
- package/dist/tools/progressiveDiscoveryTools.d.ts +5 -1
- package/dist/tools/progressiveDiscoveryTools.js +113 -21
- package/dist/tools/progressiveDiscoveryTools.js.map +1 -1
- package/dist/tools/researchWritingTools.js +42 -42
- package/dist/tools/rssTools.d.ts +8 -0
- package/dist/tools/rssTools.js +833 -0
- package/dist/tools/rssTools.js.map +1 -0
- package/dist/tools/toolRegistry.d.ts +17 -0
- package/dist/tools/toolRegistry.js +236 -17
- package/dist/tools/toolRegistry.js.map +1 -1
- package/dist/tools/voiceBridgeTools.js +498 -498
- package/dist/toolsetRegistry.d.ts +10 -0
- package/dist/toolsetRegistry.js +84 -0
- package/dist/toolsetRegistry.js.map +1 -0
- package/package.json +12 -5
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Usage Analytics Schema for NodeBench MCP
|
|
3
|
+
*
|
|
4
|
+
* Tracks tool usage, project context, and generates smart preset recommendations.
|
|
5
|
+
* All data stored locally in SQLite at ~/.nodebench/analytics.db
|
|
6
|
+
*/
|
|
7
|
+
import Database from 'better-sqlite3';
|
|
8
|
+
export interface ToolUsageRecord {
|
|
9
|
+
id?: number;
|
|
10
|
+
toolName: string;
|
|
11
|
+
toolset: string;
|
|
12
|
+
timestamp: number;
|
|
13
|
+
duration: number;
|
|
14
|
+
success: boolean;
|
|
15
|
+
errorMessage?: string;
|
|
16
|
+
projectPath: string;
|
|
17
|
+
preset: string;
|
|
18
|
+
args?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface ProjectContextRecord {
|
|
21
|
+
id?: number;
|
|
22
|
+
projectPath: string;
|
|
23
|
+
projectType: string;
|
|
24
|
+
detectedAt: number;
|
|
25
|
+
lastSeen: number;
|
|
26
|
+
language: string;
|
|
27
|
+
framework?: string;
|
|
28
|
+
hasTests: boolean;
|
|
29
|
+
hasCI: boolean;
|
|
30
|
+
hasDocs: boolean;
|
|
31
|
+
fileCount: number;
|
|
32
|
+
}
|
|
33
|
+
export interface PresetHistoryRecord {
|
|
34
|
+
id?: number;
|
|
35
|
+
projectPath: string;
|
|
36
|
+
preset: string;
|
|
37
|
+
toolsetCount: number;
|
|
38
|
+
selectedAt: number;
|
|
39
|
+
selectionReason: 'manual' | 'smart' | 'default';
|
|
40
|
+
}
|
|
41
|
+
export interface UsageStatsCacheRecord {
|
|
42
|
+
id?: number;
|
|
43
|
+
projectPath: string;
|
|
44
|
+
cacheKey: string;
|
|
45
|
+
stats: string;
|
|
46
|
+
computedAt: number;
|
|
47
|
+
ttl: number;
|
|
48
|
+
}
|
|
49
|
+
export declare function initAnalyticsDb(): Database.Database;
|
|
50
|
+
export declare function getAnalyticsDb(): Database.Database;
|
|
51
|
+
export declare function closeAnalyticsDb(db: Database.Database): void;
|
|
52
|
+
export declare function recordToolUsage(db: Database.Database, record: Omit<ToolUsageRecord, 'id'>): void;
|
|
53
|
+
export declare function updateProjectContext(db: Database.Database, context: Omit<ProjectContextRecord, 'id'>): void;
|
|
54
|
+
export declare function recordPresetSelection(db: Database.Database, record: Omit<PresetHistoryRecord, 'id'>): void;
|
|
55
|
+
export declare function getCachedStats(db: Database.Database, projectPath: string, cacheKey: string): string | null;
|
|
56
|
+
export declare function setCachedStats(db: Database.Database, record: Omit<UsageStatsCacheRecord, 'id'>): void;
|
|
57
|
+
export declare function clearOldRecords(db: Database.Database, daysToKeep?: number): void;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Usage Analytics Schema for NodeBench MCP
|
|
3
|
+
*
|
|
4
|
+
* Tracks tool usage, project context, and generates smart preset recommendations.
|
|
5
|
+
* All data stored locally in SQLite at ~/.nodebench/analytics.db
|
|
6
|
+
*/
|
|
7
|
+
import Database from 'better-sqlite3';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import os from 'os';
|
|
10
|
+
import fs from 'fs';
|
|
11
|
+
const DB_DIR = path.join(os.homedir(), '.nodebench');
|
|
12
|
+
const DB_PATH = path.join(DB_DIR, 'analytics.db');
|
|
13
|
+
let _analyticsDb = null;
|
|
14
|
+
export function initAnalyticsDb() {
|
|
15
|
+
fs.mkdirSync(DB_DIR, { recursive: true });
|
|
16
|
+
const db = new Database(DB_PATH);
|
|
17
|
+
// Enable WAL mode for better concurrency
|
|
18
|
+
db.pragma('journal_mode = WAL');
|
|
19
|
+
// Create tables
|
|
20
|
+
db.exec(`
|
|
21
|
+
CREATE TABLE IF NOT EXISTS tool_usage (
|
|
22
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
23
|
+
tool_name TEXT NOT NULL,
|
|
24
|
+
toolset TEXT NOT NULL,
|
|
25
|
+
timestamp INTEGER NOT NULL,
|
|
26
|
+
duration INTEGER NOT NULL,
|
|
27
|
+
success BOOLEAN NOT NULL,
|
|
28
|
+
error_message TEXT,
|
|
29
|
+
project_path TEXT NOT NULL,
|
|
30
|
+
preset TEXT NOT NULL,
|
|
31
|
+
args TEXT
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
CREATE INDEX IF NOT EXISTS idx_tool_usage_tool ON tool_usage(tool_name);
|
|
35
|
+
CREATE INDEX IF NOT EXISTS idx_tool_usage_toolset ON tool_usage(toolset);
|
|
36
|
+
CREATE INDEX IF NOT EXISTS idx_tool_usage_project ON tool_usage(project_path);
|
|
37
|
+
CREATE INDEX IF NOT EXISTS idx_tool_usage_timestamp ON tool_usage(timestamp);
|
|
38
|
+
|
|
39
|
+
CREATE TABLE IF NOT EXISTS project_context (
|
|
40
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
41
|
+
project_path TEXT UNIQUE NOT NULL,
|
|
42
|
+
project_type TEXT NOT NULL,
|
|
43
|
+
detected_at INTEGER NOT NULL,
|
|
44
|
+
last_seen INTEGER NOT NULL,
|
|
45
|
+
language TEXT NOT NULL,
|
|
46
|
+
framework TEXT,
|
|
47
|
+
has_tests BOOLEAN NOT NULL,
|
|
48
|
+
has_ci BOOLEAN NOT NULL,
|
|
49
|
+
has_docs BOOLEAN NOT NULL,
|
|
50
|
+
file_count INTEGER NOT NULL
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
CREATE INDEX IF NOT EXISTS idx_project_context_type ON project_context(project_type);
|
|
54
|
+
CREATE INDEX IF NOT EXISTS idx_project_context_last_seen ON project_context(last_seen);
|
|
55
|
+
|
|
56
|
+
CREATE TABLE IF NOT EXISTS preset_history (
|
|
57
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
58
|
+
project_path TEXT NOT NULL,
|
|
59
|
+
preset TEXT NOT NULL,
|
|
60
|
+
toolset_count INTEGER NOT NULL,
|
|
61
|
+
selected_at INTEGER NOT NULL,
|
|
62
|
+
selection_reason TEXT NOT NULL
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
CREATE INDEX IF NOT EXISTS idx_preset_history_project ON preset_history(project_path);
|
|
66
|
+
CREATE INDEX IF NOT EXISTS idx_preset_history_timestamp ON preset_history(selected_at);
|
|
67
|
+
|
|
68
|
+
CREATE TABLE IF NOT EXISTS usage_stats_cache (
|
|
69
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
70
|
+
project_path TEXT NOT NULL,
|
|
71
|
+
cache_key TEXT NOT NULL,
|
|
72
|
+
stats TEXT NOT NULL,
|
|
73
|
+
computed_at INTEGER NOT NULL,
|
|
74
|
+
ttl INTEGER NOT NULL,
|
|
75
|
+
UNIQUE(project_path, cache_key)
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
CREATE INDEX IF NOT EXISTS idx_usage_stats_cache_key ON usage_stats_cache(project_path, cache_key);
|
|
79
|
+
`);
|
|
80
|
+
return db;
|
|
81
|
+
}
|
|
82
|
+
export function getAnalyticsDb() {
|
|
83
|
+
if (_analyticsDb)
|
|
84
|
+
return _analyticsDb;
|
|
85
|
+
_analyticsDb = initAnalyticsDb();
|
|
86
|
+
return _analyticsDb;
|
|
87
|
+
}
|
|
88
|
+
export function closeAnalyticsDb(db) {
|
|
89
|
+
db.close();
|
|
90
|
+
if (_analyticsDb === db)
|
|
91
|
+
_analyticsDb = null;
|
|
92
|
+
}
|
|
93
|
+
// Helper functions for common queries
|
|
94
|
+
export function recordToolUsage(db, record) {
|
|
95
|
+
const stmt = db.prepare(`
|
|
96
|
+
INSERT INTO tool_usage (
|
|
97
|
+
tool_name, toolset, timestamp, duration, success,
|
|
98
|
+
error_message, project_path, preset, args
|
|
99
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
100
|
+
`);
|
|
101
|
+
stmt.run(record.toolName, record.toolset, record.timestamp, record.duration, record.success ? 1 : 0, record.errorMessage || null, record.projectPath, record.preset, record.args || null);
|
|
102
|
+
}
|
|
103
|
+
export function updateProjectContext(db, context) {
|
|
104
|
+
const stmt = db.prepare(`
|
|
105
|
+
INSERT INTO project_context (
|
|
106
|
+
project_path, project_type, detected_at, last_seen,
|
|
107
|
+
language, framework, has_tests, has_ci, has_docs, file_count
|
|
108
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
109
|
+
ON CONFLICT(project_path) DO UPDATE SET
|
|
110
|
+
project_type = excluded.project_type,
|
|
111
|
+
last_seen = excluded.last_seen,
|
|
112
|
+
language = excluded.language,
|
|
113
|
+
framework = excluded.framework,
|
|
114
|
+
has_tests = excluded.has_tests,
|
|
115
|
+
has_ci = excluded.has_ci,
|
|
116
|
+
has_docs = excluded.has_docs,
|
|
117
|
+
file_count = excluded.file_count
|
|
118
|
+
`);
|
|
119
|
+
stmt.run(context.projectPath, context.projectType, context.detectedAt, context.lastSeen, context.language, context.framework || null, context.hasTests ? 1 : 0, context.hasCI ? 1 : 0, context.hasDocs ? 1 : 0, context.fileCount);
|
|
120
|
+
}
|
|
121
|
+
export function recordPresetSelection(db, record) {
|
|
122
|
+
const stmt = db.prepare(`
|
|
123
|
+
INSERT INTO preset_history (
|
|
124
|
+
project_path, preset, toolset_count, selected_at, selection_reason
|
|
125
|
+
) VALUES (?, ?, ?, ?, ?)
|
|
126
|
+
`);
|
|
127
|
+
stmt.run(record.projectPath, record.preset, record.toolsetCount, record.selectedAt, record.selectionReason);
|
|
128
|
+
}
|
|
129
|
+
export function getCachedStats(db, projectPath, cacheKey) {
|
|
130
|
+
const stmt = db.prepare(`
|
|
131
|
+
SELECT stats FROM usage_stats_cache
|
|
132
|
+
WHERE project_path = ? AND cache_key = ?
|
|
133
|
+
AND computed_at + (ttl * 1000) > ?
|
|
134
|
+
`);
|
|
135
|
+
const now = Date.now();
|
|
136
|
+
const result = stmt.get(projectPath, cacheKey, now);
|
|
137
|
+
return result?.stats || null;
|
|
138
|
+
}
|
|
139
|
+
export function setCachedStats(db, record) {
|
|
140
|
+
const stmt = db.prepare(`
|
|
141
|
+
INSERT INTO usage_stats_cache (
|
|
142
|
+
project_path, cache_key, stats, computed_at, ttl
|
|
143
|
+
) VALUES (?, ?, ?, ?, ?)
|
|
144
|
+
ON CONFLICT(project_path, cache_key) DO UPDATE SET
|
|
145
|
+
stats = excluded.stats,
|
|
146
|
+
computed_at = excluded.computed_at,
|
|
147
|
+
ttl = excluded.ttl
|
|
148
|
+
`);
|
|
149
|
+
stmt.run(record.projectPath, record.cacheKey, record.stats, record.computedAt, record.ttl);
|
|
150
|
+
}
|
|
151
|
+
export function clearOldRecords(db, daysToKeep = 90) {
|
|
152
|
+
const cutoff = Date.now() - (daysToKeep * 24 * 60 * 60 * 1000);
|
|
153
|
+
db.prepare('DELETE FROM tool_usage WHERE timestamp < ?').run(cutoff);
|
|
154
|
+
db.prepare('DELETE FROM usage_stats_cache WHERE computed_at < ?').run(cutoff);
|
|
155
|
+
// Don't delete project_context or preset_history - they're useful for history
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/analytics/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart Preset Generator — Weighted Multi-Signal Scoring Model
|
|
3
|
+
*
|
|
4
|
+
* Recommends preset (default vs full) using 5 weighted signals derived from
|
|
5
|
+
* actual project context and historical usage data:
|
|
6
|
+
*
|
|
7
|
+
* 1. Project Type Affinity — static: how many specialized toolsets fit this project type
|
|
8
|
+
* 2. Usage Breadth — empirical: how many distinct toolsets were actually used
|
|
9
|
+
* 3. Specialized Usage Depth — empirical: calls to non-default toolsets (weighted by recency)
|
|
10
|
+
* 4. Failure Penalty — empirical: frequently failing tools penalize confidence
|
|
11
|
+
* 5. History Weight — meta: more history = higher confidence in the recommendation
|
|
12
|
+
*
|
|
13
|
+
* The final score is a weighted sum normalized to [0, 1].
|
|
14
|
+
* score > 0.55 → recommend full
|
|
15
|
+
* score <= 0.55 → recommend default
|
|
16
|
+
* confidence = f(history_weight, failure_penalty)
|
|
17
|
+
*/
|
|
18
|
+
import Database from 'better-sqlite3';
|
|
19
|
+
import { type ProjectContext } from './projectDetector.js';
|
|
20
|
+
import type { McpTool } from '../types.js';
|
|
21
|
+
export interface PresetRecommendation {
|
|
22
|
+
preset: 'default' | 'full';
|
|
23
|
+
reason: string;
|
|
24
|
+
confidence: number;
|
|
25
|
+
score: number;
|
|
26
|
+
suggestedToolsets: string[];
|
|
27
|
+
optionalToolsets: string[];
|
|
28
|
+
projectContext: ProjectContext;
|
|
29
|
+
usageInsights: UsageInsights;
|
|
30
|
+
signals: SignalBreakdown;
|
|
31
|
+
}
|
|
32
|
+
export interface UsageInsights {
|
|
33
|
+
mostUsedToolsets: string[];
|
|
34
|
+
unusedToolsets: string[];
|
|
35
|
+
frequentlyFailingTools: Array<{
|
|
36
|
+
name: string;
|
|
37
|
+
failures: number;
|
|
38
|
+
lastError: string | null;
|
|
39
|
+
}>;
|
|
40
|
+
totalCallsLast30d: number;
|
|
41
|
+
uniqueToolsetsUsed: number;
|
|
42
|
+
}
|
|
43
|
+
export interface SignalBreakdown {
|
|
44
|
+
projectTypeAffinity: number;
|
|
45
|
+
usageBreadth: number;
|
|
46
|
+
specializedDepth: number;
|
|
47
|
+
failurePenalty: number;
|
|
48
|
+
historyWeight: number;
|
|
49
|
+
}
|
|
50
|
+
export interface PresetConfig {
|
|
51
|
+
name: 'default' | 'full';
|
|
52
|
+
toolsets: string[];
|
|
53
|
+
toolCount: number;
|
|
54
|
+
}
|
|
55
|
+
export declare function generateSmartPreset(db: Database.Database, toolsetMap: Record<string, McpTool[]>, projectPath?: string): PresetRecommendation;
|
|
56
|
+
export declare function getPresetConfig(preset: 'default' | 'full', toolsetMap: Record<string, McpTool[]>): PresetConfig;
|
|
57
|
+
export declare function listPresets(toolsetMap: Record<string, McpTool[]>): Array<{
|
|
58
|
+
name: string;
|
|
59
|
+
toolsets: string[];
|
|
60
|
+
toolCount: number;
|
|
61
|
+
description: string;
|
|
62
|
+
}>;
|
|
63
|
+
export declare function formatPresetRecommendation(recommendation: PresetRecommendation, toolsetMap: Record<string, McpTool[]>): string;
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart Preset Generator — Weighted Multi-Signal Scoring Model
|
|
3
|
+
*
|
|
4
|
+
* Recommends preset (default vs full) using 5 weighted signals derived from
|
|
5
|
+
* actual project context and historical usage data:
|
|
6
|
+
*
|
|
7
|
+
* 1. Project Type Affinity — static: how many specialized toolsets fit this project type
|
|
8
|
+
* 2. Usage Breadth — empirical: how many distinct toolsets were actually used
|
|
9
|
+
* 3. Specialized Usage Depth — empirical: calls to non-default toolsets (weighted by recency)
|
|
10
|
+
* 4. Failure Penalty — empirical: frequently failing tools penalize confidence
|
|
11
|
+
* 5. History Weight — meta: more history = higher confidence in the recommendation
|
|
12
|
+
*
|
|
13
|
+
* The final score is a weighted sum normalized to [0, 1].
|
|
14
|
+
* score > 0.55 → recommend full
|
|
15
|
+
* score <= 0.55 → recommend default
|
|
16
|
+
* confidence = f(history_weight, failure_penalty)
|
|
17
|
+
*/
|
|
18
|
+
import { detectProject } from './projectDetector.js';
|
|
19
|
+
import { getToolUsageStats, getToolsetUsageStats, getFrequentlyFailingTools, } from './usageStats.js';
|
|
20
|
+
// ── Constants ───────────────────────────────────────────────────────────
|
|
21
|
+
const DEFAULT_TOOLSETS = ['verification', 'eval', 'quality_gate', 'learning', 'flywheel', 'recon', 'security', 'boilerplate'];
|
|
22
|
+
const DEFAULT_TOOLSET_SET = new Set(DEFAULT_TOOLSETS);
|
|
23
|
+
const SCORE_THRESHOLD = 0.55; // above this → recommend full
|
|
24
|
+
// Signal weights (sum to 1.0)
|
|
25
|
+
const W_PROJECT_TYPE = 0.25;
|
|
26
|
+
const W_USAGE_BREADTH = 0.30;
|
|
27
|
+
const W_SPECIALIZED_DEPTH = 0.30;
|
|
28
|
+
const W_HISTORY = 0.15;
|
|
29
|
+
// Project type → extra toolsets beyond default
|
|
30
|
+
const PROJECT_TYPE_EXTRAS = {
|
|
31
|
+
web_frontend: ['ui_capture', 'vision'],
|
|
32
|
+
web_backend: ['web', 'github'],
|
|
33
|
+
fullstack: ['ui_capture', 'vision', 'web', 'github', 'llm'],
|
|
34
|
+
mobile: [],
|
|
35
|
+
desktop: [],
|
|
36
|
+
cli: [],
|
|
37
|
+
library: ['docs', 'github'],
|
|
38
|
+
data_science: ['local_file', 'llm'],
|
|
39
|
+
devops: ['github'],
|
|
40
|
+
unknown: [],
|
|
41
|
+
};
|
|
42
|
+
// All toolsets considered "specialized" (not in default)
|
|
43
|
+
const SPECIALIZED_TOOLSETS = [
|
|
44
|
+
'ui_capture', 'vision', 'web', 'github', 'docs', 'local_file',
|
|
45
|
+
'self_eval', 'parallel', 'llm', 'platform', 'research_writing',
|
|
46
|
+
'bootstrap', 'flicker_detection', 'figma_flow', 'benchmark',
|
|
47
|
+
'gaia_solvers', 'session_memory', 'toon', 'pattern', 'git_workflow',
|
|
48
|
+
'seo', 'voice_bridge', 'critter', 'email', 'rss', 'architect',
|
|
49
|
+
];
|
|
50
|
+
// ── Helpers ─────────────────────────────────────────────────────────────
|
|
51
|
+
function calculateToolsetCount(toolsets, toolsetMap) {
|
|
52
|
+
let count = 0;
|
|
53
|
+
for (const ts of toolsets)
|
|
54
|
+
count += toolsetMap[ts]?.length || 0;
|
|
55
|
+
return count + 6; // +6 meta/discovery
|
|
56
|
+
}
|
|
57
|
+
function createPresets(toolsetMap) {
|
|
58
|
+
return {
|
|
59
|
+
default: {
|
|
60
|
+
name: 'default',
|
|
61
|
+
toolsets: DEFAULT_TOOLSETS,
|
|
62
|
+
toolCount: calculateToolsetCount(DEFAULT_TOOLSETS, toolsetMap),
|
|
63
|
+
},
|
|
64
|
+
full: {
|
|
65
|
+
name: 'full',
|
|
66
|
+
toolsets: Object.keys(toolsetMap),
|
|
67
|
+
toolCount: Object.values(toolsetMap).reduce((s, t) => s + t.length, 0) + 6,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
// ── Signal computation ──────────────────────────────────────────────────
|
|
72
|
+
function computeProjectTypeAffinity(projectType) {
|
|
73
|
+
const extras = PROJECT_TYPE_EXTRAS[projectType] || [];
|
|
74
|
+
// 0 extras → 0.0 (default is fine), 5+ extras → 1.0 (needs full)
|
|
75
|
+
return Math.min(extras.length / 5, 1.0);
|
|
76
|
+
}
|
|
77
|
+
function computeUsageBreadth(toolsetStats, totalAvailableToolsets) {
|
|
78
|
+
if (totalAvailableToolsets === 0)
|
|
79
|
+
return 0;
|
|
80
|
+
const usedCount = toolsetStats.filter(ts => ts.totalCalls > 0).length;
|
|
81
|
+
// Fraction of available toolsets that were actually used
|
|
82
|
+
return Math.min(usedCount / totalAvailableToolsets, 1.0);
|
|
83
|
+
}
|
|
84
|
+
function computeSpecializedDepth(toolsetStats, totalCalls) {
|
|
85
|
+
if (totalCalls === 0)
|
|
86
|
+
return 0;
|
|
87
|
+
// What fraction of total calls went to non-default toolsets?
|
|
88
|
+
const specializedCalls = toolsetStats
|
|
89
|
+
.filter(ts => !DEFAULT_TOOLSET_SET.has(ts.toolset))
|
|
90
|
+
.reduce((sum, ts) => sum + ts.totalCalls, 0);
|
|
91
|
+
return Math.min(specializedCalls / totalCalls, 1.0);
|
|
92
|
+
}
|
|
93
|
+
function computeFailurePenalty(failingTools, totalCalls) {
|
|
94
|
+
if (totalCalls === 0 || failingTools.length === 0)
|
|
95
|
+
return 0;
|
|
96
|
+
const totalFailures = failingTools.reduce((s, t) => s + t.failureCount, 0);
|
|
97
|
+
// Cap at 0.5 — failures reduce confidence but don't dominate
|
|
98
|
+
return Math.min(totalFailures / totalCalls, 0.5);
|
|
99
|
+
}
|
|
100
|
+
function computeHistoryWeight(totalCalls) {
|
|
101
|
+
// No history → 0, 10 calls → 0.5, 100+ calls → 1.0 (logarithmic)
|
|
102
|
+
if (totalCalls === 0)
|
|
103
|
+
return 0;
|
|
104
|
+
return Math.min(Math.log10(totalCalls + 1) / 2, 1.0);
|
|
105
|
+
}
|
|
106
|
+
// ── Core: generate recommendation ───────────────────────────────────────
|
|
107
|
+
export function generateSmartPreset(db, toolsetMap, projectPath = process.cwd()) {
|
|
108
|
+
const projectContext = detectProject(projectPath);
|
|
109
|
+
const presets = createPresets(toolsetMap);
|
|
110
|
+
const availableToolsets = Object.keys(toolsetMap);
|
|
111
|
+
// Gather empirical data
|
|
112
|
+
const toolsetStats = getToolsetUsageStats(db, projectPath, 30);
|
|
113
|
+
const toolStats = getToolUsageStats(db, projectPath, 30);
|
|
114
|
+
const failingToolsRaw = getFrequentlyFailingTools(db, projectPath, 30, 2);
|
|
115
|
+
const totalCalls = toolStats.reduce((s, t) => s + t.callCount, 0);
|
|
116
|
+
// Compute 5 signals
|
|
117
|
+
const projectTypeAffinity = computeProjectTypeAffinity(projectContext.projectType);
|
|
118
|
+
const usageBreadth = computeUsageBreadth(toolsetStats, availableToolsets.length);
|
|
119
|
+
const specializedDepth = computeSpecializedDepth(toolsetStats, totalCalls);
|
|
120
|
+
const failurePenalty = computeFailurePenalty(failingToolsRaw, totalCalls);
|
|
121
|
+
const historyWeight = computeHistoryWeight(totalCalls);
|
|
122
|
+
const signals = {
|
|
123
|
+
projectTypeAffinity,
|
|
124
|
+
usageBreadth,
|
|
125
|
+
specializedDepth,
|
|
126
|
+
failurePenalty,
|
|
127
|
+
historyWeight,
|
|
128
|
+
};
|
|
129
|
+
// Weighted score: blend static (project type) with empirical signals
|
|
130
|
+
// When history is low, project type dominates. When history is rich, usage dominates.
|
|
131
|
+
const empiricalBlend = historyWeight; // 0 = no history, 1 = trust history fully
|
|
132
|
+
const staticScore = projectTypeAffinity;
|
|
133
|
+
const empiricalScore = (usageBreadth * W_USAGE_BREADTH + specializedDepth * W_SPECIALIZED_DEPTH + historyWeight * W_HISTORY)
|
|
134
|
+
/ (W_USAGE_BREADTH + W_SPECIALIZED_DEPTH + W_HISTORY);
|
|
135
|
+
// Normalize: simple weighted average where empirical grows with history
|
|
136
|
+
const score = Math.min(staticScore * (1 - empiricalBlend) + empiricalScore * empiricalBlend, 1.0);
|
|
137
|
+
// Decision
|
|
138
|
+
const preset = score > SCORE_THRESHOLD ? 'full' : 'default';
|
|
139
|
+
// Confidence: higher with more history, penalized by failures
|
|
140
|
+
const baseConfidence = historyWeight > 0
|
|
141
|
+
? 0.6 + historyWeight * 0.35 // 0.6 → 0.95 as history grows
|
|
142
|
+
: 0.5 + projectTypeAffinity * 0.3; // 0.5 → 0.8 for static-only
|
|
143
|
+
const confidence = Math.max(0.3, baseConfidence - failurePenalty * 0.2);
|
|
144
|
+
// Build reason
|
|
145
|
+
const reason = buildReason(preset, signals, projectContext, totalCalls);
|
|
146
|
+
// Build suggested toolsets: default + project-type extras + actually-used specialized
|
|
147
|
+
const extras = PROJECT_TYPE_EXTRAS[projectContext.projectType] || [];
|
|
148
|
+
const usedSpecialized = toolsetStats
|
|
149
|
+
.filter(ts => !DEFAULT_TOOLSET_SET.has(ts.toolset) && ts.totalCalls > 0)
|
|
150
|
+
.map(ts => ts.toolset);
|
|
151
|
+
const suggestedToolsets = [...new Set([...DEFAULT_TOOLSETS, ...extras, ...usedSpecialized])];
|
|
152
|
+
const optionalToolsets = SPECIALIZED_TOOLSETS.filter(ts => !suggestedToolsets.includes(ts));
|
|
153
|
+
// Usage insights
|
|
154
|
+
const mostUsedToolsets = toolsetStats
|
|
155
|
+
.filter(ts => ts.totalCalls > 0)
|
|
156
|
+
.sort((a, b) => b.totalCalls - a.totalCalls)
|
|
157
|
+
.map(ts => ts.toolset)
|
|
158
|
+
.slice(0, 5);
|
|
159
|
+
const usedSet = new Set(toolsetStats.filter(ts => ts.totalCalls > 0).map(ts => ts.toolset));
|
|
160
|
+
const unusedToolsets = availableToolsets.filter(ts => !usedSet.has(ts));
|
|
161
|
+
return {
|
|
162
|
+
preset,
|
|
163
|
+
reason,
|
|
164
|
+
confidence: Math.round(confidence * 100) / 100,
|
|
165
|
+
score: Math.round(score * 1000) / 1000,
|
|
166
|
+
suggestedToolsets,
|
|
167
|
+
optionalToolsets,
|
|
168
|
+
projectContext,
|
|
169
|
+
usageInsights: {
|
|
170
|
+
mostUsedToolsets,
|
|
171
|
+
unusedToolsets,
|
|
172
|
+
frequentlyFailingTools: failingToolsRaw.map(t => ({
|
|
173
|
+
name: t.toolName,
|
|
174
|
+
failures: t.failureCount,
|
|
175
|
+
lastError: t.lastError,
|
|
176
|
+
})),
|
|
177
|
+
totalCallsLast30d: totalCalls,
|
|
178
|
+
uniqueToolsetsUsed: toolsetStats.filter(ts => ts.totalCalls > 0).length,
|
|
179
|
+
},
|
|
180
|
+
signals,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
function buildReason(preset, signals, ctx, totalCalls) {
|
|
184
|
+
const parts = [];
|
|
185
|
+
if (totalCalls === 0) {
|
|
186
|
+
parts.push(`No usage history yet.`);
|
|
187
|
+
if (preset === 'full') {
|
|
188
|
+
parts.push(`Project type (${ctx.projectType}) suggests specialized toolsets would help.`);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
parts.push(`Project type (${ctx.projectType}) aligns with default preset.`);
|
|
192
|
+
}
|
|
193
|
+
parts.push(`As you use more tools, this recommendation will improve.`);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
parts.push(`Based on ${totalCalls} tool calls across ${signals.historyWeight > 0.5 ? 'rich' : 'limited'} history.`);
|
|
197
|
+
if (signals.specializedDepth > 0.3) {
|
|
198
|
+
parts.push(`${(signals.specializedDepth * 100).toFixed(0)}% of calls use specialized (non-default) toolsets.`);
|
|
199
|
+
}
|
|
200
|
+
if (signals.usageBreadth > 0.4) {
|
|
201
|
+
parts.push(`Broad toolset usage detected across ${(signals.usageBreadth * 100).toFixed(0)}% of available toolsets.`);
|
|
202
|
+
}
|
|
203
|
+
if (preset === 'full') {
|
|
204
|
+
parts.push(`Full preset recommended for comprehensive coverage.`);
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
parts.push(`Default preset covers your current usage patterns.`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (signals.failurePenalty > 0.1) {
|
|
211
|
+
parts.push(`Note: ${(signals.failurePenalty * 100).toFixed(0)}% failure rate detected - check failing tools below.`);
|
|
212
|
+
}
|
|
213
|
+
return parts.join(' ');
|
|
214
|
+
}
|
|
215
|
+
// ── Preset listing ──────────────────────────────────────────────────────
|
|
216
|
+
export function getPresetConfig(preset, toolsetMap) {
|
|
217
|
+
return createPresets(toolsetMap)[preset];
|
|
218
|
+
}
|
|
219
|
+
export function listPresets(toolsetMap) {
|
|
220
|
+
const presets = createPresets(toolsetMap);
|
|
221
|
+
const THEMED_PRESETS = [
|
|
222
|
+
{ name: 'web_dev', extras: ['ui_capture', 'vision', 'web', 'seo', 'git_workflow', 'architect'], description: 'Web projects — adds visual QA, SEO audit, git workflow, code architecture' },
|
|
223
|
+
{ name: 'research', extras: ['web', 'llm', 'rss', 'email', 'docs'], description: 'Research workflows — adds web search, LLM calls, RSS feeds, email, docs' },
|
|
224
|
+
{ name: 'data', extras: ['local_file', 'llm', 'web'], description: 'Data analysis — adds CSV/XLSX/PDF/JSON parsing, LLM extraction, web fetch' },
|
|
225
|
+
{ name: 'devops', extras: ['git_workflow', 'session_memory', 'benchmark', 'pattern'], description: 'CI/CD & ops — adds git compliance, session memory, benchmarks, pattern mining' },
|
|
226
|
+
{ name: 'mobile', extras: ['ui_capture', 'vision', 'flicker_detection'], description: 'Mobile apps — adds screenshot capture, vision analysis, flicker detection' },
|
|
227
|
+
{ name: 'academic', extras: ['research_writing', 'llm', 'web', 'local_file'], description: 'Academic papers — adds polish, review, translate, logic check, data analysis' },
|
|
228
|
+
{ name: 'multi_agent', extras: ['parallel', 'self_eval', 'session_memory', 'pattern', 'toon'], description: 'Multi-agent teams — adds task locking, messaging, roles, oracle testing' },
|
|
229
|
+
{ name: 'content', extras: ['llm', 'critter', 'email', 'rss', 'platform', 'architect'], description: 'Content & publishing — adds LLM, accountability, email, RSS, platform queue' },
|
|
230
|
+
];
|
|
231
|
+
const result = [
|
|
232
|
+
{
|
|
233
|
+
name: 'default',
|
|
234
|
+
toolsets: presets.default.toolsets,
|
|
235
|
+
toolCount: presets.default.toolCount,
|
|
236
|
+
description: 'Core AI Flywheel methodology — verification, eval, quality gates, learning, recon, security, boilerplate',
|
|
237
|
+
},
|
|
238
|
+
];
|
|
239
|
+
for (const themed of THEMED_PRESETS) {
|
|
240
|
+
const toolsets = [...DEFAULT_TOOLSETS, ...themed.extras];
|
|
241
|
+
result.push({
|
|
242
|
+
name: themed.name,
|
|
243
|
+
toolsets,
|
|
244
|
+
toolCount: calculateToolsetCount(toolsets, toolsetMap),
|
|
245
|
+
description: themed.description,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
result.push({
|
|
249
|
+
name: 'full',
|
|
250
|
+
toolsets: presets.full.toolsets,
|
|
251
|
+
toolCount: presets.full.toolCount,
|
|
252
|
+
description: `All ${presets.full.toolCount} tools across ${Object.keys(toolsetMap).length} toolsets — complete coverage`,
|
|
253
|
+
});
|
|
254
|
+
return result;
|
|
255
|
+
}
|
|
256
|
+
// ── Formatted output ────────────────────────────────────────────────────
|
|
257
|
+
export function formatPresetRecommendation(recommendation, toolsetMap) {
|
|
258
|
+
const lines = [];
|
|
259
|
+
const { signals: s, usageInsights: u, projectContext: p } = recommendation;
|
|
260
|
+
lines.push(`\n=== Smart Preset Recommendation ===\n`);
|
|
261
|
+
lines.push(` Preset: ${recommendation.preset.toUpperCase()}`);
|
|
262
|
+
lines.push(` Confidence: ${(recommendation.confidence * 100).toFixed(0)}%`);
|
|
263
|
+
lines.push(` Score: ${recommendation.score.toFixed(3)} (threshold: ${SCORE_THRESHOLD})\n`);
|
|
264
|
+
lines.push(` ${recommendation.reason}`);
|
|
265
|
+
// Signal breakdown
|
|
266
|
+
lines.push(`\n--- Signal Breakdown ---`);
|
|
267
|
+
lines.push(` Project Type Affinity: ${(s.projectTypeAffinity * 100).toFixed(0)}% (${p.projectType}/${p.language}${p.framework ? '/' + p.framework : ''})`);
|
|
268
|
+
lines.push(` Usage Breadth: ${(s.usageBreadth * 100).toFixed(0)}% (${u.uniqueToolsetsUsed}/${Object.keys(toolsetMap).length} toolsets used)`);
|
|
269
|
+
lines.push(` Specialized Depth: ${(s.specializedDepth * 100).toFixed(0)}% (non-default call share)`);
|
|
270
|
+
lines.push(` History Weight: ${(s.historyWeight * 100).toFixed(0)}% (${u.totalCallsLast30d} calls in 30d)`);
|
|
271
|
+
lines.push(` Failure Penalty: ${(s.failurePenalty * 100).toFixed(0)}%`);
|
|
272
|
+
// Project context
|
|
273
|
+
lines.push(`\n--- Project ---`);
|
|
274
|
+
lines.push(` Type: ${p.projectType} | Language: ${p.language}${p.framework ? ' | Framework: ' + p.framework : ''}`);
|
|
275
|
+
lines.push(` Tests: ${p.hasTests ? 'Yes' : 'No'} | CI: ${p.hasCI ? 'Yes' : 'No'} | Files: ${p.fileCount}`);
|
|
276
|
+
// Suggested toolsets
|
|
277
|
+
lines.push(`\n--- Suggested Toolsets (${calculateToolsetCount(recommendation.suggestedToolsets, toolsetMap)} tools) ---`);
|
|
278
|
+
lines.push(` ${recommendation.suggestedToolsets.join(', ')}`);
|
|
279
|
+
// Usage insights
|
|
280
|
+
if (u.mostUsedToolsets.length > 0) {
|
|
281
|
+
lines.push(`\n--- Most Used (30d) ---`);
|
|
282
|
+
lines.push(` ${u.mostUsedToolsets.join(', ')}`);
|
|
283
|
+
}
|
|
284
|
+
// Failing tools warnings
|
|
285
|
+
if (u.frequentlyFailingTools.length > 0) {
|
|
286
|
+
lines.push(`\n--- Failing Tools (action required) ---`);
|
|
287
|
+
for (const t of u.frequentlyFailingTools) {
|
|
288
|
+
lines.push(` ! ${t.name}: ${t.failures} failures${t.lastError ? ' - ' + t.lastError.slice(0, 80) : ''}`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
// How to apply
|
|
292
|
+
lines.push(`\n--- Apply ---`);
|
|
293
|
+
lines.push(` npx nodebench-mcp --preset ${recommendation.preset}`);
|
|
294
|
+
if (recommendation.suggestedToolsets.length > DEFAULT_TOOLSETS.length) {
|
|
295
|
+
lines.push(` npx nodebench-mcp --toolsets ${recommendation.suggestedToolsets.join(',')}`);
|
|
296
|
+
}
|
|
297
|
+
lines.push('');
|
|
298
|
+
return lines.join('\n');
|
|
299
|
+
}
|
|
300
|
+
//# sourceMappingURL=smartPreset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smartPreset.js","sourceRoot":"","sources":["../../src/analytics/smartPreset.ts"],"names":[],"mappings":"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"}
|