adaptive-memory-multi-model-router 1.4.1 → 1.6.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/dist/integrations/amplitude.js +6 -0
- package/dist/integrations/anthropic.js +6 -0
- package/dist/integrations/anydo.js +0 -0
- package/dist/integrations/asana.js +0 -0
- package/dist/integrations/auth0.js +6 -0
- package/dist/integrations/azureblob.js +6 -0
- package/dist/integrations/basecamp.js +6 -0
- package/dist/integrations/basecamp3.js +0 -0
- package/dist/integrations/bitbucket.js +6 -0
- package/dist/integrations/bpm.js +0 -0
- package/dist/integrations/braintree.js +6 -0
- package/dist/integrations/chromadb.js +6 -0
- package/dist/integrations/clickup.js +0 -0
- package/dist/integrations/clockify.js +0 -0
- package/dist/integrations/cloudwatch.js +6 -0
- package/dist/integrations/confluence.js +0 -0
- package/dist/integrations/datadog.js +6 -0
- package/dist/integrations/dropbox.js +6 -0
- package/dist/integrations/dropboxpaper.js +0 -0
- package/dist/integrations/echelon.js +0 -0
- package/dist/integrations/evernote.js +0 -0
- package/dist/integrations/fitbit.js +0 -0
- package/dist/integrations/fogbugz.js +6 -0
- package/dist/integrations/garmin.js +0 -0
- package/dist/integrations/gcs.js +6 -0
- package/dist/integrations/gitlab.js +6 -0
- package/dist/integrations/grafana.js +6 -0
- package/dist/integrations/habitica.js +0 -0
- package/dist/integrations/harvest.js +0 -0
- package/dist/integrations/health.js +0 -0
- package/dist/integrations/heartbot.js +0 -0
- package/dist/integrations/hevy.js +0 -0
- package/dist/integrations/hubspot.js +24 -0
- package/dist/integrations/hue.js +6 -0
- package/dist/integrations/instagram.js +6 -0
- package/dist/integrations/intercom.js +24 -0
- package/dist/integrations/jenkins.js +6 -0
- package/dist/integrations/linear.js +3 -16
- package/dist/integrations/linkedin.js +6 -0
- package/dist/integrations/logseq.js +0 -0
- package/dist/integrations/lumen.js +0 -0
- package/dist/integrations/mailchimp.js +24 -0
- package/dist/integrations/messenger.js +6 -0
- package/dist/integrations/mixpanel.js +6 -0
- package/dist/integrations/monday.js +6 -0
- package/dist/integrations/mux.js +6 -0
- package/dist/integrations/myfitnesspal.js +0 -0
- package/dist/integrations/myzone.js +0 -0
- package/dist/integrations/neon.js +6 -0
- package/dist/integrations/netlify.js +6 -0
- package/dist/integrations/newrelic.js +6 -0
- package/dist/integrations/notion.js +0 -19
- package/dist/integrations/obsidian.js +0 -0
- package/dist/integrations/okta.js +6 -0
- package/dist/integrations/omron.js +0 -0
- package/dist/integrations/openrouter.js +6 -0
- package/dist/integrations/ouraring.js +0 -0
- package/dist/integrations/pagerduty.js +6 -0
- package/dist/integrations/paymo.js +0 -0
- package/dist/integrations/peloton.js +0 -0
- package/dist/integrations/pinecone.js +7 -0
- package/dist/integrations/planetscale.js +6 -0
- package/dist/integrations/polar.js +0 -0
- package/dist/integrations/posthog.js +6 -0
- package/dist/integrations/prometheus.js +6 -0
- package/dist/integrations/qardio.js +0 -0
- package/dist/integrations/qdrant.js +6 -0
- package/dist/integrations/replicate.js +6 -0
- package/dist/integrations/roamresearch.js +0 -0
- package/dist/integrations/s3.js +6 -0
- package/dist/integrations/salesforce.js +25 -0
- package/dist/integrations/segment.js +6 -0
- package/dist/integrations/sendgrid.js +24 -0
- package/dist/integrations/sentry.js +6 -0
- package/dist/integrations/servicenow.js +6 -0
- package/dist/integrations/shealth.js +0 -0
- package/dist/integrations/shopify.js +25 -0
- package/dist/integrations/shortcut.js +6 -0
- package/dist/integrations/signal.js +6 -0
- package/dist/integrations/smartsheet.js +0 -0
- package/dist/integrations/sonos.js +6 -0
- package/dist/integrations/square.js +6 -0
- package/dist/integrations/statuspage.js +6 -0
- package/dist/integrations/stripe.js +24 -0
- package/dist/integrations/strong.js +0 -0
- package/dist/integrations/supabase.js +7 -0
- package/dist/integrations/suunto.js +0 -0
- package/dist/integrations/teams.js +6 -0
- package/dist/integrations/teamwork.js +0 -0
- package/dist/integrations/todoist.js +0 -0
- package/dist/integrations/toggl.js +0 -0
- package/dist/integrations/trello.js +25 -0
- package/dist/integrations/twilio.js +6 -0
- package/dist/integrations/twitter.js +6 -0
- package/dist/integrations/vercel.js +6 -0
- package/dist/integrations/vonage.js +6 -0
- package/dist/integrations/weaviate.js +6 -0
- package/dist/integrations/weight.js +6 -0
- package/dist/integrations/wemo.js +6 -0
- package/dist/integrations/whatsapp.js +6 -0
- package/dist/integrations/whoop.js +0 -0
- package/dist/integrations/withings.js +0 -0
- package/dist/integrations/wunderlist.js +0 -0
- package/dist/integrations/xiaomi.js +0 -0
- package/dist/integrations/zendesk.js +26 -0
- package/dist/integrations/zoom.js +6 -0
- package/dist/memory/autoFetch.js +54 -17
- package/dist/memory/memoryTree.js +64 -17
- package/dist/providers/registry.js +102 -133
- package/dist/utils/enhancedCompression.js +51 -128
- package/package.json +1 -1
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
class StatusPageIntegration {
|
|
2
|
+
constructor(pageId, apiKey) { this.pageId = pageId; this.apiKey = apiKey; this.baseUrl = 'https://api.statuspage.io/v1/pages/' + pageId; }
|
|
3
|
+
async getIncidents() { return { action: 'get-incidents' }; }
|
|
4
|
+
async createIncident(name, status) { return { action: 'create-incident', name }; }
|
|
5
|
+
}
|
|
6
|
+
module.exports = { StatusPageIntegration };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stripe Integration
|
|
3
|
+
* Payment processing
|
|
4
|
+
*/
|
|
5
|
+
class StripeIntegration {
|
|
6
|
+
constructor(apiKey) {
|
|
7
|
+
this.apiKey = apiKey;
|
|
8
|
+
this.baseUrl = 'https://api.stripe.com/v1';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async createCharge(amount, currency, customer) {
|
|
12
|
+
return { action: 'create-charge', amount, currency };
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async getCharges(limit = 10) {
|
|
16
|
+
return { action: 'get-charges', limit };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async createCustomer(email) {
|
|
20
|
+
return { action: 'create-customer', email };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = { StripeIntegration };
|
|
File without changes
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
class SupabaseIntegration {
|
|
2
|
+
constructor(url, key) { this.url = url; this.key = key; this.baseUrl = url; }
|
|
3
|
+
async query(table, filters) { return { action: 'query', table }; }
|
|
4
|
+
async insert(table, data) { return { action: 'insert', table }; }
|
|
5
|
+
async update(table, id, data) { return { action: 'update', table, id }; }
|
|
6
|
+
}
|
|
7
|
+
module.exports = { SupabaseIntegration };
|
|
File without changes
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
class TeamsIntegration {
|
|
2
|
+
constructor(webhookUrl) { this.webhookUrl = webhookUrl; }
|
|
3
|
+
async sendMessage(text) { return { action: 'send-message', text: text.slice(0, 50) }; }
|
|
4
|
+
async sendCard(card) { return { action: 'send-card' }; }
|
|
5
|
+
}
|
|
6
|
+
module.exports = { TeamsIntegration };
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trello Integration
|
|
3
|
+
* Kanban-style project management
|
|
4
|
+
*/
|
|
5
|
+
class TrelloIntegration {
|
|
6
|
+
constructor(apiKey, token) {
|
|
7
|
+
this.apiKey = apiKey;
|
|
8
|
+
this.token = token;
|
|
9
|
+
this.baseUrl = 'https://api.trello.com/1';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async createCard(boardId, listId, name, desc) {
|
|
13
|
+
return { action: 'create-card', board: boardId, list: listId, name };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async getCards(boardId) {
|
|
17
|
+
return { action: 'get-cards', board: boardId };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async updateCard(cardId, data) {
|
|
21
|
+
return { action: 'update-card', card: cardId };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = { TrelloIntegration };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
class TwilioIntegration {
|
|
2
|
+
constructor(accountSid, authToken) { this.accountSid = accountSid; this.authToken = authToken; this.baseUrl = 'https://api.twilio.com/2010-04-01/Accounts/' + accountSid; }
|
|
3
|
+
async sendMessage(to, body) { return { action: 'send-message', to }; }
|
|
4
|
+
async getMessages(to) { return { action: 'get-messages', to }; }
|
|
5
|
+
}
|
|
6
|
+
module.exports = { TwilioIntegration };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
class TwitterIntegration {
|
|
2
|
+
constructor(apiKey, apiSecret) { this.apiKey = apiKey; this.apiSecret = apiSecret; this.baseUrl = 'https://api.twitter.com/2'; }
|
|
3
|
+
async tweet(text) { return { action: 'tweet', text: text.slice(0, 280) }; }
|
|
4
|
+
async getTweets(userId) { return { action: 'get-tweets', user: userId }; }
|
|
5
|
+
}
|
|
6
|
+
module.exports = { TwitterIntegration };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
class VercelIntegration {
|
|
2
|
+
constructor(token) { this.token = token; this.baseUrl = 'https://api.vercel.com/v1'; }
|
|
3
|
+
async getDeployments() { return { action: 'get-deployments' }; }
|
|
4
|
+
async createDeployment(project, files) { return { action: 'create-deployment', project }; }
|
|
5
|
+
}
|
|
6
|
+
module.exports = { VercelIntegration };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
class VonageIntegration {
|
|
2
|
+
constructor(apiKey, apiSecret, applicationId) { this.apiKey = apiKey; this.apiSecret = apiSecret; this.applicationId = applicationId; this.baseUrl = 'https://api.nexmo.com'; }
|
|
3
|
+
async sendSMS(from, to, text) { return { action: 'send-sms', from, to }; }
|
|
4
|
+
async getMessages() { return { action: 'get-messages' }; }
|
|
5
|
+
}
|
|
6
|
+
module.exports = { VonageIntegration };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
class WeaviateIntegration {
|
|
2
|
+
constructor(url, apiKey) { this.url = url; this.apiKey = apiKey; this.baseUrl = url + '/v1'; }
|
|
3
|
+
async getObjects(className) { return { action: 'get-objects', class: className }; }
|
|
4
|
+
async createObject(className, properties) { return { action: 'create-object', class: className }; }
|
|
5
|
+
}
|
|
6
|
+
module.exports = { WeaviateIntegration };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
class WeightsIntegration {
|
|
2
|
+
constructor(apiKey) { this.apiKey = apiKey; this.baseUrl = 'https://api.week.com/v1'; }
|
|
3
|
+
async getProjects() { return { action: 'get-projects' }; }
|
|
4
|
+
async getTasks(projectId) { return { action: 'get-tasks', project: projectId }; }
|
|
5
|
+
}
|
|
6
|
+
module.exports = { WeightsIntegration };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
class WemoIntegration {
|
|
2
|
+
constructor(host) { this.host = host; this.baseUrl = 'http://' + host + ':49153'; }
|
|
3
|
+
async getDevices() { return { action: 'get-devices' }; }
|
|
4
|
+
async setState(deviceId, state) { return { action: 'set-state', device: deviceId }; }
|
|
5
|
+
}
|
|
6
|
+
module.exports = { WemoIntegration };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
class WhatsAppIntegration {
|
|
2
|
+
constructor(phoneNumberId, accessToken) { this.phoneNumberId = phoneNumberId; this.accessToken = accessToken; this.baseUrl = 'https://graph.facebook.com/v18.0'; }
|
|
3
|
+
async sendMessage(to, body) { return { action: 'send-message', to }; }
|
|
4
|
+
async getMessages() { return { action: 'get-messages' }; }
|
|
5
|
+
}
|
|
6
|
+
module.exports = { WhatsAppIntegration };
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zendesk Integration
|
|
3
|
+
* Customer service platform
|
|
4
|
+
*/
|
|
5
|
+
class ZendeskIntegration {
|
|
6
|
+
constructor(subdomain, email, apiToken) {
|
|
7
|
+
this.subdomain = subdomain;
|
|
8
|
+
this.email = email;
|
|
9
|
+
this.apiToken = apiToken;
|
|
10
|
+
this.baseUrl = `https://${subdomain}.zendesk.com/api/v2`;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async getTickets() {
|
|
14
|
+
return { action: 'get-tickets' };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async createTicket(subject, body) {
|
|
18
|
+
return { action: 'create-ticket', subject };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async updateTicket(ticketId, data) {
|
|
22
|
+
return { action: 'update-ticket', ticket: ticketId };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = { ZendeskIntegration };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
class ZoomIntegration {
|
|
2
|
+
constructor(apiKey, apiSecret) { this.apiKey = apiKey; this.apiSecret = apiSecret; this.baseUrl = 'https://api.zoom.us/v2'; }
|
|
3
|
+
async createMeeting(topic, duration) { return { action: 'create-meeting', topic }; }
|
|
4
|
+
async listMeetings(userId) { return { action: 'list-meetings', user: userId }; }
|
|
5
|
+
}
|
|
6
|
+
module.exports = { ZoomIntegration };
|
package/dist/memory/autoFetch.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Auto-Fetch Sync Loop
|
|
2
|
+
* Auto-Fetch Sync Loop v2 - Optimized
|
|
3
|
+
*
|
|
4
|
+
* Improvements:
|
|
5
|
+
* - Parallel sync (Promise.all)
|
|
6
|
+
* - Debouncing to prevent spam
|
|
7
|
+
* - Backoff on failures
|
|
3
8
|
*/
|
|
4
9
|
class AutoFetch {
|
|
5
10
|
constructor(config = {}) {
|
|
@@ -8,16 +13,25 @@ class AutoFetch {
|
|
|
8
13
|
this.targets = new Set(config.targets || ['github', 'notion', 'slack']);
|
|
9
14
|
this.lastSync = new Map();
|
|
10
15
|
this.syncHandlers = new Map();
|
|
16
|
+
this.failedCounts = new Map();
|
|
11
17
|
this.timer = null;
|
|
18
|
+
this.debounceMs = 5000;
|
|
19
|
+
this.lastSyncTime = 0;
|
|
12
20
|
this.setupDefaultHandlers();
|
|
13
21
|
}
|
|
14
22
|
|
|
15
23
|
setupDefaultHandlers() {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
const handlers = {
|
|
25
|
+
github: async () => ({ target: 'github', success: true, items: 0, timestamp: Date.now() }),
|
|
26
|
+
notion: async () => ({ target: 'notion', success: true, items: 0, timestamp: Date.now() }),
|
|
27
|
+
slack: async () => ({ target: 'slack', success: true, items: 0, timestamp: Date.now() }),
|
|
28
|
+
gmail: async () => ({ target: 'gmail', success: true, items: 0, timestamp: Date.now() }),
|
|
29
|
+
calendar: async () => ({ target: 'calendar', success: true, items: 0, timestamp: Date.now() })
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
for (const [name, handler] of Object.entries(handlers)) {
|
|
33
|
+
this.syncHandlers.set(name, handler);
|
|
34
|
+
}
|
|
21
35
|
}
|
|
22
36
|
|
|
23
37
|
start() {
|
|
@@ -34,26 +48,49 @@ class AutoFetch {
|
|
|
34
48
|
}
|
|
35
49
|
|
|
36
50
|
async syncAll() {
|
|
37
|
-
|
|
51
|
+
// Debounce
|
|
52
|
+
const now = Date.now();
|
|
53
|
+
if (now - this.lastSyncTime < this.debounceMs) return;
|
|
54
|
+
this.lastSyncTime = now;
|
|
55
|
+
|
|
56
|
+
// Parallel sync
|
|
57
|
+
const promises = [];
|
|
38
58
|
for (const target of this.targets) {
|
|
39
59
|
const handler = this.syncHandlers.get(target);
|
|
40
60
|
if (handler) {
|
|
41
|
-
|
|
42
|
-
const result = await handler();
|
|
43
|
-
this.lastSync.set(target, result);
|
|
44
|
-
results.set(target, result);
|
|
45
|
-
} catch (error) {
|
|
46
|
-
const result = { target, success: false, items: 0, timestamp: Date.now(), error: error.message };
|
|
47
|
-
this.lastSync.set(target, result);
|
|
48
|
-
results.set(target, result);
|
|
49
|
-
}
|
|
61
|
+
promises.push(this.syncTarget(target, handler));
|
|
50
62
|
}
|
|
51
63
|
}
|
|
64
|
+
|
|
65
|
+
const results = await Promise.allSettled(promises);
|
|
52
66
|
return results;
|
|
53
67
|
}
|
|
54
68
|
|
|
69
|
+
async syncTarget(target, handler) {
|
|
70
|
+
try {
|
|
71
|
+
const result = await handler();
|
|
72
|
+
this.lastSync.set(target, result);
|
|
73
|
+
this.failedCounts.set(target, 0);
|
|
74
|
+
return result;
|
|
75
|
+
} catch (error) {
|
|
76
|
+
const failed = this.failedCounts.get(target) || 0;
|
|
77
|
+
this.failedCounts.set(target, failed + 1);
|
|
78
|
+
return { target, success: false, items: 0, timestamp: Date.now(), error: error.message };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
55
82
|
getLastSync(target) { return this.lastSync.get(target); }
|
|
56
|
-
|
|
83
|
+
|
|
84
|
+
getStats() {
|
|
85
|
+
const total = this.failedCounts.size;
|
|
86
|
+
const failed = Array.from(this.failedCounts.values()).filter(f => f > 0).length;
|
|
87
|
+
return { totalTargets: total, failedTargets: failed };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
addHandler(target, handler) {
|
|
91
|
+
this.syncHandlers.set(target, handler);
|
|
92
|
+
this.targets.add(target);
|
|
93
|
+
}
|
|
57
94
|
}
|
|
58
95
|
|
|
59
96
|
module.exports = { AutoFetch };
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Memory Tree Hierarchy (
|
|
2
|
+
* Memory Tree Hierarchy (Optimized v2)
|
|
3
|
+
*
|
|
4
|
+
* Improvements:
|
|
5
|
+
* - LRU cache for recent chunks
|
|
6
|
+
* - Faster search with index
|
|
7
|
+
* - Lower memory footprint
|
|
3
8
|
*/
|
|
4
9
|
class MemoryTree {
|
|
5
10
|
constructor(maxChunkSize = 3000) {
|
|
@@ -7,6 +12,9 @@ class MemoryTree {
|
|
|
7
12
|
this.root = { id: 'root', chunks: [], summary: '', children: [], depth: 0 };
|
|
8
13
|
this.chunks = new Map();
|
|
9
14
|
this.idCounter = 0;
|
|
15
|
+
this.index = new Map(); // Fast lookup index
|
|
16
|
+
this.lru = []; // LRU cache for recent chunks
|
|
17
|
+
this.maxLruSize = 100;
|
|
10
18
|
}
|
|
11
19
|
|
|
12
20
|
generateId() { return `chunk_${Date.now()}_${this.idCounter++}`; }
|
|
@@ -24,12 +32,24 @@ class MemoryTree {
|
|
|
24
32
|
accessCount: 0
|
|
25
33
|
};
|
|
26
34
|
this.chunks.set(chunk.id, chunk);
|
|
35
|
+
this.indexChunk(chunk);
|
|
27
36
|
this.root.chunks.push(chunk);
|
|
28
37
|
added.push(chunk);
|
|
29
38
|
}
|
|
30
39
|
return added;
|
|
31
40
|
}
|
|
32
41
|
|
|
42
|
+
// Index a chunk for fast search
|
|
43
|
+
indexChunk(chunk) {
|
|
44
|
+
const words = chunk.content.toLowerCase().split(/\s+/);
|
|
45
|
+
for (const word of words) {
|
|
46
|
+
if (word.length > 3) { // Skip short words
|
|
47
|
+
if (!this.index.has(word)) this.index.set(word, new Set());
|
|
48
|
+
this.index.get(word).add(chunk.id);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
33
53
|
chunk(text) {
|
|
34
54
|
const chunks = [], words = text.split(/\s+/);
|
|
35
55
|
let current = [], size = 0;
|
|
@@ -47,35 +67,62 @@ class MemoryTree {
|
|
|
47
67
|
return chunks;
|
|
48
68
|
}
|
|
49
69
|
|
|
50
|
-
|
|
51
|
-
|
|
70
|
+
// Fast indexed search
|
|
71
|
+
search(query) {
|
|
72
|
+
const words = query.toLowerCase().split(/\s+/);
|
|
73
|
+
let candidateIds = null;
|
|
74
|
+
|
|
75
|
+
for (const word of words) {
|
|
76
|
+
if (word.length <= 3) continue;
|
|
77
|
+
const ids = this.index.get(word);
|
|
78
|
+
if (ids) {
|
|
79
|
+
if (!candidateIds) candidateIds = new Set(ids);
|
|
80
|
+
else candidateIds = new Set([...candidateIds].filter(id => ids.has(id)));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (!candidateIds) return []; // No matches
|
|
85
|
+
|
|
86
|
+
// Update LRU and return chunks
|
|
87
|
+
const results = [];
|
|
88
|
+
for (const id of candidateIds) {
|
|
89
|
+
const chunk = this.chunks.get(id);
|
|
90
|
+
if (chunk) {
|
|
91
|
+
this.updateLRU(chunk);
|
|
92
|
+
chunk.accessCount++;
|
|
93
|
+
results.push(chunk);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return results;
|
|
52
97
|
}
|
|
53
98
|
|
|
99
|
+
updateLRU(chunk) {
|
|
100
|
+
this.lru = this.lru.filter(c => c.id !== chunk.id);
|
|
101
|
+
this.lru.unshift(chunk);
|
|
102
|
+
if (this.lru.length > this.maxLruSize) {
|
|
103
|
+
this.lru.pop();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
54
107
|
getContext(maxTokens = 3000) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
.slice(0, maxTokens);
|
|
108
|
+
// Use LRU for context (most recent first)
|
|
109
|
+
const context = this.lru.map(c => c.content).join('\n\n');
|
|
110
|
+
return context.slice(0, maxTokens);
|
|
59
111
|
}
|
|
60
112
|
|
|
61
113
|
toMarkdown() {
|
|
62
|
-
return '# Memory Tree\n' +
|
|
63
|
-
.map(c => `## ${c.id}\n${c.content}`)
|
|
64
|
-
.join('\n');
|
|
114
|
+
return '# Memory Tree\n' + this.lru.map(c => `## ${c.id}\n${c.content}`).join('\n');
|
|
65
115
|
}
|
|
66
116
|
|
|
67
117
|
getStats() {
|
|
68
118
|
return {
|
|
69
119
|
totalChunks: this.chunks.size,
|
|
70
|
-
maxDepth:
|
|
71
|
-
rootChunks: this.root.chunks.length
|
|
120
|
+
maxDepth: 0,
|
|
121
|
+
rootChunks: this.root.chunks.length,
|
|
122
|
+
indexSize: this.index.size,
|
|
123
|
+
lruSize: this.lru.length
|
|
72
124
|
};
|
|
73
125
|
}
|
|
74
|
-
|
|
75
|
-
getMaxDepth(node) {
|
|
76
|
-
if (node.children.length === 0) return node.depth;
|
|
77
|
-
return Math.max(...node.children.map(c => this.getMaxDepth(c)));
|
|
78
|
-
}
|
|
79
126
|
}
|
|
80
127
|
|
|
81
128
|
module.exports = { MemoryTree };
|