@duckmind/deepquark-darwin-arm64 0.9.83 → 0.9.90
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/.deepquark/skills/bundled/knowledge-graph/SKILL.md +385 -0
- package/.deepquark/skills/bundled/knowledge-graph/STANDARDS.md +461 -0
- package/.deepquark/skills/bundled/knowledge-graph/lib/cli.ts +588 -0
- package/.deepquark/skills/bundled/knowledge-graph/lib/config.ts +630 -0
- package/.deepquark/skills/bundled/knowledge-graph/lib/connection-profile.ts +629 -0
- package/.deepquark/skills/bundled/knowledge-graph/lib/container.ts +756 -0
- package/.deepquark/skills/bundled/knowledge-graph/lib/mcp-client.ts +1310 -0
- package/.deepquark/skills/bundled/knowledge-graph/lib/output-formatter.ts +997 -0
- package/.deepquark/skills/bundled/knowledge-graph/lib/token-metrics.ts +335 -0
- package/.deepquark/skills/bundled/knowledge-graph/lib/transformation-log.ts +137 -0
- package/.deepquark/skills/bundled/knowledge-graph/lib/wrapper-config.ts +113 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/.env.example +129 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/compare-embeddings.ts +175 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/config-falkordb.yaml +108 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/config-neo4j.yaml +111 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/diagnose.ts +483 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/docker-compose-falkordb-dev.yml +146 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/docker-compose-falkordb.yml +151 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/docker-compose-neo4j-dev-local.yml +161 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/docker-compose-neo4j-dev.yml +161 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/docker-compose-neo4j.yml +169 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/docker-compose-production.yml +128 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/docker-compose-test.yml +10 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/docker-compose.yml +84 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/entrypoint.sh +40 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/install.ts +2054 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/podman-compose-falkordb.yml +78 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/podman-compose-neo4j.yml +88 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/podman-compose.yml +83 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/test-all-llms-mcp.ts +387 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/test-embedding-models.ts +201 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/test-embedding-providers.ts +641 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/test-graphiti-model.ts +217 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/test-grok-correct.ts +141 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/test-grok-llms-mcp.ts +386 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/test-grok-models.ts +173 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/test-llama-extraction.ts +188 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/test-mcp-final.ts +240 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/test-mcp-live.ts +187 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/test-mcp-session.ts +127 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/test-model-combinations.ts +316 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/test-ollama-models.ts +228 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/test-openrouter-models.ts +460 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/test-real-life-mcp.ts +311 -0
- package/.deepquark/skills/bundled/knowledge-graph/server/test-search-debug.ts +199 -0
- package/.deepquark/skills/bundled/knowledge-graph/tools/Install.md +104 -0
- package/.deepquark/skills/bundled/knowledge-graph/tools/README.md +120 -0
- package/.deepquark/skills/bundled/knowledge-graph/tools/knowledge-cli.ts +996 -0
- package/.deepquark/skills/bundled/knowledge-graph/tools/server-cli.ts +531 -0
- package/.deepquark/skills/bundled/knowledge-graph/workflows/BulkImport.md +514 -0
- package/.deepquark/skills/bundled/knowledge-graph/workflows/CaptureEpisode.md +242 -0
- package/.deepquark/skills/bundled/knowledge-graph/workflows/ClearGraph.md +392 -0
- package/.deepquark/skills/bundled/knowledge-graph/workflows/GetRecent.md +352 -0
- package/.deepquark/skills/bundled/knowledge-graph/workflows/GetStatus.md +373 -0
- package/.deepquark/skills/bundled/knowledge-graph/workflows/HealthReport.md +212 -0
- package/.deepquark/skills/bundled/knowledge-graph/workflows/InvestigateEntity.md +142 -0
- package/.deepquark/skills/bundled/knowledge-graph/workflows/OntologyManagement.md +201 -0
- package/.deepquark/skills/bundled/knowledge-graph/workflows/RunMaintenance.md +302 -0
- package/.deepquark/skills/bundled/knowledge-graph/workflows/SearchByDate.md +255 -0
- package/.deepquark/skills/bundled/knowledge-graph/workflows/SearchFacts.md +382 -0
- package/.deepquark/skills/bundled/knowledge-graph/workflows/SearchKnowledge.md +374 -0
- package/.deepquark/skills/bundled/knowledge-graph/workflows/StixImport.md +212 -0
- package/bin/deepquark +0 -0
- package/package.json +1 -1
- package/.deepquark/skills/bundled/ge-payroll/SKILL.md +0 -153
- package/.deepquark/skills/bundled/ge-payroll/evals/evals.json +0 -23
- package/.deepquark/skills/bundled/ge-payroll/references/pain-points-improvements.md +0 -106
- package/.deepquark/skills/bundled/ge-payroll/references/process-detail.md +0 -217
- package/.deepquark/skills/bundled/ge-payroll/references/raci-stakeholders.md +0 -85
- package/.deepquark/skills/bundled/ge-payroll/references/timeline-mandays.md +0 -64
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Real-life MCP Knowledge System Test
|
|
4
|
+
* Tests the actual add_memory, search_nodes, and search_memory_facts operations
|
|
5
|
+
* by calling the MCP server directly via HTTP/SSE protocol
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// Test data - realistic knowledge scenarios
|
|
9
|
+
const TEST_EPISODES = [
|
|
10
|
+
{
|
|
11
|
+
name: 'Tech Stack Decision',
|
|
12
|
+
body: 'The team decided to use TypeScript with Bun runtime for the new API project. Sarah recommended Hono for the HTTP framework due to its performance and edge compatibility.',
|
|
13
|
+
source: 'text',
|
|
14
|
+
group_id: 'mcp-test',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: 'Meeting Notes',
|
|
18
|
+
body: "John Smith from Acme Corp met with our CTO Alice Chen to discuss the Q1 roadmap. They agreed on a partnership to integrate Acme's payment API into our platform.",
|
|
19
|
+
source: 'text',
|
|
20
|
+
group_id: 'mcp-test',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'Technical Documentation',
|
|
24
|
+
body: "The PAI system uses Neo4j as the graph database backend. OpenAI's gpt-4o-mini is configured for entity extraction, while mxbai-embed-large running on Ollama handles embeddings.",
|
|
25
|
+
source: 'text',
|
|
26
|
+
group_id: 'mcp-test',
|
|
27
|
+
},
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
const SEARCH_QUERIES = [
|
|
31
|
+
{ query: 'What technology stack is being used?', expected: ['TypeScript', 'Bun', 'Hono'] },
|
|
32
|
+
{ query: 'Who is working with Acme Corp?', expected: ['John Smith', 'Alice Chen', 'Acme Corp'] },
|
|
33
|
+
{ query: 'What database does PAI use?', expected: ['Neo4j', 'PAI'] },
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
async function testDirectAPI() {
|
|
37
|
+
console.log('═'.repeat(60));
|
|
38
|
+
console.log('🧪 Real-Life MCP Knowledge System Test');
|
|
39
|
+
console.log('═'.repeat(60));
|
|
40
|
+
|
|
41
|
+
// Test 1: Health check
|
|
42
|
+
console.log('\n📋 Test 1: Health Check');
|
|
43
|
+
const health = await fetch('http://localhost:8000/health').then((r) => r.json());
|
|
44
|
+
console.log(` Status: ${health.status}`);
|
|
45
|
+
console.log(` Patch: ${health.patch || 'none'}`);
|
|
46
|
+
|
|
47
|
+
// For actual MCP testing, we'll use the MCP protocol via curl or a proper client
|
|
48
|
+
console.log('\n📋 Testing via MCP protocol requires session management...');
|
|
49
|
+
console.log(' Using direct curl tests instead:\n');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function runCurlTests() {
|
|
53
|
+
const results: any[] = [];
|
|
54
|
+
|
|
55
|
+
// Test add_memory
|
|
56
|
+
console.log('═'.repeat(60));
|
|
57
|
+
console.log('📥 TEST: add_memory operations');
|
|
58
|
+
console.log('═'.repeat(60));
|
|
59
|
+
|
|
60
|
+
for (const episode of TEST_EPISODES) {
|
|
61
|
+
const start = Date.now();
|
|
62
|
+
const proc = Bun.spawn([
|
|
63
|
+
'curl',
|
|
64
|
+
'-sf',
|
|
65
|
+
'-X',
|
|
66
|
+
'POST',
|
|
67
|
+
'http://localhost:8000/mcp',
|
|
68
|
+
'-H',
|
|
69
|
+
'Content-Type: application/json',
|
|
70
|
+
'-H',
|
|
71
|
+
'Accept: text/event-stream',
|
|
72
|
+
'-d',
|
|
73
|
+
JSON.stringify({
|
|
74
|
+
jsonrpc: '2.0',
|
|
75
|
+
id: Date.now(),
|
|
76
|
+
method: 'tools/call',
|
|
77
|
+
params: {
|
|
78
|
+
name: 'add_memory',
|
|
79
|
+
arguments: {
|
|
80
|
+
name: episode.name,
|
|
81
|
+
episode_body: episode.body,
|
|
82
|
+
source: episode.source,
|
|
83
|
+
group_id: episode.group_id,
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
}),
|
|
87
|
+
]);
|
|
88
|
+
|
|
89
|
+
const output = await new Response(proc.stdout).text();
|
|
90
|
+
const duration = Date.now() - start;
|
|
91
|
+
|
|
92
|
+
const success = output.includes('result') && !output.includes('error');
|
|
93
|
+
console.log(`\n ${success ? '✅' : '❌'} "${episode.name}" (${duration}ms)`);
|
|
94
|
+
if (!success) console.log(` Response: ${output.slice(0, 200)}`);
|
|
95
|
+
|
|
96
|
+
results.push({
|
|
97
|
+
operation: 'add_memory',
|
|
98
|
+
name: episode.name,
|
|
99
|
+
success,
|
|
100
|
+
duration,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
await new Promise((r) => setTimeout(r, 2000)); // Wait for processing
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Test search_nodes
|
|
107
|
+
console.log(`\n${'═'.repeat(60)}`);
|
|
108
|
+
console.log('🔍 TEST: search_nodes operations');
|
|
109
|
+
console.log('═'.repeat(60));
|
|
110
|
+
|
|
111
|
+
for (const search of SEARCH_QUERIES) {
|
|
112
|
+
const start = Date.now();
|
|
113
|
+
const proc = Bun.spawn([
|
|
114
|
+
'curl',
|
|
115
|
+
'-sf',
|
|
116
|
+
'-X',
|
|
117
|
+
'POST',
|
|
118
|
+
'http://localhost:8000/mcp',
|
|
119
|
+
'-H',
|
|
120
|
+
'Content-Type: application/json',
|
|
121
|
+
'-H',
|
|
122
|
+
'Accept: text/event-stream',
|
|
123
|
+
'-d',
|
|
124
|
+
JSON.stringify({
|
|
125
|
+
jsonrpc: '2.0',
|
|
126
|
+
id: Date.now(),
|
|
127
|
+
method: 'tools/call',
|
|
128
|
+
params: {
|
|
129
|
+
name: 'search_nodes',
|
|
130
|
+
arguments: {
|
|
131
|
+
query: search.query,
|
|
132
|
+
group_ids: ['mcp-test'],
|
|
133
|
+
max_nodes: 10,
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
}),
|
|
137
|
+
]);
|
|
138
|
+
|
|
139
|
+
const output = await new Response(proc.stdout).text();
|
|
140
|
+
const duration = Date.now() - start;
|
|
141
|
+
|
|
142
|
+
// Check if any expected entities were found
|
|
143
|
+
const foundExpected = search.expected.some((e) =>
|
|
144
|
+
output.toLowerCase().includes(e.toLowerCase())
|
|
145
|
+
);
|
|
146
|
+
console.log(`\n ${foundExpected ? '✅' : '⚠️'} "${search.query}" (${duration}ms)`);
|
|
147
|
+
|
|
148
|
+
// Parse and show found nodes
|
|
149
|
+
try {
|
|
150
|
+
const lines = output.split('\n');
|
|
151
|
+
for (const line of lines) {
|
|
152
|
+
if (line.startsWith('data: ')) {
|
|
153
|
+
const data = JSON.parse(line.slice(6));
|
|
154
|
+
if (data.result?.content?.[0]?.text) {
|
|
155
|
+
const nodes = JSON.parse(data.result.content[0].text);
|
|
156
|
+
if (nodes.nodes?.length > 0) {
|
|
157
|
+
console.log(` Found ${nodes.nodes.length} nodes:`);
|
|
158
|
+
nodes.nodes.slice(0, 3).forEach((n: any) => {
|
|
159
|
+
console.log(` - ${n.name} (${n.entity_type})`);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
} catch (_e) {
|
|
166
|
+
// Output parsing failed
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
results.push({
|
|
170
|
+
operation: 'search_nodes',
|
|
171
|
+
query: search.query,
|
|
172
|
+
success: foundExpected,
|
|
173
|
+
duration,
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Test search_memory_facts
|
|
180
|
+
console.log(`\n${'═'.repeat(60)}`);
|
|
181
|
+
console.log('🔗 TEST: search_memory_facts operations');
|
|
182
|
+
console.log('═'.repeat(60));
|
|
183
|
+
|
|
184
|
+
const factQueries = [
|
|
185
|
+
'partnership between companies',
|
|
186
|
+
'technology decisions',
|
|
187
|
+
'database configuration',
|
|
188
|
+
];
|
|
189
|
+
|
|
190
|
+
for (const query of factQueries) {
|
|
191
|
+
const start = Date.now();
|
|
192
|
+
const proc = Bun.spawn([
|
|
193
|
+
'curl',
|
|
194
|
+
'-sf',
|
|
195
|
+
'-X',
|
|
196
|
+
'POST',
|
|
197
|
+
'http://localhost:8000/mcp',
|
|
198
|
+
'-H',
|
|
199
|
+
'Content-Type: application/json',
|
|
200
|
+
'-H',
|
|
201
|
+
'Accept: text/event-stream',
|
|
202
|
+
'-d',
|
|
203
|
+
JSON.stringify({
|
|
204
|
+
jsonrpc: '2.0',
|
|
205
|
+
id: Date.now(),
|
|
206
|
+
method: 'tools/call',
|
|
207
|
+
params: {
|
|
208
|
+
name: 'search_memory_facts',
|
|
209
|
+
arguments: {
|
|
210
|
+
query: query,
|
|
211
|
+
group_ids: ['mcp-test'],
|
|
212
|
+
max_facts: 5,
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
}),
|
|
216
|
+
]);
|
|
217
|
+
|
|
218
|
+
const output = await new Response(proc.stdout).text();
|
|
219
|
+
const duration = Date.now() - start;
|
|
220
|
+
|
|
221
|
+
const hasFacts = output.includes('facts') && !output.includes('"facts":[]');
|
|
222
|
+
console.log(`\n ${hasFacts ? '✅' : '⚠️'} "${query}" (${duration}ms)`);
|
|
223
|
+
|
|
224
|
+
// Parse and show facts
|
|
225
|
+
try {
|
|
226
|
+
const lines = output.split('\n');
|
|
227
|
+
for (const line of lines) {
|
|
228
|
+
if (line.startsWith('data: ')) {
|
|
229
|
+
const data = JSON.parse(line.slice(6));
|
|
230
|
+
if (data.result?.content?.[0]?.text) {
|
|
231
|
+
const facts = JSON.parse(data.result.content[0].text);
|
|
232
|
+
if (facts.facts?.length > 0) {
|
|
233
|
+
console.log(` Found ${facts.facts.length} facts:`);
|
|
234
|
+
facts.facts.slice(0, 3).forEach((f: any) => {
|
|
235
|
+
console.log(` - ${f.fact?.slice(0, 80)}...`);
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
} catch (_e) {
|
|
242
|
+
// Output parsing failed
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
results.push({
|
|
246
|
+
operation: 'search_memory_facts',
|
|
247
|
+
query: query,
|
|
248
|
+
success: hasFacts,
|
|
249
|
+
duration,
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Summary
|
|
256
|
+
console.log(`\n${'═'.repeat(60)}`);
|
|
257
|
+
console.log('📊 RESULTS SUMMARY');
|
|
258
|
+
console.log('═'.repeat(60));
|
|
259
|
+
|
|
260
|
+
const byOperation = results.reduce(
|
|
261
|
+
(acc, r) => {
|
|
262
|
+
if (!acc[r.operation]) acc[r.operation] = { success: 0, total: 0, totalMs: 0 };
|
|
263
|
+
acc[r.operation].total++;
|
|
264
|
+
if (r.success) acc[r.operation].success++;
|
|
265
|
+
acc[r.operation].totalMs += r.duration;
|
|
266
|
+
return acc;
|
|
267
|
+
},
|
|
268
|
+
{} as Record<string, { success: number; total: number; totalMs: number }>
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
console.log('\n| Operation | Success Rate | Avg Duration |');
|
|
272
|
+
console.log('|--------------------|--------------|--------------|');
|
|
273
|
+
for (const [op, stats] of Object.entries(byOperation)) {
|
|
274
|
+
const rate = ((stats.success / stats.total) * 100).toFixed(0);
|
|
275
|
+
const avgMs = Math.round(stats.totalMs / stats.total);
|
|
276
|
+
console.log(`| ${op.padEnd(18)} | ${rate.padStart(10)}% | ${(`${avgMs}ms`).padStart(12)} |`);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Save results
|
|
280
|
+
await Bun.write(
|
|
281
|
+
'mcp-test-results.json',
|
|
282
|
+
JSON.stringify(
|
|
283
|
+
{
|
|
284
|
+
results,
|
|
285
|
+
summary: byOperation,
|
|
286
|
+
timestamp: new Date().toISOString(),
|
|
287
|
+
config: {
|
|
288
|
+
llm: 'gpt-4o-mini',
|
|
289
|
+
embedder: 'openai',
|
|
290
|
+
database: 'neo4j',
|
|
291
|
+
},
|
|
292
|
+
},
|
|
293
|
+
null,
|
|
294
|
+
2
|
|
295
|
+
)
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
console.log('\n📁 Results saved to mcp-test-results.json');
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
async function main() {
|
|
302
|
+
try {
|
|
303
|
+
await testDirectAPI();
|
|
304
|
+
await runCurlTests();
|
|
305
|
+
} catch (err: any) {
|
|
306
|
+
console.error('Test failed:', err.message);
|
|
307
|
+
process.exit(1);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
main();
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Debug search_nodes and search_memory_facts
|
|
4
|
+
* Data is confirmed in Neo4j - need to understand why searches fail
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const MCP_URL = 'http://localhost:8000/mcp';
|
|
8
|
+
const ACCEPT = 'application/json, text/event-stream';
|
|
9
|
+
|
|
10
|
+
let sessionId: string | null = null;
|
|
11
|
+
|
|
12
|
+
async function mcpRequest(method: string, params: any = {}): Promise<any> {
|
|
13
|
+
const headers: Record<string, string> = {
|
|
14
|
+
'Content-Type': 'application/json',
|
|
15
|
+
Accept: ACCEPT,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
if (sessionId) {
|
|
19
|
+
headers['mcp-session-id'] = sessionId;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const res = await fetch(MCP_URL, {
|
|
23
|
+
method: 'POST',
|
|
24
|
+
headers,
|
|
25
|
+
body: JSON.stringify({
|
|
26
|
+
jsonrpc: '2.0',
|
|
27
|
+
id: Date.now(),
|
|
28
|
+
method,
|
|
29
|
+
params,
|
|
30
|
+
}),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Capture session ID from response
|
|
34
|
+
const newSessionId = res.headers.get('mcp-session-id');
|
|
35
|
+
if (newSessionId) sessionId = newSessionId;
|
|
36
|
+
|
|
37
|
+
const text = await res.text();
|
|
38
|
+
|
|
39
|
+
// Parse SSE or JSON response
|
|
40
|
+
let result: any = null;
|
|
41
|
+
let error: any = null;
|
|
42
|
+
|
|
43
|
+
for (const line of text.split('\n')) {
|
|
44
|
+
if (line.startsWith('data: ')) {
|
|
45
|
+
try {
|
|
46
|
+
const data = JSON.parse(line.slice(6));
|
|
47
|
+
if (data.result) result = data.result;
|
|
48
|
+
if (data.error) error = data.error;
|
|
49
|
+
} catch {}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Fallback to direct JSON
|
|
54
|
+
if (!result && !error) {
|
|
55
|
+
try {
|
|
56
|
+
const json = JSON.parse(text);
|
|
57
|
+
result = json.result;
|
|
58
|
+
error = json.error;
|
|
59
|
+
} catch {}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return { result, error, raw: text };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async function callTool(
|
|
66
|
+
name: string,
|
|
67
|
+
args: any
|
|
68
|
+
): Promise<{ success: boolean; data: any; duration: number; raw: string }> {
|
|
69
|
+
const start = Date.now();
|
|
70
|
+
const { result, error, raw } = await mcpRequest('tools/call', { name, arguments: args });
|
|
71
|
+
const duration = Date.now() - start;
|
|
72
|
+
|
|
73
|
+
if (error) {
|
|
74
|
+
return { success: false, data: error, duration, raw };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Parse tool result content
|
|
78
|
+
let data: any = result;
|
|
79
|
+
try {
|
|
80
|
+
if (result?.content?.[0]?.text) {
|
|
81
|
+
data = JSON.parse(result.content[0].text);
|
|
82
|
+
}
|
|
83
|
+
} catch {}
|
|
84
|
+
|
|
85
|
+
return { success: true, data, duration, raw };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async function main() {
|
|
89
|
+
console.log('═'.repeat(60));
|
|
90
|
+
console.log('🔍 Search Debug Test - Data confirmed in Neo4j');
|
|
91
|
+
console.log('═'.repeat(60));
|
|
92
|
+
|
|
93
|
+
// Initialize session
|
|
94
|
+
console.log('\n📋 Initializing MCP session...');
|
|
95
|
+
const _initRes = await mcpRequest('initialize', {
|
|
96
|
+
protocolVersion: '2024-11-05',
|
|
97
|
+
capabilities: {},
|
|
98
|
+
clientInfo: { name: 'search-debug', version: '1.0' },
|
|
99
|
+
});
|
|
100
|
+
console.log(` Session: ${sessionId}`);
|
|
101
|
+
|
|
102
|
+
await mcpRequest('notifications/initialized', {});
|
|
103
|
+
|
|
104
|
+
// Test 1: Search for exact entity names that exist
|
|
105
|
+
console.log(`\n${'─'.repeat(60)}`);
|
|
106
|
+
console.log('Test 1: Search exact entity names');
|
|
107
|
+
console.log('─'.repeat(60));
|
|
108
|
+
|
|
109
|
+
const exactQueries = ['TypeScript', 'Acme Corp', 'Sarah', 'Neo4j'];
|
|
110
|
+
for (const q of exactQueries) {
|
|
111
|
+
const res = await callTool('search_nodes', {
|
|
112
|
+
query: q,
|
|
113
|
+
group_ids: ['mcp-test'],
|
|
114
|
+
max_nodes: 10,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const nodes = res.data?.nodes || [];
|
|
118
|
+
console.log(`\n"${q}" → ${nodes.length} nodes (${res.duration}ms)`);
|
|
119
|
+
|
|
120
|
+
if (nodes.length > 0) {
|
|
121
|
+
nodes.slice(0, 3).forEach((n: any) => console.log(` ✅ ${n.name} (${n.entity_type})`));
|
|
122
|
+
} else {
|
|
123
|
+
console.log(' ⚠️ No results. Raw response sample:');
|
|
124
|
+
console.log(` ${res.raw.slice(0, 200)}`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
await Bun.sleep(300);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Test 2: Search without group_id filter
|
|
131
|
+
console.log(`\n${'─'.repeat(60)}`);
|
|
132
|
+
console.log('Test 2: Search without group_id filter');
|
|
133
|
+
console.log('─'.repeat(60));
|
|
134
|
+
|
|
135
|
+
const res2 = await callTool('search_nodes', {
|
|
136
|
+
query: 'TypeScript',
|
|
137
|
+
max_nodes: 10,
|
|
138
|
+
});
|
|
139
|
+
const nodes2 = res2.data?.nodes || [];
|
|
140
|
+
console.log(`\n"TypeScript" (no group filter) → ${nodes2.length} nodes (${res2.duration}ms)`);
|
|
141
|
+
nodes2.slice(0, 3).forEach((n: any) => console.log(` ✅ ${n.name}`));
|
|
142
|
+
|
|
143
|
+
// Test 3: Search facts
|
|
144
|
+
console.log(`\n${'─'.repeat(60)}`);
|
|
145
|
+
console.log('Test 3: Search facts');
|
|
146
|
+
console.log('─'.repeat(60));
|
|
147
|
+
|
|
148
|
+
const factQueries = ['partnership', 'technology', 'framework'];
|
|
149
|
+
for (const q of factQueries) {
|
|
150
|
+
const res = await callTool('search_memory_facts', {
|
|
151
|
+
query: q,
|
|
152
|
+
group_ids: ['mcp-test'],
|
|
153
|
+
max_facts: 10,
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
const facts = res.data?.facts || [];
|
|
157
|
+
console.log(`\n"${q}" → ${facts.length} facts (${res.duration}ms)`);
|
|
158
|
+
|
|
159
|
+
if (facts.length > 0) {
|
|
160
|
+
facts.slice(0, 2).forEach((f: any) => console.log(` ✅ ${f.fact?.slice(0, 80)}...`));
|
|
161
|
+
} else {
|
|
162
|
+
console.log(' ⚠️ No results');
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
await Bun.sleep(300);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Test 4: Get episodes to verify data
|
|
169
|
+
console.log(`\n${'─'.repeat(60)}`);
|
|
170
|
+
console.log('Test 4: Get episodes via MCP');
|
|
171
|
+
console.log('─'.repeat(60));
|
|
172
|
+
|
|
173
|
+
const epRes = await callTool('get_episodes', {
|
|
174
|
+
group_ids: ['mcp-test'],
|
|
175
|
+
max_episodes: 10,
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
const episodes = epRes.data?.episodes || [];
|
|
179
|
+
console.log(`\nEpisodes in mcp-test: ${episodes.length}`);
|
|
180
|
+
episodes.forEach((ep: any) => console.log(` 📄 ${ep.name || ep.uuid}`));
|
|
181
|
+
|
|
182
|
+
// Summary
|
|
183
|
+
console.log(`\n${'═'.repeat(60)}`);
|
|
184
|
+
console.log('📊 DEBUG SUMMARY');
|
|
185
|
+
console.log('═'.repeat(60));
|
|
186
|
+
console.log(`
|
|
187
|
+
Data exists in Neo4j (verified via cypher-shell):
|
|
188
|
+
- Entities: TypeScript, Bun, Sarah, Hono, John Smith, Acme Corp, Alice Chen
|
|
189
|
+
- Episodes: Tech Stack, Partnership, PAI System
|
|
190
|
+
- Group: mcp-test
|
|
191
|
+
|
|
192
|
+
If searches return 0 results, possible causes:
|
|
193
|
+
1. Embedding dimension mismatch between storage and query
|
|
194
|
+
2. Vector index not created or not matching
|
|
195
|
+
3. Group ID filter issue in search query
|
|
196
|
+
`);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Install Knowledge System
|
|
2
|
+
|
|
3
|
+
Workflow for installing and configuring the Madeinoz Knowledge System.
|
|
4
|
+
|
|
5
|
+
## When to Use
|
|
6
|
+
|
|
7
|
+
Use this workflow when the user requests:
|
|
8
|
+
- "install knowledge"
|
|
9
|
+
- "setup knowledge system"
|
|
10
|
+
- "configure knowledge graph"
|
|
11
|
+
- "install knowledge system"
|
|
12
|
+
|
|
13
|
+
## Prerequisites Check
|
|
14
|
+
|
|
15
|
+
Before installation, verify:
|
|
16
|
+
|
|
17
|
+
1. **Container runtime available:**
|
|
18
|
+
```bash
|
|
19
|
+
command -v podman || command -v docker
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
2. **Bun runtime installed:**
|
|
23
|
+
```bash
|
|
24
|
+
command -v bun
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
3. **API key configured:**
|
|
28
|
+
- Check for `MADEINOZ_KNOWLEDGE_OPENAI_API_KEY` in PAI config (`$PAI_DIR/.env` or `~/.claude/.env`)
|
|
29
|
+
- Legacy `OPENAI_API_KEY` is also supported but `MADEINOZ_KNOWLEDGE_*` prefix is preferred
|
|
30
|
+
|
|
31
|
+
4. **Neo4j connection configured (for Neo4j backend):**
|
|
32
|
+
- Add to PAI config (`~/.claude/.env`):
|
|
33
|
+
```bash
|
|
34
|
+
MADEINOZ_KNOWLEDGE_NEO4J_URI=bolt://neo4j:7687
|
|
35
|
+
MADEINOZ_KNOWLEDGE_NEO4J_USER=neo4j
|
|
36
|
+
MADEINOZ_KNOWLEDGE_NEO4J_PASSWORD=madeinozknowledge
|
|
37
|
+
```
|
|
38
|
+
- Note: Use `bolt://neo4j:7687` (container hostname) not `bolt://localhost:7687`
|
|
39
|
+
|
|
40
|
+
## Installation Steps
|
|
41
|
+
|
|
42
|
+
### Step 1: Start MCP Server
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
cd /path/to/madeinoz-knowledge-system
|
|
46
|
+
bun run server-cli start
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Step 2: Verify Server Health
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
curl -s http://localhost:8000/health
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Expected: `{"status":"healthy"}`
|
|
56
|
+
|
|
57
|
+
### Step 3: Install Skill
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
PAI_SKILLS_DIR="${PAI_DIR:-$HOME/.claude}/skills"
|
|
61
|
+
cp -r src/skills "$PAI_SKILLS_DIR/Knowledge"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Step 4: Configure MCP in Claude
|
|
65
|
+
|
|
66
|
+
Add to `~/.claude.json`:
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"mcpServers": {
|
|
70
|
+
"madeinoz-knowledge": {
|
|
71
|
+
"type": "http",
|
|
72
|
+
"url": "http://localhost:8000/mcp"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Step 5: Restart Claude Code
|
|
79
|
+
|
|
80
|
+
Restart Claude Code to load the MCP configuration.
|
|
81
|
+
|
|
82
|
+
## Verification
|
|
83
|
+
|
|
84
|
+
After installation, test with:
|
|
85
|
+
|
|
86
|
+
1. **Check status:** "Show knowledge graph status"
|
|
87
|
+
2. **Capture test:** "Remember that Madeinoz Knowledge System is now installed"
|
|
88
|
+
3. **Search test:** "What do I know about PAI?"
|
|
89
|
+
|
|
90
|
+
## Troubleshooting
|
|
91
|
+
|
|
92
|
+
| Issue | Solution |
|
|
93
|
+
|-------|----------|
|
|
94
|
+
| Server won't start | Check logs: `bun run server-cli logs` |
|
|
95
|
+
| MCP tools not available | Verify `~/.claude.json` has madeinoz-knowledge entry |
|
|
96
|
+
| API errors (401) | Check API key is valid and has quota |
|
|
97
|
+
| Neo4j connection errors | Verify `MADEINOZ_KNOWLEDGE_NEO4J_URI=bolt://neo4j:7687` in `~/.claude/.env` |
|
|
98
|
+
| Env file has wrong URI | Run `bun run server-cli stop && bun run server-cli start` to regenerate env files |
|
|
99
|
+
|
|
100
|
+
## Related
|
|
101
|
+
|
|
102
|
+
- `INSTALL.md` - Full installation guide in pack root
|
|
103
|
+
- `VERIFY.md` - Complete verification checklist
|
|
104
|
+
- `diagnose.ts` - Diagnostic tool for troubleshooting
|