@yamo/memory-mesh 3.2.1 → 3.2.4
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 +36 -4
- package/bin/memory_mesh.js +82 -1
- package/lib/memory/memory-mesh.js +25 -0
- package/lib/memory/memory-mesh.ts +24 -0
- package/lib/memory/schema.d.ts +9 -0
- package/lib/memory/schema.js +54 -7
- package/lib/memory/schema.ts +51 -7
- package/lib/yamo/schema.js +16 -6
- package/lib/yamo/schema.ts +16 -6
- package/package.json +12 -8
package/README.md
CHANGED
|
@@ -47,14 +47,46 @@ The installer will:
|
|
|
47
47
|
|
|
48
48
|
### CLI
|
|
49
49
|
|
|
50
|
+
The `memory-mesh` CLI provides seven commands for full subconscious CRUD and recall:
|
|
51
|
+
|
|
50
52
|
```bash
|
|
51
53
|
# Store a memory (automatically scrubbed & embedded)
|
|
52
|
-
|
|
54
|
+
memory-mesh store --content "My important memory" --type insight
|
|
55
|
+
|
|
56
|
+
# Store with full provenance metadata
|
|
57
|
+
memory-mesh store -c "Insight text" -t decision -r "Improves latency" -h "Caching reduces p95"
|
|
58
|
+
|
|
59
|
+
# Bulk-ingest a directory (recursive, by extension)
|
|
60
|
+
memory-mesh pull ./docs --extension ".md,.yamo" --type documentation
|
|
61
|
+
|
|
62
|
+
# Semantic search
|
|
63
|
+
memory-mesh search "query about orchestration" --limit 5
|
|
64
|
+
|
|
65
|
+
# Retrieve a specific record by ID
|
|
66
|
+
memory-mesh get --id mem_abc123
|
|
53
67
|
|
|
54
|
-
#
|
|
55
|
-
|
|
68
|
+
# Delete a record by ID
|
|
69
|
+
memory-mesh delete --id mem_abc123
|
|
70
|
+
|
|
71
|
+
# Synthesize insights from recent memories
|
|
72
|
+
memory-mesh reflect --topic "bugs" --lookback 10
|
|
73
|
+
|
|
74
|
+
# Database health and statistics
|
|
75
|
+
memory-mesh stats
|
|
56
76
|
```
|
|
57
77
|
|
|
78
|
+
**Command Reference:**
|
|
79
|
+
|
|
80
|
+
| Command | Key Options | Description |
|
|
81
|
+
|---------|-------------|-------------|
|
|
82
|
+
| `store` | `-c/--content` (required), `-t/--type`, `-r/--rationale`, `-h/--hypothesis` | Persist a semantic memory |
|
|
83
|
+
| `pull` | `<path>` (required), `-e/--extension`, `-t/--type` | Bulk-ingest a directory |
|
|
84
|
+
| `search` | `<query>` (required), `-l/--limit` | Semantic recall |
|
|
85
|
+
| `get` | `-i/--id` (required) | Fetch a record by ID |
|
|
86
|
+
| `delete` | `-i/--id` (required) | Remove a record by ID |
|
|
87
|
+
| `reflect` | `-t/--topic`, `-l/--lookback` | Synthesize insights from memories |
|
|
88
|
+
| `stats` | — | DB health, count, embedding model |
|
|
89
|
+
|
|
58
90
|
### Node.js API
|
|
59
91
|
|
|
60
92
|
```javascript
|
|
@@ -173,7 +205,7 @@ docker run -v $(pwd)/data:/app/runtime/data \
|
|
|
173
205
|
|
|
174
206
|
## About YAMO Protocol
|
|
175
207
|
|
|
176
|
-
Memory Mesh is built on the **YAMO (Yet Another
|
|
208
|
+
Memory Mesh is built on the **YAMO (Yet Another Model Ontology) Protocol** - a structured language for transparent AI agent collaboration with immutable provenance tracking.
|
|
177
209
|
|
|
178
210
|
**YAMO Protocol Features:**
|
|
179
211
|
- **Structured Agent Workflows**: Semicolon-terminated constraints, explicit handoff chains
|
package/bin/memory_mesh.js
CHANGED
|
@@ -21,7 +21,7 @@ const program = new Command();
|
|
|
21
21
|
program
|
|
22
22
|
.name('memory-mesh')
|
|
23
23
|
.description('YAMO Semantic Subconscious - Protocol-Native CLI')
|
|
24
|
-
.version('3.2.
|
|
24
|
+
.version('3.2.3');
|
|
25
25
|
|
|
26
26
|
// Helper for beautiful logging
|
|
27
27
|
const ui = {
|
|
@@ -194,4 +194,85 @@ program
|
|
|
194
194
|
}
|
|
195
195
|
});
|
|
196
196
|
|
|
197
|
+
// 5. Get Command
|
|
198
|
+
program
|
|
199
|
+
.command('get')
|
|
200
|
+
.description('Retrieve a memory record by ID')
|
|
201
|
+
.requiredOption('-i, --id <id>', 'Memory record ID')
|
|
202
|
+
.action(async (options) => {
|
|
203
|
+
const mesh = new MemoryMesh();
|
|
204
|
+
try {
|
|
205
|
+
const record = await mesh.get(options.id);
|
|
206
|
+
if (!record) {
|
|
207
|
+
ui.warn(`Record not found: ${options.id}`);
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
const meta = typeof record.metadata === 'string' ? JSON.parse(record.metadata) : (record.metadata || {});
|
|
211
|
+
ui.header(`Memory ${options.id}`);
|
|
212
|
+
console.log(`${pc.bold('ID:')} ${pc.dim(record.id)}`);
|
|
213
|
+
console.log(`${pc.bold('Type:')} ${pc.dim(meta.type || 'event')}`);
|
|
214
|
+
console.log(`${pc.bold('Created:')} ${pc.dim(record.created_at)}`);
|
|
215
|
+
console.log(`\n${pc.white(record.content)}`);
|
|
216
|
+
} catch (err) {
|
|
217
|
+
ui.error(`Get failed: ${err.message}`);
|
|
218
|
+
process.exit(1);
|
|
219
|
+
} finally {
|
|
220
|
+
await mesh.close();
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// 6. Delete Command
|
|
225
|
+
program
|
|
226
|
+
.command('delete')
|
|
227
|
+
.description('Permanently remove a memory record by ID')
|
|
228
|
+
.requiredOption('-i, --id <id>', 'Memory record ID to delete')
|
|
229
|
+
.action(async (options) => {
|
|
230
|
+
const mesh = new MemoryMesh();
|
|
231
|
+
try {
|
|
232
|
+
await mesh.delete(options.id);
|
|
233
|
+
ui.success(`Deleted record ${pc.bold(options.id)}`);
|
|
234
|
+
} catch (err) {
|
|
235
|
+
ui.error(`Delete failed: ${err.message}`);
|
|
236
|
+
process.exit(1);
|
|
237
|
+
} finally {
|
|
238
|
+
await mesh.close();
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
// 7. Reflect Command
|
|
243
|
+
program
|
|
244
|
+
.command('reflect')
|
|
245
|
+
.description('Synthesize insights from stored memories')
|
|
246
|
+
.option('-t, --topic <topic>', 'Focus the reflection on a specific topic')
|
|
247
|
+
.option('-l, --lookback <number>', 'Number of memories to review', '10')
|
|
248
|
+
.action(async (options) => {
|
|
249
|
+
const mesh = new MemoryMesh();
|
|
250
|
+
try {
|
|
251
|
+
ui.info(`Reflecting on ${options.topic ? `"${pc.italic(options.topic)}"` : 'recent memories'}...`);
|
|
252
|
+
const result = await mesh.reflect({
|
|
253
|
+
topic: options.topic,
|
|
254
|
+
lookback: parseInt(options.lookback),
|
|
255
|
+
});
|
|
256
|
+
ui.header('Reflection');
|
|
257
|
+
if (result.reflection) {
|
|
258
|
+
console.log(pc.white(result.reflection));
|
|
259
|
+
console.log(`\n${pc.bold('Confidence:')} ${pc.cyan((result.confidence * 100).toFixed(0))}%`);
|
|
260
|
+
} else {
|
|
261
|
+
console.log(pc.dim(`Reviewed ${result.count} memories${result.topic ? ` on topic: ${result.topic}` : ''}`));
|
|
262
|
+
console.log(`\n${pc.bold('Prompt for LLM:')}\n${pc.white(result.prompt)}`);
|
|
263
|
+
if (result.context?.length) {
|
|
264
|
+
console.log('');
|
|
265
|
+
result.context.forEach((m, i) => {
|
|
266
|
+
console.log(`${pc.cyan(`Memory ${i + 1}:`)} ${pc.white(m.content.substring(0, 200))}${m.content.length > 200 ? '...' : ''}`);
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
} catch (err) {
|
|
271
|
+
ui.error(`Reflect failed: ${err.message}`);
|
|
272
|
+
process.exit(1);
|
|
273
|
+
} finally {
|
|
274
|
+
await mesh.close();
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
|
|
197
278
|
program.parse();
|
|
@@ -288,8 +288,16 @@ export class MemoryMesh {
|
|
|
288
288
|
const skillSchema = createSynthesizedSkillSchema(this.vectorDimension);
|
|
289
289
|
this.skillTable = await this.client.db.createTable("synthesized_skills", [], {
|
|
290
290
|
schema: skillSchema,
|
|
291
|
+
storageOptions: { new_table_data_storage_version: "stable" },
|
|
291
292
|
});
|
|
292
293
|
}
|
|
294
|
+
// Migrate manifest paths to V2 layout (idempotent)
|
|
295
|
+
try {
|
|
296
|
+
await this.skillTable.migrateManifestPathsV2();
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
// Already migrated or not a local table — ignore
|
|
300
|
+
}
|
|
293
301
|
if (process.env.YAMO_DEBUG === "true") {
|
|
294
302
|
logger.debug("YAMO blocks and synthesized skills tables initialized");
|
|
295
303
|
}
|
|
@@ -1808,6 +1816,23 @@ export async function run() {
|
|
|
1808
1816
|
else if (action === "stats") {
|
|
1809
1817
|
process.stdout.write(`[MemoryMesh] Database Statistics:\n${JSON.stringify({ status: "ok", stats: await mesh.stats() }, null, 2)}\n`);
|
|
1810
1818
|
}
|
|
1819
|
+
else if (action === "get") {
|
|
1820
|
+
const record = await mesh.get(input.id);
|
|
1821
|
+
if (!record) {
|
|
1822
|
+
process.stdout.write(`[MemoryMesh] Record not found: ${input.id}\n${JSON.stringify({ status: "not_found", id: input.id })}\n`);
|
|
1823
|
+
}
|
|
1824
|
+
else {
|
|
1825
|
+
process.stdout.write(`[MemoryMesh] Record ${record.id}\n${JSON.stringify({ status: "ok", record }, null, 2)}\n`);
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
else if (action === "delete") {
|
|
1829
|
+
await mesh.delete(input.id);
|
|
1830
|
+
process.stdout.write(`[MemoryMesh] Deleted record ${input.id}\n${JSON.stringify({ status: "ok", id: input.id })}\n`);
|
|
1831
|
+
}
|
|
1832
|
+
else if (action === "reflect") {
|
|
1833
|
+
const result = await mesh.reflect({ topic: input.topic, lookback: input.lookback });
|
|
1834
|
+
process.stdout.write(`[MemoryMesh] Reflection complete.\n${JSON.stringify({ status: "ok", result }, null, 2)}\n`);
|
|
1835
|
+
}
|
|
1811
1836
|
else {
|
|
1812
1837
|
logger.error({ action }, "Unknown action");
|
|
1813
1838
|
process.exit(1);
|
|
@@ -320,8 +320,16 @@ export class MemoryMesh {
|
|
|
320
320
|
const skillSchema = createSynthesizedSkillSchema(this.vectorDimension);
|
|
321
321
|
this.skillTable = await this.client.db.createTable("synthesized_skills", [], {
|
|
322
322
|
schema: skillSchema,
|
|
323
|
+
storageOptions: { new_table_data_storage_version: "stable" },
|
|
323
324
|
});
|
|
324
325
|
}
|
|
326
|
+
// Migrate manifest paths to V2 layout (idempotent)
|
|
327
|
+
try {
|
|
328
|
+
await this.skillTable.migrateManifestPathsV2();
|
|
329
|
+
}
|
|
330
|
+
catch {
|
|
331
|
+
// Already migrated or not a local table — ignore
|
|
332
|
+
}
|
|
325
333
|
if (process.env.YAMO_DEBUG === "true") {
|
|
326
334
|
logger.debug("YAMO blocks and synthesized skills tables initialized");
|
|
327
335
|
}
|
|
@@ -1895,6 +1903,22 @@ export async function run() {
|
|
|
1895
1903
|
else if (action === "stats") {
|
|
1896
1904
|
process.stdout.write(`[MemoryMesh] Database Statistics:\n${JSON.stringify({ status: "ok", stats: await mesh.stats() }, null, 2)}\n`);
|
|
1897
1905
|
}
|
|
1906
|
+
else if (action === "get") {
|
|
1907
|
+
const record = await mesh.get(input.id);
|
|
1908
|
+
if (!record) {
|
|
1909
|
+
process.stdout.write(`[MemoryMesh] Record not found: ${input.id}\n${JSON.stringify({ status: "not_found", id: input.id })}\n`);
|
|
1910
|
+
} else {
|
|
1911
|
+
process.stdout.write(`[MemoryMesh] Record ${record.id}\n${JSON.stringify({ status: "ok", record }, null, 2)}\n`);
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
else if (action === "delete") {
|
|
1915
|
+
await mesh.delete(input.id);
|
|
1916
|
+
process.stdout.write(`[MemoryMesh] Deleted record ${input.id}\n${JSON.stringify({ status: "ok", id: input.id })}\n`);
|
|
1917
|
+
}
|
|
1918
|
+
else if (action === "reflect") {
|
|
1919
|
+
const result = await mesh.reflect({ topic: input.topic, lookback: input.lookback });
|
|
1920
|
+
process.stdout.write(`[MemoryMesh] Reflection complete.\n${JSON.stringify({ status: "ok", result }, null, 2)}\n`);
|
|
1921
|
+
}
|
|
1898
1922
|
else {
|
|
1899
1923
|
logger.error({ action }, "Unknown action");
|
|
1900
1924
|
process.exit(1);
|
package/lib/memory/schema.d.ts
CHANGED
|
@@ -57,6 +57,14 @@ export declare function createSynthesizedSkillSchema(vectorDim?: number): arrow.
|
|
|
57
57
|
* @returns {boolean} True if V2 schema detected
|
|
58
58
|
*/
|
|
59
59
|
export declare function isSchemaV2(schema: any): any;
|
|
60
|
+
/**
|
|
61
|
+
* Migrate an existing table to V2:
|
|
62
|
+
* 1. Migrate manifest paths to V2 layout (efficient versioning, idempotent)
|
|
63
|
+
* 2. Add nullable V2 columns to memory_entries-style tables if not already present
|
|
64
|
+
*
|
|
65
|
+
* Safe to call on any table — non-memory tables skip the schema column additions.
|
|
66
|
+
*/
|
|
67
|
+
export declare function migrateTableV2(table: any): Promise<void>;
|
|
60
68
|
/**
|
|
61
69
|
* Memory table schema using Apache Arrow format (default 384 dimensions)
|
|
62
70
|
* @deprecated Use createMemorySchema(vectorDim) for dynamic dimensions
|
|
@@ -113,6 +121,7 @@ declare const _default: {
|
|
|
113
121
|
createMemorySchema: typeof createMemorySchema;
|
|
114
122
|
createMemorySchemaV2: typeof createMemorySchemaV2;
|
|
115
123
|
isSchemaV2: typeof isSchemaV2;
|
|
124
|
+
migrateTableV2: typeof migrateTableV2;
|
|
116
125
|
getEmbeddingDimension: typeof getEmbeddingDimension;
|
|
117
126
|
DEFAULT_VECTOR_DIMENSION: number;
|
|
118
127
|
EMBEDDING_DIMENSIONS: {
|
package/lib/memory/schema.js
CHANGED
|
@@ -112,6 +112,47 @@ export function createSynthesizedSkillSchema(vectorDim = DEFAULT_VECTOR_DIMENSIO
|
|
|
112
112
|
export function isSchemaV2(schema) {
|
|
113
113
|
return schema.fields.some((f) => f.name === "session_id");
|
|
114
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Migrate an existing table to V2:
|
|
117
|
+
* 1. Migrate manifest paths to V2 layout (efficient versioning, idempotent)
|
|
118
|
+
* 2. Add nullable V2 columns to memory_entries-style tables if not already present
|
|
119
|
+
*
|
|
120
|
+
* Safe to call on any table — non-memory tables skip the schema column additions.
|
|
121
|
+
*/
|
|
122
|
+
export async function migrateTableV2(table) {
|
|
123
|
+
// Step 1: manifest path migration (idempotent on already-migrated tables)
|
|
124
|
+
try {
|
|
125
|
+
await table.migrateManifestPathsV2();
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// Already migrated or not a local table — ignore
|
|
129
|
+
}
|
|
130
|
+
// Step 2: add V2 schema columns if this is a memory_entries-style table (V1)
|
|
131
|
+
// Guard: schema() may not exist on mock tables in tests
|
|
132
|
+
if (typeof table.schema !== "function")
|
|
133
|
+
return;
|
|
134
|
+
let schema;
|
|
135
|
+
try {
|
|
136
|
+
schema = await table.schema();
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return; // Can't inspect schema — skip
|
|
140
|
+
}
|
|
141
|
+
if (isSchemaV2(schema))
|
|
142
|
+
return;
|
|
143
|
+
// Only add V2 columns if the table has the V1 memory_entries shape
|
|
144
|
+
const fieldNames = schema.fields.map((f) => f.name);
|
|
145
|
+
if (!fieldNames.includes("content") || !fieldNames.includes("vector"))
|
|
146
|
+
return;
|
|
147
|
+
await table.addColumns([
|
|
148
|
+
{ name: "session_id", valueSql: "cast(null as string)" },
|
|
149
|
+
{ name: "agent_id", valueSql: "cast(null as string)" },
|
|
150
|
+
{ name: "memory_type", valueSql: "cast(null as string)" },
|
|
151
|
+
{ name: "importance_score", valueSql: "cast(null as float)" },
|
|
152
|
+
{ name: "access_count", valueSql: "cast(null as int)" },
|
|
153
|
+
{ name: "last_accessed", valueSql: "cast(null as timestamp)" },
|
|
154
|
+
]);
|
|
155
|
+
}
|
|
115
156
|
/**
|
|
116
157
|
* Memory table schema using Apache Arrow format (default 384 dimensions)
|
|
117
158
|
* @deprecated Use createMemorySchema(vectorDim) for dynamic dimensions
|
|
@@ -153,16 +194,21 @@ export async function createMemoryTable(db, tableName = "memory_entries") {
|
|
|
153
194
|
*/
|
|
154
195
|
export async function createMemoryTableWithDimension(db, tableName, vectorDim) {
|
|
155
196
|
try {
|
|
156
|
-
// Check if table already exists
|
|
157
197
|
const existingTables = await db.tableNames();
|
|
198
|
+
let table;
|
|
158
199
|
if (existingTables.includes(tableName)) {
|
|
159
|
-
|
|
200
|
+
table = await db.openTable(tableName);
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
// New tables use V2 schema and stable storage format
|
|
204
|
+
const schema = createMemorySchemaV2(vectorDim);
|
|
205
|
+
table = await db.createTable(tableName, [], {
|
|
206
|
+
schema,
|
|
207
|
+
storageOptions: { new_table_data_storage_version: "stable" },
|
|
208
|
+
});
|
|
160
209
|
}
|
|
161
|
-
//
|
|
162
|
-
|
|
163
|
-
// Create table with schema
|
|
164
|
-
// LanceDB v0.23.0+ accepts empty array as initial data with schema option
|
|
165
|
-
const table = await db.createTable(tableName, [], { schema }); // Cast to any because lancedb types might be strict about options
|
|
210
|
+
// Migrate existing tables to V2 (manifest paths + schema columns, idempotent)
|
|
211
|
+
await migrateTableV2(table);
|
|
166
212
|
return table;
|
|
167
213
|
}
|
|
168
214
|
catch (error) {
|
|
@@ -178,6 +224,7 @@ export default {
|
|
|
178
224
|
createMemorySchema,
|
|
179
225
|
createMemorySchemaV2,
|
|
180
226
|
isSchemaV2,
|
|
227
|
+
migrateTableV2,
|
|
181
228
|
getEmbeddingDimension,
|
|
182
229
|
DEFAULT_VECTOR_DIMENSION,
|
|
183
230
|
EMBEDDING_DIMENSIONS,
|
package/lib/memory/schema.ts
CHANGED
|
@@ -112,6 +112,44 @@ export function createSynthesizedSkillSchema(vectorDim = DEFAULT_VECTOR_DIMENSIO
|
|
|
112
112
|
export function isSchemaV2(schema) {
|
|
113
113
|
return schema.fields.some((f) => f.name === "session_id");
|
|
114
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Migrate an existing table to V2:
|
|
117
|
+
* 1. Migrate manifest paths to V2 layout (efficient versioning, idempotent)
|
|
118
|
+
* 2. Add nullable V2 columns to memory_entries-style tables if not already present
|
|
119
|
+
*
|
|
120
|
+
* Safe to call on any table — non-memory tables skip the schema column additions.
|
|
121
|
+
*/
|
|
122
|
+
export async function migrateTableV2(table) {
|
|
123
|
+
// Step 1: manifest path migration (idempotent on already-migrated tables)
|
|
124
|
+
try {
|
|
125
|
+
await table.migrateManifestPathsV2();
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// Already migrated or not a local table — ignore
|
|
129
|
+
}
|
|
130
|
+
// Step 2: add V2 schema columns if this is a memory_entries-style table (V1)
|
|
131
|
+
// Guard: schema() may not exist on mock tables in tests
|
|
132
|
+
if (typeof table.schema !== "function") return;
|
|
133
|
+
let schema;
|
|
134
|
+
try {
|
|
135
|
+
schema = await table.schema();
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
return; // Can't inspect schema — skip
|
|
139
|
+
}
|
|
140
|
+
if (isSchemaV2(schema)) return;
|
|
141
|
+
// Only add V2 columns if the table has the V1 memory_entries shape
|
|
142
|
+
const fieldNames = schema.fields.map((f) => f.name);
|
|
143
|
+
if (!fieldNames.includes("content") || !fieldNames.includes("vector")) return;
|
|
144
|
+
await table.addColumns([
|
|
145
|
+
{ name: "session_id", valueSql: "cast(null as string)" },
|
|
146
|
+
{ name: "agent_id", valueSql: "cast(null as string)" },
|
|
147
|
+
{ name: "memory_type", valueSql: "cast(null as string)" },
|
|
148
|
+
{ name: "importance_score", valueSql: "cast(null as float)" },
|
|
149
|
+
{ name: "access_count", valueSql: "cast(null as int)" },
|
|
150
|
+
{ name: "last_accessed", valueSql: "cast(null as timestamp)" },
|
|
151
|
+
]);
|
|
152
|
+
}
|
|
115
153
|
/**
|
|
116
154
|
* Memory table schema using Apache Arrow format (default 384 dimensions)
|
|
117
155
|
* @deprecated Use createMemorySchema(vectorDim) for dynamic dimensions
|
|
@@ -153,16 +191,21 @@ export async function createMemoryTable(db, tableName = "memory_entries") {
|
|
|
153
191
|
*/
|
|
154
192
|
export async function createMemoryTableWithDimension(db, tableName, vectorDim) {
|
|
155
193
|
try {
|
|
156
|
-
// Check if table already exists
|
|
157
194
|
const existingTables = await db.tableNames();
|
|
195
|
+
let table;
|
|
158
196
|
if (existingTables.includes(tableName)) {
|
|
159
|
-
|
|
197
|
+
table = await db.openTable(tableName);
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
// New tables use V2 schema and stable storage format
|
|
201
|
+
const schema = createMemorySchemaV2(vectorDim);
|
|
202
|
+
table = await db.createTable(tableName, [], {
|
|
203
|
+
schema,
|
|
204
|
+
storageOptions: { new_table_data_storage_version: "stable" },
|
|
205
|
+
});
|
|
160
206
|
}
|
|
161
|
-
//
|
|
162
|
-
|
|
163
|
-
// Create table with schema
|
|
164
|
-
// LanceDB v0.23.0+ accepts empty array as initial data with schema option
|
|
165
|
-
const table = await db.createTable(tableName, [], { schema }); // Cast to any because lancedb types might be strict about options
|
|
207
|
+
// Migrate existing tables to V2 (manifest paths + schema columns, idempotent)
|
|
208
|
+
await migrateTableV2(table);
|
|
166
209
|
return table;
|
|
167
210
|
}
|
|
168
211
|
catch (error) {
|
|
@@ -178,6 +221,7 @@ export default {
|
|
|
178
221
|
createMemorySchema,
|
|
179
222
|
createMemorySchemaV2,
|
|
180
223
|
isSchemaV2,
|
|
224
|
+
migrateTableV2,
|
|
181
225
|
getEmbeddingDimension,
|
|
182
226
|
DEFAULT_VECTOR_DIMENSION,
|
|
183
227
|
EMBEDDING_DIMENSIONS,
|
package/lib/yamo/schema.js
CHANGED
|
@@ -40,15 +40,25 @@ export function createYamoSchema() {
|
|
|
40
40
|
*/
|
|
41
41
|
export async function createYamoTable(db, tableName = "yamo_blocks") {
|
|
42
42
|
try {
|
|
43
|
-
// Check if table already exists
|
|
44
43
|
const existingTables = await db.tableNames();
|
|
44
|
+
let table;
|
|
45
45
|
if (existingTables.includes(tableName)) {
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
table = await db.openTable(tableName);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
const schema = createYamoSchema();
|
|
50
|
+
table = await db.createTable(tableName, [], {
|
|
51
|
+
schema,
|
|
52
|
+
storageOptions: { new_table_data_storage_version: "stable" },
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
// Migrate manifest paths to V2 layout (idempotent)
|
|
56
|
+
try {
|
|
57
|
+
await table.migrateManifestPathsV2();
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Already migrated or not a local table — ignore
|
|
48
61
|
}
|
|
49
|
-
// Create new table with YAMO schema
|
|
50
|
-
const schema = createYamoSchema();
|
|
51
|
-
const table = await db.createTable(tableName, [], { schema });
|
|
52
62
|
return table;
|
|
53
63
|
}
|
|
54
64
|
catch (error) {
|
package/lib/yamo/schema.ts
CHANGED
|
@@ -40,15 +40,25 @@ export function createYamoSchema() {
|
|
|
40
40
|
*/
|
|
41
41
|
export async function createYamoTable(db, tableName = "yamo_blocks") {
|
|
42
42
|
try {
|
|
43
|
-
// Check if table already exists
|
|
44
43
|
const existingTables = await db.tableNames();
|
|
44
|
+
let table;
|
|
45
45
|
if (existingTables.includes(tableName)) {
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
table = await db.openTable(tableName);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
const schema = createYamoSchema();
|
|
50
|
+
table = await db.createTable(tableName, [], {
|
|
51
|
+
schema,
|
|
52
|
+
storageOptions: { new_table_data_storage_version: "stable" },
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
// Migrate manifest paths to V2 layout (idempotent)
|
|
56
|
+
try {
|
|
57
|
+
await table.migrateManifestPathsV2();
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Already migrated or not a local table — ignore
|
|
48
61
|
}
|
|
49
|
-
// Create new table with YAMO schema
|
|
50
|
-
const schema = createYamoSchema();
|
|
51
|
-
const table = await db.createTable(tableName, [], { schema });
|
|
52
62
|
return table;
|
|
53
63
|
}
|
|
54
64
|
catch (error) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yamo/memory-mesh",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.4",
|
|
4
4
|
"description": "Portable semantic memory system with Layer 0 Scrubber for YAMO agents (v3 Singularity Edition)",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/yamo-protocol/yamo-memory-mesh"
|
|
8
|
+
},
|
|
5
9
|
"type": "module",
|
|
6
10
|
"main": "lib/memory/index.js",
|
|
7
11
|
"types": "lib/memory/index.d.ts",
|
|
@@ -23,16 +27,16 @@
|
|
|
23
27
|
"prepublishOnly": "npm run build"
|
|
24
28
|
},
|
|
25
29
|
"dependencies": {
|
|
26
|
-
"@lancedb/lancedb": "^0.
|
|
27
|
-
"@xenova/transformers": "^2.17.
|
|
28
|
-
"apache-arrow": "^
|
|
30
|
+
"@lancedb/lancedb": "^0.26.2",
|
|
31
|
+
"@xenova/transformers": "^2.17.2",
|
|
32
|
+
"apache-arrow": "^18.1.0",
|
|
29
33
|
"commander": "^14.0.3",
|
|
30
|
-
"onnxruntime-node": "^1.
|
|
34
|
+
"onnxruntime-node": "^1.24.3",
|
|
31
35
|
"pino": "^10.3.1",
|
|
32
36
|
"pino-pretty": "^13.1.3",
|
|
33
37
|
"cli-progress": "^3.12.0",
|
|
34
38
|
"picocolors": "^1.1.1",
|
|
35
|
-
"glob": "^
|
|
39
|
+
"glob": "^13.0.6"
|
|
36
40
|
},
|
|
37
41
|
"author": "Soverane Labs",
|
|
38
42
|
"license": "MIT",
|
|
@@ -40,9 +44,9 @@
|
|
|
40
44
|
"node": ">=18.0.0"
|
|
41
45
|
},
|
|
42
46
|
"devDependencies": {
|
|
43
|
-
"@types/node": "^25.0
|
|
47
|
+
"@types/node": "^25.4.0",
|
|
44
48
|
"cohere-ai": "^7.20.0",
|
|
45
|
-
"openai": "^6.
|
|
49
|
+
"openai": "^6.27.0",
|
|
46
50
|
"typescript": "^5.9.3"
|
|
47
51
|
}
|
|
48
52
|
}
|