mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-12 02:37:45 +08:00
refactor: Replace knowledge graph with session clustering system
Remove legacy knowledge graph and evolution tracking features, introduce new session clustering model for Core Memory. Changes: - Remove knowledge_graph, knowledge_graph_edges, evolution_history tables - Add session_clusters, cluster_members, cluster_relations tables - Add session_metadata_cache for metadata caching - Add new interfaces: SessionCluster, ClusterMember, ClusterRelation, SessionMetadataCache - Add CRUD methods for cluster management - Add session metadata upsert and search methods - Remove extractKnowledgeGraph, getKnowledgeGraph, trackEvolution methods - Remove API routes for /knowledge-graph, /evolution, /graph - Add database migration to clean up old tables - Update generateClusterId() for CLST-* ID format Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import * as http from 'http';
|
||||
import { URL } from 'url';
|
||||
import { getCoreMemoryStore } from '../core-memory-store.js';
|
||||
import type { CoreMemory, KnowledgeGraph, EvolutionVersion } from '../core-memory-store.js';
|
||||
import type { CoreMemory } from '../core-memory-store.js';
|
||||
|
||||
/**
|
||||
* Route context interface
|
||||
@@ -197,142 +197,5 @@ export async function handleCoreMemoryRoutes(ctx: RouteContext): Promise<boolean
|
||||
return true;
|
||||
}
|
||||
|
||||
// API: Core Memory - Extract knowledge graph
|
||||
if (pathname.startsWith('/api/core-memory/memories/') && pathname.endsWith('/knowledge-graph') && req.method === 'GET') {
|
||||
const memoryId = pathname.replace('/api/core-memory/memories/', '').replace('/knowledge-graph', '');
|
||||
const projectPath = url.searchParams.get('path') || initialPath;
|
||||
|
||||
try {
|
||||
const store = getCoreMemoryStore(projectPath);
|
||||
const knowledgeGraph = store.getKnowledgeGraph(memoryId);
|
||||
|
||||
// If no graph exists, extract it first
|
||||
if (knowledgeGraph.nodes.length === 0) {
|
||||
const extracted = store.extractKnowledgeGraph(memoryId);
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ success: true, knowledgeGraph: extracted }));
|
||||
} else {
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ success: true, knowledgeGraph }));
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
res.writeHead(500, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ error: (error as Error).message }));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// API: Core Memory - Track evolution history
|
||||
if (pathname.startsWith('/api/core-memory/memories/') && pathname.endsWith('/evolution') && req.method === 'GET') {
|
||||
const memoryId = pathname.replace('/api/core-memory/memories/', '').replace('/evolution', '');
|
||||
const projectPath = url.searchParams.get('path') || initialPath;
|
||||
|
||||
try {
|
||||
const store = getCoreMemoryStore(projectPath);
|
||||
const evolution = store.trackEvolution(memoryId);
|
||||
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ success: true, evolution }));
|
||||
} catch (error: unknown) {
|
||||
res.writeHead(500, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ error: (error as Error).message }));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// API: Core Memory - Get aggregated graph data for graph explorer
|
||||
if (pathname === '/api/core-memory/graph' && req.method === 'GET') {
|
||||
const projectPath = url.searchParams.get('path') || initialPath;
|
||||
|
||||
try {
|
||||
const store = getCoreMemoryStore(projectPath);
|
||||
const memories = store.getMemories({ archived: false });
|
||||
|
||||
// Aggregate all knowledge graphs from memories
|
||||
const aggregatedNodes: Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
type: string;
|
||||
symbol_type?: string;
|
||||
path?: string;
|
||||
line_number?: number;
|
||||
imports?: number;
|
||||
exports?: number;
|
||||
references?: number;
|
||||
}> = [];
|
||||
|
||||
const aggregatedEdges: Array<{
|
||||
source: string;
|
||||
target: string;
|
||||
type: string;
|
||||
weight: number;
|
||||
}> = [];
|
||||
|
||||
const nodeMap = new Map<string, any>();
|
||||
const edgeMap = new Map<string, any>();
|
||||
|
||||
// Collect nodes and edges from all memories
|
||||
memories.forEach((memory: CoreMemory) => {
|
||||
const graph = store.getKnowledgeGraph(memory.id);
|
||||
|
||||
// Process nodes
|
||||
graph.nodes.forEach((node: any) => {
|
||||
const nodeId = node.id || node.name;
|
||||
if (!nodeMap.has(nodeId)) {
|
||||
nodeMap.set(nodeId, {
|
||||
id: nodeId,
|
||||
name: node.name || node.label || nodeId,
|
||||
type: node.type || 'MODULE',
|
||||
symbol_type: node.symbol_type,
|
||||
path: node.path || node.file_path,
|
||||
line_number: node.line_number,
|
||||
imports: node.imports || 0,
|
||||
exports: node.exports || 0,
|
||||
references: node.references || 0
|
||||
});
|
||||
} else {
|
||||
// Aggregate counts for duplicate nodes
|
||||
const existing = nodeMap.get(nodeId);
|
||||
existing.imports = (existing.imports || 0) + (node.imports || 0);
|
||||
existing.exports = (existing.exports || 0) + (node.exports || 0);
|
||||
existing.references = (existing.references || 0) + (node.references || 0);
|
||||
}
|
||||
});
|
||||
|
||||
// Process edges
|
||||
graph.edges.forEach((edge: any) => {
|
||||
const edgeKey = `${edge.source}-${edge.target}-${edge.type || 'CALLS'}`;
|
||||
if (!edgeMap.has(edgeKey)) {
|
||||
edgeMap.set(edgeKey, {
|
||||
source: edge.source || edge.from,
|
||||
target: edge.target || edge.to,
|
||||
type: edge.type || edge.relation_type || 'CALLS',
|
||||
weight: edge.weight || 1
|
||||
});
|
||||
} else {
|
||||
// Aggregate weights for duplicate edges
|
||||
const existing = edgeMap.get(edgeKey);
|
||||
existing.weight = (existing.weight || 1) + (edge.weight || 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Convert maps to arrays
|
||||
aggregatedNodes.push(...nodeMap.values());
|
||||
aggregatedEdges.push(...edgeMap.values());
|
||||
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({
|
||||
success: true,
|
||||
nodes: aggregatedNodes,
|
||||
edges: aggregatedEdges
|
||||
}));
|
||||
} catch (error: unknown) {
|
||||
res.writeHead(500, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ error: (error as Error).message }));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user