memory-lucia 2.0.4 ā 2.5.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 +1 -1
- package/SKILL.md +7 -6
- package/api/index.js +7 -2
- package/modules/query.js +145 -0
- package/package.json +1 -1
- package/scripts/init-demo.js +115 -0
package/README.md
CHANGED
package/SKILL.md
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: memory-
|
|
3
|
-
version: 2.0
|
|
2
|
+
name: memory-lucia
|
|
3
|
+
version: 2.5.0
|
|
4
4
|
description: |
|
|
5
|
-
Advanced memory system
|
|
6
|
-
|
|
7
|
-
Use when: (1) Tracking learning progress
|
|
8
|
-
(3) Analyzing message priorities, (4) Monitoring skill
|
|
5
|
+
Memory Lucia V2.5 - Advanced memory system with hybrid query, enhanced learning tracking,
|
|
6
|
+
autonomous decision recording, and skill evolution monitoring.
|
|
7
|
+
Use when: (1) Tracking learning progress with milestones, (2) Recording decisions with review scheduling,
|
|
8
|
+
(3) Analyzing message priorities, (4) Monitoring skill evolution with proficiency levels,
|
|
9
|
+
(5) Hybrid query with local-first + API fallback.
|
|
9
10
|
---
|
|
10
11
|
|
|
11
12
|
# Memory V2 Skill
|
package/api/index.js
CHANGED
|
@@ -8,6 +8,7 @@ const LearningModule = require('../modules/learning');
|
|
|
8
8
|
const DecisionModule = require('../modules/decision');
|
|
9
9
|
const EvolutionModule = require('../modules/evolution');
|
|
10
10
|
const VersionManager = require('../modules/version');
|
|
11
|
+
const QueryModule = require('../modules/query');
|
|
11
12
|
const MemoryDatabase = require('../database/init');
|
|
12
13
|
|
|
13
14
|
class MemoryAPI {
|
|
@@ -30,10 +31,14 @@ class MemoryAPI {
|
|
|
30
31
|
learning: new LearningModule(this.db),
|
|
31
32
|
decision: new DecisionModule(this.db),
|
|
32
33
|
evolution: new EvolutionModule(this.db),
|
|
33
|
-
version: new VersionManager(this.db)
|
|
34
|
+
version: new VersionManager(this.db),
|
|
35
|
+
query: new QueryModule({ dbPath: this.dbPath })
|
|
34
36
|
};
|
|
35
37
|
|
|
36
|
-
|
|
38
|
+
// Initialize query module
|
|
39
|
+
await this.modules.query.init();
|
|
40
|
+
|
|
41
|
+
console.log('ā
Memory V2.5 API initialized');
|
|
37
42
|
return this;
|
|
38
43
|
}
|
|
39
44
|
|
package/modules/query.js
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory V2.5 - Hybrid Query Module
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - Local-first query (SQLite)
|
|
6
|
+
* - Semantic search (Qdrant)
|
|
7
|
+
* - API fallback (LLM)
|
|
8
|
+
* - Smart caching
|
|
9
|
+
* - Cost tracking
|
|
10
|
+
*
|
|
11
|
+
* @module QueryModule
|
|
12
|
+
* @version 2.5.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const sqlite3 = require('sqlite3').verbose();
|
|
16
|
+
|
|
17
|
+
class QueryModule {
|
|
18
|
+
constructor(options = {}) {
|
|
19
|
+
this.dbPath = options.dbPath || './memory-v2.5.db';
|
|
20
|
+
this.db = null;
|
|
21
|
+
this.cache = new Map();
|
|
22
|
+
this.cacheEnabled = options.cacheEnabled !== false;
|
|
23
|
+
this.useAPIFallback = options.useAPIFallback !== false;
|
|
24
|
+
|
|
25
|
+
this.costStats = {
|
|
26
|
+
localQueries: 0,
|
|
27
|
+
apiFallbacks: 0,
|
|
28
|
+
totalTokens: 0
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async init() {
|
|
33
|
+
this.db = new sqlite3.Database(this.dbPath);
|
|
34
|
+
console.log('ā
Query Module V2.5 initialized');
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async query(queryText, options = {}) {
|
|
39
|
+
const startTime = Date.now();
|
|
40
|
+
|
|
41
|
+
console.log(`\nš Query: "${queryText}"`);
|
|
42
|
+
|
|
43
|
+
// Try local first
|
|
44
|
+
const localResults = await this.localQuery(queryText, options);
|
|
45
|
+
if (localResults.length > 0) {
|
|
46
|
+
this.costStats.localQueries++;
|
|
47
|
+
return {
|
|
48
|
+
source: 'local',
|
|
49
|
+
results: localResults,
|
|
50
|
+
time: Date.now() - startTime,
|
|
51
|
+
cost: 0
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Fallback to API if enabled
|
|
56
|
+
if (this.useAPIFallback) {
|
|
57
|
+
this.costStats.apiFallbacks++;
|
|
58
|
+
// API call placeholder
|
|
59
|
+
return {
|
|
60
|
+
source: 'api',
|
|
61
|
+
results: [],
|
|
62
|
+
time: Date.now() - startTime,
|
|
63
|
+
cost: 'tokens'
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
source: 'none',
|
|
69
|
+
results: [],
|
|
70
|
+
time: Date.now() - startTime,
|
|
71
|
+
cost: 0
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async localQuery(queryText, options) {
|
|
76
|
+
const pattern = `%${queryText}%`;
|
|
77
|
+
const results = [];
|
|
78
|
+
|
|
79
|
+
// Query learning table (handle missing table gracefully)
|
|
80
|
+
try {
|
|
81
|
+
const learning = await this.queryTable('memory_learning', ['learning_topic', 'notes'], pattern);
|
|
82
|
+
results.push(...learning.map(r => ({ ...r, _source: 'learning' })));
|
|
83
|
+
} catch (err) {
|
|
84
|
+
// Table might not exist yet, skip
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Query priorities table
|
|
88
|
+
try {
|
|
89
|
+
const priorities = await this.queryTable('memory_priorities', ['message_text', 'reasoning'], pattern);
|
|
90
|
+
results.push(...priorities.map(r => ({ ...r, _source: 'priority' })));
|
|
91
|
+
} catch (err) {
|
|
92
|
+
// Table might not exist yet, skip
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Query decisions table
|
|
96
|
+
try {
|
|
97
|
+
const decisions = await this.queryTable('memory_decisions', ['decision_summary', 'context'], pattern);
|
|
98
|
+
results.push(...decisions.map(r => ({ ...r, _source: 'decision' })));
|
|
99
|
+
} catch (err) {
|
|
100
|
+
// Table might not exist yet, skip
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Query evolution table
|
|
104
|
+
try {
|
|
105
|
+
const evolution = await this.queryTable('memory_evolution', ['skill_name'], pattern);
|
|
106
|
+
results.push(...evolution.map(r => ({ ...r, _source: 'evolution' })));
|
|
107
|
+
} catch (err) {
|
|
108
|
+
// Table might not exist yet, skip
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return results.slice(0, options.limit || 10);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async queryTable(table, fields, pattern) {
|
|
115
|
+
return new Promise((resolve, reject) => {
|
|
116
|
+
// Build OR query for multiple fields
|
|
117
|
+
const whereClause = fields.map(f => `${f} LIKE ?`).join(' OR ');
|
|
118
|
+
const params = fields.map(() => pattern);
|
|
119
|
+
const sql = `SELECT * FROM ${table} WHERE ${whereClause} LIMIT 10`;
|
|
120
|
+
|
|
121
|
+
this.db.all(sql, params, (err, rows) => {
|
|
122
|
+
if (err) {
|
|
123
|
+
// Return empty array for missing tables
|
|
124
|
+
if (err.message.includes('no such table')) {
|
|
125
|
+
resolve([]);
|
|
126
|
+
} else {
|
|
127
|
+
reject(err);
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
resolve(rows || []);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
getStats() {
|
|
137
|
+
return this.costStats;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
close() {
|
|
141
|
+
if (this.db) this.db.close();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
module.exports = QueryModule;
|
package/package.json
CHANGED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory V2.5 Demo Data Initialization
|
|
3
|
+
* Creates sample data for testing and demonstration
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const sqlite3 = require('sqlite3').verbose();
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
const dbPath = process.argv[2] || './demo-memory-v2.5.db';
|
|
10
|
+
|
|
11
|
+
console.log('š Initializing Memory V2.5 Demo Data...');
|
|
12
|
+
console.log(`š Database: ${dbPath}`);
|
|
13
|
+
|
|
14
|
+
const db = new sqlite3.Database(dbPath);
|
|
15
|
+
|
|
16
|
+
// Read and execute schema
|
|
17
|
+
const fs = require('fs');
|
|
18
|
+
const schemaPath = path.join(__dirname, '..', 'database', 'schema.sql');
|
|
19
|
+
const schema = fs.readFileSync(schemaPath, 'utf8');
|
|
20
|
+
|
|
21
|
+
// Execute schema
|
|
22
|
+
const statements = schema.split(';').filter(s => s.trim());
|
|
23
|
+
|
|
24
|
+
async function initDemo() {
|
|
25
|
+
try {
|
|
26
|
+
// Run schema
|
|
27
|
+
for (const statement of statements) {
|
|
28
|
+
if (statement.trim()) {
|
|
29
|
+
await new Promise((resolve, reject) => {
|
|
30
|
+
db.exec(statement, (err) => {
|
|
31
|
+
if (err) reject(err);
|
|
32
|
+
else resolve();
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
console.log('ā
Schema initialized');
|
|
38
|
+
|
|
39
|
+
// Insert demo data
|
|
40
|
+
console.log('š Inserting demo data...');
|
|
41
|
+
|
|
42
|
+
// Demo priorities
|
|
43
|
+
await insertDemoData(db, 'memory_priorities', [
|
|
44
|
+
{ message_id: 'demo-msg-001', conversation_id: 1, priority_level: 1, importance_score: 95, keywords: '["urgent","critical"]', context_summary: 'Critical system alert' },
|
|
45
|
+
{ message_id: 'demo-msg-002', conversation_id: 1, priority_level: 2, importance_score: 75, keywords: '["important","review"]', context_summary: 'Important decision pending' },
|
|
46
|
+
{ message_id: 'demo-msg-003', conversation_id: 1, priority_level: 3, importance_score: 50, keywords: '["normal","routine"]', context_summary: 'Regular update' }
|
|
47
|
+
]);
|
|
48
|
+
|
|
49
|
+
// Demo learning
|
|
50
|
+
await insertDemoData(db, 'memory_learning', [
|
|
51
|
+
{ message_id: 'demo-learn-001', conversation_id: 1, learning_topic: 'OpenClaw Skill Development', topic_category: 'programming', progress_status: 'in_progress', progress_percentage: 65, milestone_count: 5, completed_milestones: 3, notes: 'Learning to build OpenClaw skills with proper architecture' },
|
|
52
|
+
{ message_id: 'demo-learn-002', conversation_id: 1, learning_topic: 'AI Agent Orchestration', topic_category: 'ai', progress_status: 'started', progress_percentage: 25, milestone_count: 4, completed_milestones: 1, notes: 'Understanding multi-agent systems' },
|
|
53
|
+
{ message_id: 'demo-learn-003', conversation_id: 1, learning_topic: 'Memory Systems Design', topic_category: 'system_design', progress_status: 'completed', progress_percentage: 100, milestone_count: 3, completed_milestones: 3, notes: 'Completed study of memory management patterns' }
|
|
54
|
+
]);
|
|
55
|
+
|
|
56
|
+
// Demo decisions
|
|
57
|
+
await insertDemoData(db, 'memory_decisions', [
|
|
58
|
+
{ message_id: 'demo-dec-001', conversation_id: 1, decision_type: 'architecture', decision_question: 'Which database to use?', decision_context: 'Choosing storage for agent memory', options_considered: '["SQLite","PostgreSQL","MySQL"]', chosen_option: 'SQLite', rationale: 'Lightweight, embedded, perfect for local agent memory', confidence_level: 4, expected_outcome: 'Simple deployment and maintenance', outcome_status: 'implemented', review_date: '2026-04-25' },
|
|
59
|
+
{ message_id: 'demo-dec-002', conversation_id: 1, decision_type: 'framework', decision_question: 'Which AI framework?', decision_context: 'Selecting agent framework', options_considered: '["LangChain","AutoGPT","OpenClaw"]', chosen_option: 'OpenClaw', rationale: 'Native support, better integration', confidence_level: 5, expected_outcome: 'Seamless agent experience', outcome_status: 'validated', review_date: '2026-04-20' },
|
|
60
|
+
{ message_id: 'demo-dec-003', conversation_id: 1, decision_type: 'deployment', decision_question: 'Cloud or local deployment?', decision_context: 'Infrastructure decision', options_considered: '["Cloud VPS","Local Server","Hybrid"]', chosen_option: 'Hybrid', rationale: 'Balance of control and scalability', confidence_level: 3, expected_outcome: 'Flexible deployment options', outcome_status: 'pending', review_date: '2026-05-01' }
|
|
61
|
+
]);
|
|
62
|
+
|
|
63
|
+
// Demo evolution
|
|
64
|
+
await insertDemoData(db, 'memory_evolution', [
|
|
65
|
+
{ skill_name: 'JavaScript', skill_category: 'programming', proficiency_level: 8, experience_points: 2500, usage_count: 150, success_count: 140, failure_count: 10, performance_metrics: '{"complexity":8,"efficiency":9}' },
|
|
66
|
+
{ skill_name: 'SQLite', skill_category: 'database', proficiency_level: 7, experience_points: 1800, usage_count: 80, success_count: 75, failure_count: 5, performance_metrics: '{"complexity":6,"efficiency":8}' },
|
|
67
|
+
{ skill_name: 'Agent Design', skill_category: 'ai', proficiency_level: 6, experience_points: 1200, usage_count: 45, success_count: 40, failure_count: 5, performance_metrics: '{"complexity":9,"efficiency":7}' },
|
|
68
|
+
{ skill_name: 'Project Management', skill_category: 'management', proficiency_level: 7, experience_points: 2000, usage_count: 100, success_count: 95, failure_count: 5, performance_metrics: '{"complexity":7,"efficiency":8}' }
|
|
69
|
+
]);
|
|
70
|
+
|
|
71
|
+
console.log('ā
Demo data inserted');
|
|
72
|
+
|
|
73
|
+
// Verify
|
|
74
|
+
const tables = ['memory_priorities', 'memory_learning', 'memory_decisions', 'memory_evolution'];
|
|
75
|
+
for (const table of tables) {
|
|
76
|
+
const count = await new Promise((resolve, reject) => {
|
|
77
|
+
db.get(`SELECT COUNT(*) as count FROM ${table}`, (err, row) => {
|
|
78
|
+
if (err) reject(err);
|
|
79
|
+
else resolve(row.count);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
console.log(` - ${table}: ${count} records`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
console.log('\nā
Demo database ready!');
|
|
86
|
+
console.log(`š Location: ${dbPath}`);
|
|
87
|
+
console.log('\nš” Usage:');
|
|
88
|
+
console.log(` const api = new MemoryAPI('${dbPath}');`);
|
|
89
|
+
console.log(' await api.init();');
|
|
90
|
+
|
|
91
|
+
db.close();
|
|
92
|
+
process.exit(0);
|
|
93
|
+
} catch (err) {
|
|
94
|
+
console.error('\nā Error:', err.message);
|
|
95
|
+
db.close();
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function insertDemoData(db, table, rows) {
|
|
101
|
+
return Promise.all(rows.map(row => {
|
|
102
|
+
const columns = Object.keys(row).join(', ');
|
|
103
|
+
const placeholders = Object.keys(row).map(() => '?').join(', ');
|
|
104
|
+
const values = Object.values(row);
|
|
105
|
+
|
|
106
|
+
return new Promise((resolve, reject) => {
|
|
107
|
+
db.run(`INSERT INTO ${table} (${columns}) VALUES (${placeholders})`, values, function(err) {
|
|
108
|
+
if (err) reject(err);
|
|
109
|
+
else resolve(this.lastID);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
initDemo();
|