@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.
@@ -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.1.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 ~/.claude/skills/yamo-super/skill-super.yamo or ~/.gemini/skills/yamo-super/skill-super.yamo.
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
  ---