@yamo/memory-mesh 2.1.2 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +122 -0
- package/bin/memory_mesh.js +8 -63
- package/lib/embeddings/factory.js +4 -3
- package/lib/lancedb/client.js +3 -1
- package/lib/llm/client.js +391 -0
- package/lib/llm/index.js +10 -0
- package/lib/memory/memory-mesh.js +378 -28
- package/lib/search/keyword-search.js +144 -0
- package/lib/yamo/emitter.js +235 -0
- package/lib/yamo/index.js +15 -0
- package/lib/yamo/schema.js +159 -0
- package/package.json +2 -2
- package/skills/SKILL.md +1 -1
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* YAMO Emitter - Constructs structured YAMO blocks for auditability
|
|
3
|
+
*
|
|
4
|
+
* Based on YAMO Protocol specification:
|
|
5
|
+
* - Semicolon-terminated key-value pairs
|
|
6
|
+
* - Agent/Intent/Context/Constraints/Meta/Output structure
|
|
7
|
+
* - Supports reflect, retain, recall operations
|
|
8
|
+
*
|
|
9
|
+
* Reference: Hindsight project's yamo_integration.py
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* YamoEmitter class for building YAMO protocol blocks
|
|
14
|
+
* YAMO (Yet Another Multi-agent Orchestration) blocks provide
|
|
15
|
+
* structured reasoning traces for AI agent operations.
|
|
16
|
+
*/
|
|
17
|
+
export class YamoEmitter {
|
|
18
|
+
/**
|
|
19
|
+
* Build a YAMO block for reflect operation
|
|
20
|
+
* Reflect operations synthesize insights from existing memories
|
|
21
|
+
*
|
|
22
|
+
* @param {Object} params - Block parameters
|
|
23
|
+
* @param {string} [params.topic] - Topic of reflection
|
|
24
|
+
* @param {number} params.memoryCount - Number of memories considered
|
|
25
|
+
* @param {string} [params.agentId='default'] - Agent identifier
|
|
26
|
+
* @param {string} params.reflection - Generated reflection text
|
|
27
|
+
* @param {number} [params.confidence=0.8] - Confidence score (0-1)
|
|
28
|
+
* @returns {string} Formatted YAMO block
|
|
29
|
+
*/
|
|
30
|
+
static buildReflectBlock(params) {
|
|
31
|
+
const {
|
|
32
|
+
topic,
|
|
33
|
+
memoryCount,
|
|
34
|
+
agentId = 'default',
|
|
35
|
+
reflection,
|
|
36
|
+
confidence = 0.8
|
|
37
|
+
} = params;
|
|
38
|
+
|
|
39
|
+
const timestamp = new Date().toISOString();
|
|
40
|
+
|
|
41
|
+
return `agent: MemoryMesh_${agentId};
|
|
42
|
+
intent: synthesize_insights_from_context;
|
|
43
|
+
context:
|
|
44
|
+
topic;${topic || 'general'};
|
|
45
|
+
memory_count;${memoryCount};
|
|
46
|
+
timestamp;${timestamp};
|
|
47
|
+
constraints:
|
|
48
|
+
hypothesis;Reflection generates new insights from existing facts;
|
|
49
|
+
priority: high;
|
|
50
|
+
output:
|
|
51
|
+
reflection;${reflection};
|
|
52
|
+
confidence;${confidence};
|
|
53
|
+
meta:
|
|
54
|
+
rationale;Synthesized from ${memoryCount} relevant memories;
|
|
55
|
+
observation;High-level belief formed from pattern recognition;
|
|
56
|
+
confidence;${confidence};
|
|
57
|
+
log: reflection_generated;timestamp;${timestamp};memories;${memoryCount};
|
|
58
|
+
handoff: End;
|
|
59
|
+
`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Build a YAMO block for retain (add) operation
|
|
64
|
+
* Retain operations store new memories into the system
|
|
65
|
+
*
|
|
66
|
+
* @param {Object} params - Block parameters
|
|
67
|
+
* @param {string} params.content - Memory content
|
|
68
|
+
* @param {Object} [params.metadata={}] - Memory metadata
|
|
69
|
+
* @param {string} params.id - Memory ID
|
|
70
|
+
* @param {string} [params.agentId='default'] - Agent identifier
|
|
71
|
+
* @param {string} [params.memoryType='event'] - Type of memory
|
|
72
|
+
* @returns {string} Formatted YAMO block
|
|
73
|
+
*/
|
|
74
|
+
static buildRetainBlock(params) {
|
|
75
|
+
const {
|
|
76
|
+
content,
|
|
77
|
+
metadata = {},
|
|
78
|
+
id,
|
|
79
|
+
agentId = 'default',
|
|
80
|
+
memoryType = 'event'
|
|
81
|
+
} = params;
|
|
82
|
+
|
|
83
|
+
const timestamp = new Date().toISOString();
|
|
84
|
+
const contentPreview = content.length > 100
|
|
85
|
+
? content.substring(0, 100) + '...'
|
|
86
|
+
: content;
|
|
87
|
+
|
|
88
|
+
// Escape semicolons in content for YAMO format
|
|
89
|
+
const escapedContent = contentPreview.replace(/;/g, ',');
|
|
90
|
+
|
|
91
|
+
return `agent: MemoryMesh_${agentId};
|
|
92
|
+
intent: store_memory_for_future_retrieval;
|
|
93
|
+
context:
|
|
94
|
+
memory_id;${id};
|
|
95
|
+
memory_type;${memoryType};
|
|
96
|
+
timestamp;${timestamp};
|
|
97
|
+
content_length;${content.length};
|
|
98
|
+
constraints:
|
|
99
|
+
hypothesis;New information should be integrated into world model;
|
|
100
|
+
priority: medium;
|
|
101
|
+
output:
|
|
102
|
+
memory_stored;${id};
|
|
103
|
+
content_preview;${escapedContent};
|
|
104
|
+
meta:
|
|
105
|
+
rationale;Memory persisted for semantic search and retrieval;
|
|
106
|
+
observation;Content vectorized and stored in LanceDB;
|
|
107
|
+
confidence;1.0;
|
|
108
|
+
log: memory_retained;timestamp;${timestamp};id;${id};type;${memoryType};
|
|
109
|
+
handoff: End;
|
|
110
|
+
`;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Build a YAMO block for recall (search) operation
|
|
115
|
+
* Recall operations retrieve memories based on semantic similarity
|
|
116
|
+
*
|
|
117
|
+
* @param {Object} params - Block parameters
|
|
118
|
+
* @param {string} params.query - Search query
|
|
119
|
+
* @param {number} params.resultCount - Number of results returned
|
|
120
|
+
* @param {number} [params.limit=10] - Maximum requested results
|
|
121
|
+
* @param {string} [params.agentId='default'] - Agent identifier
|
|
122
|
+
* @param {string} [params.searchType='semantic'] - Type of search
|
|
123
|
+
* @returns {string} Formatted YAMO block
|
|
124
|
+
*/
|
|
125
|
+
static buildRecallBlock(params) {
|
|
126
|
+
const {
|
|
127
|
+
query,
|
|
128
|
+
resultCount,
|
|
129
|
+
limit = 10,
|
|
130
|
+
agentId = 'default',
|
|
131
|
+
searchType = 'semantic'
|
|
132
|
+
} = params;
|
|
133
|
+
|
|
134
|
+
const timestamp = new Date().toISOString();
|
|
135
|
+
const recallRatio = resultCount > 0 ? (resultCount / limit).toFixed(2) : '0.00';
|
|
136
|
+
|
|
137
|
+
return `agent: MemoryMesh_${agentId};
|
|
138
|
+
intent: retrieve_relevant_memories;
|
|
139
|
+
context:
|
|
140
|
+
query;${query};
|
|
141
|
+
search_type;${searchType};
|
|
142
|
+
requested_limit;${limit};
|
|
143
|
+
timestamp;${timestamp};
|
|
144
|
+
constraints:
|
|
145
|
+
hypothesis;Relevant memories retrieved based on query;
|
|
146
|
+
priority: high;
|
|
147
|
+
output:
|
|
148
|
+
results_count;${resultCount};
|
|
149
|
+
recall_ratio;${recallRatio};
|
|
150
|
+
meta:
|
|
151
|
+
rationale;Semantic search finds similar content by vector similarity;
|
|
152
|
+
observation;${resultCount} memories found matching query;
|
|
153
|
+
confidence;${resultCount > 0 ? '0.9' : '0.5'};
|
|
154
|
+
log: memory_recalled;timestamp;${timestamp};results;${resultCount};query;${query};
|
|
155
|
+
handoff: End;
|
|
156
|
+
`;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Build a YAMO block for delete operation (optional)
|
|
161
|
+
* Delete operations remove memories from the system
|
|
162
|
+
*
|
|
163
|
+
* @param {Object} params - Block parameters
|
|
164
|
+
* @param {string} params.id - Memory ID being deleted
|
|
165
|
+
* @param {string} [params.agentId='default'] - Agent identifier
|
|
166
|
+
* @param {string} [params.reason='user_request'] - Reason for deletion
|
|
167
|
+
* @returns {string} Formatted YAMO block
|
|
168
|
+
*/
|
|
169
|
+
static buildDeleteBlock(params) {
|
|
170
|
+
const {
|
|
171
|
+
id,
|
|
172
|
+
agentId = 'default',
|
|
173
|
+
reason = 'user_request'
|
|
174
|
+
} = params;
|
|
175
|
+
|
|
176
|
+
const timestamp = new Date().toISOString();
|
|
177
|
+
|
|
178
|
+
return `agent: MemoryMesh_${agentId};
|
|
179
|
+
intent: remove_memory_from_storage;
|
|
180
|
+
context:
|
|
181
|
+
memory_id;${id};
|
|
182
|
+
reason;${reason};
|
|
183
|
+
timestamp;${timestamp};
|
|
184
|
+
constraints:
|
|
185
|
+
hypothesis;Memory removal should be traceable for audit;
|
|
186
|
+
priority: low;
|
|
187
|
+
output:
|
|
188
|
+
deleted;${id};
|
|
189
|
+
meta:
|
|
190
|
+
rationale;Memory removed from vector store;
|
|
191
|
+
observation;Deletion recorded for provenance;
|
|
192
|
+
confidence;1.0;
|
|
193
|
+
log: memory_deleted;timestamp;${timestamp};id;${id};
|
|
194
|
+
handoff: End;
|
|
195
|
+
`;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Validate a YAMO block structure
|
|
200
|
+
* Checks for required sections and proper formatting
|
|
201
|
+
*
|
|
202
|
+
* @param {string} yamoBlock - YAMO block to validate
|
|
203
|
+
* @returns {Object} Validation result { valid, errors }
|
|
204
|
+
*/
|
|
205
|
+
static validateBlock(yamoBlock) {
|
|
206
|
+
const errors = [];
|
|
207
|
+
|
|
208
|
+
// Check for required sections
|
|
209
|
+
const requiredSections = ['agent:', 'intent:', 'context:', 'output:', 'log:'];
|
|
210
|
+
for (const section of requiredSections) {
|
|
211
|
+
if (!yamoBlock.includes(section)) {
|
|
212
|
+
errors.push(`Missing required section: ${section}`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Check for semicolon termination
|
|
217
|
+
const lines = yamoBlock.split('\n');
|
|
218
|
+
for (const line of lines) {
|
|
219
|
+
const trimmed = line.trim();
|
|
220
|
+
if (trimmed.length > 0 && !trimmed.startsWith('//') && !trimmed.endsWith(';')) {
|
|
221
|
+
// Allow empty lines and comments
|
|
222
|
+
if (trimmed && !trimmed.startsWith('agent:') && !trimmed.startsWith('handoff:')) {
|
|
223
|
+
errors.push(`Line not semicolon-terminated: ${trimmed.substring(0, 50)}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
valid: errors.length === 0,
|
|
230
|
+
errors
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export default YamoEmitter;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* YAMO Module - YAMO Protocol support for yamo-memory-mesh
|
|
3
|
+
* Exports YAMO block construction, validation, and schema utilities
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export { YamoEmitter } from './emitter.js';
|
|
7
|
+
export * from './schema.js';
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
YamoEmitter: (await import('./emitter.js')).YamoEmitter,
|
|
11
|
+
createYamoSchema: (await import('./schema.js')).createYamoSchema,
|
|
12
|
+
createYamoTable: (await import('./schema.js')).createYamoTable,
|
|
13
|
+
validateYamoRecord: (await import('./schema.js')).validateYamoRecord,
|
|
14
|
+
generateYamoId: (await import('./schema.js')).generateYamoId
|
|
15
|
+
};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* YAMO Block Schema Definitions for yamo-memory-mesh
|
|
3
|
+
* Uses Apache Arrow Schema format for LanceDB JavaScript SDK
|
|
4
|
+
*
|
|
5
|
+
* Provides schema and table creation for YAMO block persistence.
|
|
6
|
+
* YAMO blocks provide audit trail for all memory operations.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import * as arrow from "apache-arrow";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Create YAMO blocks table schema
|
|
13
|
+
* Defines the structure for storing YAMO protocol blocks
|
|
14
|
+
*
|
|
15
|
+
* Schema includes:
|
|
16
|
+
* - Core identifiers (id, agent_id)
|
|
17
|
+
* - Operation tracking (operation_type, yamo_text)
|
|
18
|
+
* - Temporal data (timestamp)
|
|
19
|
+
* - Blockchain fields (block_hash, prev_hash) - nullable for future use
|
|
20
|
+
* - Metadata (JSON string for flexibility)
|
|
21
|
+
*
|
|
22
|
+
* @returns {import('apache-arrow').Schema} Arrow schema for YAMO blocks
|
|
23
|
+
*/
|
|
24
|
+
export function createYamoSchema() {
|
|
25
|
+
return new arrow.Schema([
|
|
26
|
+
// Core identifiers
|
|
27
|
+
new arrow.Field('id', new arrow.Utf8(), false),
|
|
28
|
+
new arrow.Field('agent_id', new arrow.Utf8(), true),
|
|
29
|
+
|
|
30
|
+
// Operation tracking
|
|
31
|
+
new arrow.Field('operation_type', new arrow.Utf8(), false), // 'retain', 'recall', 'reflect'
|
|
32
|
+
new arrow.Field('yamo_text', new arrow.Utf8(), false), // Full YAMO block content
|
|
33
|
+
|
|
34
|
+
// Temporal
|
|
35
|
+
new arrow.Field('timestamp', new arrow.Timestamp(arrow.TimeUnit.MILLISECOND), false),
|
|
36
|
+
|
|
37
|
+
// Blockchain fields (optional, nullable) - for future anchoring
|
|
38
|
+
new arrow.Field('block_hash', new arrow.Utf8(), true), // Hash of this block
|
|
39
|
+
new arrow.Field('prev_hash', new arrow.Utf8(), true), // Hash of previous block (for chain)
|
|
40
|
+
|
|
41
|
+
// Metadata (JSON string for flexibility)
|
|
42
|
+
new arrow.Field('metadata', new arrow.Utf8(), true), // Additional metadata as JSON
|
|
43
|
+
]);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Create YAMO blocks table in LanceDB
|
|
48
|
+
* Creates the table if it doesn't exist, opens it if it does
|
|
49
|
+
*
|
|
50
|
+
* @param {import('@lancedb/lancedb').Connection} db - LanceDB connection
|
|
51
|
+
* @param {string} [tableName='yamo_blocks'] - Name of the table
|
|
52
|
+
* @returns {Promise<import('@lancedb/lancedb').Table>} The created or opened table
|
|
53
|
+
* @throws {Error} If table creation fails
|
|
54
|
+
*/
|
|
55
|
+
export async function createYamoTable(db, tableName = 'yamo_blocks') {
|
|
56
|
+
try {
|
|
57
|
+
// Check if table already exists
|
|
58
|
+
const existingTables = await db.tableNames();
|
|
59
|
+
|
|
60
|
+
if (existingTables.includes(tableName)) {
|
|
61
|
+
// Table exists, open it
|
|
62
|
+
return await db.openTable(tableName);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Create new table with YAMO schema
|
|
66
|
+
const schema = createYamoSchema();
|
|
67
|
+
const table = await db.createTable(tableName, [], { schema });
|
|
68
|
+
|
|
69
|
+
return table;
|
|
70
|
+
|
|
71
|
+
} catch (error) {
|
|
72
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
73
|
+
throw new Error(`Failed to create YAMO table '${tableName}': ${message}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Validate a YAMO block record before insertion
|
|
79
|
+
* Checks for required fields and valid values
|
|
80
|
+
*
|
|
81
|
+
* @param {Object} record - Record to validate
|
|
82
|
+
* @param {string} record.id - Block ID
|
|
83
|
+
* @param {string} record.operation_type - Operation type
|
|
84
|
+
* @param {string} record.yamo_text - YAMO block text
|
|
85
|
+
* @returns {Object} Validation result { valid, errors }
|
|
86
|
+
*/
|
|
87
|
+
export function validateYamoRecord(record) {
|
|
88
|
+
const errors = [];
|
|
89
|
+
|
|
90
|
+
// Check required fields
|
|
91
|
+
if (!record.id) {
|
|
92
|
+
errors.push('Missing required field: id');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (!record.operation_type) {
|
|
96
|
+
errors.push('Missing required field: operation_type');
|
|
97
|
+
} else {
|
|
98
|
+
// Validate operation_type is one of the allowed values
|
|
99
|
+
const validTypes = ['retain', 'recall', 'reflect'];
|
|
100
|
+
if (!validTypes.includes(record.operation_type)) {
|
|
101
|
+
errors.push(`Invalid operation_type: ${record.operation_type}. Must be one of: ${validTypes.join(', ')}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (!record.yamo_text) {
|
|
106
|
+
errors.push('Missing required field: yamo_text');
|
|
107
|
+
} else {
|
|
108
|
+
// Validate YAMO block format
|
|
109
|
+
const requiredSections = ['agent:', 'intent:', 'context:', 'output:', 'log:'];
|
|
110
|
+
for (const section of requiredSections) {
|
|
111
|
+
if (!record.yamo_text.includes(section)) {
|
|
112
|
+
errors.push(`YAMO block missing required section: ${section}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
valid: errors.length === 0,
|
|
119
|
+
errors
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Generate a YAMO block ID
|
|
125
|
+
* Creates a unique ID for a YAMO block
|
|
126
|
+
*
|
|
127
|
+
* @param {string} operationType - Type of operation
|
|
128
|
+
* @returns {string} Generated YAMO block ID
|
|
129
|
+
*/
|
|
130
|
+
export function generateYamoId(operationType) {
|
|
131
|
+
const timestamp = Date.now();
|
|
132
|
+
const random = Math.random().toString(36).substring(2, 10);
|
|
133
|
+
return `yamo_${operationType}_${timestamp}_${random}`;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Check if a table uses YAMO schema
|
|
138
|
+
* Detects if a table has the YAMO block schema structure
|
|
139
|
+
*
|
|
140
|
+
* @param {import('apache-arrow').Schema} schema - Table schema to check
|
|
141
|
+
* @returns {boolean} True if YAMO schema detected
|
|
142
|
+
*/
|
|
143
|
+
export function isYamoSchema(schema) {
|
|
144
|
+
// Check for unique YAMO fields
|
|
145
|
+
const hasYamoFields = schema.fields.some(f =>
|
|
146
|
+
f.name === 'operation_type' || f.name === 'yamo_text'
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
return hasYamoFields;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Export schema function as default for consistency with lancedb/schema.js
|
|
153
|
+
export default {
|
|
154
|
+
createYamoSchema,
|
|
155
|
+
createYamoTable,
|
|
156
|
+
validateYamoRecord,
|
|
157
|
+
generateYamoId,
|
|
158
|
+
isYamoSchema
|
|
159
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yamo/memory-mesh",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Portable semantic memory system with Layer 0 Scrubber for YAMO agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/memory/index.js",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"index.d.ts"
|
|
18
18
|
],
|
|
19
19
|
"scripts": {
|
|
20
|
-
"test": "npm run type-check",
|
|
20
|
+
"test": "npm run type-check && node --test test/*.test.js",
|
|
21
21
|
"type-check": "tsc --noEmit"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
package/skills/SKILL.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: yamo-super
|
|
3
|
-
description: For all code improvement or creation tasks, strictly adhere to the logic, agents, and constraints defined in
|
|
3
|
+
description: A comprehensive AI coding workflow system that orchestrates test-driven development, systematic debugging, collaborative planning, git worktree isolation, and dual-mode execution (subagent-driven or batched) with mandatory TDD red-green-refactor cycles, root-cause analysis, two-stage code review, and branch lifecycle management.For all code improvement or creation tasks, strictly adhere to the logic, agents, and constraints defined in skill-super.yamo.
|
|
4
4
|
---
|