@riligar/agents-memories 1.4.2 → 1.5.1
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/package.json +7 -5
- package/src/core/identity.js +4 -16
- package/src/core/logic.js +11 -5
- package/src/core/sip.js +75 -22
- package/src/sdk/memory-system.js +1 -1
- package/src/server/index.js +0 -56
- package/src/server/mcp-server.js +0 -159
- package/src/test.js +0 -101
- package/src/test_identity.js +0 -61
- package/src/test_sse.js +0 -74
package/package.json
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@riligar/agents-memories",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "RiLiGar Agents Memories - A self-improving relational memory system for AI agents.",
|
|
5
5
|
"module": "src/index.js",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"files": [
|
|
9
|
-
"src",
|
|
9
|
+
"src/core",
|
|
10
|
+
"src/database",
|
|
11
|
+
"src/sdk",
|
|
12
|
+
"src/index.js",
|
|
10
13
|
"README.md",
|
|
11
14
|
"LICENSE"
|
|
12
15
|
],
|
|
@@ -31,15 +34,14 @@
|
|
|
31
34
|
"dependencies": {
|
|
32
35
|
"@huggingface/transformers": "^4.0.1",
|
|
33
36
|
"@libsql/client": "^0.17.2",
|
|
34
|
-
"@modelcontextprotocol/sdk": "latest"
|
|
35
|
-
"cors": "^2.8.6",
|
|
36
|
-
"express": "^5.2.1"
|
|
37
|
+
"@modelcontextprotocol/sdk": "latest"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
39
40
|
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
40
41
|
"@semantic-release/github": "^12.0.6",
|
|
41
42
|
"@semantic-release/npm": "^13.1.5",
|
|
42
43
|
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
44
|
+
"conventional-changelog-conventionalcommits": "^8.0.0",
|
|
43
45
|
"md-to-pdf": "^5.2.5",
|
|
44
46
|
"semantic-release": "^25.0.3"
|
|
45
47
|
}
|
package/src/core/identity.js
CHANGED
|
@@ -2,12 +2,9 @@ import fs from 'fs'
|
|
|
2
2
|
import path from 'path'
|
|
3
3
|
import crypto from 'crypto'
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Utilitário para gerenciar a identidade criptográfica do agente.
|
|
7
|
-
*/
|
|
8
5
|
export function getSystemIdentity(dataDir) {
|
|
9
6
|
const identityPath = path.join(dataDir, 'identity.json')
|
|
10
|
-
|
|
7
|
+
|
|
11
8
|
if (fs.existsSync(identityPath)) {
|
|
12
9
|
const data = JSON.parse(fs.readFileSync(identityPath, 'utf8'))
|
|
13
10
|
return data.owner_id
|
|
@@ -15,19 +12,10 @@ export function getSystemIdentity(dataDir) {
|
|
|
15
12
|
|
|
16
13
|
if (!fs.existsSync(dataDir)) fs.mkdirSync(dataDir, { recursive: true })
|
|
17
14
|
|
|
18
|
-
const
|
|
19
|
-
publicKeyEncoding: { type: 'spki', format: 'pem' },
|
|
20
|
-
privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
const ownerId = crypto.createHash('sha256').update(publicKey).digest('hex').substring(0, 10)
|
|
15
|
+
const ownerId = crypto.randomBytes(5).toString('hex')
|
|
24
16
|
|
|
25
|
-
fs.writeFileSync(identityPath, JSON.stringify({
|
|
26
|
-
owner_id: ownerId,
|
|
27
|
-
public_key: publicKey,
|
|
28
|
-
private_key: privateKey
|
|
29
|
-
}, null, 2), 'utf8')
|
|
17
|
+
fs.writeFileSync(identityPath, JSON.stringify({ owner_id: ownerId }, null, 2), 'utf8')
|
|
30
18
|
|
|
31
|
-
console.error(`Generated new
|
|
19
|
+
console.error(`Generated new identity: ${ownerId}`)
|
|
32
20
|
return ownerId
|
|
33
21
|
}
|
package/src/core/logic.js
CHANGED
|
@@ -2,14 +2,20 @@ import { pipeline } from '@huggingface/transformers'
|
|
|
2
2
|
|
|
3
3
|
let extractor = null
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
* Gera embeddings para o texto fornecido.
|
|
7
|
-
*/
|
|
8
|
-
export async function getEmbedding(text) {
|
|
5
|
+
async function getExtractor() {
|
|
9
6
|
if (!extractor) {
|
|
10
7
|
extractor = await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2')
|
|
11
8
|
}
|
|
12
|
-
|
|
9
|
+
return extractor
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function warmup() {
|
|
13
|
+
await getExtractor()
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export async function getEmbedding(text) {
|
|
17
|
+
const extract = await getExtractor()
|
|
18
|
+
const output = await extract(text, { pooling: 'mean', normalize: true })
|
|
13
19
|
return new Float32Array(output.data)
|
|
14
20
|
}
|
|
15
21
|
|
package/src/core/sip.js
CHANGED
|
@@ -1,30 +1,83 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Self-Improvement Protocol (SIP) - Protocol Definition
|
|
3
|
-
* This document defines the core pillars of the RiLiGar self-improvement loop.
|
|
4
|
-
*/
|
|
5
1
|
export const SIP_PROTOCOL = `
|
|
6
|
-
#
|
|
2
|
+
# Agent Behavioral Protocol — RiLiGar Memory System
|
|
7
3
|
|
|
8
|
-
|
|
4
|
+
This protocol defines exactly how you, as an agent, should interact with this memory system. Follow it without being asked. Its purpose is to make you consistent across sessions and capable of learning from your own history.
|
|
9
5
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Rule 1 — Search Before Acting
|
|
9
|
+
|
|
10
|
+
Before starting any non-trivial task, call \`search\` with a query that describes what you are about to do.
|
|
11
|
+
|
|
12
|
+
Why: past decisions, failed approaches, and established conventions are stored here. Acting without searching means you may contradict something already decided, or repeat a mistake already documented.
|
|
13
|
+
|
|
14
|
+
Examples of when to search proactively:
|
|
15
|
+
- User asks you to implement something → search for "how we implemented X before"
|
|
16
|
+
- User mentions an error → search for "past errors with X"
|
|
17
|
+
- User references a preference or convention → search for "our approach to X"
|
|
18
|
+
- You are unsure how something was done → search before guessing
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Rule 2 — Save After Every Significant Action
|
|
23
|
+
|
|
24
|
+
After completing a task, making a decision, or discovering a lesson, call \`save\`.
|
|
25
|
+
|
|
26
|
+
What makes a memory worth saving:
|
|
27
|
+
- A design or architectural decision (and why it was made)
|
|
28
|
+
- A lesson learned from an error or unexpected behavior
|
|
29
|
+
- A user preference or working convention
|
|
30
|
+
- A solution to a non-obvious problem
|
|
31
|
+
|
|
32
|
+
What to write: always include the WHY. A memory that says "we use X" is weak. A memory that says "we use X because Y, which avoids Z" is strong and useful in future searches.
|
|
33
|
+
|
|
34
|
+
---
|
|
14
35
|
|
|
15
|
-
##
|
|
16
|
-
- **Goal**: Update internal instructions and code patterns based on discovered "State of the Art" (SOTA) solutions.
|
|
17
|
-
- **Action**: If a specific implementation pattern proves superior (e.g., Elysia optimization), save it under \`Patterns.SOTA.*\` and update relevant local \`.agent/skills/\`.
|
|
36
|
+
## Rule 3 — Bridge When You Find Relationships
|
|
18
37
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
38
|
+
When you notice that two topics in memory have a logical dependency, hierarchy, or conflict, call \`bridge\` to make it explicit.
|
|
39
|
+
|
|
40
|
+
Call \`list\` first to confirm both paths exist before bridging.
|
|
41
|
+
|
|
42
|
+
Use these relation types:
|
|
43
|
+
- \`depends_on\` — A cannot work without B
|
|
44
|
+
- \`part_of\` — A is a component of B
|
|
45
|
+
- \`implements\` — A is a concrete realization of B
|
|
46
|
+
- \`conflicts_with\` — A and B cannot coexist
|
|
47
|
+
- \`supersedes\` — A replaces B
|
|
48
|
+
- \`related_to\` — general association (default)
|
|
23
49
|
|
|
24
50
|
---
|
|
25
51
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
52
|
+
## Rule 4 — Organize Knowledge with Paths
|
|
53
|
+
|
|
54
|
+
Every memory must have a \`path\`. Use dot-notation to reflect the logical hierarchy:
|
|
55
|
+
|
|
56
|
+
- \`Project.Architecture.Database\`
|
|
57
|
+
- \`Project.Auth.Strategy\`
|
|
58
|
+
- \`User.Preferences.CodeStyle\`
|
|
59
|
+
- \`Lessons.Errors.Migration\`
|
|
60
|
+
- \`Patterns.SOTA.Caching\`
|
|
61
|
+
- \`Self.Identity\`
|
|
62
|
+
- \`Self.Ethics\`
|
|
63
|
+
|
|
64
|
+
Call \`list\` before saving to reuse existing paths. Do not create a new path if a sufficiently similar one already exists.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Rule 5 — Audit the Graph Periodically
|
|
69
|
+
|
|
70
|
+
Use \`inspect\` to view the knowledge graph as a diagram. Do this after a session with many saves and bridges to verify the structure is coherent and no important connections are missing.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Summary — What to do at each stage
|
|
75
|
+
|
|
76
|
+
| Stage | Action |
|
|
77
|
+
|---|---|
|
|
78
|
+
| Before any task | \`search\` for relevant past context |
|
|
79
|
+
| After completing a task | \`save\` the decision and its rationale |
|
|
80
|
+
| After discovering a relationship | \`bridge\` the two paths |
|
|
81
|
+
| Before saving or bridging | \`list\` to confirm existing paths |
|
|
82
|
+
| After a heavy session | \`inspect\` to audit the graph |
|
|
83
|
+
`.trim()
|
package/src/sdk/memory-system.js
CHANGED
package/src/server/index.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { createClient } from '@libsql/client'
|
|
2
|
-
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
3
|
-
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js'
|
|
4
|
-
import express from 'express'
|
|
5
|
-
import cors from 'cors'
|
|
6
|
-
import path from 'path'
|
|
7
|
-
|
|
8
|
-
import { MemorySystem, getSystemIdentity, createMcpServer } from '../index.js'
|
|
9
|
-
|
|
10
|
-
// 1. SETUP
|
|
11
|
-
const DATA_DIR = 'data'
|
|
12
|
-
const SYSTEM_OWNER_ID = getSystemIdentity(DATA_DIR)
|
|
13
|
-
const db = createClient({ url: `file:${path.join(DATA_DIR, 'memories.db')}` })
|
|
14
|
-
|
|
15
|
-
const memorySystem = new MemorySystem(db, SYSTEM_OWNER_ID)
|
|
16
|
-
await memorySystem.init()
|
|
17
|
-
|
|
18
|
-
console.error(`RiLiGar Agents Memories initialized for Owner: ${SYSTEM_OWNER_ID}`)
|
|
19
|
-
|
|
20
|
-
// 2. TRANSPORTS
|
|
21
|
-
// 2.1. STDIO
|
|
22
|
-
const mcpServer = createMcpServer(memorySystem)
|
|
23
|
-
const stdioTransport = new StdioServerTransport()
|
|
24
|
-
mcpServer.connect(stdioTransport).catch(err => console.error('STDIO Error:', err))
|
|
25
|
-
|
|
26
|
-
// 2.2. SSE (Express)
|
|
27
|
-
const app = express()
|
|
28
|
-
app.use(cors())
|
|
29
|
-
const sseSessions = new Map()
|
|
30
|
-
|
|
31
|
-
app.get('/sse', async (req, res) => {
|
|
32
|
-
const transport = new SSEServerTransport('/messages', res)
|
|
33
|
-
const sessionServer = createMcpServer(memorySystem)
|
|
34
|
-
await sessionServer.connect(transport)
|
|
35
|
-
|
|
36
|
-
const sessionId = transport.sessionId
|
|
37
|
-
sseSessions.set(sessionId, transport)
|
|
38
|
-
console.error(`SSE session started: ${sessionId}`)
|
|
39
|
-
|
|
40
|
-
res.on('close', () => {
|
|
41
|
-
sseSessions.delete(sessionId)
|
|
42
|
-
console.error(`SSE session closed: ${sessionId}`)
|
|
43
|
-
})
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
app.post('/messages', async (req, res) => {
|
|
47
|
-
const sessionId = req.query.sessionId
|
|
48
|
-
const transport = sseSessions.get(sessionId)
|
|
49
|
-
if (!transport) return res.status(404).send('Session not found')
|
|
50
|
-
await transport.handlePostMessage(req, res)
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
const PORT = process.env.PORT || 3000
|
|
54
|
-
app.listen(PORT, () => {
|
|
55
|
-
console.error(`RiLiGar Agents Memories Standalone running at http://localhost:${PORT}`)
|
|
56
|
-
})
|
package/src/server/mcp-server.js
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
|
|
2
|
-
import {
|
|
3
|
-
CallToolRequestSchema,
|
|
4
|
-
ListToolsRequestSchema,
|
|
5
|
-
ListResourcesRequestSchema,
|
|
6
|
-
ReadResourceRequestSchema
|
|
7
|
-
} from '@modelcontextprotocol/sdk/types.js'
|
|
8
|
-
import { SIP_PROTOCOL } from '../core/sip.js'
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Factory para criar o servidor MCP usando o SDK do RiLiGar.
|
|
12
|
-
*/
|
|
13
|
-
export function createMcpServer(memorySystem) {
|
|
14
|
-
const server = new Server(
|
|
15
|
-
{ name: 'RiLiGar Agents Memories', version: '4.2.0' },
|
|
16
|
-
{ capabilities: { tools: {}, resources: {} } }
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
20
|
-
return {
|
|
21
|
-
tools: [
|
|
22
|
-
{
|
|
23
|
-
name: 'save',
|
|
24
|
-
description: 'Primary "CAPTURE" tool for the RiLiGar Self-Improvement Protocol (SIP). Saves information into the Relational Knowledge Graph using Resonance Intelligence and Auto-Bridging. IMPORTANT: Always include the "Rationale" (the "Why") within the content to enable future Pattern Mining. Supports batch saving via arrays.',
|
|
25
|
-
inputSchema: {
|
|
26
|
-
type: 'object',
|
|
27
|
-
properties: {
|
|
28
|
-
content: {
|
|
29
|
-
description: 'The information to persist. For architectural decisions, include the technical Rationale.',
|
|
30
|
-
oneOf: [
|
|
31
|
-
{ type: 'string' },
|
|
32
|
-
{ type: 'array', items: { anyOf: [
|
|
33
|
-
{ type: 'string' },
|
|
34
|
-
{ type: 'object', properties: {
|
|
35
|
-
content: { type: 'string', description: 'The main data/lesson/decision text.' },
|
|
36
|
-
path: { type: 'string', description: 'Dot-notation path (e.g., Project.Architecture.Storage).' },
|
|
37
|
-
owner_id: { type: 'string', description: 'Agent/User identity for ownership.' },
|
|
38
|
-
priority: { type: 'integer', description: 'Base priority (0-10) for Resonance rippling.' }
|
|
39
|
-
}, required: ['content'] }
|
|
40
|
-
] } }
|
|
41
|
-
],
|
|
42
|
-
},
|
|
43
|
-
path: { type: 'string', description: 'Hierarchical path (e.g., Self.Ethics.Protocol or Patterns.SOTA.Elysia).' },
|
|
44
|
-
owner_id: { type: 'string', description: 'Identity string of the memory owner.' },
|
|
45
|
-
priority: { type: 'integer', description: 'Initial importance; triggers priority adjustment in semantic neighbors.' },
|
|
46
|
-
},
|
|
47
|
-
required: ['content'],
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
name: 'bridge',
|
|
52
|
-
description: 'Establish explicit "Relational Intelligence" by connecting two disparate memory paths. Use this to document logical dependencies (depends_on), hierarchies (part_of), or implementation requirements that semantic similarity might not immediately detect.',
|
|
53
|
-
inputSchema: {
|
|
54
|
-
type: 'object',
|
|
55
|
-
properties: {
|
|
56
|
-
source_path: { type: 'string', description: 'The origin path of the relationship.' },
|
|
57
|
-
target_path: { type: 'string', description: 'The destination path of the relationship.' },
|
|
58
|
-
relation: { type: 'string', default: 'related_to', description: 'The type of connection: depends_on, part_of, implements, conflicts_with, etc.' },
|
|
59
|
-
},
|
|
60
|
-
required: ['source_path', 'target_path'],
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
name: 'search',
|
|
65
|
-
description: 'Execute "Reflexive Cognition". Performs a Relational Semantic Search across memories. Agents MUST use this proactively before complex tasks to find past "Lessons Learned", "Rationales", or "Errors" related to the current context. Results are ranked by Similarity (60%) and Recency (40%).',
|
|
66
|
-
inputSchema: {
|
|
67
|
-
type: 'object',
|
|
68
|
-
properties: {
|
|
69
|
-
query: { type: 'string', description: 'Semantic search query (e.g., "how we optimized sidebar storage").' },
|
|
70
|
-
path_filter: { type: 'string', description: 'Filter by path prefix (e.g., "Project.Architecture").' },
|
|
71
|
-
},
|
|
72
|
-
required: ['query'],
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
name: 'inspect',
|
|
77
|
-
description: 'Visualize the Relational Knowledge Graph in Mermaid.js syntax. Critical for the "Self-Critique" phase of SIP. Use it to audit system architecture, browse cognitive connections, and ensure no architectural drift has occurred.',
|
|
78
|
-
inputSchema: { type: 'object', properties: {} },
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
name: 'list',
|
|
82
|
-
description: 'List all unique memory paths (namespace discovery). Use this to explore the hierarchy and understand the available knowledge domains before performing targeted searches or saves.',
|
|
83
|
-
inputSchema: { type: 'object', properties: {} },
|
|
84
|
-
},
|
|
85
|
-
],
|
|
86
|
-
}
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
90
|
-
return {
|
|
91
|
-
resources: [
|
|
92
|
-
{
|
|
93
|
-
uri: 'sip://protocol',
|
|
94
|
-
name: 'Self-Improvement Protocol (SIP)',
|
|
95
|
-
description: 'Protocolo de autoaperfeiçoamento contínuo para agentes RiLiGar.',
|
|
96
|
-
mimeType: 'text/markdown',
|
|
97
|
-
},
|
|
98
|
-
],
|
|
99
|
-
}
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
server.setRequestHandler(ReadResourceRequestSchema, async request => {
|
|
103
|
-
if (request.params.uri === 'sip://protocol') {
|
|
104
|
-
return {
|
|
105
|
-
contents: [
|
|
106
|
-
{
|
|
107
|
-
uri: 'sip://protocol',
|
|
108
|
-
mimeType: 'text/markdown',
|
|
109
|
-
text: SIP_PROTOCOL,
|
|
110
|
-
},
|
|
111
|
-
],
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
throw new Error('Resource not found')
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
server.setRequestHandler(CallToolRequestSchema, async request => {
|
|
118
|
-
const { name, arguments: args } = request.params
|
|
119
|
-
|
|
120
|
-
try {
|
|
121
|
-
if (name === 'save') {
|
|
122
|
-
const res = await memorySystem.save(args)
|
|
123
|
-
return { content: [{ type: 'text', text: `Saved ${res.count} memories. Semantic Magnet applied.` }] }
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (name === 'bridge') {
|
|
127
|
-
await memorySystem.bridge(args)
|
|
128
|
-
return { content: [{ type: 'text', text: `Bridge created: [${args.source_path}] --(${args.relation})--> [${args.target_path}]` }] }
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (name === 'search') {
|
|
132
|
-
const rows = await memorySystem.search(args)
|
|
133
|
-
const formattedResults = rows.map(r => {
|
|
134
|
-
const linkText = r.links.length > 0
|
|
135
|
-
? `\n🔗 Related: ${r.links.map(l => `${l.path} (${l.relation_type})`).join(', ')}`
|
|
136
|
-
: ''
|
|
137
|
-
return `[${r.path} | P:${r.priority}] ${r.content}${linkText}`
|
|
138
|
-
})
|
|
139
|
-
return { content: [{ type: 'text', text: formattedResults.join('\n\n') || 'No results.' }] }
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (name === 'inspect') {
|
|
143
|
-
const mermaid = await memorySystem.inspect()
|
|
144
|
-
return { content: [{ type: 'text', text: `### Knowledge Graph\n\n\`\`\`mermaid\n${mermaid}\`\`\`` }] }
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (name === 'list') {
|
|
148
|
-
const paths = await memorySystem.list()
|
|
149
|
-
return { content: [{ type: 'text', text: paths.map(p => `- ${p}`).join('\n') || 'Empty.' }] }
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
throw new Error('Unknown tool.')
|
|
153
|
-
} catch (error) {
|
|
154
|
-
return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true }
|
|
155
|
-
}
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
return server
|
|
159
|
-
}
|
package/src/test.js
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { Client } from '@modelcontextprotocol/sdk/client/index.js'
|
|
2
|
-
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Knowledge Graph & Relational Intelligence Test Suite.
|
|
6
|
-
* Verifies manual bridging, auto-linking (Semantic Magnet), and graph inspection.
|
|
7
|
-
*/
|
|
8
|
-
async function runTest() {
|
|
9
|
-
console.log('\n🕸️ Initializing Relational Knowledge Graph E2E Test...\n')
|
|
10
|
-
|
|
11
|
-
const transport = new StdioClientTransport({
|
|
12
|
-
command: process.platform === 'win32' ? 'bun.exe' : (process.env.HOME + '/.bun/bin/bun'),
|
|
13
|
-
args: ['src/server/index.js']
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
const client = new Client(
|
|
17
|
-
{ name: 'Graph-Tester', version: '1.0.0' },
|
|
18
|
-
{ capabilities: {} }
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
try {
|
|
22
|
-
await client.connect(transport)
|
|
23
|
-
console.log('✅ Connected to RiLiGar Agents Memories.')
|
|
24
|
-
|
|
25
|
-
// ==========================================
|
|
26
|
-
// SCENARIO 1: MANUAL BRIDGING
|
|
27
|
-
// ==========================================
|
|
28
|
-
console.log('\n🌉 [Scenario 1] Creating a Manual Semantic Bridge')
|
|
29
|
-
|
|
30
|
-
await client.callTool({
|
|
31
|
-
name: 'save',
|
|
32
|
-
arguments: {
|
|
33
|
-
content: [
|
|
34
|
-
{ content: 'LibSQL supports local vector extensions.', path: 'Infrastructure.Database' },
|
|
35
|
-
{ content: 'Search latency is sub-10ms for local queries.', path: 'Architecture.Performance' }
|
|
36
|
-
],
|
|
37
|
-
owner_id: 'tester'
|
|
38
|
-
}
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
await client.callTool({
|
|
42
|
-
name: 'bridge',
|
|
43
|
-
arguments: {
|
|
44
|
-
source_path: 'Architecture.Performance',
|
|
45
|
-
target_path: 'Infrastructure.Database',
|
|
46
|
-
relation: 'depends_on'
|
|
47
|
-
}
|
|
48
|
-
})
|
|
49
|
-
console.log('✅ Bridge established: Performance depends_on Database.')
|
|
50
|
-
|
|
51
|
-
// ==========================================
|
|
52
|
-
// SCENARIO 2: SEMANTIC MAGNET (AUTO-LINKING)
|
|
53
|
-
// ==========================================
|
|
54
|
-
console.log('\n🧲 [Scenario 2] Testing Semantic Magnet (Auto-Linking)')
|
|
55
|
-
|
|
56
|
-
await client.callTool({
|
|
57
|
-
name: 'save',
|
|
58
|
-
arguments: {
|
|
59
|
-
content: 'Neural networks inspired by biological synaptic connections.',
|
|
60
|
-
owner_id: 'tester'
|
|
61
|
-
}
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
console.log('--- Saving extremely similar content to trigger Auto-Link ---')
|
|
65
|
-
await client.callTool({
|
|
66
|
-
name: 'save',
|
|
67
|
-
arguments: {
|
|
68
|
-
content: 'Biological synapses are the foundation for neural network models.',
|
|
69
|
-
owner_id: 'tester'
|
|
70
|
-
}
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
// ==========================================
|
|
74
|
-
// SCENARIO 3: GRAPH INSPECTION (VISUAL)
|
|
75
|
-
// ==========================================
|
|
76
|
-
console.log('\n🗺️ [Scenario 3] Inspecting the Mental Map (Graph Visualization)')
|
|
77
|
-
const graphResult = await client.callTool({ name: 'inspect', arguments: {} })
|
|
78
|
-
console.log(graphResult.content[0].text)
|
|
79
|
-
|
|
80
|
-
// ==========================================
|
|
81
|
-
// SCENARIO 4: RELATIONAL SEARCH
|
|
82
|
-
// ==========================================
|
|
83
|
-
console.log('\n🔍 [Scenario 4] Executing Relational Semantic Search')
|
|
84
|
-
const searchResult = await client.callTool({
|
|
85
|
-
name: 'search',
|
|
86
|
-
arguments: { query: 'How does performance relate to infrastructure?' }
|
|
87
|
-
})
|
|
88
|
-
console.log('🎯 Search Result (should show 🔗 Related paths):\n')
|
|
89
|
-
console.log(searchResult.content[0].text)
|
|
90
|
-
|
|
91
|
-
console.log('\n✅ Knowledge Graph Suite completed successfully.\n')
|
|
92
|
-
|
|
93
|
-
} catch (error) {
|
|
94
|
-
console.error('🚨 Critical failure:', error)
|
|
95
|
-
} finally {
|
|
96
|
-
await transport.close()
|
|
97
|
-
process.exit()
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
runTest()
|
package/src/test_identity.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { Client } from '@modelcontextprotocol/sdk/client/index.js'
|
|
2
|
-
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'
|
|
3
|
-
import fs from 'fs'
|
|
4
|
-
|
|
5
|
-
async function runIdentityTest() {
|
|
6
|
-
console.log('\n🆔 Testing Persistent Cryptographic Identity...\n')
|
|
7
|
-
|
|
8
|
-
const identityFile = 'data/identity.json'
|
|
9
|
-
if (fs.existsSync(identityFile)) {
|
|
10
|
-
const data = JSON.parse(fs.readFileSync(identityFile, 'utf8'))
|
|
11
|
-
console.log(`Current persistent cryptographic ID: ${data.owner_id}`)
|
|
12
|
-
console.log(`Public Key found: ${data.public_key.substring(0, 40)}...`)
|
|
13
|
-
} else {
|
|
14
|
-
console.log('No cryptographic identity found yet.')
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const transport = new StdioClientTransport({
|
|
18
|
-
command: (process.env.HOME + '/.bun/bin/bun'),
|
|
19
|
-
args: ['src/server/index.js']
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
const client = new Client(
|
|
23
|
-
{ name: 'Identity-Tester', version: '1.0.0' },
|
|
24
|
-
{ capabilities: {} }
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
await client.connect(transport)
|
|
29
|
-
|
|
30
|
-
console.log('\n--- Case 1: Saving WITHOUT owner_id (Implicit Cryptographic) ---')
|
|
31
|
-
await client.callTool({
|
|
32
|
-
name: 'save',
|
|
33
|
-
arguments: {
|
|
34
|
-
content: 'Implicit cryptographic owner test memory',
|
|
35
|
-
path: 'Test.Identity'
|
|
36
|
-
}
|
|
37
|
-
})
|
|
38
|
-
console.log('✅ Saved implicit memory.')
|
|
39
|
-
|
|
40
|
-
console.log('\n--- Case 2: Saving WITH owner_id (Explicit Override) ---')
|
|
41
|
-
await client.callTool({
|
|
42
|
-
name: 'save',
|
|
43
|
-
arguments: {
|
|
44
|
-
content: 'Explicit owner test memory',
|
|
45
|
-
path: 'Test.Identity',
|
|
46
|
-
owner_id: 'EXTERNAL_HUMAN'
|
|
47
|
-
}
|
|
48
|
-
})
|
|
49
|
-
console.log('✅ Saved explicit memory.')
|
|
50
|
-
|
|
51
|
-
console.log('\n✅ Identity tests completed successfully.\n')
|
|
52
|
-
|
|
53
|
-
} catch (error) {
|
|
54
|
-
console.error('🚨 Test failed:', error)
|
|
55
|
-
} finally {
|
|
56
|
-
await transport.close()
|
|
57
|
-
process.exit()
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
runIdentityTest()
|
package/src/test_sse.js
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
async function testSSE() {
|
|
3
|
-
console.log('--- Testing SSE Connection ---');
|
|
4
|
-
try {
|
|
5
|
-
const response = await fetch('http://localhost:3000/sse');
|
|
6
|
-
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
|
7
|
-
|
|
8
|
-
const reader = response.body.getReader();
|
|
9
|
-
const decoder = new TextDecoder();
|
|
10
|
-
|
|
11
|
-
console.log('Connection opened. Waiting for endpoint event...');
|
|
12
|
-
|
|
13
|
-
let endpointUrl = null;
|
|
14
|
-
|
|
15
|
-
// Read the first chunk
|
|
16
|
-
const { value, done } = await reader.read();
|
|
17
|
-
const chunk = decoder.decode(value);
|
|
18
|
-
console.log('Received chunk:\n', chunk);
|
|
19
|
-
|
|
20
|
-
if (chunk.includes('event: endpoint')) {
|
|
21
|
-
console.log('✅ Received endpoint event!');
|
|
22
|
-
const lines = chunk.split('\n');
|
|
23
|
-
const dataLine = lines.find(l => l.startsWith('data: '));
|
|
24
|
-
if (dataLine) {
|
|
25
|
-
endpointUrl = dataLine.replace('data: ', '').trim();
|
|
26
|
-
console.log(`Endpoint URL: ${endpointUrl}`);
|
|
27
|
-
}
|
|
28
|
-
} else {
|
|
29
|
-
console.log('❌ FAILED: Did not receive endpoint event as the first message.');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (endpointUrl) {
|
|
33
|
-
console.log('\n--- Testing Tool Call via SSE ---');
|
|
34
|
-
const message = {
|
|
35
|
-
jsonrpc: '2.0',
|
|
36
|
-
id: 1,
|
|
37
|
-
method: 'tools/call',
|
|
38
|
-
params: {
|
|
39
|
-
name: 'list',
|
|
40
|
-
arguments: {}
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
const postRes = await fetch(`http://localhost:3000${endpointUrl}`, {
|
|
45
|
-
method: 'POST',
|
|
46
|
-
headers: { 'Content-Type': 'application/json' },
|
|
47
|
-
body: JSON.stringify(message)
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
if (postRes.ok) {
|
|
51
|
-
console.log('✅ Message POST-ed successfully.');
|
|
52
|
-
|
|
53
|
-
// Read next chunk for the result
|
|
54
|
-
const { value: val2 } = await reader.read();
|
|
55
|
-
const chunk2 = decoder.decode(val2);
|
|
56
|
-
console.log('Received response chunk:\n', chunk2);
|
|
57
|
-
|
|
58
|
-
if (chunk2.includes('event: message')) {
|
|
59
|
-
console.log('✅ Received message event response!');
|
|
60
|
-
} else {
|
|
61
|
-
console.log('❌ FAILED: Response did not have event: message prefix.');
|
|
62
|
-
}
|
|
63
|
-
} else {
|
|
64
|
-
console.log(`❌ FAILED to POST message: ${postRes.status} ${await postRes.text()}`);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
reader.cancel();
|
|
69
|
-
} catch (error) {
|
|
70
|
-
console.error('🚨 Error during SSE test:', error);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
testSSE();
|