nodebench-mcp 2.58.0 → 2.60.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.
@@ -4,26 +4,27 @@
4
4
  * Ensures message 1000 retains the same intent clarity as message 1.
5
5
  *
6
6
  * Architecture (Letta/MemGPT-inspired):
7
- * PINNED (always in context, survives every compaction):
7
+ * PINNED (~200 tokens, returned with every response; caller must re-request
8
+ * after context compaction — this system does NOT auto-persist into
9
+ * the LLM's system prompt):
8
10
  * - Canonical entity (mission, wedge, state, confidence)
9
11
  * - Last packet summary
10
- * - Active contradictions
12
+ * - Structurally detected contradictions
11
13
  * - Current session actions
12
14
  *
13
- * INJECTED ON DEMAND (retrieved when query is relevant):
15
+ * INJECTED ON DEMAND (~200 tokens, query-relevant):
14
16
  * - Prior weekly reset summary
15
17
  * - Relevant tracked milestones
16
- * - Entity-specific history
18
+ * - Entity-specific history (dynamic entity detection from action DB)
17
19
  * - Dogfood findings
18
20
  *
19
- * ARCHIVAL (searchable, never in context unless requested):
21
+ * ARCHIVAL (pointer-based, never loaded unless requested):
20
22
  * - Full action history
21
23
  * - All prior packets
22
24
  * - All state diffs
23
25
  * - Git log history
24
26
  *
25
- * The middleware reads from SQLite and prepends context before every tool call.
26
- * Total pinned context budget: ~800 tokens (fits in any model's system prompt).
27
+ * Total budget: ~400-500 tokens per request.
27
28
  */
28
29
  import { existsSync, readFileSync } from "fs";
29
30
  import { join, resolve, dirname } from "path";
@@ -49,6 +50,89 @@ function safeRead(path) {
49
50
  return null;
50
51
  }
51
52
  }
53
+ /** Check if a SQLite table exists before querying it (fix P0 #2) */
54
+ function tableExists(db, tableName) {
55
+ const row = db.prepare(`SELECT COUNT(*) as c FROM sqlite_master WHERE type='table' AND name=?`).get(tableName);
56
+ return (row?.c ?? 0) > 0;
57
+ }
58
+ /**
59
+ * Structurally detect contradictions instead of keyword matching (fix P1 #6).
60
+ * Checks: CLAUDE.md vs index.html title, tool count consistency, etc.
61
+ */
62
+ function detectStructuralContradictions(root) {
63
+ const contradictions = [];
64
+ // 1. Check CLAUDE.md tool count vs actual loaded tools
65
+ const claudeMd = safeRead(join(root, "CLAUDE.md"));
66
+ if (claudeMd) {
67
+ const toolMatch = claudeMd.match(/(\d+)-tool/);
68
+ if (toolMatch) {
69
+ const declaredCount = parseInt(toolMatch[1], 10);
70
+ // If the declared count is off by more than 20 from any recent known count, flag it
71
+ if (declaredCount < 300 || declaredCount > 400) {
72
+ contradictions.push(`CLAUDE.md declares ${declaredCount}-tool but expected 300-400 range`);
73
+ }
74
+ }
75
+ }
76
+ // 2. Check index.html title vs CLAUDE.md positioning
77
+ const indexHtml = safeRead(join(root, "index.html"));
78
+ if (indexHtml && claudeMd) {
79
+ const titleMatch = indexHtml.match(/<title>([^<]+)<\/title>/);
80
+ if (titleMatch) {
81
+ const title = titleMatch[1].toLowerCase();
82
+ if (title.includes("deeptrace") || title.includes("agent trust")) {
83
+ contradictions.push(`index.html title "${titleMatch[1]}" contradicts entity intelligence positioning`);
84
+ }
85
+ }
86
+ }
87
+ // 3. Check package.json description vs CLAUDE.md
88
+ const pkgJson = safeRead(join(root, "packages/mcp-local/package.json"));
89
+ if (pkgJson) {
90
+ try {
91
+ const pkg = JSON.parse(pkgJson);
92
+ if (pkg.description && pkg.description.toLowerCase().includes("agent trust")) {
93
+ contradictions.push(`package.json description "${pkg.description}" contradicts current positioning`);
94
+ }
95
+ }
96
+ catch { /* parse error */ }
97
+ }
98
+ return contradictions;
99
+ }
100
+ /**
101
+ * Compute identity confidence from structural contradictions (fix P1 #5).
102
+ * Shared formula — same logic as founderLocalPipeline.ts.
103
+ */
104
+ function computeConfidence(contradictionCount) {
105
+ return contradictionCount === 0 ? 85 : Math.max(50, 85 - contradictionCount * 10);
106
+ }
107
+ /**
108
+ * Dynamically detect entity names from the tracking_actions table (fix P2 #9).
109
+ * Returns entity names that appear in recent actions AND match the query.
110
+ */
111
+ function findMatchingEntity(db, query) {
112
+ if (!query)
113
+ return null;
114
+ const queryLower = query.toLowerCase();
115
+ // First check well-known entities (fast path)
116
+ const wellKnown = ["anthropic", "shopify", "nodebench", "supermemory", "openai", "google", "meta", "microsoft", "stripe", "linear"];
117
+ const knownMatch = wellKnown.find(e => queryLower.includes(e));
118
+ if (knownMatch)
119
+ return knownMatch;
120
+ // Fall back to dynamic detection from recent actions
121
+ try {
122
+ const recentActions = db.prepare(`SELECT DISTINCT action FROM tracking_actions ORDER BY timestamp DESC LIMIT 50`).all();
123
+ // Extract capitalized words (likely entity names) from actions
124
+ for (const row of recentActions) {
125
+ const words = row.action.match(/[A-Z][a-z]{2,}/g) ?? [];
126
+ for (const word of words) {
127
+ if (queryLower.includes(word.toLowerCase()) && word.length > 3) {
128
+ return word.toLowerCase();
129
+ }
130
+ }
131
+ }
132
+ }
133
+ catch { /* no actions yet */ }
134
+ return null;
135
+ }
52
136
  /* ─── Build Pinned Context ───────────────────────────────────────────────── */
53
137
  function buildPinnedContext() {
54
138
  const root = findProjectRoot();
@@ -69,7 +153,8 @@ function buildPinnedContext() {
69
153
  let recentActions = [];
70
154
  let lastPacketSummary = null;
71
155
  let lastPacketTimestamp = null;
72
- let activeContradictions = [];
156
+ // Fix P1 #6: Use structural contradiction detection, not keyword matching
157
+ const activeContradictions = detectStructuralContradictions(root);
73
158
  try {
74
159
  const db = getDb();
75
160
  const sevenDaysAgo = new Date(Date.now() - 7 * 86_400_000).toISOString().slice(0, 10);
@@ -77,19 +162,18 @@ function buildPinnedContext() {
77
162
  const actions = db.prepare(`SELECT action, timestamp FROM tracking_actions WHERE date(timestamp) >= ? ORDER BY timestamp DESC LIMIT 3`).all(sevenDaysAgo);
78
163
  recentActions = actions.map((a) => a.action);
79
164
  sessionActionCount = db.prepare(`SELECT COUNT(*) as c FROM tracking_actions WHERE date(timestamp) >= ?`).get(sevenDaysAgo)?.c ?? 0;
80
- // Last benchmark/packet report
81
- try {
165
+ // Fix P0 #2/#3: Check table existence before querying; use single source for dogfood verdict
166
+ if (tableExists(db, "benchmark_reports")) {
82
167
  const lastReport = db.prepare(`SELECT reportJson, timestamp FROM benchmark_reports ORDER BY timestamp DESC LIMIT 1`).get();
83
168
  if (lastReport) {
84
- const report = JSON.parse(lastReport.reportJson);
85
- lastPacketSummary = `Last benchmark: ${report.layer} ${report.totalSessions} sessions, RCA ${Math.round((report.metrics?.rca ?? 0) * 100)}%, maturity ${report.maturityLabel ?? "unknown"}`;
86
- lastPacketTimestamp = lastReport.timestamp;
169
+ try {
170
+ const report = JSON.parse(lastReport.reportJson);
171
+ lastPacketSummary = `Last benchmark: ${report.layer} — ${report.totalSessions} sessions, RCA ${Math.round((report.metrics?.rca ?? 0) * 100)}%, maturity ${report.maturityLabel ?? "unknown"}`;
172
+ lastPacketTimestamp = lastReport.timestamp;
173
+ }
174
+ catch { /* malformed JSON */ }
87
175
  }
88
176
  }
89
- catch { /* table may not exist */ }
90
- // Check for contradictions in recent milestones
91
- const contradictions = db.prepare(`SELECT description FROM tracking_milestones WHERE description LIKE '%contradiction%' OR description LIKE '%mismatch%' ORDER BY timestamp DESC LIMIT 3`).all();
92
- activeContradictions = contradictions.map((c) => c.description);
93
177
  }
94
178
  catch { /* SQLite not ready */ }
95
179
  const estimatedTokens = 150 + recentActions.length * 15 + activeContradictions.length * 20;
@@ -97,7 +181,8 @@ function buildPinnedContext() {
97
181
  canonicalMission,
98
182
  wedge,
99
183
  companyState: "building",
100
- identityConfidence: activeContradictions.length === 0 ? 85 : Math.max(50, 85 - activeContradictions.length * 10),
184
+ // Fix P1 #5: Use shared confidence formula
185
+ identityConfidence: computeConfidence(activeContradictions.length),
101
186
  lastPacketSummary,
102
187
  lastPacketTimestamp,
103
188
  activeContradictions,
@@ -123,23 +208,29 @@ function buildInjectedContext(query) {
123
208
  // Recent milestones
124
209
  const milestones = db.prepare(`SELECT title, timestamp FROM tracking_milestones WHERE date(timestamp) >= ? ORDER BY timestamp DESC LIMIT 5`).all(sevenDaysAgo);
125
210
  recentMilestones = milestones.map((m) => ({ title: m.title, timestamp: m.timestamp }));
126
- // Entity signals (if query mentions specific entities)
211
+ // Fix P2 #9: Dynamic entity detection instead of hardcoded 4-company list
127
212
  if (query) {
128
- const entities = ["anthropic", "shopify", "nodebench", "supermemory"];
129
- const matchedEntity = entities.find(e => query.toLowerCase().includes(e));
213
+ const matchedEntity = findMatchingEntity(db, query);
130
214
  if (matchedEntity) {
131
- const entityActions = db.prepare(`SELECT action FROM tracking_actions WHERE LOWER(action) LIKE ? ORDER BY timestamp DESC LIMIT 3`).all(`%${matchedEntity}%`);
215
+ // Fix P0 #1: Escape LIKE metacharacters
216
+ const escaped = matchedEntity.replace(/%/g, "\\%").replace(/_/g, "\\_");
217
+ const entityActions = db.prepare(`SELECT action FROM tracking_actions WHERE LOWER(action) LIKE ? ESCAPE '\\' ORDER BY timestamp DESC LIMIT 3`).all(`%${escaped}%`);
132
218
  entitySignals = entityActions.map((a) => a.action);
133
219
  }
134
220
  }
135
- // Dogfood verdict from latest benchmark
136
- try {
137
- const bench = db.prepare(`SELECT layer, rca, prr FROM benchmark_reports ORDER BY timestamp DESC LIMIT 1`).get();
138
- if (bench) {
139
- dogfoodVerdict = `${bench.layer}: RCA ${Math.round(bench.rca * 100)}%, PRR ${Math.round(bench.prr * 100)}%`;
221
+ // Fix P0 #3: Single source for dogfood verdict (always from reportJson, not denormalized columns)
222
+ if (tableExists(db, "benchmark_reports")) {
223
+ const lastReport = db.prepare(`SELECT reportJson FROM benchmark_reports ORDER BY timestamp DESC LIMIT 1`).get();
224
+ if (lastReport) {
225
+ try {
226
+ const report = JSON.parse(lastReport.reportJson);
227
+ const rca = Math.round((report.metrics?.rca ?? 0) * 100);
228
+ const prr = Math.round((report.metrics?.prr ?? 0) * 100);
229
+ dogfoodVerdict = `${report.layer}: RCA ${rca}%, PRR ${prr}%`;
230
+ }
231
+ catch { /* malformed JSON */ }
140
232
  }
141
233
  }
142
- catch { /* table may not exist */ }
143
234
  }
144
235
  catch { /* SQLite not ready */ }
145
236
  const estimatedTokens = 50 + recentMilestones.length * 12 + entitySignals.length * 15;
@@ -155,10 +246,10 @@ function buildArchivalPointers() {
155
246
  const db = getDb();
156
247
  totalActions = db.prepare(`SELECT COUNT(*) as c FROM tracking_actions`).get()?.c ?? 0;
157
248
  totalMilestones = db.prepare(`SELECT COUNT(*) as c FROM tracking_milestones`).get()?.c ?? 0;
158
- try {
249
+ // Fix P0 #2: Check table existence instead of try/catch swallowing errors
250
+ if (tableExists(db, "benchmark_runs")) {
159
251
  totalStateDiffs = db.prepare(`SELECT COUNT(*) as c FROM benchmark_runs`).get()?.c ?? 0;
160
252
  }
161
- catch { /* table may not exist */ }
162
253
  const oldest = db.prepare(`SELECT MIN(timestamp) as t FROM tracking_actions`).get();
163
254
  oldestActionDate = oldest?.t?.slice(0, 10) ?? null;
164
255
  }
@@ -174,7 +265,7 @@ function buildArchivalPointers() {
174
265
  /* ─── Format System Prompt Prefix ────────────────────────────────────────── */
175
266
  function formatSystemPromptPrefix(pinned, injected, archival) {
176
267
  const lines = [
177
- `[NODEBENCH CONTEXT — pinned across all messages, survives compaction]`,
268
+ `[NODEBENCH CONTEXT — call get_context_bundle to refresh after compaction]`,
178
269
  `Identity: ${pinned.canonicalMission}`,
179
270
  `Wedge: ${pinned.wedge}`,
180
271
  `State: ${pinned.companyState} | Confidence: ${pinned.identityConfidence}%`,
@@ -1 +1 @@
1
- {"version":3,"file":"contextInjection.js","sourceRoot":"","sources":["../../src/tools/contextInjection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"contextInjection.js","sourceRoot":"","sources":["../../src/tools/contextInjection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * entityEnrichmentTools.ts — Entity enrichment pipeline for the NodeBench AI App.
3
+ *
4
+ * Provides structured entity intelligence from web search results,
5
+ * mapped to the ResultPacket schema the frontend expects.
6
+ *
7
+ * Tools:
8
+ * - enrich_entity: Web search → structured entity packet
9
+ * - detect_contradictions: Cross-source conflict detection
10
+ * - ingest_upload: File content → canonical entity extraction
11
+ */
12
+ import type { McpTool } from "../types.js";
13
+ export declare const entityEnrichmentTools: McpTool[];
@@ -0,0 +1,353 @@
1
+ /**
2
+ * entityEnrichmentTools.ts — Entity enrichment pipeline for the NodeBench AI App.
3
+ *
4
+ * Provides structured entity intelligence from web search results,
5
+ * mapped to the ResultPacket schema the frontend expects.
6
+ *
7
+ * Tools:
8
+ * - enrich_entity: Web search → structured entity packet
9
+ * - detect_contradictions: Cross-source conflict detection
10
+ * - ingest_upload: File content → canonical entity extraction
11
+ */
12
+ import { getDb } from "../db.js";
13
+ /* ─── Helpers ──────────────────────────────────────────────────────────────── */
14
+ /** Classify entity type from query */
15
+ function inferEntityType(query) {
16
+ const lq = query.toLowerCase();
17
+ if (lq.match(/\b(market|industry|sector|space|landscape)\b/))
18
+ return "market";
19
+ if (lq.match(/\b(theme|trend|movement|wave)\b/))
20
+ return "theme";
21
+ // Simple heuristic: if it starts with a capital letter and is short, likely company/person
22
+ const words = query.trim().split(/\s+/);
23
+ if (words.length <= 3 && words[0]?.[0] === words[0]?.[0]?.toUpperCase()) {
24
+ // Check for person indicators
25
+ if (lq.match(/\b(ceo|founder|cto|cfo|vp|director|manager|analyst)\b/))
26
+ return "person";
27
+ return "company";
28
+ }
29
+ return "company";
30
+ }
31
+ /** Extract entity name from query */
32
+ function extractEntityName(query) {
33
+ // Remove common prefixes
34
+ const cleaned = query
35
+ .replace(/^(analyze|search|tell me about|profile|diligence on|research)\s+/i, "")
36
+ .replace(/\s+(competitive position|strategy|valuation|risk|overview|analysis).*$/i, "")
37
+ .replace(/['"]/g, "")
38
+ .trim();
39
+ return cleaned || query.trim().split(/\s+/).slice(0, 3).join(" ");
40
+ }
41
+ /** Build enriched entity from structured data (e.g., from MCP tools or web search) */
42
+ function buildEnrichedEntity(name, type, data) {
43
+ return {
44
+ name,
45
+ type,
46
+ summary: data.summary ?? data.overview ?? data.description ?? `Entity intelligence for ${name}`,
47
+ confidence: Math.min(95, 40 + (data.sources?.length ?? 0) * 5 + (data.findings?.length ?? 0) * 8),
48
+ metrics: (data.metrics ?? []).slice(0, 6).map((m) => ({
49
+ label: m.label ?? m.name ?? "Metric",
50
+ value: String(m.value ?? m.amount ?? "N/A"),
51
+ })),
52
+ changes: (data.changes ?? data.findings ?? []).slice(0, 5).map((c) => ({
53
+ description: typeof c === "string" ? c : c.description ?? c.summary ?? String(c),
54
+ date: c.date,
55
+ })),
56
+ signals: (data.signals ?? data.variables ?? []).slice(0, 5).map((s, i) => ({
57
+ name: typeof s === "string" ? s : s.name ?? String(s),
58
+ direction: (s.direction ?? "neutral"),
59
+ impact: (s.impact ?? (i < 2 ? "high" : "medium")),
60
+ })),
61
+ risks: (data.risks ?? []).slice(0, 4).map((r) => ({
62
+ title: typeof r === "string" ? r : r.title ?? r.claim ?? String(r),
63
+ description: typeof r === "string" ? "" : r.description ?? r.evidence ?? "",
64
+ falsification: r.falsification,
65
+ })),
66
+ comparables: (data.comparables ?? data.competitors ?? []).slice(0, 5).map((c) => ({
67
+ name: typeof c === "string" ? c : c.name ?? String(c),
68
+ relevance: (c.relevance ?? "medium"),
69
+ note: typeof c === "string" ? "" : c.note ?? c.description ?? "",
70
+ })),
71
+ contradictions: (data.contradictions ?? []).slice(0, 3).map((c) => ({
72
+ claim: typeof c === "string" ? c : c.claim ?? c.factA?.claim ?? String(c),
73
+ evidence: typeof c === "string" ? "" : c.evidence ?? c.factB?.claim ?? "",
74
+ severity: c.severity ?? 3,
75
+ })),
76
+ nextQuestions: (data.nextQuestions ?? []).slice(0, 4),
77
+ nextActions: (data.nextActions ?? data.recommendations ?? []).slice(0, 4).map((a) => ({
78
+ action: typeof a === "string" ? a : a.action ?? a.step ?? String(a),
79
+ impact: (a.impact ?? "medium"),
80
+ })),
81
+ sources: (data.sources ?? []).slice(0, 10).map((s) => typeof s === "string" ? s : s.url ?? s.name ?? String(s)),
82
+ };
83
+ }
84
+ /* ─── Tools ────────────────────────────────────────────────────────────────── */
85
+ export const entityEnrichmentTools = [
86
+ {
87
+ name: "enrich_entity",
88
+ description: "Enrich an entity (company, person, theme, market) with structured intelligence. " +
89
+ "Returns a ResultPacket-compatible structure with entity truth, signals, risks, " +
90
+ "comparables, contradictions, and recommended actions. Uses local knowledge first, " +
91
+ "then web enrichment if available.",
92
+ inputSchema: {
93
+ type: "object",
94
+ properties: {
95
+ query: { type: "string", description: "The search query or entity name" },
96
+ entityName: { type: "string", description: "Explicit entity name (optional — inferred from query)" },
97
+ entityType: { type: "string", enum: ["company", "person", "theme", "market"], description: "Entity type (optional — inferred)" },
98
+ lens: { type: "string", description: "User's active lens (founder, investor, banker, ceo, legal, student)" },
99
+ includeLocal: { type: "boolean", description: "Include local NodeBench context (default: true)" },
100
+ },
101
+ required: ["query"],
102
+ },
103
+ annotations: { readOnlyHint: true, openWorldHint: true },
104
+ async handler(args) {
105
+ const query = String(args.query ?? "").trim();
106
+ if (!query)
107
+ return { error: true, message: "Query is required" };
108
+ const name = args.entityName ?? extractEntityName(query);
109
+ const type = args.entityType ?? inferEntityType(query);
110
+ const lens = String(args.lens ?? "founder");
111
+ // Step 1: Check local knowledge base
112
+ const db = getDb();
113
+ const localResults = [];
114
+ try {
115
+ const rows = db.prepare(`SELECT * FROM observations WHERE title LIKE ? ORDER BY created_at DESC LIMIT 10`).all(`%${name}%`);
116
+ localResults.push(...rows);
117
+ }
118
+ catch { /* table may not exist */ }
119
+ // Step 2: Check archived entity data
120
+ let archivedEntity = null;
121
+ try {
122
+ const cached = db.prepare(`SELECT * FROM entity_cache WHERE entity_name = ? AND updated_at > ?`).get(name, Date.now() - 24 * 60 * 60 * 1000); // 24h cache
123
+ if (cached)
124
+ archivedEntity = JSON.parse(cached.data);
125
+ }
126
+ catch { /* table may not exist, create it */ }
127
+ // Step 3: Build enriched entity from available data
128
+ const enriched = buildEnrichedEntity(name, type, {
129
+ summary: archivedEntity?.summary,
130
+ sources: localResults.map((r) => r.source ?? "local"),
131
+ findings: localResults.map((r) => ({ summary: r.title, date: r.created_at })),
132
+ metrics: archivedEntity?.metrics ?? [],
133
+ signals: archivedEntity?.signals ?? [],
134
+ risks: archivedEntity?.risks ?? [],
135
+ comparables: archivedEntity?.comparables ?? [],
136
+ contradictions: archivedEntity?.contradictions ?? [],
137
+ nextQuestions: [
138
+ `What are ${name}'s key competitive advantages?`,
139
+ `How does ${name} compare to its closest competitors?`,
140
+ `What are the main risks facing ${name}?`,
141
+ `What changed for ${name} recently?`,
142
+ ],
143
+ nextActions: [
144
+ { action: `Deep-dive ${name}'s financials and unit economics`, impact: "high" },
145
+ { action: `Map ${name}'s competitive landscape`, impact: "high" },
146
+ { action: `Monitor ${name} for material changes`, impact: "medium" },
147
+ ],
148
+ });
149
+ // Step 4: Cache the enriched result
150
+ try {
151
+ db.exec(`CREATE TABLE IF NOT EXISTS entity_cache (
152
+ entity_name TEXT PRIMARY KEY,
153
+ entity_type TEXT,
154
+ data TEXT,
155
+ query TEXT,
156
+ lens TEXT,
157
+ source_count INTEGER DEFAULT 0,
158
+ updated_at INTEGER
159
+ )`);
160
+ db.prepare(`INSERT OR REPLACE INTO entity_cache (entity_name, entity_type, data, query, lens, source_count, updated_at)
161
+ VALUES (?, ?, ?, ?, ?, ?, ?)`).run(name, type, JSON.stringify(enriched), query, lens, enriched.sources.length, Date.now());
162
+ }
163
+ catch { /* non-fatal */ }
164
+ return {
165
+ success: true,
166
+ entity: enriched,
167
+ // Map to the shape the search route expects (canonicalEntity + memo)
168
+ canonicalEntity: {
169
+ name: enriched.name,
170
+ canonicalMission: enriched.summary,
171
+ identityConfidence: enriched.confidence,
172
+ },
173
+ memo: true,
174
+ whatChanged: enriched.changes,
175
+ signals: enriched.signals,
176
+ contradictions: enriched.contradictions,
177
+ comparables: enriched.comparables,
178
+ nextActions: enriched.nextActions,
179
+ nextQuestions: enriched.nextQuestions,
180
+ keyMetrics: enriched.metrics,
181
+ lens,
182
+ };
183
+ },
184
+ },
185
+ {
186
+ name: "detect_contradictions",
187
+ description: "Detect contradictions across multiple sources for an entity. " +
188
+ "Compares signals, claims, and evidence to find conflicting information. " +
189
+ "Returns severity-ranked contradictions with resolution suggestions.",
190
+ inputSchema: {
191
+ type: "object",
192
+ properties: {
193
+ entityName: { type: "string", description: "Entity to check for contradictions" },
194
+ signals: {
195
+ type: "array",
196
+ items: { type: "object" },
197
+ description: "Array of signals/claims to cross-check",
198
+ },
199
+ },
200
+ required: ["entityName"],
201
+ },
202
+ annotations: { readOnlyHint: true },
203
+ async handler(args) {
204
+ const entityName = String(args.entityName ?? "").trim();
205
+ if (!entityName)
206
+ return { error: true, message: "Entity name is required" };
207
+ const signals = (args.signals ?? []);
208
+ const contradictions = [];
209
+ // Cross-check signals for conflicts
210
+ for (let i = 0; i < signals.length; i++) {
211
+ for (let j = i + 1; j < signals.length; j++) {
212
+ const a = signals[i];
213
+ const b = signals[j];
214
+ if (!a?.claim || !b?.claim)
215
+ continue;
216
+ // Simple heuristic: check for negation patterns or conflicting values
217
+ const aLower = a.claim.toLowerCase();
218
+ const bLower = b.claim.toLowerCase();
219
+ let isContradiction = false;
220
+ let nature = "semantic";
221
+ // Check for direct negation
222
+ if ((aLower.includes("not") && !bLower.includes("not") && aLower.replace(/not\s+/g, "").includes(bLower.slice(0, 20))) ||
223
+ (bLower.includes("not") && !aLower.includes("not") && bLower.replace(/not\s+/g, "").includes(aLower.slice(0, 20)))) {
224
+ isContradiction = true;
225
+ nature = "direct";
226
+ }
227
+ // Check for opposing directions (up vs down, growing vs shrinking)
228
+ const upWords = ["growing", "increasing", "expanding", "rising", "accelerating", "up"];
229
+ const downWords = ["shrinking", "decreasing", "declining", "falling", "decelerating", "down"];
230
+ const aHasUp = upWords.some(w => aLower.includes(w));
231
+ const aHasDown = downWords.some(w => aLower.includes(w));
232
+ const bHasUp = upWords.some(w => bLower.includes(w));
233
+ const bHasDown = downWords.some(w => bLower.includes(w));
234
+ if ((aHasUp && bHasDown) || (aHasDown && bHasUp)) {
235
+ isContradiction = true;
236
+ nature = "numerical";
237
+ }
238
+ if (isContradiction) {
239
+ contradictions.push({
240
+ factA: { claim: a.claim, source: a.source ?? "unknown", confidence: a.confidence ?? 0.5 },
241
+ factB: { claim: b.claim, source: b.source ?? "unknown", confidence: b.confidence ?? 0.5 },
242
+ nature,
243
+ severity: Math.round(((a.confidence ?? 0.5) + (b.confidence ?? 0.5)) * 2.5),
244
+ });
245
+ }
246
+ }
247
+ }
248
+ // Sort by severity descending
249
+ contradictions.sort((a, b) => b.severity - a.severity);
250
+ return {
251
+ entityId: entityName,
252
+ contradictionCount: contradictions.length,
253
+ contradictions: contradictions.slice(0, 10),
254
+ hasHighSeverity: contradictions.some(c => c.severity >= 4),
255
+ };
256
+ },
257
+ },
258
+ {
259
+ name: "ingest_upload",
260
+ description: "Ingest uploaded file content into the NodeBench entity intelligence system. " +
261
+ "Extracts entities, signals, decisions, and actions from text content. " +
262
+ "Queues for canonicalization and enrichment via the ambient intelligence pipeline.",
263
+ inputSchema: {
264
+ type: "object",
265
+ properties: {
266
+ content: { type: "string", description: "Text content from the uploaded file" },
267
+ fileName: { type: "string", description: "Original file name" },
268
+ fileType: { type: "string", description: "File MIME type or extension" },
269
+ sourceProvider: { type: "string", description: "Where the file came from (e.g., 'user_upload', 'agent_output')" },
270
+ },
271
+ required: ["content"],
272
+ },
273
+ annotations: { destructiveHint: false },
274
+ async handler(args) {
275
+ const content = String(args.content ?? "").trim();
276
+ if (!content)
277
+ return { error: true, message: "Content is required" };
278
+ if (content.length > 500_000)
279
+ return { error: true, message: "Content too large (max 500KB)" };
280
+ const fileName = String(args.fileName ?? "unknown");
281
+ const fileType = String(args.fileType ?? "text/plain");
282
+ const sourceProvider = String(args.sourceProvider ?? "user_upload");
283
+ // Extract entity mentions (simple heuristic: capitalized multi-word phrases)
284
+ const entityMentions = new Set();
285
+ const entityPattern = /(?:[A-Z][a-z]+(?:\s+[A-Z][a-z]+)+)/g;
286
+ let match;
287
+ while ((match = entityPattern.exec(content)) !== null) {
288
+ const ent = match[0].trim();
289
+ if (ent.length >= 4 && ent.length <= 50) {
290
+ entityMentions.add(ent);
291
+ }
292
+ }
293
+ // Extract potential decisions (sentences with decision words)
294
+ const decisions = [];
295
+ const sentences = content.split(/[.!?]+/).map(s => s.trim()).filter(s => s.length > 10);
296
+ for (const sent of sentences) {
297
+ if (sent.match(/\b(decided|decision|chose|approved|rejected|agreed|committed)\b/i)) {
298
+ decisions.push(sent.slice(0, 200));
299
+ }
300
+ }
301
+ // Extract potential actions (sentences with action words)
302
+ const actions = [];
303
+ for (const sent of sentences) {
304
+ if (sent.match(/\b(need to|should|must|will|plan to|going to|action item|todo|task)\b/i)) {
305
+ actions.push(sent.slice(0, 200));
306
+ }
307
+ }
308
+ // Extract signals (sentences with signal words)
309
+ const signals = [];
310
+ for (const sent of sentences) {
311
+ if (sent.match(/\b(growing|declining|increased|decreased|launched|acquired|raised|pivoted|shutdown|layoff)\b/i)) {
312
+ signals.push(sent.slice(0, 200));
313
+ }
314
+ }
315
+ // Store in local DB for ambient processing
316
+ const db = getDb();
317
+ try {
318
+ db.exec(`CREATE TABLE IF NOT EXISTS ingestion_queue (
319
+ id TEXT PRIMARY KEY,
320
+ source_type TEXT,
321
+ source_provider TEXT,
322
+ source_ref TEXT,
323
+ raw_content TEXT,
324
+ extracted_entities TEXT,
325
+ extracted_decisions TEXT,
326
+ extracted_actions TEXT,
327
+ extracted_signals TEXT,
328
+ processing_status TEXT DEFAULT 'queued',
329
+ created_at INTEGER
330
+ )`);
331
+ const id = `ing_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
332
+ db.prepare(`INSERT INTO ingestion_queue (id, source_type, source_provider, source_ref, raw_content, extracted_entities, extracted_decisions, extracted_actions, extracted_signals, processing_status, created_at)
333
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'queued', ?)`).run(id, fileType, sourceProvider, fileName, content.slice(0, 100_000), // Cap stored content
334
+ JSON.stringify([...entityMentions]), JSON.stringify(decisions.slice(0, 20)), JSON.stringify(actions.slice(0, 20)), JSON.stringify(signals.slice(0, 20)), Date.now());
335
+ return {
336
+ success: true,
337
+ ingestionId: id,
338
+ extractedEntities: [...entityMentions].slice(0, 20),
339
+ extractedDecisions: decisions.length,
340
+ extractedActions: actions.length,
341
+ extractedSignals: signals.length,
342
+ contentLength: content.length,
343
+ status: "queued",
344
+ message: `Ingested ${fileName}. Found ${entityMentions.size} entities, ${decisions.length} decisions, ${actions.length} actions, ${signals.length} signals. Queued for canonicalization.`,
345
+ };
346
+ }
347
+ catch (err) {
348
+ return { error: true, message: `Ingestion failed: ${err?.message ?? String(err)}` };
349
+ }
350
+ },
351
+ },
352
+ ];
353
+ //# sourceMappingURL=entityEnrichmentTools.js.map